diff options
author | Matt Fleming <matt.fleming@intel.com> | 2012-11-14 10:50:27 +0000 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2012-11-14 10:50:27 +0000 |
commit | 4c7278413ef068bd8239fd8a6c69d64bd2c0a385 (patch) | |
tree | 4c39e8872de7babc24bed9fe528df28c8d82d427 | |
parent | 749297b070d1fe3d82fd9e5c4306b4aaf257f2a1 (diff) | |
parent | 348ae6af01350a9a46f3076a2facd27918f0f603 (diff) | |
download | syslinux-4c7278413ef068bd8239fd8a6c69d64bd2c0a385.tar.gz |
Merge tag 'syslinux-5.00-pre10' into for-hpa/elflink/firmware
Pull in the latest prerelease that includes some bug fixes for ldlinux
and a realloc() bug in core/.
Conflicts:
com32/cmenu/Makefile
com32/elflink/ldlinux/Makefile
com32/lib/Makefile
core/pxelinux.asm
31 files changed, 674 insertions, 174 deletions
@@ -30,6 +30,7 @@ \#* .\#* .depend +/com32/lib/errlist.c /com32/lib/sys/vesa/alphatbl.c /diag/geodsp/mk-lba-img /extlinux/extlinux diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile index 80fff368..7ff1ff6e 100644 --- a/com32/cmenu/Makefile +++ b/com32/cmenu/Makefile @@ -40,7 +40,7 @@ MENUS = $(LIBS) $(subst $(SRC)/,,$(CMENUS) $(IMENUS)) .PRECIOUS: %.c %.c: %.menu adv_menu.tpl - python $(SRC)/menugen.py --input=$< --output=$@ --template=$(SRC)/adv_menu.tpl + $(PYTHON) $(SRC)/menugen.py --input=$< --output=$@ --template=$(SRC)/adv_menu.tpl all: makeoutputdirs menus diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile index 58fc9c94..7da6e287 100644 --- a/com32/elflink/ldlinux/Makefile +++ b/com32/elflink/ldlinux/Makefile @@ -13,7 +13,7 @@ VPATH = $(SRC) include $(MAKEDIR)/elf.mk -CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include +CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib LIBS = --whole-archive $(objdir)/com32/lib/libcom32min.a OBJS = ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o adv.o \ diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index a1cf50cc..ebeaeece 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -13,6 +13,7 @@ #include <sys/exec.h> #include <sys/module.h> #include <dprintf.h> +#include <core.h> #include "getkey.h" #include "menu.h" @@ -340,9 +341,16 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , case KEY_UP: { if (!list_empty(&cli_history_head)) { + struct list_head *next; + + if (!comm_counter) + next = cli_history_head.next; + else + next = comm_counter->list.next; + comm_counter = - list_entry(comm_counter->list.next, - typeof(*comm_counter), list); + list_entry(next, typeof(*comm_counter), list); + if (&comm_counter->list == &cli_history_head) { strcpy(cmdline, temp_cmdline); } else { @@ -357,9 +365,16 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , case KEY_DOWN: { if (!list_empty(&cli_history_head)) { + struct list_head *prev; + + if (!comm_counter) + prev = cli_history_head.prev; + else + prev = comm_counter->list.prev; + comm_counter = - list_entry(comm_counter->list.prev, - typeof(*comm_counter), list); + list_entry(prev, typeof(*comm_counter), list); + if (&comm_counter->list == &cli_history_head) { strcpy(cmdline, temp_cmdline); } else { @@ -407,6 +422,15 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , redraw = 1; break; } + case KEY_CTRL('V'): + if (BIOSName) + eprintf("%s%s%s", syslinux_banner, + MK_PTR(0, BIOSName), copyright_str); + else + eprintf("%s%s", syslinux_banner, copyright_str); + + redraw = 1; + break; default: if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) { diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h index ea4736e6..63e33b69 100644 --- a/com32/elflink/ldlinux/config.h +++ b/com32/elflink/ldlinux/config.h @@ -47,6 +47,6 @@ extern int new_linux_kernel(char *okernel, char *ocmdline); extern void pm_load_high(com32sys_t *regs); -extern void ldlinux_enter_command(bool prompt); +extern void ldlinux_enter_command(void); #endif /* __CONFIG_H__ */ diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c index e7969c2e..6ccde49d 100644 --- a/com32/elflink/ldlinux/execute.c +++ b/com32/elflink/ldlinux/execute.c @@ -102,7 +102,7 @@ void execute(const char *cmdline, uint32_t type) * e.g. from vesamenu.c32. */ unload_modules_since("ldlinux.c32"); - ldlinux_enter_command(!noescape); + ldlinux_enter_command(); } else if (type == IMAGE_TYPE_CONFIG) { char *argv[] = { "ldlinux.c32", NULL }; diff --git a/com32/elflink/ldlinux/get_key.c b/com32/elflink/ldlinux/get_key.c index 0be06b98..123171ae 100644 --- a/com32/elflink/ldlinux/get_key.c +++ b/com32/elflink/ldlinux/get_key.c @@ -41,6 +41,7 @@ #include <sys/times.h> #include <getkey.h> #include <libutil.h> +#include <sys/file.h> struct keycode { int code; @@ -146,6 +147,25 @@ int get_key_decode(char *buffer, int nc, int *code) return rv; } +#ifdef __COM32__ +extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count); + +int raw_read(int fd, void *buf, size_t count) +{ + (void)fd; + + /* + * Instead of using the read(2) stdlib function use + * __rawcon_read() directly since we want a single key and + * don't want any processing/batching of the user input to + * occur - we want the raw data. + */ + return __rawcon_read(NULL, buf, count); +} +#else +extern int raw_read(int fd, void *buf, size_t count); +#endif + int get_key(FILE * f, clock_t timeout) { char buffer[KEY_MAXLEN]; @@ -162,7 +182,7 @@ int get_key(FILE * f, clock_t timeout) nc = 0; start = times(NULL); do { - rv = read(fileno(f), &ch, 1); + rv = raw_read(fileno(f), &ch, 1); if (rv == 0 || (rv == -1 && errno == EAGAIN)) { clock_t lateness = times(NULL) - start; if (nc && lateness > 1 + KEY_TIMEOUT) { diff --git a/com32/elflink/ldlinux/kernel.c b/com32/elflink/ldlinux/kernel.c index b8f9cb8d..1cfb6508 100644 --- a/com32/elflink/ldlinux/kernel.c +++ b/com32/elflink/ldlinux/kernel.c @@ -29,10 +29,6 @@ int new_linux_kernel(char *okernel, char *ocmdline) cmdline = cmdline_buf; temp = cmdline; - /* - strcpy(temp, "BOOT_IMAGE="); - temp += 11; - */ if (okernel) kernel_name = okernel; @@ -42,36 +38,12 @@ int new_linux_kernel(char *okernel, char *ocmdline) strcpy(temp, kernel_name); temp += strlen(kernel_name); - /* in elflink branch, KernelCName no more exist */ - /* - else { - strcpy(temp, KernelCName); - temp += strlen(KernelCName); - kernel_name = KernelCName; - } - */ - *temp = ' '; temp++; if (ocmdline) strcpy(temp, ocmdline); else if (append) strcpy(temp, append); - /* - else if (*(char *)CmdOptPtr) - strcpy(temp, (char *)CmdOptPtr); - else if (AppendLen) { - for (i = 0; i < AppendLen; i++) - *temp++ = AppendBuf[i]; - *temp = '\0'; - } - */ - - printf("cmdline = %s\n", cmdline); - /* - printf("VkernelEnd = %x\n", VKernelEnd); - printf("HighMemSize = %x\n", __com32.cs_memsize); - */ /* "keeppxe" handling */ #if IS_PXELINUX @@ -90,7 +62,7 @@ int new_linux_kernel(char *okernel, char *ocmdline) if (loadfile(kernel_name, &kernel_data, &kernel_len)) { if (opt_quiet) printf("Loading %s ", kernel_name); - printf("failed!\n"); + printf("failed: "); goto bail; } @@ -121,7 +93,7 @@ int new_linux_kernel(char *okernel, char *ocmdline) if (initramfs_load_archive(initramfs, initrd_name)) { if (opt_quiet) printf("Loading %s ", initrd_name); - printf("failed!\n"); + printf("failed: "); goto bail; } @@ -132,8 +104,9 @@ int new_linux_kernel(char *okernel, char *ocmdline) /* This should not return... */ syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, cmdline); + printf("Booting kernel failed: "); bail: - printf("Kernel load failure (insufficient memory?)\n"); + printf("%s\n", strerror(errno)); return 1; } diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c index d9635956..59c55980 100644 --- a/com32/elflink/ldlinux/ldlinux.c +++ b/com32/elflink/ldlinux/ldlinux.c @@ -216,41 +216,36 @@ static void enter_cmdline(void) printf("\n"); /* return if user only press enter or we timed out */ - if (!cmdline || cmdline[0] == '\0') + if (!cmdline || cmdline[0] == '\0') { + if (ontimeoutlen) + load_kernel(ontimeout); return; + } load_kernel(cmdline); } } -void ldlinux_enter_command(bool prompt) +/* + * If this function returns you must call ldinux_enter_command() to + * preserve the 4.0x behaviour. + */ +void ldlinux_auto_boot(void) { - const char *cmdline = default_cmd; - - if (prompt) - goto cmdline; -auto_boot: - /* - * Auto boot - */ - if (defaultlevel || noescape) { - if (defaultlevel) { - load_kernel(cmdline); /* Shouldn't return */ - } else { + if (!defaultlevel) { + if (strlen(ConfigName)) printf("No DEFAULT or UI configuration directive found!\n"); + if (noescape) + kaboom(); + } else + load_kernel(default_cmd); +} - if (noescape) - kaboom(); - } - } - -cmdline: - /* Only returns if the user pressed enter or input timed out */ +void ldlinux_enter_command(void) +{ + if (noescape) + ldlinux_auto_boot(); enter_cmdline(); - - cmdline = ontimeoutlen ? ontimeout : default_cmd; - - goto auto_boot; } /* @@ -291,7 +286,7 @@ int main(int argc __unused, char **argv __unused) cmdline = dst = malloc(count + 1); if (!dst) { printf("Failed to allocate memory for ADV\n"); - ldlinux_enter_command(true); + ldlinux_enter_command(); } for (i = 0; i < count; i++) @@ -303,11 +298,16 @@ int main(int argc __unused, char **argv __unused) syslinux_adv_write(); load_kernel(cmdline); /* Shouldn't return */ - ldlinux_enter_command(true); + ldlinux_enter_command(); } /* TODO: Check KbdFlags? */ + if (!forceprompt) + ldlinux_auto_boot(); + + if (defaultlevel > 1) + ldlinux_auto_boot(); - ldlinux_enter_command(forceprompt); + ldlinux_enter_command(); return 0; } diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c index 1db397a1..2fa0641e 100644 --- a/com32/elflink/ldlinux/readconfig.c +++ b/com32/elflink/ldlinux/readconfig.c @@ -1420,7 +1420,10 @@ void parse_configs(char **argv) current_menu = root_menu; if (!argv || !*argv) { - parse_one_config(NULL); + if (parse_one_config(NULL) < 0) { + printf("WARNING: No configuration file found\n"); + return; + } } else { while ((filename = *argv++)) { dprintf("Parsing config: %s", filename); diff --git a/com32/lib/Makefile b/com32/lib/Makefile index eb0d6124..81e6fcd1 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -106,7 +106,7 @@ libcom32core.a : $(CORELIBOBJS) $(RANLIB) $@ tidy dist clean: - rm -f sys/vesa/alphatbl.c + rm -f sys/vesa/alphatbl.c errlist.c find . \( -name \*.o -o -name \*.a -o -name .\*.d -o -name \*.tmp \) -print0 | \ xargs -0r rm -f @@ -120,6 +120,9 @@ install: all -rm -rf $(INSTALLROOT)$(COM32DIR)/include cp -r $(SRC)/../include $(INSTALLROOT)$(COM32DIR) +errlist.c: makeerrlist.pl $(SRC)/../include/errno.h + $(PERL) $< $(CFLAGS) -errlist > $@ || rm -f $@ + # These files are performance critical, and doesn't compile well with -Os #FIXME: determine if drawtxt.c is really EFI-dependent #ifndef EFI_BUILD diff --git a/com32/lib/elf32.ld b/com32/lib/elf32.ld index ddf6e048..16d10a38 100644 --- a/com32/lib/elf32.ld +++ b/com32/lib/elf32.ld @@ -75,17 +75,6 @@ SECTIONS { KEEP (*(.preinit_array)) } - .init_array : - { - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - } - .fini_array : - { - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - } - .ctors : { __ctors_start = .; @@ -93,6 +82,8 @@ SECTIONS KEEP (*(.ctors)) KEEP (*(.ctors_modinit)) KEEP (*(.ctors_modmain)) + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) __ctors_end = .; } @@ -102,6 +93,8 @@ SECTIONS KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) KEEP (*(.dtors_modexit)) + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) __dtors_end = .; } diff --git a/com32/lib/init.h b/com32/lib/init.h deleted file mode 100644 index 2d983427..00000000 --- a/com32/lib/init.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * init.h - * - * Magic to set up initializers - */ - -#ifndef _INIT_H -#define _INIT_H 1 - -#include <inttypes.h> - -#define COM32_INIT(x) static const void * const __COM32_INIT \ - __attribute__((section(".init_array"),unused)) = (const void * const)&x - -#endif /* _INIT_H */ diff --git a/com32/lib/makeerrlist.pl b/com32/lib/makeerrlist.pl new file mode 100644 index 00000000..9243b9dd --- /dev/null +++ b/com32/lib/makeerrlist.pl @@ -0,0 +1,98 @@ +#!/usr/bin/perl +# +# This creates sys_errlist from <asm/errno.h> through somewhat +# heuristic matching. It presumes the relevant entries are of the form +# #define Exxxx <integer> /* comment */ +# + +use FileHandle; + +%errors = (); +%errmsg = (); +$maxerr = -1; +@includelist = (); # Include directories + +sub parse_file($) { + my($file) = @_; + my($fh) = new FileHandle; + my($line, $error, $msg); + my($kernelonly) = 0; + my($root); + + print STDERR "opening $file\n" unless ( $quiet ); + + $ok = 0; + foreach $root ( @includelist ) { + if ( $fh->open($root.'//'.$file, '<') ) { + $ok = 1; + last; + } + } + + if ( ! $ok ) { + die "$0: Cannot find file $file\n"; + } + + while ( defined($line = <$fh>) ) { + if ( $kernelonly ) { + if ( $line =~ /^\#\s*endif/ ) { + $kernelonly--; + } elsif ( $line =~ /^\#\sif/ ) { + $kernelonly++; + } + } else { + if ( $line =~ /^\#\s*define\s+([A-Z0-9_]+)\s+([0-9]+)\s*\/\*\s*(.*\S)\s*\*\// ) { + $error = $1; + $errno = $2+0; + $msg = $3; + print STDERR "$error ($errno) => \"$msg\"\n" unless ( $quiet ); + $errors{$errno} = $error; + $errmsg{$errno} = $msg; + $maxerr = $errno if ( $errno > $maxerr ); + } elsif ( $line =~ /^\#\s*include\s+[\<\"](.*)[\>\"]/ ) { + parse_file($1); + } elsif ( $line =~ /^\#\s*ifdef\s+__KERNEL__/ ) { + $kernelonly++; + } + } + } + close($fh); + print STDERR "closing $file\n" unless ( $quiet ); +} + +$v = $ENV{'KBUILD_VERBOSE'}; +$quiet = defined($v) ? !$v : 0; + +foreach $arg ( @ARGV ) { + if ( $arg eq '-q' ) { + $quiet = 1; + } elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) { + $type = $arg; + } elsif ( $arg =~ '^\-I' ) { + push(@includelist, "$'"); + } else { + # Ignore + } +} + +parse_file('errno.h'); + +if ( $type eq '-errlist' ) { + print "#include <errno.h>\n"; + printf "const int sys_nerr = %d;\n", $maxerr+1; + printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; + foreach $e ( sort(keys(%errors)) ) { + printf " [%s] = \"%s\",\n", $errors{$e}, $errmsg{$e}; + } + print "};\n"; +} elsif ( $type eq '-errnos' ) { + print "#include <errno.h>\n"; + printf "const int sys_nerr = %d;\n", $maxerr+1; + printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; + foreach $e ( sort(keys(%errors)) ) { + printf " [%s] = \"%s\",\n", $errors{$e}, $errors{$e}; + } + print "};\n"; +} elsif ( $type eq '-maxerr' ) { + print $maxerr, "\n"; +} diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c index ec103ab3..ce35f3d1 100644 --- a/com32/lib/malloc.c +++ b/com32/lib/malloc.c @@ -8,7 +8,6 @@ #include <string.h> #include <com32.h> #include <syslinux/memscan.h> -#include "init.h" #include "malloc.h" struct free_arena_header __malloc_head = { diff --git a/com32/lib/strerror.c b/com32/lib/strerror.c index 8dbe74ad..1b3d4452 100644 --- a/com32/lib/strerror.c +++ b/com32/lib/strerror.c @@ -6,18 +6,26 @@ char *strerror(int errnum) { - static char message[32] = "error "; /* enough for error 2^63-1 */ + static char message[32] = "error "; /* enough for error 2^63-1 */ + char numbuf[32]; + char *p; + unsigned int e = (unsigned int)errnum; - char numbuf[32]; - char *p; + extern const int sys_nerr; + extern const char *const sys_errlist[]; - p = numbuf + sizeof numbuf; - *--p = '\0'; + if (e < (unsigned int)sys_nerr && sys_errlist[e]) + return (char *)sys_errlist[e]; - do { - *--p = (errnum % 10) + '0'; - errnum /= 10; - } while (errnum); + p = numbuf + sizeof numbuf; + *--p = '\0'; - return (char *)memcpy(message + 6, p, (numbuf + sizeof numbuf) - p); + do { + *--p = (e % 10) + '0'; + e /= 10; + } while (e); + + memcpy(message + 6, p, (numbuf + sizeof numbuf) - p); + + return message; } diff --git a/com32/lib/syslinux/initramfs_file.c b/com32/lib/syslinux/initramfs_file.c index 763eff28..7eb55b5e 100644 --- a/com32/lib/syslinux/initramfs_file.c +++ b/com32/lib/syslinux/initramfs_file.c @@ -65,7 +65,7 @@ static size_t initramfs_mkdirs(const char *filename, void *buffer, const char *p = filename; char *bp = buffer; int len; - size_t bytes = 0; + size_t bytes = 0, hdr_sz; int pad; while ((p = strchr(p, '/'))) { @@ -81,15 +81,17 @@ static size_t initramfs_mkdirs(const char *filename, void *buffer, while ((p = strchr(p, '/'))) { if (p != filename && p[-1] != '/') { len = p - filename; + hdr_sz = ((sizeof(struct cpio_header) + len + 1) + 3) & ~3; bp += sprintf(bp, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x" "%08x%08x%08x%08x", next_ino++, S_IFDIR | 0755, 0, 0, 1, 0, 0, 0, 1, 0, 1, len + 1, 0); memcpy(bp, filename, len); bp += len; - pad = (-(sizeof(struct cpio_header) + len) & 3) + 1; + pad = hdr_sz - (sizeof(struct cpio_header) + len); memset(bp, 0, pad); bp += pad; } + p++; } } @@ -104,7 +106,7 @@ int initramfs_mknod(struct initramfs *ihead, const char *filename, int do_mkdir, uint16_t mode, size_t len, uint32_t major, uint32_t minor) { - size_t bytes; + size_t bytes, hdr_sz; int namelen = strlen(filename); int pad; char *buffer, *bp; @@ -114,7 +116,8 @@ int initramfs_mknod(struct initramfs *ihead, const char *filename, else bytes = 0; - bytes += ((sizeof(struct cpio_header) + namelen + 1) + 3) & ~3; + hdr_sz = ((sizeof(struct cpio_header) + namelen + 1) + 3) & ~3; + bytes += hdr_sz; bp = buffer = malloc(bytes); if (!buffer) @@ -127,8 +130,8 @@ int initramfs_mknod(struct initramfs *ihead, const char *filename, "%08x%08x%08x%08x", next_ino++, mode, 0, 0, 1, 0, len, 0, 1, major, minor, namelen + 1, 0); memcpy(bp, filename, namelen); - bp += len; - pad = (-(sizeof(struct cpio_header) + namelen) & 3) + 1; + bp += namelen; + pad = hdr_sz - (sizeof(struct cpio_header) + namelen); memset(bp, 0, pad); if (initramfs_add_data(ihead, buffer, bytes, bytes, 4)) { diff --git a/com32/libutil/ansiraw.c b/com32/libutil/ansiraw.c index 2afd48a7..b67768c5 100644 --- a/com32/libutil/ansiraw.c +++ b/com32/libutil/ansiraw.c @@ -47,6 +47,7 @@ void console_ansi_raw(void) #include <stdio.h> #include <termios.h> +#include <unistd.h> static struct termios original_termios_settings; @@ -82,4 +83,22 @@ void console_ansi_raw(void) tcsetattr(0, TCSAFLUSH, &tio); } +int raw_read(int fd, void *buf, size_t count) +{ + struct termios tio, rtio; + int rv; + + tcgetattr(fd, &tio); + + cfmakeraw(&rtio); + tcsetattr(fd, 0, &rtio); + + rv = read(fd, buf, count); + + /* Restore settings */ + tcsetattr(fd, 0, &tio); + + return rv; +} + #endif diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c index cffe8e3d..3690e480 100644 --- a/com32/menu/readconfig.c +++ b/com32/menu/readconfig.c @@ -189,6 +189,9 @@ static struct menu *new_menu(struct menu *parent, m->menu_master_passwd = refstr_get(parent->menu_master_passwd); m->menu_background = refstr_get(parent->menu_background); + refstr_put(m->title); + m->title = refstr_get(parent->title); + m->color_table = copy_color_table(parent->color_table); for (i = 0; i < 12; i++) { diff --git a/com32/modules/Makefile b/com32/modules/Makefile index d87127dc..e794b3b9 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -23,7 +23,8 @@ MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \ meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \ kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \ ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \ - whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 + whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \ + hexdump.c32 TESTFILES = diff --git a/com32/modules/hexdump.c b/com32/modules/hexdump.c new file mode 100644 index 00000000..bc2c70dd --- /dev/null +++ b/com32/modules/hexdump.c @@ -0,0 +1,245 @@ +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <console.h> +#include <errno.h> +#include <syslinux/loadfile.h> + +/* Macros */ +#define ROWS_PER_PAGE 24 +#define COLS_PER_ROW 16 +#define BYTES_PER_PAGE (ROWS_PER_PAGE * COLS_PER_ROW) + +/* Functions declarations */ +static int usage(void); +static void eat_stdin(void); +static int do_page(void); +static void hexdump(const void *memory, size_t bytes); + +/* Objects */ +static const char *prog_name; +static int opt_page; +static int opt_no_buffer; +static int opt_extended_ascii; + +int main(int argc, char **argv) +{ + int rc; + const char *filename; + int i; + void *file_data; + size_t file_sz; + FILE *f; + size_t len; + const char *cur_pos; + + /* Assume failure */ + rc = EXIT_FAILURE; + + /* Determine the program name, as invoked */ + if (argc < 1 || !argv || !argv[0]) { + fprintf(stderr, "argc or argv failure!\n"); + goto err_prog_name; + } + prog_name = argv[0]; + + /* Process arguments */ + filename = NULL; + for (i = 1; i < argc; ++i) { + if (!argv[i]) { + fprintf(stderr, "argc and argv mismatch!\n"); + goto err_argv; + } + + if (!strncmp(argv[i], "--page", sizeof "--page") || + !strncmp(argv[i], "-p", sizeof "-p")) { + opt_page = 1; + continue; + } + + if (!strncmp(argv[i], "--no-buffer", sizeof "--no-buffer")) { + opt_no_buffer = 1; + continue; + } + + if (!strncmp(argv[i], "--extended-ascii", sizeof "--extended-ascii")) { + opt_extended_ascii = 1; + continue; + } + + if (!strncmp(argv[i], "--help", sizeof "--help") || + !strncmp(argv[i], "-h", sizeof "-h") || + !strncmp(argv[i], "-?", sizeof "-?")) + return usage(); + + /* Otherwise, interpret as a filename, but only accept one */ + if (filename) + return usage(); + filename = argv[i]; + } + if (!filename) + return usage(); + fprintf(stdout, "Dumping file: %s\n", filename); + + /* Either fetch the whole file, or just allocate a buffer */ + f = NULL; + if (opt_no_buffer) { + errno = 0; + if (loadfile(filename, &file_data, &file_sz)) { + fprintf(stderr, "Couldn't load file. Error: %d\n", errno); + goto err_file_data; + } + } else { + file_sz = BYTES_PER_PAGE; + file_data = malloc(file_sz); + if (!file_data) { + fprintf(stderr, "Couldn't allocate file data buffer\n"); + goto err_file_data; + } + errno = 0; + f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Couldn't open file. Error: %d\n", errno); + goto err_f; + } + } + + /* Dump the data */ + len = BYTES_PER_PAGE; + cur_pos = file_data; + do { + if (f) { + /* Buffered */ + len = fread(file_data, 1, file_sz, f); + cur_pos = file_data; + } else { + /* Non-buffered */ + if (file_sz < len) + len = file_sz; + } + if (!len) + break; + + hexdump(cur_pos, len); + + /* Pause, if requested */ + if (opt_page) { + /* The user might choose to quit */ + if (do_page()) + break; + } + + /* Reduce file_sz for non-buffered mode */ + if (!f) + file_sz -= len; + } while (cur_pos += len); + + rc = EXIT_SUCCESS; + + if (f) + fclose(f); + err_f: + + free(file_data); + err_file_data: + + err_argv: + + err_prog_name: + + return rc; +} + +static int usage(void) +{ + static const char usage[] = + "Usage: %s [<option> [...]] <filename> [<option> [...]]\n" + "\n" + "Options: -p\n" + " --page . . . . . . . Pause output every 24 lines\n" + " --no-buffer . . . . Load the entire file before dumping\n" + " --extended-ascii . . Use extended ASCII chars in dump\n" + " -?\n" + " -h\n" + " --help . . . . . . Display this help\n"; + + fprintf(stderr, usage, prog_name); + return EXIT_FAILURE; +} + +static void eat_stdin(void) +{ + int i; + + while (1) { + i = fgetc(stdin); + if (i == EOF || i == '\n') + return; + } +} +static int do_page(void) +{ + int i; + + while (1) { + fprintf(stdout, "Continue? [Y|n]: "); + i = fgetc(stdin); + switch (i) { + case 'n': + case 'N': + eat_stdin(); + return 1; + + case EOF: + fprintf(stderr, "No response. Continuing...\n"); + /* Fall through to "yes" */ + + case 'y': + case 'Y': + eat_stdin(); + case '\n': + return 0; + + default: + fprintf(stderr, "Invalid choice\n"); + eat_stdin(); + } + } +} + +static void hexdump(const void *memory, size_t bytes) +{ + const unsigned char *p, *q; + int i; + + p = memory; + while (bytes) { + q = p; + printf("%p: ", (void *) p); + for (i = 0; i < 16 && bytes; ++i) { + printf("%02X ", *p); + ++p; + --bytes; + } + bytes += i; + while (i < 16) { + printf("XX "); + ++i; + } + printf("| "); + p = q; + for (i = 0; i < 16 && bytes; ++i) { + printf("%c", isprint(*p) && !isspace(*p) ? *p : ' '); + ++p; + --bytes; + } + while (i < 16) { + printf(" "); + ++i; + } + printf("\n"); + } + return; +} diff --git a/com32/modules/linux.c b/com32/modules/linux.c index e4c067ff..f657eab4 100644 --- a/com32/modules/linux.c +++ b/com32/modules/linux.c @@ -48,6 +48,14 @@ #include <syslinux/linux.h> #include <syslinux/pxe.h> +enum ldmode { + ldmode_raw, + ldmode_cpio, + ldmodes +}; + +typedef int f_ldinitramfs(struct initramfs *, char *); + const char *progname = "linux.c32"; /* Find the last instance of a particular command line argument @@ -59,13 +67,34 @@ static char *find_argument(char **argv, const char *argument) char *ptr = NULL; for (arg = argv; *arg; arg++) { - if (!memcmp(*arg, argument, la)) + if (!strncmp(*arg, argument, la)) ptr = *arg + la; } return ptr; } +/* Find the next instance of a particular command line argument */ +static char **find_arguments(char **argv, char **ptr, + const char *argument) +{ + int la = strlen(argument); + char **arg; + + for (arg = argv; *arg; arg++) { + if (!strncmp(*arg, argument, la)) { + *ptr = *arg + la; + break; + } + } + + /* Exhausted all arguments */ + if (!*arg) + return NULL; + + return arg; +} + /* Search for a boolean argument; return its position, or 0 if not present */ static int find_boolean(char **argv, const char *argument) { @@ -109,6 +138,99 @@ static char *make_cmdline(char **argv) return cmdline; } +static f_ldinitramfs ldinitramfs_raw; +static int ldinitramfs_raw(struct initramfs *initramfs, char *fname) +{ + return initramfs_load_archive(initramfs, fname); +} + +static f_ldinitramfs ldinitramfs_cpio; +static int ldinitramfs_cpio(struct initramfs *initramfs, char *fname) +{ + char *target_fname, *p; + int do_mkdir, unmangle, rc; + + /* Choose target_fname based on presence of "@" syntax */ + target_fname = strchr(fname, '@'); + if (target_fname) { + /* Temporarily mangle */ + unmangle = 1; + *target_fname++ = '\0'; + + /* Make parent directories? */ + do_mkdir = !!strchr(target_fname, '/'); + } else { + unmangle = 0; + + /* Forget the source path */ + target_fname = fname; + while ((p = strchr(target_fname, '/'))) + target_fname = p + 1; + + /* The user didn't specify a desired path */ + do_mkdir = 0; + } + + /* + * Load the file, encapsulate it with the desired path, make the + * parent directories if the desired path contains them, add to initramfs + */ + rc = initramfs_load_file(initramfs, fname, target_fname, do_mkdir, 0755); + + /* Unmangle, if needed*/ + if (unmangle) + *--target_fname = '@'; + + return rc; +} + +/* It only makes sense to call this function from main */ +static int process_initramfs_args(char *arg, struct initramfs *initramfs, + const char *kernel_name, enum ldmode mode, + bool opt_quiet) +{ + const char *mode_msg; + f_ldinitramfs *ldinitramfs; + char *p; + + switch (mode) { + case ldmode_raw: + mode_msg = "Loading"; + ldinitramfs = ldinitramfs_raw; + break; + case ldmode_cpio: + mode_msg = "Encapsulating"; + ldinitramfs = ldinitramfs_cpio; + break; + case ldmodes: + default: + return 1; + } + + do { + p = strchr(arg, ','); + if (p) + *p = '\0'; + + if (!opt_quiet) + printf("%s %s... ", mode_msg, arg); + errno = 0; + if (ldinitramfs(initramfs, arg)) { + if (opt_quiet) + printf("Loading %s ", kernel_name); + printf("failed: "); + return 1; + } + if (!opt_quiet) + printf("ok\n"); + + if (p) + *p++ = ','; + } while ((arg = p)); + + return 0; +} + static int setup_data_file(struct setup_data *setup_data, uint32_t type, const char *filename, bool opt_quiet) @@ -142,7 +264,7 @@ int main(int argc, char *argv[]) bool opt_quiet = false; void *dhcpdata; size_t dhcplen; - char **argp, **argl, *arg, *p; + char **argp, **argl, *arg; (void)argc; argp = argv + 1; @@ -207,27 +329,27 @@ int main(int argc, char *argv[]) goto bail; } + /* Process initramfs arguments */ if ((arg = find_argument(argp, "initrd="))) { - do { - p = strchr(arg, ','); - if (p) - *p = '\0'; - - if (!opt_quiet) - printf("Loading %s... ", arg); - errno = 0; - if (initramfs_load_archive(initramfs, arg)) { - if (opt_quiet) - printf("Loading %s ", kernel_name); - printf("failed: "); - goto bail; - } - if (!opt_quiet) - printf("ok\n"); - - if (p) - *p++ = ','; - } while ((arg = p)); + if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw, + opt_quiet)) + goto bail; + } + + argl = argv; + while ((argl = find_arguments(argl, &arg, "initrd+="))) { + argl++; + if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw, + opt_quiet)) + goto bail; + } + + argl = argv; + while ((argl = find_arguments(argl, &arg, "initrdfile="))) { + argl++; + if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_cpio, + opt_quiet)) + goto bail; } /* Append the DHCP info */ @@ -246,24 +368,28 @@ int main(int argc, char *argv[]) if (!setup_data) goto bail; - for (argl = argv; (arg = *argl); argl++) { - if (!memcmp(arg, "dtb=", 4)) { - if (setup_data_file(setup_data, SETUP_DTB, arg+4, opt_quiet)) - goto bail; - } else if (!memcmp(arg, "blob.", 5)) { - uint32_t type; - char *ep; + argl = argv; + while ((argl = find_arguments(argl, &arg, "dtb="))) { + argl++; + if (setup_data_file(setup_data, SETUP_DTB, arg, opt_quiet)) + goto bail; + } + + argl = argv; + while ((argl = find_arguments(argl, &arg, "blob."))) { + uint32_t type; + char *ep; - type = strtoul(arg + 5, &ep, 10); - if (ep[0] != '=' || !ep[1]) - continue; + argl++; + type = strtoul(arg, &ep, 10); + if (ep[0] != '=' || !ep[1]) + continue; - if (!type) - continue; + if (!type) + continue; - if (setup_data_file(setup_data, type, ep+1, opt_quiet)) - goto bail; - } + if (setup_data_file(setup_data, type, ep+1, opt_quiet)) + goto bail; } /* This should not return... */ diff --git a/core/diskstart.inc b/core/diskstart.inc index 0c27d577..603a6db2 100644 --- a/core/diskstart.inc +++ b/core/diskstart.inc @@ -142,6 +142,7 @@ print_bios: call writestr_early section .earlybss + global BIOSName alignb 2 %define HAVE_BIOSNAME 1 BIOSName resw 1 diff --git a/core/include/core.h b/core/include/core.h index be687f8b..b5dac885 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -30,6 +30,7 @@ extern char cmd_line[]; extern char ConfigFile[]; extern char syslinux_banner[]; extern char copyright_str[]; +extern uint16_t BIOSName; extern char StackBuf[]; extern unsigned int __bcopyxx_len; diff --git a/core/mem/malloc.c b/core/mem/malloc.c index 865de1e7..df05db01 100644 --- a/core/mem/malloc.c +++ b/core/mem/malloc.c @@ -162,9 +162,9 @@ void *realloc(void *ptr, size_t size) ah->a.next->a.prev = ah; nah->next_free->prev_free = nah->prev_free; nah->prev_free->next_free = nah->next_free; - ARENA_SIZE_SET(ah->a.attrs, ARENA_SIZE_GET(nah->a.attrs)); + ARENA_SIZE_SET(ah->a.attrs, ARENA_SIZE_GET(ah->a.attrs) + + ARENA_SIZE_GET(nah->a.attrs)); xsize = ARENA_SIZE_GET(ah->a.attrs); - //xsize = (ah->a.size += nah->a.size); } if (xsize >= newsize) { diff --git a/core/pxelinux.asm b/core/pxelinux.asm index 5735e642..d927b2b2 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -81,11 +81,12 @@ InitStack resd 1 PXEStack resd 1 ; Saved stack during PXE call alignb 4 - global DHCPMagic, RebootTime, StrucPtr + global DHCPMagic, RebootTime, StrucPtr, BIOSName RebootTime resd 1 ; Reboot timeout, if set by option StrucPtr resw 2 ; Pointer to PXENV+ or !PXE structure LocalBootType resw 1 ; Local boot return code DHCPMagic resb 1 ; PXELINUX magic flags +BIOSName resw 1 ; Dummy variable - always 0 section .text16 global StackBuf @@ -191,8 +192,7 @@ ROOT_FS_OPS: call reset_idle ; -; Now we're all set to start with our *real* business. First load the -; configuration file (if any) and parse it. +; Now we're all set to start with our *real* business. ; ; In previous versions I avoided using 32-bit registers because of a ; rumour some BIOSes clobbered the upper half of 32-bit registers at @@ -216,16 +216,6 @@ ROOT_FS_OPS: %endmacro ; -; Open configuration file. ldlinux.c32 needs ConfigName to be set - so we need -; to call open_config() before loading it. -; -; Note: We don't need to check return value of open_config() function. It will -; call kaboom() on failure. -; - extern open_config - pm_call open_config - -; ; Jump to 32-bit ELF space ; pm_call load_env32 @@ -27,6 +27,7 @@ uint8_t KbdMap[256]; uint16_t VGAFontSize = 16; char aux_seg[256]; uint8_t UserFont = 0; +uint16_t BIOSName; #undef kaboom void kaboom(void) diff --git a/extlinux/main.c b/extlinux/main.c index 27527335..d1909745 100644 --- a/extlinux/main.c +++ b/extlinux/main.c @@ -1288,9 +1288,7 @@ int modify_existing_adv(const char *path) if (devfd < 0) return 1; - if (opt.reset_adv) - syslinux_reset_adv(syslinux_adv); - else if (ext_read_adv(path, devfd, &filename) < 0) { + if (ext_read_adv(path, devfd, &filename) < 0) { close(devfd); return 1; } @@ -75,7 +75,7 @@ LIBOTHER_OBJS = \ mempcpy.o memmem.o memmove.o memswap.o \ perror.o qsort.o seed48.o \ srand48.o sscanf.o strcasecmp.o strcat.o \ - strerror.o \ + strerror.o errlist.o \ strnlen.o \ strncat.o strndup.o \ stpncpy.o \ diff --git a/mk/syslinux.mk b/mk/syslinux.mk index cab80102..484afb2a 100644 --- a/mk/syslinux.mk +++ b/mk/syslinux.mk @@ -36,6 +36,7 @@ NASM = nasm NASMOPT = -Ox PERL = perl +PYTHON = python UPX = upx CHMOD = chmod diff --git a/win/syslinux.c b/win/syslinux.c index f8e27801..c291f005 100644 --- a/win/syslinux.c +++ b/win/syslinux.c @@ -270,13 +270,17 @@ static void move_file(char *pathname, char *filename) memcpy(cp, filename, 12); /* Delete any previous file */ - SetFileAttributes(pathname, FILE_ATTRIBUTE_NORMAL); - DeleteFile(pathname); - if (!MoveFile(pathname, new_name)) + SetFileAttributes(new_name, FILE_ATTRIBUTE_NORMAL); + DeleteFile(new_name); + if (!MoveFile(pathname, new_name)) { + fprintf(stderr, + "Failed to move %s to destination directory: %s\n", + filename, opt.directory); + SetFileAttributes(pathname, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); - else + } else SetFileAttributes(new_name, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); |