aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS4
-rw-r--r--com32/include/dprintf.h10
-rw-r--r--com32/include/syslinux/debug.h15
-rw-r--r--com32/lib/syslinux/debug.c95
-rw-r--r--com32/lib/syslinux/load_linux.c43
-rw-r--r--com32/modules/Makefile2
-rw-r--r--com32/modules/debug.c54
-rw-r--r--com32/modules/prdhcp.c4
-rw-r--r--core/comboot.inc3
-rw-r--r--core/common.inc1
-rw-r--r--core/conio.c4
-rw-r--r--core/idle.c4
-rw-r--r--core/idle.inc80
-rw-r--r--core/pxelinux.asm5
-rw-r--r--doc/syslinux.txt5
-rw-r--r--mk/devel.mk1
-rw-r--r--mk/elf.mk2
-rw-r--r--mk/lib.mk1
-rw-r--r--txt/syslinux.cfg.txt6
19 files changed, 227 insertions, 112 deletions
diff --git a/NEWS b/NEWS
index ca1f396e..ed145c10 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,10 @@ Changes in 6.00:
* EFI TCP/IP support. This allows the EFI backend to hook into
the generic TFTP, HTTP and FTP functionality.
+Changes in 5.11:
+ * Dynamic debug support: Add new module, debug.c32, that allows
+ debug code to be dynamically enabled and disabled at runtime.
+
Changes in 5.10:
* PXELINUX: An entirely new network implementation based on
the lwIP embedded TCP/IP stack. As a result, plain PXELINUX
diff --git a/com32/include/dprintf.h b/com32/include/dprintf.h
index de4625bc..ef23282b 100644
--- a/com32/include/dprintf.h
+++ b/com32/include/dprintf.h
@@ -5,6 +5,8 @@
#ifndef _DPRINTF_H
#define _DPRINTF_H
+#include <syslinux/debug.h>
+
#if !defined(DEBUG_PORT) && !defined(DEBUG_STDIO)
# undef CORE_DEBUG
#endif
@@ -23,8 +25,12 @@ void vdprintf(const char *, va_list);
#else
-# define dprintf(fmt, ...) ((void)(0))
-# define vdprintf(fmt, ap) ((void)(0))
+#define dprintf(...) \
+ if (syslinux_debug_enabled) \
+ printf(__VA_ARGS__)
+#define vdprintf(fmt, ap) \
+ if (syslinux_debug_enabled) \
+ vprintf(fmt, ap)
#endif /* CORE_DEBUG */
diff --git a/com32/include/syslinux/debug.h b/com32/include/syslinux/debug.h
new file mode 100644
index 00000000..aee6fdbb
--- /dev/null
+++ b/com32/include/syslinux/debug.h
@@ -0,0 +1,15 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdbool.h>
+
+#ifdef DYNAMIC_DEBUG
+#define syslinux_debug_enabled __syslinux_debug_enabled(__func__)
+extern bool __syslinux_debug_enabled(const char *func);
+#else
+#define syslinux_debug_enabled (0)
+#endif /* DYNAMIC_DEBUG */
+
+extern int syslinux_debug(const char *str, bool enable);
+
+#endif /* DEBUG_H */
diff --git a/com32/lib/syslinux/debug.c b/com32/lib/syslinux/debug.c
new file mode 100644
index 00000000..d9ab863f
--- /dev/null
+++ b/com32/lib/syslinux/debug.c
@@ -0,0 +1,95 @@
+#include <linux/list.h>
+#include <string.h>
+#include <stdbool.h>
+
+#ifdef DYNAMIC_DEBUG
+
+static LIST_HEAD(debug_funcs);
+
+struct debug_func_entry {
+ const char *name;
+ struct list_head list;
+};
+
+static struct debug_func_entry *lookup_entry(const char *func)
+{
+ struct debug_func_entry *e, *entry = NULL;
+
+ list_for_each_entry(e, &debug_funcs, list) {
+ if (!strcmp(e->name, func)) {
+ entry = e;
+ break;
+ }
+ }
+
+ return entry;
+}
+
+bool __syslinux_debug_enabled(const char *func)
+{
+ struct debug_func_entry *entry;
+
+ entry = lookup_entry(func);
+ if (entry)
+ return true;
+
+ return false;
+}
+
+static int __enable(const char *func)
+{
+ struct debug_func_entry *entry;
+
+ entry = lookup_entry(func);
+ if (entry)
+ return 0; /* already enabled */
+
+ entry = malloc(sizeof(*entry));
+ if (!entry)
+ return -1;
+
+ entry->name = func;
+ list_add(&entry->list, &debug_funcs);
+ return 0;
+}
+
+static int __disable(const char *func)
+{
+ struct debug_func_entry *entry;
+
+ entry = lookup_entry(func);
+ if (!entry)
+ return 0; /* already disabled */
+
+ list_del(&entry->list);
+ free(entry);
+ return 0;
+}
+
+/*
+ * Enable or disable debug code for function 'func'.
+ */
+int syslinux_debug(const char *func, bool enable)
+{
+ int rv;
+
+ if (enable)
+ rv = __enable(func);
+ else
+ rv = __disable(func);
+
+ return rv;
+}
+
+#else
+
+int syslinux_debug(const char *func, bool enable)
+{
+ (void)func;
+ (void)enable;
+
+ printf("Dynamic debug unavailable\n");
+ return -1;
+}
+
+#endif /* DYNAMIC_DEBUG */
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index 914258ba..6a0afd39 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -147,8 +147,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
cmdline_size = strlen(cmdline) + 1;
errno = EINVAL;
- if (kernel_size < 2 * 512)
+ if (kernel_size < 2 * 512) {
+ dprintf("Kernel size too small\n");
goto bail;
+ }
/* Look for specific command-line arguments we care about */
if ((arg = find_argument(cmdline, "mem=")))
@@ -179,8 +181,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
memcpy(&hdr, kernel_buf, sizeof hdr);
whdr = (struct linux_header *)kernel_buf;
- if (hdr.boot_flag != BOOT_MAGIC)
+ if (hdr.boot_flag != BOOT_MAGIC) {
+ dprintf("Invalid boot magic\n");
goto bail;
+ }
if (hdr.header != LINUX_MAGIC) {
hdr.version = 0x0100; /* Very old kernel */
@@ -192,7 +196,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
if (!hdr.setup_sects)
hdr.setup_sects = 4;
- if (hdr.version < 0x0203)
+ if (hdr.version < 0x0203 || !hdr.initrd_addr_max)
hdr.initrd_addr_max = 0x37ffffff;
if (!memlimit && memlimit - 1 > hdr.initrd_addr_max)
@@ -230,14 +234,18 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
hdr.init_size = 3 * prot_mode_size;
}
- if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512 * 1024)
- goto bail; /* Kernel cannot be loaded low */
+ if (!(hdr.loadflags & LOAD_HIGH) && prot_mode_size > 512 * 1024) {
+ dprintf("Kernel cannot be loaded low\n");
+ goto bail;
+ }
/* Get the size of the initramfs, if there is one */
irf_size = initramfs_size(initramfs);
- if (irf_size && hdr.version < 0x0200)
- goto bail; /* initrd/initramfs not supported */
+ if (irf_size && hdr.version < 0x0200) {
+ dprintf("Initrd specified but not supported by kernel\n");
+ goto bail;
+ }
if (hdr.version >= 0x0200) {
whdr->type_of_loader = 0x30; /* SYSLINUX unknown module */
@@ -275,8 +283,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
!= SMT_FREE) {
const struct syslinux_memmap *mp;
- if (!hdr.relocatable_kernel)
- goto bail; /* Can't relocate - no hope */
+ if (!hdr.relocatable_kernel) {
+ dprintf("Cannot relocate kernel\n");
+ goto bail;
+ }
ok = false;
for (mp = amap; mp; mp = mp->next) {
@@ -305,8 +315,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
}
}
- if (!ok)
+ if (!ok) {
+ dprintf("Could not find location for protected-mode code\n");
goto bail;
+ }
}
/* Real mode code */
@@ -339,8 +351,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
}
}
- if (!ok)
+ if (!ok) {
+ dprintf("Could not find location for real-mode code\n");
goto bail;
+ }
}
if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t) kernel_buf,
@@ -408,8 +422,10 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
best_addr = (adj_end - irf_size) & ~align_mask;
}
- if (!best_addr)
- goto bail; /* Insufficient memory for initramfs */
+ if (!best_addr) {
+ dprintf("Insufficient memory for initramfs\n");
+ goto bail;
+ }
whdr->ramdisk_image = best_addr;
whdr->ramdisk_size = irf_size;
@@ -504,6 +520,7 @@ int bios_boot_linux(void *kernel_buf, size_t kernel_size,
}
syslinux_shuffle_boot_rm(fraglist, mmap, 0, &regs);
+ dprintf("shuffle_boot_rm failed\n");
bail:
syslinux_free_movelist(fraglist);
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 6e562b8c..13cc63bb 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -24,7 +24,7 @@ MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.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 \
- hexdump.c32 poweroff.c32 cptime.c32
+ hexdump.c32 poweroff.c32 cptime.c32 debug.c32
TESTFILES =
diff --git a/com32/modules/debug.c b/com32/modules/debug.c
new file mode 100644
index 00000000..1026ebf3
--- /dev/null
+++ b/com32/modules/debug.c
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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 <syslinux/debug.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *progname;
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: %s [-e|-d] <func1> [<func2>, ...]\n", progname);
+}
+
+int main(int argc, char *argv[])
+{
+ bool enable;
+ int i;
+
+ progname = argv[0];
+
+ if (argc < 3) {
+ usage();
+ return -1;
+ }
+
+ if (!strncmp(argv[1], "-e", 2))
+ enable = true;
+ else if (!strncmp(argv[1], "-d", 2))
+ enable = false;
+ else {
+ usage();
+ return -1;
+ }
+
+ for (i = 2; i < argc; i++) {
+ char *str = argv[i];
+
+ if (syslinux_debug(str, enable) < 0)
+ fprintf(stderr, "Failed to debug symbol \"%s\"\n", str);
+ }
+
+ return 0;
+}
diff --git a/com32/modules/prdhcp.c b/com32/modules/prdhcp.c
index e1785a03..4ae295e8 100644
--- a/com32/modules/prdhcp.c
+++ b/com32/modules/prdhcp.c
@@ -39,11 +39,11 @@
#include <unistd.h>
#include <getkey.h>
-#define DEBUG 0
+#define PRDHCP_DEBUG 0
#define dprintf0(f, ...) ((void)0)
-#ifdef DEBUG
+#ifdef PRDHCP_DEBUG
# define dpressanykey pressanykey
# define dprintf printf
# define dprint_pxe_bootp_t print_pxe_bootp_t
diff --git a/core/comboot.inc b/core/comboot.inc
index 3197c8a7..63394350 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -294,7 +294,8 @@ comboot_getchar:
comboot_int28:
sti
cld
- call do_idle
+ extern __idle
+ pm_call __idle
iret
;
diff --git a/core/common.inc b/core/common.inc
index 65b4ab69..fd75dfe1 100644
--- a/core/common.inc
+++ b/core/common.inc
@@ -7,7 +7,6 @@
%include "pm.inc" ; Protected mode
%include "bcopy32.inc" ; 32-bit bcopy
%include "strcpy.inc" ; strcpy()
-%include "idle.inc" ; Idle handling
%include "adv.inc" ; Auxillary Data Vector
%include "timer.inc" ; Timer handling
diff --git a/core/conio.c b/core/conio.c
index d388edaa..df929aed 100644
--- a/core/conio.c
+++ b/core/conio.c
@@ -201,8 +201,6 @@ void pm_pollchar(com32sys_t *regs)
regs->eflags.l |= EFLAGS_ZF;
}
-extern void do_idle(void);
-
char bios_getchar(char *hi)
{
com32sys_t ireg, oreg;
@@ -211,7 +209,7 @@ char bios_getchar(char *hi)
memset(&ireg, 0, sizeof(ireg));
memset(&oreg, 0, sizeof(oreg));
while (1) {
- call16(do_idle, &zero_regs, NULL);
+ __idle();
ireg.eax.b[1] = 0x11; /* Poll keyboard */
__intcall(0x16, &ireg, &oreg);
diff --git a/core/idle.c b/core/idle.c
index a089b088..c8050554 100644
--- a/core/idle.c
+++ b/core/idle.c
@@ -24,7 +24,7 @@
#define TICKS_TO_IDLE 4 /* Also in idle.inc */
-extern jiffies_t _IdleTimer;
+static jiffies_t _IdleTimer;
__export uint16_t NoHalt = 0;
int (*idle_hook_func)(void);
@@ -32,6 +32,7 @@ int (*idle_hook_func)(void);
void reset_idle(void)
{
_IdleTimer = jiffies();
+ sti(); /* Guard against BIOS/PXE brokenness... */
}
__export void __idle(void)
@@ -42,6 +43,7 @@ __export void __idle(void)
if (idle_hook_func && idle_hook_func())
return; /* Nonzero return = do not idle */
+ sti();
if (NoHalt)
cpu_relax();
else
diff --git a/core/idle.inc b/core/idle.inc
deleted file mode 100644
index 65d6c5c8..00000000
--- a/core/idle.inc
+++ /dev/null
@@ -1,80 +0,0 @@
-;; -*- fundamental -*- ---------------------------------------------------
-;;
-;; Copyright 2008 H. Peter Anvin - All Rights Reserved
-;; Copyright 2009-2010 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
-;; 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.
-;;
-;; -----------------------------------------------------------------------
-
- section .text16
-TICKS_TO_IDLE equ 4 ; Also in idle.c
-
-reset_idle:
- push eax
- mov eax,[cs:__jiffies]
- mov [cs:_IdleTimer],eax
- pop eax
- sti ; Guard against BIOS/PXE brokenness...
- ret
-
- global do_idle:function hidden
-do_idle:
- push eax
- push ds
- push es
- mov ax,cs
- mov ds,ax
- mov es,ax
- pushf
- pop ax
- test ah,2
- jnz .ok
- push si
- push cx
- mov si,hlt_err
- pm_call pm_writestr
- mov si,sp
- add si,10
- mov cx,16
-.errloop:
- ss lodsw
- pm_call pm_writehex4
- dec cx
- jz .endloop
- mov al,' '
- pm_call pm_writechr
- jmp .errloop
-.endloop:
- pm_call crlf
- pop cx
- pop si
- sti
-.ok:
- ; Don't spend time jumping to PM unless we're actually idle...
-
- mov eax,[__jiffies]
- sub eax,[_IdleTimer]
- cmp eax,TICKS_TO_IDLE
- jb .done
-
- extern __idle
- pm_call __idle
-.done:
- pop es
- pop ds
- pop eax
-.ret: ret
-
- section .data16
- alignz 4
- global _IdleTimer:data hidden
-_IdleTimer dd 0
-
-hlt_err db 'ERROR: idle with IF=0', CR, LF, 0
-
- section .text16
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 3e2bc0a1..6b8c9e4c 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -170,7 +170,8 @@ ROOT_FS_OPS:
;
; Initialize the idle mechanism
;
- call reset_idle
+ extern reset_idle
+ pm_call reset_idle
;
; Now we're all set to start with our *real* business.
@@ -339,7 +340,7 @@ kaboom:
.wait2: mov dx,[BIOS_timer]
.wait3: call pollchar
jnz .keypress
- call do_idle
+ pm_call __idle
cmp dx,[BIOS_timer]
je .wait3
loop .wait2,ecx
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index 43e20777..fd7396e3 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -158,8 +158,9 @@ IPAPPEND bitmask
The SYSAPPEND option was introduced in Syslinux 5.10; it is an
enhancement of a previous option IPAPPEND which was only
- available on PXELINUX. bitmask is interpretted as decimal format
- unless prefixed with "0x" for hexidecimal.
+ available on PXELINUX. bitmask is interpreted as decimal format
+ unless prefixed with "0x" for hexadecimal or "0" (zero) for
+ octal.
1: indicates that an option of the following format
should be generated and added to the kernel command line:
diff --git a/mk/devel.mk b/mk/devel.mk
index e0429380..7c029771 100644
--- a/mk/devel.mk
+++ b/mk/devel.mk
@@ -2,3 +2,4 @@
GCCWARN += -Wno-clobbered
#GCCWARN += -DDEBUG_MALLOC
# GCCWARN += -DDEBUG_PORT=0x3f8 -DCORE_DEBUG=1
+GCCWARN += -DDYNAMIC_DEBUG
diff --git a/mk/elf.mk b/mk/elf.mk
index 8f2421a8..1ec9b2d9 100644
--- a/mk/elf.mk
+++ b/mk/elf.mk
@@ -54,7 +54,7 @@ GPLLIB =
GPLINCLUDE =
endif
-CFLAGS = $(GCCOPT) -W -Wall \
+CFLAGS = $(GCCOPT) $(GCCWARN) -W -Wall \
-fomit-frame-pointer -D__COM32__ -DDYNAMIC_MODULE \
-nostdinc -iwithprefix include \
-I$(com32)/libutil/include -I$(com32)/include \
diff --git a/mk/lib.mk b/mk/lib.mk
index 6ae26c86..bc516c2c 100644
--- a/mk/lib.mk
+++ b/mk/lib.mk
@@ -199,6 +199,7 @@ CORELIBOBJS = \
libgcc/__negdi2.o libgcc/__ashrdi3.o libgcc/__lshrdi3.o \
libgcc/__muldi3.o libgcc/__udivmoddi4.o libgcc/__umoddi3.o \
libgcc/__divdi3.o libgcc/__moddi3.o \
+ syslinux/debug.o \
$(LIBENTRY_OBJS) \
$(LIBMODULE_OBJS)
diff --git a/txt/syslinux.cfg.txt b/txt/syslinux.cfg.txt
index f9e02b6b..a06fe050 100644
--- a/txt/syslinux.cfg.txt
+++ b/txt/syslinux.cfg.txt
@@ -128,9 +128,9 @@ section can be used to override a global *APPEND*.
(*SYSAPPEND*: 5.10+; *IPAPPEND*: *PXELINUX* only)
The *SYSAPPEND* option was introduced in *Syslinux* 5.10; it is an
enhancement of a previous option *IPAPPEND* which was only available on
-*PXELINUX*. 'bitmask' is interpretted as decimal format unless prefixed
-with "0x" for hexidecimal. The 'bitmask' is an OR (sum) of the
-following integer options:
+*PXELINUX*. 'bitmask' is interpreted as decimal format unless prefixed
+with "0x" for hexadecimal or "0" (zero) for octal. The 'bitmask' is an
+OR (sum) of the following integer options:
ifndef::doctype-manpage[[horizontal]]
*1*::: An option of the following format should be generated, based on