[syslinux] [PATCH] mboot using module path

Damien damien.nozay at gmail.com
Mon Jul 27 15:47:57 PDT 2009


Hi,

We are using pxelinux at my company to test our product. And there are
limitations
that we have hit in the past w.r.t. the max length of a path, or the
max length of a module
name (in mboot.c / mboot.c32). We've used workarounds in the past, and
reorganized the
directory structure, but we face that problem again. Out of the 128 /
FILENAME_MAX chars
that can be used, 110 - 120 go to the path, that includes:
server - user - build - build type - changeset - product type -  product etc.
This includes tags that are valuable to us, and that we cannot keep on
shortening.

I have tried changing FILENAME_MAX / FILENAME_MAX_LG2 definitions to accept more
characters, but it wouldn't compile, the linker script complaining
about the 64k limit.
Another way is to use the CurrentDirName and save the precious
characters for the module
names.

thanks,
Damien

---
from: Damien Nozay
[PATCH 01/04] implement chdir as the way to change the path prefix

chdir is unimplemented and returns ENOSYS. we could rely on chdir when
using the pxelinux stack to give a module path. this implementation uses
chdir to change the CurrentDirName and uses it for mangling the filenames.

signed-off-by: Damien Nozay <damien /dot nozay /at gmail.com>
---
diff -u -r -X nodiff syslinux-3.82-orig/com32/lib/chdir.c
syslinux-3.82/com32/lib/chdir.c
--- syslinux-3.82-orig/com32/lib/chdir.c    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/com32/lib/chdir.c    2009-07-27 11:11:34.000000000 -0700
@@ -5,9 +5,25 @@
 #include <dirent.h>
 #include <stdio.h>
 #include <errno.h>
+#include <com32.h>

 int chdir(const char *path)
 {
-    errno = ENOSYS;
-    return -1;
+    com32sys_t regs;
+
+    strlcpy(__com32.cs_bounce, path, __com32.cs_bounce_size);
+
+    regs.eax.w[0] = 0x0025;
+    regs.esi.w[0] = OFFS(__com32.cs_bounce);
+    regs.es = SEG(__com32.cs_bounce);
+
+    __com32.cs_intcall(0x22, &regs, &regs);
+
+    if (!(regs.eflags.l & EFLAGS_CF)) {
+        return -1;
+    }
+
+    /* We're done */
+    return 0;
 }
+
diff -u -r -X nodiff syslinux-3.82-orig/core/comboot.inc
syslinux-3.82/core/comboot.inc
--- syslinux-3.82-orig/core/comboot.inc    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/comboot.inc    2009-07-27 11:23:23.000000000 -0700
@@ -963,6 +963,24 @@
         mov ecx,P_ECX
         jmp shuffle_and_boot_raw

+
+;
+; INT 22h AX=0025h    Change PathPrefix
+;
+comapi_changedir:
+        push di
+        push ds
+        mov ds,P_ES
+        mov si,P_SI
+        mov di,CurrentDirName
+        call strcpy
+        pop ds
+        pop di
+        clc
+        ret
+
+
+
         section .data

 %macro        int21 2
@@ -1022,6 +1040,7 @@
         dw comapi_closedir    ; 0022 close directory
         dw comapi_shufsize    ; 0023 query shuffler size
         dw comapi_shufraw    ; 0024 cleanup, shuffle and boot raw
+        dw comapi_changedir    ; 0025 change directory / path prefix
 int22_count    equ ($-int22_table)/2

 APIKeyWait    db 0
diff -u -r -X nodiff syslinux-3.82-orig/core/pxelinux.asm
syslinux-3.82/core/pxelinux.asm
--- syslinux-3.82-orig/core/pxelinux.asm    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/pxelinux.asm    2009-07-27 10:13:37.000000000 -0700
@@ -977,7 +977,8 @@
         jnz .noprefix        ; No prefix, and we have the server

         push si            ; Add common prefix
-        mov si,PathPrefix
+;        mov si,PathPrefix
+        mov si,CurrentDirName
         call strcpy
         dec di
         pop si
---end


---
from: Damien Nozay
[PATCH 02/04] add DIRNAME_MAX definition

add DIRNAME_MAX definition which can be different from FILENAME_MAX.
FILENAME_MAX is used in many places and also for directories. Thus when
changing FILENAME_MAX / FILENAME_MAX_LG2 definitions, everything can
explode and the linker script may not be happy.

signed-off-by: Damien Nozay <damien /dot nozay /at gmail.com>
---
diff -u -r -X nodiff syslinux-3.82-orig/core/comboot.inc
syslinux-3.82/core/comboot.inc
--- syslinux-3.82-orig/core/comboot.inc    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/comboot.inc    2009-07-27 11:23:23.000000000 -0700
@@ -1045,5 +1064,6 @@
         section .bss1
         alignb 4
 DOSErrTramp    resd    33        ; Error trampolines
+CurrentDirName    resb    DIRNAME_MAX
 ConfigName    resb    FILENAME_MAX
-CurrentDirName    resb    FILENAME_MAX
+
diff -u -r -X nodiff syslinux-3.82-orig/core/extlinux.asm
syslinux-3.82/core/extlinux.asm
--- syslinux-3.82-orig/core/extlinux.asm    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/extlinux.asm    2009-07-24 12:19:45.000000000 -0700
@@ -25,6 +25,8 @@
 ;
 my_id        equ extlinux_id
 ; NASM 0.98.38 croaks if these are equ's rather than macros...
+DIRNAME_MAX_LG2 equ 8            ; log2(Max dirname size Including final null)
+DIRNAME_MAX    equ (1 << DIRNAME_MAX_LG2)
 FILENAME_MAX_LG2 equ 8            ; log2(Max filename size Including
final null)
 FILENAME_MAX    equ (1 << FILENAME_MAX_LG2)    ; Max mangled filename size
 NULLFILE    equ 0            ; Null character == empty filename
diff -u -r -X nodiff syslinux-3.82-orig/core/isolinux.asm
syslinux-3.82/core/isolinux.asm
--- syslinux-3.82-orig/core/isolinux.asm    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/isolinux.asm    2009-07-24 12:19:50.000000000 -0700
@@ -26,6 +26,8 @@
 ; Some semi-configurable constants... change on your own risk.
 ;
 my_id        equ isolinux_id
+DIRNAME_MAX_LG2 equ 8            ; log2(Max dirname size Including final null)
+DIRNAME_MAX    equ (1 << DIRNAME_MAX_LG2)
 FILENAME_MAX_LG2 equ 8            ; log2(Max filename size Including
final null)
 FILENAME_MAX    equ (1 << FILENAME_MAX_LG2)
 NULLFILE    equ 0            ; Zero byte == null file name
diff -u -r -X nodiff syslinux-3.82-orig/core/ldlinux.asm
syslinux-3.82/core/ldlinux.asm
--- syslinux-3.82-orig/core/ldlinux.asm    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/ldlinux.asm    2009-07-24 12:19:56.000000000 -0700
@@ -31,6 +31,8 @@
 ; Some semi-configurable constants... change on your own risk.
 ;
 my_id        equ syslinux_id
+DIRNAME_MAX_LG2 equ 8            ; log2(Max dirname size Including final null)
+DIRNAME_MAX    equ (1 << DIRNAME_MAX_LG2)
 FILENAME_MAX_LG2 equ 6            ; log2(Max filename size Including
final null)
 FILENAME_MAX    equ (1<<FILENAME_MAX_LG2) ; Max mangled filename size
 NULLFILE    equ 0            ; First char space == null filename
diff -u -r -X nodiff syslinux-3.82-orig/core/parsecmd.inc
syslinux-3.82/core/parsecmd.inc
--- syslinux-3.82-orig/core/parsecmd.inc    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/parsecmd.inc    2009-07-24 14:58:07.000000000 -0700
@@ -130,5 +130,5 @@
 KernelCName     resb FILENAME_MAX    ; Unmangled kernel name
 InitRDCName     resb FILENAME_MAX    ; Unmangled initrd name
 %endif
-MNameBuf        resb FILENAME_MAX
-InitRD          resb FILENAME_MAX
+MNameBuf        resb DIRNAME_MAX
+InitRD          resb DIRNAME_MAX
diff -u -r -X nodiff syslinux-3.82-orig/core/pxelinux.asm
syslinux-3.82/core/pxelinux.asm
--- syslinux-3.82-orig/core/pxelinux.asm    2009-06-09 10:19:25.000000000 -0700
+++ syslinux-3.82/core/pxelinux.asm    2009-07-27 10:13:37.000000000 -0700
@@ -29,6 +29,8 @@
 ; Some semi-configurable constants... change on your own risk.
 ;
 my_id        equ pxelinux_id
+DIRNAME_MAX_LG2 equ 8            ; log2(Max dirname size Including final null)
+DIRNAME_MAX    equ (1 << DIRNAME_MAX_LG2)
 FILENAME_MAX_LG2 equ 7            ; log2(Max filename size Including
final null)
 FILENAME_MAX    equ (1 << FILENAME_MAX_LG2)
 NULLFILE    equ 0            ; Zero byte == null file name
@@ -164,9 +166,10 @@
         alignb open_file_t_size
 Files        resb MAX_OPEN*open_file_t_size

+        alignb DIRNAME_MAX
         alignb FILENAME_MAX
-BootFile    resb 256        ; Boot file from DHCP packet
-PathPrefix    resb 256        ; Path prefix derived from boot file
+PathPrefix    resb DIRNAME_MAX        ; Path prefix derived from boot file
+BootFile    resb FILENAME_MAX        ; Boot file from DHCP packet
 DotQuadBuf    resb 16            ; Buffer for dotted-quad IP address
 IPOption    resb 80            ; ip= option buffer
 InitStack    resd 1            ; Pointer to reset stack (SS:SP)
---end


---
from: Damien Nozay
[PATCH 03/04] add -p modulepath option to mboot.c

when using pxelinux, complex paths can be used in conjunction with the prefix we
get from tftp (e.g. /tftpboot/linux-install/). without a path option,
the modules need to
use paths relative to the prefix, this can be inconvenient and clutter
the command line.
with this change it is possible to do:
* kernel /zzz/zzzzzz/zzzzz/mboot.c32
* append -p /some/module/path kernel.gz --- module1.gz --- module2.gz
instead of:
* kernel /zzz/zzzzzz/zzzzz/mboot.c32
* append /some/module/path/kernel.gz --- /some/module/path/module1.gz
--- /some/module/path/module2.gz

signed-off-by: Damien Nozay <damien /dot nozay /at gmail.com>
---
diff -u -r -X nodiff syslinux-3.82-orig/com32/mboot/mboot.c
syslinux-3.82/com32/mboot/mboot.c
--- syslinux-3.82-orig/com32/mboot/mboot.c    2009-06-09
10:19:25.000000000 -0700
+++ syslinux-3.82/com32/mboot/mboot.c    2009-07-27 12:19:27.000000000 -0700
@@ -38,12 +38,18 @@
 struct syslinux_pm_regs regs;
 struct my_options opt;

+char pxelinuxpath[1024];
+
 struct module_data {
   void *data;
   size_t len;
   const char *cmdline;
 };

+static void restorepath(void) {
+   chdir(pxelinuxpath);
+}
+
 static int map_modules(struct module_data *modules, int nmodules)
 {
   struct mod_list *mod_list;
@@ -96,6 +102,7 @@
   int module_count = 1;
   int arglen;
   const char module_separator[] = "---";
+  char cwd[1024];

   for (argp = argv; *argp; argp++) {
     if (!strcmp(*argp, module_separator))
@@ -109,10 +116,13 @@
   }

   argp = argv;
+
+  getcwd(cwd, sizeof(cwd));
+
   while (*argp) {
     /* Note: it seems Grub transparently decompresses all compressed files,
        not just the primary kernel. */
-    printf("Loading %s... ", *argp);
+    printf("Loading (cwd=%s) %s... ", cwd, *argp);
     rv = zloadfile(*argp, &mp->data, &mp->len);

     if (rv) {
@@ -150,9 +160,10 @@

 int main(int argc, char *argv[])
 {
-  int nmodules;
+  int nmodules, len;
   struct module_data *modules;
   bool keeppxe = false;
+  char modulepath[1024], *str;

   openconsole(&dev_null_r, &dev_stdcon_w);

@@ -160,11 +171,27 @@
   argv++;

   while (*argv) {
-    if (!strcmp(*argv, "-solaris"))
+    if (!strcmp(*argv, "-solaris")) {
       opt.solaris = true;
-    else if (!strcmp(*argv, "-aout"))
+    } else if (!strcmp(*argv, "-aout")) {
       opt.aout = true;
-    else
+    } else if (!strcmp(*argv, "-p")) {
+      argv++;
+      getcwd(pxelinuxpath, sizeof(pxelinuxpath));
+      atexit(restorepath);
+      strcpy(modulepath, pxelinuxpath);
+      len = strlen(modulepath);
+      if (len && modulepath[len-1] == '/') {
+         modulepath[len-1] = 0;
+      }
+      strcat(modulepath, *argv);
+      len = strlen(modulepath);
+      if (len && modulepath[len-1] != '/') {
+         modulepath[len] = '/';
+         modulepath[len+1] = 0;
+      }
+      chdir(modulepath);
+    } else
       break;
     argv++;
   }
---end


---
from: Damien Nozay
[PATCH 04/04] menu miscellanous glitch

correct small glitch when displaying the command ([TAB]) that is very long.
The glitch is that it displays the same chunks of the command line twice.

signed-off-by: Damien Nozay <damien /dot nozay /at gmail.com>
---
diff -u -r -X nodiff syslinux-3.82-orig/com32/menu/menumain.c
syslinux-3.82/com32/menu/menumain.c
--- syslinux-3.82-orig/com32/menu/menumain.c    2009-06-09
10:19:25.000000000 -0700
+++ syslinux-3.82/com32/menu/menumain.c    2009-07-15 11:18:42.000000000 -0700
@@ -448,8 +448,8 @@
       /* Redraw the command line */
       printf("\033[?25l\033[%d;1H\1#9> \2#10%s",
          CMDLINE_ROW, pad_line(cmdline, 0, max(len, prev_len)));
-      printf("\2#10\033[%d;3H%s\033[?25h",
-         CMDLINE_ROW, pad_line(cmdline, 0, cursor));
+//      printf("\2#10\033[%d;3H%s\033[?25h",
+//         CMDLINE_ROW, pad_line(cmdline, 0, cursor));
       prev_len = len;
       redraw = 0;
     }
---end




More information about the Syslinux mailing list