aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-06-17 11:57:29 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-06-17 11:57:29 +0100
commita0bb1928c8652aada30243089c53754ddd9b99df (patch)
tree5fd177bf495f80b51d323a7d7ebf76e8650e65c4
parent97bff28959e9deed6b78dd7df974797476683006 (diff)
parent022cdd1d56512e8759e8374c10a7420201db93c0 (diff)
downloadsyslinux-a0bb1928c8652aada30243089c53754ddd9b99df.tar.gz
syslinux-a0bb1928c8652aada30243089c53754ddd9b99df.tar.xz
syslinux-a0bb1928c8652aada30243089c53754ddd9b99df.zip
Merge tag 'syslinux-5.11-pre2' into firmware
syslinux-5.11-pre2 Conflicts: core/elflink/load_env32.c version
-rw-r--r--NEWS13
-rw-r--r--com32/elflink/ldlinux/cli.c2
-rw-r--r--com32/elflink/ldlinux/readconfig.c85
-rw-r--r--com32/lib/sys/module/common.c36
-rw-r--r--com32/lib/syslinux/load_linux.c49
-rw-r--r--core/elflink/load_env32.c26
-rw-r--r--core/font.c20
-rw-r--r--core/fs/fs.c2
-rw-r--r--core/include/bios.h17
-rw-r--r--core/include/fs.h10
-rw-r--r--core/path.c42
-rwxr-xr-xlinux/syslinux.c2
12 files changed, 187 insertions, 117 deletions
diff --git a/NEWS b/NEWS
index f486bcbe..567bc910 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}