diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-06-17 11:57:29 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-06-17 11:57:29 +0100 |
commit | a0bb1928c8652aada30243089c53754ddd9b99df (patch) | |
tree | 5fd177bf495f80b51d323a7d7ebf76e8650e65c4 | |
parent | 97bff28959e9deed6b78dd7df974797476683006 (diff) | |
parent | 022cdd1d56512e8759e8374c10a7420201db93c0 (diff) | |
download | syslinux-a0bb1928c8652aada30243089c53754ddd9b99df.tar.gz |
Merge tag 'syslinux-5.11-pre2' into firmware
syslinux-5.11-pre2
Conflicts:
core/elflink/load_env32.c
version
-rw-r--r-- | NEWS | 13 | ||||
-rw-r--r-- | com32/elflink/ldlinux/cli.c | 2 | ||||
-rw-r--r-- | com32/elflink/ldlinux/readconfig.c | 85 | ||||
-rw-r--r-- | com32/lib/sys/module/common.c | 36 | ||||
-rw-r--r-- | com32/lib/syslinux/load_linux.c | 49 | ||||
-rw-r--r-- | core/elflink/load_env32.c | 26 | ||||
-rw-r--r-- | core/font.c | 20 | ||||
-rw-r--r-- | core/fs/fs.c | 2 | ||||
-rw-r--r-- | core/include/bios.h | 17 | ||||
-rw-r--r-- | core/include/fs.h | 10 | ||||
-rw-r--r-- | core/path.c | 42 | ||||
-rwxr-xr-x | linux/syslinux.c | 2 |
12 files changed, 187 insertions, 117 deletions
@@ -10,7 +10,9 @@ Changes in 5.10: the lwIP embedded TCP/IP stack. As a result, plain PXELINUX can now support HTTP and FTP without gPXE/iPXE. ls/readdir functionality is supported over HTTP with an indexing - webserver, or over FTP with most common FTP servers. + webserver, or over FTP with most common FTP servers. For the + new network stack use lpxelinux.0. For the legacy stack use + pxelinux.0. * Rename the "ipappend" option to "sysappend" ("ipappend" is still accepted as an alias) and make it available for all derivatives. Add additional strings derived from the system @@ -18,6 +20,15 @@ Changes in 5.10: * "sysappend" strings are also sent as http cookies, with the prefix _Syslinux_ added, on all http transfers. This can be overridden with the SENDCOOKIES configuration file command. + * poweroff.c32: A new module to power off a system via APM. It + replaces the poweroff COMBOOT module (Sebastian Herbszt). + * PXELINUX: Fix booting with DHCP options 209 and 210 which was + broken in 5.00. + * Handle loading kernel images with no protected mode code. A + legitimate kernel image can consist solely of real-mode code. + The support for booting such images was broken in 5.00 (Josh Triplett). + * Fix a regression in the .psf font file loader introduced + in 5.00. Changes in 5.01: * txt/: A new AsciiDoc documentation set (work-in-progress) diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c index b85357b2..7c4f14c6 100644 --- a/com32/elflink/ldlinux/cli.c +++ b/com32/elflink/ldlinux/cli.c @@ -168,7 +168,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ , prev_len = max(len, prev_len); /* Redraw the command line */ - printf("\033[?7l\033[?25l"); + printf("\033[?25l"); printf("\033[1G%s ", input); x = strlen(input); diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c index 9d50c2f3..d6e34bda 100644 --- a/com32/elflink/ldlinux/readconfig.c +++ b/com32/elflink/ldlinux/readconfig.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * * * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * Copyright 2009-2013 Intel Corporation; author: H. Peter Anvin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -759,7 +759,6 @@ static uint8_t SerialNotice = 1; #define DEFAULT_BAUD 9600 #define BAUD_DIVISOR 115200 -#define serial_base 0x0400 extern void sirq_cleanup_nowipe(void); extern void sirq_install(void); @@ -771,6 +770,46 @@ extern void loadkeys(char *); extern char syslinux_banner[]; extern char copyright_str[]; +/* + * PATH-based lookup + * + * Each entry in the PATH directive is separated by a colon, e.g. + * + * PATH /bar:/bin/foo:/baz/bar/bin + */ +static int parse_path(char *p) +{ + struct path_entry *entry; + const char *str; + + while (*p) { + char *c = p; + + /* Find the next directory */ + while (*c && *c != ':') + c++; + + str = refstrndup(p, c - p); + if (!str) + goto bail; + + entry = path_add(str); + refstr_put(str); + + if (!entry) + goto bail; + + if (!*c++) + break; + p = c; + } + + return 0; + +bail: + return -1; +} + static void parse_config_file(FILE * f) { char line[MAX_LINE], *p, *ep, ch; @@ -1185,16 +1224,9 @@ do_include: refstr_put(filename); } else if (looking_at(p, "kbdmap")) { const char *filename; - char *dst = KernelName; - size_t len = FILENAME_MAX - 1; - - filename = refstrdup(skipspace(p + 4)); - - while (len-- && not_whitespace(*filename)) - *dst++ = *filename++; - *dst = '\0'; - loadkeys(KernelName); + filename = refstrdup(skipspace(p + 6)); + loadkeys(filename); refstr_put(filename); } /* @@ -1280,16 +1312,7 @@ do_include: baud &= 0xffff; BaudDivisor = baud; - /* - * If port > 3 then port is I/O addr - */ - if (port <= 3) { - /* Get the I/O port from the BIOS */ - port <<= 1; - port = *(volatile uint16_t *)serial_base; - } - - + port = get_serial_port(port); SerialPort = port; /* @@ -1347,24 +1370,8 @@ do_include: } else if (looking_at(p, "say")) { printf("%s\n", p+4); } else if (looking_at(p, "path")) { - /* PATH-based lookup */ - const char *new_path; - char *_p; - size_t len, new_len; - - new_path = refstrdup(skipspace(p + 4)); - len = strlen(PATH); - new_len = strlen(new_path); - _p = malloc(len + new_len + 2); - if (_p) { - strncpy(_p, PATH, len); - _p[len++] = ':'; - strncpy(_p + len, new_path, new_len); - _p[len + new_len] = '\0'; - free(PATH); - PATH = _p; - } else - printf("Failed to realloc PATH\n"); + if (parse_path(skipspace(p + 4))) + printf("Failed to parse PATH\n"); } else if (looking_at(p, "sendcookies")) { const union syslinux_derivative_info *sdi; diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c index 4c83789e..a589f24f 100644 --- a/com32/lib/sys/module/common.c +++ b/com32/lib/sys/module/common.c @@ -59,40 +59,28 @@ void print_elf_symbols(struct elf_module *module) { FILE *findpath(char *name) { + struct path_entry *entry; char path[FILENAME_MAX]; FILE *f; - char *p, *n; - int i; f = fopen(name, "rb"); /* for full path */ if (f) return f; - p = PATH; -again: - i = 0; - while (*p && *p != ':' && i < FILENAME_MAX - 1) { - path[i++] = *p++; - } - - if (*p == ':') - p++; + list_for_each_entry(entry, &PATH, list) { + bool slash = false; - /* Ensure we have a '/' separator */ - if (path[i] != '/' && i < FILENAME_MAX - 1) - path[i++] = '/'; + /* Ensure we have a '/' separator */ + if (entry->str[strlen(entry->str) - 1] != '/') + slash = true; - n = name; - while (*n && i < FILENAME_MAX - 1) - path[i++] = *n++; - path[i] = '\0'; + snprintf(path, sizeof(path), "%s%s%s", + entry->str, slash ? "/" : "", name); - f = fopen(path, "rb"); - if (f) - return f; - - if (p >= PATH && p < PATH + strlen(PATH)) - goto again; + f = fopen(path, "rb"); + if (f) + return f; + } return NULL; } diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c index aea03058..f6e03f76 100644 --- a/com32/lib/syslinux/load_linux.c +++ b/com32/lib/syslinux/load_linux.c @@ -146,6 +146,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, cmdline_size = strlen(cmdline) + 1; + errno = EINVAL; if (kernel_size < 2 * 512) goto bail; @@ -249,8 +250,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, /* Get the memory map */ mmap = syslinux_memory_map(); /* Memory map for shuffle_boot */ amap = syslinux_dup_memmap(mmap); /* Keep track of available memory */ - if (!mmap || !amap) + if (!mmap || !amap) { + errno = ENOMEM; goto bail; + } dprintf("Initial memory map:\n"); syslinux_dump_memmap(mmap); @@ -260,8 +263,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, it's unavailable to the boot loader, which probably has already touched some of it), or just in the amap? */ if (memlimit) - if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED)) + if (syslinux_add_memmap(&amap, memlimit, -memlimit, SMT_RESERVED)) { + errno = ENOMEM; goto bail; + } /* Place the kernel in memory */ @@ -342,18 +347,24 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, real_mode_size)) goto bail; if (syslinux_add_memmap - (&amap, real_mode_base, cmdline_offset + cmdline_size, SMT_ALLOC)) + (&amap, real_mode_base, cmdline_offset + cmdline_size, SMT_ALLOC)) { + errno = ENOMEM; goto bail; + } /* Zero region between real mode code and cmdline */ if (syslinux_add_memmap(&mmap, real_mode_base + real_mode_size, - cmdline_offset - real_mode_size, SMT_ZERO)) + cmdline_offset - real_mode_size, SMT_ZERO)) { + errno = ENOMEM; goto bail; + } /* Command line */ if (syslinux_add_movelist(&fraglist, real_mode_base + cmdline_offset, - (addr_t) cmdline, cmdline_size)) + (addr_t) cmdline, cmdline_size)) { + errno = ENOMEM; goto bail; + } if (hdr.version >= 0x0202) { whdr->cmd_line_ptr = real_mode_base + cmdline_offset; } else { @@ -369,11 +380,15 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, if (prot_mode_size) { if (syslinux_add_movelist(&fraglist, prot_mode_base, (addr_t) kernel_buf + real_mode_size, - prot_mode_size)) + prot_mode_size)) { + errno = ENOMEM; goto bail; + } if (syslinux_add_memmap(&amap, prot_mode_base, prot_mode_size, - SMT_ALLOC)) + SMT_ALLOC)) { + errno = ENOMEM; goto bail; + } } /* Figure out the size of the initramfs, and where to put it. @@ -399,11 +414,15 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, whdr->ramdisk_image = best_addr; whdr->ramdisk_size = irf_size; - if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC)) + if (syslinux_add_memmap(&amap, best_addr, irf_size, SMT_ALLOC)) { + errno = ENOMEM; goto bail; + } - if (map_initramfs(&fraglist, &mmap, initramfs, best_addr)) + if (map_initramfs(&fraglist, &mmap, initramfs, best_addr)) { + errno = ENOMEM; goto bail; + } } } @@ -439,14 +458,20 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size, *prev_ptr = best_addr; prev_ptr = &sdp->hdr.next; - if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC)) + if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC)) { + errno = ENOMEM; goto bail; + } if (syslinux_add_movelist(&fraglist, best_addr, - (addr_t)&sdp->hdr, sizeof sdp->hdr)) + (addr_t)&sdp->hdr, sizeof sdp->hdr)) { + errno = ENOMEM; goto bail; + } if (syslinux_add_movelist(&fraglist, best_addr + sizeof sdp->hdr, - (addr_t)sdp->data, sdp->hdr.len)) + (addr_t)sdp->data, sdp->hdr.len)) { + errno = ENOMEM; goto bail; + } } } diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c index 470bd154..492cc095 100644 --- a/core/elflink/load_env32.c +++ b/core/elflink/load_env32.c @@ -121,14 +121,11 @@ void load_env32(com32sys_t * regs __unused) dprintf("Starting %s elf module subsystem...\n", ELF_MOD_SYS); - PATH = malloc(strlen(CurrentDirName) + 1); - if (!PATH) { + if (strlen(CurrentDirName) && !path_add(CurrentDirName)) { printf("Couldn't allocate memory for PATH\n"); goto out; } - strcpy(PATH, CurrentDirName); - size = (size_t)__dynstr_end - (size_t)__dynstr_start; core_module.strtable_size = size; size = (size_t)__dynsym_end - (size_t)__dynsym_start; @@ -162,30 +159,15 @@ void load_env32(com32sys_t * regs __unused) if (!core_getcwd(path, sizeof(path))) goto out; - if (!strlen(PATH)) { - PATH = realloc(PATH, strlen(path) + 1); - if (!PATH) { - printf("Couldn't allocate memory for PATH\n"); - goto out; - } - - strcpy(PATH, path); - } else { - PATH = realloc(PATH, strlen(path) + strlen(PATH) + 2); - if (!PATH) { - printf("Couldn't allocate memory for PATH\n"); - goto out; - } - - strcat(PATH, ":"); - strcat(PATH, path); + if (!path_add(path)) { + printf("Couldn't allocate memory for PATH\n"); + goto out; } start_ldlinux(1, argv); } out: - free(PATH); writestr("\nFailed to load "); writestr(LDLINUX); } diff --git a/core/font.c b/core/font.c index edc9de8e..30c0afb8 100644 --- a/core/font.c +++ b/core/font.c @@ -1,7 +1,7 @@ -/* - * ----------------------------------------------------------------------- +/* ----------------------------------------------------------------------- * * * Copyright 1994-2008 H. Peter Anvin - All Rights Reserved + * Copyright 2013 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -9,8 +9,9 @@ * Boston MA 02111-1307, USA; either version 2 of the License, or * (at your option) any later version; incorporated herein by reference. * - * ----------------------------------------------------------------------- - * + * ----------------------------------------------------------------------- */ + +/* * * font.c * @@ -46,8 +47,6 @@ __export void loadfont(const char *filename) uint8_t height; } hdr; FILE *f; - char *p; - int i; f = fopen(filename, "r"); if (!f) @@ -71,13 +70,8 @@ __export void loadfont(const char *filename) /* Load the actual font into the font buffer. */ memset(fontbuf, 0, 256*32); - - p = fontbuf; - for (i = 0; i < 256; i++) { - if (_fread(p, hdr.height, f) != hdr.height) - goto fail; - p += 32; - } + if (_fread(fontbuf, 256*hdr.height, f) != 256*hdr.height) + goto fail; /* Loaded OK */ VGAFontSize = hdr.height; diff --git a/core/fs/fs.c b/core/fs/fs.c index 2c1bdbee..8c1feeac 100644 --- a/core/fs/fs.c +++ b/core/fs/fs.c @@ -10,8 +10,6 @@ #include "fs.h" #include "cache.h" -__export char *PATH; - /* The currently mounted filesystem */ __export struct fs_info *this_fs = NULL; /* Root filesystem */ diff --git a/core/include/bios.h b/core/include/bios.h index 7bbd274c..0a68f5d3 100644 --- a/core/include/bios.h +++ b/core/include/bios.h @@ -30,7 +30,7 @@ #define fdctab1 fdctab #define fdctab2 (fdctab + 2) -#define serial_base 0x0400 /* Base address for 4 serial ports */ +#define SERIAL_BASE 0x0400 /* Base address for 4 serial ports */ #define BIOS_fbm 0x0413 /* Free Base Memory (kilobytes) */ #define BIOS_page 0x0462 /* Current video page */ #define BIOS_timer 0x046C /* Timer ticks */ @@ -90,4 +90,19 @@ extern char *SerialTail; extern void bios_init(void); extern void bios_cleanup_hardware(void); +static inline uint16_t get_serial_port(uint16_t port) +{ + /* Magic array in BIOS memory, contains four entries */ + const uint16_t * const serial_ports = (const uint16_t *)SERIAL_BASE; + + /* + * If port > 3 then the port is simply the I/O base address + */ + if (port > 3) + return port; + + /* Get the I/O port from the BIOS */ + return serial_ports[port]; +} + #endif /* _BIOS_H */ diff --git a/core/include/fs.h b/core/include/fs.h index b4519cee..31ef3157 100644 --- a/core/include/fs.h +++ b/core/include/fs.h @@ -1,6 +1,7 @@ #ifndef FS_H #define FS_H +#include <linux/list.h> #include <stddef.h> #include <stdbool.h> #include <string.h> @@ -182,7 +183,14 @@ static inline struct file *handle_to_file(uint16_t handle) return handle ? &files[handle-1] : NULL; } -extern char *PATH; +struct path_entry { + struct list_head list; + const char *str; +}; + +extern struct list_head PATH; + +extern struct path_entry *path_add(const char *str); /* fs.c */ void fs_init(const struct fs_ops **ops, void *priv); diff --git a/core/path.c b/core/path.c new file mode 100644 index 00000000..8e517ca7 --- /dev/null +++ b/core/path.c @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2013 Intel Corporation; author: Matt Fleming + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston MA 02110-1301, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#include <klibc/compiler.h> +#include <linux/list.h> +#include <fs.h> +#include <string.h> + +__export LIST_HEAD(PATH); + +__export struct path_entry *path_add(const char *str) +{ + struct path_entry *entry; + + if (!strlen(str)) + return NULL; + + entry = malloc(sizeof(*entry)); + if (!entry) + return NULL; + + entry->str = strdup(str); + if (!entry->str) + goto bail; + + list_add(&entry->list, &PATH); + + return entry; + +bail: + free(entry); + return NULL; +} diff --git a/linux/syslinux.c b/linux/syslinux.c index f4749ead..f64834bd 100755 --- a/linux/syslinux.c +++ b/linux/syslinux.c @@ -251,7 +251,7 @@ int do_open_file(char *name) unlink(name); fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0444); if (fd < 0) - perror(opt.device); + perror(name); return fd; } |