Hi,
I've put together some more patches so that we've got feature-parity on
the elflink branch with Syslinux 4.x. I'm just about to do a final
review for features that elflink is missing but I think we're nearly
there now.
Like previous patches, I've punted on converting lots of stuff from asm
to C (like the "kbdmap" parsing code) but we should be able to do the
conversion under the hood later.
I've also made use of your recent commit introducing open_config() so
that we can delete the config file lookup code in readconfig.c, thanks!
Some interesting new features are the PATH-based module loading and
using DT_NEEDED entries in an ELF's .dynamic section instead of the
elf_gen_dep.sh script and modules.dep file. The PATH-based module
loading allows users to use the "PATH" config directive to specify
directories to search when loading modules. The DT_NEEDED change means
that you no longer have to run elf_gen_dep.sh to generate the
modules.dep file so that a module's dependencies are loaded; it's taken
care of automatically now.
Please review and pull!
The following changes since commit ba4fefa9b52b25ca1babd77066e21abef19518c2:
core: change load_config() to open_config() (2011-05-27 17:45:59 -0700)
are available in the git repository at:
git://git.zytor.com/users/mfleming/syslinux.git for-hpa/elflink/ldlinux
Matt Fleming (16):
ldlinux: Fix "prompt" config option parsing
ldlinux: Initialise ipappend strings
ldlinux: Add support for parsing pxeretry option
core: Load the 32-bit environment at startup
ldlinux: PATH-based module lookup
core: open_file() returns a non-negative handle id
core: Return a file descriptor from open_config()
ldlinux: Use open_config() to open config files
ldlinux: Add support for parsing "serial" config directive
ldlinux: Parse "display" in config files
ldlinux: Support "font"
ldlinux: Support "kbdmap"
Merge branch 'fs-config' into for-hpa/elflink/ldlinux
Merge branch 'PATH-based-search' into for-hpa/elflink/ldlinux
ldlinux: Use DT_NEEDED for module dependencies
Merge branch 'DT_NEEDED-module-deps' into for-hpa/elflink/ldlinux
.gitignore | 1 -
com32/elflink/ldlinux/execute.c | 2 -
com32/elflink/ldlinux/ldlinux.c | 1 +
com32/elflink/ldlinux/readconfig.c | 275 +++++++++++++++++++++++++++++++-----
com32/include/sys/exec.h | 12 --
com32/lib/sys/module/common.c | 35 +++++-
com32/lib/sys/module/elf_module.c | 51 +++++++-
com32/lib/sys/module/exec.c | 144 -------------------
core/Makefile | 2 +-
core/conio.inc | 4 +
core/elflink/load_env32.c | 1 -
core/font.inc | 1 +
core/fs/fs.c | 29 ++++-
core/fs/lib/searchconfig.c | 2 +-
core/include/core.h | 2 +
core/include/fs.h | 2 +
core/parseconfig.inc | 1 +
core/pxelinux.asm | 6 +
core/serirq.inc | 2 +
elf_gen_dep.sh | 130 -----------------
mk/lib.mk | 3 +-
21 files changed, 374 insertions(+), 332 deletions(-)
delete mode 100755 elf_gen_dep.sh
diff --git a/.gitignore b/.gitignore
index 05f0d14..98ea19f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,4 +50,3 @@
*GPATH
*GRTAGS
*GTAGS
-modules.dep
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 635e327..dff59e6 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -132,7 +132,6 @@ void execute(const char *cmdline, enum kernel_type type)
}
argv[argc] = NULL;
- module_load_dependencies(kernel, "modules.dep");
spawn_load(kernel, argc, argv);
} else if (type == KT_KERNEL) {
/* Need add one item for kernel load, as we don't use
@@ -141,7 +140,6 @@ void execute(const char *cmdline, enum kernel_type type)
} else if (type == KT_CONFIG) {
/* kernel contains the config file name */
char *spawn_load_param[2] = { args, NULL };
- module_load_dependencies("ui.c32", "modules.dep");
spawn_load(kernel, 1, spawn_load_param);
} else {
/* process the image need int 22 support */
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 8b5fd30..84cb41f 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -110,6 +110,7 @@ int main(int argc, char **argv)
openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+ __syslinux_get_ipappend_strings();
parse_configs(NULL);
__syslinux_init();
diff --git a/com32/elflink/ldlinux/readconfig.c
b/com32/elflink/ldlinux/readconfig.c
index 8ded92a..5bf6f42 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -11,6 +11,8 @@
*
* ----------------------------------------------------------------------- */
+#include <sys/io.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -23,10 +25,15 @@
#include <syslinux/adv.h>
#include <syslinux/config.h>
#include <dprintf.h>
+#include <ctype.h>
+#include <core.h>
+#include <fs.h>
#include "menu.h"
#include "config.h"
#include "getkey.h"
+#include "core.h"
+#include "fs.h"
const struct menu_parameter mparm[NPARAMS] = {
[P_WIDTH] = {"width", 0},
@@ -112,14 +119,6 @@ static struct menu *find_menu(const char *label)
#define MAX_LINE 4096
-static char *skipspace(char *p)
-{
- while (*p && my_isspace(*p))
- p++;
-
- return p;
-}
-
/* Strip ^ from a string, returning a new reference to the same refstring
if none present */
static const char *strip_caret(const char *str)
@@ -582,6 +581,7 @@ uint32_t parse_argb(char **p)
extern const char *append;
//static unsigned int ipappend = 0;
unsigned int ipappend = 0;
+extern uint16_t PXERetry;
static struct labeldata ld;
static int parse_one_config(const char *filename);
@@ -708,6 +708,34 @@ static char *is_fkey(char *cmdstr, int *fkeyno)
return q;
}
+extern uint8_t FlowIgnore;
+extern uint8_t FlowInput;
+extern uint8_t FlowOutput;
+extern uint16_t SerialPort;
+extern uint16_t BaudDivisor;
+extern uint8_t SerialNotice;
+
+#define DEFAULT_BAUD 9600
+#define BAUD_DIVISOR 115200
+#define serial_base 0x0400
+
+extern void sirq_cleanup_nowipe(void);
+extern void sirq_install(void);
+extern void write_serial_str(void);
+
+static inline void io_delay(void)
+{
+ outb(0, 0x80);
+ outb(0, 0x80);
+}
+
+extern void get_msg_file(void);
+extern void loadfont(void);
+extern void loadkeys(void);
+
+extern char syslinux_banner[];
+extern char copyright_str[];
+
static void parse_config_file(FILE * f)
{
char line[MAX_LINE], *p, *ep, ch;
@@ -1092,11 +1120,65 @@ do_include:
* display/font/kbdmap are rather similar, open a file then do sth
*/
else if (looking_at(p, "display")) {
+ com32sys_t reg;
+ char *filename, *dst = KernelName;
+ size_t len = FILENAME_MAX - 1;
+
+ filename = refstrdup(skipspace(p + 7));
+ while (len-- && not_whitespace(*filename))
+ *dst++ = *filename++;
+ *dst = '\0';
+
+ memset(®, 0, sizeof(reg));
+ reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+ call16(core_open, ®, ®);
+ if (!(reg.eflags.l & EFLAGS_ZF))
+ call16(get_msg_file, ®, NULL);
+ else
+ printf("File not found\n");
+
+ refstr_put(filename);
} else if (looking_at(p, "font")) {
+ com32sys_t reg;
+ char *filename, *dst = KernelName;
+ size_t len = FILENAME_MAX - 1;
+
+ filename = refstrdup(skipspace(p + 4));
+ while (len-- && not_whitespace(*filename))
+ *dst++ = *filename++;
+ *dst = '\0';
+
+ memset(®, 0, sizeof(reg));
+ reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+ call16(core_open, ®, ®);
+ if (!(reg.eflags.l & EFLAGS_ZF))
+ call16(loadfont, ®, NULL);
+ else
+ printf("File not found\n");
+
+ refstr_put(filename);
} else if (looking_at(p, "kbdmap")) {
+ com32sys_t reg;
+ char *filename, *dst = KernelName;
+ size_t len = FILENAME_MAX - 1;
+
+ filename = refstrdup(skipspace(p + 4));
+
+ while (len-- && not_whitespace(*filename))
+ *dst++ = *filename++;
+ *dst = '\0';
+ memset(®, 0, sizeof(reg));
+ reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+ call16(core_open, ®, ®);
+ if (!(reg.eflags.l & EFLAGS_ZF))
+ call16(loadkeys, ®, NULL);
+ else
+ printf("File not found\n");
+
+ refstr_put(filename);
}
/*
* subset 2: pc_setint16
@@ -1105,7 +1187,7 @@ do_include:
else if (looking_at(p, "implicit")) {
allowimplicit = atoi(skipspace(p + 8));
} else if (looking_at(p, "prompt")) {
- forceprompt = atoi(skipspace(p + 8));
+ forceprompt = atoi(skipspace(p + 6));
} else if (looking_at(p, "console")) {
displaycon = atoi(skipspace(p + 7));
} else if (looking_at(p, "allowoptions")) {
@@ -1124,48 +1206,171 @@ do_include:
onerror = refstrdup(m->onerror);
}
+ else if (looking_at(p, "pxeretry"))
+ PXERetry = atoi(skipspace(p + 8));
+
/* serial setting, bps, flow control */
else if (looking_at(p, "serial")) {
- /* core/conio.inc
- * should be able to find some code in com32
+ com32sys_t ireg;
+ uint16_t port, flow;
+ uint32_t baud;
+
+ p = skipspace(p + 6);
+ port = atoi(p);
+
+ while (isalnum(*p))
+ p++;
+ p = skipspace(p);
+
+ /* Default to no flow control */
+ FlowOutput = 0;
+ FlowInput = 0;
+
+ baud = DEFAULT_BAUD;
+ if (isalnum(*p)) {
+ uint8_t ignore;
+
+ /* setup baud */
+ baud = atoi(p);
+ while (isalnum(*p))
+ p++;
+ p = skipspace(p);
+
+ ignore = 0;
+ flow = 0;
+ if (isalnum(*p)) {
+ /* flow control */
+ flow = atoi(p);
+ ignore = ((flow & 0x0F00) >> 4);
+ }
+
+ FlowIgnore = ignore;
+ flow = ((flow & 0xff) << 8) | (flow & 0xff);
+ flow &= 0xF00B;
+ FlowOutput = (flow & 0xff);
+ FlowInput = ((flow & 0xff00) >> 8);
+ }
+
+ /*
+ * Parse baud
+ */
+ if (baud < 75) {
+ /* < 75 baud == bogus */
+ SerialPort = 0;
+ continue;
+ }
+
+ baud = BAUD_DIVISOR / baud;
+ baud &= 0xffff;
+ BaudDivisor = baud;
+
+ /*
+ * If port > 3 then port is I/O addr
+ */
+ if (port <= 3) {
+ /* Get the I/O port from the BIOS */
+ port <<= 1;
+ port = *(volatile uint16_t *)serial_base;
+ }
+
+
+ SerialPort = port;
+
+ /*
+ * Begin code to actually set up the serial port
*/
+ memset(&ireg, 0, sizeof(ireg));
+ call16(sirq_cleanup_nowipe, &ireg, NULL);
+
+ outb(0x83, port + 3); /* Enable DLAB */
+ io_delay();
+
+ outb((baud & 0xff), port); /* write divisor to LS */
+ io_delay();
+ outb(((baud & 0xff00) >> 8), port + 1); /* write to MS */
+ io_delay();
+
+ outb(0x03, port + 3); /* Disable DLAB */
+ io_delay();
+
+ /*
+ * Read back LCR (detect missing hw). If nothing here
+ * we'll read 00 or FF.
+ */
+ if (inb(port + 3) != 0x03) {
+ /* Assume serial port busted */
+ SerialPort = 0;
+ continue;
+ }
+
+ outb(0x01, port + 2); /* Enable FIFOs if present */
+ io_delay();
+
+ /* Disable FIFO if unusable */
+ if (inb(port + 2) < 0x0C0) {
+ outb(0, port + 2);
+ io_delay();
+ }
+
+ /* Assert bits in MCR */
+ outb(FlowOutput, port + 4);
+ io_delay();
+
+ /* Enable interrupts if requested */
+ if (FlowOutput & 0x8)
+ call16(sirq_install, &ireg, NULL);
+
+ /* Show some life */
+ if (SerialNotice != 0) {
+ SerialNotice = 0;
+
+ ireg.esi.w[0] = syslinux_banner;
+ call16(write_serial_str, &ireg, NULL);
+
+ ireg.esi.w[0] = copyright_str;
+ call16(write_serial_str, &ireg, NULL);
+ }
} else if (looking_at(p, "say")) {
printf("%s\n", p + 4);
+ } else if (looking_at(p, "path")) {
+ /* PATH-based lookup */
+ char *new_path, *_p;
+ size_t len, new_len;
+
+ new_path = refstrdup(skipspace(p + 4));
+ len = strlen(PATH);
+ new_len = strlen(new_path);
+ _p = realloc(PATH, len + new_len + 2);
+ if (_p) {
+ strncpy(_p, PATH, len);
+ _p[len++] = ':';
+ strncpy(_p + len, new_path, new_len);
+ _p[len + new_len] = '\0';
+ PATH = _p;
+ } else
+ printf("Failed to realloc PATH\n");
}
}
}
static int parse_one_config(const char *filename)
{
+ const char *mode = "r";
FILE *f;
+ int fd;
- /*
- if (!strcmp(filename, "~"))
- filename = syslinux_config_file();
- */
-
- f = fopen(filename, "r");
- if (f)
- goto config_found;
-
- /* force to use hard coded config file name */
- f = fopen("extlinux.conf", "r");
- if (f)
- goto config_found;
-
- f = fopen("isolinux/isolinux.cfg", "r");
- if (f)
- goto config_found;
+ if (!filename)
+ fd = open_config();
+ else
+ fd = open(filename, O_RDONLY);
- f = fopen("syslinux.cfg", "r");
- if (f)
- goto config_found;
+ if (fd < 0)
+ return fd;
- return -1;
-config_found:
+ f = fdopen(fd, mode);
parse_config_file(f);
- fclose(f);
+
return 0;
}
@@ -1214,7 +1419,7 @@ void parse_configs(char **argv)
current_menu = root_menu;
if (!argv || !*argv) {
- parse_one_config("~");
+ parse_one_config(NULL);
} else {
while ((filename = *argv++)) {
dprintf("Parsing config: %s", filename);
diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h
index 656f8e2..9c00e4a 100644
--- a/com32/include/sys/exec.h
+++ b/com32/include/sys/exec.h
@@ -20,16 +20,6 @@
#define EXEC_ROOT_NAME "_root_.c32"
/**
- * MODULES_DEP - The name of the standard module dependency file
- *
- * This is the file which contains information about the module dependency
- * graph ( what other modules it depends on ). The file format is identical
- * to the standard linux modules.dep file... for more information check out the
- * man page ).
- */
-#define MODULES_DEP "modules.dep"
-
-/**
* spawn_load - Load a library module or executes an executable one
* @name the name of the library/executable to use, including the extension
* (e.g. 'sort.c32')
@@ -43,8 +33,6 @@
*/
extern int spawn_load(const char *name, int argc, char **argv);
-extern int module_load_dependencies(const char*name,const char*dep_file);
-
/**
* exec_init - Initialize the dynamic execution environment.
*
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index 431f5cd..1afdbf5 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -8,6 +8,7 @@
#include <stdio.h>
#include <elf.h>
#include <string.h>
+#include <fs.h>
#include <linux/list.h>
#include <sys/module.h>
@@ -56,13 +57,45 @@ void print_elf_symbols(struct elf_module *module) {
}
#endif //ELF_DEBUG
+static FILE *findpath(char *name)
+{
+ char path[FILENAME_MAX];
+ FILE *f;
+ char *p, *n;
+ int i;
+
+ p = PATH;
+again:
+ i = 0;
+ while (*p && *p != ':' && i < FILENAME_MAX) {
+ path[i++] = *p++;
+ }
+
+ if (*p == ':')
+ p++;
+
+ n = name;
+ while (*n && i < FILENAME_MAX)
+ path[i++] = *n++;
+ path[i] = '\0';
+
+ f = fopen(path, "rb");
+ if (f)
+ return f;
+
+ if (p >= PATH && p < PATH + strlen(PATH))
+ goto again;
+
+ return NULL;
+}
+
/*
* Image files manipulation routines
*/
int image_load(struct elf_module *module)
{
- module->u.l._file = fopen(module->name, "rb");
+ module->u.l._file = findpath(module->name);
if (module->u.l._file == NULL) {
DBG_PRINT("Could not open object file '%s'\n",
module->name);
diff --git a/com32/lib/sys/module/elf_module.c
b/com32/lib/sys/module/elf_module.c
index 8db4220..7d8dad4 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -18,6 +18,8 @@
#include "elfutils.h"
#include "common.h"
+#define MAX_NR_DEPS 64
+
static int check_header(Elf32_Ehdr *elf_hdr) {
int res;
@@ -178,6 +180,8 @@ out:
return res;
}
+static int nr_needed;
+static Elf32_Word needed[MAX_NR_DEPS];;
static int prepare_dynlinking(struct elf_module *module) {
Elf32_Dyn *dyn_entry = module->dyn_table;
@@ -185,7 +189,18 @@ static int prepare_dynlinking(struct elf_module *module) {
while (dyn_entry->d_tag != DT_NULL) {
switch (dyn_entry->d_tag) {
case DT_NEEDED:
- // TODO: Manage dependencies here
+ /*
+ * It's unlikely there'll be more than
+ * MAX_NR_DEPS DT_NEEDED entries but if there
+ * are then inform the user that we ran out of
+ * space.
+ */
+ if (nr_needed < MAX_NR_DEPS)
+ needed[nr_needed++] = dyn_entry->d_un.d_ptr;
+ else {
+ printf("Too many dependencies!\n");
+ return -1;
+ }
break;
case DT_HASH:
module->hash_table @@ -447,11 +462,45 @@ int module_load(struct
elf_module *module) {
CHECKED(res, load_segments(module, &elf_hdr), error);
//printf("bleah... 3\n");
// Obtain dynamic linking information
+ nr_needed = 0;
CHECKED(res, prepare_dynlinking(module), error);
//printf("check... 4\n");
//
//dump_elf_module(module);
+ /* Find modules we need to load as dependencies */
+ if (module->str_table) {
+ int i, n;
+
+ /*
+ * nr_needed can be modified by recursive calls to
+ * module_load() so keep a local copy on the stack.
+ */
+ n = nr_needed;
+ for (i = 0; i < n; i++) {
+ size_t len, j;
+ char *dep, *p;
+
+ dep = module->str_table + needed[i];
+
+ /* strip everything but the last component */
+ j = len = strlen(dep);
+ if (!len)
+ continue;
+
+ p = dep + len - 1;
+ while (j > 0 && *p && *p != '/') {
+ p--;
+ j--;
+ }
+
+ if (*p++ == '/') {
+ char argv[2] = { p, NULL };
+ spawn_load(p, 1, argv);
+ }
+ }
+ }
+
// Check the symbols for duplicates / missing definitions
CHECKED(res, check_symbols(module), error);
//printf("check... 5\n");
diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c
index 1ed3263..71d3192 100644
--- a/com32/lib/sys/module/exec.c
+++ b/com32/lib/sys/module/exec.c
@@ -346,150 +346,6 @@ int spawn_load(const char *name, int argc, char **argv)
*/
}
-/*
- * Avoid circular dependencies.
- *
- * It's possible that someone messed up the modules.dep file and that
- * it includes circular dependencies, so we need to take steps here to
- * avoid looping in module_load_dependencies() forever.
- *
- * We build a singly-linked list of modules that are in the middle of
- * being loaded. When they have completed loading their entry is
- * removed from this list in LIFO order (new entries are always added
- * to the head of the list).
- */
-struct loading_dep {
- const char *name;
- struct module_dep *next;
-};
-static struct loading_dep *loading_deps;
-
-/*
- * Remember that because we insert elements in a LIFO order we need to
- * start from the end of the list and work towards the front so that
- * we print the modules in the order in which we tried to load them.
- *
- * Yay for recursive function calls.
- */
-static void print_loading_dep(struct loading_dep *dep)
-{
- if (dep) {
- print_loading_dep(dep->next);
- printf("\t\t\"%s\"\n", dep->name);
- }
-}
-
-int module_load_dependencies(const char *name,const char *dep_file)
-{
- FILE *d_file=fopen(dep_file,"r");
- char line[2048],aux[2048],temp_name[MODULE_NAME_SIZE],slbz[24];
- int i=0,j=0,res=0;
- struct loading_dep *dep;
-
- if(d_file==NULL)
- {
- DBG_PRINT("Could not open object file '%s'\n",dep_file);
- return -1;
- }
-
- /*
- * Are we already in the middle of loading this module's
- * dependencies?
- */
- for (dep = loading_deps; dep; dep = dep->next) {
- if (!strcasecmp(dep->name, name))
- break; /* found */
- }
-
- if (dep) {
- struct loading_dep *last, *prev;
-
- /* Dup! */
- printf("\t\tCircular depedency detected when loading "
- "modules!\n");
- printf("\t\tModules dependency chain looks like this,\n\n");
- print_loading_dep(loading_deps);
- printf("\n\t\t... and we tried to load \"%s\" again\n",
name);
-
- return -1;
- } else {
- dep = malloc(sizeof(*dep));
- if (!dep) {
- printf("Failed to alloc memory for loading_dep\n");
- return -1;
- }
-
- dep->name = name;
- dep->next = loading_deps;
-
- /* Insert at the head of the list */
- loading_deps = dep;
- }
-
- /* Note from feng:
- * new modues.dep has line like this:
- * a.c32: b.32 c.c32 d.c32
- * with desktop glibc
- * sscanf(line,"%[^:]: %[^\n]", temp_name, aux);
- * works, which doesn't work here
- */
- memset(temp_name, 0, sizeof(temp_name));
- memset(aux, 0, sizeof(aux));
- while (1) {
- if(fgets(line,2048,d_file)==NULL)
- break;
-
- //sscanf(line,"%s %[^\t\n]s",temp_name,aux);
- //sscanf(line,"%[^:]: %[^\n]", temp_name, aux);
- //sscanf(line,"%[^:]: %[^\n]\n", temp_name, aux);
-
- sscanf(line,"%[^:]:", temp_name);
- if (!strncmp(name, temp_name, strlen(name))) {
- /* The next 2 chars should be ':' and ' ' */
- i = strlen(temp_name);
- if (line[i] != ':' || line[i+1] != ' ')
- break;
-
- i +=2;
- j = 0;
- while (line[i] != '\n')
- aux[j++] = line[i++];
- aux[j] = '\0';
- //dprintf("found dependency: temp_name = %s, aux = %s, name = %s",
temp_name, aux, name);
- break;
- }
- }
- fclose(d_file);
-
- /* Reuse temp_name for dependent module name buffer */
- memset(temp_name, 0, sizeof(temp_name));
- i = 0;
- while (aux[i]) {
- sscanf(aux + i, "%s", temp_name);
- //dprintf("load module: %s", temp_name);
- i += strlen(temp_name);
- i++; /* skip a space */
-
- if (strlen(temp_name)) {
- char *argv[2] = { temp_name, NULL };
- int ret;
-
- ret = module_load_dependencies(temp_name,
- MODULES_DEP);
- if (!ret) {
- if (spawn_load(temp_name, 1, argv) < 0)
- continue;
- }
- }
- }
-
- /* Remove our entry from the head of loading_deps */
- loading_deps = loading_deps->next;
- free(dep);
-
- return 0;
-}
-
void exec_term(void)
{
modules_term();
diff --git a/core/Makefile b/core/Makefile
index 96a7b9f..95424dc 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -25,7 +25,7 @@ include $(MAKEDIR)/embedded.mk
-include $(topdir)/version.mk
OPTFLAGS -INCLUDES = -I./include -I$(com32)/include
+INCLUDES = -I./include -I$(com32)/include -I$(com32)/lib
# This is very similar to cp437; technically it's for Norway and Denmark,
# but it's unlikely the characters that are different will be used in
diff --git a/core/conio.inc b/core/conio.inc
index b450502..ec2aa2a 100644
--- a/core/conio.inc
+++ b/core/conio.inc
@@ -26,6 +26,7 @@
;
section .text16
+ global loadkeys
loadkeys:
mov cx,256
mov di,trackbuf
@@ -53,6 +54,7 @@ loadkeys:
;
; Assumes CS == DS == ES.
;
+ global get_msg_file
get_msg_file:
mov byte [TextAttribute],07h ; Default grey on white
mov byte [DisplayMask],07h ; Display text in all modes
@@ -274,6 +276,7 @@ write_serial_str_displaymask:
test byte [DisplayMask], 04h
jz write_serial_str.end
+ global write_serial_str
write_serial_str:
.loop lodsb
and al,al
@@ -415,6 +418,7 @@ VidRows resb 1 ; Rows on screen-1
; loading a new config file to undo this setting.
section .data16
alignz 4
+ global SerialPort, BaudDivisor, FlowIgnore, FlowInput, FlowOutput
SerialPort dw 0 ; Serial port base (or 0 for no serial port)
BaudDivisor dw 115200/9600 ; Baud rate divisor
FlowControl equ $
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 793ecd5..e639653 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -75,6 +75,5 @@ void load_env32(com32sys_t * regs)
init_module_subsystem(&core_module);
- module_load_dependencies(LDLINUX, "modules.dep");
spawn_load(LDLINUX, 1, argv);
}
diff --git a/core/font.inc b/core/font.inc
index 1223635..9e840e4 100644
--- a/core/font.inc
+++ b/core/font.inc
@@ -25,6 +25,7 @@
;
loadfont.err: jmp close ; Tailcall the close routine
+ global loadfont
loadfont:
mov di,trackbuf
mov cx,4
diff --git a/core/fs/fs.c b/core/fs/fs.c
index 39ba09e..52bcf5b 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -1,11 +1,15 @@
+#include <sys/file.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <dprintf.h>
#include "core.h"
+#include "dev.h"
#include "fs.h"
#include "cache.h"
+char *PATH = "/:/bin/";
+
/* The currently mounted filesystem */
struct fs_info *this_fs = NULL; /* Root filesystem */
@@ -74,12 +78,33 @@ void _close_file(struct file *file)
free_file(file);
}
+extern const struct input_dev __file_dev;
+
/*
* Find and open the configuration file
*/
-int open_config(struct com32_filedata *filedata)
+int open_config(void)
{
- return this_fs->fs_ops->open_config(filedata);
+ int fd, handle;
+ struct file_info *fp;
+
+ fd = opendev(&__file_dev, NULL, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ fp = &__file_info[fd];
+
+ handle = this_fs->fs_ops->open_config(&fp->i.fd);
+ if (handle < 0) {
+ close(fd);
+ errno = ENOENT;
+ return -1;
+ }
+
+ fp->i.offset = 0;
+ fp->i.nbytes = 0;
+
+ return fd;
}
void pm_mangle_name(com32sys_t *regs)
diff --git a/core/fs/lib/searchconfig.c b/core/fs/lib/searchconfig.c
index 8e53ebc..fb7322b 100644
--- a/core/fs/lib/searchconfig.c
+++ b/core/fs/lib/searchconfig.c
@@ -26,7 +26,7 @@ int search_config(struct com32_filedata *filedata,
sf);
realpath(ConfigName, confignamebuf, FILENAME_MAX);
dprintf("Config search: %s\n", ConfigName);
- if (!open_file(ConfigName, filedata)) {
+ if (open_file(ConfigName, filedata) >= 0) {
chdir(sd);
return 0; /* Got it */
}
diff --git a/core/include/core.h b/core/include/core.h
index ed8e51a..4f5f843 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -21,6 +21,8 @@ extern char ConfigName[];
extern char KernelName[];
extern char cmd_line[];
extern char ConfigFile[];
+extern char syslinux_banner[];
+extern char copyright_str[];
/* diskstart.inc isolinux.asm*/
extern void getlinsec(void);
diff --git a/core/include/fs.h b/core/include/fs.h
index e9e4548..04451ed 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -178,6 +178,8 @@ static inline struct file *handle_to_file(uint16_t handle)
return handle ? &files[handle-1] : NULL;
}
+extern char *PATH;
+
/* fs.c */
void pm_mangle_name(com32sys_t *);
void pm_searchdir(com32sys_t *);
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index 512f16b..f24efe4 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -432,6 +432,7 @@ commit_vk:
ret
section .data16
+ global SerialNotice
vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
SerialNotice db 1 ; Only print this once
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index de380e8..8c56022 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -264,6 +264,11 @@ ROOT_FS_OPS:
%endmacro
;
+; Jump to 32-bit ELF space
+;
+ pm_call load_env32
+
+;
; Now we have the config file open. Parse the config file and
; run the user interface.
;
@@ -513,6 +518,7 @@ writestr_early equ writestr
section .data16
+ global copyright_str, syslinux_banner
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
db ' H. Peter Anvin et al', CR, LF, 0
diff --git a/core/serirq.inc b/core/serirq.inc
index 47ccd50..bd08b69 100644
--- a/core/serirq.inc
+++ b/core/serirq.inc
@@ -96,6 +96,7 @@ IRQMask resw 1 ; PIC IRQ mask status
section .text16
+ global sirq_install
sirq_install:
pushad
@@ -155,6 +156,7 @@ sirq_install:
popad
ret
+ global sirq_cleanup_nowipe
sirq_cleanup_nowipe:
pushad
push ds
diff --git a/elf_gen_dep.sh b/elf_gen_dep.sh
deleted file mode 100755
index 1badb64..0000000
--- a/elf_gen_dep.sh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-
-#######################################################
-# Round 1: get all the loacl and external symbols
-#######################################################
-
-for i in core/isolinux.elf core/pxelinux.elf com32/*/*.c32 com32/*/*/*.c32
-do
- # module=$(echo $i | sed "s/^\(.*\).o$/\1/")
-
- # remove the path infomation
- module=$(echo $i | sed "s/^.*\/\(.*\)$/\1/")
-
- readelf -s $i > temp.txt
- #Get the last 2 items of each line
- cut -c47- temp.txt > $module.txt
- rm temp.txt
-
- #Get the unresolved symbols
- sed -n -e "/UND $/d" -e "/_GLOBAL_OFFSET_TABLE_/d" -e
"s/^.UND.\(.*\)$/\1/p" $module.txt > $module.ext
-
- #Get the local symbols
- sed -n -e "/UND/d" -e "/ABS/d" -e "/...[0-9]
$/d" -e "/...[0-9] \./d" -e "/...[0-9]/p" $module.txt
> $module.int
- sed -i -e "s/^.....//g" $module.int
- sed -i -e "s/^\(.*\)$/\1 <$module>/g" $module.int
- # Delete all whitespace
- sed -i -e "s/^[ \t]*$//g" $module.int
-
- cat $module.int >> all.txt
-done
-
-
-touch modules.dep
-
-#######################################################
-# Round 2: get all the loacl and external symbols
-#######################################################
-
-# Consolidate the dependent modules to one line and remove
-# the redundant ones, and the "core"
-rm_cr ()
-{
- touch rmcr.tmp
- all_dep=$module:
- space=' '
-
- while read line
- do
- # skip the module which is alreay on the list
- grep $line rmcr.tmp > /dev/null && continue
-
- # grep extlinux/isolinux and remove them
- echo $line | grep extlinux > /dev/null && continue
- echo $line | grep isolinux > /dev/null && continue
- echo $line | grep pxelinux > /dev/null && continue
- echo $line | grep ldlinux > /dev/null && continue
-
- all_dep=$all_dep$space$line
- echo $all_dep > rmcr.tmp
- done
-
- echo $all_dep >> modules.dep
- rm rmcr.tmp
-}
-
-# Find the symbol belongs to which module by screening all.txt, do it
-# one by one, and the result "resolve.tmp" will be a file like:
-# a.c32
-# b.c32
-# c.c32
-resolve_sym ()
-{
- touch resolve.tmp
-
- while read symbol
- do
- # If no one provides the symbol we're trying to
- # resolve then add it to the list of unresolved
- # symbols.
- grep -q $symbol all.txt
- if [ $? -ne 0 ]; then
- # We only need to add the symbol once
- if [[ ! "$unresolved_symbols" =~ "$symbol" ]]; then
- unresolved_symbols="$unresolved_symbols $symbol"
- fi
- else
- #echo $symbol
- sed -n -e "s/^$symbol <\(.*\)>/\1/p" all.txt | head -n1
>> resolve.tmp
- #grep $symbol all.txt
- fi
- done
-
- rm_cr < resolve.tmp
- rm resolve.tmp
-}
-
-#only test name start with a/b
-#rm [c-z]*.ext
-
-if [ -e modules.dep ]
-then
- rm modules.dep
- touch modules.dep
-fi
-
-# Don't need to resolve the core symbols
-for i in extlinux isolinux pxelinux
-do
- if [ -e $i.elf.ext ]
- then
- rm $i.elf.ext
- fi
-done
-
-for i in *.ext
-do
- module=$(echo $i | sed "s/^\(.*\).ext$/\1/")
- resolve_sym < $i
-done
-
-# Do some cleanup
-rm *.txt
-rm *.ext
-rm *.int
-
-if [ "$unresolved_symbols" ]; then
- echo "WARNING: These symbols could not be resolved:"
$unresolved_symbols
-fi
-
-echo ELF modules dependency is bult up, pls check modules.dep!
diff --git a/mk/lib.mk b/mk/lib.mk
index 1792ea1..604b91a 100644
--- a/mk/lib.mk
+++ b/mk/lib.mk
@@ -32,7 +32,8 @@ LIBFLAGS = -DDYNAMIC_CRC_TABLE -DPNG_NO_CONSOLE_IO \
# LIBFLAGS += -DPNG_NO_FLOATING_POINT_SUPPORTED
REQFLAGS = $(GCCOPT) -g -mregparm=3 -DREGPARM=3 -D__COM32__ \
- -nostdinc -iwithprefix include -I. -I./sys -I../include
+ -nostdinc -iwithprefix include -I. -I./sys -I../include \
+ -I../../core/include
OPTFLAGS = -Os -march=i386 -falign-functions=0 -falign-jumps=0 \
-falign-labels=0 -ffast-math -fomit-frame-pointer
WARNFLAGS = $(GCCWARN) -Wpointer-arith -Wwrite-strings -Wstrict-prototypes
-Winline