[syslinux] Accessing command_line from core C code

Sebastian Herbszt herbszt at gmx.de
Thu Jul 15 15:02:45 PDT 2010


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




More information about the Syslinux mailing list