diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 29a0173..d2819d9 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -103,6 +103,7 @@ global realentry realentry: ; execution continues here clc ; this is patched to stc by exeflat adc byte [cs:use_upx_config], 0 + ; ! ZF used later in initialise_command_line_buffer push ax push bx @@ -139,10 +140,60 @@ kernel_start: popf pop bx - mov ax,I_GROUP + +extern _kernel_command_line + + ; preserve unit in bl +initialise_command_line_buffer: + mov dx, I_GROUP + mov es, dx + mov ax, ss + mov ds, ax + mov ax, sp ; ds:ax = ss:sp + mov si, bp ; si = bp + jz .notupx ; ! ZF still left by adc + + xor ax, ax + mov ds, ax ; :5E0h -> UPX help data + lds si, [5E0h + 1Ch] ; -> original ss:sp - 2 + lea ax, [si + 2] ; ax = original sp + mov si, word [si] ; si = original bp + +.notupx: + ; Note that the kernel command line buffer in + ; the init data segment is pre-initialised to + ; hold 0x00 0xFF in the first two bytes. This + ; is used to indicate no command line present, + ; as opposed to an empty command line which + ; will hold 0x00 0x00. + ; If any of the branches to .none are taken then + ; the buffer is not modified so it retains the + ; 0x00 0xFF contents. + cmp si, 114h ; buffer fits below ss:bp ? + jb .none ; no --> + cmp word [si - 14h], "CL" ; signature passed to us ? + jne .none ; no --> + lea si, [si - 114h] ; -> command line buffer + cmp ax, si ; stack top starts below-or-equal buffer ? + ja .none ; no --> + mov di, _kernel_command_line ; our buffer + mov cx, 255 + xor ax, ax + push di + rep movsb ; copy up to 255 bytes + stosb ; truncate + pop di + mov ch, 1 ; cx = 256 + repne scasb ; scan for terminator + rep stosb ; clear remainder of buffer + ; (make sure we do not have 0x00 0xFF + ; even if the command line given is + ; actually the empty string) +.none: + cli - mov ss,ax - mov sp,init_tos + mov ss, dx + mov sp, init_tos int 12h ; move init text+data to higher memory mov cl,6 shl ax,cl ; convert kb to para diff --git a/kernel/main.c b/kernel/main.c index ffd14e8..ea06803 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -69,6 +69,8 @@ __segment DosTextSeg = 0; struct lol FAR *LoL = &DATASTART; struct _KernelConfig InitKernelConfig = { 0xFF }; +UBYTE kernel_command_line[256] = { 0x00, 0xFF }; /* special none value */ +int kernel_command_line_length BSS_INIT(0); UBYTE debugger_present = 0xFF; /* initialised in kernel.asm do NOT set 0 here or compiler may move it into bss that we zero out */ @@ -77,6 +79,7 @@ VOID ASMCFUNC FreeDOSmain(void) { unsigned char drv; unsigned char FAR *p; + char * pp; #ifdef _MSC_VER extern FAR prn_dev; @@ -106,6 +109,22 @@ VOID ASMCFUNC FreeDOSmain(void) /* install DOS API and other interrupt service routines, basic kernel functionality works */ setup_int_vectors(); +#ifdef DEBUG + /* printf must go after setup_int_vectors call */ + if (kernel_command_line[0] == 0x00 && kernel_command_line[1] == 0xFF) { + printf("\nKERNEL: Command line is not specified.\n"); + } else { + printf("\nKERNEL: Command line is \"%s\"\n", kernel_command_line); + } +#endif + + kernel_command_line_length = strlen(kernel_command_line); + for (pp = kernel_command_line; *pp; ++pp) { + if (*pp == ';') { + *pp = 0; + } + } + /* check if booting from floppy/CD */ CheckContinueBootFromHarddisk();