From: Matt Fleming <matt.fleming at intel.com> Here are the patches that I've got queued up based on the very helpful feedback I received from people testing Syslinux 5.00-pre9. Unless anyone has any concerns these will make it into Syslinux 5.00-pre10. Matt Fleming (9): pxe: Don't call open_config() from the pxe core ldlinux: Print a warning if no config file is found ldlinux: Fix logic if no DEFAULT or UI directive is found ldlinux: get_key() requires raw access to user input com32: Include .init_array section in .ctors in linker script CLI: Fix command history traversal win: Fix installing to a directory win: Print error message if we fail to install to --directory CLI: Add Ctrl + V support for printing the Syslinux version com32/elflink/ldlinux/Makefile | 2 +- com32/elflink/ldlinux/cli.c | 32 +++++++++++++++++++--- com32/elflink/ldlinux/config.h | 2 +- com32/elflink/ldlinux/execute.c | 2 +- com32/elflink/ldlinux/get_key.c | 22 ++++++++++++++- com32/elflink/ldlinux/ldlinux.c | 56 +++++++++++++++++++------------------- com32/elflink/ldlinux/readconfig.c | 5 +++- com32/lib/elf32.ld | 15 +++------- com32/lib/init.h | 15 ---------- com32/lib/malloc.c | 1 - com32/libutil/ansiraw.c | 19 +++++++++++++ core/diskstart.inc | 1 + core/include/core.h | 1 + core/pxelinux.asm | 16 ++--------- win/syslinux.c | 12 +++++--- 15 files changed, 120 insertions(+), 81 deletions(-) delete mode 100644 com32/lib/init.h -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 1/9] pxe: Don't call open_config() from the pxe core
From: Matt Fleming <matt.fleming at intel.com> Delete some stale comments about ldlinux.c32 requiring ConfigName to be initialised before it's launched - this is no longer true. ldlinux.c32 takes care of opening the config files. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- core/pxelinux.asm | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/core/pxelinux.asm b/core/pxelinux.asm index ef9c723..35c7408 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -192,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 @@ -217,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 -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 2/9] ldlinux: Print a warning if no config file is found
From: Matt Fleming <matt.fleming at intel.com> This behaviour is taken from 4.06, where an error message is printed if no config file is found. A warning is a more user-friendly choice since Syslinux will still function without a config file. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/elflink/ldlinux/readconfig.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c index 1db397a..2fa0641 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); -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 3/9] ldlinux: Fix logic if no DEFAULT or UI directive is found
From: Matt Fleming <matt.fleming at intel.com> Somewhere along the way the code that prints, No DEFAULT or UI configuration directive found! was broken, and now no longer prints at all. While we're fixing this it's a good opportunity to rework the logic to be clearer. Now we only print the message if a config file was found, since these directives are obviously missing if there is no config file (a warning will be printed about the lack of config file anyway). Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/elflink/ldlinux/config.h | 2 +- com32/elflink/ldlinux/execute.c | 2 +- com32/elflink/ldlinux/ldlinux.c | 56 ++++++++++++++++++++--------------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h index ea4736e..63e33b6 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 e7969c2..6ccde49 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/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c index d963595..59c5598 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; } -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 4/9] ldlinux: get_key() requires raw access to user input
From: Matt Fleming <matt.fleming at intel.com> commit 4503e6260c0 ("ldlinux: Use stdcon instead of rawcon for the console") broke get_key() because it was no longer possible to read raw data from stdin. Provide a new function raw_read() that will return user input a character at a time. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/elflink/ldlinux/Makefile | 2 +- com32/elflink/ldlinux/get_key.c | 22 +++++++++++++++++++++- com32/libutil/ansiraw.c | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile index dc48ca9..0666d9f 100644 --- a/com32/elflink/ldlinux/Makefile +++ b/com32/elflink/ldlinux/Makefile @@ -14,7 +14,7 @@ topdir = ../../.. MAKEDIR = $(topdir)/mk 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 $(com32)/lib/libcom32min.a all: ldlinux.c32 ldlinux_lnx.a diff --git a/com32/elflink/ldlinux/get_key.c b/com32/elflink/ldlinux/get_key.c index 0be06b9..123171a 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/libutil/ansiraw.c b/com32/libutil/ansiraw.c index 2afd48a..b67768c 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 -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 5/9] com32: Include .init_array section in .ctors in linker script
From: Matt Fleming <matt.fleming at intel.com> GCC 4.7 now places pointers to functions with the 'constructor' and 'destructor' function attributes in .init_array and .fini_array sections, respectively, whereas previously they were in the .ctors and .dtors sections. This change breaks the ctors/dtors code as it only expects function to be in the .ctors and .dtors sections, meaning the ctors and dtors functions are never executed. While a COM32_INIT() macro exists that places functions in the .init_array section, no function makes use of it, so there should be no fallout from this change. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/lib/elf32.ld | 15 ++++----------- com32/lib/init.h | 15 --------------- com32/lib/malloc.c | 1 - 3 files changed, 4 insertions(+), 27 deletions(-) delete mode 100644 com32/lib/init.h diff --git a/com32/lib/elf32.ld b/com32/lib/elf32.ld index ddf6e04..16d10a3 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 2d98342..0000000 --- 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/malloc.c b/com32/lib/malloc.c index ec103ab..ce35f3d 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 = { -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 6/9] CLI: Fix command history traversal
From: Matt Fleming <matt.fleming at intel.com> The up/down keys were broken with respect to traversing through the command history because it was dereferencing a NULL pointer on the first iteration. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/elflink/ldlinux/cli.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index a1cf50c..65a5057 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -340,9 +340,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 +364,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 { -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 7/9] win: Fix installing to a directory
From: Matt Fleming <matt.fleming at intel.com> commit bda54cb68067 ("installers: Install ldlinux.c32 automatically)" introduced a bug in the move_file() function. move_file() isn't deleting the destination path, including the --directory argument, that ldlinux.sys should be installed to ('new_name'), which means that the MoveFile() calls fails. What it's actually doing is deleting ldlinux.sys from the file destination system. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- win/syslinux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/syslinux.c b/win/syslinux.c index f8e2780..64369d5 100644 --- a/win/syslinux.c +++ b/win/syslinux.c @@ -270,8 +270,8 @@ static void move_file(char *pathname, char *filename) memcpy(cp, filename, 12); /* Delete any previous file */ - SetFileAttributes(pathname, FILE_ATTRIBUTE_NORMAL); - DeleteFile(pathname); + SetFileAttributes(new_name, FILE_ATTRIBUTE_NORMAL); + DeleteFile(new_name); if (!MoveFile(pathname, new_name)) SetFileAttributes(pathname, FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 8/9] win: Print error message if we fail to install to --directory
From: Matt Fleming <matt.fleming at intel.com> Instead of silently returning with no indication of error if we couldn't install to the --directory argument, print an error message that tells the user the files are not where they wanted. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- win/syslinux.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/win/syslinux.c b/win/syslinux.c index 64369d5..c291f00 100644 --- a/win/syslinux.c +++ b/win/syslinux.c @@ -272,11 +272,15 @@ static void move_file(char *pathname, char *filename) /* Delete any previous file */ SetFileAttributes(new_name, FILE_ATTRIBUTE_NORMAL); DeleteFile(new_name); - if (!MoveFile(pathname, 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); -- 1.7.11.7
Matt Fleming
2012-Nov-02 14:13 UTC
[syslinux] [PATCH 9/9] CLI: Add Ctrl + V support for printing the Syslinux version
From: Matt Fleming <matt.fleming at intel.com> The cli code is missing support for printing the version string that is available in Syslinux 4.06 and earlier. Signed-off-by: Matt Fleming <matt.fleming at intel.com> --- com32/elflink/ldlinux/cli.c | 10 ++++++++++ core/diskstart.inc | 1 + core/include/core.h | 1 + core/pxelinux.asm | 3 ++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index 65a5057..ebeaeec 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" @@ -421,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/core/diskstart.inc b/core/diskstart.inc index c8f7936..8806593 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 da94dbf..a6ecbc4 100644 --- a/core/include/core.h +++ b/core/include/core.h @@ -24,6 +24,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/pxelinux.asm b/core/pxelinux.asm index 35c7408..63334ff 100644 --- a/core/pxelinux.asm +++ b/core/pxelinux.asm @@ -81,12 +81,13 @@ InitStack resd 1 PXEStack resd 1 ; Saved stack during PXE call alignb 4 - global DHCPMagic, RebootTime, APIVer + global DHCPMagic, RebootTime, APIVer, BIOSName RebootTime resd 1 ; Reboot timeout, if set by option StrucPtr resw 2 ; Pointer to PXENV+ or !PXE structure APIVer resw 1 ; PXE API version found LocalBootType resw 1 ; Local boot return code DHCPMagic resb 1 ; PXELINUX magic flags +BIOSName resw 1 ; Dummy variable - always 0 section .text16 global StackBuf -- 1.7.11.7
Shao Miller
2012-Nov-03 05:00 UTC
[syslinux] [PATCH 2/9] ldlinux: Print a warning if no config file is found
On 11/2/2012 10:13, Matt Fleming wrote:> From: Matt Fleming <matt.fleming at intel.com> > > This behaviour is taken from 4.06, where an error message is printed > if no config file is found. A warning is a more user-friendly choice > since Syslinux will still function without a config file. > > Signed-off-by: Matt Fleming <matt.fleming at intel.com> > --- > com32/elflink/ldlinux/readconfig.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c > index 1db397a..2fa0641 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); >Except for PXELINUX, where it might be best as "ERROR". Gene Cumm suggested something like: printf("%s: No configuration file found\n", is_pxelinux ? "ERROR" : "WARNING"); - Shao Miller