aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--NEWS16
-rw-r--r--com32/chain/Makefile2
-rw-r--r--com32/cmenu/Makefile13
-rw-r--r--com32/cmenu/menugen.py56
-rw-r--r--com32/elflink/ldlinux/Makefile8
-rw-r--r--com32/elflink/ldlinux/cli.c38
-rw-r--r--com32/elflink/ldlinux/config.h2
-rw-r--r--com32/elflink/ldlinux/eprintf.c36
-rw-r--r--com32/elflink/ldlinux/execute.c8
-rw-r--r--com32/elflink/ldlinux/ldlinux.c3
-rw-r--r--com32/elflink/ldlinux/msg.c86
-rw-r--r--com32/elflink/ldlinux/readconfig.c45
-rw-r--r--com32/gfxboot/Makefile2
-rw-r--r--com32/gpllib/Makefile8
-rw-r--r--com32/hdt/Makefile2
-rw-r--r--com32/hdt/hdt.c2
-rw-r--r--com32/include/sys/exec.h21
-rw-r--r--com32/include/sys/module.h23
-rw-r--r--com32/include/syslinux/config.h2
-rw-r--r--com32/lib/Makefile6
-rw-r--r--com32/lib/sys/module/common.c5
-rw-r--r--com32/lib/sys/module/elf_module.c2
-rw-r--r--com32/lib/sys/module/exec.c49
-rw-r--r--com32/lib/sys/module/i386/elf_module.c8
-rw-r--r--com32/lib/sys/module/i386/shallow_module.c161
-rw-r--r--com32/lib/sys/module/shallow_module.c161
-rw-r--r--com32/lib/sys/module/x86_64/elf_module.c8
-rw-r--r--com32/lib/sys/module/x86_64/shallow_module.c161
-rw-r--r--com32/lib/syslinux/serial.c2
-rw-r--r--com32/libutil/Makefile6
-rw-r--r--com32/lua/src/Makefile7
-rw-r--r--com32/mboot/Makefile2
-rw-r--r--com32/menu/Makefile4
-rw-r--r--com32/modules/Makefile2
-rw-r--r--com32/rosh/Makefile2
-rw-r--r--com32/samples/Makefile2
-rw-r--r--com32/sysdump/Makefile2
-rw-r--r--core/bios.c1
-rw-r--r--core/conio.c31
-rw-r--r--core/elflink/load_env32.c33
-rw-r--r--core/fs/fs.c118
-rw-r--r--core/fs/pxe/dnsresolv.c2
-rw-r--r--core/fs/pxe/pxe.c4
-rw-r--r--core/fs/xfs/xfs.c56
-rw-r--r--core/fs/xfs/xfs.h15
-rw-r--r--core/fs/xfs/xfs_dinode.c4
-rw-r--r--core/fs/xfs/xfs_dir2.c212
-rw-r--r--core/fs/xfs/xfs_dir2.h21
-rw-r--r--core/fs/xfs/xfs_readdir.c112
-rw-r--r--core/include/bios.h2
-rw-r--r--core/include/fs.h3
-rw-r--r--core/init.inc6
-rw-r--r--core/isolinux.asm3
-rw-r--r--core/lzo/enter.ash3
-rw-r--r--core/lzo/leave.ash3
-rw-r--r--core/lzo/lzo1c_d.ash3
-rw-r--r--core/lzo/lzo1f_d.ash3
-rw-r--r--core/lzo/lzo1x_d.ash3
-rw-r--r--core/lzo/lzo1x_f2.S (renamed from core/lzo/lzo1x_f1.S)13
-rw-r--r--core/lzo/lzo_asm.h23
-rw-r--r--core/mem/malloc.c2
-rw-r--r--core/pxelinux.asm4
-rw-r--r--dos/argv.c62
-rw-r--r--dos/crt0.S47
-rw-r--r--dos/dosexe.ld23
-rw-r--r--dos/getsetsl.c26
-rw-r--r--dos/mystuff.h59
-rw-r--r--dos/syslinux.c16
-rw-r--r--extlinux/main.c40
-rw-r--r--libinstaller/syslxint.h17
-rw-r--r--mk/elf.mk10
-rw-r--r--mk/lib.mk5
-rw-r--r--txt/.gitignore7
-rw-r--r--txt/Makefile113
-rw-r--r--txt/com-bug.txt11
-rw-r--r--txt/com-name.txt12
-rw-r--r--txt/com-rpt.txt22
-rw-r--r--txt/hello.txt16
-rw-r--r--txt/syslinux-cli.txt65
-rw-r--r--txt/syslinux.cfg.txt572
-rw-r--r--txt/syslinux.txt217
82 files changed, 1806 insertions, 1183 deletions
diff --git a/Makefile b/Makefile
index 7add22e7..e7d89d90 100644
--- a/Makefile
+++ b/Makefile
@@ -162,15 +162,15 @@ BOBJECTS = $(BTARGET) \
ifdef EFI_BUILD
-BSUBDIRS = codepage com32 lzo core mbr sample efi
+BSUBDIRS = codepage com32 lzo core mbr sample efi txt
ISUBDIRS = efi utils
INSTALLSUBDIRS = efi
else
-BSUBDIRS = codepage com32 lzo core memdisk sample diag mbr memdump dos \
- gpxe libinstaller win32 win64 dosutil
+BSUBDIRS = codepage com32 lzo core memdisk mbr memdump gpxe sample \
+ diag libinstaller dos win32 win64 dosutil txt
ITARGET =
IOBJECTS = $(ITARGET) \
diff --git a/NEWS b/NEWS
index 37c0e545..11e692d7 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,22 @@ to all derivatives.
Changes in 6.00:
* Add support for booting from EFI.
+Changes in 5.01:
+ * txt/: A new AsciiDoc documentation set (work-in-progress)
+ (Gene Cumm).
+ * core: Fix a bug in the realloc() implementation that caused
+ machines to appear to run out of free memory.
+ * ldlinux: Fix multiple buffer overflows in cmdline parsing
+ code that resulted in files failing to run and cmdlines
+ being truncated.
+ * core: Fix debug build by tagging __bad_SEG() with __export.
+ * com32: Restrict library filenames to 8.3 format.
+ * EXTLINUX: Fix installation and subdirectory patching.
+ * ISOLINUX: Fix booting isohybrid images that are over 32K.
+ * com32: Strip modules to reduce their size.
+ * XFS: Implement directory block cache and fix
+ shortform-directory lookup (Paulo Alcantara).
+
Changes in 5.00:
* com32: Switched from the COM32 object format to ELF as it is
a much more powerful format that allows undefined symbols to
diff --git a/com32/chain/Makefile b/com32/chain/Makefile
index 32385509..1a7ac9e6 100644
--- a/com32/chain/Makefile
+++ b/com32/chain/Makefile
@@ -18,7 +18,7 @@ OBJS = chain.o partiter.o utility.o options.o mangle.o
all: chain.c32
-chain.c32: $(OBJS) $(C_LIBS)
+chain.elf: $(OBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
%.o: %.c
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index 7ff1ff6e..f4321366 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -18,7 +18,7 @@
NOGPL := 1
LIBS = libmenu/libmenu.c32 \
- $(objdir)/com32/libutil/libutil_com.c32 \
+ $(objdir)/com32/libutil/libutil.c32 \
$(objdir)/com32/lib/libcom32.c32
VPATH = $(SRC)
@@ -26,7 +26,7 @@ include $(MAKEDIR)/elf.mk
CFLAGS += -I$(SRC)/libmenu
-LIBMENU = $(objdir)/com32/libutil/libutil_com.c32 \
+LIBMENU = $(objdir)/com32/libutil/libutil.c32 \
$(objdir)/com32/lib/libcom32.c32 \
libmenu/syslnx.o libmenu/com32io.o libmenu/tui.o \
libmenu/menu.o libmenu/passwords.o libmenu/des.o libmenu/help.o
@@ -47,14 +47,15 @@ all: makeoutputdirs menus
makeoutputdirs:
@mkdir -p $(OBJ)/libmenu
-libmenu/libmenu.c32: $(LIBMENU)
- $(LD) -shared $(LDFLAGS) -o $@ $^
+libmenu/libmenu.elf: $(LIBMENU)
+ $(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) \
+ -o $@ $^
tidy dist:
- rm -f *.o *.lo *.c32 *.lst *.elf .*.d */.*.d
+ rm -f *.o *.lo *.lst *.elf */*.o */*.elf .*.d */.*.d
libclean:
- rm -f libmenu/*.o libmenu/*.c32
+ rm -f libmenu/*.c32
clean: tidy menuclean libclean
rm -f *.lss *.c32 *.com
diff --git a/com32/cmenu/menugen.py b/com32/cmenu/menugen.py
index 70ec1f87..da64d937 100644
--- a/com32/cmenu/menugen.py
+++ b/com32/cmenu/menugen.py
@@ -72,9 +72,9 @@ class Menusystem:
self.init_entry()
self.init_menu()
self.init_system()
- self.vtypes = " OR ".join(self.types.keys())
- self.vattrs = " OR ".join(filter(lambda x: x[0] != "_", self.entry.keys()))
- self.mattrs = " OR ".join(filter(lambda x: x[0] != "_", self.menu.keys()))
+ self.vtypes = " OR ".join(list(self.types.keys()))
+ self.vattrs = " OR ".join([x for x in list(self.entry.keys()) if x[0] != "_"])
+ self.mattrs = " OR ".join([x for x in list(self.menu.keys()) if x[0] != "_"])
def init_entry(self):
self.entry = self.entry_init.copy()
@@ -100,27 +100,27 @@ class Menusystem:
if not self.entry["info"]:
self.entry["info"] = self.entry["data"]
if not self.menus:
- print "Error before line %d" % self.lineno
- print "REASON: menu must be declared before a menu item is declared"
+ print("Error before line %d" % self.lineno)
+ print("REASON: menu must be declared before a menu item is declared")
sys.exit(1)
self.menus[-1][1].append(self.entry)
self.init_entry()
def set_item(self,name,value):
- if not self.entry.has_key(name):
+ if name not in self.entry:
msg = ["Unknown attribute %s in line %d" % (name,self.lineno)]
msg.append("REASON: Attribute must be one of %s" % self.vattrs)
return "\n".join(msg)
- if name=="type" and not self.types.has_key(value):
+ if name=="type" and value not in self.types:
msg = [ "Unrecognized type %s in line %d" % (value,self.lineno)]
msg.append("REASON: Valid types are %s" % self.vtypes)
return "\n".join(msg)
if name=="shortcut":
- if (value <> "-1") and not re.match("^[A-Za-z0-9]$",value):
+ if (value != "-1") and not re.match("^[A-Za-z0-9]$",value):
msg = [ "Invalid shortcut char '%s' in line %d" % (value,self.lineno) ]
msg.append("REASON: Valid values are [A-Za-z0-9]")
return "\n".join(msg)
- elif value <> "-1": value = "'%s'" % value
+ elif value != "-1": value = "'%s'" % value
elif name in ["state","helpid","ipappend"]:
try:
value = int(value)
@@ -131,14 +131,14 @@ class Menusystem:
return ""
def set_menu(self,name,value):
- if not self.menu.has_key(name):
+ if name not in self.menu:
return "Error: Unknown keyword %s" % name
self.menu[name] = value
self.menu["_updated"] = 1
return ""
def set_system(self,name,value):
- if not self.system.has_key(name):
+ if name not in self.system:
return "Error: Unknown keyword %s" % name
if name == "skipcondn":
try: # is skipcondn a number?
@@ -146,7 +146,7 @@ class Menusystem:
except: # it is a "-" delimited sequence
value = value.lower()
parts = [ self.shift_flags.get(x.strip(),None) for x in value.split("-") ]
- self.system["skipcondn"] = " | ".join(filter(None, parts))
+ self.system["skipcondn"] = " | ".join([_f for _f in parts if _f])
else:
self.system[name] = value
@@ -169,7 +169,7 @@ class Menusystem:
if not err: return
# all errors so return item's error message
- print err
+ print(err)
sys.exit(1)
def print_entry(self,entry,fd):
@@ -211,9 +211,9 @@ class Menusystem:
missing = None
for x in self.reqd_templates:
- if not self.templates.has_key(x): missing = x
+ if x not in self.templates: missing = x
if missing:
- print "Template %s required but not defined in %s" % (missing,self.code_template_filename)
+ print("Template %s required but not defined in %s" % (missing,self.code_template_filename))
if filename == "-":
fd = sys.stdout
@@ -227,8 +227,8 @@ class Menusystem:
fd.write(self.templates["footer"])
fd.close()
if not self.foundmain:
- print "main menu not found"
- print self.menus
+ print("main menu not found")
+ print(self.menus)
sys.exit(1)
def input(self,filename):
@@ -259,26 +259,26 @@ class Menusystem:
# add property of current entry
pos = line.find("=") # find the first = in string
if pos < 0:
- print "Syntax error in line %d" % self.lineno
- print "REASON: non-section lines must be of the form ATTRIBUTE=VALUE"
+ print("Syntax error in line %d" % self.lineno)
+ print("REASON: non-section lines must be of the form ATTRIBUTE=VALUE")
sys.exit(1)
attr = line[:pos].strip().lower()
value = line[pos+1:].strip()
self.set(attr,value)
except:
- print "Error while parsing line %d: %s" % (self.lineno,line)
+ print("Error while parsing line %d: %s" % (self.lineno,line))
raise
fd.close()
self.add_item()
def usage():
- print sys.argv[0]," [options]"
- print "--input=<file> is the name of the .menu file declaring the menu structure"
- print "--output=<file> is the name of generated C source"
- print "--template=<file> is the name of template to be used"
- print
- print "input and output default to - (stdin and stdout respectively)"
- print "template defaults to adv_menu.tpl"
+ print(sys.argv[0]," [options]")
+ print("--input=<file> is the name of the .menu file declaring the menu structure")
+ print("--output=<file> is the name of generated C source")
+ print("--template=<file> is the name of template to be used")
+ print()
+ print("input and output default to - (stdin and stdout respectively)")
+ print("template defaults to adv_menu.tpl")
sys.exit(1)
def main():
@@ -287,7 +287,7 @@ def main():
ofile = "-"
opts,args = getopt.getopt(sys.argv[1:], "hi:o:t:",["input=","output=","template=","help"])
if args:
- print "Unknown options %s" % args
+ print("Unknown options %s" % args)
usage()
for o,a in opts:
if o in ["-i","--input"]:
diff --git a/com32/elflink/ldlinux/Makefile b/com32/elflink/ldlinux/Makefile
index 659aa405..bfec4503 100644
--- a/com32/elflink/ldlinux/Makefile
+++ b/com32/elflink/ldlinux/Makefile
@@ -1,6 +1,6 @@
## -----------------------------------------------------------------------
##
-## Copyright 2011 Intel Corporation - All Rights Reserved
+## Copyright 2011-2013 Intel Corporation - All Rights Reserved
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -18,14 +18,14 @@ LIBS = --whole-archive $(objdir)/com32/lib/libcom32min.a
OBJS = ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o adv.o \
execute.o chainboot.o kernel.o get_key.o advwrite.o setadv.o \
- eprintf.o loadhigh.o msg.o
+ loadhigh.o msg.o
BTARGET = ldlinux.c32
all: $(BTARGET) ldlinux_lnx.a
-ldlinux.c32 : $(OBJS)
- $(LD) $(LDFLAGS) -soname $(@F) -o $@ $^ $(LIBS)
+ldlinux.elf : $(OBJS)
+ $(LD) $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^ $(LIBS)
LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
LNXLIBOBJS = get_key.lo
diff --git a/com32/elflink/ldlinux/cli.c b/com32/elflink/ldlinux/cli.c
index b94c6835..b85357b2 100644
--- a/com32/elflink/ldlinux/cli.c
+++ b/com32/elflink/ldlinux/cli.c
@@ -71,7 +71,7 @@ static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
memset(buf, 0, MAX_CMDLINE_LEN);
- eprintf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+ printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
while (1) {
key = mygetkey_timeout(kbd_to, tto);
@@ -105,11 +105,11 @@ static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
*cursor = p - last_good->command;
}
- eprintf("\033[?7l\033[?25l");
+ printf("\033[?7l\033[?25l");
/* Didn't handle the line wrap case here */
- eprintf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
+ printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
buf, last_good->command ? : "");
- eprintf("\033[K\r");
+ printf("\033[K\r");
}
return last_good ? last_good->command : NULL;
@@ -147,7 +147,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
* so that it follows whatever text has been written to the screen
* previously.
*/
- eprintf("%s ", input);
+ printf("%s ", input);
while (!done) {
if (redraw > 1) {
@@ -158,7 +158,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
if (pDraw_Menu)
(*pDraw_Menu) (-1, top, 1);
prev_len = 0;
- eprintf("\033[2J\033[H");
+ printf("\033[2J\033[H");
// printf("\033[0m\033[2J\033[H");
}
@@ -168,8 +168,8 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
prev_len = max(len, prev_len);
/* Redraw the command line */
- eprintf("\033[?7l\033[?25l");
- eprintf("\033[1G%s ", input);
+ printf("\033[?7l\033[?25l");
+ printf("\033[1G%s ", input);
x = strlen(input);
y = 0;
@@ -179,23 +179,23 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
at++;
x++;
if (x >= width) {
- eprintf("\r\n");
+ printf("\r\n");
x = 0;
y++;
}
}
- eprintf("\033[K\r");
+ printf("\033[K\r");
dy = y - (cursor + strlen(input) + 1) / width;
x = (cursor + strlen(input) + 1) % width;
if (dy) {
- eprintf("\033[%dA", dy);
+ printf("\033[%dA", dy);
y -= dy;
}
if (x)
- eprintf("\033[%dC", x);
- eprintf("\033[?25h");
+ printf("\033[%dC", x);
+ printf("\033[?25h");
prev_len = len;
redraw = 0;
}
@@ -288,7 +288,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
cursor++;
x++;
if (x >= width) {
- eprintf("\r\n");
+ printf("\r\n");
y++;
x = 0;
}
@@ -418,10 +418,10 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
}
case KEY_CTRL('V'):
if (BIOSName)
- eprintf("%s%s%s", syslinux_banner,
- MK_PTR(0, BIOSName), copyright_str);
+ printf("%s%s%s", syslinux_banner,
+ (char *)MK_PTR(0, BIOSName), copyright_str);
else
- eprintf("%s%s", syslinux_banner, copyright_str);
+ printf("%s%s", syslinux_banner, copyright_str);
redraw = 1;
break;
@@ -435,7 +435,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
cursor++;
x++;
if (x >= width) {
- eprintf("\r\n\033[K");
+ printf("\r\n\033[K");
y++;
x = 0;
}
@@ -452,7 +452,7 @@ const char *edit_cmdline(const char *input, int top /*, int width */ ,
}
}
- eprintf("\033[?7h");
+ printf("\033[?7h");
/* Add the command to the history */
comm_counter = malloc(sizeof(struct cli_command));
diff --git a/com32/elflink/ldlinux/config.h b/com32/elflink/ldlinux/config.h
index c551fb19..242b7dc5 100644
--- a/com32/elflink/ldlinux/config.h
+++ b/com32/elflink/ldlinux/config.h
@@ -41,8 +41,6 @@ extern void cat_help_file(int key);
extern struct menu_entry *find_label(const char *str);
extern void print_labels(const char *prefix, size_t len);
-extern void eprintf(const char *filename, ...);
-
extern int new_linux_kernel(char *okernel, char *ocmdline);
extern void pm_load_high(com32sys_t *regs);
diff --git a/com32/elflink/ldlinux/eprintf.c b/com32/elflink/ldlinux/eprintf.c
deleted file mode 100644
index f15edc6e..00000000
--- a/com32/elflink/ldlinux/eprintf.c
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <core.h>
-
-#define BUFFER_SIZE 4096
-
-static void veprintf(const char *format, va_list ap)
-{
- int rv, _rv;
- char buffer[BUFFER_SIZE];
- char *p;
-
- _rv = rv = vsnprintf(buffer, BUFFER_SIZE, format, ap);
-
- if (rv < 0)
- return;
-
- if (rv > BUFFER_SIZE - 1)
- rv = BUFFER_SIZE - 1;
-
- p = buffer;
- while (rv--)
- write_serial(*p++);
-
- _fwrite(buffer, _rv, stdout);
-}
-
-void eprintf(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- veprintf(format, ap);
- va_end(ap);
-}
diff --git a/com32/elflink/ldlinux/execute.c b/com32/elflink/ldlinux/execute.c
index 727df50a..5c53b995 100644
--- a/com32/elflink/ldlinux/execute.c
+++ b/com32/elflink/ldlinux/execute.c
@@ -55,11 +55,9 @@ __export void execute(const char *cmdline, uint32_t type)
memset(&ireg, 0, sizeof ireg);
- /* for parameter will be passed to __intcall, we need use
- * lmalloc a block of low memory */
- q = lmalloc(128);
+ q = malloc(strlen(cmdline) + 2);
if (!q) {
- printf("%s(): Fail to lmalloc a buffer to exec %s\n",
+ printf("%s(): Fail to malloc a buffer to exec %s\n",
__func__, cmdline);
return;
}
@@ -147,7 +145,7 @@ __export void execute(const char *cmdline, uint32_t type)
new_linux_kernel((char *)kernel, (char *)cmdline);
}
- lfree((void *)kernel);
+ free((void *)kernel);
/* If this returns, something went bad; return to menu */
}
diff --git a/com32/elflink/ldlinux/ldlinux.c b/com32/elflink/ldlinux/ldlinux.c
index 6f9f20fa..a8b1b386 100644
--- a/com32/elflink/ldlinux/ldlinux.c
+++ b/com32/elflink/ldlinux/ldlinux.c
@@ -12,6 +12,7 @@
#include "config.h"
#include "syslinux/adv.h"
#include "syslinux/boot.h"
+#include "syslinux/config.h"
#include <sys/module.h>
@@ -290,6 +291,8 @@ __export int main(int argc __unused, char **argv __unused)
parse_configs(config_argv);
+ __syslinux_set_serial_console_info();
+
adv = syslinux_getadv(ADV_BOOTONCE, &count);
if (adv && count) {
/*
diff --git a/com32/elflink/ldlinux/msg.c b/com32/elflink/ldlinux/msg.c
index 2efcc792..9ded33ef 100644
--- a/com32/elflink/ldlinux/msg.c
+++ b/com32/elflink/ldlinux/msg.c
@@ -4,7 +4,7 @@
#include <graphics.h>
static uint8_t TextAttribute; /* Text attribute for message file */
-static uint8_t DisplayMask; /* Display modes mask */
+extern uint8_t DisplayMask; /* Display modes mask */
/* Routine to interpret next print char */
static void (*NextCharJump)(uint8_t);
@@ -42,27 +42,27 @@ int get_msg_file(char *filename)
if (ch == 0x1A)
break;
- /*
- * 01h = text mode
- * 02h = graphics mode
- */
- UsingVGA &= 0x1;
- UsingVGA += 1;
-
NextCharJump(ch); /* Do what shall be done */
}
+ DisplayMask = 0x07;
+
fclose(f);
return 0;
}
+static inline int display_mask_vga(void)
+{
+ uint8_t mask = UsingVGA & 0x1;
+ return (DisplayMask & ++mask);
+}
+
static void msg_setbg(uint8_t data)
{
if (unhexchar(&data) == 0) {
data <<= 4;
- if (DisplayMask & UsingVGA) {
+ if (display_mask_vga())
TextAttribute = data;
- }
NextCharJump = msg_setfg;
} else {
@@ -74,7 +74,7 @@ static void msg_setbg(uint8_t data)
static void msg_setfg(uint8_t data)
{
if (unhexchar(&data) == 0) {
- if (DisplayMask & UsingVGA) {
+ if (display_mask_vga()) {
/* setbg set foreground to 0 */
TextAttribute |= data;
}
@@ -89,6 +89,34 @@ static inline void msg_ctrl_o(void)
NextCharJump = msg_setbg;
}
+/* Convert ANSI colors to PC display attributes */
+static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+static void set_fgbg(void)
+{
+ uint8_t bg, fg;
+
+ fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
+ bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
+
+ printf("\033[");
+ if (TextAttribute & 0x8)
+ printf("1;"); /* Foreground bright */
+
+ printf("3%dm\033[", fg);
+
+ if (TextAttribute & 0x80)
+ printf("5;"); /* Foreground blink */
+
+ printf("4%dm", bg);
+}
+
+static void msg_formfeed(void)
+{
+ set_fgbg();
+ printf("\033[2J\033[H\033[0m");
+}
+
static void msg_novga(void)
{
syslinux_force_text_mode();
@@ -138,36 +166,19 @@ static void msg_vga(void)
VGAFilePtr = (uint16_t *)VGAFileBuf;
}
-/* Convert ANSI colors to PC display attributes */
-static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-
static void msg_normal(uint8_t data)
{
- uint8_t bg, fg;
-
- /* Write to serial port */
- if (DisplayMask & 0x4)
- write_serial(data);
+ /* 0x1 = text mode, 0x2 = graphics mode */
+ if (!display_mask_vga() || !(DisplayCon & 0x01)) {
+ /* Write to serial port */
+ if (DisplayMask & 0x4)
+ write_serial(data);
- if (!(DisplayMask & UsingVGA))
return; /* Not screen */
+ }
- if (!(DisplayCon & 0x01))
- return;
-
- fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
- bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
-
- printf("\033[");
- if (TextAttribute & 0x40)
- printf("1;"); /* Foreground bright */
-
- printf("3%dm\033[", fg);
-
- if (TextAttribute & 0x80)
- printf("5;"); /* Foreground blink */
-
- printf("4%dm%c\033[0m", bg, data);
+ set_fgbg();
+ printf("%c\033[0m", data);
}
static void msg_modectl(uint8_t data)
@@ -191,6 +202,9 @@ static void msg_putchar(uint8_t ch)
break;
case 0x0D: /* Ignore <CR> */
break;
+ case 0x0C: /* <FF> = clear screen */
+ msg_formfeed();
+ break;
case 0x19: /* <EM> = return to text mode */
msg_novga();
break;
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index 6a419c6d..a2421e95 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -26,6 +26,7 @@
#include <syslinux/config.h>
#include <dprintf.h>
#include <ctype.h>
+#include <bios.h>
#include <core.h>
#include <fs.h>
@@ -79,7 +80,6 @@ short allowoptions = 1; //user-specified options allowed
short includelevel = 1; //nesting level
short defaultlevel = 0; //the current level of default
short vkernel = 0; //have we seen any "label" statements?
-short displaycon = 1; //conio.inc
extern short NoHalt; //idle.c
const char *onerror = NULL; //"onerror" command line
@@ -442,12 +442,12 @@ void print_labels(const char *prefix, size_t len)
{
struct menu_entry *me;
- eprintf("\n");
+ printf("\n");
for (me = all_entries; me; me = me->next ) {
if (!strncmp(prefix, me->label, len))
- eprintf(" %s", me->label);
+ printf(" %s", me->label);
}
- eprintf("\n");
+ printf("\n");
}
struct menu_entry *find_label(const char *str)
@@ -498,18 +498,24 @@ static const char *unlabel(const char *str)
return str;
}
-static const char *refdup_word(char **p)
+static const char *__refdup_word(char *p, char **ref)
{
- char *sp = *p;
+ char *sp = p;
char *ep = sp;
while (*ep && !my_isspace(*ep))
ep++;
- *p = ep;
+ if (ref)
+ *ref = ep;
return refstrndup(sp, ep - sp);
}
+static const char *refdup_word(char **p)
+{
+ return __refdup_word(*p, p);
+}
+
int my_isxdigit(char c)
{
unsigned int uc = c;
@@ -690,7 +696,7 @@ void cat_help_file(int key)
return;
if (cm->fkeyhelp[fkey].textname) {
- eprintf("\n");
+ printf("\n");
get_msg_file((char *)cm->fkeyhelp[fkey].textname);
}
}
@@ -729,12 +735,6 @@ extern void sirq_cleanup_nowipe(void);
extern void sirq_install(void);
extern void write_serial_str(char *);
-static inline void io_delay(void)
-{
- outb(0, 0x80);
- outb(0, 0x80);
-}
-
extern void loadfont(char *);
extern void loadkeys(char *);
@@ -1065,8 +1065,8 @@ do_include:
p = skipspace(p + 5);
/* when first time see "label", it will not really record anything */
record(m, &ld, append);
- ld.label = refstrdup(p);
- ld.kernel = refstrdup(p);
+ ld.label = __refdup_word(p, NULL);
+ ld.kernel = __refdup_word(p, NULL);
/* feng: this is the default type for all */
ld.type = KT_KERNEL;
ld.passwd = NULL;
@@ -1174,7 +1174,7 @@ do_include:
} else if (looking_at(p, "prompt")) {
forceprompt = atoi(skipspace(p + 6));
} else if (looking_at(p, "console")) {
- displaycon = atoi(skipspace(p + 7));
+ DisplayCon = atoi(skipspace(p + 7));
} else if (looking_at(p, "allowoptions")) {
allowoptions = atoi(skipspace(p + 12));
} else if (looking_at(p, "noescape")) {
@@ -1311,8 +1311,9 @@ do_include:
write_serial_str(syslinux_banner);
write_serial_str(copyright_str);
}
+
} else if (looking_at(p, "say")) {
- eprintf("%s\n", p+4);
+ printf("%s\n", p+4);
} else if (looking_at(p, "path")) {
/* PATH-based lookup */
const char *new_path;
@@ -1331,7 +1332,7 @@ do_include:
free(PATH);
PATH = _p;
} else
- eprintf("Failed to realloc PATH\n");
+ printf("Failed to realloc PATH\n");
}
}
}
@@ -1350,15 +1351,15 @@ static int parse_one_config(const char *filename)
if (fd < 0)
return fd;
- f = fdopen(fd, mode);
- parse_config_file(f);
-
if (config_cwd[0]) {
if (chdir(config_cwd) < 0)
printf("Failed to chdir to %s\n", config_cwd);
config_cwd[0] = '\0';
}
+ f = fdopen(fd, mode);
+ parse_config_file(f);
+
return 0;
}
diff --git a/com32/gfxboot/Makefile b/com32/gfxboot/Makefile
index 98d6a032..824d7d0d 100644
--- a/com32/gfxboot/Makefile
+++ b/com32/gfxboot/Makefile
@@ -20,7 +20,7 @@ all: $(MODULES)
OBJS = gfxboot.o realmode_callback.o
-gfxboot.c32 : $(OBJS) $(LIBS) $(C_LIBS)
+gfxboot.elf : $(OBJS) $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
realmode_callback.o: realmode_callback.asm
diff --git a/com32/gpllib/Makefile b/com32/gpllib/Makefile
index 4d0bb82f..e3e30d76 100644
--- a/com32/gpllib/Makefile
+++ b/com32/gpllib/Makefile
@@ -17,14 +17,14 @@ AUXDIR = $(DATADIR)/syslinux
INCDIR = /usr/include
COM32DIR = $(AUXDIR)/com32
-all: makeoutputdirs libcom32gpl.c32
+all: makeoutputdirs libgpl.c32
makeoutputdirs:
@mkdir -p $(foreach b, \
$(addprefix $(OBJ),$(sort $(dir $(LIBOBJS)))),$(b))
-libcom32gpl.c32 : $(LIBOBJS)
- $(LD) -shared $(LDFLAGS) -soname $(@F) -o $@ $^
+libgpl.elf : $(LIBOBJS)
+ $(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
tidy dist clean:
find . \( -name \*.o -o -name .\*.d -o -name \*.tmp \) -print0 | \
@@ -38,7 +38,7 @@ spotless: clean
# there is a better way to do it.
install: all
mkdir -m 755 -p $(INSTALLROOT)$(COM32DIR)
- install -m 644 libcom32gpl.c32 $(INSTALLROOT)$(COM32DIR)
+ install -m 644 libgpl.c32 $(INSTALLROOT)$(COM32DIR)
mkdir -p $(INSTALLROOT)$(COM32DIR)/include/
cp -r $(SRC)/../gplinclude $(INSTALLROOT)$(COM32DIR)/include/
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 362b4874..80f2d0a0 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -51,7 +51,7 @@ QEMU ?= qemu-kvm
all: $(MODULES) $(TESTFILES)
-hdt.c32 : $(OBJS) $(LIBS) $(C_LIBS)
+hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
memtest:
diff --git a/com32/hdt/hdt.c b/com32/hdt/hdt.c
index 653995d0..67b3ab0c 100644
--- a/com32/hdt/hdt.c
+++ b/com32/hdt/hdt.c
@@ -48,7 +48,7 @@ int max_console_lines = MAX_CLI_LINES;
int main(const int argc, const char *argv[])
{
char version_string[256];
- struct s_hardware hardware;
+ static struct s_hardware hardware;
snprintf(version_string, sizeof version_string, "%s %s (%s)",
PRODUCT_NAME, VERSION, CODENAME);
diff --git a/com32/include/sys/exec.h b/com32/include/sys/exec.h
index ac05c276..f4559d15 100644
--- a/com32/include/sys/exec.h
+++ b/com32/include/sys/exec.h
@@ -34,27 +34,6 @@
extern int spawn_load(const char *name, int argc, char **argv);
/**
- * exec_init - Initialize the dynamic execution environment.
- *
- * Among others, it initializes the module subsystem and loads the root
- * module into memory. You should note the difference between the module
- * management API, and the execution API:
- * - the module system is a static one - it only manages the data structures
- * and their relationship. It does not describe the way modules are executed,
- * when and how they are loaded/unloaded, etc. It acts as a service layer for
- * the execution API.
- * - the execution environment is the dynamic part of the SYSLINUX dynamic
- * module API - it implements the behavior of the modules: it
- * triggers the execution of initialization and termination functions for
- * libraries, executes the modules marked as executable, handles dynamic
- * memory cleanup, etc. In other words, at this layer the code and data
- * loaded by the lower module layer gets to be executed by the CPU,
- * thus becoming part of the SYSLINUX environment.
- */
-extern int exec_init(void);
-
-
-/**
* spawnv - Executes a program in the current environment.
* @name: the name of the program to spawn, including the extension
* (e.g. 'hello.c32')
diff --git a/com32/include/sys/module.h b/com32/include/sys/module.h
index 02778fbf..c1d42531 100644
--- a/com32/include/sys/module.h
+++ b/com32/include/sys/module.h
@@ -199,6 +199,17 @@ extern struct list_head modules_head;
list_for_each_entry_safe(m, n, &modules_head, list)
/**
+ * module_current - return the module at the head of the module list.
+ */
+static inline struct elf_module *module_current(void)
+{
+ struct elf_module *head;
+
+ head = list_entry((&modules_head)->next, typeof(*head), list);
+ return head;
+}
+
+/**
* modules_init - initialize the module subsystem.
*
* This function must be called before any module operation is to be performed.
@@ -242,18 +253,6 @@ extern int module_load(struct elf_module *module);
/**
- * module_load_shallow - loads a shallow ELF module into memory.
- * @module: the module descriptor returned by module_alloc.
- *
- * The function reads the module file, checks whether the file has a valid
- * structure, then loads into memory the module metadata. The metadata currently
- * contains a symbol table that describes code & data allocated by other means.
- * Its current use is to describe the root COM32 module to the rest of the
- * module subsystem.
- */
-extern int module_load_shallow(struct elf_module *module, Elf_Addr base_addr);
-
-/**
* module_unload - unloads the module from the system.
* @module: the module descriptor structure.
*
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index 7bdcdd6b..8f4124ce 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -156,6 +156,8 @@ struct syslinux_serial_console_info {
uint16_t flowctl;
};
+extern void __syslinux_set_serial_console_info(void);
+
extern __nocommon struct syslinux_serial_console_info
__syslinux_serial_console_info;
static inline const struct syslinux_serial_console_info
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 2a47fc6f..1624ae78 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -89,9 +89,9 @@ makeoutputdirs:
@mkdir -p $(foreach b, \
$(addprefix $(OBJ)/,$(sort $(dir $(LIBOBJS) $(MINLIBOBJS) $(CORELIBOBJS)))),$(b))
-libcom32.c32 : $(LIBOBJS)
+libcom32.elf : $(LIBOBJS)
rm -f $@
- $(LD) -shared $(LDFLAGS) -soname $(@F) -o $@ $^
+ $(LD) -shared $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
libcom32min.a : $(MINLIBOBJS)
rm -f $@
@@ -109,7 +109,7 @@ tidy dist clean:
xargs -0r rm -f
spotless: clean
- rm -f *.a
+ rm -f *.a *.c32
rm -f *~ \#* */*~ */\#*
install: all
diff --git a/com32/lib/sys/module/common.c b/com32/lib/sys/module/common.c
index 2ecc9e59..4c83789e 100644
--- a/com32/lib/sys/module/common.c
+++ b/com32/lib/sys/module/common.c
@@ -185,6 +185,11 @@ void modules_term(void) {
struct elf_module *module_alloc(const char *name) {
struct elf_module *result = malloc(sizeof(struct elf_module));
+ if (!result) {
+ dprintf("module: Failed to alloc elf_module\n");
+ return NULL;
+ }
+
memset(result, 0, sizeof(struct elf_module));
INIT_LIST_HEAD(&result->list);
diff --git a/com32/lib/sys/module/elf_module.c b/com32/lib/sys/module/elf_module.c
index 0d27c92b..e3d9928a 100644
--- a/com32/lib/sys/module/elf_module.c
+++ b/com32/lib/sys/module/elf_module.c
@@ -218,7 +218,7 @@ int module_load(struct elf_module *module) {
CHECKED(res, prepare_dynlinking(module), error);
//printf("check... 4\n");
- head = list_entry((&modules_head)->next, typeof(*head), list);
+ head = module_current();
/* Find modules we need to load as dependencies */
if (module->str_table) {
diff --git a/com32/lib/sys/module/exec.c b/com32/lib/sys/module/exec.c
index 559bafc7..18c8306d 100644
--- a/com32/lib/sys/module/exec.c
+++ b/com32/lib/sys/module/exec.c
@@ -18,32 +18,8 @@
#define DBG_PRINT(fmt, args...) dprintf("[EXEC] " fmt, ##args)
-static struct elf_module *mod_root = NULL;
struct elf_module *__syslinux_current = NULL;
-int exec_init(void)
-{
- int res;
-
- res = modules_init();
- if (res != 0)
- return res;
-
- // Load the root module
- mod_root = module_alloc(EXEC_ROOT_NAME);
-
- if (mod_root == NULL)
- return -1;
-
- res = module_load_shallow(mod_root, 0);
- if (res != 0) {
- mod_root = NULL;
- return res;
- }
-
- return 0;
-}
-
int get_module_type(struct elf_module *module)
{
if(module->main_func) return EXEC_MODULE;
@@ -161,8 +137,6 @@ int spawnl(const char *name, const char *arg, ...)
}
#endif
-struct elf_module *cur_module;
-
/*
* Load a module and runs its start function.
*
@@ -185,7 +159,7 @@ int spawn_load(const char *name, int argc, char **argv)
struct elf_module *previous;
//malloc_tag_t prev_mem_tag;
struct elf_module *module = module_alloc(name);
- struct elf_module *prev_module;
+ struct elf_module *cur_module;
int type;
dprintf("enter: name = %s", name);
@@ -200,23 +174,11 @@ int spawn_load(const char *name, int argc, char **argv)
}
}
+ cur_module = module_current();
if (!strcmp(cur_module->name, module->name)) {
dprintf("We is running this module %s already!", module->name);
- /*
- * If we're already running the module and it's of
- * type EXEC_MODULE, then just return. We don't reload
- * the module because that might cause us to re-run
- * the init functions, which will cause us to run the
- * main function, which will take control of this
- * process.
- *
- * This can happen if some other EXEC_MODULE is
- * resolving a symbol that is exported by the current
- * EXEC_MODULE.
- */
- if (get_module_type(module) == EXEC_MODULE)
- return 0;
+ module_unload(cur_module);
}
res = module_load(module);
@@ -224,11 +186,9 @@ int spawn_load(const char *name, int argc, char **argv)
goto out;
type = get_module_type(module);
- prev_module = cur_module;
- cur_module = module;
dprintf("type = %d, prev = %s, cur = %s",
- type, prev_module->name, cur_module->name);
+ type, cur_module->name, module->name);
if(type==EXEC_MODULE)
{
@@ -256,7 +216,6 @@ int spawn_load(const char *name, int argc, char **argv)
// Restore the process context
__syslinux_current = previous;
- cur_module = prev_module;
res = module_unload(module);
if (res != 0)
diff --git a/com32/lib/sys/module/i386/elf_module.c b/com32/lib/sys/module/i386/elf_module.c
index a3792554..d30f4ce2 100644
--- a/com32/lib/sys/module/i386/elf_module.c
+++ b/com32/lib/sys/module/i386/elf_module.c
@@ -46,6 +46,9 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
// Load the PHT
pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+ if (!pht)
+ return -1;
+
image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
// Compute the memory needings of the module
@@ -149,6 +152,11 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
// Load the SHT
sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ if (!sht) {
+ res = -1;
+ goto out;
+ }
+
image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
// Setup the symtable size
diff --git a/com32/lib/sys/module/i386/shallow_module.c b/com32/lib/sys/module/i386/shallow_module.c
deleted file mode 100644
index fbcf781b..00000000
--- a/com32/lib/sys/module/i386/shallow_module.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * shallow_module.c
- *
- * Created on: Aug 11, 2008
- * Author: Stefan Bucur <stefanb@zytor.com>
- */
-
-
-#include <string.h>
-#include <sys/module.h>
-
-#include "common.h"
-#include "elfutils.h"
-
-
-static int check_header_shallow(Elf32_Ehdr *elf_hdr) {
- int res;
-
- res = check_header_common(elf_hdr);
-
- if (res != 0)
- return res;
-
- if (elf_hdr->e_shoff == 0x00000000) {
- DBG_PRINT("SHT missing\n");
- return -1;
- }
-
- return 0;
-}
-
-static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
- int i;
- int res = 0;
- void *sht = NULL;
- void *buffer = NULL;
- Elf32_Shdr *crt_sht;
- Elf32_Off buff_offset;
-
- Elf32_Off min_offset = 0xFFFFFFFF;
- Elf32_Off max_offset = 0x00000000;
- Elf32_Word max_align = 0x1;
-
- Elf32_Off sym_offset = 0xFFFFFFFF;
- Elf32_Off str_offset = 0xFFFFFFFF;
-
-
- char *sh_strtable;
-
- // We buffer the data up to the SHT
- buff_offset = module->u.l._cr_offset;
-
- buffer = malloc(elf_hdr->e_shoff - buff_offset);
- // Get to the SHT
- image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
-
- // Load the SHT
- sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
- image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
-
- // Get the string table of the section names
- crt_sht = (Elf32_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
- sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
-
- for (i = 0; i < elf_hdr->e_shnum; i++) {
- crt_sht = (Elf32_Shdr*)(sht + i*elf_hdr->e_shentsize);
-
- if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the symbol table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- sym_offset = crt_sht->sh_offset;
-
- module->syment_size = crt_sht->sh_entsize;
- module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
- }
- if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the string table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- str_offset = crt_sht->sh_offset;
-
- module->strtable_size = crt_sht->sh_size;
- }
- }
-
- if (elf_malloc(&module->module_addr, max_align,
- max_offset - min_offset) != 0) {
- DBG_PRINT("Could not allocate sections\n");
- goto out;
- }
-
- // Copy the data
- image_seek(min_offset, module);
- image_read(module->module_addr, max_offset - min_offset, module);
-
- // Setup module information
- module->module_size = max_offset - min_offset;
- module->str_table = (char*)(module->module_addr + (str_offset - min_offset));
- module->sym_table = module->module_addr + (sym_offset - min_offset);
-
-out:
- // Release the SHT
- if (sht != NULL)
- free(sht);
-
- // Release the buffer
- if (buffer != NULL)
- free(buffer);
-
- return res;
-}
-
-
-int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr) {
- int res;
- Elf32_Ehdr elf_hdr;
-
- // Do not allow duplicate modules
- if (module_find(module->name) != NULL) {
- DBG_PRINT("Module already loaded.\n");
- return -1;
- }
-
- res = image_load(module);
-
- if (res < 0)
- return res;
-
- module->shallow = 1;
-
- CHECKED(res, image_read(&elf_hdr, sizeof(Elf32_Ehdr), module), error);
-
- // Checking the header signature and members
- CHECKED(res, check_header_shallow(&elf_hdr), error);
-
- CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
- module->base_addr = base_addr;
-
- // Check the symbols for duplicates / missing definitions
- CHECKED(res, check_symbols(module), error);
-
- // Add the module at the beginning of the module list
- list_add(&module->list, &modules_head);
-
- // The file image is no longer needed
- image_unload(module);
-
- DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
-
- return 0;
-
-error:
- image_unload(module);
-
- return res;
-}
diff --git a/com32/lib/sys/module/shallow_module.c b/com32/lib/sys/module/shallow_module.c
deleted file mode 100644
index 8a88e403..00000000
--- a/com32/lib/sys/module/shallow_module.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * shallow_module.c
- *
- * Created on: Aug 11, 2008
- * Author: Stefan Bucur <stefanb@zytor.com>
- */
-
-
-#include <string.h>
-#include <sys/module.h>
-
-#include "common.h"
-#include "elfutils.h"
-
-
-static int check_header_shallow(Elf32_Ehdr *elf_hdr) {
- int res;
-
- res = check_header_common(elf_hdr);
-
- if (res != 0)
- return res;
-
- if (elf_hdr->e_shoff == 0x00000000) {
- DBG_PRINT("SHT missing\n");
- return -1;
- }
-
- return 0;
-}
-
-static int load_shallow_sections(struct elf_module *module, Elf32_Ehdr *elf_hdr) {
- int i;
- int res = 0;
- char *sht = NULL;
- char *buffer = NULL;
- Elf32_Shdr *crt_sht;
- Elf32_Off buff_offset;
-
- Elf32_Off min_offset = 0xFFFFFFFF;
- Elf32_Off max_offset = 0x00000000;
- Elf32_Word max_align = 0x1;
-
- Elf32_Off sym_offset = 0xFFFFFFFF;
- Elf32_Off str_offset = 0xFFFFFFFF;
-
-
- char *sh_strtable;
-
- // We buffer the data up to the SHT
- buff_offset = module->u.l._cr_offset;
-
- buffer = malloc(elf_hdr->e_shoff - buff_offset);
- // Get to the SHT
- image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
-
- // Load the SHT
- sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
- image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
-
- // Get the string table of the section names
- crt_sht = (Elf32_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
- sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
-
- for (i = 0; i < elf_hdr->e_shnum; i++) {
- crt_sht = (Elf32_Shdr*)(sht + i*elf_hdr->e_shentsize);
-
- if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the symbol table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- sym_offset = crt_sht->sh_offset;
-
- module->syment_size = crt_sht->sh_entsize;
- module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
- }
- if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the string table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- str_offset = crt_sht->sh_offset;
-
- module->strtable_size = crt_sht->sh_size;
- }
- }
-
- if (elf_malloc(&module->module_addr, max_align,
- max_offset - min_offset) != 0) {
- DBG_PRINT("Could not allocate sections\n");
- goto out;
- }
-
- // Copy the data
- image_seek(min_offset, module);
- image_read(module->module_addr, max_offset - min_offset, module);
-
- // Setup module information
- module->module_size = max_offset - min_offset;
- module->str_table = (char *)module->module_addr + (str_offset - min_offset);
- module->sym_table = (char *)module->module_addr + (sym_offset - min_offset);
-
-out:
- // Release the SHT
- if (sht != NULL)
- free(sht);
-
- // Release the buffer
- if (buffer != NULL)
- free(buffer);
-
- return res;
-}
-
-
-int module_load_shallow(struct elf_module *module, Elf32_Addr base_addr) {
- int res;
- Elf32_Ehdr elf_hdr;
-
- // Do not allow duplicate modules
- if (module_find(module->name) != NULL) {
- DBG_PRINT("Module already loaded.\n");
- return -1;
- }
-
- res = image_load(module);
-
- if (res < 0)
- return res;
-
- module->shallow = 1;
-
- CHECKED(res, image_read(&elf_hdr, sizeof(Elf32_Ehdr), module), error);
-
- // Checking the header signature and members
- CHECKED(res, check_header_shallow(&elf_hdr), error);
-
- CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
- module->base_addr = base_addr;
-
- // Check the symbols for duplicates / missing definitions
- CHECKED(res, check_symbols(module), error);
-
- // Add the module at the beginning of the module list
- list_add(&module->list, &modules_head);
-
- // The file image is no longer needed
- image_unload(module);
-
- DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
-
- return 0;
-
-error:
- image_unload(module);
-
- return res;
-}
diff --git a/com32/lib/sys/module/x86_64/elf_module.c b/com32/lib/sys/module/x86_64/elf_module.c
index 64404a17..dd24bd12 100644
--- a/com32/lib/sys/module/x86_64/elf_module.c
+++ b/com32/lib/sys/module/x86_64/elf_module.c
@@ -46,6 +46,9 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
// Load the PHT
pht = malloc(elf_hdr->e_phnum * elf_hdr->e_phentsize);
+ if (!pht)
+ return -1;
+
image_read(pht, elf_hdr->e_phnum * elf_hdr->e_phentsize, module);
// Compute the memory needings of the module
@@ -149,6 +152,11 @@ int load_segments(struct elf_module *module, Elf_Ehdr *elf_hdr) {
// Load the SHT
sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
+ if (!sht) {
+ res = -1;
+ goto out;
+ }
+
image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
// Setup the symtable size
diff --git a/com32/lib/sys/module/x86_64/shallow_module.c b/com32/lib/sys/module/x86_64/shallow_module.c
deleted file mode 100644
index b7248150..00000000
--- a/com32/lib/sys/module/x86_64/shallow_module.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * shallow_module.c
- *
- * Created on: Aug 11, 2008
- * Author: Stefan Bucur <stefanb@zytor.com>
- */
-
-
-#include <string.h>
-#include <sys/module.h>
-
-#include "common.h"
-#include "elfutils.h"
-
-
-static int check_header_shallow(Elf64_Ehdr *elf_hdr) {
- int res;
-
- res = check_header_common(elf_hdr);
-
- if (res != 0)
- return res;
-
- if (elf_hdr->e_shoff == 0x00000000) {
- DBG_PRINT("SHT missing\n");
- return -1;
- }
-
- return 0;
-}
-
-static int load_shallow_sections(struct elf_module *module, Elf64_Ehdr *elf_hdr) {
- int i;
- int res = 0;
- void *sht = NULL;
- void *buffer = NULL;
- Elf64_Shdr *crt_sht;
- Elf64_Off buff_offset;
-
- Elf64_Off min_offset = 0xFFFFFFFFFFFFFFFF;
- Elf64_Off max_offset = 0x0000000000000000;
- Elf64_Word max_align = 0x1;
-
- Elf64_Off sym_offset = 0xFFFFFFFFFFFFFFFF;
- Elf64_Off str_offset = 0xFFFFFFFFFFFFFFFF;
-
-
- char *sh_strtable;
-
- // We buffer the data up to the SHT
- buff_offset = module->u.l._cr_offset;
-
- buffer = malloc(elf_hdr->e_shoff - buff_offset);
- // Get to the SHT
- image_read(buffer, elf_hdr->e_shoff - buff_offset, module);
-
- // Load the SHT
- sht = malloc(elf_hdr->e_shnum * elf_hdr->e_shentsize);
- image_read(sht, elf_hdr->e_shnum * elf_hdr->e_shentsize, module);
-
- // Get the string table of the section names
- crt_sht = (Elf64_Shdr*)(sht + elf_hdr->e_shstrndx * elf_hdr->e_shentsize);
- sh_strtable = (char*)(buffer + (crt_sht->sh_offset - buff_offset));
-
- for (i = 0; i < elf_hdr->e_shnum; i++) {
- crt_sht = (Elf64_Shdr*)(sht + i*elf_hdr->e_shentsize);
-
- if (strcmp(".symtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the symbol table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- sym_offset = crt_sht->sh_offset;
-
- module->syment_size = crt_sht->sh_entsize;
- module->symtable_size = crt_sht->sh_size / crt_sht->sh_entsize;
- }
- if (strcmp(".strtab", sh_strtable + crt_sht->sh_name) == 0) {
- // We found the string table
- min_offset = MIN(min_offset, crt_sht->sh_offset);
- max_offset = MAX(max_offset, crt_sht->sh_offset + crt_sht->sh_size);
- max_align = MAX(max_align, crt_sht->sh_addralign);
-
- str_offset = crt_sht->sh_offset;
-
- module->strtable_size = crt_sht->sh_size;
- }
- }
-
- if (elf_malloc(&module->module_addr, max_align,
- max_offset - min_offset) != 0) {
- DBG_PRINT("Could not allocate sections\n");
- goto out;
- }
-
- // Copy the data
- image_seek(min_offset, module);
- image_read(module->module_addr, max_offset - min_offset, module);
-
- // Setup module information
- module->module_size = max_offset - min_offset;
- module->str_table = (char*)(module->module_addr + (str_offset - min_offset));
- module->sym_table = module->module_addr + (sym_offset - min_offset);
-
-out:
- // Release the SHT
- if (sht != NULL)
- free(sht);
-
- // Release the buffer
- if (buffer != NULL)
- free(buffer);
-
- return res;
-}
-
-
-int module_load_shallow(struct elf_module *module, Elf64_Addr base_addr) {
- int res;
- Elf64_Ehdr elf_hdr;
-
- // Do not allow duplicate modules
- if (module_find(module->name) != NULL) {
- DBG_PRINT("Module already loaded.\n");
- return -1;
- }
-
- res = image_load(module);
-
- if (res < 0)
- return res;
-
- module->shallow = 1;
-
- CHECKED(res, image_read(&elf_hdr, sizeof(Elf64_Ehdr), module), error);
-
- // Checking the header signature and members
- CHECKED(res, check_header_shallow(&elf_hdr), error);
-
- CHECKED(res, load_shallow_sections(module, &elf_hdr), error);
- module->base_addr = base_addr;
-
- // Check the symbols for duplicates / missing definitions
- CHECKED(res, check_symbols(module), error);
-
- // Add the module at the beginning of the module list
- list_add(&module->list, &modules_head);
-
- // The file image is no longer needed
- image_unload(module);
-
- DBG_PRINT("SHALLOW MODULE %s LOADED SUCCESSFULLY\n", module->name);
-
- return 0;
-
-error:
- image_unload(module);
-
- return res;
-}
diff --git a/com32/lib/syslinux/serial.c b/com32/lib/syslinux/serial.c
index bc41acfc..041e8505 100644
--- a/com32/lib/syslinux/serial.c
+++ b/com32/lib/syslinux/serial.c
@@ -38,7 +38,7 @@
struct syslinux_serial_console_info __syslinux_serial_console_info;
-void __constructor __syslinux_get_serial_console_info(void)
+void __syslinux_set_serial_console_info(void)
{
uint16_t iobase, divisor, flowctl;
diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile
index 5e941658..094f1ff5 100644
--- a/com32/libutil/Makefile
+++ b/com32/libutil/Makefile
@@ -38,10 +38,10 @@ LIBOBJS = ansiline.o ansiraw.o keyname.o \
quicksort.o
LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS))
-all: libutil_com.c32 libutil_lnx.a
+all: libutil.c32 libutil_lnx.a
-libutil_com.c32: $(LIBOBJS)
- $(LD) $(LDFLAGS) -soname $(@F) -o $@ $^
+libutil.elf: $(LIBOBJS)
+ $(LD) $(LDFLAGS) -soname $(patsubst %.elf,%.c32,$(@F)) -o $@ $^
libutil_lnx.a: $(LNXLIBOBJS)
rm -f $@
diff --git a/com32/lua/src/Makefile b/com32/lua/src/Makefile
index 70a7e808..f3625e1a 100644
--- a/com32/lua/src/Makefile
+++ b/com32/lua/src/Makefile
@@ -49,10 +49,11 @@ CFLAGS += -DLUA_ANSI
all: $(MODULES) $(TESTFILES)
-$(LIBLUA) : $(LIBLUA_OBJS)
- $(LD) -shared $(LDFLAGS) -o $@ $^
+liblua.elf : $(LIBLUA_OBJS)
+ $(LD) $(LDFLAGS) -shared -soname $(patsubst %.elf,%.c32,$(@F)) \
+ -o $@ $^
-lua.c32 : $(OBJS) $(LIBLUA) $(C_LIBS)
+lua.elf : $(OBJS) $(LIBLUA) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/mboot/Makefile b/com32/mboot/Makefile
index a3f61ba8..e9164369 100644
--- a/com32/mboot/Makefile
+++ b/com32/mboot/Makefile
@@ -27,7 +27,7 @@ OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o syslinux.o
all: $(MODULES) $(TESTFILES)
-mboot.c32 : $(OBJS) $(C_LIBS)
+mboot.elf : $(OBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index 9f7a0e46..7c2d5927 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -27,10 +27,10 @@ COMMONOBJS = menumain.o readconfig.o passwd.o drain.o \
all: $(MODULES) $(TESTFILES)
-vesamenu.c32: vesamenu.o $(COMMONOBJS) $(C_LIBS)
+menu.elf : menu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
-menu.c32: menu.o $(COMMONOBJS) $(C_LIBS)
+vesamenu.elf : vesamenu.o $(COMMONOBJS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index e794b3b9..8965f5f0 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -34,7 +34,7 @@ all: $(MODULES) $(TESTFILES)
dmitest.o: dmitest.c
$(CC) $(CFLAGS) $(GPLINCLUDE) -c -o $@ $<
-dmitest.c32 : dmi_utils.o dmitest.o $(C_LIBS)
+dmitest.elf : dmi_utils.o dmitest.o $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index a4c0bc28..4d900f4f 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -16,7 +16,7 @@
## ROSH Read Only Shell
##
-LIBS = $(objdir)/com32/libutil/libutil_com.c32 \
+LIBS = $(objdir)/com32/libutil/libutil.c32 \
$(objdir)/com32/lib/libcom32.c32
VPATH = $(SRC)
diff --git a/com32/samples/Makefile b/com32/samples/Makefile
index ca04f644..06e9684b 100644
--- a/com32/samples/Makefile
+++ b/com32/samples/Makefile
@@ -14,7 +14,7 @@
## samples for syslinux users
##
-LIBS = $(objdir)/com32/libutil/libutil_com.c32
+LIBS = $(objdir)/com32/libutil/libutil.c32
VPATH = $(SRC)
include $(MAKEDIR)/elf.mk
diff --git a/com32/sysdump/Makefile b/com32/sysdump/Makefile
index dca5d717..240edaaa 100644
--- a/com32/sysdump/Makefile
+++ b/com32/sysdump/Makefile
@@ -44,7 +44,7 @@ CFLAGS += -DDATE='"$(DATE)"'
all: $(MODULES) $(TESTFILES)
-sysdump.c32 : $(OBJS) $(LIBS) $(C_LIBS)
+sysdump.elf : $(OBJS) $(LIBS) $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
tidy dist:
diff --git a/core/bios.c b/core/bios.c
index 1becd280..bd8b4d87 100644
--- a/core/bios.c
+++ b/core/bios.c
@@ -537,7 +537,6 @@ void bios_init(void)
/* Init the memory subsystem */
bios_free_mem = (uint16_t *)0x413;
- mem_init();
/* CPU-dependent initialization and related checks. */
check_escapes();
diff --git a/core/conio.c b/core/conio.c
index a351fd14..5587203f 100644
--- a/core/conio.c
+++ b/core/conio.c
@@ -45,6 +45,8 @@ __export uint8_t FlowIgnore = 0; /* Ignore input unless these bits set */
__export uint16_t DisplayCon = 0x01; /* Display console enabled */
__export uint8_t FlowOutput = 0; /* Output to assert for serial flow */
+__export uint8_t DisplayMask = 0x07; /* Display modes mask */
+
uint8_t ScrollAttribute = 0x07; /* Grey on white (normal text color) */
/*
@@ -75,6 +77,9 @@ __export void write_serial(char data)
if (!SerialPort)
return;
+ if (!(DisplayMask & 0x04))
+ return;
+
while (1) {
char ch;
@@ -162,21 +167,22 @@ int bios_pollchar(void)
/* Already-queued input? */
if (SerialTail == SerialHead) {
/* LSR */
- data = inb(SerialPort + 5) & 1;
- if (data) {
+ data = !(inb(SerialPort + 5) & 1);
+ if (!data) {
/* MSR */
data = inb(SerialPort + 6);
/* Required status bits */
- if (data) {
- data &= FlowIgnore;
- if (data != FlowIgnore)
- data = 0;
- else
- data = 1;
- }
- }
- }
+ data &= FlowIgnore;
+
+ if (data == FlowIgnore)
+ data = 1;
+ else
+ data = 0;
+ } else
+ data = 1;
+ } else
+ data = 1;
sti();
}
@@ -221,7 +227,8 @@ char bios_getchar(char *hi)
sti(); /* We already know we'll consume data */
data = *SerialTail++;
- SerialTail = (char *)((unsigned long)SerialTail & (serial_buf_size - 1));
+ if (SerialTail > SerialHead + serial_buf_size)
+ SerialTail = SerialHead;
} else {
/* LSR */
data = inb(SerialPort + 5) & 1;
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 1fa43bd6..b277877a 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -48,10 +48,10 @@ struct elf_module core_module = {
};
/*
- Initializes the module subsystem by taking the core module ( shallow module ) and placing
- it on top of the modules_head_list. Since the core module is initialized when declared
- we technically don't need the exec_init() and module_load_shallow() procedures
-*/
+ * Initializes the module subsystem by taking the core module
+ * (preinitialized shallow module) and placing it on top of the
+ * modules_head_list.
+ */
void init_module_subsystem(struct elf_module *module)
{
list_add(&module->list, &modules_head);
@@ -126,7 +126,7 @@ void load_env32(com32sys_t * regs __unused)
PATH = malloc(strlen(CurrentDirName) + 1);
if (!PATH) {
printf("Couldn't allocate memory for PATH\n");
- return;
+ goto out;
}
strcpy(PATH, CurrentDirName);
@@ -147,15 +147,36 @@ void load_env32(com32sys_t * regs __unused)
* a bit harder to find LDLINUX. If search_dirs() succeeds
* in finding LDLINUX it will set the cwd.
*/
+ free(PATH);
fd = opendev(&__file_dev, NULL, O_RDONLY);
if (fd < 0)
return;
fp = &__file_info[fd];
- if (!search_dirs(&fp->i.fd, search_directories, filenames, realname))
+ if (!search_dirs(&fp->i.fd, search_directories, filenames, realname)) {
+ char path[FILENAME_MAX];
+
+ /*
+ * search_dirs() sets the current working directory if
+ * it successfully opens the file. Set PATH to the
+ * directory in which we found ldlinux.c32.
+ */
+ if (!core_getcwd(path, sizeof(path)))
+ goto out;
+
+ PATH = malloc(strlen(path) + 1);
+ if (!PATH) {
+ printf("Couldn't allocate memory for PATH\n");
+ goto out;
+ }
+
+ strcpy(PATH, path);
+
start_ldlinux(argv);
+ }
+out:
writestr("\nFailed to load ldlinux.c32");
}
diff --git a/core/fs/fs.c b/core/fs/fs.c
index 40f97d5e..adcee916 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -40,9 +40,13 @@ struct inode *alloc_inode(struct fs_info *fs, uint32_t ino, size_t data)
*/
void put_inode(struct inode *inode)
{
- while (inode && --inode->refcnt == 0) {
+ while (inode) {
struct inode *dead = inode;
- inode = inode->parent;
+ int refcnt = --(dead->refcnt);
+ dprintf("put_inode %p name %s refcnt %u\n", dead, dead->name, refcnt);
+ if (refcnt)
+ break; /* We still have references */
+ inode = dead->parent;
if (dead->name)
free((char *)dead->name);
free(dead);
@@ -108,77 +112,11 @@ __export int open_config(void)
return fd;
}
-void pm_mangle_name(com32sys_t *regs)
-{
- const char *src = MK_PTR(regs->ds, regs->esi.w[0]);
- char *dst = MK_PTR(regs->es, regs->edi.w[0]);
-
- mangle_name(dst, src);
-}
-
__export void mangle_name(char *dst, const char *src)
{
this_fs->fs_ops->mangle_name(dst, src);
}
-void getfssec(com32sys_t *regs)
-{
- int sectors;
- bool have_more;
- uint32_t bytes_read;
- char *buf;
- struct file *file;
- uint16_t handle;
-
- sectors = regs->ecx.w[0];
-
- handle = regs->esi.w[0];
- file = handle_to_file(handle);
-
- buf = MK_PTR(regs->es, regs->ebx.w[0]);
- bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);
-
- /*
- * If we reach EOF, the filesystem driver will have already closed
- * the underlying file... this really should be cleaner.
- */
- if (!have_more) {
- _close_file(file);
- regs->esi.w[0] = 0;
- }
-
- regs->ecx.l = bytes_read;
-}
-
-void getfsbytes(com32sys_t *regs)
-{
- int sectors;
- bool have_more;
- uint32_t bytes_read;
- char *buf;
- struct file *file;
- uint16_t handle;
-
- handle = regs->esi.w[0];
- file = handle_to_file(handle);
-
- sectors = regs->ecx.w[0] >> SECTOR_SHIFT(file->fs);
-
- buf = MK_PTR(regs->es, regs->ebx.w[0]);
- bytes_read = file->fs->fs_ops->getfssec(file, buf, sectors, &have_more);
-
- /*
- * If we reach EOF, the filesystem driver will have already closed
- * the underlying file... this really should be cleaner.
- */
- if (!have_more) {
- _close_file(file);
- regs->esi.w[0] = 0;
- }
-
- regs->ecx.l = bytes_read;
-}
-
size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors)
{
bool have_more;
@@ -200,23 +138,6 @@ size_t pmapi_read_file(uint16_t *handle, void *buf, size_t sectors)
return bytes_read;
}
-void pm_searchdir(com32sys_t *regs)
-{
- char *name = MK_PTR(regs->ds, regs->edi.w[0]);
- int rv;
-
- rv = searchdir(name);
- if (rv < 0) {
- regs->esi.w[0] = 0;
- regs->eax.l = 0;
- regs->eflags.l |= EFLAGS_ZF;
- } else {
- regs->esi.w[0] = rv;
- regs->eax.l = handle_to_file(rv)->inode->size;
- regs->eflags.l &= ~EFLAGS_ZF;
- }
-}
-
int searchdir(const char *name)
{
static char root_name[] = "/";
@@ -444,28 +365,6 @@ __export int open_file(const char *name, struct com32_filedata *filedata)
return rv;
}
-void pm_open_file(com32sys_t *regs)
-{
- int rv;
- struct file *file;
- const char *name = MK_PTR(regs->es, regs->esi.w[0]);
- char mangled_name[FILENAME_MAX];
-
- dprintf("pm_open_file %s\n", name);
-
- mangle_name(mangled_name, name);
- rv = searchdir(mangled_name);
- if (rv < 0) {
- regs->eflags.l |= EFLAGS_CF;
- } else {
- file = handle_to_file(rv);
- regs->eflags.l &= ~EFLAGS_CF;
- regs->eax.l = file->inode->size;
- regs->ecx.w[0] = SECTOR_SIZE(file->fs);
- regs->esi.w[0] = rv;
- }
-}
-
__export void close_file(uint16_t handle)
{
struct file *file;
@@ -476,11 +375,6 @@ __export void close_file(uint16_t handle)
}
}
-void pm_close_file(com32sys_t *regs)
-{
- close_file(regs->esi.w[0]);
-}
-
/*
* it will do:
* initialize the memory management function;
diff --git a/core/fs/pxe/dnsresolv.c b/core/fs/pxe/dnsresolv.c
index fda0f815..184bacbd 100644
--- a/core/fs/pxe/dnsresolv.c
+++ b/core/fs/pxe/dnsresolv.c
@@ -170,7 +170,7 @@ static char *dns_skiplabel(char *label)
*
* XXX: probably need some caching here.
*/
-uint32_t dns_resolv(const char *name)
+__export uint32_t dns_resolv(const char *name)
{
static char __lowmem DNSSendBuf[PKTBUF_SIZE];
static char __lowmem DNSRecvBuf[PKTBUF_SIZE];
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 11270044..ae44cffe 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -254,7 +254,7 @@ static const char *parse_dotquad(const char *ip_str, uint32_t *res)
* the ASM pxenv function wrapper, return 1 if error, or 0
*
*/
-int pxe_call(int opcode, void *data)
+__export int pxe_call(int opcode, void *data)
{
extern void pxenv(void);
com32sys_t regs;
@@ -1656,7 +1656,7 @@ int reset_pxe(void)
* This function unloads the PXE and UNDI stacks and
* unclaims the memory.
*/
-void unload_pxe(uint16_t flags)
+__export void unload_pxe(uint16_t flags)
{
/* PXE unload sequences */
static const uint8_t new_api_unload[] = {
diff --git a/core/fs/xfs/xfs.c b/core/fs/xfs/xfs.c
index 89a9aef2..b6a396aa 100644
--- a/core/fs/xfs/xfs.c
+++ b/core/fs/xfs/xfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
+ * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -38,29 +38,26 @@
#include "xfs_readdir.h"
static inline int xfs_fmt_local_readdir(struct file *file,
- struct dirent *dirent, xfs_dinode_t *core)
+ struct dirent *dirent,
+ xfs_dinode_t *core)
{
- return xfs_readdir_dir2_block(file, dirent, core);
+ return xfs_readdir_dir2_local(file, dirent, core);
}
static inline int xfs_fmt_extents_readdir(struct file *file,
struct dirent *dirent,
xfs_dinode_t *core)
{
- int retval;
-
if (be32_to_cpu(core->di_nextents) <= 1) {
/* Single-block Directories */
- retval = xfs_readdir_dir2_block(file, dirent, core);
+ return xfs_readdir_dir2_block(file, dirent, core);
} else if (xfs_dir2_isleaf(file->fs, core)) {
/* Leaf Directory */
- retval = xfs_readdir_dir2_leaf(file, dirent, core);
+ return xfs_readdir_dir2_leaf(file, dirent, core);
} else {
/* Node Directory */
- retval = xfs_readdir_dir2_node(file, dirent, core);
+ return xfs_readdir_dir2_node(file, dirent, core);
}
-
- return retval;
}
static int xfs_readdir(struct file *file, struct dirent *dirent)
@@ -68,7 +65,8 @@ static int xfs_readdir(struct file *file, struct dirent *dirent)
struct fs_info *fs = file->fs;
xfs_dinode_t *core;
struct inode *inode = file->inode;
- int retval = -1;
+
+ xfs_debug("file %p dirent %p");
core = xfs_dinode_get_core(fs, inode->ino);
if (!core) {
@@ -77,11 +75,11 @@ static int xfs_readdir(struct file *file, struct dirent *dirent)
}
if (core->di_format == XFS_DINODE_FMT_LOCAL)
- retval = xfs_fmt_local_readdir(file, dirent, core);
+ return xfs_fmt_local_readdir(file, dirent, core);
else if (core->di_format == XFS_DINODE_FMT_EXTENTS)
- retval = xfs_fmt_extents_readdir(file, dirent, core);
+ return xfs_fmt_extents_readdir(file, dirent, core);
- return retval;
+ return -1;
}
static uint32_t xfs_getfssec(struct file *file, char *buf, int sectors,
@@ -106,6 +104,8 @@ static int xfs_next_extent(struct inode *inode, uint32_t lstart)
(void)lstart;
+ xfs_debug("inode %p lstart %lu", inode, lstart);
+
core = xfs_dinode_get_core(fs, inode->ino);
if (!core) {
xfs_error("Failed to get dinode from disk (ino %llx)", inode->ino);
@@ -190,20 +190,16 @@ static inline struct inode *xfs_fmt_extents_find_entry(const char *dname,
struct inode *parent,
xfs_dinode_t *core)
{
- struct inode *inode;
-
if (be32_to_cpu(core->di_nextents) <= 1) {
- /* Single-block Directories */
- inode = xfs_dir2_block_find_entry(dname, parent, core);
+ /* Single-block Directories */
+ return xfs_dir2_block_find_entry(dname, parent, core);
} else if (xfs_dir2_isleaf(parent->fs, core)) {
- /* Leaf Directory */
- inode = xfs_dir2_leaf_find_entry(dname, parent, core);
+ /* Leaf Directory */
+ return xfs_dir2_leaf_find_entry(dname, parent, core);
} else {
- /* Node Directory */
- inode = xfs_dir2_node_find_entry(dname, parent, core);
+ /* Node Directory */
+ return xfs_dir2_node_find_entry(dname, parent, core);
}
-
- return inode;
}
static inline struct inode *xfs_fmt_btree_find_entry(const char *dname,
@@ -233,11 +229,6 @@ static struct inode *xfs_iget(const char *dname, struct inode *parent)
inode = xfs_fmt_extents_find_entry(dname, parent, core);
} else if (core->di_format == XFS_DINODE_FMT_BTREE) {
inode = xfs_fmt_btree_find_entry(dname, parent, core);
- } else {
- xfs_debug("format %hhu", core->di_format);
- xfs_debug("TODO: format \"local\" and \"extents\" are the only "
- "supported ATM");
- goto out;
}
if (!inode) {
@@ -266,7 +257,9 @@ static int xfs_readlink(struct inode *inode, char *buf)
int pathlen = -1;
xfs_bmbt_irec_t rec;
block_t db;
- char *dir_buf;
+ const char *dir_buf;
+
+ xfs_debug("inode %p buf %p", inode, buf);
core = xfs_dinode_get_core(fs, inode->ino);
if (!core) {
@@ -289,7 +282,7 @@ static int xfs_readlink(struct inode *inode, char *buf)
} else if (core->di_format == XFS_DINODE_FMT_EXTENTS) {
bmbt_irec_get(&rec, (xfs_bmbt_rec_t *)&core->di_literal_area[0]);
db = fsblock_to_bytes(fs, rec.br_startblock) >> BLOCK_SHIFT(fs);
- dir_buf = xfs_dir2_get_dirblks(fs, db, rec.br_blockcount);
+ dir_buf = xfs_dir2_dirblks_get_cached(fs, db, rec.br_blockcount);
/*
* Syslinux only supports filesystem block size larger than or equal to
@@ -297,7 +290,6 @@ static int xfs_readlink(struct inode *inode, char *buf)
* symbolic link file content, which is only 1024 bytes long.
*/
memcpy(buf, dir_buf, pathlen);
- free(dir_buf);
}
out:
diff --git a/core/fs/xfs/xfs.h b/core/fs/xfs/xfs.h
index da57221a..0d953d89 100644
--- a/core/fs/xfs/xfs.h
+++ b/core/fs/xfs/xfs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
+ * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
*
* Some parts borrowed from Linux kernel tree (linux/fs/xfs):
*
@@ -30,11 +30,16 @@
#include "xfs_types.h"
#include "xfs_ag.h"
-#define xfs_error(fmt, args...) \
- printf("xfs: " fmt "\n", ## args);
+#define xfs_error(fmt, args...) \
+ ({ \
+ printf("%s:%u: xfs - [ERROR] " fmt "\n", __func__, __LINE__, ## args); \
+ })
-#define xfs_debug(fmt, args...) \
- dprintf("%s: " fmt "\n", __func__, ## args);
+#define xfs_debug(fmt, args...) \
+ ({ \
+ dprintf("%s:%u: xfs - [DEBUG] " fmt "\n", __func__, __LINE__, \
+ ## args); \
+ })
struct xfs_fs_info;
diff --git a/core/fs/xfs/xfs_dinode.c b/core/fs/xfs/xfs_dinode.c
index 8e2d8d04..55be6e2d 100644
--- a/core/fs/xfs/xfs_dinode.c
+++ b/core/fs/xfs/xfs_dinode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
+ * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -33,7 +33,7 @@ xfs_dinode_t *xfs_dinode_get_core(struct fs_info *fs, xfs_ino_t ino)
xfs_dinode_t *core;
uint64_t offset;
- xfs_debug("ino %lu", ino);
+ xfs_debug("fs %p ino %lu", fs, ino);
blk = ino_to_bytes(fs, ino) >> BLOCK_SHIFT(fs);
offset = XFS_INO_TO_OFFSET(XFS_INFO(fs), ino) << XFS_INFO(fs)->inode_shift;
diff --git a/core/fs/xfs/xfs_dir2.c b/core/fs/xfs/xfs_dir2.c
index c52196ae..de37ef7c 100644
--- a/core/fs/xfs/xfs_dir2.c
+++ b/core/fs/xfs/xfs_dir2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
+ * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -28,23 +28,16 @@
#include "xfs_dir2.h"
-char *xfs_dir2_get_entry_name(uint8_t *start, uint8_t *end)
-{
- char *s;
- char *p;
-
- s = malloc(end - start + 1);
- if (!s)
- malloc_error("string");
+#define XFS_DIR2_DIRBLKS_CACHE_SIZE 128
- p = s;
- while (start < end)
- *p++ = *start++;
+struct xfs_dir2_dirblks_cache {
+ block_t dc_startblock;
+ xfs_filblks_t dc_blkscount;
+ void *dc_area;
+};
- *p = '\0';
-
- return s;
-}
+static struct xfs_dir2_dirblks_cache dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE];
+static unsigned char dirblks_cached_count = 0;
uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen)
{
@@ -73,8 +66,8 @@ uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen)
}
}
-void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock,
- xfs_filblks_t c)
+static void *get_dirblks(struct fs_info *fs, block_t startblock,
+ xfs_filblks_t c)
{
int count = c << XFS_INFO(fs)->dirblklog;
uint8_t *p;
@@ -96,6 +89,85 @@ void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock,
return buf;
}
+const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
+ xfs_filblks_t c)
+{
+ unsigned char i;
+ void *buf;
+
+ xfs_debug("fs %p startblock %llu (0x%llx) blkscount %lu", fs, startblock,
+ startblock, c);
+
+ if (!dirblks_cached_count) {
+ buf = get_dirblks(fs, startblock, c);
+
+ dirblks_cache[dirblks_cached_count].dc_startblock = startblock;
+ dirblks_cache[dirblks_cached_count].dc_blkscount = c;
+ dirblks_cache[dirblks_cached_count].dc_area = buf;
+
+ return dirblks_cache[dirblks_cached_count++].dc_area;
+ } else if (dirblks_cached_count == XFS_DIR2_DIRBLKS_CACHE_SIZE) {
+ for (i = 0; i < XFS_DIR2_DIRBLKS_CACHE_SIZE / 2; i++) {
+ unsigned char k = XFS_DIR2_DIRBLKS_CACHE_SIZE - (i + 1);
+
+ free(dirblks_cache[i].dc_area);
+ dirblks_cache[i] = dirblks_cache[k];
+ memset(&dirblks_cache[k], 0, sizeof(dirblks_cache[k]));
+ }
+
+ buf = get_dirblks(fs, startblock, c);
+
+ dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_startblock =
+ startblock;
+ dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_blkscount = c;
+ dirblks_cache[XFS_DIR2_DIRBLKS_CACHE_SIZE / 2].dc_area = buf;
+
+ dirblks_cached_count = XFS_DIR2_DIRBLKS_CACHE_SIZE / 2;
+
+ return dirblks_cache[dirblks_cached_count++].dc_area;
+ } else {
+ block_t block;
+ xfs_filblks_t count;
+
+ block = dirblks_cache[dirblks_cached_count - 1].dc_startblock;
+ count = dirblks_cache[dirblks_cached_count - 1].dc_blkscount;
+
+ if (block == startblock && count == c) {
+ return dirblks_cache[dirblks_cached_count - 1].dc_area;
+ } else {
+ for (i = 0; i < dirblks_cached_count; i++) {
+ block = dirblks_cache[i].dc_startblock;
+ count = dirblks_cache[i].dc_blkscount;
+
+ if (block == startblock && count == c)
+ return dirblks_cache[i].dc_area;
+ }
+
+ buf = get_dirblks(fs, startblock, c);
+
+ dirblks_cache[dirblks_cached_count].dc_startblock = startblock;
+ dirblks_cache[dirblks_cached_count].dc_blkscount = c;
+ dirblks_cache[dirblks_cached_count].dc_area = buf;
+
+ return dirblks_cache[dirblks_cached_count++].dc_area;
+ }
+ }
+
+ return NULL;
+}
+
+void xfs_dir2_dirblks_flush_cache(void)
+{
+ unsigned char i;
+
+ for (i = 0; i < dirblks_cached_count; i++) {
+ free(dirblks_cache[i].dc_area);
+ memset(&dirblks_cache[i], 0, sizeof(dirblks_cache[i]));
+ }
+
+ dirblks_cached_count = 0;
+}
+
struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent,
xfs_dinode_t *core)
{
@@ -107,6 +179,7 @@ struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent,
xfs_intino_t ino;
xfs_dinode_t *ncore = NULL;
+ xfs_debug("dname %s parent %p core %p", dname, parent, core);
xfs_debug("count %hhu i8count %hhu", sf->hdr.count, sf->hdr.i8count);
sf_entry = (xfs_dir2_sf_entry_t *)((uint8_t *)&sf->list[0] -
@@ -114,19 +187,12 @@ struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent,
while (count--) {
uint8_t *start_name = &sf_entry->name[0];
uint8_t *end_name = start_name + sf_entry->namelen;
- char *name;
- name = xfs_dir2_get_entry_name(start_name, end_name);
-
- xfs_debug("entry name: %s", name);
-
- if (!strncmp(name, dname, strlen(dname))) {
- free(name);
+ if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) {
+ xfs_debug("Found entry %s", dname);
goto found;
}
- free(name);
-
sf_entry = (xfs_dir2_sf_entry_t *)((uint8_t *)sf_entry +
offsetof(struct xfs_dir2_sf_entry,
name[0]) +
@@ -184,7 +250,7 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent,
xfs_bmbt_irec_t r;
block_t dir_blk;
struct fs_info *fs = parent->fs;
- uint8_t *dirblk_buf;
+ const uint8_t *dirblk_buf;
uint8_t *p, *endp;
xfs_dir2_data_hdr_t *hdr;
struct inode *inode = NULL;
@@ -194,10 +260,12 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent,
xfs_intino_t ino;
xfs_dinode_t *ncore;
+ xfs_debug("dname %s parent %p core %p", dname, parent, core);
+
bmbt_irec_get(&r, (xfs_bmbt_rec_t *)&core->di_literal_area[0]);
dir_blk = fsblock_to_bytes(fs, r.br_startblock) >> BLOCK_SHIFT(fs);
- dirblk_buf = xfs_dir2_get_dirblks(fs, dir_blk, r.br_blockcount);
+ dirblk_buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, r.br_blockcount);
hdr = (xfs_dir2_data_hdr_t *)dirblk_buf;
if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) {
xfs_error("Block directory header's magic number does not match!");
@@ -213,7 +281,6 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent,
while (p < endp) {
uint8_t *start_name;
uint8_t *end_name;
- char *name;
dup = (xfs_dir2_data_unused_t *)p;
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
@@ -225,20 +292,16 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent,
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
- if (!strncmp(name, dname, strlen(dname))) {
- free(name);
+ if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) {
+ xfs_debug("Found entry %s", dname);
goto found;
}
- free(name);
p += xfs_dir2_data_entsize(dep->namelen);
}
out:
- free(dirblk_buf);
-
return NULL;
found:
@@ -274,12 +337,10 @@ found:
xfs_debug("entry inode's number %lu", ino);
- free(dirblk_buf);
return inode;
failed:
free(inode);
- free(dirblk_buf);
return NULL;
}
@@ -302,25 +363,26 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
xfs_dir2_data_hdr_t *data_hdr;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
xfs_intino_t ino;
xfs_dinode_t *ncore;
- uint8_t *buf = NULL;
+ const uint8_t *buf = NULL;
+
+ xfs_debug("dname %s parent %p core %p", dname, parent, core);
bmbt_irec_get(&irec, ((xfs_bmbt_rec_t *)&core->di_literal_area[0]) +
be32_to_cpu(core->di_nextents) - 1);
leaf_blk = fsblock_to_bytes(parent->fs, irec.br_startblock) >>
BLOCK_SHIFT(parent->fs);
- leaf = (xfs_dir2_leaf_t *)xfs_dir2_get_dirblks(parent->fs, leaf_blk,
- irec.br_blockcount);
+ leaf = (xfs_dir2_leaf_t *)xfs_dir2_dirblks_get_cached(parent->fs, leaf_blk,
+ irec.br_blockcount);
if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) {
xfs_error("Single leaf block header's magic number does not match!");
goto out;
}
if (!leaf->hdr.count)
- goto out;
+ goto out;
hashwant = xfs_dir2_da_hashname((uint8_t *)dname, strlen(dname));
@@ -355,18 +417,16 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
newdb = xfs_dir2_dataptr_to_db(parent->fs, be32_to_cpu(lep->address));
if (newdb != curdb) {
- if (buf)
- free(buf);
-
bmbt_irec_get(&irec,
((xfs_bmbt_rec_t *)&core->di_literal_area[0]) + newdb);
dir_blk = fsblock_to_bytes(parent->fs, irec.br_startblock) >>
+
BLOCK_SHIFT(parent->fs);
- buf = xfs_dir2_get_dirblks(parent->fs, dir_blk, irec.br_blockcount);
+ buf = xfs_dir2_dirblks_get_cached(parent->fs, dir_blk, irec.br_blockcount);
data_hdr = (xfs_dir2_data_hdr_t *)buf;
if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) {
xfs_error("Leaf directory's data magic No. does not match!");
- goto out1;
+ goto out;
}
curdb = newdb;
@@ -377,21 +437,14 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
- if (!strncmp(name, dname, strlen(dname))) {
- free(name);
+ if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) {
+ xfs_debug("Found entry %s", dname);
goto found;
}
-
- free(name);
}
-out1:
- free(buf);
out:
- free(leaf);
-
return NULL;
found:
@@ -428,15 +481,10 @@ found:
xfs_debug("entry inode's number %lu", ino);
- free(buf);
- free(leaf);
-
return ip;
failed:
free(ip);
- free(buf);
- free(leaf);
return ip;
}
@@ -560,14 +608,15 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
struct inode *ip;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
int low;
int high;
int mid = 0;
uint32_t newdb, curdb = -1;
xfs_intino_t ino;
xfs_dinode_t *ncore;
- uint8_t *buf = NULL;
+ const uint8_t *buf = NULL;
+
+ xfs_debug("dname %s parent %p core %p", dname, parent, core);
hashwant = xfs_dir2_da_hashname((uint8_t *)dname, strlen(dname));
@@ -579,7 +628,8 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
return NULL;
}
- node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(parent->fs, fsblkno, 1);
+ node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(parent->fs, fsblkno,
+ 1);
if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) {
xfs_error("Node's magic number does not match!");
goto out;
@@ -630,9 +680,8 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
goto out;
}
- free(node);
- node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(parent->fs,
- fsblkno, 1);
+ node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(parent->fs,
+ fsblkno, 1);
} while(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
leaf = (xfs_dir2_leaf_t*)node;
@@ -675,20 +724,17 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
newdb = xfs_dir2_dataptr_to_db(parent->fs, be32_to_cpu(lep->address));
if (newdb != curdb) {
- if (buf)
- free(buf);
-
fsblkno = xfs_dir2_get_right_blk(parent->fs, core, newdb, &error);
if (error) {
xfs_error("Cannot find data block!");
goto out;
}
- buf = xfs_dir2_get_dirblks(parent->fs, fsblkno, 1);
+ buf = xfs_dir2_dirblks_get_cached(parent->fs, fsblkno, 1);
data_hdr = (xfs_dir2_data_hdr_t *)buf;
if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) {
xfs_error("Leaf directory's data magic No. does not match!");
- goto out1;
+ goto out;
}
curdb = newdb;
@@ -699,21 +745,14 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
- if (!strncmp(name, dname, strlen(dname))) {
- free(name);
- goto found;
- }
- free(name);
+ if (!xfs_dir2_entry_name_cmp(start_name, end_name, dname)) {
+ xfs_debug("Found entry %s", dname);
+ goto found;
+ }
}
-out1:
- free(buf);
-
out:
- free(node);
-
return NULL;
found:
@@ -745,15 +784,10 @@ found:
xfs_debug("entry inode's number %lu", ino);
- free(buf);
- free(node);
-
return ip;
failed:
free(ip);
- free(buf);
- free(node);
return NULL;
}
diff --git a/core/fs/xfs/xfs_dir2.h b/core/fs/xfs/xfs_dir2.h
index e1b96227..158cf44f 100644
--- a/core/fs/xfs/xfs_dir2.h
+++ b/core/fs/xfs/xfs_dir2.h
@@ -23,10 +23,12 @@
#include "xfs.h"
-char *xfs_dir2_get_entry_name(uint8_t *start, uint8_t *end);
-void *xfs_dir2_get_dirblks(struct fs_info *fs, block_t startblock,
- xfs_filblks_t c);
+const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
+ xfs_filblks_t c);
+void xfs_dir2_dirblks_flush_cache(void);
+
uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen);
+
block_t xfs_dir2_get_right_blk(struct fs_info *fs, xfs_dinode_t *core,
block_t fsblkno, int *error);
@@ -51,4 +53,17 @@ static inline bool xfs_dir2_isleaf(struct fs_info *fs, xfs_dinode_t *dip)
return (last == XFS_INFO(fs)->dirleafblk + (1 << XFS_INFO(fs)->dirblklog));
}
+static inline int xfs_dir2_entry_name_cmp(uint8_t *start, uint8_t *end,
+ const char *name)
+{
+ if (!name || (strlen(name) != end - start))
+ return -1;
+
+ while (start < end)
+ if (*start++ != *name++)
+ return -1;
+
+ return 0;
+}
+
#endif /* XFS_DIR2_H_ */
diff --git a/core/fs/xfs/xfs_readdir.c b/core/fs/xfs/xfs_readdir.c
index 0e013e55..86c8a77b 100644
--- a/core/fs/xfs/xfs_readdir.c
+++ b/core/fs/xfs/xfs_readdir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
+ * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr@zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -35,6 +35,9 @@ static int fill_dirent(struct fs_info *fs, struct dirent *dirent,
{
xfs_dinode_t *core;
+ xfs_debug("fs %p, dirent %p offset %lu ino %llu name %s namelen %llu", fs,
+ dirent, offset, ino, name, namelen);
+
dirent->d_ino = ino;
dirent->d_off = offset;
dirent->d_reclen = offsetof(struct dirent, d_name) + namelen + 1;
@@ -52,7 +55,8 @@ static int fill_dirent(struct fs_info *fs, struct dirent *dirent,
else if (be16_to_cpu(core->di_mode) & S_IFLNK)
dirent->d_type = DT_LNK;
- memcpy(dirent->d_name, name, namelen + 1);
+ memcpy(dirent->d_name, name, namelen);
+ dirent->d_name[namelen] = '\0';
return 0;
}
@@ -66,15 +70,15 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent,
uint32_t offset = file->offset;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
xfs_ino_t ino;
struct fs_info *fs = file->fs;
int retval = 0;
+ xfs_debug("file %p dirent %p core %p", file, dirent, core);
xfs_debug("count %hhu i8count %hhu", sf->hdr.count, sf->hdr.i8count);
if (file->offset + 1 > count)
- return -1;
+ goto out;
file->offset++;
@@ -96,22 +100,23 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent,
start_name = &sf_entry->name[0];
end_name = start_name + sf_entry->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
-
ino = xfs_dir2_sf_get_inumber(sf, (xfs_dir2_inou_t *)(
(uint8_t *)sf_entry +
offsetof(struct xfs_dir2_sf_entry,
name[0]) +
sf_entry->namelen));
- retval = fill_dirent(fs, dirent, file->offset, ino, (char *)name,
+ retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name,
end_name - start_name);
if (retval)
xfs_error("Failed to fill in dirent structure");
- free(name);
-
return retval;
+
+out:
+ xfs_dir2_dirblks_flush_cache();
+
+ return -1;
}
int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
@@ -120,7 +125,7 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
xfs_bmbt_irec_t r;
block_t dir_blk;
struct fs_info *fs = file->fs;
- uint8_t *dirblk_buf;
+ const uint8_t *dirblk_buf;
uint8_t *p;
uint32_t offset;
xfs_dir2_data_hdr_t *hdr;
@@ -129,28 +134,26 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
xfs_dir2_data_entry_t *dep;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
xfs_ino_t ino;
int retval = 0;
+ xfs_debug("file %p dirent %p core %p", file, dirent, core);
+
bmbt_irec_get(&r, (xfs_bmbt_rec_t *)&core->di_literal_area[0]);
dir_blk = fsblock_to_bytes(fs, r.br_startblock) >> BLOCK_SHIFT(fs);
- dirblk_buf = xfs_dir2_get_dirblks(fs, dir_blk, r.br_blockcount);
+ dirblk_buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, r.br_blockcount);
hdr = (xfs_dir2_data_hdr_t *)dirblk_buf;
if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) {
xfs_error("Block directory header's magic number does not match!");
xfs_debug("hdr->magic: 0x%lx", be32_to_cpu(hdr->magic));
-
- free(dirblk_buf);
-
- return -1;
+ goto out;
}
btp = xfs_dir2_block_tail_p(XFS_INFO(fs), hdr);
if (file->offset + 1 > be32_to_cpu(btp->count))
- return -1;
+ goto out;
file->offset++;
@@ -175,19 +178,20 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
ino = be64_to_cpu(dep->inumber);
- retval = fill_dirent(fs, dirent, file->offset, ino, name,
+ retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name,
end_name - start_name);
if (retval)
xfs_error("Failed to fill in dirent structure");
- free(dirblk_buf);
- free(name);
-
return retval;
+
+out:
+ xfs_dir2_dirblks_flush_cache();
+
+ return -1;
}
int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
@@ -204,18 +208,19 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
xfs_dir2_data_hdr_t *data_hdr;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
xfs_intino_t ino;
- uint8_t *buf = NULL;
+ const uint8_t *buf = NULL;
int retval = 0;
+ xfs_debug("file %p dirent %p core %p", file, dirent, core);
+
bmbt_irec_get(&irec, ((xfs_bmbt_rec_t *)&core->di_literal_area[0]) +
be32_to_cpu(core->di_nextents) - 1);
leaf_blk = fsblock_to_bytes(fs, irec.br_startblock) >>
BLOCK_SHIFT(file->fs);
- leaf = (xfs_dir2_leaf_t *)xfs_dir2_get_dirblks(fs, leaf_blk,
- irec.br_blockcount);
+ leaf = (xfs_dir2_leaf_t *)xfs_dir2_dirblks_get_cached(fs, leaf_blk,
+ irec.br_blockcount);
if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) {
xfs_error("Single leaf block header's magic number does not match!");
goto out;
@@ -239,11 +244,11 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
dir_blk = fsblock_to_bytes(fs, irec.br_startblock) >> BLOCK_SHIFT(fs);
- buf = xfs_dir2_get_dirblks(fs, dir_blk, irec.br_blockcount);
+ buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, irec.br_blockcount);
data_hdr = (xfs_dir2_data_hdr_t *)buf;
if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) {
xfs_error("Leaf directory's data magic number does not match!");
- goto out1;
+ goto out;
}
offset = xfs_dir2_dataptr_to_off(fs, be32_to_cpu(lep->address));
@@ -252,26 +257,18 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
ino = be64_to_cpu(dep->inumber);
- retval = fill_dirent(fs, dirent, file->offset, ino, name,
+ retval = fill_dirent(fs, dirent, file->offset, ino, (char *)start_name,
end_name - start_name);
if (retval)
xfs_error("Failed to fill in dirent structure");
- free(name);
- free(buf);
- free(leaf);
-
return retval;
-out1:
- free(buf);
-
out:
- free(leaf);
+ xfs_dir2_dirblks_flush_cache();
return -1;
}
@@ -293,11 +290,12 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent,
xfs_dir2_data_entry_t *dep;
uint8_t *start_name;
uint8_t *end_name;
- char *name;
uint32_t db;
- uint8_t *buf = NULL;
+ const uint8_t *buf = NULL;
int retval = 0;
+ xfs_debug("file %p dirent %p core %p", file, dirent, core);
+
do {
bmbt_irec_get(&irec, (xfs_bmbt_rec_t *)&core->di_literal_area[0] +
++node_off);
@@ -305,7 +303,7 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent,
fsblkno = fsblock_to_bytes(fs, irec.br_startblock) >> BLOCK_SHIFT(fs);
- node = (xfs_da_intnode_t *)xfs_dir2_get_dirblks(fs, fsblkno, 1);
+ node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(fs, fsblkno, 1);
if (be16_to_cpu(node->hdr.info.magic) != XFS_DA_NODE_MAGIC) {
xfs_error("Node's magic number does not match!");
goto out;
@@ -314,7 +312,7 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent,
try_next_btree:
if (!node->hdr.count ||
XFS_PVT(inode)->i_btree_offset >= be16_to_cpu(node->hdr.count))
- goto out;
+ goto out;
fsblkno = be32_to_cpu(node->btree[XFS_PVT(inode)->i_btree_offset].before);
fsblkno = xfs_dir2_get_right_blk(fs, core, fsblkno, &error);
@@ -323,17 +321,16 @@ try_next_btree:
goto out;
}
- leaf = (xfs_dir2_leaf_t*)xfs_dir2_get_dirblks(fs, fsblkno, 1);
+ leaf = (xfs_dir2_leaf_t*)xfs_dir2_dirblks_get_cached(fs, fsblkno, 1);
if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAFN_MAGIC) {
xfs_error("Leaf's magic number does not match!");
- goto out1;
+ goto out;
}
if (!leaf->hdr.count ||
XFS_PVT(inode)->i_leaf_ent_offset >= be16_to_cpu(leaf->hdr.count)) {
XFS_PVT(inode)->i_btree_offset++;
XFS_PVT(inode)->i_leaf_ent_offset = 0;
- free(leaf);
goto try_next_btree;
}
@@ -347,7 +344,6 @@ try_next_btree:
if (XFS_PVT(inode)->i_leaf_ent_offset == be16_to_cpu(leaf->hdr.count)) {
XFS_PVT(inode)->i_btree_offset++;
XFS_PVT(inode)->i_leaf_ent_offset = 0;
- free(leaf);
goto try_next_btree;
} else {
XFS_PVT(inode)->i_leaf_ent_offset++;
@@ -358,14 +354,14 @@ try_next_btree:
fsblkno = xfs_dir2_get_right_blk(fs, core, db, &error);
if (error) {
xfs_error("Cannot find data block!");
- goto out1;
+ goto out;
}
- buf = xfs_dir2_get_dirblks(fs, fsblkno, 1);
+ buf = xfs_dir2_dirblks_get_cached(fs, fsblkno, 1);
data_hdr = (xfs_dir2_data_hdr_t *)buf;
if (be32_to_cpu(data_hdr->magic) != XFS_DIR2_DATA_MAGIC) {
xfs_error("Leaf directory's data magic No. does not match!");
- goto out2;
+ goto out;
}
offset = xfs_dir2_dataptr_to_off(fs, be32_to_cpu(lep->address));
@@ -374,28 +370,16 @@ try_next_btree:
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
- name = xfs_dir2_get_entry_name(start_name, end_name);
- retval = fill_dirent(fs, dirent, 0, be64_to_cpu(dep->inumber), name,
- end_name - start_name);
+ retval = fill_dirent(fs, dirent, 0, be64_to_cpu(dep->inumber),
+ (char *)start_name, end_name - start_name);
if (retval)
xfs_error("Failed to fill in dirent structure");
- free(name);
- free(buf);
- free(leaf);
- free(node);
-
return retval;
-out2:
- free(buf);
-
-out1:
- free(leaf);
-
out:
- free(node);
+ xfs_dir2_dirblks_flush_cache();
XFS_PVT(inode)->i_btree_offset = 0;
XFS_PVT(inode)->i_leaf_ent_offset = 0;
diff --git a/core/include/bios.h b/core/include/bios.h
index 9334c41a..7bbd274c 100644
--- a/core/include/bios.h
+++ b/core/include/bios.h
@@ -20,6 +20,8 @@
#ifndef _BIOS_H
#define _BIOS_H
+#include <sys/io.h>
+
/*
* Interrupt vectors
*/
diff --git a/core/include/fs.h b/core/include/fs.h
index 554dc97f..560458b6 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -7,6 +7,7 @@
#include <com32.h>
#include <stdio.h>
#include <sys/dirent.h>
+#include <dprintf.h>
#include "core.h"
#include "disk.h"
@@ -158,6 +159,8 @@ static inline void free_inode(struct inode * inode)
static inline struct inode *get_inode(struct inode *inode)
{
inode->refcnt++;
+ dprintf("get_inode %p name %s refcnt %d\n",
+ inode, inode->name, inode->refcnt);
return inode;
}
diff --git a/core/init.inc b/core/init.inc
index 995f9825..b74cf30b 100644
--- a/core/init.inc
+++ b/core/init.inc
@@ -47,17 +47,17 @@ common_init:
;
; The code to decompress the PM code and initialize other segments.
;
- extern _lzo1x_decompress_asm_fast
+ extern _lzo1x_decompress_asm_fast_safe
section .textnr
bits 32
pm_decompress:
- push 0 ; Space for decompressed size
+ push __pm_code_len + 16 ; Space for decompressed size
push esp ; Pointer to previous word
push __pm_code_start ; Target address
push dword [lzo_data_size] ; Compressed size
push dword __pm_code_lma
- call _lzo1x_decompress_asm_fast
+ call _lzo1x_decompress_asm_fast_safe
add esp,16
pop RM_EAX ; Decompressed size
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 673134b0..b54beb4a 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -433,7 +433,9 @@ MaxLMA equ 384*1024 ; Reasonable limit (384K)
.ok:
xor bx,bx
push bp
+ push eax
call getlinsec
+ pop eax
pop cx
mov dx,cx
pop bp
@@ -441,6 +443,7 @@ MaxLMA equ 384*1024 ; Reasonable limit (384K)
shl cx,SECTOR_SHIFT - 4
add bx,cx
+ add eax,edx
sub bp,dx
jnz .more
diff --git a/core/lzo/enter.ash b/core/lzo/enter.ash
index e865c4cb..dc7782fd 100644
--- a/core/lzo/enter.ash
+++ b/core/lzo/enter.ash
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
diff --git a/core/lzo/leave.ash b/core/lzo/leave.ash
index f77e2efd..cc48ce6b 100644
--- a/core/lzo/leave.ash
+++ b/core/lzo/leave.ash
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
diff --git a/core/lzo/lzo1c_d.ash b/core/lzo/lzo1c_d.ash
index 9969c86a..56622ab5 100644
--- a/core/lzo/lzo1c_d.ash
+++ b/core/lzo/lzo1c_d.ash
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
diff --git a/core/lzo/lzo1f_d.ash b/core/lzo/lzo1f_d.ash
index aa9279e0..97a103c0 100644
--- a/core/lzo/lzo1f_d.ash
+++ b/core/lzo/lzo1f_d.ash
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
diff --git a/core/lzo/lzo1x_d.ash b/core/lzo/lzo1x_d.ash
index aa138354..782b47fe 100644
--- a/core/lzo/lzo1x_d.ash
+++ b/core/lzo/lzo1x_d.ash
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
diff --git a/core/lzo/lzo1x_f1.S b/core/lzo/lzo1x_f2.S
index 8360e34a..8cc26b8b 100644
--- a/core/lzo/lzo1x_f1.S
+++ b/core/lzo/lzo1x_f2.S
@@ -1,7 +1,10 @@
-/* lzo1x_f1.S -- fast LZO1X decompression in assembler (i386 + gcc)
+/* lzo1x_f2.S -- fast LZO1X decompression in assembler (i386 + gcc)
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -44,17 +47,21 @@
#define LZO_FAST
+#define LZO_TEST_DECOMPRESS_OVERRUN_INPUT
+#define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT
+#define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
+
#include "lzo_asm.h"
.section ".textnr","ax"
- LZO_PUBLIC(lzo1x_decompress_asm_fast)
+ LZO_PUBLIC(lzo1x_decompress_asm_fast_safe)
#include "enter.ash"
#include "lzo1x_d.ash"
#include "leave.ash"
- LZO_PUBLIC_END(lzo1x_decompress_asm_fast)
+ LZO_PUBLIC_END(lzo1x_decompress_asm_fast_safe)
/*
diff --git a/core/lzo/lzo_asm.h b/core/lzo/lzo_asm.h
index 5e870b85..663ca1a0 100644
--- a/core/lzo/lzo_asm.h
+++ b/core/lzo/lzo_asm.h
@@ -2,6 +2,9 @@
This file is part of the LZO real-time data compression library.
+ Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
@@ -54,17 +57,17 @@
#else
/* manual configuration - see defaults below */
# if defined(__ELF__)
-# define MFX_ASM_HAVE_TYPE
-# define MFX_ASM_NAME_NO_UNDERSCORES
+# define MFX_ASM_HAVE_TYPE 1
+# define MFX_ASM_NAME_NO_UNDERSCORES 1
# elif defined(__linux__) /* Linux a.out */
-# define MFX_ASM_ALIGN_PTWO
+# define MFX_ASM_ALIGN_PTWO 1
# elif defined(__DJGPP__)
-# define MFX_ASM_ALIGN_PTWO
+# define MFX_ASM_ALIGN_PTWO 1
# elif defined(__GO32__) /* djgpp v1 */
-# define MFX_ASM_CANNOT_USE_EBP
+# define MFX_ASM_CANNOT_USE_EBP 1
# elif defined(__EMX__)
-# define MFX_ASM_ALIGN_PTWO
-# define MFX_ASM_CANNOT_USE_EBP
+# define MFX_ASM_ALIGN_PTWO 1
+# define MFX_ASM_CANNOT_USE_EBP 1
# endif
#endif
#endif
@@ -125,7 +128,7 @@
************************************************************************/
#if !defined(MFX_ASM_ALIGN_BYTES) && !defined(MFX_ASM_ALIGN_PTWO)
-# define MFX_ASM_ALIGN_BYTES
+# define MFX_ASM_ALIGN_BYTES 1
#endif
#if !defined(LZO_ASM_ALIGN)
@@ -147,10 +150,10 @@
#if !defined(MFX_ASM_CANNOT_USE_EBP)
# if 1 && !defined(N_3_EBP) && !defined(N_255_EBP)
-# define N_3_EBP
+# define N_3_EBP 1
# endif
# if 0 && !defined(N_3_EBP) && !defined(N_255_EBP)
-# define N_255_EBP
+# define N_255_EBP 1
# endif
#endif
diff --git a/core/mem/malloc.c b/core/mem/malloc.c
index a3d6b45d..c439dcbb 100644
--- a/core/mem/malloc.c
+++ b/core/mem/malloc.c
@@ -175,6 +175,8 @@ void *bios_realloc(void *ptr, size_t size)
ARENA_TYPE_SET(nah->a.attrs, ARENA_TYPE_FREE);
ARENA_SIZE_SET(nah->a.attrs, xsize - newsize);
ARENA_SIZE_SET(ah->a.attrs, newsize);
+ ARENA_HEAP_SET(nah->a.attrs, ARENA_HEAP_GET(ah->a.attrs));
+
//nah->a.type = ARENA_TYPE_FREE;
//nah->a.size = xsize - newsize;
//ah->a.size = newsize;
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 95f76617..841f69f5 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -289,10 +289,12 @@ KernelType resb 1 ; Kernel type, from vkernel, if known
global KernelName
KernelName resb FILENAME_MAX ; Mangled name for kernel
section .data16
- extern IPOption
+ extern IPOption, BOOTIFStr, SYSUUIDStr
global IPAppends, numIPAppends
alignz 2
IPAppends dw IPOption
+ dw BOOTIFStr
+ dw SYSUUIDStr
numIPAppends equ ($-IPAppends)/2
section .text16
diff --git a/dos/argv.c b/dos/argv.c
index 056aae59..da283666 100644
--- a/dos/argv.c
+++ b/dos/argv.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2013 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
@@ -28,48 +29,81 @@
/*
* argv.c
*
- * Parse a single C string into argc and argv (argc is return value.)
+ * Parse the MS-DOS command line into argc and argv (argc is return value.)
* memptr points to available memory.
*/
#include <inttypes.h>
#include <stddef.h>
-#include <stdio.h>
+#include <stdbool.h>
+#include "mystuff.h"
#define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1)))
extern char __heap_start[];
void *__mem_end = &__heap_start; /* Global variable for use by malloc() */
-int __parse_argv(char ***argv, const char *str)
+int __parse_argv(char ***argv)
{
char *mem = __mem_end;
- const char *p = str;
+ const char *str, *p;
char *q = mem;
- char *r;
+ char c, *r;
char **arg;
- int wasspace = 0;
- int argc = 1;
+ bool wasspace;
+ int argc;
+ int len;
+ size_t offs;
+ int nulls;
+ uint16_t nstr;
- /* First copy the string, turning whitespace runs into nulls */
+ /* Find and copy argv[0] after the environment block */
+ set_fs(_PSP.environment);
+ offs = 0;
+ nulls = 0;
+ do {
+ if (get_8_fs(offs++) == '\0')
+ nulls++;
+ else
+ nulls = 0;
+ } while (nulls < 2);
+
+ nstr = get_16_fs(offs);
+ offs += 2;
+
+ /* Copy the null-terminated filename string */
+ if (nstr >= 1) {
+ while ((c = get_8_fs(offs++)))
+ *q++ = c;
+ }
+ *q++ = '\0';
+
+ /* Now for the command line tail... */
+
+ len = _PSP.cmdlen;
+ str = _PSP.cmdtail;
+ argc = 1;
+ wasspace = true;
+
+ /* Copy the command tail, turning whitespace runs into nulls */
for (p = str;; p++) {
- if (*p <= ' ') {
+ if (!len || *p <= ' ') {
if (!wasspace) {
- wasspace = 1;
+ wasspace = true;
*q++ = '\0';
}
} else {
if (wasspace) {
argc++;
- wasspace = 0;
+ wasspace = false;
}
*q++ = *p;
}
- /* This test is AFTER we have processed the null byte;
+ /* This test is AFTER we have processed the end byte;
we treat it as a whitespace character so it terminates
the last argument */
- if (!*p)
+ if (!len--)
break;
}
@@ -78,7 +112,7 @@ int __parse_argv(char ***argv, const char *str)
*argv = arg;
*arg++ = mem; /* argv[0] */
- q--; /* Point q to final null */
+ q--; /* Point q to terminal character */
for (r = mem; r < q; r++) {
if (*r == '\0') {
*arg++ = r + 1;
diff --git a/dos/crt0.S b/dos/crt0.S
index 3be57125..66b52c06 100644
--- a/dos/crt0.S
+++ b/dos/crt0.S
@@ -9,7 +9,7 @@
.type _start,@function
_start:
# Align the stack and make sure the high half is zero
- andl $0xfff8,%esp
+ andl $0xfffc,%esp
# DS, ES points to the PSP at this point
pushw %es # Save PSP pointer
@@ -26,16 +26,27 @@ _start:
shrw $2,%cx
rep ; stosl
- # Copy the command line into our own segment
+ # Copy the PSP into our own segment
popw %fs # FS -> PSP
- movw $_cmdline,%di
- movzbw %fs:0x80,%cx
- movw $0x81,%si
- fs ; rep ; movsb
- # Already zero-terminated since we're writing into clean bss
+ movw $_PSP,%di
+ xorw %si,%si
+ movw $0x40,%cx
+ fs ; rep ; movsl
+ # Verify that this is a supportable DOS version
+ movw $0x3001,%ax
+ int $0x21
+ xchgb %ah,%al
+ movw %ax,dos_version
+ cmpw $0x0314,%ax # DOS >= 3.20?
+ jae 1f # If so, okay
+ movw $bad_dos,%dx # Print error message
+ movb $0x09,%ah
+ int $0x21
+ int $0x20 # Die
+
+1:
# Compute argc and argv (assumes REGPARM)
- movl $_cmdline,%edx
pushl %eax # Make space for argv
movl %esp,%eax
calll __parse_argv
@@ -44,7 +55,7 @@ _start:
# Initialize malloc
calll __init_memory_arena
- # Now call main... (NOTE: gcc forces main to be regparm 0)
+ # Now call main
popl %eax # argc
popl %edx # argv
calll main
@@ -63,8 +74,18 @@ exit:
jmp 1b
.size exit,.-exit
+ .section ".rodata","a"
+bad_dos:
+ .ascii "Unsupported DOS version\r\n$"
+ .size bad_dos,.-bad_dos
+
.section ".bss","aw"
- .balign 4
-_cmdline:
- .space 128
- .size _cmdline,.-_cmdline
+ .balign 16
+ .globl _PSP
+_PSP:
+ .space 256
+ .size _PSP, .-_PSP
+
+ /* Purely for sanity */
+ .section ".null","a"
+ .long 0,0,0,0
diff --git a/dos/dosexe.ld b/dos/dosexe.ld
index bd6ad8ba..733f73d8 100644
--- a/dos/dosexe.ld
+++ b/dos/dosexe.ld
@@ -35,16 +35,23 @@ SECTIONS
__payload_len = ABSOLUTE(__payload_end) - ABSOLUTE(__payload_start);
__payload_dwords = __payload_len >> 2;
- __text_lma = __payload_lma + syslinux_size;
- __payload_sseg = (__payload_lma - __text_lma) >> 4;
- _exe_text_seg = (__text_lma - __header_size) >> 4;
+ __dgroup_lma = __payload_lma + syslinux_size;
+ __payload_sseg = (__payload_lma - __dgroup_lma) >> 4;
+ _exe_text_seg = (__dgroup_lma - __header_size) >> 4;
/*
* __assert1 = ASSERT((__payload_len == syslinux_ldlinux_size),
* "syslinux_size must equal the size of .payload");
*/
. = 0;
- .text : AT (__text_lma) {
+ __null = .;
+ .null : AT(__dgroup_lma) {
+ *(.null)
+ }
+
+ . = ALIGN(16);
+ __text_vma = .;
+ .text : AT (__text_vma + __dgroup_lma) {
*(.text .stub .text.* .gnu.linkonce.t.*)
*(.gnu.warning)
} =0x90909090
@@ -52,7 +59,7 @@ SECTIONS
. = ALIGN(16);
__rodata_vma = .;
- .rodata : AT (__rodata_vma + __text_lma) {
+ .rodata : AT (__rodata_vma + __dgroup_lma) {
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
@@ -60,15 +67,15 @@ SECTIONS
data within same 128-byte chunk. */
. = ALIGN(128);
__data_vma = .;
- .data : AT (__data_vma + __text_lma) {
+ .data : AT (__data_vma + __dgroup_lma) {
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .;
- _exe_edata_low = ((_edata + __text_lma) & 511);
- _exe_edata_blocks = ((_edata + __text_lma) + 511) >> 9;
+ _exe_edata_low = ((_edata + __dgroup_lma) & 511);
+ _exe_edata_blocks = ((_edata + __dgroup_lma) + 511) >> 9;
.bss (NOLOAD) : {
__bss_start = .;
diff --git a/dos/getsetsl.c b/dos/getsetsl.c
index 67e954d1..fadef438 100644
--- a/dos/getsetsl.c
+++ b/dos/getsetsl.c
@@ -11,15 +11,23 @@
#include <stdlib.h>
#include "syslxint.h"
+#include "mystuff.h"
-#define __noinline __attribute__((noinline))
+static inline void *set_fs_sl(const void *p)
+{
+ uint16_t seg;
+
+ seg = ds() + ((size_t) p >> 4);
+ set_fs(seg);
+ return (void *)((size_t) p & 0xf);
+}
#if 0 /* unused */
uint8_t get_8_sl(const uint8_t * p)
{
uint8_t v;
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movb %%fs:%1,%0":"=q" (v):"m"(*p));
return v;
}
@@ -29,7 +37,7 @@ uint16_t get_16_sl(const uint16_t * p)
{
uint16_t v;
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movw %%fs:%1,%0":"=r" (v):"m"(*p));
return v;
}
@@ -38,7 +46,7 @@ uint32_t get_32_sl(const uint32_t * p)
{
uint32_t v;
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movl %%fs:%1,%0":"=r" (v):"m"(*p));
return v;
}
@@ -47,7 +55,7 @@ uint32_t get_32_sl(const uint32_t * p)
uint64_t get_64_sl(const uint64_t * p)
{
uint32_t v0, v1;
- const uint32_t *pp = (const uint32_t *)set_fs(p);
+ const uint32_t *pp = (const uint32_t *)set_fs_sl(p);
asm volatile("movl %%fs:%1,%0" : "=r" (v0) : "m" (pp[0]));
asm volatile("movl %%fs:%1,%0" : "=r" (v1) : "m" (pp[1]));
@@ -58,26 +66,26 @@ uint64_t get_64_sl(const uint64_t * p)
#if 0 /* unused */
void set_8_sl(uint8_t * p, uint8_t v)
{
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movb %1,%%fs:%0":"=m" (*p):"qi"(v));
}
#endif
void set_16_sl(uint16_t * p, uint16_t v)
{
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movw %1,%%fs:%0":"=m" (*p):"ri"(v));
}
void set_32_sl(uint32_t * p, uint32_t v)
{
- p = set_fs(p);
+ p = set_fs_sl(p);
asm volatile("movl %1,%%fs:%0":"=m" (*p):"ri"(v));
}
void set_64_sl(uint64_t * p, uint64_t v)
{
- uint32_t *pp = (uint32_t *)set_fs(p);
+ uint32_t *pp = (uint32_t *)set_fs_sl(p);
asm volatile("movl %1,%%fs:%0" : "=m" (pp[0]) : "ri"((uint32_t)v));
asm volatile("movl %1,%%fs:%0" : "=m" (pp[1]) : "ri"((uint32_t)(v >> 32)));
}
diff --git a/dos/mystuff.h b/dos/mystuff.h
index 25344413..2d9574d6 100644
--- a/dos/mystuff.h
+++ b/dos/mystuff.h
@@ -2,8 +2,7 @@
#define MYSTUFF_H
#include <inttypes.h>
-
-#define NULL ((void *)0)
+#include <stddef.h>
unsigned int skip_atou(const char **s);
unsigned int atou(const char *s);
@@ -21,4 +20,60 @@ struct diskio {
int int25_read_sector(unsigned char drive, struct diskio *dio);
int int26_write_sector(unsigned char drive, struct diskio *dio);
+struct psp {
+ uint16_t int20;
+ uint16_t nextpara;
+ uint8_t resv1;
+ uint8_t dispatcher[5];
+ uint32_t termvector;
+ uint32_t ctrlcvector;
+ uint32_t criterrvector;
+ uint16_t resv2[11];
+ uint16_t environment;
+ uint16_t resv3[23];
+ uint8_t fcb[2][16];
+ uint32_t resv4;
+ uint8_t cmdlen;
+ char cmdtail[127];
+} __attribute__((packed));
+
+extern struct psp _PSP;
+
+static inline __attribute__((const))
+uint16_t ds(void)
+{
+ uint16_t v;
+ asm("movw %%ds,%0":"=rm"(v));
+ return v;
+}
+
+static inline void set_fs(uint16_t seg)
+{
+ asm volatile("movw %0,%%fs"::"rm" (seg));
+}
+
+static inline uint8_t get_8_fs(size_t offs)
+{
+ uint8_t v;
+ asm volatile("movb %%fs:%1,%0"
+ : "=q" (v) : "m" (*(const uint8_t *)offs));
+ return v;
+}
+
+static inline uint16_t get_16_fs(size_t offs)
+{
+ uint16_t v;
+ asm volatile("movw %%fs:%1,%0"
+ : "=r" (v) : "m" (*(const uint16_t *)offs));
+ return v;
+}
+
+static inline uint32_t get_32_fs(size_t offs)
+{
+ uint32_t v;
+ asm volatile("movl %%fs:%1,%0"
+ : "=r" (v) : "m" (*(const uint32_t *)offs));
+ return v;
+}
+
#endif /* MYSTUFF_H */
diff --git a/dos/syslinux.c b/dos/syslinux.c
index eb8bace6..63a3a854 100644
--- a/dos/syslinux.c
+++ b/dos/syslinux.c
@@ -41,7 +41,7 @@ uint16_t dos_version;
void pause(void)
{
uint16_t ax;
-
+
asm volatile("int $0x16" : "=a" (ax) : "a" (0));
}
#else
@@ -187,7 +187,7 @@ void write_device(int drive, const void *buf, size_t nsecs, unsigned int sector)
dio.sectors = nsecs;
dio.bufoffs = (uintptr_t) buf;
dio.bufseg = data_segment();
-
+
if (dos_version >= 0x070a) {
/* Try FAT32-aware system call first */
asm volatile("int $0x21 ; jc 1f ; xorw %0,%0\n"
@@ -220,7 +220,7 @@ void read_device(int drive, void *buf, size_t nsecs, unsigned int sector)
dio.sectors = nsecs;
dio.bufoffs = (uintptr_t) buf;
dio.bufseg = data_segment();
-
+
if (dos_version >= 0x070a) {
/* Try FAT32-aware system call first */
asm volatile("int $0x21 ; jc 1f ; xorw %0,%0\n"
@@ -402,14 +402,6 @@ int libfat_xpread(intptr_t pp, void *buf, size_t secsize,
static inline void get_dos_version(void)
{
- uint16_t ver;
-
- asm("int $0x21 ; xchgb %%ah,%%al"
- : "=a" (ver)
- : "a" (0x3001)
- : "ebx", "ecx");
- dos_version = ver;
-
dprintf("DOS version %d.%d\n", (dos_version >> 8), dos_version & 0xff);
}
@@ -475,7 +467,7 @@ soft_fail:
if (hard_lock) {
/* Hard locking, only level 4 supported */
/* This is needed for Win9x in DOS mode */
-
+
err = do_lock(4);
if (err) {
if (err == 0x0001) {
diff --git a/extlinux/main.c b/extlinux/main.c
index e925a1d8..9ee9abb4 100644
--- a/extlinux/main.c
+++ b/extlinux/main.c
@@ -440,13 +440,11 @@ int install_bootblock(int fd, const char *device)
return 0;
}
-static int rewrite_boot_image(int devfd, const char *filename)
+static int rewrite_boot_image(int devfd, const char *path, const char *filename)
{
int fd;
int ret;
int modbytes;
- char path[PATH_MAX];
- char slash;
/* Let's create LDLINUX.SYS file again (if it already exists, of course) */
fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
@@ -470,8 +468,6 @@ static int rewrite_boot_image(int devfd, const char *filename)
goto error;
}
- sscanf(filename, "%s%cldlinux.sys", path, &slash);
-
/* Map the file, and patch the initial sector accordingly */
modbytes = patch_file_and_bootblock(fd, path, devfd);
@@ -525,7 +521,7 @@ int ext2_fat_install_file(const char *path, int devfd, struct stat *rst)
}
close(fd);
- fd = rewrite_boot_image(devfd, file);
+ fd = rewrite_boot_image(devfd, path, file);
if (fd < 0)
goto bail;
@@ -648,12 +644,16 @@ int btrfs_install_file(const char *path, int devfd, struct stat *rst)
*/
static int xfs_install_file(const char *path, int devfd, struct stat *rst)
{
- static char file[PATH_MAX];
+ static char file[PATH_MAX + 1];
+ static char c32file[PATH_MAX + 1];
int dirfd = -1;
int fd = -1;
+ int retval;
- snprintf(file, PATH_MAX, "%s%sldlinux.sys",
- path, path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+ snprintf(file, PATH_MAX + 1, "%s%sldlinux.sys", path,
+ path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
+ snprintf(c32file, PATH_MAX + 1, "%s%sldlinux.c32", path,
+ path[0] && path[strlen(path) - 1] == '/' ? "" : "/");
dirfd = open(path, O_RDONLY | O_DIRECTORY);
if (dirfd < 0) {
@@ -673,7 +673,7 @@ static int xfs_install_file(const char *path, int devfd, struct stat *rst)
close(fd);
- fd = rewrite_boot_image(devfd, file);
+ fd = rewrite_boot_image(devfd, path, file);
if (fd < 0)
goto bail;
@@ -689,6 +689,26 @@ static int xfs_install_file(const char *path, int devfd, struct stat *rst)
close(dirfd);
close(fd);
+ dirfd = -1;
+ fd = -1;
+
+ fd = open(c32file, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC,
+ S_IRUSR | S_IRGRP | S_IROTH);
+ if (fd < 0) {
+ perror(c32file);
+ goto bail;
+ }
+
+ retval = xpwrite(fd, syslinux_ldlinuxc32, syslinux_ldlinuxc32_len, 0);
+ if (retval != (int)syslinux_ldlinuxc32_len) {
+ fprintf(stderr, "%s: write failure on %s\n", program, file);
+ goto bail;
+ }
+
+ close(fd);
+
+ sync();
+
return 0;
bail:
diff --git a/libinstaller/syslxint.h b/libinstaller/syslxint.h
index e5428b79..59e3e5ef 100644
--- a/libinstaller/syslxint.h
+++ b/libinstaller/syslxint.h
@@ -124,23 +124,6 @@ static inline void set_64(uint64_t *p, uint64_t v)
*/
#ifdef __MSDOS__
-static inline __attribute__ ((const))
-uint16_t ds(void)
-{
- uint16_t v;
- asm("movw %%ds,%0":"=rm"(v));
- return v;
-}
-
-static inline void *set_fs(const void *p)
-{
- uint16_t seg;
-
- seg = ds() + ((size_t) p >> 4);
- asm volatile ("movw %0,%%fs"::"rm" (seg));
- return (void *)((size_t) p & 0xf);
-}
-
uint8_t get_8_sl(const uint8_t * p);
uint16_t get_16_sl(const uint16_t * p);
uint32_t get_32_sl(const uint32_t * p);
diff --git a/mk/elf.mk b/mk/elf.mk
index 76b5487e..bd8775cf 100644
--- a/mk/elf.mk
+++ b/mk/elf.mk
@@ -47,7 +47,7 @@ com32 = $(topdir)/com32
core = $(topdir)/core
ifneq ($(NOGPL),1)
-GPLLIB = $(objdir)/com32/gpllib/libcom32gpl.c32
+GPLLIB = $(objdir)/com32/gpllib/libgpl.c32
GPLINCLUDE = -I$(com32)/gplinclude
else
GPLLIB =
@@ -68,7 +68,7 @@ LNXCFLAGS = -I$(com32)/libutil/include -W -Wall -O -g -D_GNU_SOURCE
LNXSFLAGS = -g
LNXLDFLAGS = -g
-C_LIBS = $(objdir)/com32/libutil/libutil_com.c32 $(GPLLIB) \
+C_LIBS = $(objdir)/com32/libutil/libutil.c32 $(GPLLIB) \
$(objdir)/com32/lib/libcom32.c32
C_LNXLIBS = $(objdir)/com32/libutil/libutil_lnx.a \
$(objdir)/com32/elflink/ldlinux/ldlinux_lnx.a
@@ -95,5 +95,9 @@ C_LNXLIBS = $(objdir)/com32/libutil/libutil_lnx.a \
%.lnx: %.lo $(LNXLIBS) $(C_LNXLIBS)
$(CC) $(LNXCFLAGS) -o $@ $^
-%.c32: %.o $(C_LIBS)
+.PRECIOUS: %.elf
+%.elf: %.o $(C_LIBS)
$(LD) $(LDFLAGS) -o $@ $^
+
+%.c32: %.elf
+ $(OBJCOPY) --strip-debug --strip-unneeded $< $@
diff --git a/mk/lib.mk b/mk/lib.mk
index 499a13b6..94502777 100644
--- a/mk/lib.mk
+++ b/mk/lib.mk
@@ -161,7 +161,7 @@ LIBLOAD_OBJS = \
LIBMODULE_OBJS = \
sys/module/common.o sys/module/$(ARCH)/elf_module.o \
- sys/module/$(ARCH)/shallow_module.o sys/module/elfutils.o \
+ sys/module/elfutils.o \
sys/module/exec.o sys/module/elf_module.o
# ZIP library object files
@@ -237,3 +237,6 @@ LDFLAGS = -m elf_$(ARCH) --hash-style=gnu -T $(com32)/lib/$(ARCH)/elf.ld
.c.ls:
$(CC) $(MAKEDEPS) $(CFLAGS) $(SOFLAGS) -S -o $@ $<
+
+%.c32: %.elf
+ $(OBJCOPY) --strip-debug --strip-unneeded $< $@
diff --git a/txt/.gitignore b/txt/.gitignore
new file mode 100644
index 00000000..55c60417
--- /dev/null
+++ b/txt/.gitignore
@@ -0,0 +1,7 @@
+*.1
+*.5
+*.html
+*.pdf
+*.text
+*.xml
+docbook-xsl.css
diff --git a/txt/Makefile b/txt/Makefile
new file mode 100644
index 00000000..0e4cfb45
--- /dev/null
+++ b/txt/Makefile
@@ -0,0 +1,113 @@
+## -----------------------------------------------------------------------
+##
+## Copyright 2012 Gene Cumm
+##
+## Some logic from win32/Makefile:
+## Copyright 1998-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2010 Intel Corporation; author: H. Peter Anvin
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+## Boston MA 02111-1307, USA; either version 2 of the License, or
+## (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## AsciiDoc documentation for syslinux
+##
+
+topdir = ..
+MAKEDIR = $(topdir)/mk
+# include $(MAKEDIR)/embedded.mk
+
+VPATH = $(SRC)
+
+A2X_OPTS = -k
+# A2X_OPTS += -v
+A2X_MAN_OPTS = -D man -f manpage
+
+DOCS = syslinux.txt syslinux-cli.txt syslinux.cfg.txt
+MAN_DOCS = man/syslinux.1 man/syslinux-cli.1 man/syslinux.cfg.5
+HTML_DOCS := $(patsubst %.txt,html/%.html,$(DOCS))
+XHTML_DOCS := $(patsubst %.txt,%.html,$(DOCS))
+# MAN_DOCS := $(patsubst %.txt,man/%.1,$(DOCS1)) $(patsubst %.txt,man/%.5,$(DOCS5))
+TEXT_DOCS := $(patsubst %.txt,%.text,$(DOCS))
+PDF_DOCS := $(patsubst %.txt,%.pdf,$(DOCS))
+TARGETS =
+
+# ASCIIDOC_OK := $(shell which asciidoc 2>&1 ; echo $$?)
+ASCIIDOC_OK := $(shell which asciidoc > /dev/null ; echo $$?)
+A2X_XML_OK := $(shell a2x $(A2X_OPTS) -f docbook hello.txt 2>&1 ; echo $$?)
+ifeq ($(A2X_XML_OK),0)
+A2X_MAN_OK := $(shell [ ! -d man ] && mkdir man ; a2x $(A2X_MAN_OPTS) hello.txt 2>&1 ; echo $$?)
+A2X_XHTML_OK := $(shell a2x $(A2X_OPTS) -f xhtml hello.xml 2>&1 ; echo $$?)
+A2X_TEXT_OK := $(shell a2x $(A2X_OPTS) -f text hello.xml 2>&1 ; echo $$?)
+endif
+
+ifeq ($(ASCIIDOC_OK),0)
+TARGETS += $(HTML_DOCS)
+endif
+ifeq ($(A2X_MAN_OK),0)
+TARGETS += $(MAN_DOCS)
+endif
+ifeq ($(A2X_XHTML_OK),0)
+TARGETS += $(XHTML_DOCS)
+endif
+ifeq ($(A2X_TEXT_OK),0)
+TARGETS += $(TEXT_DOCS)
+endif
+
+# $(HTML_DOCS) $(MAN_DOCS) $(XHTML_DOCS) $(TEXT_DOCS)
+all: $(TARGETS)
+
+syslinux.cfg.txt: com-bug.txt com-rpt.txt
+
+# During 'make all', *.xml is kept but deleted at the end; do we _really_
+# need the XML longer?
+.PRECIOUS: %.xml
+
+# %.html: %.txt
+# asciidoc -D html $<
+
+html/ man/ text/ xhtml/:
+ mkdir $@
+
+html/%.html: %.txt html/
+ asciidoc -o $@ $<
+
+# As of AsciiDoc-8.5.2, altering the output filename for a2x does not appear possible
+# xhtml/%.html: %.txt
+# a2x $(A2X_OPTS) -D xhtml -f xhtml $<
+# text/%.text: %.xml %.txt
+# a2x $(A2X_OPTS) -D text -f text $<
+
+%.xml: %.txt
+ a2x $(A2X_OPTS) -f docbook $<
+
+# when %.xml is missing, an update to %.txt must force regeneration
+%.html: %.xml %.txt
+ a2x $(A2X_OPTS) -f xhtml $<
+
+man/%.1: %.txt man/
+ a2x $(A2X_MAN_OPTS) $<
+
+man/%.5: %.txt man/
+ a2x $(A2X_MAN_OPTS) $<
+
+%.text: %.xml %.txt
+ a2x $(A2X_OPTS) -f text $<
+
+%.pdf: %.xml %.txt
+ a2x $(A2X_OPTS) -f pdf $<
+
+tidy dist:
+ rm -f *~ *.xml *.text.html text/*.text.html text/*.xml xhtml/*.xml
+
+clean: tidy
+
+spotless: clean
+ rm -f *.1 *.5 *.css *.html *.text html/*.html man/*.1 man/*.5 text/*.text xhtml/*.html xhtml/*.css
+
+-include .*.d
diff --git a/txt/com-bug.txt b/txt/com-bug.txt
new file mode 100644
index 00000000..f16139a0
--- /dev/null
+++ b/txt/com-bug.txt
@@ -0,0 +1,11 @@
+
+// == KNOWN BUGS ==
+
+Several known bugs/common problems are listed at
+http://www.syslinux.org/wiki/index.php/Common_Problems and known
+hardware compatibility issues are listed at
+http://www.syslinux.org/wiki/index.php/Hardware_Compatibility with
+filename translation difficulty and early PXE stacks being some of the
+most common. Reporting of other encountered issues is welcome and
+appreciated.
+
diff --git a/txt/com-name.txt b/txt/com-name.txt
new file mode 100644
index 00000000..b24811f2
--- /dev/null
+++ b/txt/com-name.txt
@@ -0,0 +1,12 @@
+
+// == NAMING CONVENTION ==
+
+As of 3.73, a standard for naming conventions was adopted to more
+clearly distinguish different aspects. The moniker "The *Syslinux*
+Project", in standard proper noun capitalization, shall be used to refer
+to the project as a whole. The all-caps form shall be used to refer to a
+particular loader variant such as "*SYSLINUX*" for the standard disk
+(floppy/hard disk; formerly just FAT) loader. The all-lower case form
+should be used to refer to a particular installer such as
+"syslinux-mtools" for the mtools-based installer for *SYSLINUX*.
+
diff --git a/txt/com-rpt.txt b/txt/com-rpt.txt
new file mode 100644
index 00000000..fe368eee
--- /dev/null
+++ b/txt/com-rpt.txt
@@ -0,0 +1,22 @@
+
+// == BUG REPORTS ==
+
+I would appreciate hearing of any problems you have with Syslinux. I
+would also like to hear from you if you have successfully used Syslinux,
+*especially* if you are using it for a distribution.
+
+If you are reporting problems, please include all possible information
+about your system and your BIOS; the vast majority of all problems
+reported turn out to be BIOS or hardware bugs, and I need as much
+information as possible in order to diagnose the problems.
+
+There is a mailing list for discussion among Syslinux users and for
+announcements of new and test versions. To join, or to browse the
+archive, go to:
+
+http://www.zytor.com/mailman/listinfo/syslinux
+
+Please DO NOT send HTML messages or attachments to the mailing list
+(including multipart/alternative or similar.) All such messages will be
+bounced.
+
diff --git a/txt/hello.txt b/txt/hello.txt
new file mode 100644
index 00000000..37576277
--- /dev/null
+++ b/txt/hello.txt
@@ -0,0 +1,16 @@
+= hello(1) =
+:doctype: manpage
+:author: World Greeter
+:author-email: hello@domain.local
+:revdate: 1970-01-01
+:data-uri:
+
+
+== NAME ==
+hello - hello world
+
+== SYNOPSIS ==
+hello
+
+== Description ==
+Say hello and greet the world
diff --git a/txt/syslinux-cli.txt b/txt/syslinux-cli.txt
new file mode 100644
index 00000000..fa6a4dc5
--- /dev/null
+++ b/txt/syslinux-cli.txt
@@ -0,0 +1,65 @@
+= syslinux-cli(1) =
+:doctype: manpage
+:revdate: 2012-11-10
+:author: H. Peter Anvin
+:author-email: hpa@zytor.com
+:editor1: Gene Cumm
+:editor1-email: gene.cumm@gmail.com
+:editor1-revlast: 2012-11-10
+:data-uri:
+
+== NAME ==
+syslinux-cli - *Syslinux* boot prompt/command line interface
+
+
+== DESCRIPTION ==
+*Syslinux*'s boot prompt provides a very simplistic command line
+interface for loading modules and booting kernels.
+
+
+== BOOT PROMPT ==
+=== COMMAND LINE KEYSTROKES ===
+The command line prompt supports the following keystrokes:
+
+ <Enter> boot specified command line
+ <BackSpace> erase one character
+ <Ctrl-U> erase the whole line
+ <Ctrl-V> display the current Syslinux version
+ <Ctrl-W> erase one word
+ <Ctrl-X> force text mode
+ <Tab> list matching labels
+ <F1>..<F12> help screens (if configured)
+ <Ctrl-F><digit> equivalent to F1..F10
+ <Ctrl-C> interrupt boot in progress
+ <Esc> interrupt boot in progress
+ <Ctrl-N> display network information (PXELINUX only)
+
+
+=== WORKING DIRECTORY ===
+At start, the initial working directory for *SYSLINUX*/*ISOLINUX* will
+be the directory containing the initial configuration file. If no
+configuration file is found, *SYSLINUX* should default to the
+install-time working directory, however this is a known issue with some
+versions including 4.06.
+
+At start, the initial working directory for *PXELINUX* will be the
+parent directory of pxelinux.0 unless overridden with DHCP option 210.
+If no configuration file is found, *PXELINUX* will start a timer to
+reboot the system in an attempt to restart the boot process and resolve
+a possible transient issue.
+
+
+=== ALTERNATE FILENAMES ===
+For kernel-like file names given on the command line, *Syslinux* will
+attempt to append file name extensions to the specified file name when
+the file is not found in the following order: .0[*PXELINUX* only],
+.bin[*ISOLINUX* only], .bs[*SYSLINUX* only], .bss[*SYSLINUX* only],
+.c32, .cbt[Up to 4.06], .com[Up to 4.06] and .img[*ISOLINUX* 1.65-4.04 only].
+
+// Is this true of file names specified in a config? As of when?
+
+
+== AUTHOR ==
+This AsciiDoc derived document is a modified version of the original
+*SYSLINUX* documentation by {author} <{author-email}>. The conversion
+to an AsciiDoc was made by {editor1} <{editor1-email}>
diff --git a/txt/syslinux.cfg.txt b/txt/syslinux.cfg.txt
new file mode 100644
index 00000000..16abe0e2
--- /dev/null
+++ b/txt/syslinux.cfg.txt
@@ -0,0 +1,572 @@
+= syslinux.cfg(5) =
+:doctype: manpage
+:revdate: 2012-10-28
+:author: H. Peter Anvin
+:author-email: hpa@zytor.com
+:editor1: Gene Cumm
+:editor1-email: gene.cumm@gmail.com
+:editor1-revlast: 2012-10-28
+:nbsp8: &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
+:nbsp32: {nbsp8}{nbsp8}{nbsp8}{nbsp8}
+:data-uri:
+
+== NAME ==
+syslinux.cfg - *Syslinux* configuration file
+
+
+== DESCRIPTION ==
+Configuration for the boot behavior and user experience of *Syslinux*
+boot loaders, the format of display files and the boot prompt behavior.
+
+Blank lines are ignored.
+
+Note that the configuration file is not completely decoded. Syntax
+different from the one described above may still work correctly in this
+version of *Syslinux*, but may break in a future one.
+
+
+== LOCATION/NAME ==
+*SYSLINUX* (before 4.00) used the configuration filename of
+syslinux.cfg. *EXTLINUX* (merged into *SYSLINUX* as of 4.00) used the
+filename extlinux.conf. Both default to searching for the config file
+in the installed directory (containing ldlinux.sys/extlinux.sys). As of
+4.00, *SYSLINUX* will search for extlinux.conf then syslinux.cfg in each
+directory before falling back to the next directory.
+
+As of 3.35, *SYSLINUX* also searches /boot/syslinux, /syslinux and /.
+
+*ISOLINUX* (before 4.02) used the configuration filename of
+isolinux.cfg, searching /boot/isolinux (starting 2.00), then /isolinux
+and /. As of 4.02, *ISOLINUX* will search for isolinux.cfg then
+syslinux.cfg in /boot/isolinux before searching for the same files in
+/isolinux, /boot/syslinux, /syslinux, and /.
+
+
+== GLOBAL DIRECTIVES - MAIN ==
+*#* comment::
+A line comment. As of version 3.10, the space between the *#* and the
+comment is no longer required.
+
+*MENU* any string::
+(3.00+) A directive for the simple menu system, treated as a comment
+outside the menu. See menu.txt.
+
+*INCLUDE* 'filename'::
+Inserts the contents of another file at this point in the configuration
+file. Files can currently be nested up to 16 levels deep, but it is not
+guaranteed that more than 8 levels will be supported in the future.
+
+*DEFAULT* 'kernel' 'options...'::
+Sets the default command line. If *Syslinux* boots automatically, it
+will act just as if the entries after *DEFAULT* had been typed in at the
+'boot:' prompt. Multiple uses will result in an override.
++
+If no configuration file is present, or no *DEFAULT* or *UI* entry is
+present in the config file, an error message is displayed and the
+'boot:' prompt is shown (3.85+).
+
+*UI* 'module' 'options...'::
+Selects a specific user interface 'module' (typically menu.c32 or
+vesamenu.c32). The command-line interface treats this as a directive
+that overrides the *DEFAULT* directive to load this module instead at
+startup and for an empty command line and *PROMPT* directive to not
+prompt. Multiple uses will result in an override.
+
+*LABEL* 'mylabel'::
+Begin a new *LABEL* clause. If 'mylabel' is entered as the kernel to
+boot, *Syslinux* should instead boot "image" (specified by a directive
+from *KERNEL-LIKE DIRECTIVES*) with any specified *DUAL-PURPOSE
+DIRECTIVES* being used instead of the global instance.
++
+'mylabel' must be unique. Currently the first instance is used but may
+result in an error or undesired behavior. 'mylabel' ends at the first
+character that is not a non-white-space printable character and should
+be restricted to non-white-space typeable characters. Prior to version
+3.32, this would transformed to a DOS compatible format of 8.3 with a
+restricted character set. A *LABEL* clause must contain exactly 1 of
+the *KERNEL-LIKE DIRECTIVES* and may contain 1 each of the *LABEL-ONLY
+DIRECTIVES* or *DUAL-PURPOSE DIRECTIVES*.
++
+Within a *LABEL*, using multiple *KERNEL-LIKE DIRECTIVES* or reuse of
+*LABEL-ONLY DIRECTIVES* or *DUAL-PURPOSE DIRECTIVES* will result in an
+override. Otherwise, multiple instances of the same directive will
+result in the last being effective.
+
+
+== DUAL-PURPOSE DIRECTIVES ==
+Use of any of the *DUAL-PURPOSE DIRECTIVES* as *GLOBAL DIRECTIVES* is
+discouraged if there will be any non-Linux images loaded as *ALL* images
+will get these, including those manually entered at the 'boot:' prompt.
+
+*APPEND* 'options...'::
+Add one or more options to the kernel command line. These are added
+both for automatic and manual boots. The options are added at the very
+beginning of the kernel command line, usually permitting explicitly
+entered kernel options to override them. This is the equivalent of the
+LILO "append" option.
++
+Use of the parameter 'initrd=' supports multiple filenames separated by
+commas (ie 'initrd=initrd_file1,initrd_file2') within a single instance.
+This is mostly useful for initramfs, which can be composed of multiple
+separate cpio or cpio.gz archives.
++
+Note: all initrd files except the last one are zero-padded to a 4K page
+boundary. This should not affect initramfs.
++
+Note: Only the last effective 'initrd=' parameter is used for loading
+initrd files.
+
+*APPEND* -::
+Append nothing. *APPEND* with a single hyphen as argument in a *LABEL*
+section can be used to override a global *APPEND*.
+
+//[FIXME: Shorten subdefinitions]
+*IPAPPEND* 'flag_val'::
+(*PXELINUX* only) The *IPAPPEND* option is available only on *PXELINUX*.
+ The flag_val is an OR (sum) of the following integer options:
+
+ifndef::doctype-manpage[[horizontal]]
+*1*::: An option of the following format should be generated, based on
+the input from the DHCP/BOOTP or PXE boot server and added to the kernel
+command line(see note below):
++
+----
+ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>
+----
++
+NOTE: The use of option 1 is no substitute for running a DHCP client in
+the booted system and should instead only be used to seed the client for
+a request. Without regular renewals, the lease acquired by the PXE BIOS
+will expire, making the IP address available for reuse by the DHCP
+server.
++
+*2*::: An option of the following format should be generated, in
+dash-separated hexadecimal with leading hardware type (same as for the
+configuration file; see pxelinux.txt.) and added to the kernel command
+line, allowing an initrd program to determine from which interface the
+system booted:
++
+----
+BOOTIF=<hardware-address-of-boot-interface>
+----
++
+*4*::: An option of the following format should be generated, in lower
+case hexadecimal in the format normally used for UUIDs (same as for the
+configuration file; see pxelinux.txt.) and added to the kernel command
+line:
++
+----
+SYSUUID=<system uuid>
+----
+
+
+== KERNEL-LIKE DIRECTIVES ==
+// Alpha sort after KERNEL and LINUX
+*KERNEL* 'image'::
+Load a kernel-like file 'image' with automatic filetype detection based
+on file extension, listed under the non-auto-detecting directives,
+defaulting to *LINUX*.
+
+//[FIXME: Should "'image' as " be removed entirely or added to all?
+*LINUX* is used as an example]
+*LINUX* 'image'::
+Load 'image' as a Linux-like kernel. MEMDISK is an example of a
+non-Linux kernel loaded in a Linux-like fashion.
+
+*BOOT* 'image'::
+(*ISOLINUX* only: .bin; *SYSLINUX* only: .bs) Load a boot sector. .bin
+is a "CD boot sector" and .bs is a regular disk boot sector.
+
+*BSS* 'image'::
+(*SYSLINUX* only: .bss) Load a BSS image, a .bs image with the DOS
+superblock patched in.
+
+*COMBOOT* 'image'::
+(.com, .cbt; Removed as of 5.00) Load a *Syslinux* COMBOOT image. .com
+images may also be runnable from DOS while .cbt images are not. See
+also *comboot.txt*
+
+*COM32* 'image'::
+(.c32) Load a *Syslinux* COM32 (32-bit *COMBOOT*) image. See also
+*comboot.txt*
+
+*CONFIG* 'image'::
+Load a new configuration file. The configuration file is read, the
+working directory is changed (if specified via an *APPEND*), then the
+configuration file is parsed.
+
+*FDIMAGE* 'image'::
+(Removed as of 4.05, added 1.65; *ISOLINUX* only: .img) Load a disk
+image.
+
+*LOCALBOOT* 'type'::
+(*PXELINUX* 1.53+; *ISOLINUX* ??3.10+; *SYSLINUX* 3.70+)Attempt a
+different local boot method. The special value -1 causes the boot
+loader to report failure to the BIOS, which, on recent BIOSes, should
+mean that the next boot device in the boot sequence should be activated.
+ Values other than those documented may produce undesired results.
++
+On *PXELINUX*, 'type' 0 means perform a normal boot. 'type' 4 will
+perform a local boot with the Universal Network Driver Interface (UNDI)
+driver still resident in memory. Finally, 'type' 5 will perform a local
+boot with the entire PXE stack, including the UNDI driver, still
+resident in memory. All other values are undefined. If you don't know
+what the UNDI or PXE stacks are, don't worry -- you don't want them,
+just specify 0.
++
+On *ISOLINUX*/*SYSLINUX*, the 'type' specifies the local drive number to
+boot from; 0x00 is the primary floppy drive and 0x80 is the primary hard
+drive.
+
+*PXE* 'image'::
+(*PXELINUX* only: .0) Load a PXE NBP (Network Boot Program) image. The
+PXE protocol does not provide any means for specifiying or using a
+command line or initrd.
+
+
+== LABEL-ONLY DIRECTIVES ==
+*INITRD* 'initrd_file'::
+(3.71+) An initrd can be specified in a separate statement (INITRD)
+instead of as part of the *APPEND* statement; this functionally appends
+"initrd=initrd_file" to the kernel command line. Like 'initrd=', this
+also supports multiple comma separated file names (see *APPEND*).
+
+
+== GLOBAL DIRECTIVES - SECONDARY ==
+These are global directives that are of lesser importance, often
+affecting the user experience and not the boot process.
+
+*ALLOWOPTIONS* 'flag_val'::
+If 'flag_val' is 0, the user is not allowed to specify any arguments on
+the kernel command line. The only options recognized are those
+specified in an *APPEND*) statement. The default is 1.
+
+*IMPLICIT* 'flag_val'::
+If 'flag_val' is 0, do not load a kernel image unless it has been
+explicitly named in a *LABEL* statement. The default is 1.
+
+*TIMEOUT* 'timeout'::
+Indicates how long to wait at the 'boot:' prompt until booting
+automatically, in units of 1/10 s. The timeout is cancelled as soon as
+the user types anything on the keyboard, the assumption being that the
+user will complete the command line already begun. A timeout of zero
+(the default) will disable the timeout completely.
+
+*TOTALTIMEOUT* 'timeout'::
+Indicates how long to wait until booting automatically, in units of
+1/10 s. This timeout is *not* cancelled by user input, and can thus be
+used to deal with serial port glitches or "the user walked away" type
+situations. A timeout of zero will disable the timeout completely, this
+is also the default.
++
+Both *TIMEOUT* and *TOTALTIMEOUT* can be used together, for example:
++
+----
+# Wait 5 seconds unless the user types something, but
+# always boot after 15 minutes.
+TIMEOUT 50
+TOTALTIMEOUT 9000
+----
+
+// FIXME: be consistent
+*ONTIMEOUT* 'kernel options...'::
+Sets the command line invoked on a timeout. Normally this is the same
+thing as invoked by 'DEFAULT'. If this is specified, then 'DEFAULT' is
+used only if the user presses <Enter> to boot.
+
+*ONERROR* 'kernel options...'::
+If a kernel image is not found (either due to it not existing, or
+because *IMPLICIT* is set), run the specified command. The faulty
+command line is appended to the specified options, so if the *ONERROR*
+directive reads as:
++
+----
+ONERROR xyzzy plugh
+----
++
+and the command line as entered by the user is:
++
+----
+foo bar baz
+----
++
+*Syslinux* will execute the following as if entered by the user:
++
+----
+xyzzy plugh foo bar baz
+----
+
+*SERIAL* 'port [[baudrate] flowcontrol]'::
+Enables a serial port to act as the console. 'port' is a number (0 =
+/dev/ttyS0 = COM1, etc.) or an I/O port address (e.g. 0x3F8); if
+'baudrate' is omitted, the baud rate defaults to 9600 bps. The serial
+parameters are hardcoded to be 8 bits, no parity, 1 stop bit.
++
+'flowcontrol' is a combination of the following bits:
++
+....
+0x001 - Assert DTR
+0x002 - Assert RTS
+0x008 - Enable interrupts
+0x010 - Wait for CTS assertion
+0x020 - Wait for DSR assertion
+0x040 - Wait for RI assertion
+0x080 - Wait for DCD assertion
+0x100 - Ignore input unless CTS asserted
+0x200 - Ignore input unless DSR asserted
+0x400 - Ignore input unless RI asserted
+0x800 - Ignore input unless DCD asserted
+....
++
+All other bits are reserved.
++
+Typical values are:
++
+....
+ 0 - No flow control (default)
+0x303 - Null modem cable detect
+0x013 - RTS/CTS flow control
+0x813 - RTS/CTS flow control, modem input
+0x023 - DTR/DSR flow control
+0x083 - DTR/DCD flow control
+....
++
+For the *SERIAL* directive to be guaranteed to work properly, it should
+be the first directive in the configuration file.
++
+NOTE: 'port' values from 0 to 3 means the first four serial ports
+detected by the BIOS. They may or may not correspond to the legacy port
+values 0x3F8, 0x2F8, 0x3E8, 0x2E8.
++
+Enabling interrupts (setting the 0x008 bit) may give better
+responsiveness without setting the *NOHALT* option, but could
+potentially cause problems with buggy BIOSes.
+
+*NOHALT* 'flag_val'::
+If 'flag_val' is 1, don't halt the processor while idle. Halting the
+processor while idle significantly reduces the power consumption, but
+can cause poor responsiveness to the serial console, especially when
+using scripts to drive the serial console, as opposed to human
+interaction.
+
+*CONSOLE* 'flag_val'::
+If 'flag_val' is 0, disable output to the normal video console. If
+'flag_val' is 1, enable output to the video console (this is the
+default.)
++
+Some BIOSes try to forward this to the serial console and sometimes make
+a total mess thereof, so this option lets you disable the video console
+on these systems.
+
+*FONT* 'filename'::
+Load a font in .psf format before displaying any output (except the
+copyright line, which is output as ldlinux.sys itself is loaded.)
+*Syslinux* only loads the font onto the video card; if the .psf file
+contains a Unicode table it is ignored. This only works on EGA and VGA
+cards; hopefully it should do nothing on others.
+
+*KBDMAP* 'keymap'::
+Install a simple keyboard map. The keyboard remapper used is *very*
+simplistic (it simply remaps the keycodes received from the BIOS, which
+means that only the key combinations relevant in the default layout --
+usually U.S. English -- can be mapped) but should at least help people
+with AZERTY keyboard layout and the locations of = and , (two special
+characters used heavily on the Linux kernel command line.)
++
+The included program keytab-lilo.pl from the LILO distribution can be
+used to create such keymaps. The file keytab-lilo.txt contains the
+documentation for this program.
+
+*DISPLAY* 'filename'::
+Displays the indicated file on the screen at boot time (before the boot:
+prompt, if displayed). Please see the section below on *DISPLAY* files.
++
+NOTE: If the file is missing, this option is simply ignored.
+
+*SAY* 'message'::
+Prints the message on the screen.
+
+*PROMPT* 'flag_val'::
+If 'flag_val' is 0, display the boot: prompt only if the Shift or Alt
+key is pressed, or Caps Lock or Scroll lock is set (this is the
+default). If 'flag_val' is 1, always display the boot: prompt.
+
+*NOESCAPE* 'flag_val'::
+If 'flag_val' is set to 1, ignore the Shift/Alt/Caps Lock/Scroll Lock
+escapes. Use this (together with PROMPT 0) to force the default boot
+alternative.
+
+*NOCOMPLETE* 'flag_val'::
+If 'flag_val' is set to 1, the Tab key does not display labels at the
+boot: prompt.
+
+// ...etc...
+*F1* 'filename'::
+*F2* 'filename'::
+*F3* 'filename'::
+*F4* 'filename'::
+*F5* 'filename'::
+*F6* 'filename'::
+*F7* 'filename'::
+*F8* 'filename'::
+*F9* 'filename'::
+*F10* 'filename'::
+*F11* 'filename'::
+*F12* 'filename'::
+Displays the indicated file on the screen when a function key is pressed
+at the boot: prompt. This can be used to implement pre-boot online help
+(presumably for the kernel command line options.) Please see the
+section below on DISPLAY files.
++
+When using the serial console, press <Ctrl-F><digit> to get to the help
+screens, e.g. <Ctrl-F><2> to get to the F2 screen. For F10-F12, hit
+<Ctrl-F><A>, <Ctrl-F>B, <Ctrl-F>C. For compatibility with earlier
+versions, F10 can also be entered as <Ctrl-F>0.
+
+*PATH* 'path'::
+(5.00+) Specify a colon-separated (':') list of directories to search when
+attempting to load modules. This directive is useful for specifying the
+directories containing the lib*.c32 library files as other modules may
+be dependent on these files, but may not reside in the same directory.
+
+
+== DISPLAY FILE FORMAT ==
+DISPLAY and function-key help files are text files in either DOS or UNIX
+format (with or without <CR>). In addition, the following special codes
+are interpreted:
+
+//[FIXME]: #1 doesn't break; #2 as-is; #3 broken but not on right; #4
+identical to #3
+// horizontal extends the line's label, reducing the definition
+// tab or space to shift explanation ? align beginning or end?
+
+// ifndef::doctype-manpage[[horizontal]]
+*<FF>*:: {nbsp32} = <Ctrl-L> = ASCII 12 +
+Clear the screen, home the cursor. Note that the screen is filled with
+the current display color.
+
+*<FF>*::
+= <Ctrl-L> = ASCII 12; Clear the screen, home the cursor. Note that the
+screen is filled with the current display color.
+
+*<FF>*:: <FF> = <Ctrl-L> = ASCII 12
++
+Clear the screen, home the cursor. Note that the screen is filled with
+the current display color.
+
+*<FF>*::
+<FF> = <Ctrl-L> = ASCII 12 +
+Clear the screen, home the cursor. Note that the screen is filled with
+the current display color.
+
+*<SI>*'<bg><fg>':: <SI> = <Ctrl-O> = ASCII 15
++
+Set the display colors to the specified background and foreground
+colors, where <bg> and <fg> are the 2 hex digits representing 1 byte,
+corresponding to the standard PC display attributes:
++
+ 0 = black 8 = dark grey
+ 1 = dark blue 9 = bright blue
+ 2 = dark green a = bright green
+ 3 = dark cyan b = bright cyan
+ 4 = dark red c = bright red
+ 5 = dark purple d = bright purple
+ 6 = brown e = yellow
+ 7 = light grey f = white
++
+Picking a bright color (8-f) for the background results in the
+corresponding dark color (0-7), with the foreground flashing.
++
+Colors are not visible over the serial console.
+
+*<CAN>*'filename<newline>':: <CAN> = <Ctrl-X> = ASCII 24
++
+If a VGA display is present, enter graphics mode and display the graphic
+included in the specified file. The file format is an ad hoc format
+called LSS16; the included Perl program "ppmtolss16" can be used to
+produce these images. This Perl program also includes the file format
+specification.
++
+The image is displayed in 640x480 16-color mode. Once in graphics mode,
+the display attributes (set by <SI> code sequences) work slightly
+differently: the background color is ignored, and the foreground colors
+are the 16 colors specified in the image file. For that reason,
+ppmtolss16 allows you to specify that certain colors should be assigned
+to specific color indicies.
++
+Color indicies 0 and 7, in particular, should be chosen with care: 0 is
+the background color, and 7 is the color used for the text printed by
+*Syslinux* itself.
+
+*<EM>*:: <EM> = <Ctrl-Y> = ASCII 25 +
+If we are currently in graphics mode, return to text mode.
+
+*<DLE>*..*<ETB>*:: <Ctrl-P>..<Ctrl-W> = ASCII 16-23
++
+These codes can be used to select which modes to print a certain part of
+the message file in. Each of these control characters select a specific
+set of modes (text screen, graphics screen, serial port) for which the
+output is actually displayed:
++
+ Character Text Graph Serial
+ ------------------------------------------------------
+ <DLE> = <Ctrl-P> = ASCII 16 No No No
+ <DC1> = <Ctrl-Q> = ASCII 17 Yes No No
+ <DC2> = <Ctrl-R> = ASCII 18 No Yes No
+ <DC3> = <Ctrl-S> = ASCII 19 Yes Yes No
+ <DC4> = <Ctrl-T> = ASCII 20 No No Yes
+ <NAK> = <Ctrl-U> = ASCII 21 Yes No Yes
+ <SYN> = <Ctrl-V> = ASCII 22 No Yes Yes
+ <ETB> = <Ctrl-W> = ASCII 23 Yes Yes Yes
++
+For example, the following will actually print out which mode the
+console is in:
++
+ <DC1>Text mode<DC2>Graphics mode<DC4>Serial port<ETB>
+
+*<SUB>*:: <SUB> = <Ctrl-Z> = ASCII 26
++
+End of file (DOS convention).
+
+*<BEL>*:: <BEL> = <Ctrl-G> = ASCII 7 +
+Beep the speaker.
+
+
+== BOOT LOADER IDS USED ==
+The Linux boot protocol supports a "boot loader ID", a single byte where
+the upper nybble specifies a boot loader family (3 = *Syslinux*) and the
+lower nybble is version or, in the case of *Syslinux*, media:
+
+ 0x31 (49) = SYSLINUX
+ 0x32 (50) = PXELINUX
+ 0x33 (51) = ISOLINUX
+ 0x34 (52) = EXTLINUX
+
+In recent versions of Linux, this ID is available as
+/proc/sys/kernel/bootloader_type.
+
+
+== NOVICE PROTECTION ==
+*Syslinux* will attempt to detect booting on a machine with too little
+memory, which means the Linux boot sequence cannot complete. If so, a
+message is displayed and the boot sequence aborted. Holding down the
+Ctrl key while booting disables this feature.
+
+Any file that *Syslinux* uses can be marked hidden, system or readonly
+if so is convenient; *Syslinux* ignores all file attributes. The
+*SYSLINUX* installer automatically sets the readonly/hidden/system
+attributes on LDLINUX.SYS.
+
+
+== KNOWN BUGS ==
+include::com-bug.txt[]
+
+
+== BUG REPORTS ==
+include::com-rpt.txt[]
+
+
+== AUTHOR ==
+This AsciiDoc derived document is a modified version of the original
+*SYSLINUX* documentation by {author} <{author-email}>. The conversion
+to an AsciiDoc was made by {editor1} <{editor1-email}>
diff --git a/txt/syslinux.txt b/txt/syslinux.txt
new file mode 100644
index 00000000..33b03d71
--- /dev/null
+++ b/txt/syslinux.txt
@@ -0,0 +1,217 @@
+= syslinux(1) =
+:doctype: manpage
+:revdate: 2012-10-28
+:author: H. Peter Anvin
+:author-email: hpa@zytor.com
+:editor1: Gene Cumm
+:editor1-email: gene.cumm@gmail.com
+:editor1-revlast: 2012-10-28
+
+
+== NAME ==
+syslinux - Install SYSLINUX to a file system
+
+
+== SYNOPSIS ==
+[verse]
+*syslinux* ['OPTIONS'] 'DEVICE'
+*extlinux* ['OPTIONS'] 'PATH'
+*syslinux* [-h | --help]
+*extlinux* [-h | --help]
+
+
+== DESCRIPTION ==
+Install *SYSLINUX* to the 'DEVICE'/'PATH', altering the boot sector and
+installing the 'ldlinux.sys' boot loader file. For the Linux installer
+extlinux, 'PATH' is the desired path for the control files on a mounted,
+supported file system and sets the install-time working directory. For
+all others, 'DEVICE' must specify a FAT12/FAT16/FAT32 file system. For
+the Linux installers syslinux and syslinux-mtools, 'DEVICE' should be an
+unmounted file system. For the DOS/Win32/Win64 installers, 'DEVICE'
+should be a drive like 'a:' (case insensitive).
+
+For versions ~4.00 and later, either -i/--install or -U/--update must be
+specified unless modifying the ADV of an existing install (options
+tagged with 'ADV') or requesting the help/usage or version info, .
+
+If, during boot, the Shift or Alt keys are held down, or the Caps or
+Scroll locks are set, *Syslinux* will display a *lilo*(8) -style "boot:"
+prompt. The user can then type a kernel file name followed by any kernel
+parameters. The *Syslinux* bootloader does not need to know about the
+kernel or config files in advance.
+
+*Syslinux* supports the loading of initial ramdisks (initrd) and the
+bzImage kernel format.
+
+Please note, the ldlinux.sys boot loader file is flagged as immutable
+(where applicable) and is modified after copying in to help ensure
+boot-time integrity. File systems with a sufficiently large boot loader
+reserved area, like btrfs, will have ldlinux.sys installed there rather
+than as a normal file.
+
+
+== OPTIONS ==
+// "See"/"See also" notes should reference long options.
+=== Standalone options ===
+*-i*, *--install*::
+(~4.00+) Install SYSLINUX, regardless of an existing install.
+
+*-U*, *--update*::
+(~4.00+) Update an existing SYSLINUX/EXTLINUX install. If no Syslinux
+boot loader is present, return an error.
+
+*-h*, *--help*::
+Display help/usage information.
+
+*-v*, *--version*::
+Display version information and exit immediately.
+
+=== Regular Options ===
+// Sorted generally by short argument
+*-a*, *--active*::
+(DOS/Win32/Win64 ONLY) Mark the install target file system's partition
+active.
+
+*-d*, *--directory* 'subdirectory'::
+(Not necessary for extlinux as it is implied by 'PATH') Install the
+*SYSLINUX* control files in a subdirectory with the specified name
+(relative to the root directory on the device).
+
+*--device* 'DEVICE'::
+(extlinux ONLY; 4.06+) Force use of a specific block device (experts
+only).
+
+*-f*, *--force*::
+Force install even if it appears unsafe. Before 4.00, -f was used for
+--offset in the Linux installers.
+
+*-H*, *--heads* 'head-count'::
+Override the detected number of heads for the geometry. See also
+*--sector*.
+
+*-m*, *--mbr*:
+(DOS/Win32/Win64 ONLY) Install the regular Syslinux MBR code to the MBR.
+
+*-M*, *--menu-save*::
+(4.00+; ADV) Set the label to select as default on the next boot.
+
+*-o*, *--once* 'command'::
+(ADV) Declare a boot command to be tried on the first boot only. The
+use of *-o* for the Linux installers syslinux or syslinux-mtools has
+been deprecated as of \~4.00 and is no longer valid as of ~4.02.
+
+*-O*, *--clear-once*::
+Clear the boot-once command. See also *--once*.
+
+*-r*, *--raid*::
+(ADV) RAID mode. If boot fails, tell the BIOS to boot the next device
+in the boot sequence (usually the next hard disk) instead of stopping
+with an error message. This is useful for RAID-1 booting.
+
+*--reset-adv*::
+(ADV) Reset auxilliary data vector.
+
+*-S*, *--sectors* 'sector-count'::
+Override the detected number of sectors for the geometry. See also
+*--head*.
+
+*-s*, *--stupid*::
+Install a "safe, slow and stupid" version of *SYSLINUX*. This version
+may work on some very buggy BIOSes on which *SYSLINUX* would otherwise
+fail. If you find a machine on which the -s option is required to make
+it boot reliably, please send as much info about your machine as you
+can, and include the failure mode.
+
+*-t*, *--offset* 'offset'::
+(Linux syslinux/syslinux-mtools ONLY) Indicates that the filesystem is
+at an offset from the base of the device or file.
+
+*-z*, *--zipdrive*
+Assume zipdrive geometry ('--heads 64 --sectors 32'). See also *--head*
+and *--sector*.
+
+
+== EXAMPLES ==
+=== Booting DOS ===
+For booting DOS and other similar operating systems, there is an easy
+and generally reliable solution to substitute in SYSLINUX as the primary
+boot loader.
+
+- Make a DOS-bootable disk; The following are possible commands:
+
+ format a: /s
+ sys a:
+
+- Copy the DOS boot sector off using Linux or copybs.com:
+
+ dd if=/dev/fd0 of=dos.bss bs=512 count=1
+ copybs a: a:dos.bss
+
+- Install SYSLINUX using one of:
+
+ syslinux a:
+ syslinux /dev/fd0 (before 4.00)
+ syslinux -i /dev/fd0 (4.00+)
+
+- For Linux, mount the disk and copy the dos.bss to the disk:
+
+ mount -t msdos /dev/fd0 /mnt
+ cp dos.bss /mnt
+
+- Copy a Linux kernel image and initrd payload files:
+*Linux:*::
+ cp vmlinux /mnt
+ cp initrd.gz /mnt
+*DOS/Windows:*::
+ copy vmlinux a:
+ copy initrd.gz a:
+
+- For Linux, umount the disk (if applicable):
+
+ umount /mnt
+
+=== MBR ===
+In order to boot from a hard disk (or hard disk-like device) in BIOS
+mode, an appropriate MBR boot block must also be installed in the MBR
+(first sector or 512 bytes of the disk), occupying at most 440 bytes.
+
+*DOS/Windows:*::
+If using FDISK, FDISK or a similar application must also be used to mark
+the partition as active.
++
+ fdisk /mbr
+ OR
+ syslinux -ma c:
+
+*Linux:*::
++
+ dd bs=440 count=1 conv=notrunc if=mbr/mbr.bin of=/dev/sda
++
+For altmbr.bin, an easy way to overwrite the MBR boot block and specify
+the partion number is:
++
+ printf '\1' | cat altmbr.bin - | dd bs=440 count=1 iflag=fullblock conv=notrunc of=/dev/sda
++
+Note: using 'cat' for writing the MBR can under some circumstances cause
+data loss or overwritting. For this reason, using 'dd' is recommended
+for all situations.
+
+//[FIXME]: any clean way to handle the above long command for manpage?
+
+
+== SEE ALSO ==
+*syslinux.cfg*(5), *syslinux-cli*(1), *lilo*(8), *keytab-lilo.pl*(8),
+*fdisk*(8), *mkfs*(8), *superformat*(1).
+
+
+== AUTHOR ==
+This AsciiDoc derived document is a modified version of the original
+*SYSLINUX* documentation by {author} <{author-email}>. The conversion to
+a manpage was made by Arthur Korn <arthur@korn.ch>. The conversion to
+an AsciiDoc was made by {editor1} <{editor1-email}>
+
+
+== COPYRIGHT ==
+Copyright \(C) 1994-2012 {author}. Free use of this software is granted
+under the terms of the GNU General Public License (GPL), version 2
+(GPLv2) (or, at your option, any later version).