aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-11-14 10:50:27 +0000
committerMatt Fleming <matt.fleming@intel.com>2012-11-14 10:50:27 +0000
commit4c7278413ef068bd8239fd8a6c69d64bd2c0a385 (patch)
tree4c39e8872de7babc24bed9fe528df28c8d82d427
parent749297b070d1fe3d82fd9e5c4306b4aaf257f2a1 (diff)
parent348ae6af01350a9a46f3076a2facd27918f0f603 (diff)
downloadsyslinux-4c7278413ef068bd8239fd8a6c69d64bd2c0a385.tar.gz
syslinux-4c7278413ef068bd8239fd8a6c69d64bd2c0a385.tar.xz
syslinux-4c7278413ef068bd8239fd8a6c69d64bd2c0a385.zip
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
-rw-r--r--.gitignore1
-rw-r--r--com32/cmenu/Makefile2
-rw-r--r--com32/elflink/ldlinux/Makefile2
-rw-r--r--com32/elflink/ldlinux/cli.c32
-rw-r--r--com32/elflink/ldlinux/config.h2
-rw-r--r--com32/elflink/ldlinux/execute.c2
-rw-r--r--com32/elflink/ldlinux/get_key.c22
-rw-r--r--com32/elflink/ldlinux/kernel.c35
-rw-r--r--com32/elflink/ldlinux/ldlinux.c56
-rw-r--r--com32/elflink/ldlinux/readconfig.c5
-rw-r--r--com32/lib/Makefile5
-rw-r--r--com32/lib/elf32.ld15
-rw-r--r--com32/lib/init.h15
-rw-r--r--com32/lib/makeerrlist.pl98
-rw-r--r--com32/lib/malloc.c1
-rw-r--r--com32/lib/strerror.c28
-rw-r--r--com32/lib/syslinux/initramfs_file.c15
-rw-r--r--com32/libutil/ansiraw.c19
-rw-r--r--com32/menu/readconfig.c3
-rw-r--r--com32/modules/Makefile3
-rw-r--r--com32/modules/hexdump.c245
-rw-r--r--com32/modules/linux.c200
-rw-r--r--core/diskstart.inc1
-rw-r--r--core/include/core.h1
-rw-r--r--core/mem/malloc.c4
-rw-r--r--core/pxelinux.asm16
-rw-r--r--efi/main.c1
-rw-r--r--extlinux/main.c4
-rw-r--r--mk/lib.mk2
-rw-r--r--mk/syslinux.mk1
-rw-r--r--win/syslinux.c12
31 files changed, 674 insertions, 174 deletions
diff --git a/.gitignore b/.gitignore
index 98ea19f8..867e8220 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/efi/main.c b/efi/main.c
index 4b684ff9..a28a211f 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -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;
}
diff --git a/mk/lib.mk b/mk/lib.mk
index b37d0dcd..fc7eba11 100644
--- a/mk/lib.mk
+++ b/mk/lib.mk
@@ -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);