diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 77c6f8e..aefa6eb 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -56,6 +56,7 @@ entry: ;************************************************************ global _LowKernelConfig _LowKernelConfig: +config_signature: db 'CONFIG' ; constant dw configend-configstart; size of config area ; to be checked !!! @@ -76,6 +77,9 @@ Version_Revision dw 41 ; REVISION_SEQ Version_Release dw 1 ; 0=release build, >0=svn# configend: +kernel_config_size: equ configend - config_signature + ; must be below-or-equal the size of struct _KernelConfig + ; in the file kconfig.h ! ;************************************************************ ; KERNEL CONFIGURATION AREA END @@ -94,7 +98,10 @@ configend: cpu 8086 ; (keep initial entry compatible) +global realentry realentry: ; execution continues here + clc ; this is patched to stc by exeflat + adc byte [cs:use_upx_config], 0 push ax push bx @@ -107,6 +114,9 @@ realentry: ; execution continues here pop ax jmp IGROUP:kernel_start + +use_upx_config: db 0 + beyond_entry: times 256-(beyond_entry-entry) db 0 ; scratch area for data (DOS_PSP) @@ -212,11 +222,38 @@ cont: ; Now set up call frame cpu XCPU %endif mov [_CPULevel], al - - mov ax,ss - mov ds,ax - mov es,ax - jmp _FreeDOSmain + +initialise_kernel_config: +extern _InitKernelConfig + + push ds + pop es ; => DOS data segment (for _BootDrive) + mov ax, ss ; => init data segment + mov si, 60h + mov ds, si ; => entry section + mov si, _LowKernelConfig ; -> our own CONFIG block + ; This block is part of what got decompressed if + ; the kernel is UPX-compressed. And if UPX was + ; used in .SYS mode then the first several words + ; are overwritten with pseudo device header fields. + cmp byte [use_upx_config], 0 ; from UPX ? + je .notupx ; no, use own CONFIG block --> + mov si, 5Eh + mov ds, si + mov si, 2 ; -> CONFIG block of compressed entry + mov bl, [0] ; 05E0h has the boot load unit + mov byte [es:_BootDrive], bl ; overwrite the value in DOS data segment +.notupx: + mov es, ax ; => init data segment + mov di, _InitKernelConfig ; -> init's CONFIG block buffer + mov cx, kernel_config_size / 2 ; size that we support + rep movsw ; copy it over +%if kernel_config_size & 1 + movsb ; allow odd size +%endif + mov ds, ax ; => init data segment + + jmp _FreeDOSmain %if XCPU != 86 cpu 8086 diff --git a/kernel/main.c b/kernel/main.c index accf603..4b5cdb9 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -44,8 +44,6 @@ static char copyright[] = "GNU General Public License as published by the Free Software Foundation;\n" "either version 2, or (at your option) any later version.\n"; -struct _KernelConfig InitKernelConfig BSS_INIT({0}); - STATIC VOID InitIO(void); STATIC VOID update_dcb(struct dhdr FAR *); @@ -70,6 +68,8 @@ __segment DosTextSeg = 0; struct lol FAR *LoL = &DATASTART; +struct _KernelConfig InitKernelConfig = { 0xFF }; + VOID ASMCFUNC FreeDOSmain(void) { unsigned char drv; @@ -92,17 +92,8 @@ VOID ASMCFUNC FreeDOSmain(void) drv = LoL->BootDrive + 1; p = MK_FP(0, 0x5e0); - if (fmemcmp(p+2,"CONFIG",6) == 0) /* UPX */ { - fmemcpy(&InitKernelConfig, p+2, sizeof(InitKernelConfig)); - - drv = *p + 1; - *(DWORD FAR *)(p+2) = 0; - } - else - { - *p = drv - 1; - fmemcpy(&InitKernelConfig, &LowKernelConfig, sizeof(InitKernelConfig)); + *p = drv - 1; /* compatibility with older kernels */ } if (drv >= 0x80)