Michael Walker
2006-May-25 22:53 UTC
[syslinux] pxelinux/mboot confused about e820 memory maps on HP Proliant BIOS's
All, When attempting to pxeboot the latest Xen3.0 hypervisor/kernel it was failing with the following error: ------ \ \/ /___ _ __ |___ / / _ \ _ _ _ __ ___| |_ __ _| |__ | | ___ \ // _ \ '_ \ |_ \| | | |__| | | | '_ \/ __| __/ _` | '_ \| |/ _ \ / \ __/ | | | ___) | |_| |__| |_| | | | \__ \ || (_| | |_) | | __/ /_/\_\___|_| |_| |____(_)___/ \__,_|_| |_|___/\__\__,_|_.__/|_|\___| cl.cam.ac.uk/netos/xen University of Cambridge Computer Laboratory Xen version 3.0-unstable (root at rc.cassatt.com) (gcc version 3.4.3 20050227 (Red Hat 3.4.3-22.1)) Thu May 18 14:14:42 PDT 2006 Latest ChangeSet: Wed May 17 23:15:36 2006 +0100 10005:86d8246c6aff (XEN) Command line: kernels/xen-debug.gz console=vga (XEN) WARNING: Buggy e820 map detected and fixed (truncated length fields). (XEN) Physical RAM map: (XEN) Not enough memory to stash the DOM0 kernel image. ... ------ After some diagnosing this turned out to be a problem with mboot and the HP Proliant DL360 & HP Proliant DL380 systems we have. When mboot was querying the BIOS for their E820 memory maps they were getting gobbly gook and not the proper memory maps. We did not see this problem with our Dell Proliant 1750's. I found a fix which I've applied to mboot.c32 and it seems to fix the problem. The issue is that the regs_in struct passed into the INT15/E820 call the full register structure was not being cleared. Although the mboot.c code does clearly set the designated fields for the e820 interrupt apparently the HP bios's can do strange things depending upon the value of the unspecified register fields. The regs_in struct is local variable and hence has random fields based off of the stack. The fix below simply does a 'memset(®s_in, 0, sizeof (regs_in))' to clear the fields. Also included in the diffs below are changes to permit the syslinux package to build on the latest Fedora Core 5 release. They should make no functional change - but reflect that CLK_TCK is not visible by default (some Xopen/Posix stuff I think). Please consider these changes for inclusion into the next release of syslinux/pxelinux/mboot. Thanx Much, _Mike_ --- Michael Walker Software Developer Cassatt Corporation, San Jose, CA ---------------------------- --- baseline-syslinux/./syslinux-3.11/com32/modules/mboot.c 2006-05-25 14:03:32.000000000 -0700 +++ fixed-syslinux/./syslinux-3.11/com32/modules/mboot.c 2006-05-25 14:03:04.000000000 -0700 @@ -362,6 +362,7 @@ e820->size = sizeof(*e820) - sizeof(e820->size); /* Ask the BIOS to fill in this descriptor */ + memset(®s_in, 0, sizeof (regs_in)); regs_in.eax.l = 0xe820; /* "Get system memory map" */ regs_in.ebx.l = regs_out.ebx.l; /* Continuation value from last call */ regs_in.ecx.l = 20; /* Size of buffer to write into */ --- baseline-syslinux/./syslinux-3.11/com32/samples/keytest.c 2006-05-25 14:03:32.000000000 -0700 +++ fixed-syslinux/./syslinux-3.11/com32/samples/keytest.c 2006-05-25 14:03:03.000000000 -0700 @@ -72,7 +72,7 @@ { console_ansi_raw(); - printf("CLK_TCK = %d\n", (int)CLK_TCK); + printf("CLOCKS_PER_SEC = %d\n", (int)CLOCKS_PER_SEC); printf("Press keys, end with Ctrl-C...\n"); for (;;) { --- baseline-syslinux/./syslinux-3.11/com32/libutil/get_key.c 2006-05-25 14:03:31.000000000 -0700 +++ fixed-syslinux/./syslinux-3.11/com32/libutil/get_key.c 2006-05-25 14:03:01.000000000 -0700 @@ -116,7 +116,7 @@ }; #define NCODES ((int)(sizeof keycodes/sizeof(struct keycode))) -#define KEY_TIMEOUT ((CLK_TCK+9)/10) +#define KEY_TIMEOUT ((CLOCKS_PER_SEC+9)/10) int get_key(FILE *f, clock_t timeout) { --- baseline-syslinux/./syslinux-3.11/com32/include/sys/times.h 2006-05-25 14:03:31.000000000 -0700 +++ fixed-syslinux/./syslinux-3.11/com32/include/sys/times.h 2006-05-25 14:03:02.000000000 -0700 @@ -13,6 +13,7 @@ #define HZ 18 /* Piddly resolution... */ #define CLK_TCK HZ +#define CLOCKS_PER_SEC HZ typedef uint16_t clock_t;