[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