aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS18
-rw-r--r--README7
-rw-r--r--com32/gplinclude/dmi/dmi_bios.h3
-rw-r--r--com32/hdt/Makefile4
-rw-r--r--com32/hdt/art/display.pngbin0 -> 19755 bytes
-rw-r--r--com32/hdt/art/red.pngbin0 -> 19674 bytes
-rw-r--r--com32/hdt/floppy/hdt.cfg12
-rw-r--r--com32/hdt/hdt-cli-hdt.c64
-rw-r--r--com32/hdt/hdt-cli.c18
-rw-r--r--com32/hdt/hdt-cli.h2
-rw-r--r--com32/hdt/hdt-common.c9
-rw-r--r--com32/hdt/hdt-common.h21
-rw-r--r--com32/hdt/hdt-dump.c2
-rw-r--r--com32/hdt/hdt.c4
-rw-r--r--com32/hdt/hdt.h2
-rw-r--r--com32/lua/src/cpu.c4
-rw-r--r--com32/lua/src/dmi.c624
-rw-r--r--com32/lua/src/liolib.c40
-rw-r--r--com32/lua/src/syslinux.c33
-rw-r--r--com32/mboot/mboot.c2
-rw-r--r--com32/menu/menumain.c2
-rw-r--r--com32/menu/readconfig.c4
-rw-r--r--com32/modules/Makefile2
-rw-r--r--com32/modules/kontron_wdt.c414
-rw-r--r--com32/modules/kontron_wdt.h117
-rw-r--r--com32/modules/prdhcp.c164
-rw-r--r--com32/modules/pxechn.c49
-rw-r--r--core/comboot.inc4
-rw-r--r--core/fs/ext2/ext2.c3
-rw-r--r--doc/comboot.txt76
-rw-r--r--doc/menu.txt2
-rw-r--r--doc/pxechn.txt106
-rw-r--r--doc/syslinux.txt2
-rw-r--r--extlinux/main.c8
-rw-r--r--libinstaller/syslxint.h23
-rw-r--r--libinstaller/syslxmod.c2
-rw-r--r--memdisk/mstructs.h4
-rw-r--r--utils/isohybrid.c10
38 files changed, 1455 insertions, 406 deletions
diff --git a/NEWS b/NEWS
index 863b8676..c8022c69 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,24 @@ to all derivatives.
Changes in 4.06:
* Support for NTFS, by Paulo Alcantara.
* EXTLINUX: more robust device detection, allow user to override.
+ * kontron_wdt.c32: Add a new module to enable the hardware
+ watchdog of some Kontron boards. It allows enabling the watchdog
+ and then booting a given image.
+ * HDT updated, and now can display images regarding some detection
+ steps. Add postexec command to run a particular entry after
+ HDT's execution, add silent option and various fixes.
+ * ifcpu.c32: Detect hypervisor presence.
+ * lua.c32: Add dhcp support and support for native Syslinux
+ functions syslinux_config(), syslinux_ipappend_strings() and
+ syslinux_reboot().
+ * isohybrid: Workaround for various EFI systems.
+ * pxechn.c32, a PXE NBP chainloader. More versatile alternative
+ to pxechain.com and resolves the PXELINUX -> WDS issue with
+ Microsoft Windows Server 2008R2 (Gene Cumm).
+ * btrfs: Fix booting off of a subvolume.
+ * com32: Add device tree support.
+ * SYSLINUX: Fix relative paths for VFAT. The CONFIG and APPEND
+ directives now support entirely relative paths.
Changes in 4.05:
* HDT updated, and now supports uploading data to a TFTP
diff --git a/README b/README
index 08a82e42..bb1aeb65 100644
--- a/README
+++ b/README
@@ -20,6 +20,13 @@ SYSLINUX now builds in a Linux environment, using nasm. You need nasm
version 2.03 or later (2.07 or later recommended) to build SYSLINUX
from source. See http://www.nasm.us/ for information about nasm.
+"utils/isohybrid" needs the UUID library and following header file,
+
+ /usr/include/uuid/uuid.h
+
+You can get them from the "uuid-dev" package on Debian based systems
+or from the "libuuid-devel" package on RPM based distributions.
+
There is now a mailing list for SYSLINUX. See the end of syslinux.txt
for details.
diff --git a/com32/gplinclude/dmi/dmi_bios.h b/com32/gplinclude/dmi/dmi_bios.h
index 5d47e899..4af7e0bd 100644
--- a/com32/gplinclude/dmi/dmi_bios.h
+++ b/com32/gplinclude/dmi/dmi_bios.h
@@ -22,7 +22,7 @@
#define BIOS_BIOS_REVISION_SIZE 16
#define BIOS_FIRMWARE_REVISION_SIZE 16
-#define BIOS_CHAR_NB_ELEMENTS 28
+#define BIOS_CHAR_NB_ELEMENTS 29
#define BIOS_CHAR_X1_NB_ELEMENTS 8
#define BIOS_CHAR_X2_NB_ELEMENTS 3
@@ -46,6 +46,7 @@ typedef struct {
bool boot_from_cd;
bool selectable_boot;
bool bios_rom_socketed;
+ bool boot_from_pcmcia;
bool edd;
bool japanese_floppy_nec_9800_1_2MB;
bool japanese_floppy_toshiba_1_2MB;
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 897b6604..d264b5ba 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -75,6 +75,8 @@ hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtool
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/syslinux.cfg a:
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/$(MEMTEST) a:
MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/backgnd.png a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/display.png a:
+ MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/red.png a:
mv hdt.img hdt-$(VERSION).img
ln -sf hdt-$(VERSION).img hdt.img
@@ -95,6 +97,8 @@ hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg memtest
cp $(MENU_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
cp $(CHAIN_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
cp -av $(ART_DIR)/backgnd.png $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp -av $(ART_DIR)/display.png $(ISO_DIR)/$(ISOLINUX_DIR)
+ cp -av $(ART_DIR)/red.png $(ISO_DIR)/$(ISOLINUX_DIR)
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
-[ -f $(MODULES_ALIAS_FILE) ] && cp $(MODULES_ALIAS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)\
diff --git a/com32/hdt/art/display.png b/com32/hdt/art/display.png
new file mode 100644
index 00000000..31fabef6
--- /dev/null
+++ b/com32/hdt/art/display.png
Binary files differ
diff --git a/com32/hdt/art/red.png b/com32/hdt/art/red.png
new file mode 100644
index 00000000..c5616ac2
--- /dev/null
+++ b/com32/hdt/art/red.png
Binary files differ
diff --git a/com32/hdt/floppy/hdt.cfg b/com32/hdt/floppy/hdt.cfg
index e5f3b0a0..524c4e06 100644
--- a/com32/hdt/floppy/hdt.cfg
+++ b/com32/hdt/floppy/hdt.cfg
@@ -93,7 +93,17 @@ TEXT HELP
VESA mode is enabled
ENDTEXT
COM32 hdt.c32
-APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show memory;say `########`;say `Starting memtest in 5 sec`%5;exit' postexec='memtest'
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show memory;say `########`;say `Starting memtest in 5 sec`;sleep 5;exit' postexec='memtest'
+
+LABEL display
+MENU LABEL Display feature (VESA mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is enabled
+ A Picture is shown by using the display command
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids silent nomenu vesa auto='display display.png; sleep 5000; display red.png'
MENU SEPARATOR
diff --git a/com32/hdt/hdt-cli-hdt.c b/com32/hdt/hdt-cli-hdt.c
index f7f7e949..3c571d60 100644
--- a/com32/hdt/hdt-cli-hdt.c
+++ b/com32/hdt/hdt-cli-hdt.c
@@ -54,12 +54,12 @@ static void main_show_modes(int argc __unused, char **argv __unused,
int i = 0;
reset_more_printf();
- printf("Available modes:\n");
+ more_printf("Available modes:\n");
while (list_modes[i]) {
printf("%s ", list_modes[i]->name);
i++;
}
- printf("\n");
+ more_printf("\n");
}
/**
@@ -119,7 +119,7 @@ static void show_cli_help(int argc __unused, char **argv __unused,
find_cli_mode_descr(hdt_cli.mode, &current_mode);
- printf("Available commands are:\n");
+ more_printf("Available commands are:\n");
/* List first default modules of the mode */
if (current_mode->default_modules && current_mode->default_modules->modules) {
@@ -154,7 +154,7 @@ static void show_cli_help(int argc __unused, char **argv __unused,
/* List secondly the show modules of the mode */
if (current_mode->show_modules && current_mode->show_modules->modules) {
- printf("\nshow commands:\n");
+ more_printf("\nshow commands:\n");
j = 0;
while (current_mode->show_modules->modules[j].name) {
printf("%s ", current_mode->show_modules->modules[j].name);
@@ -165,7 +165,7 @@ static void show_cli_help(int argc __unused, char **argv __unused,
/* List thirdly the set modules of the mode */
if (current_mode->set_modules && current_mode->set_modules->modules) {
- printf("\nset commands:\n");
+ more_printf("\nset commands:\n");
j = 0;
while (current_mode->set_modules->modules[j].name) {
printf("%s ", current_mode->set_modules->modules[j].name);
@@ -260,6 +260,30 @@ static void do_dump(int argc __unused, char **argv __unused,
}
/**
+ * do_sleep - sleep a number of milliseconds
+ **/
+static void do_sleep(int argc , char **argv ,
+ struct s_hardware *hardware)
+{
+ (void) hardware;
+ if (argc != 1) return;
+ more_printf("Sleep %d milliseconds\n",atoi(argv[0]));
+ msleep(atoi(argv[0]));
+}
+
+/**
+ * do_display - display an image to user
+ **/
+static void do_display(int argc , char **argv ,
+ struct s_hardware *hardware)
+{
+ (void) hardware;
+ if ((argc != 1) || (vesamode == false)) return;
+ more_printf("Display %s file\n",argv[0]);
+ vesacon_load_background(argv[0]);
+}
+
+/**
* do_say - say message to user
**/
static void do_say(int argc , char **argv ,
@@ -270,7 +294,6 @@ static void do_say(int argc , char **argv ,
char text_to_say[255]={0};
int arg=0;
- int sleep_time=0;
#if DEBUG
for (int i=0; i<argc;i++) dprintf("SAY: arg[%d]={%s}\n",i,argv[i]);
#endif
@@ -293,24 +316,7 @@ static void do_say(int argc , char **argv ,
dprintf("SAY CMD = [%s]\n",text_to_say);
}
- /* The % char can be in the same argument, let's consider it again */
- arg--;
-
- /* Searching for a % argument to determine the time to show the message */
- char *time_to_display = NULL;
- /* Search for a requested time to display */
- while ( ((time_to_display=strchr(argument, '%')) == NULL) && (arg+1<argc)) {
- arg++;
- argument = (char *)argv[arg];
- }
-
- if (time_to_display != NULL) {
- sleep_time=atoi(time_to_display+1);
- dprintf("SAY CMD :Time to display = %d\n",sleep_time);
- }
-
- printf("%s\n",text_to_say);
- sleep(sleep_time);
+ more_printf("%s\n",text_to_say);
}
}
@@ -357,6 +363,16 @@ struct cli_callback_descr list_hdt_default_modules[] = {
.nomodule = true,
},
{
+ .name = CLI_DISPLAY,
+ .exec = do_display,
+ .nomodule = true,
+ },
+ {
+ .name = CLI_SLEEP,
+ .exec = do_sleep,
+ .nomodule = true,
+ },
+ {
.name = NULL,
.exec = NULL,
.nomodule = false},
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 11984e5a..7542da83 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -132,7 +132,7 @@ void set_mode(cli_mode_t mode, struct s_hardware *hardware)
break;
case PXE_MODE:
if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
- printf("You are not currently using PXELINUX\n");
+ more_printf("You are not currently using PXELINUX\n");
break;
}
hdt_cli.mode = mode;
@@ -160,7 +160,7 @@ void set_mode(cli_mode_t mode, struct s_hardware *hardware)
break;
case DMI_MODE:
if (!hardware->is_dmi_valid) {
- printf("No valid DMI table found, exiting.\n");
+ more_printf("No valid DMI table found, exiting.\n");
break;
}
hdt_cli.mode = mode;
@@ -172,7 +172,7 @@ void set_mode(cli_mode_t mode, struct s_hardware *hardware)
break;
case VPD_MODE:
if (!hardware->is_vpd_valid) {
- printf("No valid VPD table found, exiting.\n");
+ more_printf("No valid VPD table found, exiting.\n");
break;
}
hdt_cli.mode = mode;
@@ -188,9 +188,9 @@ void set_mode(cli_mode_t mode, struct s_hardware *hardware)
break;
default:
/* Invalid mode */
- printf("Unknown mode, please choose among:\n");
+ more_printf("Unknown mode, please choose among:\n");
while (list_modes[i]) {
- printf("\t%s\n", list_modes[i]->name);
+ more_printf("\t%s\n", list_modes[i]->name);
i++;
}
}
@@ -199,7 +199,7 @@ void set_mode(cli_mode_t mode, struct s_hardware *hardware)
/* There is not cli_mode_descr struct for the exit mode */
if (current_mode == NULL && hdt_cli.mode != EXIT_MODE) {
/* Shouldn't get here... */
- printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+ more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
}
}
@@ -679,7 +679,7 @@ static void exec_command(char *line, struct s_hardware *hardware)
if (current_module != NULL)
current_module->exec(argc, argv, hardware);
else
- printf("unknown command: '%s'\n", command);
+ more_printf("unknown command: '%s'\n", command);
}
} else {
/*
@@ -833,7 +833,7 @@ void start_cli_mode(struct s_hardware *hardware)
find_cli_mode_descr(hdt_cli.mode, &current_mode);
if (current_mode == NULL) {
/* Shouldn't get here... */
- printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+ more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
return;
}
@@ -842,7 +842,7 @@ void start_cli_mode(struct s_hardware *hardware)
start_auto_mode(hardware);
}
- printf("Entering CLI mode\n");
+ more_printf("Entering CLI mode\n");
reset_prompt();
diff --git a/com32/hdt/hdt-cli.h b/com32/hdt/hdt-cli.h
index 30fe5187..82a4fc99 100644
--- a/com32/hdt/hdt-cli.h
+++ b/com32/hdt/hdt-cli.h
@@ -67,6 +67,8 @@
#define CLI_DISABLE "disable"
#define CLI_DUMP "dump"
#define CLI_SAY "say"
+#define CLI_DISPLAY "display"
+#define CLI_SLEEP "sleep"
typedef enum {
INVALID_MODE,
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index f729a107..289d74e3 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -63,6 +63,9 @@ void detect_parameters(const int argc, const char *argv[],
/* Quiet mode - make the output more quiet */
quiet = true;
+ /* Silent mode - make not output at all */
+ silent = false;
+
/* Vesa mode isn't set until we explictly call it */
vesamode = false;
@@ -75,6 +78,8 @@ void detect_parameters(const int argc, const char *argv[],
for (int i = 1; i < argc; i++) {
if (!strncmp(argv[i], "quiet", 5)) {
quiet = true;
+ } else if (!strncmp(argv[i], "silent", 6)) {
+ silent = true;
} else if (!strncmp(argv[i], "verbose", 7)) {
quiet = false;
} else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
@@ -749,8 +754,8 @@ void detect_hardware(struct s_hardware *hardware)
if (!quiet)
more_printf("DMI: Detecting Table\n");
if (detect_dmi(hardware) == -ENODMITABLE) {
- printf("DMI: ERROR ! Table not found ! \n");
- printf("DMI: Many hardware components will not be detected ! \n");
+ more_printf("DMI: ERROR ! Table not found ! \n");
+ more_printf("DMI: Many hardware components will not be detected ! \n");
} else {
if (!quiet)
more_printf("DMI: Table found ! (version %u.%u)\n",
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index 4a288b44..53aa43e7 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -84,6 +84,9 @@ struct upload_backend *upload;
/* Defines if the cli is quiet*/
bool quiet;
+/* Defines if the cli is totally silent*/
+bool silent;
+
/* Defines if we must use the vesa mode */
bool vesamode;
@@ -111,16 +114,18 @@ extern bool disable_more_printf;
* one \n (and only one)
*/
#define more_printf(...) do {\
- if (__likely(!disable_more_printf)) {\
- if (display_line_nb == max_console_lines) {\
- display_line_nb=0;\
- printf("\n--More--");\
- get_key(stdin, 0);\
- printf("\033[2K\033[1G\033[1F");\
+ if (__likely(!silent)) {\
+ if (__likely(!disable_more_printf)) {\
+ if (display_line_nb == max_console_lines) {\
+ display_line_nb=0;\
+ printf("\n--More--");\
+ get_key(stdin, 0);\
+ printf("\033[2K\033[1G\033[1F");\
+ }\
+ display_line_nb++;\
}\
- display_line_nb++;\
+ printf(__VA_ARGS__);\
}\
- printf(__VA_ARGS__);\
} while (0);
/* Display CPU registers for debugging purposes */
diff --git a/com32/hdt/hdt-dump.c b/com32/hdt/hdt-dump.c
index b963e19b..b1748c8e 100644
--- a/com32/hdt/hdt-dump.c
+++ b/com32/hdt/hdt-dump.c
@@ -156,7 +156,7 @@ void flush(ZZJSON_CONFIG * config, ZZJSON ** item)
void dump(struct s_hardware *hardware)
{
if (hardware->is_pxe_valid == false) {
- printf("PXE stack was not detected, Dump feature is not available\n");
+ more_printf("PXE stack was not detected, Dump feature is not available\n");
return;
}
diff --git a/com32/hdt/hdt.c b/com32/hdt/hdt.c
index 851b0462..653995d0 100644
--- a/com32/hdt/hdt.c
+++ b/com32/hdt/hdt.c
@@ -72,7 +72,7 @@ int main(const int argc, const char *argv[])
clear_screen();
printf("\033[1;1H");
- printf("%s\n", version_string);
+ more_printf("%s\n", version_string);
int return_code = 0;
@@ -86,7 +86,7 @@ int main(const int argc, const char *argv[])
/* Do we got request to do something at exit time ? */
if (strlen(hardware.postexec)>0) {
- printf("Executing postexec instructions : %s\n",hardware.postexec);
+ more_printf("Executing postexec instructions : %s\n",hardware.postexec);
runsyslinuxcmd(hardware.postexec);
}
diff --git a/com32/hdt/hdt.h b/com32/hdt/hdt.h
index 041d726d..e385417a 100644
--- a/com32/hdt/hdt.h
+++ b/com32/hdt/hdt.h
@@ -33,7 +33,7 @@
#define AUTHOR "Erwan Velu"
#define CORE_DEVELOPER "Pierre-Alexandre Meyer"
#define CONTACT "hdt@zytor.com"
-#define VERSION "0.5.2-pre2"
+#define VERSION "0.5.2"
#define CODENAME "Manon"
#define NB_CONTRIBUTORS 3
#define CONTRIBUTORS {"Sebastien Gonzalve (Patches)", "Gert Hulselmans (Tests)", "Alexander Andino (Design)"}
diff --git a/com32/lua/src/cpu.c b/com32/lua/src/cpu.c
index 8a246e3d..6ef4e5a3 100644
--- a/com32/lua/src/cpu.c
+++ b/com32/lua/src/cpu.c
@@ -9,13 +9,13 @@
#include"lualib.h"
#include"cpuid.h"
-static void add_string_item(lua_State *L, const char *item, const char *value_str) {
+void add_string_item(lua_State *L, const char *item, const char *value_str) {
lua_pushstring(L,item);
lua_pushstring(L,value_str);
lua_settable(L,-3);
}
-static void add_int_item(lua_State *L, const char *item, int value_int) {
+void add_int_item(lua_State *L, const char *item, int value_int) {
lua_pushstring(L,item);
lua_pushnumber(L,value_int);
lua_settable(L,-3);
diff --git a/com32/lua/src/dmi.c b/com32/lua/src/dmi.c
index c8329d33..984fb60c 100644
--- a/com32/lua/src/dmi.c
+++ b/com32/lua/src/dmi.c
@@ -9,275 +9,487 @@
#include "lualib.h"
#include "dmi/dmi.h"
-static int dmi_gettable(lua_State *L)
+extern void add_string_item(lua_State*, const char*, const char*);
+extern void add_int_item(lua_State*, const char*, int);
+typedef int (*table_fn)(lua_State*, s_dmi*);
+
+/* Add a Lua_String entry to the table on stack
+ xxx_P is the poiter version (i.e., pBase is a pointer)
+ xxx_S is the staic version (i.e., Base is the struct)
+*/
+#define LUA_ADD_STR_P(pLua_state, pBase, Field) \
+ add_string_item(pLua_state, #Field, pBase->Field);
+#define LUA_ADD_STR_S(pLua_state, Base, Field) \
+ add_string_item(pLua_state, #Field, Base.Field);
+
+/* Add a Lua_Number entry to the table on stack
+ xxx_P is the poiter version (i.e., pBase is a pointer)
+ xxx_S is the staic version (i.e., Base is the struct)
+*/
+#define LUA_ADD_NUM_P(pLua_state, pBase, Field) \
+ add_int_item(pLua_state, #Field, pBase->Field);
+#define LUA_ADD_NUM_S(pLua_state, Base, Field) \
+ add_int_item(pLua_state, #Field, Base.Field);
+
+/* Add a sub-DMI table to the table on stack
+ All (*table_fn)() have to be named as get_<tabel_name>_table() for this
+ macro to work. For example, for the bios subtable, the table_fn is
+ get_bios_table() and the subtable name is "bios".
+ All (*table_fn)() have to return 1 if a subtable is created on the stack
+ or 0 if the subtable is not created (no corresponding dim subtable found).
+*/
+#define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \
+ add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table);
+
+
+static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name,
+ table_fn get_table_fn)
{
- s_dmi dmi;
-
- lua_newtable(L);
-
- if ( ! dmi_iterate(&dmi) ) {
- printf("No DMI Structure found\n");
- return -1;
+ if (get_table_fn(L, dmi_ptr)) { /* only adding it when it is there */
+ lua_pushstring(L, table_name);
+ lua_insert(L, -2);
+ lua_settable(L,-3);
}
+}
- parse_dmitable(&dmi);
-
- /* bios */
- lua_pushstring(L, "bios.vendor");
- lua_pushstring(L, dmi.bios.vendor);
- lua_settable(L,-3);
-
- lua_pushstring(L, "bios.version");
- lua_pushstring(L, dmi.bios.version);
- lua_settable(L,-3);
-
- lua_pushstring(L, "bios.release_date");
- lua_pushstring(L, dmi.bios.release_date);
- lua_settable(L,-3);
- lua_pushstring(L, "bios.bios_revision");
- lua_pushstring(L, dmi.bios.bios_revision);
- lua_settable(L,-3);
+void get_bool_table(lua_State *L, const char *str_table[], int n_elem,
+ bool *bool_table)
+{
+ int i;
+ for (i = 0; i < n_elem; i++) {
+ if (!str_table[i] || !*str_table[i]) /* aviod NULL/empty string */
+ continue;
+
+ lua_pushstring(L, str_table[i]);
+ lua_pushboolean(L, bool_table[i]);
+ lua_settable(L,-3);
+ }
+}
- lua_pushstring(L, "bios.firmware_revision");
- lua_pushstring(L, dmi.bios.firmware_revision);
- lua_settable(L,-3);
- lua_pushstring(L, "bios.address");
- lua_pushnumber(L, dmi.bios.address);
- lua_settable(L,-3);
+/*
+** {======================================================
+** DMI subtables
+** =======================================================
+*/
+static int get_bios_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_bios *bios = &dmi_ptr->bios;
- lua_pushstring(L, "bios.runtime_size");
- lua_pushnumber(L, dmi.bios.runtime_size);
+ if (!bios->filled)
+ return 0;
+ /* bios */
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, bios, vendor)
+ LUA_ADD_STR_P(L, bios, version)
+ LUA_ADD_STR_P(L, bios, release_date)
+ LUA_ADD_STR_P(L, bios, bios_revision)
+ LUA_ADD_STR_P(L, bios, firmware_revision)
+ LUA_ADD_NUM_P(L, bios, address)
+ LUA_ADD_NUM_P(L, bios, runtime_size)
+ LUA_ADD_STR_P(L, bios, runtime_size_unit)
+ LUA_ADD_NUM_P(L, bios, rom_size)
+ LUA_ADD_STR_P(L, bios, rom_size_unit)
+
+ /* bios characteristics */
+ lua_pushstring(L, "chars");
+ lua_newtable(L);
+ get_bool_table(L, bios_charac_strings,
+ sizeof(s_characteristics)/sizeof(bool),
+ (bool *)(&bios->characteristics));
+ get_bool_table(L, bios_charac_x1_strings,
+ sizeof(s_characteristics_x1)/sizeof(bool),
+ (bool *)(&bios->characteristics_x1));
+ get_bool_table(L, bios_charac_x2_strings,
+ sizeof(s_characteristics_x2)/sizeof(bool),
+ (bool *)(&bios->characteristics_x2));
lua_settable(L,-3);
- lua_pushstring(L, "bios.runtime_size_unit");
- lua_pushstring(L, dmi.bios.runtime_size_unit);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "bios.rom_size");
- lua_pushnumber(L, dmi.bios.rom_size);
- lua_settable(L,-3);
- lua_pushstring(L, "bios.rom_size_unit");
- lua_pushstring(L, dmi.bios.rom_size_unit);
- lua_settable(L,-3);
+static int get_system_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_system *system = &dmi_ptr->system;
+ if (!system->filled)
+ return 0;
/* system */
- lua_pushstring(L, "system.manufacturer");
- lua_pushstring(L, dmi.system.manufacturer);
- lua_settable(L,-3);
-
- lua_pushstring(L, "system.product_name");
- lua_pushstring(L, dmi.system.product_name);
- lua_settable(L,-3);
-
- lua_pushstring(L, "system.version");
- lua_pushstring(L, dmi.system.version);
- lua_settable(L,-3);
-
- lua_pushstring(L, "system.serial");
- lua_pushstring(L, dmi.system.serial);
- lua_settable(L,-3);
-
- lua_pushstring(L, "system.uuid");
- lua_pushstring(L, dmi.system.uuid);
- lua_settable(L,-3);
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, system, manufacturer)
+ LUA_ADD_STR_P(L, system, product_name)
+ LUA_ADD_STR_P(L, system, version)
+ LUA_ADD_STR_P(L, system, serial)
+ LUA_ADD_STR_P(L, system, uuid)
+ LUA_ADD_STR_P(L, system, wakeup_type)
+ LUA_ADD_STR_P(L, system, sku_number)
+ LUA_ADD_STR_P(L, system, family)
+ LUA_ADD_STR_P(L, system, system_boot_status)
+ LUA_ADD_STR_P(L, system, configuration_options)
+
+ /* system reset */
+ if (system->system_reset.filled) {
+ lua_pushstring(L, "reset");
+ lua_newtable(L);
+ LUA_ADD_NUM_S(L, system->system_reset, status)
+ LUA_ADD_NUM_S(L, system->system_reset, watchdog)
+ LUA_ADD_STR_S(L, system->system_reset, boot_option)
+ LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit)
+ LUA_ADD_STR_S(L, system->system_reset, reset_count)
+ LUA_ADD_STR_S(L, system->system_reset, reset_limit)
+ LUA_ADD_STR_S(L, system->system_reset, timer_interval)
+ LUA_ADD_STR_S(L, system->system_reset, timeout)
+ lua_settable(L,-3);
+ }
- lua_pushstring(L, "system.wakeup_type");
- lua_pushstring(L, dmi.system.wakeup_type);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "system.sku_number");
- lua_pushstring(L, dmi.system.sku_number);
- lua_settable(L,-3);
- lua_pushstring(L, "system.family");
- lua_pushstring(L, dmi.system.family);
- lua_settable(L,-3);
+static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_base_board *base_board = &dmi_ptr->base_board;
+ int n_dev = sizeof(base_board->devices_information) /
+ sizeof(base_board->devices_information[0]);
+ int i, j, has_dev;
+ if (!base_board->filled)
+ return 0;
/* base_board */
- lua_pushstring(L, "base_board.manufacturer");
- lua_pushstring(L, dmi.base_board.manufacturer);
- lua_settable(L,-3);
-
- lua_pushstring(L, "base_board.product_name");
- lua_pushstring(L, dmi.base_board.product_name);
- lua_settable(L,-3);
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, base_board, manufacturer)
+ LUA_ADD_STR_P(L, base_board, product_name)
+ LUA_ADD_STR_P(L, base_board, version)
+ LUA_ADD_STR_P(L, base_board, serial)
+ LUA_ADD_STR_P(L, base_board, asset_tag)
+ LUA_ADD_STR_P(L, base_board, location)
+ LUA_ADD_STR_P(L, base_board, type)
+
+ /* base board features */
+ lua_pushstring(L, "features");
+ lua_newtable(L);
+ get_bool_table(L, base_board_features_strings,
+ sizeof(s_base_board_features)/sizeof(bool),
+ (bool *)(&base_board->features));
+ lua_settable(L,-3);
+
+ /* on-board devices */
+ for (has_dev = 0, i = 0; i < n_dev; i++)
+ if (*base_board->devices_information[i].type)
+ has_dev++;
+
+ if (has_dev) {
+ lua_pushstring(L, "devices");
+ lua_newtable(L);
+ for (i = 0, j = 1; i < n_dev; i++) {
+ if (!*base_board->devices_information[i].type) /* empty device */
+ continue;
+
+ lua_pushinteger(L, j++);
+ lua_newtable(L);
+ LUA_ADD_STR_S(L, base_board->devices_information[i], type)
+ LUA_ADD_STR_S(L, base_board->devices_information[i], description)
+ LUA_ADD_NUM_S(L, base_board->devices_information[i], status)
+ lua_settable(L,-3);
+ }
+ lua_settable(L,-3);
+ }
- lua_pushstring(L, "base_board.version");
- lua_pushstring(L, dmi.base_board.version);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "base_board.serial");
- lua_pushstring(L, dmi.base_board.serial);
- lua_settable(L,-3);
- lua_pushstring(L, "base_board.asset_tag");
- lua_pushstring(L, dmi.base_board.asset_tag);
- lua_settable(L,-3);
+static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_chassis *chassis = &dmi_ptr->chassis;
- lua_pushstring(L, "base_board.location");
- lua_pushstring(L, dmi.base_board.location);
- lua_settable(L,-3);
+ if (!chassis->filled)
+ return 0;
+ /* chassis */
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, chassis, manufacturer)
+ LUA_ADD_STR_P(L, chassis, type)
+ LUA_ADD_STR_P(L, chassis, lock)
+ LUA_ADD_STR_P(L, chassis, version)
+ LUA_ADD_STR_P(L, chassis, serial)
+ LUA_ADD_STR_P(L, chassis, asset_tag)
+ LUA_ADD_STR_P(L, chassis, boot_up_state)
+ LUA_ADD_STR_P(L, chassis, power_supply_state)
+ LUA_ADD_STR_P(L, chassis, thermal_state)
+ LUA_ADD_STR_P(L, chassis, security_status)
+ LUA_ADD_STR_P(L, chassis, oem_information)
+ LUA_ADD_NUM_P(L, chassis, height)
+ LUA_ADD_NUM_P(L, chassis, nb_power_cords)
- lua_pushstring(L, "base_board.type");
- lua_pushstring(L, dmi.base_board.type);
- lua_settable(L,-3);
+ return 1;
+}
- /* chassis */
- lua_pushstring(L, "chassis.manufacturer");
- lua_pushstring(L, dmi.chassis.manufacturer);
- lua_settable(L,-3);
- lua_pushstring(L, "chassis.type");
- lua_pushstring(L, dmi.chassis.type);
- lua_settable(L,-3);
+static int get_processor_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_processor *processor = &dmi_ptr->processor;
+ s_signature *signature = &processor->signature;
- lua_pushstring(L, "chassis.lock");
- lua_pushstring(L, dmi.chassis.lock);
+ if (!processor->filled)
+ return 0;
+ /* processor */
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, processor, socket_designation)
+ LUA_ADD_STR_P(L, processor, type)
+ LUA_ADD_STR_P(L, processor, family)
+ LUA_ADD_STR_P(L, processor, manufacturer)
+ LUA_ADD_STR_P(L, processor, version)
+ LUA_ADD_NUM_P(L, processor, external_clock)
+ LUA_ADD_NUM_P(L, processor, max_speed)
+ LUA_ADD_NUM_P(L, processor, current_speed)
+ LUA_ADD_NUM_P(L, processor, voltage_mv)
+ LUA_ADD_STR_P(L, processor, status)
+ LUA_ADD_STR_P(L, processor, upgrade)
+ LUA_ADD_STR_P(L, processor, cache1)
+ LUA_ADD_STR_P(L, processor, cache2)
+ LUA_ADD_STR_P(L, processor, cache3)
+ LUA_ADD_STR_P(L, processor, serial)
+ LUA_ADD_STR_P(L, processor, part_number)
+ LUA_ADD_STR_P(L, processor, id)
+ LUA_ADD_NUM_P(L, processor, core_count)
+ LUA_ADD_NUM_P(L, processor, core_enabled)
+ LUA_ADD_NUM_P(L, processor, thread_count)
+
+ /* processor signature */
+ lua_pushstring(L, "signature");
+ lua_newtable(L);
+ LUA_ADD_NUM_P(L, signature, type)
+ LUA_ADD_NUM_P(L, signature, family)
+ LUA_ADD_NUM_P(L, signature, model)
+ LUA_ADD_NUM_P(L, signature, stepping)
+ LUA_ADD_NUM_P(L, signature, minor_stepping)
lua_settable(L,-3);
- lua_pushstring(L, "chassis.version");
- lua_pushstring(L, dmi.chassis.version);
+ /* processor flags */
+ lua_pushstring(L, "flags");
+ lua_newtable(L);
+ get_bool_table(L, cpu_flags_strings,
+ sizeof(s_dmi_cpu_flags)/sizeof(bool),
+ (bool *)(&processor->cpu_flags));
lua_settable(L,-3);
- lua_pushstring(L, "chassis.serial");
- lua_pushstring(L, dmi.chassis.serial);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "chassis.asset_tag");
- lua_pushstring(L, dmi.chassis.asset_tag);
- lua_settable(L,-3);
- lua_pushstring(L, "chassis.boot_up_state");
- lua_pushstring(L, dmi.chassis.boot_up_state);
- lua_settable(L,-3);
+static int get_battery_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_battery *battery = &dmi_ptr->battery;
- lua_pushstring(L, "chassis.power_supply_state");
- lua_pushstring(L, dmi.chassis.power_supply_state);
- lua_settable(L,-3);
+ if (!battery->filled)
+ return 0;
+ /* battery */
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, battery, location)
+ LUA_ADD_STR_P(L, battery, manufacturer)
+ LUA_ADD_STR_P(L, battery, manufacture_date)
+ LUA_ADD_STR_P(L, battery, serial)
+ LUA_ADD_STR_P(L, battery, name)
+ LUA_ADD_STR_P(L, battery, chemistry)
+ LUA_ADD_STR_P(L, battery, design_capacity)
+ LUA_ADD_STR_P(L, battery, design_voltage)
+ LUA_ADD_STR_P(L, battery, sbds)
+ LUA_ADD_STR_P(L, battery, sbds_serial)
+ LUA_ADD_STR_P(L, battery, maximum_error)
+ LUA_ADD_STR_P(L, battery, sbds_manufacture_date)
+ LUA_ADD_STR_P(L, battery, sbds_chemistry)
+ LUA_ADD_STR_P(L, battery, oem_info)
- lua_pushstring(L, "chassis.thermal_state");
- lua_pushstring(L, dmi.chassis.thermal_state);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "chassis.security_status");
- lua_pushstring(L, dmi.chassis.security_status);
- lua_settable(L,-3);
- lua_pushstring(L, "chassis.oem_information");
- lua_pushstring(L, dmi.chassis.oem_information);
- lua_settable(L,-3);
+static int get_memory_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_memory *memory = dmi_ptr->memory;
+ int i, j, n_mem = dmi_ptr->memory_count;
- lua_pushstring(L, "chassis.height");
- lua_pushnumber(L, dmi.chassis.height);
- lua_settable(L,-3);
+ if (n_mem <= 0) /* no memory info */
+ return 0;
- lua_pushstring(L, "chassis.nb_power_cords");
- lua_pushnumber(L, dmi.chassis.nb_power_cords);
- lua_settable(L,-3);
+ /* memory */
+ lua_newtable(L);
+ for (j = 1, i = 0; i < n_mem; i++) {
+ if (!memory[i].filled)
+ continue;
+
+ lua_pushinteger(L, j++);
+ lua_newtable(L);
+ LUA_ADD_STR_S(L, memory[i], manufacturer)
+ LUA_ADD_STR_S(L, memory[i], error)
+ LUA_ADD_STR_S(L, memory[i], total_width)
+ LUA_ADD_STR_S(L, memory[i], data_width)
+ LUA_ADD_STR_S(L, memory[i], size)
+ LUA_ADD_STR_S(L, memory[i], form_factor)
+ LUA_ADD_STR_S(L, memory[i], device_set)
+ LUA_ADD_STR_S(L, memory[i], device_locator)
+ LUA_ADD_STR_S(L, memory[i], bank_locator)
+ LUA_ADD_STR_S(L, memory[i], type)
+ LUA_ADD_STR_S(L, memory[i], type_detail)
+ LUA_ADD_STR_S(L, memory[i], speed)
+ LUA_ADD_STR_S(L, memory[i], serial)
+ LUA_ADD_STR_S(L, memory[i], asset_tag)
+ LUA_ADD_STR_S(L, memory[i], part_number)
+ lua_settable(L,-3);
+ }
+ return 1;
+}
- /* processor */
- lua_pushstring(L, "processor.socket_designation");
- lua_pushstring(L, dmi.processor.socket_designation);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.type");
- lua_pushstring(L, dmi.processor.type);
- lua_settable(L,-3);
+static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_memory_module *memory_module = dmi_ptr->memory_module;
+ int i, j, n_mem = dmi_ptr->memory_module_count;
- lua_pushstring(L, "processor.family");
- lua_pushstring(L, dmi.processor.family);
- lua_settable(L,-3);
+ if (n_mem <= 0) /* no memory module info */
+ return 0;
- lua_pushstring(L, "processor.manufacturer");
- lua_pushstring(L, dmi.processor.manufacturer);
- lua_settable(L,-3);
+ /* memory module */
+ lua_newtable(L);
+ for (j = 1, i = 0; i < n_mem; i++) {
+ if (!memory_module[i].filled)
+ continue;
+
+ lua_pushinteger(L, j++);
+ lua_newtable(L);
+ LUA_ADD_STR_S(L, memory_module[i], socket_designation)
+ LUA_ADD_STR_S(L, memory_module[i], bank_connections)
+ LUA_ADD_STR_S(L, memory_module[i], speed)
+ LUA_ADD_STR_S(L, memory_module[i], type)
+ LUA_ADD_STR_S(L, memory_module[i], installed_size)
+ LUA_ADD_STR_S(L, memory_module[i], enabled_size)
+ LUA_ADD_STR_S(L, memory_module[i], error_status)
+ lua_settable(L,-3);
+ }
+ return 1;
+}
- lua_pushstring(L, "processor.version");
- lua_pushstring(L, dmi.processor.version);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.external_clock");
- lua_pushnumber(L, dmi.processor.external_clock);
- lua_settable(L,-3);
+static int get_cache_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_cache *cache = dmi_ptr->cache;
+ int i, n_cache = dmi_ptr->cache_count;
- lua_pushstring(L, "processor.max_speed");
- lua_pushnumber(L, dmi.processor.max_speed);
- lua_settable(L,-3);
+ if (n_cache <= 0) /* no cache info */
+ return 0;
- lua_pushstring(L, "processor.current_speed");
- lua_pushnumber(L, dmi.processor.current_speed);
- lua_settable(L,-3);
+ /* memory */
+ lua_newtable(L);
+ for (i = 0; i < n_cache; i++) {
+ lua_pushinteger(L, i + 1);
+ lua_newtable(L);
+ LUA_ADD_STR_S(L, cache[i], socket_designation)
+ LUA_ADD_STR_S(L, cache[i], configuration)
+ LUA_ADD_STR_S(L, cache[i], mode)
+ LUA_ADD_STR_S(L, cache[i], location)
+ LUA_ADD_NUM_S(L, cache[i], installed_size)
+ LUA_ADD_NUM_S(L, cache[i], max_size)
+ LUA_ADD_STR_S(L, cache[i], supported_sram_types)
+ LUA_ADD_STR_S(L, cache[i], installed_sram_types)
+ LUA_ADD_NUM_S(L, cache[i], speed)
+ LUA_ADD_STR_S(L, cache[i], error_correction_type)
+ LUA_ADD_STR_S(L, cache[i], system_type)
+ LUA_ADD_STR_S(L, cache[i], associativity)
+ lua_settable(L,-3);
+ }
+ return 1;
+}
- lua_pushstring(L, "processor.signature.type");
- lua_pushnumber(L, dmi.processor.signature.type);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.signature.family");
- lua_pushnumber(L, dmi.processor.signature.family);
- lua_settable(L,-3);
+static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ if (!dmi_ptr->hardware_security.filled)
+ return 0;
+ /* hardware_security */
+ lua_newtable(L);
+ LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status)
+ LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status)
+ LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status)
+ LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status)
- lua_pushstring(L, "processor.signature.model");
- lua_pushnumber(L, dmi.processor.signature.model);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "processor.signature.stepping");
- lua_pushnumber(L, dmi.processor.signature.stepping);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.signature.minor_stepping");
- lua_pushnumber(L, dmi.processor.signature.minor_stepping);
- lua_settable(L,-3);
+static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ dmi_table *dmitable = &dmi_ptr->dmitable;
- lua_pushstring(L, "processor.voltage_mv");
- lua_pushnumber(L, dmi.processor.voltage_mv);
- lua_settable(L,-3);
+ /* dmi info */
+ lua_newtable(L);
+ LUA_ADD_NUM_P(L, dmitable, num)
+ LUA_ADD_NUM_P(L, dmitable, len)
+ LUA_ADD_NUM_P(L, dmitable, ver)
+ LUA_ADD_NUM_P(L, dmitable, base)
+ LUA_ADD_NUM_P(L, dmitable, major_version)
+ LUA_ADD_NUM_P(L, dmitable, minor_version)
- lua_pushstring(L, "processor.status");
- lua_pushstring(L, dmi.processor.status);
- lua_settable(L,-3);
+ return 1;
+}
- lua_pushstring(L, "processor.upgrade");
- lua_pushstring(L, dmi.processor.upgrade);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.cache1");
- lua_pushstring(L, dmi.processor.cache1);
- lua_settable(L,-3);
+static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr)
+{
+ s_ipmi *ipmi = &dmi_ptr->ipmi;
- lua_pushstring(L, "processor.cache2");
- lua_pushstring(L, dmi.processor.cache2);
- lua_settable(L,-3);
+ if (!ipmi->filled)
+ return 0;
+ /* ipmi */
+ lua_newtable(L);
+ LUA_ADD_STR_P(L, ipmi, interface_type)
+ LUA_ADD_NUM_P(L, ipmi, major_specification_version)
+ LUA_ADD_NUM_P(L, ipmi, minor_specification_version)
+ LUA_ADD_NUM_P(L, ipmi, I2C_slave_address)
+ LUA_ADD_NUM_P(L, ipmi, nv_address)
+ LUA_ADD_NUM_P(L, ipmi, base_address)
+ LUA_ADD_NUM_P(L, ipmi, irq)
- lua_pushstring(L, "processor.cache3");
- lua_pushstring(L, dmi.processor.cache3);
- lua_settable(L,-3);
+ return 1;
+}
+/*
+** {======================================================
+** End of DMI subtables
+** =======================================================
+*/
- lua_pushstring(L, "processor.serial");
- lua_pushstring(L, dmi.processor.serial);
- lua_settable(L,-3);
- lua_pushstring(L, "processor.part_number");
- lua_pushstring(L, dmi.processor.part_number);
- lua_settable(L,-3);
+static int dmi_gettable(lua_State *L)
+{
+ s_dmi dmi;
- lua_pushstring(L, "processor.id");
- lua_pushstring(L, dmi.processor.id);
- lua_settable(L,-3);
+ lua_newtable(L);
- lua_pushstring(L, "processor.core_count");
- lua_pushnumber(L, dmi.processor.core_count);
- lua_settable(L,-3);
+ if ( ! dmi_iterate(&dmi) ) {
+ printf("No DMI Structure found\n");
+ return -1;
+ }
- lua_pushstring(L, "processor.core_enabled");
- lua_pushnumber(L, dmi.processor.core_enabled);
- lua_settable(L,-3);
+ parse_dmitable(&dmi);
- lua_pushstring(L, "processor.thread_count");
- lua_pushnumber(L, dmi.processor.thread_count);
- lua_settable(L,-3);
+ LUA_ADD_NUM_S(L, dmi, memory_module_count)
+ LUA_ADD_NUM_S(L, dmi, memory_count)
+ LUA_ADD_NUM_S(L, dmi, cache_count)
+ LUA_ADD_STR_S(L, dmi, oem_strings)
+
+ LUA_ADD_TABLE(L, &dmi, bios)
+ LUA_ADD_TABLE(L, &dmi, system)
+ LUA_ADD_TABLE(L, &dmi, base_board)
+ LUA_ADD_TABLE(L, &dmi, chassis)
+ LUA_ADD_TABLE(L, &dmi, processor)
+ LUA_ADD_TABLE(L, &dmi, battery)
+ LUA_ADD_TABLE(L, &dmi, memory)
+ LUA_ADD_TABLE(L, &dmi, memory_module)
+ LUA_ADD_TABLE(L, &dmi, cache)
+ LUA_ADD_TABLE(L, &dmi, ipmi)
+ LUA_ADD_TABLE(L, &dmi, hardware_security)
+ LUA_ADD_TABLE(L, &dmi, dmi_info)
/* set global variable: lua_setglobal(L, "dmitable"); */
diff --git a/com32/lua/src/liolib.c b/com32/lua/src/liolib.c
index 3f27395d..cf9dca22 100644
--- a/com32/lua/src/liolib.c
+++ b/com32/lua/src/liolib.c
@@ -18,12 +18,18 @@
#include "lauxlib.h"
#include "lualib.h"
-
+#ifdef SYSLINUX
+ #define NO_TMP_FILE 1
+ #define NO_READ_NUMBER 1
+ #define NO_TEST_EOF 1
+ #define NO_CLEAR_ERR 1
+ #define NO_F_SEEK 1
+ #define NO_F_SETVBUF 1
+#endif
#define IO_INPUT 1
#define IO_OUTPUT 2
-
static const char *const fnames[] = {"input", "output"};
@@ -180,7 +186,7 @@ static int io_popen (lua_State *L) {
}
-#ifndef SYSLINUX
+#ifndef NO_TMP_FILE
static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
@@ -271,7 +277,7 @@ static int io_lines (lua_State *L) {
** =======================================================
*/
-#ifndef SYSLINUX
+#ifndef NO_READ_NUMBER /* No fscanf() and thus no read_number() */
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
@@ -283,8 +289,9 @@ static int read_number (lua_State *L, FILE *f) {
return 0; /* read fails */
}
}
+#endif
-
+#ifndef NO_TEST_EOF /* no buffering -> no ungetc() -> no EOF test */
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
@@ -315,7 +322,6 @@ static int read_line (lua_State *L, FILE *f) {
}
}
-#ifndef SYSLINUX /* Not used */
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */
@@ -337,7 +343,9 @@ static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
+#ifndef NO_CLEAR_ERR
clearerr(f);
+#endif
if (nargs == 0) { /* no arguments? */
success = read_line(L, f);
n = first+1; /* to return 1 result */
@@ -348,14 +356,22 @@ static int g_read (lua_State *L, FILE *f, int first) {
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
+#ifndef NO_TEST_EOF
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
+#else /* we don't have test_eof defined */
+ success = (l == 0) ? 1 : read_chars(L, f, l);
+#endif
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
+#ifndef NO_READ_NUMBER
success = read_number(L, f);
+#else
+ return luaL_argerror(L, n, "\"*number\" not supported");
+#endif
break;
case 'l': /* line */
success = read_line(L, f);
@@ -388,7 +404,6 @@ static int io_read (lua_State *L) {
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
-#endif
static int io_readline (lua_State *L) {
@@ -441,7 +456,7 @@ static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}
-#ifndef SYSLINUX
+#ifndef NO_F_SEEK
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
@@ -456,8 +471,9 @@ static int f_seek (lua_State *L) {
return 1;
}
}
+#endif
-
+#ifndef NO_F_SETVBUF
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
@@ -488,8 +504,8 @@ static const luaL_Reg iolib[] = {
{"open", io_open},
{"output", io_output},
{"popen", io_popen},
-#ifndef SYSLINUX
{"read", io_read},
+#ifndef NO_TMP_FILE
{"tmpfile", io_tmpfile},
#endif
{"type", io_type},
@@ -502,9 +518,11 @@ static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
-#ifndef SYSLINUX
{"read", f_read},
+#ifndef NO_F_SEEK
{"seek", f_seek},
+#endif
+#ifndef NO_F_SETVBUF
{"setvbuf", f_setvbuf},
#endif
{"write", f_write},
diff --git a/com32/lua/src/syslinux.c b/com32/lua/src/syslinux.c
index af5db834..afcdcaad 100644
--- a/com32/lua/src/syslinux.c
+++ b/com32/lua/src/syslinux.c
@@ -39,6 +39,7 @@
#include "syslinux/loadfile.h"
#include "syslinux/linux.h"
#include "syslinux/config.h"
+#include "syslinux/reboot.h"
int __parse_argv(char ***argv, const char *str);
@@ -408,6 +409,35 @@ static int sl_boot_it(lua_State * L)
initramfs, NULL, (char *)cmdline);
}
+static int sl_config_file(lua_State * L)
+{
+ const char *config_file = syslinux_config_file();
+ lua_pushstring(L, config_file);
+ return 1;
+}
+
+static int sl_reboot(lua_State * L)
+{
+ int warm_boot = luaL_optint(L, 1, 0);
+ /* explicitly convert it to 1 or 0 */
+ warm_boot = warm_boot? 1 : 0;
+ syslinux_reboot(warm_boot);
+ return 0;
+}
+
+static int sl_ipappend_strs(lua_State * L)
+{
+ int i;
+ const struct syslinux_ipappend_strings *ip_strs = syslinux_ipappend_strings();
+ lua_newtable(L);
+ for (i = 0; i < ip_strs->count; i++) {
+ lua_pushinteger(L, i + 1);
+ lua_pushstring(L, ip_strs->ptr[i]);
+ lua_settable(L,-3);
+ }
+ return 1;
+}
+
static int sl_derivative(lua_State * L)
{
const struct syslinux_version *sv;
@@ -459,6 +489,9 @@ static const luaL_reg syslinuxlib[] = {
{"initramfs_load_archive", sl_initramfs_load_archive},
{"initramfs_add_file", sl_initramfs_add_file},
{"boot_it", sl_boot_it},
+ {"config_file", sl_config_file},
+ {"ipappend_strs", sl_ipappend_strs},
+ {"reboot", sl_reboot},
{"derivative", sl_derivative},
{"version", sl_version},
{NULL, NULL}
diff --git a/com32/mboot/mboot.c b/com32/mboot/mboot.c
index 35450e03..10e6701c 100644
--- a/com32/mboot/mboot.c
+++ b/com32/mboot/mboot.c
@@ -198,7 +198,7 @@ int main(int argc, char *argv[])
}
if (init_map())
- return 1; /* Failed to allocate intitial map */
+ return 1; /* Failed to allocate initial map */
/*
* Map the primary image. This should be done before mapping anything
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index c9762b27..487f8299 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -808,7 +808,7 @@ static const char *run_menu(void)
while (entry < cm->nentries && is_disabled(cm->menu_entries[entry]))
entry++;
}
- if (entry >= cm->nentries) {
+ if (entry >= cm->nentries - 1) {
entry = cm->nentries - 1;
while (entry > 0 && is_disabled(cm->menu_entries[entry]))
entry--;
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 69f524c4..cffe8e3d 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -392,7 +392,9 @@ static void record(struct menu *m, struct labeldata *ld, const char *append)
break;
}
- if (ld->menudefault && me->action == MA_CMD)
+ if (ld->menudefault && (me->action == MA_CMD ||
+ me->action == MA_GOTO ||
+ me->action == MA_GOTO_UNRES))
m->defentry = m->nentries - 1;
}
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index fcdf0471..ee428e30 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -24,7 +24,7 @@ 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 pxechn.c32
+ whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32
TESTFILES =
diff --git a/com32/modules/kontron_wdt.c b/com32/modules/kontron_wdt.c
new file mode 100644
index 00000000..4e1d2535
--- /dev/null
+++ b/com32/modules/kontron_wdt.c
@@ -0,0 +1,414 @@
+/*
+ * kempld_wdt.c - Kontron PLD watchdog driver
+ *
+ * Copyright (c) 2010 Kontron Embedded Modules GmbH
+ * Author: Michael Brunner <michael.brunner@kontron.com>
+ * Author: Erwan Velu <erwan.velu@zodiacaerospace.com>
+ *
+ * Note: From the PLD watchdog point of view timeout and pretimeout are
+ * defined differently than in the kernel.
+ * First the pretimeout stage runs out before the timeout stage gets
+ * active. This has to be kept in mind.
+ *
+ * Kernel/API: P-----| pretimeout
+ * |-----------------------T timeout
+ * Watchdog: |-----------------P pretimeout_stage
+ * |-----T timeout_stage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <string.h>
+#include <sys/io.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include "kontron_wdt.h"
+
+struct kempld_device_data pld;
+struct kempld_watchdog_data wdt;
+uint8_t status;
+char default_label[255];
+
+/* Default Timeout is 60sec */
+#define TIMEOUT 60
+#define PRETIMEOUT 0
+
+#define do_div(n,base) ({ \
+ int __res; \
+ __res = ((unsigned long) n) % (unsigned) base; \
+ n = ((unsigned long) n) / (unsigned) base; \
+ __res; })
+
+
+/* Basic Wrappers to get code as less changed as possible */
+void iowrite8(uint8_t val, uint16_t addr) { outb(val,addr); }
+void iowrite16(uint16_t val, uint16_t addr) { outw(val,addr); }
+void iowrite32(uint32_t val, uint16_t addr) { outl(val,addr);}
+uint8_t ioread8(uint16_t addr) { return inb(addr);}
+uint16_t ioread16(uint16_t addr) { return inw(addr);}
+uint32_t ioread32(uint32_t addr) { return inl(addr);}
+
+
+/**
+ * kempld_set_index - change the current register index of the PLD
+ * @pld: kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * This function changes the register index of the PLD.
+ */
+void kempld_set_index(struct kempld_device_data *pld, uint8_t index)
+{
+ if (pld->last_index != index) {
+ iowrite8(index, pld->io_index);
+ pld->last_index = index;
+ }
+}
+
+
+uint8_t kempld_read8(struct kempld_device_data *pld, uint8_t index) {
+ kempld_set_index(pld, index);
+ return ioread8(pld->io_data);
+}
+
+
+void kempld_write8(struct kempld_device_data *pld, uint8_t index, uint8_t data) {
+ kempld_set_index(pld, index);
+ iowrite8(data, pld->io_data);
+}
+
+
+uint16_t kempld_read16(struct kempld_device_data *pld, uint8_t index)
+{
+ return kempld_read8(pld, index) | kempld_read8(pld, index+1) << 8;
+}
+
+
+void kempld_write16(struct kempld_device_data *pld, uint8_t index, uint16_t data)
+{
+ kempld_write8(pld, index, (uint8_t)data);
+ kempld_write8(pld, index+1, (uint8_t)(data>>8));
+}
+
+uint32_t kempld_read32(struct kempld_device_data *pld, uint8_t index)
+{
+ return kempld_read16(pld, index) | kempld_read16(pld, index+2) << 16;
+}
+
+void kempld_write32(struct kempld_device_data *pld, uint8_t index, uint32_t data)
+{
+ kempld_write16(pld, index, (uint16_t)data);
+ kempld_write16(pld, index+2, (uint16_t)(data>>16));
+}
+
+static void kempld_release_mutex(struct kempld_device_data *pld)
+{
+ iowrite8(pld->last_index | KEMPLD_MUTEX_KEY, pld->io_index);
+}
+
+void init_structure(void) {
+ /* set default values for the case we start the watchdog or change
+ * the configuration */
+ memset(&wdt,0,sizeof(wdt));
+ memset(&pld,0,sizeof(pld));
+ memset(&default_label,0,sizeof(default_label));
+ wdt.timeout = TIMEOUT;
+ wdt.pretimeout = PRETIMEOUT;
+ wdt.pld = &pld;
+
+ pld.io_base=KEMPLD_IOPORT;
+ pld.io_index=KEMPLD_IOPORT;
+ pld.io_data=KEMPLD_IODATA;
+ pld.pld_clock=33333333;
+}
+
+static int kempld_probe(void) {
+ /* Check for empty IO space */
+ int ret=0;
+ uint8_t index_reg = ioread8(pld.io_index);
+ if ((index_reg == 0xff) && (ioread8(pld.io_data) == 0xff)) {
+ ret = 1;
+ goto err_empty_io;
+ }
+ printf("Kempld structure found at 0x%X (data @ 0x%X)\n",pld.io_base,pld.io_data);
+ return 0;
+
+err_empty_io:
+ printf("No IO Found !\n");
+ return ret;
+}
+
+static int kempld_wdt_probe_stages(struct kempld_watchdog_data *wdt)
+{
+ struct kempld_device_data *pld = wdt->pld;
+ int i, ret;
+ uint32_t timeout;
+ uint32_t timeout_mask;
+ struct kempld_watchdog_stage *stage;
+
+ wdt->stages = 0;
+ wdt->timeout_stage = NULL;
+ wdt->pretimeout_stage = NULL;
+
+ for (i = 0; i < KEMPLD_WDT_MAX_STAGES; i++) {
+
+ timeout = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+ kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), 0x00000000);
+ timeout_mask = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+ kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), timeout);
+
+ if (timeout_mask != 0xffffffff) {
+ stage = malloc(sizeof(struct kempld_watchdog_stage));
+ if (stage == NULL) {
+ ret = -1;
+ goto err_alloc_stages;
+ }
+ stage->num = i;
+ stage->timeout_mask = ~timeout_mask;
+ wdt->stage[i] = stage;
+ wdt->stages++;
+
+ /* assign available stages to timeout and pretimeout */
+ if (wdt->stages == 1)
+ wdt->timeout_stage = stage;
+ else if (wdt->stages == 2) {
+ wdt->pretimeout_stage = wdt->timeout_stage;
+ wdt->timeout_stage = stage;
+ }
+ } else {
+ wdt->stage[i] = NULL;
+ }
+ }
+
+ return 0;
+err_alloc_stages:
+ kempld_release_mutex(pld);
+ printf("Cannot allocate stages\n");
+ return ret;
+}
+
+static int kempld_wdt_keepalive(struct kempld_watchdog_data *wdt)
+{
+ struct kempld_device_data *pld = wdt->pld;
+
+ kempld_write8(pld, KEMPLD_WDT_KICK, 'K');
+
+ return 0;
+}
+
+static int kempld_wdt_setstageaction(struct kempld_watchdog_data *wdt,
+ struct kempld_watchdog_stage *stage,
+ int action)
+{
+ struct kempld_device_data *pld = wdt->pld;
+ uint8_t stage_cfg;
+
+ if (stage == NULL)
+ return -1;
+
+ stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+ stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ACTION_MASK;
+ stage_cfg |= (action & KEMPLD_WDT_STAGE_CFG_ACTION_MASK);
+ if (action == KEMPLD_WDT_ACTION_RESET)
+ stage_cfg |= KEMPLD_WDT_STAGE_CFG_ASSERT;
+ else
+ stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ASSERT;
+
+ kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+ stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+
+ return 0;
+}
+
+static int kempld_wdt_setstagetimeout(struct kempld_watchdog_data *wdt,
+ struct kempld_watchdog_stage *stage,
+ int timeout)
+{
+ struct kempld_device_data *pld = wdt->pld;
+ uint8_t stage_cfg;
+ uint8_t prescaler;
+ uint64_t stage_timeout64;
+ uint32_t stage_timeout;
+
+ if (stage == NULL)
+ return -1;
+
+ prescaler = KEMPLD_WDT_PRESCALER_21BIT;
+
+ stage_timeout64 = ((uint64_t)timeout*pld->pld_clock);
+ do_div(stage_timeout64, KEMPLD_PRESCALER(prescaler));
+ stage_timeout = stage_timeout64 & stage->timeout_mask;
+
+ if (stage_timeout64 != (uint64_t)stage_timeout)
+ return -1;
+
+ stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+ stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK;
+ stage_cfg |= KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(prescaler);
+ kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+ kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->num),
+ stage_timeout);
+
+ return 0;
+}
+
+
+static int kempld_wdt_settimeout(struct kempld_watchdog_data *wdt)
+{
+ int stage_timeout;
+ int stage_pretimeout;
+ int ret;
+ if ((wdt->timeout <= 0) ||
+ (wdt->pretimeout < 0) ||
+ (wdt->pretimeout > wdt->timeout)) {
+ ret = -1;
+ goto err_check_values;
+ }
+
+ if ((wdt->pretimeout == 0) || (wdt->pretimeout_stage == NULL)) {
+ if (wdt->pretimeout != 0)
+ printf("No pretimeout stage available, only enabling reset!\n");
+ stage_pretimeout = 0;
+ stage_timeout = wdt->timeout;
+ } else {
+ stage_pretimeout = wdt->timeout - wdt->pretimeout;
+ stage_timeout = wdt->pretimeout;
+ }
+
+ if (stage_pretimeout != 0) {
+ ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+ KEMPLD_WDT_ACTION_NMI);
+ } else if ((stage_pretimeout == 0)
+ && (wdt->pretimeout_stage != NULL)) {
+ ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+ KEMPLD_WDT_ACTION_NONE);
+ } else
+ ret = 0;
+ if (ret)
+ goto err_setstage;
+
+ if (stage_pretimeout != 0) {
+ ret = kempld_wdt_setstagetimeout(wdt, wdt->pretimeout_stage,
+ stage_pretimeout);
+ if (ret)
+ goto err_setstage;
+ }
+
+ ret = kempld_wdt_setstageaction(wdt, wdt->timeout_stage,
+ KEMPLD_WDT_ACTION_RESET);
+ if (ret)
+ goto err_setstage;
+
+ ret = kempld_wdt_setstagetimeout(wdt, wdt->timeout_stage,
+ stage_timeout);
+ if (ret)
+ goto err_setstage;
+
+ return 0;
+err_setstage:
+err_check_values:
+ return ret;
+}
+
+static int kempld_wdt_start(struct kempld_watchdog_data *wdt)
+{
+ struct kempld_device_data *pld = wdt->pld;
+ uint8_t status;
+
+ status = kempld_read8(pld, KEMPLD_WDT_CFG);
+ status |= KEMPLD_WDT_CFG_ENABLE;
+ kempld_write8(pld, KEMPLD_WDT_CFG, status);
+ status = kempld_read8(pld, KEMPLD_WDT_CFG);
+
+ /* check if the watchdog was enabled */
+ if (!(status & KEMPLD_WDT_CFG_ENABLE))
+ return -1;
+
+ return 0;
+}
+
+/* A regular configuration file looks like
+
+ LABEL WDT
+ COM32 wdt.c32
+ APPEND timeout=120 default_label=local
+*/
+void detect_parameters(const int argc, const char *argv[]) {
+ for (int i = 1; i < argc; i++) {
+ /* Override the timeout if specified on the cmdline */
+ if (!strncmp(argv[i], "timeout=", 8)) {
+ wdt.timeout=atoi(argv[i]+8);
+ } else
+ /* Define which boot entry shall be used */
+ if (!strncmp(argv[i], "default_label=", 14)) {
+ strlcpy(default_label, argv[i] + 14, sizeof(default_label));
+ }
+ }
+}
+
+int main(int argc, const char *argv[]) {
+ int ret=0;
+ openconsole(&dev_rawcon_r, &dev_stdcon_w);
+ init_structure();
+ detect_parameters(argc,argv);
+ kempld_probe();
+
+ /* probe how many usable stages we have */
+ if (kempld_wdt_probe_stages(&wdt)) {
+ printf("Cannot Probe Stages\n");
+ return -1;
+ }
+
+ /* Useless but who knows */
+ wdt.ident.firmware_version = KEMPLD_WDT_REV_GET(kempld_read8(&pld, KEMPLD_WDT_REV));
+
+ status = kempld_read8(&pld, KEMPLD_WDT_CFG);
+ /* kick the watchdog if it is already enabled, otherwise start it */
+ if (status & KEMPLD_WDT_CFG_ENABLE) {
+ /* Maybye the BIOS did setup a first timer
+ * in this case, let's enforce the timeout
+ * to be sure we do have the proper value */
+ kempld_wdt_settimeout(&wdt);
+ kempld_wdt_keepalive(&wdt);
+ } else {
+ ret = kempld_wdt_settimeout(&wdt);
+ if (ret) {
+ printf("Unable to setup timeout !\n");
+ goto booting;
+ }
+
+ ret = kempld_wdt_start(&wdt);
+ if (ret) {
+ printf("Unable to start watchdog !\n");
+ goto booting;
+ }
+
+ }
+
+ printf("Watchog armed ! Rebooting in %d seconds if no feed occurs !\n",wdt.timeout);
+
+booting:
+ /* Release Mutex to let Linux's Driver taking control */
+ kempld_release_mutex(&pld);
+
+ /* Let's boot the default entry if specified */
+ if (strlen(default_label)>0) {
+ printf("Executing default label = '%s'\n",default_label);
+ syslinux_run_command(default_label);
+ } else {
+ return ret;
+ }
+}
diff --git a/com32/modules/kontron_wdt.h b/com32/modules/kontron_wdt.h
new file mode 100644
index 00000000..e916de30
--- /dev/null
+++ b/com32/modules/kontron_wdt.h
@@ -0,0 +1,117 @@
+/*
+ * kempld_wdt.h - Kontron PLD watchdog driver definitions
+ *
+ * Copyright (c) 2010 Kontron Embedded Modules GmbH
+ * Author: Michael Brunner <michael.brunner@kontron.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _KEMPLD_WDT_H_
+#define _KEMPLD_WDT_H_
+#include <stdint.h>
+
+#define KEMPLD_IOPORT 0x0a80
+#define KEMPLD_IODATA (KEMPLD_IOPORT+1)
+
+#define KEMPLD_MUTEX_KEY 0x80
+
+/* watchdog register definitions */
+#define KEMPLD_WDT_KICK 0x16
+#define KEMPLD_WDT_REV 0x16
+#define KEMPLD_WDT_REV_GET(x) (x & 0xf)
+#define KEMPLD_WDT_CFG 0x17
+#define KEMPLD_WDT_CFG_STAGE_TIMEOUT_OCCURED(x) (1<<x)
+#define KEMPLD_WDT_CFG_ENABLE_LOCK 0x8
+#define KEMPLD_WDT_CFG_ENABLE 0x10
+#define KEMPLD_WDT_CFG_AUTO_RELOAD 0x40
+#define KEMPLD_WDT_CFG_GLOBAL_LOCK 0x80
+#define KEMPLD_WDT_STAGE_CFG(x) (0x18+x)
+#define KEMPLD_WDT_STAGE_CFG_ACTION_MASK 0x7
+#define KEMPLD_WDT_STAGE_CFG_GET_ACTION(x) (x & 0x7)
+#define KEMPLD_WDT_STAGE_CFG_ASSERT 0x8
+#define KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK 0x30
+#define KEMPLD_WDT_STAGE_CFG_GET_PRESCALER(x) ((x & 0x30)>>4)
+#define KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(x) ((x & 0x30)<<4)
+#define KEMPLD_WDT_STAGE_TIMEOUT(x) (0x1b+x*4)
+#define KEMPLD_WDT_MAX_STAGES 3
+
+#define KEMPLD_WDT_ACTION_NONE 0x0
+#define KEMPLD_WDT_ACTION_RESET 0x1
+#define KEMPLD_WDT_ACTION_NMI 0x2
+#define KEMPLD_WDT_ACTION_SMI 0x3
+#define KEMPLD_WDT_ACTION_SCI 0x4
+#define KEMPLD_WDT_ACTION_DELAY 0x5
+
+#define KEMPLD_WDT_PRESCALER_21BIT 0x0
+#define KEMPLD_WDT_PRESCALER_17BIT 0x1
+#define KEMPLD_WDT_PRESCALER_12BIT 0x2
+
+const int kempld_prescaler_bits[] = { 21, 17, 12 };
+
+struct kempld_watchdog_stage {
+ int num;
+ uint32_t timeout_mask;
+};
+
+/**
+ * struct kempld_device_data - Internal representation of the PLD device
+ * @io_base: Pointer to the IO memory
+ * @io_index: Pointer to the IO index register
+ * @io_data: Pointer to the IO data register
+ * @pld_clock: PLD clock frequency
+ * @lock: PLD spin-lock
+ * @lock_flags: PLD spin-lock flags
+ * @have_mutex: Bool value that indicates if mutex is aquired
+ * @last_index: Last written index value
+ * @rscr: Kernel resource structure
+ * @dev: Pointer to kernel device structure
+ * @info: KEMPLD info structure
+ */
+struct kempld_device_data {
+ uint16_t io_base;
+ uint16_t io_index;
+ uint16_t io_data;
+ uint32_t pld_clock;
+/* spinlock_t lock;
+ unsigned long lock_flags; */
+ int have_mutex;
+ uint8_t last_index;
+/* struct resource rscr;
+ struct device *dev;
+ struct kempld_info info;*/
+};
+
+struct watchdog_info {
+ uint32_t options; /* Options the card/driver supports */
+ uint32_t firmware_version; /* Firmware version of the card */
+ uint8_t identity[32]; /* Identity of the board */
+};
+
+struct kempld_watchdog_data {
+ unsigned int revision;
+ int timeout;
+ int pretimeout;
+ unsigned long is_open;
+ unsigned long expect_close;
+ int stages;
+ struct kempld_watchdog_stage *timeout_stage;
+ struct kempld_watchdog_stage *pretimeout_stage;
+ struct kempld_device_data *pld;
+ struct kempld_watchdog_stage *stage[KEMPLD_WDT_MAX_STAGES];
+ struct watchdog_info ident;
+};
+
+#endif /* _KEMPLD_WDT_H_ */
+#define KEMPLD_PRESCALER(x) (0xffffffff>>(32-kempld_prescaler_bits[x]))
diff --git a/com32/modules/prdhcp.c b/com32/modules/prdhcp.c
new file mode 100644
index 00000000..e1785a03
--- /dev/null
+++ b/com32/modules/prdhcp.c
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010-2011 Gene Cumm - All Rights Reserved
+ *
+ * Portions from chain.c:
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ * Significant portions copyright (C) 2010 Shao Miller
+ * [partition iteration, GPT, "fs"]
+ *
+ * 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., 53 Temple Place Ste 330,
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * prdhcp.c
+ *
+ * Print the contents of the 3 DHCP packets
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+
+#define DEBUG 0
+
+#define dprintf0(f, ...) ((void)0)
+
+#ifdef DEBUG
+# define dpressanykey pressanykey
+# define dprintf printf
+# define dprint_pxe_bootp_t print_pxe_bootp_t
+# define dprint_pxe_vendor_blk print_pxe_vendor_blk
+# define dprint_pxe_vendor_raw print_pxe_vendor_raw
+#else
+# define dpressanykey(void) ((void)0)
+# define dprintf(f, ...) ((void)0)
+# define dprint_pxe_bootp_t(p, l) ((void)0)
+# define dprint_pxe_vendor_blk(p, l) ((void)0)
+# define dprint_pxe_vendor_raw(p, l) ((void)0)
+#endif
+
+#define dprintf_opt_cp dprintf0
+#define dprintf_opt_inj dprintf
+
+
+const char app_name_str[] = "prdhcp.c32";
+
+
+int pressanykey(void) {
+ int inc;
+
+ printf("Press any key to continue. ");
+ inc = KEY_NONE;
+ while (inc == KEY_NONE)
+ inc = get_key(stdin, 6000);
+ puts("");
+ return inc;
+}
+
+void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
+{
+ int i, vlen, oplen, j;
+ uint8_t *d;
+ uint32_t magic;
+ if (!p) {
+ printf(" packet pointer is null\n");
+ return;
+ }
+ vlen = len - ((void *)&(p->vendor) - (void *)p);
+ printf(" Vendor Data: Len=%d", vlen);
+ d = p->vendor.d;
+ /* Print only 256 characters of the vendor/option data */
+ /*
+ print_pxe_vendor_raw(p, (len - vlen) + 256);
+ vlen = 0;
+ */
+ magic = ntohl(*((uint32_t *)d));
+ printf(" Magic: %08X", ntohl(*((uint32_t *)d)));
+ if (magic != VM_RFC1048) /* Invalid DHCP packet */
+ vlen = 0;
+ for (i = 4; i < vlen; i++) {
+ if (d[i]) /* Skip the padding */
+ printf("\n @%03X-%3d", i, d[i]);
+ if (d[i] == 255) /* End of list */
+ break;
+ if (d[i]) {
+ oplen = d[++i];
+ printf(" l=%3d:", oplen);
+ for (j = (++i + oplen); i < vlen && i < j; i++) {
+ printf(" %02X", d[i]);
+ }
+ i--;
+ }
+ }
+ printf("\n");
+}
+
+void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
+{
+ if (!p) {
+ printf(" packet pointer is null\n");
+ return;
+ }
+ printf(" op:%02X hw:%02X hl:%02X gh:%02X id:%08X se:%04X f:%04X"
+ " cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
+ ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
+ printf(" yip:%08X sip:%08X gip:%08X",
+ ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
+ printf(" caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
+ p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
+ printf(" sName: '%s'\n", p->Sname);
+ printf(" bootfile: '%s'\n", p->bootfile);
+ print_pxe_vendor_blk(p, len);
+}
+
+void print_dhcp_pkt_all(void)
+{
+ pxe_bootp_t *p;
+ size_t len;
+ int i;
+ int ptype[3] = {PXENV_PACKET_TYPE_DHCP_DISCOVER, PXENV_PACKET_TYPE_DHCP_ACK, PXENV_PACKET_TYPE_CACHED_REPLY};
+
+ for (i = 0; i < 3; i++) {
+ if (!pxe_get_cached_info(ptype[i],
+ (void **)&(p), &(len))) {
+ dprintf("Got packet #%d/%d\n", (i + 1), ptype[i]);
+ print_pxe_bootp_t(p, len);
+ pressanykey();
+ }
+ }
+}
+
+int main(void)
+{
+ int rv= -1;
+ const struct syslinux_version *sv;
+
+ console_ansi_raw();
+ sv = syslinux_version();
+ if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
+ printf("%s: May only run in PXELINUX\n", app_name_str);
+ return -2;
+ }
+ print_dhcp_pkt_all();
+ return rv;
+}
diff --git a/com32/modules/pxechn.c b/com32/modules/pxechn.c
index 39ac72ea..7f2002db 100644
--- a/com32/modules/pxechn.c
+++ b/com32/modules/pxechn.c
@@ -43,7 +43,11 @@
#include <limits.h>
-#define PXECHN_DEBUG 1
+#ifdef DEBUG
+# define PXECHN_DEBUG 1
+#else
+# define PXECHN_DEBUG 0
+#endif
typedef union {
uint64_t q;
@@ -54,15 +58,21 @@ typedef union {
#define dprintf0(f, ...) ((void)0)
+#ifndef dprintf
+# if (PXECHN_DEBUG > 0)
+# define dprintf printf
+# else
+# define dprintf(f, ...) ((void)0)
+# endif
+#endif
+
#if (PXECHN_DEBUG > 0)
# define dpressanykey pressanykey
-# define dprintf printf
# define dprint_pxe_bootp_t print_pxe_bootp_t
# define dprint_pxe_vendor_blk print_pxe_vendor_blk
# define dprint_pxe_vendor_raw print_pxe_vendor_raw
#else
# define dpressanykey(tm) ((void)0)
-# define dprintf(f, ...) ((void)0)
# define dprint_pxe_bootp_t(p, l) ((void)0)
# define dprint_pxe_vendor_blk(p, l) ((void)0)
# define dprint_pxe_vendor_raw(p, l) ((void)0)
@@ -107,6 +117,7 @@ struct pxelinux_opt {
uint32_t force;
uint32_t wait; /* Additional decision to wait before boot */
int32_t wds; /* WDS option/level */
+ in_addr_t sip; /* siaddr: Next Server IP Address */
struct dhcp_option p[PXECHN_NUM_PKT_AVAIL];
/* original _DHCP_DISCOVER, _DHCP_ACK, _CACHED_REPLY then modified packets */
char host[PXECHN_HOST_LEN];
@@ -453,6 +464,7 @@ void pxechn_init(struct pxelinux_opt *pxe)
pxe->wait = 0;
pxe->gip = 0;
pxe->wds = 0;
+ pxe->sip = 0;
pxe->host[0] = 0;
pxe->host[((NUM_DHCP_OPTS) - 1)] = 0;
for (int j = 0; j < PXECHN_NUM_PKT_TYPE; j++){
@@ -731,7 +743,7 @@ int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe,
{
int arg, optnum, rv = 0;
char *p = NULL;
- const char optstr[] = "c:f:g:o:p:t:uwW";
+ const char optstr[] = "c:f:g:o:p:St:uwW";
struct dhcp_option iopt;
if (pxe->p[5].data)
@@ -765,6 +777,9 @@ int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe,
case 'p': /* prefix */
pxechn_setopt_str(&(opts[210]), optarg);
break;
+ case 'S': /* sip from sName */
+ pxe->sip = 1;
+ break;
case 't': /* timeout */
optnum = strtoul(optarg, &p, 0);
if (p != optarg) {
@@ -809,6 +824,7 @@ int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe)
pxe_bootp_t *bootp0, *bootp1;
int ret = 0;
struct dhcp_option *opts;
+ char *str;
opts = pxe->opts[2];
/* Start filling packet #1 */
@@ -826,7 +842,30 @@ int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe)
ret = pxechn_parse_args(argc, argv, pxe, opts);
if (ret)
return ret;
- bootp1->sip = pxe->fip;
+ if (pxe->sip > 0xFFFFFF) { /* a real IPv4 address */
+ bootp1->sip = pxe->sip;
+ } else if ((pxe->sip == 1)
+ && (opts[66].len > 0)){
+ /* unterminated? */
+ if (strnlen(opts[66].data, opts[66].len) == (size_t)opts[66].len) {
+ str = malloc(opts[66].len + 1);
+ if (str) {
+ memcpy(str, opts[66].data, opts[66].len);
+ str[opts[66].len] = 0;
+ }
+ } else {
+ str = opts[66].data;
+ }
+ if (str) {
+ bootp1->sip = pxe_dns(str);
+ if (str != opts[66].data)
+ free(str);
+ } else {
+ bootp1->sip = pxe->fip;
+ }
+ } else {
+ bootp1->sip = pxe->fip;
+ }
bootp1->gip = pxe->gip;
ret = dhcp_pack_packet(bootp1, (size_t *)&(pxe->p[5].len), opts);
diff --git a/core/comboot.inc b/core/comboot.inc
index 175c50c9..92c43ff2 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -563,10 +563,8 @@ comapi_cleanup:
ret
;
-; INT 22h AX=000Dh Clean up then replace bootstrap
+; INT 22h AX=000Dh Obsolete
;
-comapi_chainboot:
- ret
;
; INT 22h AX=000Eh Get configuration file name
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index ea211005..957c60b7 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -164,6 +164,9 @@ static struct inode *ext2_iget_by_inr(struct fs_info *fs, uint32_t inr)
struct inode *inode;
e_inode = ext2_get_inode(fs, inr);
+ if (!e_inode)
+ return NULL;
+
if (!(inode = alloc_inode(fs, inr, sizeof(struct ext2_pvt_inode))))
return NULL;
fill_inode(inode, e_inode);
diff --git a/doc/comboot.txt b/doc/comboot.txt
index 04d5deb8..6e9d7ab5 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -560,29 +560,7 @@ AX=000Ch [2.00] Perform final cleanup
meanings in future versions of Syslinux.
-AX=000Dh [2.08] Cleanup and replace bootstrap code
- Input: AX 000Dh
- DX derivative-specific flags (see previous function)
- EDI bootstrap code (linear address, can be in high memory)
- ECX bootstrap code length in bytes (must fit in low mem)
- EBX(!) initial value of EDX after bootstrap
- ESI initial value of ESI after bootstrap
- DS initial value of DS after bootstrap
- Output: Does not return
-
- This routine performs final cleanup, then takes a piece of
- code, copies it over the primary bootstrap at address 7C00h,
- and jumps to it. This can be used to chainload boot sectors,
- MBRs, bootstraps, etc.
-
- Normal boot sectors expect DL to contain the drive number,
- and, for hard drives (DL >= 80h) DS:SI to contain a pointer to
- the 16-byte partition table entry. The memory between
- 600h-7FFh is available to put the partition table entry in.
-
- For PXELINUX, if the PXE stack is not unloaded, all registers
- (except DS, ESI and EDX) and the stack will be set up as they
- were set up by the PXE ROM.
+AX=000Dh [2.08] Obsoleted in 3.80
AX=000Eh [2.11] Get configuration file name
@@ -627,57 +605,7 @@ AX=0010h [3.00] Resolve hostname [PXELINUX]
AX=0011h [3.05] Obsoleted in 3.80
-AX=0012h [3.50] Cleanup, shuffle and boot
- Input: AX 0012h
- DX derivative-specific flags (see function 000Ch)
- ES:DI shuffle descriptor list (must be in low memory)
- CX number of shuffle descriptors
- EBX(!) initial value of EDX after bootstrap
- ESI initial value of ESI after bootstrap
- DS initial value of DS after bootstrap
- EBP CS:IP of routine to jump to
- Output: Does not return
- (if CX is too large the routine returns with CF=1)
-
- This routine performs final cleanup, then performs a sequence
- of copies, and jumps to a specified real mode entry point.
- This is a more general version of function 000Dh, which can
- also be used to load other types of programs.
-
- The copies must not touch memory below address 7C00h.
-
- ES:DI points to a list of CX descriptors each of the form:
-
- Offset Size Meaning
- 0 dword destination address
- 4 dword source address
- 8 dword length in bytes
-
- The copies are overlap-safe, like memmove().
-
- Starting in version 3.50, if the source address is -1
- (FFFFFFFFh) then the block specified by the destination
- address and the length is set to all zero.
-
- Starting in version 3.50, if the destination address is -1
- (FFFFFFFFh) then the data block is loaded as a new set of
- descriptors, and processing is continued (and unprocessed
- descriptors are lost, this is thus typically only used as the
- last descriptor in a block.) The block must still fit in the
- internal descriptor buffer (see function 0011h), but can, of
- course, itself chain another block.
-
-
- Normal boot sectors expect DL to contain the drive number,
- and, for hard drives (DL >= 80h) DS:SI to contain a pointer to
- the 16-byte partition table entry. The memory between
- 600h-7FFh is available to put the partition table entry in.
-
- For PXELINUX, if the PXE stack is not unloaded, all registers
- (except DS, ESI and EDX) and the stack will be set up as they
- were set up by the PXE ROM.
-
- This interface was probably broken before version 3.50.
+AX=0012h [3.50] Obsoleted in 3.80
AX=0013h [3.08] Idle loop call
diff --git a/doc/menu.txt b/doc/menu.txt
index 620527e6..8a999cd4 100644
--- a/doc/menu.txt
+++ b/doc/menu.txt
@@ -18,7 +18,7 @@ See menu/README for more information.
+++ THE SIMPLE MENU SYSTEM +++
The simple menu system is a single module located at
-com32/modules/vesamenu.c32 (graphical) or com32/modules/menu.c32 (text
+com32/menu/vesamenu.c32 (graphical) or com32/menu/menu.c32 (text
mode only). It uses the same configuration file as the regular
Syslinux command line, and displays all the LABEL statements.
diff --git a/doc/pxechn.txt b/doc/pxechn.txt
index a09bbe2b..7853d9ab 100644
--- a/doc/pxechn.txt
+++ b/doc/pxechn.txt
@@ -1,88 +1,131 @@
-= pxechn.c32 =
+= pxechn.c32(1) =
:doctype: manpage
:author: Gene Cumm
:email: gene.cumm@gmail.com
-:revdate: 2012-05-27
+:revdate: 2012-09-16
== NAME ==
-pxechn.c32 - Chainboot to new NBP
+pxechn.c32 - Chainboot to new Network Boot Program (NBP)
== SYNOPSIS ==
+[verse]
*pxechn.c32* [-h | --help | -?]
*pxechn.c32* -r 'FILE'
*pxechn.c32* 'FILE' ['OPTIONS']
== DESCRIPTION ==
-Chainboot to a new NBP (Network Boot Program) 'FILE' with options to adjust PXE packet #3 (PXENV_PACKET_TYPE_CACHED_REPLY) to alter end behavior. 'FILE' may be a filename, an IP::FN ( 192.168.1.1::path/to/file.0 ), or URL. 'FILE' is parsed to adjust the DHCP 'sname' field/option 66 and 'file' field/option 67.
+Chainboot to a new Network Boot Program (NBP) 'FILE' with options to
+adjust PXE packet #3 (PXENV_PACKET_TYPE_CACHED_REPLY) to alter end
+behavior. 'FILE' may be a filename, an IP::FN (
+192.168.1.1::path/to/file.0 ), or URL. 'FILE' is parsed to adjust the
+DHCP 'sname' field/option 66 and 'file' field/option 67.
// but these may be override-able in the future.
== OPTIONS ==
*-c* 'CONFIG'::
- PXELINUX config file (DHCP Option 209).
+ 'config' file for PXELINUX (DHCP Option 209).
// *-f* 'MOD'::
-// Force behavior specified by 'MOD'
+// 'Force' behavior specified by modifier 'MOD'
//
// *-g* 'HOST'::
-// Set DHCP gateway/relay. Parsed by pxe_dns().
+// Set 'gateway'/relay DHCP field to 'HOST'. Parsed by pxe_dns().
//
*-h*, *--help*, *-?*::
- Print usage information; invalid options will also cause this.
+ Print 'help'/usage information; invalid options will also cause
+ this.
// *-n*::
-// Use native methods, ignoring underlying gPXE/iPXE.
+// Use 'native' methods, ignoring underlying gPXE/iPXE.
//
// *-N*::
-// Use non-native methods to utilize gPXE/iPXE (if available).
+// Use 'non-native' methods to utilize gPXE/iPXE (if available).
//
*-o* 'OPT.TYPE=VALUE'::
- Specify a generic option. 'OPT' is in 'DECIMAL INPUT' format (below). 'TYPE' specifies the output type and input syntax. 'b'yte, 'w'ord(2B), 'l'ong(4B), 'q'uad(8B), character 's'tring and colon-separated he'x' string (case insensitive; bytes must have 2 digits and each byte must be separated). byte, word, long and quad input values must meet criteria for 'DECIMAL INPUT'
+ Set 'option'. 'OPT' is in 'DECIMAL INPUT' format (below). 'TYPE'
+ specifies the output type and input syntax (listed here in quotes
+ and at present, 1 character). ''b'yte', ''w'ord'(2B), ''l'ong'(4B),
+ ''q'uad'(8B), character ''s'tring' and colon-separated 'he'x''
+ string (case insensitive; bytes must have 2 digits and each byte
+ must be separated). byte, word, long and quad input values must
+ meet criteria for 'DECIMAL INPUT'
*-p* 'PATH'::
- PXELINUX path (DHCP Option 210).
+ 'path' option for PXELINUX (DHCP Option 210).
*-r*::
- Call the PXE stack with PXENV_RESTART_TFTP. _Must_ be the only option and before 'FILE'.
+ 'restart'. Call the PXE stack with PXENV_RESTART_TFTP. _Must_ be
+ the only option and before 'FILE'.
+
+*-S*::
+ Set 'sip' based on sname field/option 66 (by direct IP if a
+ period-delimited address or otherwise DNS).
*-t* 'SECONDS'::
- PXELINUX timeout (DHCP Option 211).
+ 'timeout' option for PXELINUX (DHCP Option 211).
// *-u*::
-// Copy UUID (Option 97) if found in packet #1
+// Copy 'UUID' (Option 97) if found in packet #1
*-w*::
- wait after loading before booting for user input.
+ 'wait'. After loading, wait for user input before booting.
*-W*::
- Enable WDS (Windows Deployment Services) - specific options.
+ Enable 'WDS' (Windows Deployment Services) - specific options.
+ 'FILE' (or its overrides for DHCP fields siaddr and file) must point
+ at the WDS server.
+ *NOTE:* As of 2012-05-31, there is a known issue with gPXE/iPXE, at
+ least with undionly.kkpxe.
+// PXELINUX asks gPXE/iPXE to unload, reverting to an underlying stack
== DECIMAL INPUT ==
-All parameters that are defaulted to decimal format are processed by *strtoul*(3) with a base of 0 which allows alternate formats and finds a suitable non-space separating character.
+All parameters that are defaulted to decimal format are processed by
+*strtoul*(3) with a base of 0 which allows alternate formats and finds a
+suitable non-space separating character.
== EXAMPLES ==
-pxechn.c32 http://myhost.dom.loc/path/nbp.0 -c myconfig
- Load nbp.0 and set PXELINUX config (option 209).
-
-pxechn.c32 gpxelinux.0 -p http://172.16.23.1/tftp/ -w -c myconfig -o 15.s=domain.loc -o 6.x=0A:01:01:02:ac:17:4D:Ec -
- Load gpxelinux.0 from the current directory, set prefix, wait to execute, set first config, set the domain name and 2 domain name servers (case mixed to show insensitivity; 10.1.1.2 and 172.23.77.236).
-
-pxechn.c32 gpxelinux.0 -p http://172.16.23.1/tftp/ -w -X A012345678 -x 197:00d0de00
-pxechn.c32 gpxelinux.0 -p http://172.16.23.1/tftp/ -w -X A012:3456:78 -x 197:00-d0-de-00
- Both of these are equivalent. Load gpxelinux.0 (relative to the current directory and not altering sname/option 66), set the PXELINUX path prefix, wait after loading, set option 160 to 0x12 0x34 0x56 0x78, and option 197 to 0x00 0xD0 0xDE 0x00.
+`pxechn.c32 http://myhost.dom.loc/path/nbp.0 -c myconfig`::
+ Load nbp.0 and set PXELINUX config (option 209).
+
+`pxechn.c32 gpxelinux.0 -p http://10.1.1.4/tftp/ -w -c myconfig -o 15.s=domain.loc -o 6.x=0A:01:01:02:ac:17:4D:Ec -`::
+ Load gpxelinux.0 from the current directory, set prefix, wait to
+ execute, set first config, set the domain name and 2 domain name
+ servers (case mixed to show insensitivity; 10.1.1.2 and
+ 172.23.77.236).
+
+`pxechn.c32 gpxelinux.0 -p http://10.1.1.4/tftp/ -w -o 0xA0.x=12:34:56:78 -x 197.x=00:d0:de:00`::
+ Load gpxelinux.0 (relative to the current directory and not
+ altering sname/option 66), set the PXELINUX path prefix, wait after
+ loading, set option 160 to 0x12 0x34 0x56 0x78, and option 197 to
+ 0x00 0xD0 0xDE 0x00.
+
+`pxechn.c32 10.1.1.8:boot\x86\wdsnbp.com -W`::
+ Load wdsnbp.com from 10.1.1.8 and copy DHCP Option 66 to DHCP
+ field sname if there's room.
+
+`pxechn.c32 10.1.1.4:boot\x86\wdsnbp.com -W -o 66.x=0a:01:01:08 -S`::
+ Load wdsnbp.com from 10.1.1.4, point packets to 10.1.1.8 for use
+ with WDS, copy DHCP Option 66 to DHCP field sname if there's room
+ and decode this to an IPv4 address.
== NOTES ==
-Please note that some NBPs may ignore packet #3 by either not examining it at all or by issuing its own DHCP DISCOVER/REQUEST, negating all DHCP field/option modifications by pxechn.c32.
+Please note that some NBPs may ignore packet #3 by either not examining
+it at all or by issuing its own DHCP DISCOVER/REQUEST, negating all DHCP
+field/option modifications by pxechn.c32, including Microsoft Windows
+Server 2008R2 WDS's wdsnbp.com. See also option '-W'.
-URL specifications in 'FILE' that include user/password before the host will currently cause the siaddr field to not be set properly.
+URL specifications in 'FILE' that include user/password before the host
+will currently cause the siaddr field to not be set properly.
-The non-space constraint is due to how Syslinux variants parse the command line as of 2012-01-12.
+The non-space constraint is due to how Syslinux variants parse the
+command line as of 2012-09-16.
== AUTHOR ==
@@ -91,4 +134,5 @@ The non-space constraint is due to how Syslinux variants parse the command line
== COPYRIGHT ==
Copyright \(C) 2012 {author}. Free use of this software is granted under
-the terms of the GNU General Public License (GPL).
+the terms of the GNU General Public License (GPL), version 2 (GPLv2)
+(or, at your option, any later version).
diff --git a/doc/syslinux.txt b/doc/syslinux.txt
index 07d5df9a..033a1ec0 100644
--- a/doc/syslinux.txt
+++ b/doc/syslinux.txt
@@ -100,7 +100,7 @@ directory on the disk.
There are two versions of the Linux installer; one in the "mtools"
directory which requires no special privilege (other than write
permission to the device where you are installing) but requires the
-mtools program suite to be available, and one in the "unix" directory
+mtools program suite to be available, and one in the "linux" directory
which requires root privilege.
diff --git a/extlinux/main.c b/extlinux/main.c
index d1a90481..611b8080 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -76,7 +76,7 @@ static char subvol[BTRFS_SUBVOL_MAX];
/*
* Get the size of a block device
*/
-uint64_t get_size(int devfd)
+static uint64_t get_size(int devfd)
{
uint64_t bytes;
uint32_t sects;
@@ -210,7 +210,7 @@ ok:
*
* Returns the number of modified bytes in the boot file.
*/
-int patch_file_and_bootblock(int fd, const char *dir, int devfd)
+static int patch_file_and_bootblock(int fd, const char *dir, int devfd)
{
struct stat dirst, xdst;
struct hd_geometry geo;
@@ -796,7 +796,7 @@ static char * get_default_subvol(char * rootdir, char * subvol)
return subvol;
}
-int install_file(const char *path, int devfd, struct stat *rst)
+static int install_file(const char *path, int devfd, struct stat *rst)
{
if (fs_type == EXT2 || fs_type == VFAT || fs_type == NTFS)
return ext2_fat_install_file(path, devfd, rst);
@@ -1226,7 +1226,7 @@ static int ext_write_adv(const char *path, const char *cfg, int devfd)
return write_adv(path, cfg);
}
-int install_loader(const char *path, int update_only)
+static int install_loader(const char *path, int update_only)
{
struct stat st, fst;
int devfd, rv;
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index 2e317d0e..e5428b79 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -23,6 +23,17 @@
# define X86_MEM 0
#endif
+#ifdef __GNUC__
+# ifdef __MINGW32__
+ /* gcc 4.7 miscompiles packed structures in MS-bitfield mode */
+# define PACKED __attribute__((packed,gcc_struct))
+# else
+# define PACKED __attribute__((packed))
+# endif
+#else
+# error "Need to define PACKED for this compiler"
+#endif
+
/*
* Access functions for littleendian numbers, possibly misaligned.
*/
@@ -190,7 +201,7 @@ struct ext_patch_area {
struct syslinux_extent {
uint64_t lba;
uint16_t len;
-} __attribute__((packed));
+} PACKED;
/* FAT bootsector format, also used by other disk-based derivatives */
struct fat_boot_sector {
@@ -218,7 +229,7 @@ struct fat_boot_sector {
char VolumeLabel[11];
char FileSysType[8];
uint8_t Code[442];
- } __attribute__ ((packed)) bs16;
+ } PACKED bs16;
struct {
uint32_t FATSz32;
uint16_t ExtFlags;
@@ -234,13 +245,13 @@ struct fat_boot_sector {
char VolumeLabel[11];
char FileSysType[8];
uint8_t Code[414];
- } __attribute__ ((packed)) bs32;
- } __attribute__ ((packed));
+ } PACKED bs32;
+ } PACKED;
uint32_t bsMagic;
uint16_t bsForwardPtr;
uint16_t bsSignature;
-} __attribute__ ((packed));
+} PACKED;
/* NTFS bootsector format */
struct ntfs_boot_sector {
@@ -273,7 +284,7 @@ struct ntfs_boot_sector {
uint32_t bsMagic;
uint16_t bsForwardPtr;
uint16_t bsSignature;
-} __attribute__((packed));
+} PACKED;
#define FAT_bsHead bsJump
#define FAT_bsHeadLen offsetof(struct fat_boot_sector, bsBytesPerSec)
diff --git a/libinstaller/syslxmod.c b/libinstaller/syslxmod.c
index 5ec156ac..98e2710a 100644
--- a/libinstaller/syslxmod.c
+++ b/libinstaller/syslxmod.c
@@ -96,8 +96,6 @@ static inline void *ptr(void *img, uint16_t *offset_p)
* Returns the number of modified bytes in ldlinux.sys if successful,
* otherwise -1.
*/
-#define NADV 2
-
int syslinux_patch(const sector_t *sectp, int nsectors,
int stupid, int raid_mode,
const char *subdir, const char *subvol)
diff --git a/memdisk/mstructs.h b/memdisk/mstructs.h
index fecbff40..0b0dc07d 100644
--- a/memdisk/mstructs.h
+++ b/memdisk/mstructs.h
@@ -121,9 +121,9 @@ typedef union {
uint8_t specify1; /* "First specify byte" */
uint8_t specify2; /* "Second specify byte" */
uint8_t delay; /* Delay until motor turn off */
- uint8_t sectors; /* Sectors/track */
-
uint8_t bps; /* Bytes/sector (02h = 512) */
+
+ uint8_t sectors; /* Sectors/track */
uint8_t isgap; /* Length of intersector gap */
uint8_t dlen; /* Data length (0FFh) */
uint8_t fgap; /* Formatting gap */
diff --git a/utils/isohybrid.c b/utils/isohybrid.c
index ac04bfd4..97d43b86 100644
--- a/utils/isohybrid.c
+++ b/utils/isohybrid.c
@@ -434,10 +434,10 @@ lendian_64(const uint64_t s)
if (*(uint8_t *)&r)
return s;
- r = (s & 0x00000000000000FF) << 56 | (s & 0xFF00000000000000) >> 56
- | (s & 0x000000000000FF00) << 40 | (s & 0x00FF000000000000) >> 40
- | (s & 0x0000000000FF0000) << 24 | (s & 0x0000FF0000000000) >> 24
- | (s & 0x00000000FF000000) << 8 | (s & 0x000000FF00000000) >> 8;
+ r = (s & 0x00000000000000FFull) << 56 | (s & 0xFF00000000000000ull) >> 56
+ | (s & 0x000000000000FF00ull) << 40 | (s & 0x00FF000000000000ull) >> 40
+ | (s & 0x0000000000FF0000ull) << 24 | (s & 0x0000FF0000000000ull) >> 24
+ | (s & 0x00000000FF000000ull) << 8 | (s & 0x000000FF00000000ull) >> 8;
return r;
}
@@ -759,7 +759,7 @@ initialise_gpt(uint8_t *gpt, uint32_t current, uint32_t alternate, int primary)
reverse_uuid(disk_uuid);
}
- header->signature = lendian_64(0x5452415020494645);
+ header->signature = lendian_64(0x5452415020494645ull);
header->revision = lendian_int(0x010000);
header->headerSize = lendian_int(0x5c);
header->currentLBA = lendian_64(current);