Hi Peter,
The main part of this pull request includes commits that try to replace
as many __intcall() invocations as possible. Some remain, but not many
(and eventually they'll be gone too). There's also a patch to make
better use of ld's --as-needed option and various other bug
fixes/cleanups.
The following changes since commit ff7334a2ce536b7f4b1f6d6f93ff4e285a3bd45a:
Only compile dprintf/vdprintf if DEBUG_PORT is defined (2012-07-19 08:42:32
-0700)
are available in the git repository at:
git://git.zytor.com/users/mfleming/syslinux.git elflink
Matt Fleming (9):
core/elflink: Delete ADV code that's already in ldlinux
ldlinux: Stop using the internal KT_* image types
lib/sys/module: Add support for weak symbols
elflink: Replace __intcall() with direct function calls
Use pxe_call() instead of COMBOOT API
com32: Use --as-needed for LDFLAGS
ldlinux: Return to command prompt after loading COM32
rawcon_read: Fix reading high part of input keys
ldlinux: Use findpath() to lookup filenames
com32/chain/utility.c | 30 ++-------
com32/cmenu/Makefile | 8 +-
com32/cmenu/libmenu/syslnx.c | 22 +++----
com32/elflink/ldlinux/chainboot.c | 5 +-
com32/elflink/ldlinux/config.h | 2 +
com32/elflink/ldlinux/execute.c | 62 ++++++++++-------
com32/elflink/ldlinux/ldlinux.c | 113 ++++++++++++++++----------------
com32/elflink/ldlinux/readconfig.c | 16 +++++
com32/include/menu.h | 7 --
com32/include/sys/module.h | 10 +++
com32/include/syslinux/boot.h | 10 +++
com32/include/syslinux/config.h | 5 ++
com32/include/syslinux/features.h | 10 +--
com32/include/syslinux/pxe_api.h | 4 +
com32/lib/Makefile | 1 -
com32/lib/sys/ansicon_write.c | 4 +-
com32/lib/sys/gpxe.c | 14 +---
com32/lib/sys/module/common.c | 36 ++++++++++-
com32/lib/sys/module/elf_module.c | 15 ++++-
com32/lib/sys/rawcon_read.c | 25 +++++---
com32/lib/sys/rawcon_write.c | 8 +--
com32/lib/sys/serial_write.c | 8 +--
com32/lib/sys/stdcon_write.c | 15 ++---
com32/lib/sys/xserial_write.c | 8 +--
com32/lib/syslinux/cleanup.c | 12 ++--
com32/lib/syslinux/features.c | 51 --------------
com32/lib/syslinux/ipappend.c | 20 ++----
com32/lib/syslinux/keyboard.c | 14 +---
com32/lib/syslinux/pxe_dns.c | 14 +---
com32/lib/syslinux/pxe_get_cached.c | 11 +---
com32/lib/syslinux/pxe_get_nic.c | 12 +---
com32/lib/syslinux/run_command.c | 9 +--
com32/lib/syslinux/run_default.c | 10 +--
com32/lib/syslinux/runimage.c | 19 ++---
com32/lib/syslinux/serial.c | 19 +++--
com32/lib/syslinux/shuffle.c | 9 +--
com32/lib/syslinux/version.c | 21 ++++---
com32/lib/syslinux/video/fontquery.c | 16 ++---
com32/lib/syslinux/video/reportmode.c | 11 +--
com32/libupload/upload_tftp.c | 18 +----
com32/menu/menumain.c | 6 +-
com32/menu/readconfig.c | 2 +-
com32/modules/Makefile | 18 +----
com32/modules/gpxecmd.c | 11 +---
com32/modules/pxechn.c | 16 +----
com32/modules/sanboot.c | 11 +---
com32/rosh/Makefile | 4 +-
com32/samples/Makefile | 5 +-
com32/samples/resolv.c | 17 +----
core/comboot.inc | 1 +
core/console.c | 7 +--
core/diskfs.inc | 2 +-
core/elflink/advwrite.c | 45 -------------
core/elflink/load_env32.c | 19 +-----
core/elflink/setadv.c | 116 ---------------------------------
core/font.c | 4 +-
core/fs/pxe/pxe.c | 7 +--
core/fs/pxe/pxe.h | 2 -
core/hello.c | 6 +--
core/include/bios.h | 1 -
core/include/core.h | 16 +++++
core/include/graphics.h | 5 ++
core/isolinux.asm | 2 +-
mk/elf.mk | 2 +-
64 files changed, 375 insertions(+), 654 deletions(-)
delete mode 100644 com32/lib/syslinux/features.c
delete mode 100644 core/elflink/advwrite.c
delete mode 100644 core/elflink/setadv.c
diff --git a/com32/chain/utility.c b/com32/chain/utility.c
index b54e0cd..cb88272 100644
--- a/com32/chain/utility.c
+++ b/com32/chain/utility.c
@@ -4,7 +4,9 @@
#include <errno.h>
#include <unistd.h>
#include <string.h>
+#include <fs.h>
#include <syslinux/disk.h>
+#include <syslinux/pmapi.h>
#include "utility.h"
static const char *bpbtypes[] = {
@@ -93,14 +95,11 @@ void lba2chs(disk_chs *dst, const struct disk_info *di,
uint64_t lba, uint32_t m
uint32_t get_file_lba(const char *filename)
{
- com32sys_t inregs;
+ struct com32_filedata fd;
uint32_t lba = 0;
int size = 65536;
char *buf;
- /* Start with clean registers */
- memset(&inregs, 0, sizeof(com32sys_t));
-
buf = lmalloc(size);
if (!buf)
return 0;
@@ -108,32 +107,15 @@ uint32_t get_file_lba(const char *filename)
/* Put the filename in the bounce buffer */
strlcpy(buf, filename, size);
- /* Call comapi_open() which returns a structure pointer in SI
- * to a structure whose first member happens to be the LBA.
- */
- inregs.eax.w[0] = 0x0006;
- inregs.esi.w[0] = OFFS(buf);
- inregs.es = SEG(buf);
- __com32.cs_intcall(0x22, &inregs, &inregs);
-
- if ((inregs.eflags.l & EFLAGS_CF) || inregs.esi.w[0] == 0) {
+ if (open_file(buf, &fd) <= 0) {
goto fail; /* Filename not found */
}
/* Since the first member is the LBA, we simply cast */
- lba = *((uint32_t *) MK_PTR(inregs.ds, inregs.esi.w[0]));
-
- /* Clean the registers for the next call */
- memset(&inregs, 0, sizeof(com32sys_t));
-
- /* Put the filename in the bounce buffer */
- strlcpy(buf, filename, size);
+ lba = *((uint32_t *) MK_PTR(0, fd.handle));
/* Call comapi_close() to free the structure */
- inregs.eax.w[0] = 0x0008;
- inregs.esi.w[0] = OFFS(buf);
- inregs.es = SEG(buf);
- __com32.cs_intcall(0x22, &inregs, &inregs);
+ close_file(fd.handle);
fail:
lfree(buf);
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index c6e0cae..beb8dd2 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -17,16 +17,16 @@
NOGPL := 1
+LIBS = libmenu/libmenu.c32 \
+ $(com32)/libutil/libutil_com.c32 \
+ $(com32)/lib/libcom32.c32
+
topdir = ../..
MAKEDIR = $(topdir)/mk
include $(MAKEDIR)/elf.mk
CFLAGS += -I./libmenu
-LIBS = libmenu/libmenu.c32 \
- $(com32)/libutil/libutil_com.c32 \
- $(com32)/lib/libcom32.c32
-
LIBMENU = libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o \
$(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
diff --git a/com32/cmenu/libmenu/syslnx.c b/com32/cmenu/libmenu/syslnx.c
index 27823df..c681f58 100644
--- a/com32/cmenu/libmenu/syslnx.c
+++ b/com32/cmenu/libmenu/syslnx.c
@@ -12,7 +12,10 @@
#include <string.h>
#include <com32.h>
+#include <core.h>
+#include <graphics.h>
#include "syslnx.h"
+#include <syslinux/config.h>
com32sys_t inreg, outreg; // Global registers for this module
@@ -35,33 +38,26 @@ void runsyslinuxcmd(const char *cmd)
return;
strcpy(bounce, cmd);
- REG_AX(inreg) = 0x0003; // Run command
- REG_BX(inreg) = OFFS(bounce);
- REG_ES(inreg) = SEG(bounce);
- __intcall(0x22, &inreg, &outreg);
+ load_kernel(bounce);
}
void gototxtmode(void)
{
- REG_AX(inreg) = 0x0005;
- __intcall(0x22, &inreg, &outreg);
+ syslinux_force_text_mode();
}
void syslinux_idle(void)
{
- REG_AX(inreg) = 0x0013;
- __intcall(0x22, &inreg, &outreg);
+ __idle();
}
unsigned int getversion(char *deriv, unsigned int *numfun)
{
- REG_AX(inreg) = 0x0001;
- __intcall(0x22, &inreg, &outreg);
if (deriv)
- *deriv = REG_DL(outreg);
+ *deriv = __syslinux_version.filesystem;
if (numfun)
- *numfun = REG_AX(outreg);
- return REG_CX(outreg);
+ *numfun = __syslinux_version.max_api;
+ return __syslinux_version.version;
}
void runsyslinuximage(const char *cmd, long ipappend)
diff --git a/com32/elflink/ldlinux/chainboot.c
b/com32/elflink/ldlinux/chainboot.c
index c1efadf..4a4a2e1 100644
--- a/com32/elflink/ldlinux/chainboot.c
+++ b/com32/elflink/ldlinux/chainboot.c
@@ -30,11 +30,12 @@
#include "localboot.h"
#include "bios.h"
+#include <syslinux/boot.h>
#include <syslinux/bootrm.h>
#include <syslinux/movebits.h>
#include <syslinux/config.h>
-void chainboot_file(const char *file, enum kernel_type type)
+void chainboot_file(const char *file, uint32_t type)
{
uint8_t keeppxe = 0;
const union syslinux_derivative_info *sdi;
@@ -97,7 +98,7 @@ void chainboot_file(const char *file, enum kernel_type type)
* superblock.
*/
if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX &&
- type == KT_BSS && this_fs->fs_ops->copy_super(buf))
+ type == IMAGE_TYPE_BSS && this_fs->fs_ops->copy_super(buf))
goto bail;
if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h
index 4583202..ea4736e 100644
--- a/com32/elflink/ldlinux/config.h
+++ b/com32/elflink/ldlinux/config.h
@@ -47,4 +47,6 @@ extern int new_linux_kernel(char *okernel, char *ocmdline);
extern void pm_load_high(com32sys_t *regs);
+extern void ldlinux_enter_command(bool prompt);
+
#endif /* __CONFIG_H__ */
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 5d128cb..e7969c2 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -18,6 +18,7 @@
#include <com32.h>
#include <sys/exec.h>
#include <sys/io.h>
+#include <sys/module.h>
#include "core.h"
#include "menu.h"
#include "fs.h"
@@ -28,29 +29,28 @@
#include <syslinux/bootrm.h>
#include <syslinux/movebits.h>
#include <syslinux/config.h>
-
-/* Must match enum kernel_type */
-const char *const kernel_types[] = {
- "none",
- "localboot",
- "kernel",
- "linux",
- "boot",
- "bss",
- "pxe",
- "fdimage",
- "comboot",
- "com32",
- "config",
- NULL
+#include <syslinux/boot.h>
+
+const struct image_types image_boot_types[] = {
+ { "localboot", IMAGE_TYPE_LOCALBOOT },
+ { "kernel", IMAGE_TYPE_KERNEL },
+ { "linux", IMAGE_TYPE_LINUX },
+ { "boot", IMAGE_TYPE_BOOT },
+ { "bss", IMAGE_TYPE_BSS },
+ { "pxe", IMAGE_TYPE_PXE },
+ { "fdimage", IMAGE_TYPE_FDIMAGE },
+ { "comboot", IMAGE_TYPE_COMBOOT },
+ { "com32", IMAGE_TYPE_COM32 },
+ { "config", IMAGE_TYPE_CONFIG },
+ { NULL, 0 },
};
extern int create_args_and_load(char *);
-void execute(const char *cmdline, enum kernel_type type)
+void execute(const char *cmdline, uint32_t type)
{
- const char *p, *const *pp;
const char *kernel, *args;
+ const char *p;
com32sys_t ireg;
char *q;
@@ -79,22 +79,31 @@ void execute(const char *cmdline, enum kernel_type type)
dprintf("kernel is %s, args = %s type = %d \n", kernel, args,
type);
- if (kernel[0] == '.' && type == KT_NONE) {
+ if (kernel[0] == '.') {
/* It might be a type specifier */
- enum kernel_type type = KT_NONE;
- for (pp = kernel_types; *pp; pp++, type++) {
- if (!strcmp(kernel + 1, *pp)) {
+ const struct image_types *t;
+ for (t = image_boot_types; t->name; t++) {
+ if (!strcmp(kernel + 1, t->name)) {
/* Strip the type specifier and retry */
- execute(p, type);
+ execute(p, t->type);
return;
}
}
}
- if (type == KT_COM32) {
+ if (type == IMAGE_TYPE_COM32) {
/* new entry for elf format c32 */
create_args_and_load((char *)cmdline);
- } else if (type == KT_CONFIG) {
+
+ /*
+ * The old COM32 module code would run the module then
+ * drop the user back at the command prompt,
+ * irrespective of how the COM32 module was loaded,
+ * e.g. from vesamenu.c32.
+ */
+ unload_modules_since("ldlinux.c32");
+ ldlinux_enter_command(!noescape);
+ } else if (type == IMAGE_TYPE_CONFIG) {
char *argv[] = { "ldlinux.c32", NULL };
/* kernel contains the config file name */
@@ -105,9 +114,10 @@ void execute(const char *cmdline, enum kernel_type type)
mangle_name(config_cwd, args);
start_ldlinux(argv);
- } else if (type == KT_LOCALBOOT) {
+ } else if (type == IMAGE_TYPE_LOCALBOOT) {
local_boot(strtoul(kernel, NULL, 0));
- } else if (type == KT_PXE || type == KT_BSS || type == KT_BOOT) {
+ } else if (type == IMAGE_TYPE_PXE || type == IMAGE_TYPE_BSS ||
+ type == IMAGE_TYPE_BOOT) {
chainboot_file(kernel, type);
} else {
/* Need add one item for kernel load, as we don't use
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index f56f2c0..1c261cd 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -11,6 +11,7 @@
#include "menu.h"
#include "config.h"
#include "syslinux/adv.h"
+#include "syslinux/boot.h"
#include <sys/module.h>
@@ -20,15 +21,15 @@ struct file_ext {
};
static const struct file_ext file_extensions[] = {
- { ".com", KT_COMBOOT },
- { ".cbt", KT_COMBOOT },
- { ".c32", KT_COM32 },
- { ".img", KT_FDIMAGE },
- { ".bss", KT_BSS },
- { ".bin", KT_BOOT },
- { ".bs", KT_BOOT },
- { ".0", KT_PXE },
- { NULL, KT_NONE },
+ { ".com", IMAGE_TYPE_COMBOOT },
+ { ".cbt", IMAGE_TYPE_COMBOOT },
+ { ".c32", IMAGE_TYPE_COM32 },
+ { ".img", IMAGE_TYPE_FDIMAGE },
+ { ".bss", IMAGE_TYPE_BSS },
+ { ".bin", IMAGE_TYPE_BOOT },
+ { ".bs", IMAGE_TYPE_BOOT },
+ { ".0", IMAGE_TYPE_PXE },
+ { NULL, 0 },
};
/*
@@ -45,7 +46,7 @@ static inline const char *find_command(const char *str)
return p;
}
-enum kernel_type parse_kernel_type(const char *kernel)
+uint32_t parse_image_type(const char *kernel)
{
const struct file_ext *ext;
const char *p;
@@ -62,8 +63,8 @@ enum kernel_type parse_kernel_type(const char *kernel)
return ext->type;
}
- /* use KT_KERNEL as default */
- return KT_KERNEL;
+ /* use IMAGE_TYPE_KERNEL as default */
+ return IMAGE_TYPE_KERNEL;
}
/*
@@ -82,19 +83,20 @@ static const char *get_extension(const char *kernel)
for (ext = file_extensions; ext->name; ext++) {
char *str;
int elen = strlen(ext->name);
- int fd;
+ FILE *f;
str = malloc(len + elen + 1);
strncpy(str, kernel, len);
strncpy(str + len, ext->name, elen);
str[len + elen] = '\0';
-
- fd = searchdir(str);
+ f = findpath(str);
free(str);
- if (fd >= 0)
+ if (f) {
+ fclose(f);
return ext->name;
+ }
}
return NULL;
@@ -136,12 +138,12 @@ static const char *apply_extension(const char *kernel,
const char *ext)
* the the kernel. If we return the caller should call enter_cmdline()
* so that the user can help us out.
*/
-static void load_kernel(const char *command_line)
+void load_kernel(const char *command_line)
{
struct menu_entry *me;
- enum kernel_type type;
const char *cmdline;
const char *kernel;
+ uint32_t type;
kernel = strdup(command_line);
if (!kernel)
@@ -150,11 +152,7 @@ static void load_kernel(const char *command_line)
/* Virtual kernel? */
me = find_label(kernel);
if (me) {
- type = parse_kernel_type(me->cmdline);
-
- /* cmdline contains type specifier */
- if (me->cmdline[0] == '.')
- type = KT_NONE;
+ type = parse_image_type(me->cmdline);
execute(me->cmdline, type);
/* We shouldn't return */
@@ -170,8 +168,8 @@ static void load_kernel(const char *command_line)
*p = '\0';
}
- type = parse_kernel_type(kernel);
- if (type == KT_KERNEL) {
+ type = parse_image_type(kernel);
+ if (type == IMAGE_TYPE_KERNEL) {
const char *ext;
/*
@@ -189,7 +187,7 @@ static void load_kernel(const char *command_line)
free((void *)kernel);
kernel = k;
- type = parse_kernel_type(kernel);
+ type = parse_image_type(kernel);
}
}
@@ -204,7 +202,7 @@ bad_kernel:
*/
if (onerrorlen) {
rsprintf(&cmdline, "%s %s", onerror, default_cmd);
- execute(cmdline, KT_COM32);
+ execute(cmdline, IMAGE_TYPE_COM32);
}
}
@@ -225,6 +223,35 @@ static void enter_cmdline(void)
}
}
+void ldlinux_enter_command(bool prompt)
+{
+ const char *cmdline = default_cmd;
+
+ if (prompt)
+ goto cmdline;
+auto_boot:
+ /*
+ * Auto boot
+ */
+ if (defaultlevel || noescape) {
+ if (defaultlevel) {
+ load_kernel(cmdline); /* Shouldn't return */
+ } else {
+ printf("No DEFAULT or UI configuration directive found!\n");
+
+ if (noescape)
+ kaboom();
+ }
+ }
+
+cmdline:
+ /* Only returns if the user pressed enter or input timed out */
+ enter_cmdline();
+
+ cmdline = ontimeoutlen ? ontimeout : default_cmd;
+
+ goto auto_boot;
+}
int main(int argc __unused, char **argv __unused)
{
const void *adv;
@@ -252,7 +279,7 @@ int main(int argc __unused, char **argv __unused)
cmdline = dst = malloc(count + 1);
if (!dst) {
printf("Failed to allocate memory for ADV\n");
- goto cmdline;
+ ldlinux_enter_command(true);
}
for (i = 0; i < count; i++)
@@ -264,37 +291,11 @@ int main(int argc __unused, char **argv __unused)
syslinux_adv_write();
load_kernel(cmdline); /* Shouldn't return */
- goto cmdline;
+ ldlinux_enter_command(true);
}
/* TODO: Check KbdFlags? */
- if (forceprompt)
- goto cmdline;
-
- cmdline = default_cmd;
-auto_boot:
- /*
- * Auto boot
- */
- if (defaultlevel || noescape) {
- if (defaultlevel) {
- load_kernel(cmdline); /* Shouldn't return */
- } else {
- printf("No DEFAULT or UI configuration directive found!\n");
-
- if (noescape)
- kaboom();
- }
- }
-
-cmdline:
- /* Only returns if the user pressed enter or input timed out */
- enter_cmdline();
-
- cmdline = ontimeoutlen ? ontimeout : default_cmd;
-
- goto auto_boot;
-
+ ldlinux_enter_command(forceprompt);
return 0;
}
diff --git a/com32/elflink/ldlinux/readconfig.c
b/com32/elflink/ldlinux/readconfig.c
index 1a8434c..1db397a 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -52,6 +52,22 @@ const struct menu_parameter mparm[NPARAMS] = {
[P_HIDDEN_ROW] = {"hiddenrow", -2},
};
+/* Must match enum kernel_type */
+static const char *const kernel_types[] = {
+ "none",
+ "localboot",
+ "kernel",
+ "linux",
+ "boot",
+ "bss",
+ "pxe",
+ "fdimage",
+ "comboot",
+ "com32",
+ "config",
+ NULL
+};
+
short uappendlen = 0; //bytes in append= command
short ontimeoutlen = 0; //bytes in ontimeout command
short onerrorlen = 0; //bytes in onerror command
diff --git a/com32/include/menu.h b/com32/include/menu.h
index a3e9cd6..5a4c901 100644
--- a/com32/include/menu.h
+++ b/com32/include/menu.h
@@ -92,10 +92,6 @@ enum kernel_type {
KT_CONFIG, /* Configuration file */
};
-extern const char *const kernel_types[];
-
-extern enum kernel_type parse_kernel_type(const char *kernel);
-
/* Configurable integer parameters */
enum parameter_number {
P_WIDTH,
@@ -230,9 +226,6 @@ extern const int message_base_color;
extern const char *current_background;
void set_background(const char *new_background);
-/* execute.c */
-void execute(const char *cmdline, enum kernel_type type);
-
/* drain.c */
void drain_keyboard(void);
diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
index eabc9e0..ea11a88 100644
--- a/com32/include/sys/module.h
+++ b/com32/include/sys/module.h
@@ -138,6 +138,16 @@ struct module_dep {
};
+/**
+ * Unload all modules that have been loaded since @name.
+ *
+ * Returns the struct elf_module * for @name or %NULL if no modules
+ * have been loaded since @name.
+ */
+extern struct elf_module *unload_modules_since(const char *name);
+
+extern FILE *findpath(char *name);
+
#ifdef DYNAMIC_MODULE
diff --git a/com32/include/syslinux/boot.h b/com32/include/syslinux/boot.h
index 870cff3..aea32d9 100644
--- a/com32/include/syslinux/boot.h
+++ b/com32/include/syslinux/boot.h
@@ -48,6 +48,13 @@ void syslinux_chain_bootstrap(uint16_t flags, const void
*bootstrap,
uint32_t bootstrap_len, uint32_t edx,
uint32_t esi, uint16_t ds);
+struct image_types {
+ const char *name;
+ uint32_t type;
+};
+
+extern const struct image_types image_boot_types[];
+
#define IMAGE_TYPE_KERNEL 0
#define IMAGE_TYPE_LINUX 1
#define IMAGE_TYPE_BOOT 2
@@ -57,6 +64,9 @@ void syslinux_chain_bootstrap(uint16_t flags, const void
*bootstrap,
#define IMAGE_TYPE_COMBOOT 6
#define IMAGE_TYPE_COM32 7
#define IMAGE_TYPE_CONFIG 8
+#define IMAGE_TYPE_LOCALBOOT 9
+
+uint32_t parse_image_type(const char *cmdline);
void syslinux_run_kernel_image(const char *filename, const char *cmdline,
uint32_t ipappend_flags, uint32_t type);
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 50bd52f..7bdcdd6 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -181,4 +181,9 @@ static inline const struct syslinux_ipappend_strings
return &__syslinux_ipappend_strings;
}
+static inline enum syslinux_filesystem syslinux_filesystem(void)
+{
+ return syslinux_derivative_info()->c.filesystem;
+}
+
#endif /* _SYSLINUX_CONFIG_H */
diff --git a/com32/include/syslinux/features.h
b/com32/include/syslinux/features.h
index 4bebda4..d25d08d 100644
--- a/com32/include/syslinux/features.h
+++ b/com32/include/syslinux/features.h
@@ -31,18 +31,16 @@
#define SYSLINUX_FEATURE_LOCAL_BOOT (0*8+0)
#define SYSLINUX_FEATURE_NOOP_IDLE (0*8+1)
-extern struct __syslinux_feature_flags {
- unsigned int len;
- const unsigned char *ptr;
-} __syslinux_feature_flags;
+extern uint8_t feature_flags;
+extern uint8_t feature_flags_len;
static inline int syslinux_has_feature(unsigned int __flag)
{
unsigned int __byte = __flag >> 3;
unsigned int __bit = __flag & 7;
- if (__byte <= __syslinux_feature_flags.len)
- return (__syslinux_feature_flags.ptr[__byte] >> __bit) & 1;
+ if (__byte <= feature_flags_len)
+ return (feature_flags[__byte] >> __bit) & 1;
else
return 0;
}
diff --git a/com32/include/syslinux/pxe_api.h b/com32/include/syslinux/pxe_api.h
index 27166b0..203ab38 100644
--- a/com32/include/syslinux/pxe_api.h
+++ b/com32/include/syslinux/pxe_api.h
@@ -568,4 +568,8 @@ typedef struct s_PXENV_UNLOAD_STACK {
#define PXENV_STATUS_LOADER_UNDI_START 0xca
#define PXENV_STATUS_LOADER_BC_START 0xcb
+int __weak pxe_call(int, void *);
+void __weak unload_pxe(uint16_t flags);
+uint32_t __weak dns_resolv(const char *);
+
#endif /* _SYSLINUX_PXE_API_H */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index b83ae6b..5d270a4 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -46,7 +46,6 @@ LIBPCI_OBJS = \
LIBSYSLINUX_OBJS = \
syslinux/reboot.o syslinux/keyboard.o \
- syslinux/features.o \
syslinux/version.o \
syslinux/pxe_get_cached.o syslinux/pxe_get_nic.o \
syslinux/pxe_dns.o \
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c
index b25f2d2..e5483fb 100644
--- a/com32/lib/sys/ansicon_write.c
+++ b/com32/lib/sys/ansicon_write.c
@@ -42,6 +42,7 @@
#include <syslinux/config.h>
#include "file.h"
#include "ansi.h"
+#include "graphics.h"
static void ansicon_erase(const struct term_state *, int, int, int, int);
static void ansicon_write_char(int, int, uint8_t, const struct term_state *);
@@ -90,8 +91,7 @@ int __ansicon_open(struct file_info *fp)
ti.cols = 80;
} else {
/* Force text mode */
- ireg.eax.w[0] = 0x0005;
- __intcall(0x22, &ireg, NULL);
+ syslinux_force_text_mode();
/* Initial state */
ti.rows = BIOS_ROWS ? BIOS_ROWS + 1 : 25;
diff --git a/com32/lib/sys/gpxe.c b/com32/lib/sys/gpxe.c
index 06c4510..3cc2b84 100644
--- a/com32/lib/sys/gpxe.c
+++ b/com32/lib/sys/gpxe.c
@@ -7,9 +7,9 @@
bool is_gpxe(void)
{
const struct syslinux_version *sv;
- com32sys_t reg;
struct s_PXENV_FILE_CHECK_API *fca;
bool gpxe;
+ int err;
sv = syslinux_version();
if (sv->filesystem != SYSLINUX_FS_PXELINUX)
@@ -22,20 +22,14 @@ bool is_gpxe(void)
fca->Size = sizeof *fca;
fca->Magic = 0x91d447b2;
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = PXENV_FILE_API_CHECK;
- /* reg.edi.w[0] = OFFS(fca); */
- reg.es = SEG(fca);
-
- __intcall(0x22, ®, ®);
+ err = pxe_call(PXENV_FILE_API_CHECK, fca);
gpxe = true;
- if (reg.eflags.l & EFLAGS_CF)
+ if (err)
gpxe = false; /* Cannot invoke PXE stack */
- if (reg.eax.w[0] || fca->Status)
+ if (fca->Status)
gpxe = false; /* PXE failure */
if (fca->Magic != 0xe9c17b20)
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index 19742e6..6e63907 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -57,7 +57,7 @@ void print_elf_symbols(struct elf_module *module) {
}
#endif //ELF_DEBUG
-static FILE *findpath(char *name)
+FILE *findpath(char *name)
{
char path[FILENAME_MAX];
FILE *f;
@@ -321,7 +321,7 @@ int check_symbols(struct elf_module *module)
crt_name = module->str_table + crt_sym->st_name;
strong_count = 0;
- weak_count = 0;
+ weak_count = (ELF32_ST_BIND(crt_sym->st_info) == STB_WEAK);
for_each_module(crt_module)
{
@@ -345,6 +345,14 @@ int check_symbols(struct elf_module *module)
if (crt_sym->st_shndx == SHN_UNDEF)
{
// We have an undefined symbol
+ //
+ // We use the weak_count to differentiate
+ // between Syslinux-derivative-specific
+ // functions. For example, unload_pxe() is
+ // only provided by PXELINUX, so we mark it as
+ // __weak and replace it with a reference to
+ // undefined_symbol() on SYSLINUX, EXTLINUX,
+ // and ISOLINUX. See perform_relocations().
if (strong_count == 0 && weak_count == 0)
{
DBG_PRINT("Symbol %s is undefined\n", crt_name);
@@ -414,6 +422,30 @@ int module_unload(struct elf_module *module) {
return _module_unload(module);
}
+struct elf_module *unload_modules_since(const char *name) {
+ struct elf_module *m, *mod, *begin = NULL;
+
+ for_each_module(mod) {
+ if (!strcmp(mod->name, name)) {
+ begin = mod;
+ break;
+ }
+ }
+
+ if (!begin)
+ return begin;
+
+ for_each_module_safe(mod, m) {
+ if (mod == begin)
+ break;
+
+ if (mod != begin)
+ module_unload(mod);
+ }
+
+ return begin;
+}
+
static Elf32_Sym *module_find_symbol_sysv(const char *name, struct elf_module
*module) {
unsigned long h = elf_hash((const unsigned char*)name);
Elf32_Word *cr_word = module->hash_table;
diff --git a/com32/lib/sys/module/elf_module.c
b/com32/lib/sys/module/elf_module.c
index dbb5afe..b220e1a 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <elf.h>
#include <dprintf.h>
+#include <core.h>
#include <linux/list.h>
#include <sys/module.h>
@@ -238,6 +239,11 @@ static int prepare_dynlinking(struct elf_module *module) {
return 0;
}
+void undefined_symbol(void)
+{
+ printf("Error: An undefined symbol was referenced\n");
+ kaboom();
+}
static int perform_relocation(struct elf_module *module, Elf32_Rel *rel) {
Elf32_Word *dest = module_get_absolute(rel->r_offset, module);
@@ -263,11 +269,16 @@ static int perform_relocation(struct elf_module *module,
Elf32_Rel *rel) {
&sym_module);
if (sym_def == NULL) {
- // This should never happen
DBG_PRINT("Cannot perform relocation for symbol %s\n",
module->str_table + sym_ref->st_name);
- return -1;
+ if (ELF32_ST_BIND(sym_ref->st_info) != STB_WEAK)
+ return -1;
+
+ // This must be a derivative-specific
+ // function. We're OK as long as we never
+ // execute the function.
+ sym_def = global_find_symbol("undefined_symbol", &sym_module);
}
// Compute the absolute symbol virtual address
diff --git a/com32/lib/sys/rawcon_read.c b/com32/lib/sys/rawcon_read.c
index fbcd936..51bb953 100644
--- a/com32/lib/sys/rawcon_read.c
+++ b/com32/lib/sys/rawcon_read.c
@@ -35,31 +35,38 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include "file.h"
/* Global, since it's used by stdcon_read */
ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count)
{
- com32sys_t ireg, oreg;
char *bufp = buf;
size_t n = 0;
+ static char hi = 0;
+ static bool hi_key = false;
(void)fp;
- memset(&ireg, 0, sizeof ireg);
-
while (n < count) {
+ if (hi_key) {
+ *bufp++ = hi;
+ n++;
+ hi_key = false;
+ continue;
+ }
+
/* Poll */
- ireg.eax.b[1] = 0x0B;
- __intcall(0x21, &ireg, &oreg);
- if (!oreg.eax.b[0])
+ if (!pollchar())
break;
/* We have data, go get it */
- ireg.eax.b[1] = 0x08;
- __intcall(0x21, &ireg, &oreg);
- *bufp++ = oreg.eax.b[0];
+ *bufp = getchar(&hi);
+ if (!*bufp)
+ hi_key = true;
+
+ bufp++;
n++;
}
diff --git a/com32/lib/sys/rawcon_write.c b/com32/lib/sys/rawcon_write.c
index 2d45a7b..1f7920b 100644
--- a/com32/lib/sys/rawcon_write.c
+++ b/com32/lib/sys/rawcon_write.c
@@ -34,24 +34,20 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include "file.h"
static ssize_t __rawcon_write(struct file_info *fp, const void *buf,
size_t count)
{
- com32sys_t ireg;
const char *bufp = buf;
size_t n = 0;
(void)fp;
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.b[1] = 0x02;
-
while (count--) {
- ireg.edx.b[0] = *bufp++;
- __intcall(0x21, &ireg, NULL);
+ writechr(*bufp++);
n++;
}
diff --git a/com32/lib/sys/serial_write.c b/com32/lib/sys/serial_write.c
index fa0f4f4..3f949fb 100644
--- a/com32/lib/sys/serial_write.c
+++ b/com32/lib/sys/serial_write.c
@@ -34,13 +34,13 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include <syslinux/config.h>
#include "file.h"
ssize_t __serial_write(struct file_info *fp, const void *buf, size_t count)
{
- com32sys_t ireg;
const char *bufp = buf;
size_t n = 0;
@@ -49,12 +49,8 @@ ssize_t __serial_write(struct file_info *fp, const void *buf,
size_t count)
if (!syslinux_serial_console_info()->iobase)
return count; /* Nothing to do */
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.b[1] = 0x04;
-
while (count--) {
- ireg.edx.b[0] = *bufp++;
- __intcall(0x21, &ireg, NULL);
+ write_serial(*bufp++);
n++;
}
diff --git a/com32/lib/sys/stdcon_write.c b/com32/lib/sys/stdcon_write.c
index 9cb2f7d..9bd225f 100644
--- a/com32/lib/sys/stdcon_write.c
+++ b/com32/lib/sys/stdcon_write.c
@@ -34,6 +34,7 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include "file.h"
@@ -57,22 +58,16 @@ static int __stdcon_open(struct file_info *fp)
static ssize_t __stdcon_write(struct file_info *fp, const void *buf,
size_t count)
{
- com32sys_t ireg;
const char *bufp = buf;
size_t n = 0;
(void)fp;
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.b[1] = 0x02;
-
while (count--) {
- if (*bufp == '\n') {
- ireg.edx.b[0] = '\r';
- __intcall(0x21, &ireg, NULL);
- }
- ireg.edx.b[0] = *bufp++;
- __intcall(0x21, &ireg, NULL);
+ if (*bufp == '\n')
+ writechr('\r');
+
+ writechr(*bufp++);
n++;
}
diff --git a/com32/lib/sys/xserial_write.c b/com32/lib/sys/xserial_write.c
index e399f5f..8a4fb9e 100644
--- a/com32/lib/sys/xserial_write.c
+++ b/com32/lib/sys/xserial_write.c
@@ -35,6 +35,7 @@
#include <errno.h>
#include <string.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include <colortbl.h>
#include <syslinux/config.h>
@@ -42,12 +43,7 @@
static void emit(char ch)
{
- static com32sys_t ireg; /* Zeroed with the BSS */
-
- ireg.eax.b[1] = 0x04;
- ireg.edx.b[0] = ch;
-
- __intcall(0x21, &ireg, NULL);
+ write_serial(ch);
}
ssize_t __xserial_write(struct file_info *fp, const void *buf, size_t count)
diff --git a/com32/lib/syslinux/cleanup.c b/com32/lib/syslinux/cleanup.c
index 12140e5..066f174 100644
--- a/com32/lib/syslinux/cleanup.c
+++ b/com32/lib/syslinux/cleanup.c
@@ -26,15 +26,17 @@
* ----------------------------------------------------------------------- */
#include <syslinux/boot.h>
+#include <syslinux/config.h>
+#include <syslinux/pxe_api.h>
#include <stddef.h>
+#include <bios.h>
#include <com32.h>
+#include <core.h>
void syslinux_final_cleanup(uint16_t flags)
{
- static com32sys_t ireg;
+ if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX)
+ unload_pxe(flags);
- ireg.eax.w[0] = 0x000c;
- ireg.edx.w[0] = flags;
-
- __intcall(0x22, &ireg, NULL);
+ cleanup_hardware();
}
diff --git a/com32/lib/syslinux/features.c b/com32/lib/syslinux/features.c
deleted file mode 100644
index c88aef3..0000000
--- a/com32/lib/syslinux/features.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall
- * be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * syslinux/features.c
- *
- * SYSLINUX feature flag query
- */
-
-#include <klibc/compiler.h>
-#include <syslinux/features.h>
-#include <string.h>
-#include <com32.h>
-
-struct __syslinux_feature_flags __syslinux_feature_flags;
-
-void __constructor __syslinux_detect_features(void)
-{
- static com32sys_t reg;
-
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0015;
- __intcall(0x22, ®, ®);
-
- __syslinux_feature_flags.len = reg.ecx.w[0];
- __syslinux_feature_flags.ptr = MK_PTR(reg.es, reg.ebx.w[0]);
-}
diff --git a/com32/lib/syslinux/ipappend.c b/com32/lib/syslinux/ipappend.c
index bd00092..3eda48c 100644
--- a/com32/lib/syslinux/ipappend.c
+++ b/com32/lib/syslinux/ipappend.c
@@ -33,26 +33,18 @@
#include <syslinux/config.h>
#include <klibc/compiler.h>
-#include <com32.h>
+#include <core.h>
struct syslinux_ipappend_strings __syslinux_ipappend_strings;
static const char *syslinux_ipappend_string_list[32];
void __constructor __syslinux_get_ipappend_strings(void)
{
- static com32sys_t reg;
- int i;
+ unsigned int i;
- reg.eax.w[0] = 0x000f;
- __intcall(0x22, ®, ®);
+ __syslinux_ipappend_strings.count = (size_t)numIPAppends;
+ __syslinux_ipappend_strings.ptr = syslinux_ipappend_string_list;
- if (!(reg.eflags.l & EFLAGS_CF)) {
- __syslinux_ipappend_strings.count = reg.ecx.w[0];
- __syslinux_ipappend_strings.ptr = syslinux_ipappend_string_list;
- for (i = 0; i < reg.ecx.w[0]; i++) {
- syslinux_ipappend_string_list[i] - MK_PTR(reg.es,
- *(uint16_t *) MK_PTR(reg.es, reg.ebx.w[0] + i * 2));
- }
- }
+ for (i = 0; i < (size_t)numIPAppends; i++)
+ syslinux_ipappend_string_list[i] = (const char *)(size_t)IPAppends[i];
}
diff --git a/com32/lib/syslinux/keyboard.c b/com32/lib/syslinux/keyboard.c
index feafde0..03bd216 100644
--- a/com32/lib/syslinux/keyboard.c
+++ b/com32/lib/syslinux/keyboard.c
@@ -26,19 +26,13 @@
* ----------------------------------------------------------------------- */
#include <syslinux/keyboard.h>
-#include <com32.h>
+#include <core.h>
struct syslinux_keyboard_map __syslinux_keyboard_map;
void __constructor __syslinux_get_keyboard_map(void)
{
- static com32sys_t reg;
-
- reg.eax.w[0] = 0x001e;
- __intcall(0x22, ®, ®);
- if (!(reg.eflags.l & EFLAGS_CF)) {
- __syslinux_keyboard_map.version = reg.eax.w[0];
- __syslinux_keyboard_map.length = reg.ecx.w[0];
- __syslinux_keyboard_map.map = MK_PTR(reg.es, reg.ebx.w[0]);
- }
+ __syslinux_keyboard_map.version = 1;
+ __syslinux_keyboard_map.length = sizeof(KbdMap);
+ __syslinux_keyboard_map.map = (void *)KbdMap;
}
diff --git a/com32/lib/syslinux/pxe_dns.c b/com32/lib/syslinux/pxe_dns.c
index 6620396..b813b54 100644
--- a/com32/lib/syslinux/pxe_dns.c
+++ b/com32/lib/syslinux/pxe_dns.c
@@ -43,12 +43,12 @@
or -1 on invocation failure */
uint32_t pxe_dns(const char *hostname)
{
- com32sys_t regs;
union {
unsigned char b[4];
uint32_t ip;
} q;
char *lm_hostname;
+ uint32_t status;
/* Is this a dot-quad? */
if (sscanf(hostname, "%hhu.%hhu.%hhu.%hhu",
@@ -59,17 +59,9 @@ uint32_t pxe_dns(const char *hostname)
if (!lm_hostname)
return 0;
- memset(®s, 0, sizeof regs);
- regs.eax.w[0] = 0x0010;
- regs.es = SEG(lm_hostname);
- /* regs.ebx.w[0] = OFFS(lm_hostname); */
-
- __intcall(0x22, ®s, ®s);
+ status = dns_resolv(lm_hostname);
lfree(lm_hostname);
- if (regs.eflags.l & EFLAGS_CF)
- return 0;
-
- return regs.eax.l;
+ return status;
}
diff --git a/com32/lib/syslinux/pxe_get_cached.c
b/com32/lib/syslinux/pxe_get_cached.c
index 4704037..a090a4c 100644
--- a/com32/lib/syslinux/pxe_get_cached.c
+++ b/com32/lib/syslinux/pxe_get_cached.c
@@ -43,7 +43,6 @@
int pxe_get_cached_info(int level, void **buf, size_t * len)
{
const int max_dhcp_packet = 2048;
- com32sys_t regs;
t_PXENV_GET_CACHED_INFO *gci;
void *bbuf, *nbuf;
int err;
@@ -52,12 +51,6 @@ int pxe_get_cached_info(int level, void **buf, size_t * len)
if (!gci)
return -1;
- memset(®s, 0, sizeof regs);
- regs.eax.w[0] = 0x0009;
- regs.ebx.w[0] = PXENV_GET_CACHED_INFO;
- regs.es = SEG(gci);
- /* regs.edi.w[0] = OFFS(gci); */
-
bbuf = &gci[1];
gci->Status = PXENV_STATUS_FAILURE;
@@ -66,9 +59,9 @@ int pxe_get_cached_info(int level, void **buf, size_t * len)
gci->Buffer.seg = SEG(bbuf);
gci->Buffer.offs = OFFS(bbuf);
- __intcall(0x22, ®s, ®s);
+ err = pxe_call(PXENV_GET_CACHED_INFO, gci);
- if (regs.eflags.l & EFLAGS_CF) {
+ if (err) {
err = -1;
goto exit;
}
diff --git a/com32/lib/syslinux/pxe_get_nic.c b/com32/lib/syslinux/pxe_get_nic.c
index b301a75..6e256f9 100644
--- a/com32/lib/syslinux/pxe_get_nic.c
+++ b/com32/lib/syslinux/pxe_get_nic.c
@@ -42,25 +42,19 @@
or -1 on invocation failure */
int pxe_get_nic_type(t_PXENV_UNDI_GET_NIC_TYPE *gnt)
{
- com32sys_t regs;
t_PXENV_UNDI_GET_NIC_TYPE *lgnt;
+ int err;
lgnt = lzalloc(sizeof *lgnt);
if (!lgnt)
return -1;
- memset(®s, 0, sizeof regs);
- regs.eax.w[0] = 0x0009;
- regs.ebx.w[0] = PXENV_UNDI_GET_NIC_TYPE;
- regs.es = SEG(lgnt);
- /* regs.edi.w[0] = OFFS(lgnt); */
-
- __intcall(0x22, ®s, ®s);
+ err = pxe_call(PXENV_UNDI_GET_NIC_TYPE, lgnt);
memcpy(gnt, lgnt, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
lfree(lgnt);
- if (regs.eflags.l & EFLAGS_CF)
+ if (err)
return -1;
return gnt->Status;
diff --git a/com32/lib/syslinux/run_command.c b/com32/lib/syslinux/run_command.c
index a0ac9a0..0efb61f 100644
--- a/com32/lib/syslinux/run_command.c
+++ b/com32/lib/syslinux/run_command.c
@@ -28,21 +28,16 @@
#include <syslinux/boot.h>
#include <stddef.h>
#include <string.h>
-#include <com32.h>
+#include <core.h>
int syslinux_run_command(const char *command)
{
- static com32sys_t ireg;
char *lm_command = lstrdup(command);
if (!lm_command)
return -1;
- ireg.eax.w[0] = 0x0003;
- ireg.es = SEG(lm_command);
- /* ireg.ebx.w[0] = OFFS(lm_command); */
-
- __intcall(0x22, &ireg, NULL);
+ create_args_and_load(lm_command);
/* Should not return even on failure, but in case... */
lfree(lm_command);
diff --git a/com32/lib/syslinux/run_default.c b/com32/lib/syslinux/run_default.c
index 8dc9fbe..0cfa547 100644
--- a/com32/lib/syslinux/run_default.c
+++ b/com32/lib/syslinux/run_default.c
@@ -26,16 +26,14 @@
* ----------------------------------------------------------------------- */
#include <syslinux/boot.h>
+#include <core.h>
#include <stddef.h>
-#include <com32.h>
+
+extern const char *default_cmd;
__noreturn syslinux_run_default(void)
{
- static com32sys_t ireg;
-
- ireg.eax.w[0] = 0x0004;
- __intcall(0x22, &ireg, NULL);
-
+ load_kernel(default_cmd);
/* Should not return even on failure */
for (;;) ;
}
diff --git a/com32/lib/syslinux/runimage.c b/com32/lib/syslinux/runimage.c
index d5cdbc6..4391114 100644
--- a/com32/lib/syslinux/runimage.c
+++ b/com32/lib/syslinux/runimage.c
@@ -34,15 +34,18 @@
#include <stdlib.h>
#include <string.h>
#include <syslinux/boot.h>
-#include <com32.h>
+#include <syslinux/config.h>
+#include <core.h>
+
+extern unsigned int ipappend;
void syslinux_run_kernel_image(const char *filename, const char *cmdline,
uint32_t ipappend_flags, uint32_t type)
{
- static com32sys_t ireg;
char *bbfilename = NULL;
char *bbcmdline = NULL;
+
bbfilename = lstrdup(filename);
if (!bbfilename)
goto fail;
@@ -51,16 +54,10 @@ void syslinux_run_kernel_image(const char *filename, const
char *cmdline,
if (!bbcmdline)
goto fail;
+ if (syslinux_filesystem() == SYSLINUX_FS_PXELINUX)
+ ipappend = ipappend_flags;
- ireg.eax.w[0] = 0x0016;
- ireg.ds = SEG(bbfilename);
- /* ireg.esi.w[0] = OFFS(bbfilename); */
- ireg.es = SEG(bbcmdline);
- /* ireg.ebx.w[0] = OFFS(bbcmdline); */
- ireg.ecx.l = ipappend_flags;
- ireg.edx.l = type;
-
- __intcall(0x22, &ireg, 0);
+ execute(bbfilename, type);
fail:
if (bbcmdline)
diff --git a/com32/lib/syslinux/serial.c b/com32/lib/syslinux/serial.c
index f06e8c8..bb92222 100644
--- a/com32/lib/syslinux/serial.c
+++ b/com32/lib/syslinux/serial.c
@@ -34,19 +34,22 @@
#include <klibc/compiler.h>
#include <syslinux/config.h>
#include <string.h>
-#include <com32.h>
+#include <bios.h>
+#include <core.h>
struct syslinux_serial_console_info __syslinux_serial_console_info;
void __constructor __syslinux_get_serial_console_info(void)
{
- static com32sys_t reg;
+ uint16_t flowctl;
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x000b;
- __intcall(0x22, ®, ®);
+ __syslinux_serial_console_info.iobase = SerialPort;
+ __syslinux_serial_console_info.divisor = BaudDivisor;
- __syslinux_serial_console_info.iobase = reg.edx.w[0];
- __syslinux_serial_console_info.divisor = reg.ecx.w[0];
- __syslinux_serial_console_info.flowctl = reg.ebx.w[0];
+ flowctl = FlowOutput | FlowInput | (FlowIgnore << 4);
+
+ if (!DisplayCon)
+ flowctl |= (0x80 << 8);
+
+ __syslinux_serial_console_info.flowctl = flowctl;
}
diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c
index e9ee6aa..544915a 100644
--- a/com32/lib/syslinux/shuffle.c
+++ b/com32/lib/syslinux/shuffle.c
@@ -38,6 +38,7 @@
#include <string.h>
#include <inttypes.h>
#include <com32.h>
+#include <core.h>
#include <minmax.h>
#include <dprintf.h>
#include <syslinux/movebits.h>
@@ -51,12 +52,8 @@ static int shuffler_size;
static void __constructor __syslinux_get_shuffer_size(void)
{
- static com32sys_t reg;
-
- reg.eax.w[0] = 0x0023;
- __intcall(0x22, ®, ®);
-
- shuffler_size = (reg.eflags.l & EFLAGS_CF) ? 2048 : reg.ecx.w[0];
+ /* +15 padding is to guarantee alignment */
+ shuffler_size = __bcopyxx_len + 15;
}
/*
diff --git a/com32/lib/syslinux/version.c b/com32/lib/syslinux/version.c
index 15b617b..1cd2efd 100644
--- a/com32/lib/syslinux/version.c
+++ b/com32/lib/syslinux/version.c
@@ -27,20 +27,23 @@
#include <syslinux/config.h>
#include <klibc/compiler.h>
-#include <com32.h>
+#include <core.h>
+#include <../../../version.h>
struct syslinux_version __syslinux_version;
void __constructor __syslinux_get_version(void)
{
- static com32sys_t reg;
+ __syslinux_version.version = (VERSION_MAJOR << 8) + VERSION_MINOR;
- reg.eax.w[0] = 0x0001;
- __intcall(0x22, ®, ®);
+ /* We no longer support the COMBOOT API */
+ __syslinux_version.max_api = 0xffff;
- __syslinux_version.version = reg.ecx.w[0];
- __syslinux_version.max_api = reg.eax.w[0];
- __syslinux_version.filesystem = reg.edx.b[0];
- __syslinux_version.version_string = MK_PTR(reg.es, reg.esi.w[0]);
- __syslinux_version.copyright_string = MK_PTR(reg.es, reg.edi.w[0]);
+ __syslinux_version.filesystem = syslinux_filesystem();
+
+ /* Skip leading CR LF */
+ __syslinux_version.version_string = &syslinux_banner[2];
+
+ /* Skip leading space */
+ __syslinux_version.copyright_string = ©right_str[1];
}
diff --git a/com32/lib/syslinux/video/fontquery.c
b/com32/lib/syslinux/video/fontquery.c
index dd5d86e..ac1fab3 100644
--- a/com32/lib/syslinux/video/fontquery.c
+++ b/com32/lib/syslinux/video/fontquery.c
@@ -31,24 +31,18 @@
*/
#include <syslinux/video.h>
-#include <com32.h>
+#include <graphics.h>
/*
* Returns height of font or zero if no custom font loaded
*/
int syslinux_font_query(uint8_t **font)
{
- static com32sys_t ireg;
- com32sys_t oreg;
- int height;
+ if (!UserFont)
+ return 0;
- ireg.eax.w[0] = 0x0018;
- __intcall(0x22, &ireg, &oreg);
+ *font = (uint8_t *)fontbuf;
- height = !(oreg.eflags.l & EFLAGS_CF) ? oreg.eax.b[0] : 0;
- if (height)
- *font = MK_PTR(oreg.es, oreg.ebx.w[0]);
-
- return height;
+ return VGAFontSize;
}
diff --git a/com32/lib/syslinux/video/reportmode.c
b/com32/lib/syslinux/video/reportmode.c
index 57fd6fd..2a2c577 100644
--- a/com32/lib/syslinux/video/reportmode.c
+++ b/com32/lib/syslinux/video/reportmode.c
@@ -31,15 +31,12 @@
*/
#include <syslinux/video.h>
-#include <com32.h>
+#include <graphics.h>
void syslinux_report_video_mode(uint16_t flags, uint16_t xsize, uint16_t ysize)
{
- static com32sys_t ireg;
+ if (flags > 0x0f)
+ return;
- ireg.eax.w[0] = 0x0017;
- ireg.ebx.w[0] = flags;
- ireg.ecx.w[0] = xsize;
- ireg.edx.w[0] = ysize;
- __intcall(0x22, &ireg, NULL);
+ using_vga(flags, xsize, ysize);
}
diff --git a/com32/libupload/upload_tftp.c b/com32/libupload/upload_tftp.c
index 5e73c1c..6a0dacb 100644
--- a/com32/libupload/upload_tftp.c
+++ b/com32/libupload/upload_tftp.c
@@ -53,7 +53,6 @@ const char *tftp_string_error_message[]={
static int send_ack_packet(struct tftp_state *tftp,
const void *pkt, size_t len)
{
- com32sys_t ireg, oreg;
t_PXENV_UDP_WRITE *uw;
t_PXENV_UDP_READ *ur;
clock_t start;
@@ -67,9 +66,6 @@ static int send_ack_packet(struct tftp_state *tftp,
uw = lmalloc(sizeof *uw + len);
ur = lmalloc(sizeof *ur + RCV_BUF);
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.w[0] = 0x0009;
-
for (timeout = timeouts ; *timeout ; timeout++) {
memset(uw, 0, sizeof *uw);
memcpy(uw+1, pkt, len);
@@ -80,11 +76,7 @@ static int send_ack_packet(struct tftp_state *tftp,
uw->buffer_size = len;
uw->buffer = FAR_PTR(uw+1);
- ireg.ebx.w[0] = PXENV_UDP_WRITE;
- ireg.es = SEG(uw);
- ireg.edi.w[0] = OFFS(uw);
-
- __intcall(0x22, &ireg, &oreg);
+ pxe_call(PXENV_UDP_WRITE, uw);
start = times(NULL);
@@ -97,13 +89,9 @@ static int send_ack_packet(struct tftp_state *tftp,
ur->buffer_size = RCV_BUF;
ur->buffer = FAR_PTR(ur+1);
- ireg.ebx.w[0] = PXENV_UDP_READ;
- ireg.es = SEG(ur);
- ireg.edi.w[0] = OFFS(ur);
- __intcall(0x22, &ireg, &oreg);
+ err = pxe_call(PXENV_UDP_READ, ur);
- if (!(oreg.eflags.l & EFLAGS_CF) &&
- ur->status == PXENV_STATUS_SUCCESS &&
+ if (!err && ur->status == PXENV_STATUS_SUCCESS &&
tftp->srv_ip == ur->src_ip &&
(tftp->srv_port == 0 ||
tftp->srv_port == ur->s_port)) {
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index 53bc6c6..c9762b2 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -28,7 +28,9 @@
#include <setjmp.h>
#include <limits.h>
#include <com32.h>
+#include <core.h>
#include <syslinux/adv.h>
+#include <syslinux/boot.h>
#include "menu.h"
@@ -1161,11 +1163,11 @@ int main(int argc, char *argv[])
printf("\033[?25h\033[%d;1H\033[0m", cursorrow);
if (cmdline) {
- enum kernel_type type = parse_kernel_type(cmdline);
+ uint32_t type = parse_image_type(cmdline);
execute(cmdline, type);
if (cm->onerror) {
- type = parse_kernel_type(cm->onerror);
+ type = parse_image_type(cm->onerror);
execute(cm->onerror, type);
}
} else {
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 8f9d237..69f524c 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -62,7 +62,7 @@ static const struct messages messages[MSG_COUNT] = {
__p; })
/* Must match enum kernel_type */
-const char *const kernel_types[] = {
+static const char *const kernel_types[] = {
"none",
"localboot",
"kernel",
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 8d94cfe..8f5b769 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -15,6 +15,9 @@
## COM32 standard modules
##
+LIBS = $(com32)/gpllib/libcom32gpl.c32 $(com32)/lib/libcom32.c32 \
+ $(com32)/libutil/libutil_com.c32
+
topdir = ../..
MAKEDIR = $(topdir)/mk
include $(MAKEDIR)/elf.mk
@@ -28,21 +31,6 @@ MODULES = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32
\
TESTFILES
-LDFLAGS_cpuidtest.o = $(com32)/gpllib/libcom32gpl.c32
-LDFLAGS_disk.o = $(com32)/gpllib/libcom32gpl.c32
-LDFLAGS_ethersel.o = $(com32)/lib/libcom32.c32
-LDFLAGS_gpxecmd.o = $(com32)/lib/libcom32.c32
-LDFLAGS_host.o = $(com32)/lib/libcom32.c32
-LDFLAGS_ifcpu.o = $(com32)/libutil/libutil_com.c32 \
- $(com32)/gpllib/libcom32gpl.c32
-LDFLAGS_kbdmap.o = $(com32)/lib/libcom32.c32
-LDFLAGS_linux.o = $(com32)/lib/libcom32.c32
-LDFLAGS_pxechn.o = $(com32)/lib/libcom32.c32 \
- $(com32)/libutil/libutil_com.c32
-LDFLAGS_sanboot.o = $(com32)/lib/libcom32.c32
-LDFLAGS_vpdtest.o = $(com32)/gpllib/libcom32gpl.c32
-LDFLAGS_zzjson.o = $(com32)/gpllib/libcom32gpl.c32
-
all: $(MODULES) $(TESTFILES)
.PRECIOUS: %.o
diff --git a/com32/modules/gpxecmd.c b/com32/modules/gpxecmd.c
index 9d4f456..d2d90a2 100644
--- a/com32/modules/gpxecmd.c
+++ b/com32/modules/gpxecmd.c
@@ -39,9 +39,6 @@ static void gpxecmd(const char **args)
{
char *q;
struct s_PXENV_FILE_EXEC *fx;
- com32sys_t reg;
-
- memset(®, 0, sizeof reg);
fx = lmalloc(sizeof *fx);
if (!fx)
@@ -60,13 +57,7 @@ static void gpxecmd(const char **args)
}
*--q = '\0';
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = PXENV_FILE_EXEC;
- reg.edi.w[0] = OFFS(fx);
- reg.es = SEG(fx);
-
- __intcall(0x22, ®, ®);
+ pxe_call(PXENV_FILE_EXEC, fx);
/* This should not return... */
}
diff --git a/com32/modules/pxechn.c b/com32/modules/pxechn.c
index 1902d4e..39ac72e 100644
--- a/com32/modules/pxechn.c
+++ b/com32/modules/pxechn.c
@@ -845,7 +845,6 @@ int pxechn_args(int argc, char *argv[], struct pxelinux_opt
*pxe)
*/
int dhcp_pkt2pxe(pxe_bootp_t *p, size_t len, int ptype)
{
- com32sys_t reg;
t_PXENV_GET_CACHED_INFO *ci;
void *cp;
int rv = -1;
@@ -857,12 +856,7 @@ int dhcp_pkt2pxe(pxe_bootp_t *p, size_t len, int ptype)
}
ci->Status = PXENV_STATUS_FAILURE;
ci->PacketType = ptype;
- memset(®, 0, sizeof(reg));
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = PXENV_GET_CACHED_INFO;
- reg.edi.w[0] = OFFS(ci);
- reg.es = SEG(ci);
- __intcall(0x22, ®, ®);
+ pxe_call(PXENV_GET_CACHED_INFO, ci);
if (ci->Status != PXENV_STATUS_SUCCESS) {
dprintf("PXE Get Cached Info failed: %d\n", ci->Status);
@@ -1015,7 +1009,6 @@ int pxe_restart(char *ifn)
{
int rv = 0;
struct pxelinux_opt pxe;
- com32sys_t reg;
t_PXENV_RESTART_TFTP *pxep; /* PXENV callback Parameter */
pxe.fn = ifn;
@@ -1030,7 +1023,6 @@ int pxe_restart(char *ifn)
goto ret;
}
printf(" Attempting to boot '%s'...\n\n", pxe.fn);
- memset(®, 0, sizeof reg);
if (!(pxep = lzalloc(sizeof(t_PXENV_RESTART_TFTP)))){
dprintf("Unable to lzalloc() for PXE call structure\n");
goto ret;
@@ -1044,12 +1036,8 @@ int pxe_restart(char *ifn)
pxep->ServerIPAddress, (unsigned int)pxep,
pxep->BufferSize, (unsigned int)pxep->Buffer);
dprintf("PXENV_RESTART_TFTP status %d\n", pxep->Status);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = PXENV_RESTART_TFTP;
- reg.edi.w[0] = OFFS(pxep);
- reg.es = SEG(pxep);
- __intcall(0x22, ®, ®);
+ pxe_call(PXENV_RESTART_TFTP, pxep);
printf("PXENV_RESTART_TFTP returned %d\n", pxep->Status);
lfree(pxep);
diff --git a/com32/modules/sanboot.c b/com32/modules/sanboot.c
index d55fbc0..ff55f68 100644
--- a/com32/modules/sanboot.c
+++ b/com32/modules/sanboot.c
@@ -39,9 +39,6 @@ static void sanboot(const char **args)
{
char *q;
struct s_PXENV_FILE_EXEC *fx;
- com32sys_t reg;
-
- memset(®, 0, sizeof reg);
fx = lmalloc(sizeof *fx);
if (!fx)
@@ -61,13 +58,7 @@ static void sanboot(const char **args)
args++;
}
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0009;
- reg.ebx.w[0] = PXENV_FILE_EXEC;
- reg.edi.w[0] = OFFS(fx);
- reg.es = SEG(fx);
-
- __intcall(0x22, ®, ®);
+ pxe_call(PXENV_FILE_EXEC, fx);
/* This should not return... */
}
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index f328395..a894c84 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -16,6 +16,8 @@
## ROSH Read Only Shell
##
+LIBS = $(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
+
topdir = ../..
MAKEDIR = $(topdir)/mk
include $(MAKEDIR)/rosh.mk
@@ -34,8 +36,6 @@ endif
CFLAGS += -DDATE='"$(DATE)"'
LNXCFLAGS += -DDATE='"$(DATE)"'
-LDFLAGS_rosh.o = $(com32)/libutil/libutil_com.c32 $(com32)/lib/libcom32.c32
-
rosh.o: rosh.h
rosh.lo: rosh.h
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index bca197e..c7abadd 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -14,13 +14,12 @@
## samples for syslinux users
##
+LIBS = $(com32)/libutil/libutil_com.c32
+
topdir = ../..
MAKEDIR = $(topdir)/mk
include $(MAKEDIR)/elf.mk
-LDFLAGS_fancyhello.o = $(com32)/libutil/libutil_com.c32
-LDFLAGS_keytest.o = $(com32)/libutil/libutil_com.c32
-
all: hello.c32 resolv.c32 serialinfo.c32 \
localboot.c32 \
fancyhello.c32 fancyhello.lnx \
diff --git a/com32/samples/resolv.c b/com32/samples/resolv.c
index bd49d9f..f4a0e52 100644
--- a/com32/samples/resolv.c
+++ b/com32/samples/resolv.c
@@ -16,6 +16,7 @@
* Resolve an IP address
*/
+#include <syslinux/pxe_api.h>
#include <string.h>
#include <stdio.h>
#include <console.h>
@@ -24,21 +25,7 @@
uint32_t resolv(const char *name)
{
- com32sys_t reg;
-
- strcpy((char *)__com32.cs_bounce, name);
-
- memset(®, 0, sizeof reg);
- reg.eax.w[0] = 0x0010;
- reg.ebx.w[0] = OFFS(__com32.cs_bounce);
- reg.es = SEG(__com32.cs_bounce);
-
- __intcall(0x22, ®, ®);
-
- if (reg.eflags.l & EFLAGS_CF)
- return 0;
- else
- return reg.eax.l;
+ return dns_resolv(name);
}
int main(int argc, char *argv[])
diff --git a/core/comboot.inc b/core/comboot.inc
index 1e19d28..175c50c 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -842,6 +842,7 @@ zero_string db 0 ; Empty, null-terminated string
; Note: PXELINUX clears the idle is noop flag if appropriate
; in pxe_detect_nic_type
;
+ global feature_flags, feature_flags_len
feature_flags:
db 1 ; Have local boot, idle is not noop
feature_flags_len equ ($-feature_flags)
diff --git a/core/console.c b/core/console.c
index 282c57f..3b545bb 100644
--- a/core/console.c
+++ b/core/console.c
@@ -1,18 +1,15 @@
#include <stddef.h>
#include <com32.h>
+#include <core.h>
#include <stdio.h>
#include <string.h>
void myputchar(int c)
{
- static com32sys_t ireg;
-
if (c == '\n')
myputchar('\r');
- ireg.eax.b[1] = 0x02;
- ireg.edx.b[0] = c;
- __intcall(0x21, &ireg, NULL);
+ writechr(c);
}
void myputs(const char *str)
diff --git a/core/diskfs.inc b/core/diskfs.inc
index 02382cc..dcbc924 100644
--- a/core/diskfs.inc
+++ b/core/diskfs.inc
@@ -109,9 +109,9 @@ PXERetry dw 0 ; Extra PXE retries
section .data16
global SerialNotice
SerialNotice db 1 ; Only print this once
+ global IPAppends, numIPAppends
%if IS_PXELINUX
extern IPOption
- global IPAppends, numIPAppends
alignz 2
IPAppends dw IPOption
numIPAppends equ ($-IPAppends)/2
diff --git a/core/elflink/advwrite.c b/core/elflink/advwrite.c
deleted file mode 100644
index 4152eea..0000000
--- a/core/elflink/advwrite.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall
- * be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * syslinux/advwrite.c
- *
- * Write back the ADV
- */
-
-#include <syslinux/adv.h>
-#include <klibc/compiler.h>
-#include <com32.h>
-
-int syslinux_adv_write(void)
-{
- static com32sys_t reg;
-
- reg.eax.w[0] = 0x001d;
- __intcall(0x22, ®, ®);
- return (reg.eflags.l & EFLAGS_CF) ? -1 : 0;
-}
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index b15cdbb..8e124a0 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -66,28 +66,15 @@ int start_ldlinux(char **argv)
again:
rv = spawn_load(LDLINUX, 1, argv);
if (rv == EEXIST) {
- struct elf_module *m, *mod, *begin = NULL;
-
/*
* If a COM32 module calls execute() we may need to
* unload all the modules loaded since ldlinux.c32,
* and restart initialisation. This is especially
* important for config files.
*/
- for_each_module(mod) {
- if (!strcmp(mod->name, LDLINUX)) {
- begin = mod;
- break;
- }
- }
+ struct elf_module *ldlinux;
- for_each_module_safe(mod, m) {
- if (mod == begin)
- break;
-
- if (mod != begin)
- module_unload(mod);
- }
+ ldlinux = unload_modules_since(LDLINUX);
/*
* Finally unload LDLINUX.
@@ -96,7 +83,7 @@ again:
* cause all the initialsation steps to be executed
* again.
*/
- module_unload(begin);
+ module_unload(ldlinux);
goto again;
}
diff --git a/core/elflink/setadv.c b/core/elflink/setadv.c
deleted file mode 100644
index 40f00a4..0000000
--- a/core/elflink/setadv.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* ----------------------------------------------------------------------- *
- *
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
- * Copyright 2009 Intel Corporation; author: H. Peter Anvin
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall
- * be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * ----------------------------------------------------------------------- */
-
-/*
- * syslinux/setadv.c
- *
- * (Over)write a data item in the auxilliary data vector. To
- * delete an item, set its length to zero.
- *
- * Return 0 on success, -1 on error, and set errno.
- *
- * NOTE: Data is not written to disk unless
- * syslinux_adv_write() is called.
- */
-
-#include <syslinux/adv.h>
-#include <klibc/compiler.h>
-#include <inttypes.h>
-#include <string.h>
-#include <errno.h>
-#include <alloca.h>
-
-int syslinux_setadv(int tag, size_t size, const void *data)
-{
- uint8_t *p, *advtmp;
- size_t rleft, left;
-
- if ((unsigned)tag - 1 > 254) {
- errno = EINVAL;
- return -1; /* Impossible tag value */
- }
-
- if (size > 255) {
- errno = ENOSPC; /* Max 255 bytes for a data item */
- return -1;
- }
-
- rleft = left = syslinux_adv_size();
- p = advtmp = alloca(left);
- memcpy(p, syslinux_adv_ptr(), left); /* Make working copy */
-
- while (rleft >= 2) {
- uint8_t ptag = p[0];
- size_t plen = p[1] + 2;
-
- if (ptag == ADV_END)
- break;
-
- if (ptag == tag) {
- /* Found our tag. Delete it. */
-
- if (plen >= rleft) {
- /* Entire remainder is our tag */
- break;
- }
- memmove(p, p + plen, rleft - plen);
- rleft -= plen; /* Fewer bytes to read, but not to write */
- } else {
- /* Not our tag */
- if (plen > rleft)
- break; /* Corrupt tag (overrun) - overwrite it */
-
- left -= plen;
- rleft -= plen;
- p += plen;
- }
- }
-
- /* Now (p, left) reflects the position to write in and how much space
- we have for our data. */
-
- if (size) {
- if (left < size + 2) {
- errno = ENOSPC; /* Not enough space for data */
- return -1;
- }
-
- *p++ = tag;
- *p++ = size;
- memcpy(p, data, size);
- p += size;
- left -= size + 2;
- }
-
- memset(p, 0, left);
-
- /* If we got here, everything went OK, commit the write to low memory */
- memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size());
-
- return 0;
-}
diff --git a/core/font.c b/core/font.c
index 31fb29e..9e7aa8f 100644
--- a/core/font.c
+++ b/core/font.c
@@ -26,9 +26,7 @@
#include "graphics.h"
#include "core.h"
-static __lowmem char fontbuf[8192];
-
-extern uint8_t UserFont;
+__lowmem char fontbuf[8192];
uint16_t GXPixCols = 1; /* Graphics mode pixel columns */
uint16_t GXPixRows = 1; /* Graphics mode pixel rows */
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 8c95623..6f490ce 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -1187,9 +1187,6 @@ static void ip_init(void)
/*
* Print the IPAPPEND strings, in order
*/
-extern const uint16_t IPAppends[];
-extern const char numIPAppends[];
-
static void print_ipappend(void)
{
size_t i;
@@ -1656,7 +1653,7 @@ int reset_pxe(void)
* This function unloads the PXE and UNDI stacks and
* unclaims the memory.
*/
-void unload_pxe(void)
+void unload_pxe(uint16_t flags)
{
/* PXE unload sequences */
static const uint8_t new_api_unload[] = {
@@ -1685,7 +1682,7 @@ void unload_pxe(void)
dprintf("FBM after reset_pxe = %d, err = %d\n", BIOS_fbm, err);
/* If we want to keep PXE around, we still need to reset it */
- if (KeepPXE || err)
+ if (flags || err)
return;
dprintf("APIVer = %04x\n", APIVer);
diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
index 47ed8f0..c754106 100644
--- a/core/fs/pxe/pxe.h
+++ b/core/fs/pxe/pxe.h
@@ -232,14 +232,12 @@ static inline uint32_t gateway(uint32_t ip)
/* pxe.c */
bool ip_ok(uint32_t);
-int pxe_call(int, void *);
/* dhcp_options.c */
void parse_dhcp(const void *, size_t);
/* dnsresolv.c */
int dns_mangle(char **, const char *);
-uint32_t dns_resolv(const char *);
/* idle.c */
void pxe_idle_init(void);
diff --git a/core/hello.c b/core/hello.c
index 5b22478..d30fc3b 100644
--- a/core/hello.c
+++ b/core/hello.c
@@ -9,14 +9,10 @@
void myputchar(int c)
{
- static com32sys_t ireg;
-
if (c == '\n')
myputchar('\r');
- ireg.eax.b[1] = 0x02;
- ireg.edx.b[0] = c;
- __intcall(0x21, &ireg, NULL);
+ writechr(c);
}
void myputs(const char *str)
diff --git a/core/include/bios.h b/core/include/bios.h
index 4bf6bc4..42a9768 100644
--- a/core/include/bios.h
+++ b/core/include/bios.h
@@ -74,7 +74,6 @@ extern union screen _screensize;
#define VidRows _screensize.b.row
/* font.c */
-extern uint16_t VGAFontSize;
extern void use_font(void);
extern void bios_adjust_screen(void);
diff --git a/core/include/core.h b/core/include/core.h
index e19f2f1..da94dbf 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -25,9 +25,19 @@ extern char ConfigFile[];
extern char syslinux_banner[];
extern char copyright_str[];
extern char StackBuf[];
+extern unsigned int __bcopyxx_len;
extern uint8_t KbdMap[256];
+extern const uint16_t IPAppends[];
+extern const char numIPAppends[];
+
+extern uint16_t SerialPort;
+extern uint16_t BaudDivisor;
+extern uint8_t FlowOutput;
+extern uint8_t FlowInput;
+extern uint8_t FlowIgnore;
+
/* diskstart.inc isolinux.asm*/
extern void getlinsec(void);
@@ -101,14 +111,20 @@ static inline void set_flags(com32sys_t *regs, uint32_t
flags)
}
extern int start_ldlinux(char **argv);
+extern int create_args_and_load(char *);
extern void write_serial(char data);
extern void writestr(char *str);
extern void writechr(char data);
extern void crlf(void);
+extern int pollchar(void);
+extern char getchar(char *hi);
extern void cleanup_hardware(void);
extern void sirq_cleanup(void);
extern void adjust_screen(void);
+extern void execute(const char *cmdline, uint32_t type);
+extern void load_kernel(const char *cmdline);
+
#endif /* CORE_H */
diff --git a/core/include/graphics.h b/core/include/graphics.h
index 897103e..814ffe7 100644
--- a/core/include/graphics.h
+++ b/core/include/graphics.h
@@ -44,6 +44,11 @@ extern uint16_t VGAPos;
extern uint16_t *VGAFilePtr;
extern char VGAFileBuf[VGA_FILE_BUF_SIZE];
extern char VGAFileMBuf[];
+extern uint16_t VGAFontSize;
+
+extern uint8_t UserFont;
+
+extern __lowmem char fontbuf[8192];
extern void syslinux_force_text_mode(void);
extern void vgadisplayfile(FILE *_fd);
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 4790887..5930a1e 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -1219,9 +1219,9 @@ PXERetry dw 0 ; Extra PXE retries
section .data16
global SerialNotice
SerialNotice db 1 ; Only print this once
+ global IPAppends, numIPAppends
%if IS_PXELINUX
extern IPOption
- global IPAppends, numIPAppends
alignz 2
IPAppends dw IPOption
numIPAppends equ ($-IPAppends)/2
diff --git a/mk/elf.mk b/mk/elf.mk
index bc2948a..4e76c71 100644
--- a/mk/elf.mk
+++ b/mk/elf.mk
@@ -82,4 +82,4 @@ C_LNXLIBS = $(com32)/libutil/libutil_lnx.a \
$(CC) $(LNXCFLAGS) -o $@ $^
%.c32: %.o $(LIBS)
- $(LD) $(LDFLAGS_$^) $(LDFLAGS) -o $@ $^
+ $(LD) $(LDFLAGS) -o $@ $^