kernel, main: read kernel command line into init segment buffer

The protocol for this extension is based on what lDebug
already does given the PROTOCOL=FREEDOS with the switch
CMDLINE=1 (which was originally defined for the lDOS and
RxDOS load protocols). Therefore the stack frame mirrors
that of the lDOS protocol.
This commit is contained in:
C. Masloch 2022-05-21 15:27:06 +02:00 committed by Kenneth J Davis
parent 49733547f1
commit 4377a257e0
2 changed files with 73 additions and 3 deletions

View File

@ -103,6 +103,7 @@ global realentry
realentry: ; execution continues here realentry: ; execution continues here
clc ; this is patched to stc by exeflat clc ; this is patched to stc by exeflat
adc byte [cs:use_upx_config], 0 adc byte [cs:use_upx_config], 0
; ! ZF used later in initialise_command_line_buffer
push ax push ax
push bx push bx
@ -139,10 +140,60 @@ kernel_start:
popf popf
pop bx 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 cli
mov ss,ax mov ss, dx
mov sp,init_tos mov sp, init_tos
int 12h ; move init text+data to higher memory int 12h ; move init text+data to higher memory
mov cl,6 mov cl,6
shl ax,cl ; convert kb to para shl ax,cl ; convert kb to para

View File

@ -69,6 +69,8 @@ __segment DosTextSeg = 0;
struct lol FAR *LoL = &DATASTART; struct lol FAR *LoL = &DATASTART;
struct _KernelConfig InitKernelConfig = { 0xFF }; 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 UBYTE debugger_present = 0xFF; /* initialised in kernel.asm
do NOT set 0 here or compiler may do NOT set 0 here or compiler may
move it into bss that we zero out */ move it into bss that we zero out */
@ -77,6 +79,7 @@ VOID ASMCFUNC FreeDOSmain(void)
{ {
unsigned char drv; unsigned char drv;
unsigned char FAR *p; unsigned char FAR *p;
char * pp;
#ifdef _MSC_VER #ifdef _MSC_VER
extern FAR prn_dev; extern FAR prn_dev;
@ -106,6 +109,22 @@ VOID ASMCFUNC FreeDOSmain(void)
/* install DOS API and other interrupt service routines, basic kernel functionality works */ /* install DOS API and other interrupt service routines, basic kernel functionality works */
setup_int_vectors(); 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 */ /* check if booting from floppy/CD */
CheckContinueBootFromHarddisk(); CheckContinueBootFromHarddisk();