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, ®s, ®s);
+
+??? 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