Sebastian Herbszt
2010-Jul-15 22:02 UTC
[syslinux] Accessing command_line from core C code
I tried to replace display_labels asm code (ui.inc) with new C code (pm_display_labels), but the data i access in command_line doesn't seem to be always up to date. The patch i am working on is only for PXELINUX because of different vkernel structure: diff --git a/core/com32.inc b/core/com32.inc index 111590c..f19df7c 100644 --- a/core/com32.inc +++ b/core/com32.inc @@ -135,6 +135,7 @@ __com32: dd 0 ; 64K bounce buffer dd core_farcall ; Farcall entry point dd core_cfarcall ; Cfarcall entry point +global HighMemSize HighMemSize dd 0 ; End of memory pointer (bytes) dd 0 ; No module name dd pm_api_vector ; Protected mode functions diff --git a/core/display_labels.c b/core/display_labels.c new file mode 100644 index 0000000..a8ba945 --- /dev/null +++ b/core/display_labels.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <string.h> +#include "core.h" +#include "fs.h" + +struct vkernel { + char vname[FILENAME_MAX]; + char rname[FILENAME_MAX]; + uint8_t ipappend; + uint8_t type; + uint16_t appendlen; + char append[2048]; /* align 4 */ +}; + +void pm_display_labels(com32sys_t *regs) +{ + struct vkernel *vk; + void *buf; + uint32_t t; + uint32_t s; + + printf("\ncommand_line: %s\n", command_line); + buf = malloc(sizeof(struct vkernel)); + memset(buf, 0, sizeof(struct vkernel)); + s = strlen((char *)command_line); + + t = HighMemSize; + while (t > VKernelEnd) { + regs->esi.l = t; + regs->edi.l = (uint32_t)buf; + rllunpack(regs); + vk = (struct vkernel *)buf; + if (!strncmp(vk->vname, (char *)command_line, s)) { + printf(" %s", vk->vname); + } + t = regs->esi.l; + } + printf("\n"); + return; +} diff --git a/core/extern.inc b/core/extern.inc index 64edea6..58d0f27 100644 --- a/core/extern.inc +++ b/core/extern.inc @@ -24,6 +24,9 @@ ; newconfig.c extern pm_is_config_file + ; display_labels.c + extern pm_display_labels + %if IS_PXELINUX ; pxe.c extern unload_pxe, reset_pxe diff --git a/core/include/core.h b/core/include/core.h index 7db5daf..8d77b52 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -14,6 +14,9 @@ extern char ConfigName[]; extern char KernelName[]; extern char cmd_line[]; extern char ConfigFile[]; +extern uint32_t HighMemSize; +extern uint32_t VKernelEnd; +extern char command_line[]; /* diskstart.inc isolinux.asm*/ extern void getlinsec(void); @@ -29,6 +32,10 @@ extern int (*idle_hook_func)(void); extern void __idle(void); extern void reset_idle(void); +/* rllpack.c */ +extern void rllpack(com32sys_t *); +extern void rllunpack(com32sys_t *); + /* mem/malloc.c, mem/free.c, mem/init.c */ extern void *malloc(size_t); extern void *lmalloc(size_t); diff --git a/core/parseconfig.inc b/core/parseconfig.inc index e7b3108..f28a68e 100644 --- a/core/parseconfig.inc +++ b/core/parseconfig.inc @@ -441,6 +441,7 @@ SerialNotice db 1 ; Only print this once section .bss16 alignb 4 +global VKernelEnd VKernelEnd resd 1 ; Lowest high memory address used ; This symbol should be used by loaders to indicate @@ -470,6 +471,7 @@ IPAppend db 0 ; Default IPAPPEND option section .uibss alignb 4 ; For the good of REP MOVSD +global command_line command_line resb max_cmd_len+2 ; Command line buffer alignb 4 default_cmd resb max_cmd_len+1 ; "default" command line diff --git a/core/ui.inc b/core/ui.inc index 2d44447..3e28dac 100644 --- a/core/ui.inc +++ b/core/ui.inc @@ -150,44 +150,8 @@ set_func_flag: display_labels: cmp word [NoComplete],0 ; Label completion enabled? jne get_char_2 - push di ; Save pointer - mov cx,di - sub cx,command_line - call crlf - mov esi,[HighMemSize] ; Start from top of memory -.scan: - cmp esi,[VKernelEnd] - jbe .not_vk - - push cx ; save command line size - - mov edi,VKernelBuf - pm_call rllunpack - ; ESI updated on return - - sub di,cx ; Return to beginning of buf - pop cx ; restore command line size - push si ; save SI - cmp cx,0 - jz .print push di - push cx - mov si,command_line - es repe cmpsb - pop cx - pop di - jne .next -.print: - mov al,' ' - call writechr - - mov si,di - call writestr -.next: - pop si ; restore SI - jmp .scan -.not_vk: - call crlf + pm_call pm_display_labels jmp fk_wrcmd ctrl_f: This is the output: boot: command_line: justtesting kernelwithmenu linux local0 a b c d e f g h boot: k command_line: k kernelwithmenu kernelonly boot: command_line: k kernelwithmenu kernelonly boot: command_line: justtesting kernelwithmenu linux local0 a b c d e f g h boot: With empty command_line the output is correct, also if the command_line is filled with "k". As soon as it is cleared again by pressing backspace the C code still seems to think it contains "k". Just pressing TAB again fixes this. Any ideas? Sebastian
On 07/15/2010 03:02 PM, Sebastian Herbszt wrote:> I tried to replace display_labels asm code (ui.inc) with new C code > (pm_display_labels), > but the data i access in command_line doesn't seem to be always up to date. > The patch i am working on is only for PXELINUX because of different > vkernel structure:I would really like to get rid of the entire ui.inc (actually the rest of the assembly core, too) and have it replaced with C code... a lot of work in that direction has already happened of the "elflink" branch (Syslinux 5). On the other hand, perhaps an incremental approach is useful, too. I think the part you're missing is that command_line is not guaranteed to be zero-terminated during editing. The assembly code uses register DI to keep track of the end of the command line; it does zero-terminate the string when it is complete, however. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf.