[syslinux] [GIT PULL] elflink ldlinux

Matt Fleming matt at console-pimps.org
Tue Jun 7 12:15:54 PDT 2011


On Tue, 07 Jun 2011 09:31:38 -0700
"H. Peter Anvin" <hpa at zytor.com> wrote:

> > 
> > ... and lo and behold as soon as I sent this pull request I found a
> > bug. The following patch needs to be applied. Should I rebase my
> > for-hpa/elflink/ldlinux branch before you pull or would you prefer a
> > patch on top?
> > 
> 
> Hm... go ahead and rebase, I'll hold off.

OK, let's try this again!

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 (17):
      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: Use DT_NEEDED for module dependencies
      ldlinux: Add support for parsing "serial" config directive
      ldlinux: Parse "display" in config files
      ldlinux: Support "font"
      ldlinux: Support "kbdmap"
      Merge branch 'pxelinux' into for-hpa/elflink/ldlinux
      Merge branch 'fs-config' into for-hpa/elflink/ldlinux
      Merge branch 'PATH-based-search' into for-hpa/elflink/ldlinux
      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/diskfs.inc                    |    1 +
 core/diskstart.inc                 |    1 +
 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/isolinux.asm                  |    1 +
 core/parseconfig.inc               |    1 +
 core/pxelinux.asm                  |    6 +
 core/serirq.inc                    |    2 +
 elf_gen_dep.sh                     |  130 -----------------
 mk/lib.mk                          |    3 +-
 24 files changed, 377 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(&reg, 0, sizeof(reg));
+		reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+		call16(core_open, &reg, &reg);
+		if (!(reg.eflags.l & EFLAGS_ZF))
+			call16(get_msg_file, &reg, 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(&reg, 0, sizeof(reg));
+		reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+		call16(core_open, &reg, &reg);
+		if (!(reg.eflags.l & EFLAGS_ZF))
+			call16(loadfont, &reg, 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(&reg, 0, sizeof(reg));
+		reg.edi.w[0] = OFFS_WRT(KernelName, 0);
+		call16(core_open, &reg, &reg);
+		if (!(reg.eflags.l & EFLAGS_ZF))
+			call16(loadkeys, &reg, 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/diskfs.inc b/core/diskfs.inc
index 470aa42..2684328 100644
--- a/core/diskfs.inc
+++ b/core/diskfs.inc
@@ -125,6 +125,7 @@ kaboom2:
 ; -----------------------------------------------------------------------------
 
 		section .data16
+		global copyright_str
 copyright_str   db ' Copyright (C) 1994-'
 		asciidec YEAR
 		db ' H. Peter Anvin et al', CR, LF, 0
diff --git a/core/diskstart.inc b/core/diskstart.inc
index e0a710d..c8f7936 100644
--- a/core/diskstart.inc
+++ b/core/diskstart.inc
@@ -514,6 +514,7 @@ SuperInfo	resq 16			; The first 16 bytes expanded 8 times
 ; Banner information not needed in sector 1
 ;
 		section .data16
+		global syslinux_banner
 syslinux_banner	db CR, LF, MY_NAME, ' ', VERSION_STR
 late_banner	db ' ', DATE_STR, 0
 
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/isolinux.asm b/core/isolinux.asm
index 344cb1e..895468c 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -1034,6 +1034,7 @@ writestr_early	equ writestr
 ; Data that needs to be in the first sector
 ; -----------------------------------------------------------------------------
 
+		global syslinux_banner, copyright_str
 syslinux_banner	db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
 copyright_str   db ' Copyright (C) 1994-'
 		asciidec YEAR
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




More information about the Syslinux mailing list