summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErwan Velu <erwan.velu@free.fr>2009-04-13 20:54:22 +0200
committerErwan Velu <erwan.velu@free.fr>2009-04-13 20:54:22 +0200
commitbaaa1ac2e15a3ab2152bc510a8059c0cd763b34d (patch)
treee334781d4696630d5adbe6c9158303cc227078a5
parentd1c432c5b851c7a8c81cc5f9c88323bfc714deb1 (diff)
parentd72bfe6108c5104bb095f1c3f9f35885ddf8da88 (diff)
downloadhdt-baaa1ac2e15a3ab2152bc510a8059c0cd763b34d.tar.gz
hdt-baaa1ac2e15a3ab2152bc510a8059c0cd763b34d.tar.bz2
hdt-baaa1ac2e15a3ab2152bc510a8059c0cd763b34d.tar.xz
hdt-baaa1ac2e15a3ab2152bc510a8059c0cd763b34d.zip
Merge branch 'for-erwan' of ssh://erwan@terminus.zytor.com/pub/git/users/pam/hdt-pierre into pam
Conflicts: com32/hdt/hdt-cli.c
-rw-r--r--MCONFIG2
-rw-r--r--Makefile8
-rw-r--r--NEWS21
-rw-r--r--com32/LICENCE1
-rw-r--r--com32/MCONFIG3
-rw-r--r--com32/cmenu/Makefile1
-rw-r--r--com32/gdbstub/Makefile2
-rw-r--r--com32/hdt/Makefile78
-rw-r--r--com32/hdt/hdt-common.c1
-rw-r--r--com32/include/com32.h28
-rw-r--r--com32/include/syslinux/advconst.h2
-rw-r--r--com32/include/syslinux/align.h47
-rw-r--r--com32/include/syslinux/config.h1
-rw-r--r--com32/include/syslinux/keyboard.h2
-rw-r--r--com32/include/syslinux/memscan.h38
-rw-r--r--com32/include/syslinux/movebits.h9
-rw-r--r--com32/lib/Makefile2
-rw-r--r--com32/lib/free.c36
-rw-r--r--com32/lib/malloc.c49
-rw-r--r--com32/lib/malloc.h2
-rw-r--r--com32/lib/sys/ansicon_write.c1
-rw-r--r--com32/lib/sys/argv.c8
-rw-r--r--com32/lib/sys/entry.S2
-rw-r--r--com32/lib/sys/vesacon_write.c1
-rw-r--r--com32/lib/syslinux/dsinfo.c1
-rw-r--r--com32/lib/syslinux/keyboard.c4
-rw-r--r--com32/lib/syslinux/load_linux.c79
-rw-r--r--com32/lib/syslinux/memmap.c127
-rw-r--r--com32/lib/syslinux/memscan.c162
-rw-r--r--com32/lib/syslinux/setadv.c16
-rw-r--r--com32/lib/syslinux/shuffle.c137
-rw-r--r--com32/lib/syslinux/shuffle_pm.c45
-rw-r--r--com32/lib/syslinux/shuffle_rm.c79
-rw-r--r--com32/lib/syslinux/zonelist.c31
-rw-r--r--com32/menu/Makefile2
-rw-r--r--com32/menu/menu.h1
-rw-r--r--com32/menu/menumain.c9
-rw-r--r--com32/menu/readconfig.c25
-rw-r--r--com32/modules/Makefile3
-rw-r--r--com32/modules/chain.c77
-rw-r--r--com32/modules/kbdmap.c2
-rw-r--r--com32/rosh/Makefile2
-rw-r--r--core/Makefile3
-rw-r--r--core/abort.inc3
-rw-r--r--core/bcopy32.inc497
-rw-r--r--core/bcopyxx.inc326
-rw-r--r--core/bootsect.inc92
-rw-r--r--core/cleanup.inc2
-rw-r--r--core/cmdline.inc60
-rw-r--r--core/com32.inc6
-rw-r--r--core/comboot.inc180
-rw-r--r--core/config.inc14
-rw-r--r--core/cpuinit.inc8
-rw-r--r--core/extlinux.asm5
-rw-r--r--core/getc.inc3
-rw-r--r--core/isolinux.asm3
-rw-r--r--core/layout.inc6
-rw-r--r--core/ldlinux.asm3
-rw-r--r--core/loadhigh.inc3
-rw-r--r--core/parsecmd.inc1
-rw-r--r--core/parseconfig.inc1
-rw-r--r--core/pxelinux.asm27
-rw-r--r--core/rllpack.inc49
-rw-r--r--core/runkernel.inc19
-rw-r--r--core/syslinux.ld53
-rw-r--r--core/ui.inc3
-rw-r--r--doc/comboot.txt156
-rw-r--r--doc/menu.txt23
-rw-r--r--gpxe/Makefile1
-rw-r--r--mbr/Makefile28
-rw-r--r--mbr/adjust.h53
-rw-r--r--mbr/altmbr.S306
-rwxr-xr-xmbr/checksize.pl36
-rw-r--r--mbr/gptmbr.S18
-rw-r--r--mbr/isohdpfx.S20
-rw-r--r--mbr/mbr.S14
-rw-r--r--memdisk/Makefile3
-rw-r--r--memdisk/memdisk.inc3
-rw-r--r--memdisk/memdisk.ld12
-rw-r--r--memdisk/setup.c3
-rw-r--r--memdisk/start32.S21
-rw-r--r--mime/image/x-lss16.xml39
-rw-r--r--modules/Makefile2
-rw-r--r--modules/gfxboot.asm964
-rw-r--r--version2
85 files changed, 3024 insertions, 1194 deletions
diff --git a/MCONFIG b/MCONFIG
index 9900ac4a..3fd3946d 100644
--- a/MCONFIG
+++ b/MCONFIG
@@ -36,6 +36,8 @@ NASMOPT = -O9999
PERL = perl
+CHMOD = chmod
+
CC = gcc
gcc_ok = $(shell tmpf=gcc_ok.$$$$.tmp; \
if $(CC) $(1) -c $(topdir)/dummy.c -o $$tmpf 2>/dev/null ; \
diff --git a/Makefile b/Makefile
index 8718f7a0..4520c35a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
## Copyright 1998-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
@@ -30,8 +31,8 @@ include $(topdir)/MCONFIG
# List of module objects that should be installed for all derivatives
MODULES = memdisk/memdisk memdump/memdump.com modules/*.com \
- com32/menu/*.c32 com32/modules/*.c32 com32/hdt/*.c32
-
+ com32/menu/*.c32 com32/modules/*.c32 com32/hdt/*.c32 \
+ com32/rosh/*.c32
# syslinux.exe is BTARGET so as to not require everyone to have the
# mingw suite installed
@@ -64,8 +65,7 @@ INSTALL_SBIN = extlinux/extlinux
INSTALL_AUX = core/pxelinux.0 gpxe/gpxelinux.0 core/isolinux.bin \
core/isolinux-debug.bin \
dos/syslinux.com dos/copybs.com win32/syslinux.exe \
- mbr/mbr.bin mbr/gptmbr.bin \
- $(MODULES)
+ mbr/*.bin $(MODULES)
INSTALL_AUX_OPT = win32/syslinux.exe
# These directories manage their own installables
diff --git a/NEWS b/NEWS
index 81bc5139..50986eb0 100644
--- a/NEWS
+++ b/NEWS
@@ -11,7 +11,7 @@ Changes in 3.74:
dynamically.
* isohybrid: workaround bug in some versions of binutils.
* Fix issue with the placement of the initrd on some machines.
- * ifcpu64: fix handling of less than three argumetns.
+ * ifcpu64: fix handling of less than three arguments.
* Fix bug in the shuffle library when dealing with a very
large number of fragments.
* Documentation fixes by Vicente Jimenez Aguilar.
@@ -25,6 +25,25 @@ Changes in 3.74:
* Suppress the Loading ... message if "quiet" is specified on
the kernel command line.
* Fix the use of "CONSOLE 0" with menu.c32.
+ * Allow COM32 modules to be aware of all memory even in the
+ presence of a memory hole. The "linux.c32" module can be
+ used to load a kernel (or memdisk) plus large initrd on
+ such a system.
+ * MBR: produce alternate MBR variants which force the drive
+ number to hd0 (_f variants), or force the drive number to
+ hd0 if the Ctrl key is pressed (_c variants.) Furthermore,
+ add an MBR variant (altmbr*.bin) which ignores the active
+ flag and instead boots the partition number specified in the
+ byte at offset 439 decimal.
+ * Add IPAPPEND strings to com32 modules, especially needed for
+ linux.c32.
+ * New MENU SAVE directive which saves the latest menu
+ selection until the next boot. Currently only implemented for
+ EXTLINUX.
+ * gfxboot.com: *experimental* interface module to Steffen
+ Winterfeldt's "gfxboot" graphical front end
+ (http://gfxboot.sourceforge.net/). Module by Sebastian Herbszt.
+
Changes in 3.73:
* Upgrade gPXE to release version 0.9.5.
diff --git a/com32/LICENCE b/com32/LICENCE
index 8934e8fb..7eec7862 100644
--- a/com32/LICENCE
+++ b/com32/LICENCE
@@ -3,6 +3,7 @@ libcom32 and libutil are licensed under the MIT license:
## -----------------------------------------------------------------------
##
## Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+## Portions Copyright 2009 Intel Corporation; author: H. Peter Anvin
##
## Permission is hereby granted, free of charge, to any person
## obtaining a copy of this software and associated documentation
diff --git a/com32/MCONFIG b/com32/MCONFIG
index d1af9455..641111ab 100644
--- a/com32/MCONFIG
+++ b/com32/MCONFIG
@@ -1,6 +1,7 @@
## -*- makefile -*- -------------------------------------------------------
##
-## Copyright 2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
diff --git a/com32/cmenu/Makefile b/com32/cmenu/Makefile
index 010fa122..db896e52 100644
--- a/com32/cmenu/Makefile
+++ b/com32/cmenu/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
## Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
diff --git a/com32/gdbstub/Makefile b/com32/gdbstub/Makefile
index 2c9171e5..5513876b 100644
--- a/com32/gdbstub/Makefile
+++ b/com32/gdbstub/Makefile
@@ -42,7 +42,7 @@ spotless: clean
rm -f *.lss *.c32 *.com
rm -f *~ \#*
-install: all
+install:
mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)
install -m 644 $(MODULES) $(INSTALLROOT)$(AUXDIR)
diff --git a/com32/hdt/Makefile b/com32/hdt/Makefile
index 20f89d6e..8f8cae21 100644
--- a/com32/hdt/Makefile
+++ b/com32/hdt/Makefile
@@ -1,81 +1,47 @@
## -----------------------------------------------------------------------
##
## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
+## the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+## Boston MA 02110-1301, USA; either version 2 of the License, or
## (at your option) any later version; incorporated herein by reference.
##
## -----------------------------------------------------------------------
##
-## samples for syslinux users
+## Hardware Detection Tool
##
topdir = ../..
-include $(topdir)/MCONFIG.embedded
+include ../MCONFIG
-MODULES = hdt.c32
+LIBS = ../cmenu/libmenu/libmenu.a ../libutil/libutil_com.a \
+ ../lib/libcom32.a $(LIBGCC)
+CFLAGS += -I$(com32)/cmenu/libmenu
-INCLUDES = -I$(com32)/include -I$(com32)/cmenu/libmenu -I$(com32)/gplinclude\
- -I$(com32)/libutil/include
+MODULES = hdt.c32
+TESTFILES =
-LIBGCC := $(shell $(CC) $(GCCOPT) --print-libgcc)
-LIB = liboldcom32.a
+OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
-com32 = $(topdir)/com32
-LIBS = $(LIB) $(com32)/cmenu/libmenu/libmenu.a \
- $(com32)/gpllib/libcom32gpl.a \
- $(com32)/libutil/libutil_com.a $(com32)/lib/libcom32.a \
- $(LIBGCC)
+all: $(MODULES) $(TESTFILES)
-LDFLAGS = -m elf_i386 -T $(com32)/lib/com32.ld
-
-all: $(MODULES) $(LIB)
-
-.PRECIOUS: %.o
-%.o: %.S
- $(CC) $(SFLAGS) -c -o $@ $<
-
-.PRECIOUS: %.o
-%.o: %.c
- @$(CC) $(CFLAGS) -std=gnu99 -D__COM32__ -c -o $@ $<
-
-.PRECIOUS: %.elf
-%.elf: c32entry.o %.o $(LIB)
- @$(LD) -Ttext 0x101000 -e _start -o $@ $^
-
-hdt.elf: hdt.o hdt-ata.o hdt-menu.o hdt-menu-pci.o hdt-menu-kernel.o \
- hdt-menu-disk.o hdt-menu-dmi.o hdt-menu-processor.o \
- hdt-menu-syslinux.o hdt-menu-about.o \
- hdt-cli.o hdt-cli-hdt.o hdt-common.o hdt-cli-pci.o hdt-cli-dmi.o \
- hdt-cli-cpu.o hdt-cli-pxe.o hdt-cli-kernel.o \
- hdt-cli-syslinux.o hdt-cli-vesa.o\
- hdt-menu-pxe.o hdt-menu-summary.o hdt-menu-vesa.o\
- lib-ansi.o\
- $(LIBS)
- @$(LD) $(LDFLAGS) -o $@ $^
-
-%.c32: %.elf
- @$(OBJCOPY) -O binary $< $@
-
-%.com: %.asm
- @$(NASM) $(NASMOPT) -f bin -o $@ -l $*.lst $<
-
-$(LIB):
- @rm -f $@
- @$(AR) cq $@ $^
- @$(RANLIB) $@
+hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
+ $(LD) $(LDFLAGS) -o $@ $^
tidy dist:
- @rm -f *.o *.a *.lst *.elf
-
-install: all
+ rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
-# Don't specify *.com since mdiskchk.com can't be built using Linux tools
clean: tidy
- @rm -f *.o *.c32 *.c~ *.h~ Makefile~
+ rm -f *.lnx
spotless: clean
+ rm -f *.lss *.c32 *.com
+ rm -f *~ \#*
+
+install:
+
+-include .*.d
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 1386a771..d02533ce 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -102,6 +102,7 @@ void init_hardware(struct s_hardware *hardware)
memset(hardware->pciids_path, 0, sizeof hardware->pciids_path);
memset(hardware->modules_pcimap_path, 0,
sizeof hardware->modules_pcimap_path);
+ memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
strcat(hardware->pciids_path, "pci.ids");
strcat(hardware->modules_pcimap_path, "modules.pcimap");
strcat(hardware->memtest_label, "memtest");
diff --git a/com32/include/com32.h b/com32/include/com32.h
index 8be87211..44cd5732 100644
--- a/com32/include/com32.h
+++ b/com32/include/com32.h
@@ -1,6 +1,29 @@
/* ----------------------------------------------------------------------- *
- * Not Copyright 2002-2008 H. Peter Anvin
- * This file is in the public domain.
+ *
+ * Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
* ----------------------------------------------------------------------- */
/*
@@ -75,6 +98,7 @@ extern struct com32_sys_args {
uint32_t cs_bounce_size;
void __cdecl (*cs_farcall)(uint32_t, const com32sys_t *, com32sys_t *);
int __cdecl (*cs_cfarcall)(uint32_t, const void *, uint32_t);
+ uint32_t cs_memsize;
} __com32;
/*
diff --git a/com32/include/syslinux/advconst.h b/com32/include/syslinux/advconst.h
index 1e1ec73e..b7c775fd 100644
--- a/com32/include/syslinux/advconst.h
+++ b/com32/include/syslinux/advconst.h
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -39,5 +40,6 @@
#define ADV_END 0
#define ADV_BOOTONCE 1
+#define ADV_MENUSAVE 2
#endif /* _SYSLINUX_ADVCONST_H */
diff --git a/com32/include/syslinux/align.h b/com32/include/syslinux/align.h
new file mode 100644
index 00000000..5b01bf27
--- /dev/null
+++ b/com32/include/syslinux/align.h
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Intel Corporation; author H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _SYSLINUX_ALIGN_H
+#define _SYSLINUX_ALIGN_H
+
+#include <stdint.h>
+
+static inline uintptr_t __align_down(uintptr_t __p, uintptr_t __a)
+{
+ return __p & ~(__a - 1);
+}
+static inline uintptr_t __align_up(uintptr_t __p, uintptr_t __a)
+{
+ return (__p + __a - 1) & ~(__a - 1);
+}
+
+#define ALIGN_UP(p,a) ((__typeof__(p))__align_up((uintptr_t)(p), (a)))
+#define ALIGN_DOWN(p,a) ((__typeof__(p))__align_down((uintptr_t)(p), (a)))
+#define ALIGN_UP_FOR(p,t) ALIGN_UP(p,sizeof(t))
+#define ALIGN_DOWN_FOR(p,t) ALIGN_DOWN(p,sizeof(t))
+
+#endif /* _SYSLINUX_ALIGN_H */
diff --git a/com32/include/syslinux/config.h b/com32/include/syslinux/config.h
index ed4bf247..ade2c4b1 100644
--- a/com32/include/syslinux/config.h
+++ b/com32/include/syslinux/config.h
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/com32/include/syslinux/keyboard.h b/com32/include/syslinux/keyboard.h
index 9d4f1409..8f21ad07 100644
--- a/com32/include/syslinux/keyboard.h
+++ b/com32/include/syslinux/keyboard.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/com32/include/syslinux/memscan.h b/com32/include/syslinux/memscan.h
new file mode 100644
index 00000000..24c4edaf
--- /dev/null
+++ b/com32/include/syslinux/memscan.h
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef _SYSLINUX_MEMSCAN_H
+#define _SYSLINUX_MEMSCAN_H
+
+#include <stdbool.h>
+#include <syslinux/movebits.h> /* addr_t */
+
+typedef int (*scan_memory_callback_t)(void *, addr_t, addr_t, bool);
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data);
+
+#endif /* _SYSLINUX_MEMSCAN_H */
diff --git a/com32/include/syslinux/movebits.h b/com32/include/syslinux/movebits.h
index f35ef228..ff3711ee 100644
--- a/com32/include/syslinux/movebits.h
+++ b/com32/include/syslinux/movebits.h
@@ -59,8 +59,13 @@ int syslinux_add_movelist(struct syslinux_movelist **,
addr_t dst, addr_t src, addr_t len);
int syslinux_allocate_from_list(struct syslinux_movelist **freelist,
addr_t dst, addr_t len);
-int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
- struct syslinux_memmap *memmap);
+int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap,
+ addr_t entry_point, addr_t entry_type,
+ uint16_t bootflags);
+struct syslinux_memmap *
+syslinux_target_memmap(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap);
/* Operatons on struct syslinux_memmap */
struct syslinux_memmap *syslinux_init_memmap(void);
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index 6c137f9d..984c6dff 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -84,6 +84,8 @@ LIBOBJS = \
syslinux/ipappend.o syslinux/dsinfo.o syslinux/version.o \
syslinux/keyboard.o \
\
+ syslinux/memscan.o \
+ \
syslinux/addlist.o syslinux/freelist.o syslinux/memmap.o \
syslinux/movebits.o syslinux/shuffle.o syslinux/shuffle_pm.o \
syslinux/shuffle_rm.o syslinux/zonelist.o \
diff --git a/com32/lib/free.c b/com32/lib/free.c
index aa17080d..20044078 100644
--- a/com32/lib/free.c
+++ b/com32/lib/free.c
@@ -58,6 +58,42 @@ __free_block(struct free_arena_header *ah)
return ah;
}
+/*
+ * This is used to insert a block which is not previously on the
+ * free list. Only the a.size field of the arena header is assumed
+ * to be valid.
+ */
+void __inject_free_block(struct free_arena_header *ah)
+{
+ struct free_arena_header *nah;
+ size_t a_end = (size_t)ah + ah->a.size;
+ size_t n_end;
+
+ for (nah = __malloc_head.a.next; nah->a.type != ARENA_TYPE_HEAD;
+ nah = nah->a.next) {
+ n_end = (size_t)nah + nah->a.size;
+
+ /* Is nah entirely beyond this block? */
+ if ((size_t)nah >= a_end)
+ break;
+
+ /* Is this block entirely beyond nah? */
+ if ((size_t)ah >= n_end)
+ continue;
+
+ /* Otherwise we have some sort of overlap - reject this block */
+ return;
+ }
+
+ /* Now, nah should point to the successor block */
+ ah->a.next = nah;
+ ah->a.prev = nah->a.prev;
+ nah->a.prev = ah;
+ ah->a.prev->a.next = ah;
+
+ __free_block(ah);
+}
+
void free(void *ptr)
{
struct free_arena_header *ah;
diff --git a/com32/lib/malloc.c b/com32/lib/malloc.c
index 2f8362b4..40e88b49 100644
--- a/com32/lib/malloc.c
+++ b/com32/lib/malloc.c
@@ -5,6 +5,9 @@
*/
#include <stdlib.h>
+#include <string.h>
+#include <com32.h>
+#include <syslinux/memscan.h>
#include "init.h"
#include "malloc.h"
@@ -31,6 +34,39 @@ static inline size_t sp(void)
return sp;
}
+#define E820_MEM_MAX 0xfff00000 /* 4 GB - 1 MB */
+
+static int consider_memory_area(void *dummy, addr_t start,
+ addr_t len, bool valid)
+{
+ struct free_arena_header *fp;
+ addr_t end;
+
+ (void)dummy;
+
+ if (valid && start < E820_MEM_MAX) {
+ if (len > E820_MEM_MAX - start)
+ len = E820_MEM_MAX - start;
+
+ end = start + len;
+
+ if (end > __com32.cs_memsize) {
+ if (start <= __com32.cs_memsize) {
+ start = __com32.cs_memsize;
+ len = end - start;
+ }
+
+ if (len >= 2*sizeof(struct arena_header)) {
+ fp = (struct free_arena_header *)start;
+ fp->a.size = len;
+ __inject_free_block(fp);
+ }
+ }
+ }
+
+ return 0;
+}
+
static void __constructor init_memory_arena(void)
{
struct free_arena_header *fp;
@@ -46,14 +82,15 @@ static void __constructor init_memory_arena(void)
__stack_size = total_space - 4*sizeof(struct arena_header);
fp = (struct free_arena_header *)start;
- fp->a.type = ARENA_TYPE_FREE;
fp->a.size = total_space - __stack_size;
- /* Insert into chains */
- fp->a.next = fp->a.prev = &__malloc_head;
- fp->next_free = fp->prev_free = &__malloc_head;
- __malloc_head.a.next = __malloc_head.a.prev = fp;
- __malloc_head.next_free = __malloc_head.prev_free = fp;
+ __inject_free_block(fp);
+
+ /* Scan the memory map to look for other suitable regions */
+ if (!__com32.cs_memsize)
+ return; /* Old Syslinux core, can't do this... */
+
+ syslinux_scan_memory(consider_memory_area, NULL);
}
static void *__malloc_from_block(struct free_arena_header *fp, size_t size)
diff --git a/com32/lib/malloc.h b/com32/lib/malloc.h
index 830377d9..983a3c52 100644
--- a/com32/lib/malloc.h
+++ b/com32/lib/malloc.h
@@ -52,3 +52,5 @@ struct free_arena_header {
};
extern struct free_arena_header __malloc_head;
+void __inject_free_block(struct free_arena_header *ah);
+
diff --git a/com32/lib/sys/ansicon_write.c b/com32/lib/sys/ansicon_write.c
index 01d69da1..7bdc8cbd 100644
--- a/com32/lib/sys/ansicon_write.c
+++ b/com32/lib/sys/ansicon_write.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/com32/lib/sys/argv.c b/com32/lib/sys/argv.c
index 0d16bfe6..b405a8d7 100644
--- a/com32/lib/sys/argv.c
+++ b/com32/lib/sys/argv.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -35,8 +36,7 @@
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
-
-#define ALIGN_UP(p,t) ((t *)(((uintptr_t)(p) + (sizeof(t)-1)) & ~(sizeof(t)-1)))
+#include <syslinux/align.h>
extern char _end[]; /* Symbol created by linker */
void *__mem_end = &_end; /* Global variable for use by malloc() */
@@ -75,7 +75,7 @@ int __parse_argv(char ***argv, const char *str)
}
/* Now create argv */
- arg = ALIGN_UP(q,char *);
+ arg = ALIGN_UP_FOR(q, char *);
*argv = arg;
*arg++ = argv0; /* argv[0] */
diff --git a/com32/lib/sys/entry.S b/com32/lib/sys/entry.S
index ed5da95f..53bf2ecb 100644
--- a/com32/lib/sys/entry.S
+++ b/com32/lib/sys/entry.S
@@ -30,7 +30,7 @@
*/
/* Number of arguments in our version of the entry structure */
-#define COM32_ARGS 6
+#define COM32_ARGS 7
.section ".init","ax"
.globl _start
diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c
index 48c1ed44..7ca25ac7 100644
--- a/com32/lib/sys/vesacon_write.c
+++ b/com32/lib/sys/vesacon_write.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/com32/lib/syslinux/dsinfo.c b/com32/lib/syslinux/dsinfo.c
index b3d3b3cd..60f7e998 100644
--- a/com32/lib/syslinux/dsinfo.c
+++ b/com32/lib/syslinux/dsinfo.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/com32/lib/syslinux/keyboard.c b/com32/lib/syslinux/keyboard.c
index 2635dfb9..2b31b270 100644
--- a/com32/lib/syslinux/keyboard.c
+++ b/com32/lib/syslinux/keyboard.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -38,7 +38,7 @@ void __constructor __syslinux_get_keyboard_map(void)
__intcall(0x22, &reg, &reg);
if (!(reg.eflags.l & EFLAGS_CF)) {
__syslinux_keyboard_map.version = reg.eax.w[0];
- __syslinux_keyboard_map.length = reg.edx.w[0];
+ __syslinux_keyboard_map.length = reg.ecx.w[0];
__syslinux_keyboard_map.map = MK_PTR(reg.es, reg.ebx.w[0]);
}
}
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index cca2efd0..41ebcb70 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 H. Peter Anvin - All Rights Reserved
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -31,9 +32,11 @@
* Load a Linux kernel (Image/zImage/bzImage).
*/
+#include <stdbool.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
+#include <syslinux/align.h>
#include <syslinux/linux.h>
#include <syslinux/bootrm.h>
#include <syslinux/movebits.h>
@@ -159,6 +162,7 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
struct syslinux_movelist *fraglist = NULL;
struct syslinux_memmap *mmap = NULL;
struct syslinux_memmap *amap = NULL;
+ bool ok;
cmdline_size = strlen(cmdline)+1;
@@ -189,6 +193,9 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
if (!memlimit || memlimit-1 > hdr.initrd_addr_max)
memlimit = hdr.initrd_addr_max+1; /* Zero for no limit */
+ if (hdr.version < 0x0205)
+ hdr.relocatable_kernel = 0;
+
if (hdr.version < 0x0206)
hdr.cmdline_max_len = 256;
@@ -250,7 +257,79 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
/* Place the kernel in memory */
+ /* First, find a suitable place for the protected-mode code */
+ if (syslinux_memmap_type(amap, prot_mode_base, prot_mode_size)
+ != SMT_FREE) {
+ const struct syslinux_memmap *mp;
+ if (!hdr.relocatable_kernel)
+ goto bail; /* Can't relocate - no hope */
+
+ ok = false;
+ for (mp = amap; mp; mp = mp->next) {
+ addr_t start, end;
+ start = mp->start;
+ end = mp->next->start;
+
+ if (mp->type != SMT_FREE)
+ continue;
+
+ if (end <= prot_mode_base)
+ continue; /* Only relocate upwards */
+
+ if (start <= prot_mode_base)
+ start = prot_mode_base;
+
+ start = ALIGN_UP(start, hdr.kernel_alignment);
+ if (start >= end)
+ continue;
+
+ /* The 3* here is a total fudge factor... it's supposed to
+ account for the fact that the kernel needs to be decompressed,
+ and then followed by the BSS and BRK regions. This doesn't,
+ however, account for the fact that the kernel is decompressed
+ into a whole other place, either. */
+ if (end - start >= 3*prot_mode_size) {
+ prot_mode_base = start;
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok)
+ goto bail;
+ }
+
/* Real mode code */
+ if (syslinux_memmap_type(amap, real_mode_base,
+ cmdline_offset+cmdline_size) != SMT_FREE) {
+ const struct syslinux_memmap *mp;
+
+ ok = false;
+ for (mp = amap; mp; mp = mp->next) {
+ addr_t start, end;
+ start = mp->start;
+ end = mp->next->start;
+
+ if (mp->type != SMT_FREE)
+ continue;
+
+ if (start < real_mode_base)
+ start = real_mode_base; /* Lowest address we'll use */
+ if (end > 640*1024)
+ end = 640*1024;
+
+ start = ALIGN_UP(start, 16);
+ if (start > 0x90000 || start >= end)
+ continue;
+
+ if (end - start >= cmdline_offset+cmdline_size) {
+ real_mode_base = start;
+ ok = true;
+ break;
+ }
+ }
+ }
+
if (syslinux_add_movelist(&fraglist, real_mode_base, (addr_t)kernel_buf,
real_mode_size))
goto bail;
diff --git a/com32/lib/syslinux/memmap.c b/com32/lib/syslinux/memmap.c
index 105c9473..9fdda886 100644
--- a/com32/lib/syslinux/memmap.c
+++ b/com32/lib/syslinux/memmap.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -32,131 +33,35 @@
*/
#include <assert.h>
-#include <stdio.h>
-#include <errno.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <inttypes.h>
-#include <setjmp.h>
-#include <string.h>
-#include <com32.h>
+#include <syslinux/memscan.h>
#include <syslinux/movebits.h>
-struct e820_entry {
- uint64_t start;
- uint64_t len;
- uint32_t type;
- uint32_t extattr;
-};
+static int syslinux_memory_map_callback(void *map, addr_t start,
+ addr_t len, bool valid)
+{
+ struct syslinux_memmap **mmap = map;
+ return syslinux_add_memmap(mmap, start, len,
+ valid ? SMT_FREE : SMT_RESERVED);
+}
struct syslinux_memmap *syslinux_memory_map(void)
{
- static com32sys_t ireg, zireg;
- com32sys_t oreg;
- struct e820_entry *e820buf = __com32.cs_bounce;
- uint64_t start, len, maxlen;
- int memfound = 0;
struct syslinux_memmap *mmap;
enum syslinux_memmap_types type;
+ int rv;
mmap = syslinux_init_memmap();
if (!mmap)
- goto bail;
+ return NULL;
- /* Use INT 12h to get DOS memory above 0x7c00 */
- __intcall(0x12, &zireg, &oreg);
- if (oreg.eax.w[0] > 31 && oreg.eax.w[0] <= 640) {
- addr_t dosmem = (oreg.eax.w[0] << 10) - 0x7c00;
- if (syslinux_add_memmap(&mmap, 0x7c00, dosmem, SMT_FREE))
- goto bail;
- }
-
- /* First try INT 15h AX=E820h */
- ireg.eax.l = 0xe820;
- ireg.edx.l = 0x534d4150;
- ireg.ebx.l = 0;
- ireg.ecx.l = sizeof(*e820buf);
- ireg.es = SEG(e820buf);
- ireg.edi.w[0] = OFFS(e820buf);
- memset(e820buf, 0, sizeof *e820buf);
- e820buf->extattr = 1;
-
- do {
- __intcall(0x15, &ireg, &oreg);
-
- if ((oreg.eflags.l & EFLAGS_CF) ||
- (oreg.eax.l != 0x534d4150) ||
- (oreg.ecx.l < 20))
- break;
-
- if (oreg.ecx.l < 24)
- e820buf->extattr = 1; /* Enabled, normal */
-
- if (!(e820buf->extattr & 1))
- continue;
-
- type = e820buf->type == 1 ? SMT_FREE : SMT_RESERVED;
- start = e820buf->start;
- len = e820buf->len;
-
- if (start < 0x100000000ULL) {
- /* Don't rely on E820 being valid for low memory. Doing so
- could mean stuff like overwriting the PXE stack even when
- using "keeppxe", etc. */
- if (start < 0x100000ULL) {
- if (len > 0x100000ULL-start)
- len -= 0x100000ULL-start;
- else
- len = 0;
- start = 0x100000ULL;
- }
-
- maxlen = 0x100000000ULL-start;
- if (len > maxlen)
- len = maxlen;
-
- if (len) {
- if (syslinux_add_memmap(&mmap, (addr_t)start, (addr_t)len, type))
- goto bail;
- memfound = 1;
- }
- }
-
- ireg.ebx.l = oreg.ebx.l;
- } while (oreg.ebx.l);
-
- if (memfound)
- return mmap;
-
- /* Next try INT 15h AX=E801h */
- ireg.eax.w[0] = 0xe801;
- __intcall(0x15, &ireg, &oreg);
-
- if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) {
- if (syslinux_add_memmap(&mmap, (addr_t)1 << 20, oreg.ecx.w[0] << 10,
- SMT_FREE))
- goto bail;
-
- if (oreg.edx.w[0]) {
- if (syslinux_add_memmap(&mmap, (addr_t)16 << 20, oreg.edx.w[0] << 16,
- SMT_FREE))
- goto bail;
- }
-
- return mmap;
- }
-
- /* Finally try INT 15h AH=88h */
- ireg.eax.w[0] = 0x8800;
- if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) {
- if (syslinux_add_memmap(&mmap, (addr_t)1 << 20, oreg.ecx.w[0] << 10,
- SMT_FREE))
- goto bail;
+ if (syslinux_scan_memory(syslinux_memory_map_callback, &mmap)) {
+ syslinux_free_memmap(mmap);
+ return NULL;
}
return mmap;
-
- bail:
- syslinux_free_memmap(mmap);
- return NULL;
}
diff --git a/com32/lib/syslinux/memscan.c b/com32/lib/syslinux/memscan.c
new file mode 100644
index 00000000..782f6346
--- /dev/null
+++ b/com32/lib/syslinux/memscan.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * memscan.c
+ *
+ * Query the system for free memory
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <com32.h>
+
+#include <syslinux/memscan.h>
+
+struct e820_entry {
+ uint64_t start;
+ uint64_t len;
+ uint32_t type;
+ uint32_t extattr;
+};
+
+int syslinux_scan_memory(scan_memory_callback_t callback, void *data)
+{
+ static com32sys_t ireg;
+ com32sys_t oreg;
+ struct e820_entry *e820buf = __com32.cs_bounce;
+ uint64_t start, len, maxlen;
+ int memfound = 0;
+ int rv;
+ addr_t dosmem;
+
+ /* Use INT 12h to get DOS memory above 0x504 */
+ __intcall(0x12, &__com32_zero_regs, &oreg);
+ dosmem = oreg.eax.w[0] << 10;
+ if (dosmem < 32*1024 || dosmem > 640*1024) {
+ /* INT 12h reports nonsense... now what? */
+ uint16_t ebda_seg = (uint16_t *)0x40e;
+ if (ebda_seg >= 0x8000 && ebda_seg < 0xa000)
+ dosmem = ebda_seg << 4;
+ else
+ dosmem = 640*1024; /* Hope for the best... */
+ }
+ dosmem = (oreg.eax.w[0] << 10) - 0x510;
+ rv = callback(data, 0x510, dosmem, true);
+ if (rv)
+ return rv;
+
+ /* First try INT 15h AX=E820h */
+ ireg.eax.l = 0xe820;
+ ireg.edx.l = 0x534d4150;
+ ireg.ebx.l = 0;
+ ireg.ecx.l = sizeof(*e820buf);
+ ireg.es = SEG(e820buf);
+ ireg.edi.w[0] = OFFS(e820buf);
+ memset(e820buf, 0, sizeof *e820buf);
+ /* Set this in case the BIOS doesn't, but doesn't change %ecx to match. */
+ e820buf->extattr = 1;
+
+ do {
+ __intcall(0x15, &ireg, &oreg);
+
+ if ((oreg.eflags.l & EFLAGS_CF) ||
+ (oreg.eax.l != 0x534d4150) ||
+ (oreg.ecx.l < 20))
+ break;
+
+ if (oreg.ecx.l < 24)
+ e820buf->extattr = 1; /* Enabled, normal */
+
+ if (!(e820buf->extattr & 1))
+ continue;
+
+ start = e820buf->start;
+ len = e820buf->len;
+
+ if (start < 0x100000000ULL) {
+ /* Don't rely on E820 being valid for low memory. Doing so
+ could mean stuff like overwriting the PXE stack even when
+ using "keeppxe", etc. */
+ if (start < 0x100000ULL) {
+ if (len > 0x100000ULL-start)
+ len -= 0x100000ULL-start;
+ else
+ len = 0;
+ start = 0x100000ULL;
+ }
+
+ maxlen = 0x100000000ULL-start;
+ if (len > maxlen)
+ len = maxlen;
+
+ if (len) {
+ rv = callback(data, (addr_t)start, (addr_t)len, e820buf->type == 1);
+ if (rv)
+ return rv;
+ memfound = 1;
+ }
+ }
+
+ ireg.ebx.l = oreg.ebx.l;
+ } while (oreg.ebx.l);
+
+ if (memfound)
+ return 0;
+
+ /* Next try INT 15h AX=E801h */
+ ireg.eax.w[0] = 0xe801;
+ __intcall(0x15, &ireg, &oreg);
+
+ if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) {
+ rv = callback(data, (addr_t)1 << 20, oreg.ecx.w[0] << 10, true);
+ if (rv)
+ return rv;
+
+ if (oreg.edx.w[0]) {
+ rv = callback(data, (addr_t)16 << 20, oreg.edx.w[0] << 16, true);
+ if (rv)
+ return rv;
+ }
+
+ return 0;
+ }
+
+ /* Finally try INT 15h AH=88h */
+ ireg.eax.w[0] = 0x8800;
+ if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) {
+ rv = callback(data, (addr_t)1 << 20, oreg.ecx.w[0] << 10, true);
+ if (rv)
+ return rv;
+ }
+
+ return 0;
+}
diff --git a/com32/lib/syslinux/setadv.c b/com32/lib/syslinux/setadv.c
index 4af8d6e1..5993df6d 100644
--- a/com32/lib/syslinux/setadv.c
+++ b/com32/lib/syslinux/setadv.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -47,7 +48,7 @@
int syslinux_setadv(int tag, size_t size, const void *data)
{
uint8_t *p, *advtmp;
- size_t left;
+ size_t rleft, left;
if ((unsigned)tag-1 > 254) {
errno = EINVAL;
@@ -59,11 +60,11 @@ int syslinux_setadv(int tag, size_t size, const void *data)
return -1;
}
- left = syslinux_adv_size();
+ rleft = left = syslinux_adv_size();
p = advtmp = alloca(left);
memcpy(p, syslinux_adv_ptr(), left); /* Make working copy */
- while (left >= 2) {
+ while (rleft >= 2) {
uint8_t ptag = p[0];
size_t plen = p[1]+2;
@@ -73,17 +74,19 @@ int syslinux_setadv(int tag, size_t size, const void *data)
if (ptag == tag) {
/* Found our tag. Delete it. */
- if (plen >= left) {
+ if (plen >= rleft) {
/* Entire remainder is our tag */
break;
}
- memmove(p, p+plen, left-plen);
+ memmove(p, p+plen, rleft-plen);
+ rleft -= plen; /* Fewer bytes to read, but not to write */
} else {
/* Not our tag */
- if (plen > left)
+ if (plen > rleft)
break; /* Corrupt tag (overrun) - overwrite it */
left -= plen;
+ rleft -= plen;
p += plen;
}
}
@@ -100,6 +103,7 @@ int syslinux_setadv(int tag, size_t size, const void *data)
*p++ = tag;
*p++ = size;
memcpy(p, data, size);
+ p += size;
left -= size+2;
}
diff --git a/com32/lib/syslinux/shuffle.c b/com32/lib/syslinux/shuffle.c
index b891722d..196fc64a 100644
--- a/com32/lib/syslinux/shuffle.c
+++ b/com32/lib/syslinux/shuffle.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -62,33 +63,42 @@ struct shuffle_descriptor {
uint32_t dst, src, len;
};
-static int desc_block_size;
+static int shuffler_size;
-static void __constructor __syslinux_get_desc_block_size(void)
+static void __constructor __syslinux_get_shuffer_size(void)
{
static com32sys_t reg;
- reg.eax.w[0] = 0x0011;
+ reg.eax.w[0] = 0x0023;
__intcall(0x22, &reg, &reg);
- desc_block_size = (reg.eflags.l & EFLAGS_CF) ? 64 : reg.ecx.w[0];
+ shuffler_size = (reg.eflags.l & EFLAGS_CF) ? 2048 : reg.ecx.w[0];
}
-/* Allocate descriptor memory in these chunks */
-#define DESC_BLOCK_SIZE desc_block_size
+/*
+ * Allocate descriptor memory in these chunks; if this is large we may
+ * waste memory, if it is small we may get slow convergence.
+ */
+#define DESC_BLOCK_SIZE 256
-int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
- struct syslinux_memmap *memmap)
+int syslinux_do_shuffle(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap,
+ addr_t entry_point, addr_t entry_type,
+ uint16_t bootflags)
{
+ int rv = -1;
struct syslinux_movelist *moves = NULL, *mp;
struct syslinux_memmap *rxmap = NULL, *ml;
struct shuffle_descriptor *dp, *dbuf;
- int np, nb, nl, rv = -1;
+ int np;
int desc_blocks, need_blocks;
int need_ptrs;
addr_t desczone, descfree, descaddr, descoffs;
int nmoves, nzero;
- struct shuffle_descriptor primaries[2];
+ com32sys_t ireg;
+
+ descaddr = 0;
+ dp = dbuf = NULL;
/* Count the number of zero operations */
nzero = 0;
@@ -98,11 +108,15 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
}
/* Find the largest contiguous region unused by input *and* output;
- this is where we put the move descriptor list */
+ this is where we put the move descriptor list and safe area */
rxmap = syslinux_dup_memmap(memmap);
if (!rxmap)
goto bail;
+ /* Avoid using the low 1 MB for the shuffle area -- this avoids
+ possible interference with the real mode code or stack */
+ if (syslinux_add_memmap(&rxmap, 0, 1024*1024, SMT_RESERVED))
+ goto bail;
for (mp = fraglist; mp; mp = mp->next) {
if (syslinux_add_memmap(&rxmap, mp->src, mp->len, SMT_ALLOC) ||
syslinux_add_memmap(&rxmap, mp->dst, mp->len, SMT_ALLOC))
@@ -119,10 +133,13 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
if (!rxmap)
goto bail;
- desc_blocks = (nzero+DESC_BLOCK_SIZE-1)/(DESC_BLOCK_SIZE-1);
+ desc_blocks = (nzero+DESC_BLOCK_SIZE-1)/DESC_BLOCK_SIZE;
for (;;) {
+ /* We want (desc_blocks) allocation blocks, plus the terminating
+ descriptor, plus the shuffler safe area. */
addr_t descmem = desc_blocks*
- sizeof(struct shuffle_descriptor)*DESC_BLOCK_SIZE;
+ sizeof(struct shuffle_descriptor)*DESC_BLOCK_SIZE
+ + sizeof(struct shuffle_descriptor) + shuffler_size;
if (descfree < descmem)
goto bail; /* No memory block large enough */
@@ -143,7 +160,7 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
for (mp = moves; mp; mp = mp->next)
nmoves++;
- need_blocks = (nmoves+nzero+DESC_BLOCK_SIZE-1)/(DESC_BLOCK_SIZE-1);
+ need_blocks = (nmoves+nzero+DESC_BLOCK_SIZE-1)/DESC_BLOCK_SIZE;
if (desc_blocks >= need_blocks)
break; /* Sufficient memory, yay */
@@ -159,7 +176,7 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
syslinux_free_memmap(rxmap);
rxmap = NULL;
- need_ptrs = nmoves+nzero+desc_blocks-1;
+ need_ptrs = nmoves+nzero+1;
dbuf = malloc(need_ptrs*sizeof(struct shuffle_descriptor));
if (!dbuf)
goto bail;
@@ -173,71 +190,38 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
/* Copy the move sequence into the descriptor buffer */
np = 0;
- nb = 0;
- nl = nmoves+nzero;
dp = dbuf;
for (mp = moves; mp; mp = mp->next) {
- if (nb == DESC_BLOCK_SIZE-1) {
- dp->dst = -1; /* Load new descriptors */
- dp->src = (addr_t)(dp+1) + descoffs;
- dp->len = sizeof(*dp)*min(nl, DESC_BLOCK_SIZE);
- dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
- dp++; np++;
- nb = 0;
- }
-
dp->dst = mp->dst;
dp->src = mp->src;
dp->len = mp->len;
dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
- dp++; np++; nb++; nl--;
+ dp++; np++;
}
/* Copy bzero operations into the descriptor buffer */
for (ml = memmap; ml->type != SMT_END; ml = ml->next) {
if (ml->type == SMT_ZERO) {
- if (nb == DESC_BLOCK_SIZE-1) {
- dp->dst = (addr_t)-1; /* Load new descriptors */
- dp->src = (addr_t)(dp+1) + descoffs;
- dp->len = sizeof(*dp)*min(nl, DESC_BLOCK_SIZE);
- dprintf("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
- dp++; np++;
- nb = 0;
- }
-
dp->dst = ml->start;
dp->src = (addr_t)-1; /* bzero region */
dp->len = ml->next->start - ml->start;
dprintf2("[ %08x %08x %08x ]\n", dp->dst, dp->src, dp->len);
- dp++; np++; nb++; nl--;
+ dp++; np++;
}
}
+ /* Finally, record the termination entry */
+ dp->dst = entry_point;
+ dp->src = entry_type;
+ dp->len = 0;
+ dp++; np++;
+
if (np != need_ptrs) {
dprintf("!!! np = %d : nmoves = %d, nzero = %d, desc_blocks = %d\n",
np, nmoves, nzero, desc_blocks);
}
- /* Set up the primary descriptors in the bounce buffer.
- The first one moves the descriptor list into its designated safe
- zone, the second one loads the first descriptor block. */
- dp = primaries;
-
- dp->dst = descaddr;
- dp->src = (addr_t)dbuf;
- dp->len = np*sizeof(*dp);
- dprintf("< %08x %08x %08x >\n", dp->dst, dp->src, dp->len);
- dp++;
-
- dp->dst = (addr_t)-1;
- dp->src = descaddr;
- dp->len = sizeof(*dp)*min(np, DESC_BLOCK_SIZE);
- dprintf("< %08x %08x %08x >\n", dp->dst, dp->src, dp->len);
- dp++;
-
- memcpy(__com32.cs_bounce, primaries, 2*sizeof(*dp));
-
- rv = 2; /* Always two primaries */
+ rv = 0;
bail:
/* This is safe only because free() doesn't use the bounce buffer!!!! */
@@ -246,5 +230,42 @@ int syslinux_prepare_shuffle(struct syslinux_movelist *fraglist,
if (rxmap)
syslinux_free_memmap(rxmap);
- return rv;
+ if (rv)
+ return rv;
+
+ /* Actually do it... */
+ memset(&ireg, 0, sizeof ireg);
+ ireg.edi.l = descaddr;
+ ireg.esi.l = (addr_t)dbuf;
+ ireg.ecx.l = (addr_t)dp-(addr_t)dbuf;
+ ireg.edx.w[0] = bootflags;
+ ireg.eax.w[0] = 0x0024;
+ __intcall(0x22, &ireg, NULL);
+
+ return -1; /* Shouldn't have returned! */
+}
+
+/*
+ * Common helper routine: takes a memory map and blots out the
+ * zones which are used in the destination of a fraglist
+ */
+struct syslinux_memmap *
+syslinux_target_memmap(struct syslinux_movelist *fraglist,
+ struct syslinux_memmap *memmap)
+{
+ struct syslinux_memmap *tmap;
+ struct syslinux_movelist *mp;
+
+ tmap = syslinux_dup_memmap(memmap);
+ if (!tmap)
+ return NULL;
+
+ for (mp = fraglist; mp; mp = mp->next) {
+ if (syslinux_add_memmap(&tmap, mp->dst, mp->len, SMT_ALLOC)) {
+ syslinux_free_memmap(tmap);
+ return NULL;
+ }
+ }
+
+ return tmap;
}
diff --git a/com32/lib/syslinux/shuffle_pm.c b/com32/lib/syslinux/shuffle_pm.c
index d19d01bb..c9bc0407 100644
--- a/com32/lib/syslinux/shuffle_pm.c
+++ b/com32/lib/syslinux/shuffle_pm.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -46,24 +47,38 @@ int syslinux_shuffle_boot_pm(struct syslinux_movelist *fraglist,
int nd;
com32sys_t ireg;
char *regbuf;
+ uint8_t handoff_code[9*5], *p;
+ const uint32_t *rp;
+ int i, rv;
+ struct syslinux_memmap *tmap;
+ addr_t regstub, stublen, safe;
- nd = syslinux_prepare_shuffle(fraglist, memmap);
- if (nd < 0)
+ tmap = syslinux_target_memmap(fraglist, memmap);
+ if (!tmap)
return -1;
- regbuf = (char *)__com32.cs_bounce + (12*nd);
- memcpy(regbuf, regs, sizeof(*regs));
+ regstub = 0x800; /* Locate anywhere above this point */
+ stublen = sizeof handoff_code;
+ rv = syslinux_memmap_find(tmap, SMT_FREE, &regstub, &stublen);
+ syslinux_free_memmap(tmap);
+ if (rv)
+ return -1;
- memset(&ireg, 0, sizeof ireg);
+ /* Build register-setting stub */
+ p = handoff_code;
+ rp = (const uint32_t *)regs;
+ for (i = 0; i < 8; i++) {
+ *p = 0xb8 + i; /* MOV gpr,imm32 */
+ *(uint32_t *)(p+1) = *rp++;
+ p += 5;
+ }
+ *p = 0xe9; /* JMP */
+ *(uint32_t *)(p+1) = regs->eip - regstub - sizeof handoff_code;
- ireg.eax.w[0] = 0x001a;
- ireg.edx.w[0] = bootflags;
- ireg.es = SEG(__com32.cs_bounce);
- ireg.edi.l = OFFS(__com32.cs_bounce);
- ireg.ecx.l = nd;
- ireg.ds = SEG(regbuf);
- ireg.esi.l = OFFS(regbuf);
- __intcall(0x22, &ireg, NULL);
+ /* Add register-setting stub to shuffle list */
+ if (syslinux_add_movelist(&fraglist, regstub, (addr_t)handoff_code,
+ sizeof handoff_code))
+ return -1;
- return -1; /* Too many descriptors? */
+ return syslinux_do_shuffle(fraglist, memmap, regstub, 1, bootflags);
}
diff --git a/com32/lib/syslinux/shuffle_rm.c b/com32/lib/syslinux/shuffle_rm.c
index e9226a82..4f424f3f 100644
--- a/com32/lib/syslinux/shuffle_rm.c
+++ b/com32/lib/syslinux/shuffle_rm.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -46,24 +47,72 @@ int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist,
int nd;
com32sys_t ireg;
char *regbuf;
+ const struct syslinux_rm_regs_alt {
+ uint16_t seg[6];
+ uint32_t gpr[8];
+ uint32_t csip;
+ } *rp;
+ int i, rv;
+ uint8_t handoff_code[5*5+8*6+5], *p;
+ struct syslinux_memmap *tmap, *tp;
+ addr_t regstub;
- nd = syslinux_prepare_shuffle(fraglist, memmap);
- if (nd < 0)
+ tmap = syslinux_target_memmap(fraglist, memmap);
+ if (!tmap)
return -1;
- regbuf = (char *)__com32.cs_bounce + (12*nd);
- memcpy(regbuf, regs, sizeof(*regs));
+ /* Search for a good place to put the real-mode register stub.
+ We prefer to put it as high as possible in the low 640K. */
+ regstub = 0;
+ for (tp = tmap; tp->type != SMT_END; tp = tp->next) {
+ addr_t xend, xlen;
+ if (tp->start >= 640*1024)
+ continue;
+ if (tp->type != SMT_FREE)
+ continue;
+ xend = tp->next->start;
+ if (xend > 640*1024)
+ xend = 640*1024;
+ xlen = xend - tp->start;
+ if (xlen < sizeof handoff_code)
+ continue;
+ regstub = xend - sizeof handoff_code; /* Best alternative so far */
+ }
- memset(&ireg, 0, sizeof ireg);
+ syslinux_free_memmap(tmap);
- ireg.eax.w[0] = 0x001b;
- ireg.edx.w[0] = bootflags;
- ireg.es = SEG(__com32.cs_bounce);
- ireg.edi.l = OFFS(__com32.cs_bounce);
- ireg.ecx.l = nd;
- ireg.ds = SEG(regbuf);
- ireg.esi.l = OFFS(regbuf);
- __intcall(0x22, &ireg, NULL);
+ /* XXX: it might be possible to do something insane here like
+ putting the stub in the IRQ vectors... */
+ if (!regstub)
+ return -1; /* No space at all */
- return -1; /* Too many descriptors? */
+ /* Build register-setting stub */
+ p = handoff_code;
+ rp = (const struct syslinux_rm_regs_alt *)regs;
+ for (i = 0; i < 6; i++) {
+ if (i != 1) { /* Skip CS */
+ p[0] = 0xb8; /* MOV AX,imm16 */
+ *(uint16_t *)(p+1) = rp->seg[i];
+ *(uint16_t *)(p+3) = 0xc08e + (i << 11); /* MOV seg,AX */
+ p += 5;
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ p[0] = 0x66; /* MOV exx,imm32 */
+ p[1] = 0xb8 + i;
+ *(uint32_t *)(p+2) = rp->gpr[i];
+ p += 6;
+ }
+ *p++ = 0xea; /* JMP FAR */
+ *(uint32_t *)p = rp->csip;
+
+ /* Add register-setting stub to shuffle list */
+ if (syslinux_add_movelist(&fraglist, regstub, (addr_t)handoff_code,
+ sizeof handoff_code))
+ return -1;
+
+ /* Convert regstub to a CS:IP entrypoint pair */
+ regstub = (SEG((void *)regstub) << 16) + OFFS((void *)regstub);
+
+ return syslinux_do_shuffle(fraglist, memmap, regstub, 0, bootflags);
}
diff --git a/com32/lib/syslinux/zonelist.c b/com32/lib/syslinux/zonelist.c
index 62b1cf3e..e3036b1a 100644
--- a/com32/lib/syslinux/zonelist.c
+++ b/com32/lib/syslinux/zonelist.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -201,6 +202,34 @@ int syslinux_memmap_largest(struct syslinux_memmap *list,
}
/*
+ * Find the first (lowest address) zone of a specific type and of
+ * a certain minimum size, with an optional starting address.
+ * The input values of start and len are used as minima.
+ */
+int syslinux_memmap_find(struct syslinux_memmap *list,
+ enum syslinux_memmap_types type,
+ addr_t *start, addr_t *len)
+{
+ addr_t min_start = *start;
+ addr_t min_len = *len;
+
+ while (list->type != SMT_END) {
+ if (list->type == type && list->next->start > min_start) {
+ addr_t xstart = min_start > list->start ? min_start : list->start;
+ addr_t xlen = list->next->start - xstart;
+ if (xlen >= min_len) {
+ *start = xstart;
+ *len = xlen;
+ return 0;
+ }
+ }
+ list = list->next;
+ }
+
+ return -1; /* Not found */
+}
+
+/*
* Free a zonelist.
*/
void syslinux_free_memmap(struct syslinux_memmap *list)
diff --git a/com32/menu/Makefile b/com32/menu/Makefile
index d6293bbd..2a032728 100644
--- a/com32/menu/Makefile
+++ b/com32/menu/Makefile
@@ -44,6 +44,6 @@ spotless: clean
rm -f *.lss *.c32 *.com
rm -f *~ \#*
-install: all
+install:
-include .*.d
diff --git a/com32/menu/menu.h b/com32/menu/menu.h
index e2ffc1bc..43f65947 100644
--- a/com32/menu/menu.h
+++ b/com32/menu/menu.h
@@ -174,6 +174,7 @@ extern struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
/* These are global parameters regardless of which menu we're displaying */
extern int shiftkey;
extern int hiddenmenu;
+extern bool menusave;
extern long long totaltimeout;
void parse_configs(char **argv);
diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c
index f7af90aa..c3da97e4 100644
--- a/com32/menu/menumain.c
+++ b/com32/menu/menumain.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
@@ -27,6 +28,7 @@
#include <setjmp.h>
#include <limits.h>
#include <com32.h>
+#include <syslinux/adv.h>
#include "menu.h"
@@ -875,6 +877,13 @@ run_menu(void)
break;
}
}
+ if (done && !me->passwd) {
+ /* Only save a new default if we don't have a password... */
+ if (menusave && me->label) {
+ syslinux_setadv(ADV_MENUSAVE, strlen(me->label), me->label);
+ syslinux_adv_write();
+ }
+ }
break;
case KEY_UP:
diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c
index 01dadff9..768591d9 100644
--- a/com32/menu/readconfig.c
+++ b/com32/menu/readconfig.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
@@ -11,6 +12,7 @@
* ----------------------------------------------------------------------- */
#include <stdio.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <minmax.h>
@@ -18,6 +20,7 @@
#include <inttypes.h>
#include <colortbl.h>
#include <com32.h>
+#include <syslinux/adv.h>
#include <syslinux/config.h>
#include "menu.h"
@@ -32,6 +35,7 @@ struct menu *root_menu, *start_menu, *hide_menu, *menu_list;
int shiftkey = 0; /* Only display menu if shift key pressed */
int hiddenmenu = 0;
long long totaltimeout = 0;
+bool menusave = false;
/* Keep track of global default */
static int has_ui = 0; /* DEFAULT only counts if UI is found */
@@ -667,6 +671,8 @@ static void parse_config_file(FILE *f)
}
} else if ( looking_at(p, "shiftkey") ) {
shiftkey = 1;
+ } else if ( looking_at(p, "save") ) {
+ menusave = true;
} else if ( looking_at(p, "onerror") ) {
refstr_put(m->onerror);
m->onerror = refstrdup(skipspace(p+7));
@@ -1025,6 +1031,23 @@ void parse_configs(char **argv)
}
}
+ /* If "menu save" is active, let the ADV override the global default */
+ if (menusave) {
+ size_t len;
+ const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
+ char *lstr;
+ if (lbl && len) {
+ lstr = refstr_alloc(len);
+ memcpy(lstr, lbl, len); /* refstr_alloc() adds the final null */
+ me = find_label(lstr);
+ if (me && me->menu != hide_menu) {
+ me->menu->defentry = me->entry;
+ start_menu = me->menu;
+ }
+ refstr_put(lstr);
+ }
+ }
+
/* Final per-menu initialization, with all labels known */
for (m = menu_list; m; m = m->next) {
m->curentry = m->defentry; /* All menus start at their defaults */
diff --git a/com32/modules/Makefile b/com32/modules/Makefile
index 305ea49f..ba76268f 100644
--- a/com32/modules/Makefile
+++ b/com32/modules/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
## Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
@@ -53,6 +54,6 @@ spotless: clean
rm -f *.lss *.c32 *.com
rm -f *~ \#*
-install: all
+install:
-include .*.d
diff --git a/com32/modules/chain.c b/com32/modules/chain.c
index 979ede2d..ead908f2 100644
--- a/com32/modules/chain.c
+++ b/com32/modules/chain.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
@@ -446,79 +447,15 @@ static void do_boot(void *boot_sector, size_t boot_size,
return;
}
- if (loadbase < 0x7c00) {
- /* Special hack: if we are to be loaded below 0x7c00, we need to handle
- the part that goes below 0x7c00 specially, since that's where the
- shuffler lives. To deal with that, stuff the balance at the end
- of low memory and put a small copy stub there.
-
- The only tricky bit is that we need to set up registers for our
- move, and then restore them to what they should be at the end of
- the code. */
- static uint8_t copy_down_code[] = {
- 0xf3,0x66,0xa5, /* 00: rep movsd */
- 0xbe,0,0, /* 03: mov si,0 */
- 0xbf,0,0, /* 06: mov di,0 */
- 0x8e,0xde, /* 09: mov ds,si */
- 0x8e,0xc7, /* 0b: mov es,di */
- 0x66,0xb9,0,0,0,0, /* 0d: mov ecx,0 */
- 0x66,0xbe,0,0,0,0, /* 13: mov esi,0 */
- 0x66,0xbf,0,0,0,0, /* 19: mov edi,0 */
- 0xea,0,0,0,0, /* 1f: jmp 0:0 */
- /* pad out to segment boundary */
- 0x90,0x90,0x90,0x90, /* 24: ... */
- 0x90,0x90,0x90,0x90, /* 28: ... */
- 0x90,0x90,0x90,0x90, /* 2c: ... */
- };
- size_t low_size = min(boot_size, 0x7c00-loadbase);
- size_t high_size = boot_size - low_size;
- size_t low_addr = (0x7c00 + high_size + 15) & ~15;
- size_t move_addr = (low_addr + low_size + 15) & ~15;
- const size_t move_size = sizeof copy_down_code;
-
- if (move_addr+move_size >= dosmem-0x7c00)
- goto too_big;
-
- *(uint16_t *)&copy_down_code[0x04] = regs->ds;
- *(uint16_t *)&copy_down_code[0x07] = regs->es;
- *(uint32_t *)&copy_down_code[0x0f] = regs->ecx.l;
- *(uint32_t *)&copy_down_code[0x15] = regs->esi.l;
- *(uint32_t *)&copy_down_code[0x1b] = regs->edi.l;
- *(uint16_t *)&copy_down_code[0x20] = regs->ip;
- *(uint16_t *)&copy_down_code[0x22] = regs->cs;
-
- regs->ecx.l = (low_size+3) >> 2;
- regs->esi.l = 0;
- regs->edi.l = loadbase & 15;
- regs->ds = low_addr >> 4;
- regs->es = loadbase >> 4;
- regs->cs = move_addr >> 4;
- regs->ip = 0;
-
- endimage = move_addr + move_size;
-
- if (high_size)
- if (syslinux_add_movelist(&mlist, 0x7c00,
- (addr_t)boot_sector+low_size, high_size))
- goto enomem;
- if (syslinux_add_movelist(&mlist, low_addr,
- (addr_t)boot_sector, low_size))
- goto enomem;
- if (syslinux_add_movelist(&mlist, move_addr,
- (addr_t)copy_down_code, move_size))
- goto enomem;
- } else {
- /* Nothing below 0x7c00, much simpler... */
+ /* Nothing below 0x7c00, much simpler... */
- if (boot_size >= dosmem-0x7c00)
+ if (boot_size >= dosmem - loadbase)
goto too_big;
- endimage = loadbase + boot_size;
+ endimage = loadbase + boot_size;
- if (syslinux_add_movelist(&mlist, loadbase, (addr_t)boot_sector,
- boot_size))
- goto enomem;
- }
+ if (syslinux_add_movelist(&mlist, loadbase, (addr_t)boot_sector, boot_size))
+ goto enomem;
if (opt.swap && driveno != swapdrive) {
static const uint8_t swapstub_master[] = {
diff --git a/com32/modules/kbdmap.c b/com32/modules/kbdmap.c
index 866acfc2..7e36a35d 100644
--- a/com32/modules/kbdmap.c
+++ b/com32/modules/kbdmap.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
diff --git a/com32/rosh/Makefile b/com32/rosh/Makefile
index 30dc7d39..3895cd89 100644
--- a/com32/rosh/Makefile
+++ b/com32/rosh/Makefile
@@ -33,6 +33,6 @@ spotless: clean
rm -f *.lss *.c32 *.com
rm -f *~ \#*
-install: # Don't install samples
+install:
-include .*.d
diff --git a/core/Makefile b/core/Makefile
index ce9fd453..16e21dc0 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
## Copyright 1998-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
@@ -117,7 +118,7 @@ tidy dist:
clean: tidy
spotless: clean
- rm -f $(BTARGET) *_bin.c .depend
+ rm -f $(BTARGET) *.bin *_bin.c .depend
# Note: the extra echo '' is to deal with old versions of NASM which
# did not properly terminate the dependency list.
diff --git a/core/abort.inc b/core/abort.inc
index 19cc6419..d8cd7f24 100644
--- a/core/abort.inc
+++ b/core/abort.inc
@@ -1,6 +1,7 @@
; -----------------------------------------------------------------------
;
-; Copyright 2005-2008 H. Peter Anvin - All Rights Reserved
+; Copyright 2005-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
diff --git a/core/bcopy32.inc b/core/bcopy32.inc
index 4ebbe3ca..f058a6f7 100644
--- a/core/bcopy32.inc
+++ b/core/bcopy32.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -26,59 +27,9 @@
; segments, but this stuff is painful enough as it is without having to rely
; on everything happening "as it ought to."
;
-; NOTE: this code is relocated into low memory, just after the .earlybss
-; segment, in order to support to "bcopy over self" operation.
-;
-
- section .bcopy32
- align 8
-__bcopy_start:
-
- ; This is in the .text segment since it needs to be
- ; contiguous with the rest of the bcopy stuff
-
-; GDT descriptor entry
-%macro desc 1
-bcopy_gdt.%1:
-PM_%1 equ bcopy_gdt.%1-bcopy_gdt
-%endmacro
-
-bcopy_gdt:
- dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
- dd bcopy_gdt ; pointer for LGDT instruction
- dw 0
-
- desc CS16
- dd 0000ffffh ; 08h Code segment, use16, readable,
- dd 00009b00h ; present, dpl 0, cover 64K
- desc DS16_4G
- dd 0000ffffh ; 10h Data segment, use16, read/write,
- dd 008f9300h ; present, dpl 0, cover all 4G
- desc DS16_RM
- dd 0000ffffh ; 18h Data segment, use16, read/write,
- dd 00009300h ; present, dpl 0, cover 64K
- ; The next two segments are used for COM32 only
- desc CS32
- dd 0000ffffh ; 20h Code segment, use32, readable,
- dd 00cf9b00h ; present, dpl 0, cover all 4G
- desc DS32
- dd 0000ffffh ; 28h Data segment, use32, read/write,
- dd 00cf9300h ; present, dpl 0, cover all 4G
-
- ; TSS segment to keep Intel VT happy. Intel VT is
- ; unhappy about anything that doesn't smell like a
- ; full-blown 32-bit OS.
- desc TSS
- dw 104-1, DummyTSS ; 30h 32-bit task state segment
- dd 00008900h ; present, dpl 0, 104 bytes @DummyTSS
-
- ; 16-bit stack segment, which may have a different
- ; base from DS16 (e.g. if we're booted from PXELINUX)
- desc SS16
- dd 0000ffffh ; 38h Data segment, use16, read/write,
- dd 00009300h ; present, dpl 0, cover 64K
-
-bcopy_gdt_size: equ $-bcopy_gdt
+
+ bits 16
+ section .text
;
; bcopy:
@@ -104,16 +55,37 @@ bcopy: jecxz .ret
.ret: ret
;
-; This routine is used to invoke a simple routine in 16-bit protected
-; mode (with 32-bit DS and ES, and working 16-bit stack.)
-; Note that all segment registers including CS, except possibly SS,
-; are zero-based in the protected-mode routine.
+; shuffle_and_boot_raw:
+; The new version of shuffle and boot.
+; Inputs:
+; ESI -> Pointer to list of (dst, src, len) pairs(*)
+; EDI -> Pointer to safe area for list + shuffler
+; (must not overlap this code nor the RM stack)
+; ECX -> Byte count of list area (for initial copy)
+;
+; If src == -1: then the memory pointed to by (dst, len) is bzeroed;
+; this is handled inside the bcopy routine.
+;
+; If len == 0: this marks the end of the list; dst indicates
+; the entry point and src the mode (0 = pm, 1 = rm)
+;
+shuffle_and_boot_raw:
+ push word pm_shuffle
+ call simple_pm_call
+ ; Never returns...
+ jmp kaboom
+
+;
+; This routine is used to invoke a simple routine in 32-bit protected
+; mode (with 32-bit zero-based CS, DS, ES, and SS, with ESP pointing to the
+; real-mode stack even if the real-mode stack was in a nonzero SS.)
;
; No interrupt thunking services are provided; interrupts are disabled
-; for the duration of the routine. Don't run for too long at a time.
+; for the duration of the routine. Don't run for too long at a time
+; unless you really mean it.
;
; Inputs:
-; On stack - pm entrypoint
+; On stack - pm entrypoint (IP only)
; EAX, EBP preserved until real-mode exit
; EBX, ECX, EDX, ESI and EDI passed to the called routine
;
@@ -125,7 +97,7 @@ bcopy: jecxz .ret
simple_pm_call:
push eax
push ebp
- mov bp,sp
+ movzx ebp,sp ; BP is used as frame pointer
pushfd ; Saves, among others, the IF flag
push ds
push es
@@ -141,44 +113,48 @@ simple_pm_call:
xor eax,eax
mov ax,ss
shl eax,4
- or eax,93000000h
- mov [cs:bcopy_gdt.SS16+2],eax
+ add ebp,eax ; EBP is now an absolute frame ptr
- push ss ; Save real-mode SS selector
+ ; Save the old segmented stack pointer
+ mov [cs:.rm_esp],esp
+ mov [cs:.rm_ss],ss
o32 lgdt [cs:bcopy_gdt]
mov eax,cr0
or al,1
mov cr0,eax ; Enter protected mode
- jmp PM_CS16:.in_pm
-.in_pm:
- mov ax,PM_SS16 ; Make stack usable
- mov ss,ax
+ jmp PM_CS32:.in_pm
- mov al,PM_DS16_4G ; Data segment selector
- mov es,ax
- mov ds,ax
+ bits 32
+.in_pm:
+ mov eax,PM_DS32
+ mov ss,eax
+ lea esp,[ebp-8*4-2*4] ; Flat mode stack
+ mov es,eax
+ mov ds,eax
; Set fs, gs, tr, and ldtr in case we're on a virtual
; machine running on Intel VT hardware -- it can't
; deal with a partial transition, for no good reason.
mov al,PM_DS16_RM ; Real-mode-like segment
- mov fs,ax
- mov gs,ax
+ mov fs,eax
+ mov gs,eax
mov al,PM_TSS ; Intel VT really doesn't want
ltr ax ; an invalid TR and LDTR, so give
- xor ax,ax ; it something that it can use...
+ xor eax,eax ; it something that it can use...
lldt ax ; (sigh)
- call [bp+2*4+2] ; Call actual routine
+ movzx eax,word [ebp+2*4+2]
+ call eax ; Call actual routine
+ jmp PM_CS16:.exit
+ bits 16
.exit:
- mov ax,PM_DS16_RM ; "Real-mode-like" data segment
- mov es,ax
- mov ds,ax
-
- pop bp ; Previous value for ss
+ mov eax,PM_DS16_RM ; "Real-mode-like" data segment
+ mov es,eax
+ mov ds,eax
+ mov ss,eax
mov eax,cr0
and al,~1
@@ -186,157 +162,24 @@ simple_pm_call:
jmp 0:.in_rm
.in_rm: ; Back in real mode
- mov ss,bp
+ lss esp,[cs:.rm_esp] ; Restore the stack
pop gs
pop fs
pop es
pop ds
-%if DISABLE_A20
- call disable_a20
-%endif
popfd ; Re-enables interrupts
pop ebp
pop eax
ret 2 ; Drops the pm entry
-;
-; pm_bcopy:
-;
-; This is the protected-mode core of the "bcopy" routine.
-; Try to do aligned transfers; if the src and dst are relatively
-; misaligned, align the dst.
-;
-; ECX is guaranteed to not be zero on entry.
-;
-pm_bcopy:
- cmp esi,-1
- je .bzero
-
- cmp esi,edi ; If source < destination, we might
- jb .reverse ; have to copy backwards
-
-.forward:
- ; Initial alignment
- mov dx,di
- shr dx,1
- jnc .faa1
- a32 movsb
- dec ecx
-.faa1:
- mov al,cl
- cmp ecx,2
- jb .f_tiny
-
- shr dx,1
- jnc .faa2
- a32 movsw
- sub ecx,2
-.faa2:
-
- ; Bulk transfer
- mov al,cl ; Save low bits
- shr ecx,2 ; Convert to dwords
- a32 rep movsd ; Do our business
- ; At this point ecx == 0
-
- test al,2
- jz .fab2
- a32 movsw
-.fab2:
-.f_tiny:
- test al,1
- jz .fab1
- a32 movsb
-.fab1:
- ret
-
-.reverse:
- std ; Reverse copy
-
- lea esi,[esi+ecx-1] ; Point to final byte
- lea edi,[edi+ecx-1]
-
- ; Initial alignment
- mov dx,di
- shr dx,1
- jnc .raa1
- a32 movsb
- dec ecx
-.raa1:
-
- dec esi
- dec edi
- mov al,cl
- cmp ecx,2
- jb .r_tiny
- shr dx,1
- jnc .raa2
- a32 movsw
- sub ecx,2
-.raa2:
-
- ; Bulk copy
- sub esi,2
- sub edi,2
- mov al,cl ; Save low bits
- shr ecx,2
- a32 rep movsd
-
- ; Final alignment
-.r_final:
- add esi,2
- add edi,2
- test al,2
- jz .rab2
- a32 movsw
-.rab2:
-.r_tiny:
- inc esi
- inc edi
- test al,1
- jz .rab1
- a32 movsb
-.rab1:
- cld
- ret
-
-.bzero:
- xor eax,eax
+ section .bss
+ alignb 4
+.rm_esp resd 1
+.rm_ss resw 1
- ; Initial alignment
- mov dx,di
- shr dx,1
- jnc .zaa1
- a32 stosb
- dec ecx
-.zaa1:
-
- mov bl,cl
- cmp ecx,2
- jb .z_tiny
- shr dx,1
- jnc .zaa2
- a32 stosw
- sub ecx,2
-.zaa2:
-
- ; Bulk
- mov bl,cl ; Save low bits
- shr ecx,2
- a32 rep stosd
-
- test bl,2
- jz .zab2
- a32 stosw
-.zab2:
-.z_tiny:
- test bl,1
- jz .zab1
- a32 stosb
-.zab1:
- ret
+ section .text
;
; Routines to enable and disable (yuck) A20. These routines are gathered
; from tips from a couple of sources, including the Linux kernel and
@@ -363,6 +206,15 @@ _io_delay: out IO_DELAY_PORT,al
out IO_DELAY_PORT,al
ret
+ section .data
+ align 2
+A20Ptr dw a20_dunno
+
+ section .bss
+A20Test resw 1 ; Counter for testing A20 status
+A20Tries resb 1 ; Times until giving up on A20
+
+ section .text
enable_a20:
pushad
mov byte [cs:A20Tries],255 ; Times to try to make this work
@@ -378,15 +230,14 @@ try_enable_a20:
;
; If the A20 type is known, jump straight to type
;
- mov bp,[cs:A20Type]
- jmp word [cs:bp+A20List]
+ jmp word [cs:A20Ptr]
;
; First, see if we are on a system with no A20 gate
;
a20_dunno:
a20_none:
- mov byte [cs:A20Type], A20_NONE
+ mov word [cs:A20Ptr], a20_none
call a20_test
jnz a20_done
@@ -394,7 +245,7 @@ a20_none:
; Next, try the BIOS (INT 15h AX=2401h)
;
a20_bios:
- mov byte [cs:A20Type], A20_BIOS
+ mov word [cs:A20Ptr], a20_bios
mov ax,2401h
pushf ; Some BIOSes muck with IF
int 15h
@@ -411,7 +262,7 @@ a20_kbc:
call empty_8042
jnz a20_done ; A20 live, no need to use KBC
- mov byte [cs:A20Type], A20_KBC ; Starting KBC command sequence
+ mov word [cs:A20Ptr], a20_kbc ; Starting KBC command sequence
mov al,0D1h ; Write output port
out 064h, al
@@ -446,7 +297,7 @@ a20_kbc:
; Running out of options here. Final attempt: enable the "fast A20 gate"
;
a20_fast:
- mov byte [cs:A20Type], A20_FAST ; Haven't used the KBC yet
+ mov word [cs:A20Ptr], a20_fast
in al, 092h
or al,02h
and al,~01h ; Don't accidentally reset the machine!
@@ -465,17 +316,15 @@ a20_fast:
; Oh bugger. A20 is not responding. Try frobbing it again; eventually give up
; and report failure to the user.
;
-
-
dec byte [cs:A20Tries]
- jnz try_enable_a20
+ jnz a20_dunno ; Did we get the wrong type?
mov si, err_a20
jmp abort_load
section .data
err_a20 db CR, LF, 'A20 gate not responding!', CR, LF, 0
- section .bcopy32
+ section .text
;
; A20 unmasked, proceed...
@@ -506,69 +355,6 @@ a20_test:
pop es
ret
-%if DISABLE_A20
-
-disable_a20:
- pushad
-;
-; Flush the caches
-;
-%if DO_WBINVD
- call try_wbinvd
-%endif
-
- mov bp,[cs:A20Type]
- jmp word [cs:bp+A20DList]
-
-a20d_bios:
- mov ax,2400h
- pushf ; Some BIOSes muck with IF
- int 15h
- popf
- jmp short a20d_snooze
-
-;
-; Disable the "fast A20 gate"
-;
-a20d_fast:
- in al, 092h
- and al,~03h
- out 092h, al
- jmp short a20d_snooze
-
-;
-; Disable the keyboard controller A20 gate
-;
-a20d_kbc:
- call empty_8042_uncond
-
- mov al,0D1h
- out 064h, al ; Write output port
- call empty_8042_uncond
-
- mov al,0DDh ; A20 off
- out 060h, al
- call empty_8042_uncond
-
- mov al,0FFh ; Null command/synchronization
- out 064h, al
- call empty_8042_uncond
-
- ; Wait a bit for it to take effect
-a20d_snooze:
- push cx
- mov cx, disable_wait
-.delayloop: call a20_test
- jz .disabled
- loop .delayloop
-.disabled: pop cx
-a20d_dunno:
-a20d_none:
- popad
- ret
-
-%endif
-
;
; Routine to empty the 8042 KBC controller. If dl != 0
; then we will test A20 in the loop and exit if A20 is
@@ -604,129 +390,6 @@ try_wbinvd:
%endif
;
-; shuffle_and_boot:
-;
-; This routine is used to shuffle memory around, followed by
-; invoking an entry point somewhere in low memory. This routine
-; can clobber any memory above 7C00h, we therefore have to move
-; necessary code into the trackbuf area before doing the copy,
-; and do adjustments to anything except BSS area references.
-;
-; NOTE: Since PXELINUX relocates itself, put all these
-; references in the ".earlybss" segment.
-;
-; After performing the copy, this routine resets the stack and
-; jumps to the specified entrypoint.
-;
-; IMPORTANT: This routine does not canonicalize the stack or the
-; SS register. That is the responsibility of the caller.
-;
-; Inputs:
-; DS:BX -> Pointer to list of (dst, src, len) pairs(*)
-; AX -> Number of list entries
-; [CS:EntryPoint] -> CS:IP to jump to
-; On stack - initial state (fd, ad, ds, es, fs, gs)
-;
-; (*) If dst == -1, then (src, len) entry refers to a set of new
-; descriptors to load.
-; If src == -1, then the memory pointed to by (dst, len) is bzeroed;
-; this is handled inside the bcopy routine.
-;
-shuffle_and_boot:
-.restart:
- and ax,ax
- jz .done
-.loop:
- mov edi,[bx]
- mov esi,[bx+4]
- mov ecx,[bx+8]
- cmp edi, -1
- je .reload
- call bcopy
- add bx,12
- dec ax
- jnz .loop
-
-.done:
- pop gs
- pop fs
- pop es
- pop ds
- popad
- popfd
- jmp far [cs:EntryPoint]
-
-.reload:
- mov bx, trackbuf ; Next descriptor
- movzx edi,bx
- push ecx ; Save byte count
- call bcopy
- pop eax ; Byte count
- xor edx,edx
- mov ecx,12
- div ecx ; Convert to descriptor count
- jmp .restart
-
-;
-; trampoline_to_pm:
-;
-; This routine is chained to from shuffle_and_boot to invoke a
-; flat 32-bit protected mode operating system.
-;
-trampoline_to_pm:
- cli
- call enable_a20
- mov byte [cs:bcopy_gdt.TSS+5],89h ; Mark TSS unbusy
- o32 lgdt [cs:bcopy_gdt]
- mov eax,cr0
- or al,1
- mov cr0,eax ; Enter protected mode
- jmp PM_CS32:.next ; Synchronize and go to 32-bit mode
-
- bits 32
-.next: xor eax,eax
- lldt ax ; TR <- 0 to be nice to Intel VT
- mov al,PM_TSS
- ltr ax ; Bogus TSS to be nice to Intel VT
- mov al,PM_DS32
- mov es,ax ; 32-bit data segment selector
- mov ds,ax
- mov ss,ax
- mov fs,ax
- mov gs,ax
- jmp word TrampolineBuf
- bits 16
-
- align 2
-A20List dw a20_dunno, a20_none, a20_bios, a20_kbc, a20_fast
-%if DISABLE_A20
-A20DList dw a20d_dunno, a20d_none, a20d_bios, a20d_kbc, a20d_fast
-%endif
-
-A20Type dw A20_NONE ; A20 type
-
- ; Total size of .bcopy32 section
- alignb 4, db 0 ; Even number of dwords
-__bcopy_size equ $-__bcopy_start
-
- section .earlybss
- alignb 2
-EntryPoint resd 1 ; CS:IP for shuffle_and_boot
-A20Test resw 1 ; Counter for testing status of A20
-A20Tries resb 1 ; Times until giving up on A20
-
-;
-; This buffer contains synthesized code for shuffle-and-boot.
-; For the PM case, it is 9*5 = 45 bytes long; for the RM case it is
-; 8*6 to set the GPRs, 6*5 to set the segment registers (including a dummy
-; setting of CS), 5 bytes to set CS:IP, for a total of 83 bytes.
+; The 32-bit copy and shuffle code is "special", so it is in its own file
;
-TrampolineBuf resb 83 ; Shuffle and boot trampoline
-
-;
-; Space for a dummy task state segment. It should never be actually
-; accessed, but just in case it is, point to a chunk of memory not used
-; for anything real.
-;
- alignb 4
-DummyTSS resb 104
+%include "bcopyxx.inc"
diff --git a/core/bcopyxx.inc b/core/bcopyxx.inc
new file mode 100644
index 00000000..4c75fa6a
--- /dev/null
+++ b/core/bcopyxx.inc
@@ -0,0 +1,326 @@
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; bcopy32xx.inc
+;;
+
+
+;
+; 32-bit bcopy routine
+;
+; This is the actual 32-bit portion of the bcopy and shuffle and boot
+; routines. ALL THIS CODE NEEDS TO BE POSITION-INDEPENDENT, with the
+; sole exception being the actual relocation code at the beginning of
+; pm_shuffle_boot.
+;
+; It also really needs to live all in a single segment, for the
+; address calculcations to actually work.
+;
+
+ bits 32
+ section .bcopyxx
+ align 16
+bcopyxx_start equ $
+;
+; pm_bcopy:
+;
+; This is the protected-mode core of the "bcopy" routine.
+; Try to do aligned transfers; if the src and dst are relatively
+; misaligned, align the dst.
+;
+; ECX is guaranteed to not be zero on entry.
+;
+; Clobbers ESI, EDI, ECX.
+;
+
+pm_bcopy:
+ push ebx
+ push edx
+ push eax
+
+ cmp esi,-1
+ je .bzero
+
+ cmp esi,edi ; If source < destination, we might
+ jb .reverse ; have to copy backwards
+
+.forward:
+ ; Initial alignment
+ mov dx,di
+ shr dx,1
+ jnc .faa1
+ a32 movsb
+ dec ecx
+.faa1:
+ mov al,cl
+ cmp ecx,2
+ jb .f_tiny
+
+ shr dx,1
+ jnc .faa2
+ a32 movsw
+ sub ecx,2
+.faa2:
+
+ ; Bulk transfer
+ mov al,cl ; Save low bits
+ shr ecx,2 ; Convert to dwords
+ a32 rep movsd ; Do our business
+ ; At this point ecx == 0
+
+ test al,2
+ jz .fab2
+ a32 movsw
+.fab2:
+.f_tiny:
+ test al,1
+ jz .fab1
+ a32 movsb
+.fab1:
+.done:
+ pop eax
+ pop edx
+ pop ebx
+ ret
+
+.reverse:
+ std ; Reverse copy
+
+ lea esi,[esi+ecx-1] ; Point to final byte
+ lea edi,[edi+ecx-1]
+
+ ; Initial alignment
+ mov dx,di
+ shr dx,1
+ jnc .raa1
+ a32 movsb
+ dec ecx
+.raa1:
+
+ dec esi
+ dec edi
+ mov al,cl
+ cmp ecx,2
+ jb .r_tiny
+ shr dx,1
+ jnc .raa2
+ a32 movsw
+ sub ecx,2
+.raa2:
+
+ ; Bulk copy
+ sub esi,2
+ sub edi,2
+ mov al,cl ; Save low bits
+ shr ecx,2
+ a32 rep movsd
+
+ ; Final alignment
+.r_final:
+ add esi,2
+ add edi,2
+ test al,2
+ jz .rab2
+ a32 movsw
+.rab2:
+.r_tiny:
+ inc esi
+ inc edi
+ test al,1
+ jz .rab1
+ a32 movsb
+.rab1:
+ cld
+ jmp short .done
+
+.bzero:
+ xor eax,eax
+
+ ; Initial alignment
+ mov dx,di
+ shr dx,1
+ jnc .zaa1
+ a32 stosb
+ dec ecx
+.zaa1:
+
+ mov bl,cl
+ cmp ecx,2
+ jb .z_tiny
+ shr dx,1
+ jnc .zaa2
+ a32 stosw
+ sub ecx,2
+.zaa2:
+
+ ; Bulk
+ mov bl,cl ; Save low bits
+ shr ecx,2
+ a32 rep stosd
+
+ test bl,2
+ jz .zab2
+ a32 stosw
+.zab2:
+.z_tiny:
+ test bl,1
+ jz .zab1
+ a32 stosb
+.zab1:
+ jmp short .done
+
+;
+; shuffle_and_boot:
+;
+; This routine is used to shuffle memory around, followed by
+; invoking an entry point somewhere in low memory. This routine
+; can clobber any memory outside the bcopy special area.
+;
+; IMPORTANT: This routine does not set up any registers.
+; It is the responsibility of the caller to generate an appropriate entry
+; stub; *especially* when going to real mode.
+;
+; Inputs:
+; ESI -> Pointer to list of (dst, src, len) pairs(*)
+; EDI -> Pointer to safe area for list + shuffler
+; (must not overlap this code nor the RM stack)
+; ECX -> Byte count of list area (for initial copy)
+;
+; If src == -1: then the memory pointed to by (dst, len) is bzeroed;
+; this is handled inside the bcopy routine.
+;
+; If len == 0: this marks the end of the list; dst indicates
+; the entry point and src the mode (0 = pm, 1 = rm)
+;
+pm_shuffle:
+ mov ebx,edi ; EBX <- descriptor list
+ lea edx,[edi+ecx] ; EDX <- shuffler end location
+ call pm_bcopy
+ mov edi,edx
+ mov esi,bcopyxx_start
+ mov ecx,bcopyxx_dwords
+ lea eax,[edx+.safe-bcopyxx_start] ; Resume point
+ ; Relocate this code
+ rep movsd
+ jmp eax ; Jump to safe location
+.safe:
+ ; Give ourselves a safe stack
+ lea esp,[edx+bcopyxx_stack+bcopyxx_end-bcopyxx_start]
+ add edx,bcopy_gdt-bcopyxx_start
+ mov [edx+2],edx ; GDT self-pointer
+ lgdt [edx] ; Switch to local GDT
+
+ ; Now for the actual shuffling...
+.loop:
+ mov edi,[ebx]
+ mov esi,[ebx+4]
+ mov ecx,[ebx+8]
+ add ebx,12
+ jecxz .done
+ call pm_bcopy
+ jmp .loop
+.done:
+ and esi,esi
+ jz pm_shuffle_real_mode
+ jmp edi ; Protected mode entry
+
+ ; We have a real-mode entry point, so we need to return
+ ; to real mode...
+pm_shuffle_real_mode:
+ call .here
+.here: pop eax
+ mov ebx,eax
+ add eax,.next-.here
+ mov [ebx-.here+.rm_entry],edi
+ mov [ebx-.here+bcopy_gdt.CS16+2],ax
+ shr eax,16
+ mov [ebx-.here+bcopy_gdt.CS16+4],al
+ mov [ebx-.here+bcopy_gdt.CS16+7],ah
+ mov eax,PM_DS16_RM
+ mov ds,eax
+ mov es,eax
+ mov fs,eax
+ mov gs,eax
+ mov ss,eax
+ jmp PM_CS16:0
+ bits 16
+.next:
+ mov eax,cr0
+ and al,~1
+ mov cr0,eax
+ jmp 0:0
+.rm_entry equ $-4
+
+ bits 32
+
+ align 16
+; GDT descriptor entry
+%macro desc 1
+bcopy_gdt.%1:
+PM_%1 equ bcopy_gdt.%1-bcopy_gdt
+%endmacro
+
+bcopy_gdt:
+ dw bcopy_gdt_size-1 ; Null descriptor - contains GDT
+ dd bcopy_gdt ; pointer for LGDT instruction
+ dw 0
+
+ desc CS16
+ dd 0000ffffh ; 08h Code segment, use16, readable,
+ dd 00009b00h ; present, dpl 0, cover 64K
+ desc DS16_4G
+ dd 0000ffffh ; 10h Data segment, use16, read/write,
+ dd 008f9300h ; present, dpl 0, cover all 4G
+ desc DS16_RM
+ dd 0000ffffh ; 18h Data segment, use16, read/write,
+ dd 00009300h ; present, dpl 0, cover 64K
+ desc CS32
+ dd 0000ffffh ; 20h Code segment, use32, readable,
+ dd 00cf9b00h ; present, dpl 0, cover all 4G
+ desc DS32
+ dd 0000ffffh ; 28h Data segment, use32, read/write,
+ dd 00cf9300h ; present, dpl 0, cover all 4G
+
+ ; TSS segment to keep Intel VT happy. Intel VT is
+ ; unhappy about anything that doesn't smell like a
+ ; full-blown 32-bit OS.
+ desc TSS
+ dw 104-1, DummyTSS ; 30h 32-bit task state segment
+ dd 00008900h ; present, dpl 0, 104 bytes @DummyTSS
+
+ ; 16-bit stack segment, which may have a different
+ ; base from DS16 (e.g. if we're booted from PXELINUX)
+ desc SS16
+ dd 0000ffffh ; 38h Data segment, use16, read/write,
+ dd 00009300h ; present, dpl 0, cover 64K
+
+bcopy_gdt_size: equ $-bcopy_gdt
+
+ align 4, db 0
+bcopyxx_end equ $ ; *Must* be dword-aligned!
+bcopyxx_len equ $-bcopyxx_start
+bcopyxx_dwords equ bcopyxx_len >> 2
+
+bcopyxx_stack equ 128 ; We want this much stack
+bcopyxx_safe equ bcopyxx_len + bcopyxx_stack
+
+;
+; Space for a dummy task state segment. It should never be actually
+; accessed, but just in case it is, point to a chunk of memory not used
+; for anything real.
+;
+DummyTSS equ 0x800
+
+ bits 16
+ section .text
diff --git a/core/bootsect.inc b/core/bootsect.inc
index 45fb7a80..c7d82a49 100644
--- a/core/bootsect.inc
+++ b/core/bootsect.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -35,9 +36,8 @@ SuperSize equ $+1
push word superblock_len_fat16
%endif
load_bootsec:
- mov edi, 100000h
+ mov edi,100000h
mov [trackbuf+4],edi ; Copy from this address
- push edi ; Save load address
xor dx,dx ; No padding
mov bx,abort_check ; Don't print dots, but allow abort
call load_high
@@ -47,10 +47,9 @@ load_bootsec:
mov eax,7C00h ; Entry point
mov [trackbuf],eax ; Copy to this address
- mov [EntryPoint],eax ; Jump to this address when done
%if IS_SYSLINUX || IS_MDSLINUX
- xchg eax,ecx ; ECX[31:16] <- 0
+ xor ecx,ecx
pop cx
; For a BSS boot sector we have to patch.
@@ -58,6 +57,7 @@ load_bootsec:
mov edi,100000h+(superblock-bootsec)
call bcopy
%endif
+ push eax ; Save entry point
xor edx,edx
xor esi,esi
@@ -77,27 +77,28 @@ load_bootsec:
%elif IS_ISOLINUX
mov dl,[DriveNumber]
%elif IS_PXELINUX
- mov byte [KeepPXE],1 ; Chainloading another NBP
+ mov byte [KeepPXE],03h ; Chainloading + keep PXE
call reset_pxe
%endif
xor bx,bx
;
; replace_bootstrap for the special case where we have exactly one
-; descriptor, and it's the first entry in the trackbuf
+; descriptor.
;
replace_bootstrap_one:
push word 1 ; Length of descriptor list
- push word trackbuf ; Address of descriptor list
; Fall through
;
; Entrypoint for "shut down and replace bootstrap" -- also invoked by
-; the COMBOOT API. This routine expects two words on the stack:
-; address of the copy list (versus DS) and count. Additionally,
-; the values of ESI and EDX are passed on to the new bootstrap;
-; the value of BX becomes the new DS.
+; the COMBOOT API. This routine expects the entry point (CS, IP) and the
+; count of the descriptor sequence on the stack; the shuffle
+; descriptors start at the first byte of the trackbuf.
+;
+; The registers EDX and ESI are passed on to the called program,
+; and BX is passed on as DS.
;
replace_bootstrap:
;
@@ -109,14 +110,13 @@ replace_bootstrap:
;
; Set up initial stack frame (not used by PXE if keeppxe is
; set - we use the PXE stack then.)
- ; AFTER THIS POINT ONLY .earlybss IS AVAILABLE, NOT .bss
;
xor ax,ax
mov ds,ax
mov es,ax
%if IS_PXELINUX
- test byte [KeepPXE],01h
+ test byte [KeepPXE],02h ; Bit 1 = chainloading PXE
jz .stdstack
les di,[InitStack] ; Reset stack to PXE original
jmp .stackok
@@ -146,12 +146,64 @@ replace_bootstrap:
mov [es:di+8],ax ; New DI
mov [es:di+4],bx ; New ES
%endif
- pop bx ; Copy from...
- pop ax ; Copy list count
+ pop ax ; List length
- cli
- mov cx,es
- mov ss,cx
- movzx esp,di
+ push di
+ push es
+
+ push ds
+ pop es
- jmp shuffle_and_boot
+ mov ebx,trackbuf
+ imul di,ax,12
+ add di,bx ; DI <- end of list
+ push di
+
+ ; Terminating entry...
+ lea eax,[di+12]
+ stosd
+ xor ax,ax ; EAX[31:16] == 0 already
+ stosd ; Real mode
+ stosd ; End of list
+
+ ; Copy the stub
+ mov si,replace_stub
+ mov cx,replace_stub.len >> 2
+ rep movsd
+
+ xor ecx,ecx
+ pop cx ; ECX <- length of list
+
+ pop word [di+replace_stub.ss]
+ pop word [di+replace_stub.esp]
+ pop dword [di+replace_stub.csip]
+
+ cli
+ mov ss,[di+replace_stub.ss]
+ mov esp,[di+replace_stub.esp]
+
+ mov edi,trackbuf
+ mov esi,edi
+
+ jmp shuffle_and_boot_raw
+
+ ; This stub gets run after the shuffle, but not in-place.
+ ; THE ALIGNS ARE CRITICAL.
+ align 4
+replace_stub:
+ mov ax,strict word 0
+.ss equ $-2-.end
+ mov ss,ax
+ mov esp,strict dword 0
+.esp: equ $-4-.end
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ popad
+ popfd
+ jmp 0:0
+.csip equ $-4-.end
+ align 4
+.end:
+.len equ $-replace_stub
diff --git a/core/cleanup.inc b/core/cleanup.inc
index dca6491a..1b00e0b0 100644
--- a/core/cleanup.inc
+++ b/core/cleanup.inc
@@ -21,7 +21,7 @@
; cleanup_hardware:
;
; Shut down anything transient. *No segment assumptions*.
-; Can trash any registers.
+; Preserves all registers.
;
cleanup_hardware:
pushad
diff --git a/core/cmdline.inc b/core/cmdline.inc
index 5d5b3c22..9d908dcc 100644
--- a/core/cmdline.inc
+++ b/core/cmdline.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 2003-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -20,14 +21,17 @@
;
; Assumes DS == CS
+;
make_plain_cmdline:
push es
; ui.inc has already copied any APPEND options
mov ax,real_mode_seg
mov es,ax
- mov si,[CmdOptPtr]
mov di,[CmdLinePtr]
+ call do_ip_append
+
+ mov si,[CmdOptPtr]
call strcpy
@@ -36,3 +40,55 @@ make_plain_cmdline:
pop es
ret
+
+;
+; Actual IPAppend strings...
+;
+%if IS_PXELINUX
+ section .data
+ alignb 2, db 0
+IPAppends dw IPOption
+ dw BOOTIFStr
+numIPAppends equ ($-IPAppends)/2
+%else
+IPAppends equ 0
+numIPAppends equ 0
+%endif
+
+;
+; Handle "ipappend" strings, if applicable
+;
+; Assumes DS == CS; pushes output to ES:DI
+;
+ section .text
+
+do_ip_append:
+%ifndef DEPEND
+ %if numIPAppends > 0
+ push cx
+ push bx
+ push si
+
+ mov bx,IPAppends
+ mov cx,[IPAppend]
+ and cx,(1 << numIPAppends)-1
+.loop:
+ jcxz .done
+ mov si,[bx]
+ inc bx
+ inc bx
+ test cl,1
+ jz .not_this
+
+ call strcpy
+ mov byte [es:di-1],' ' ; Replace final null with space
+.not_this:
+ shr cx,1
+ jmp .loop
+.done:
+ pop si
+ pop bx
+ pop cx
+ %endif
+%endif
+ ret
diff --git a/core/com32.inc b/core/com32.inc
index bd6d727a..28e8d528 100644
--- a/core/com32.inc
+++ b/core/com32.inc
@@ -172,13 +172,14 @@ com32_call_start:
; Now everything is set up for interrupts...
+ push dword [HighMemSize] ; Memory managed by Syslinux
push dword com32_cfarcall ; Cfarcall entry point
push dword com32_farcall ; Farcall entry point
push dword (1 << 16) ; 64K bounce buffer
push dword (comboot_seg << 4) ; Bounce buffer address
push dword com32_intcall ; Intcall entry point
push dword command_line ; Command line pointer
- push dword 6 ; Argument count
+ push dword 7 ; Argument count
sti ; Interrupts OK now
call pm_entry ; Run the program...
; ... on return, fall through to com32_exit ...
@@ -218,9 +219,6 @@ com32_enter_rm:
jmp bx ; Go to whereever we need to go...
com32_done:
-%if DISABLE_A20
- call disable_a20
-%endif
sti
jmp enter_command
diff --git a/core/comboot.inc b/core/comboot.inc
index 2ff5f33e..0cce67ab 100644
--- a/core/comboot.inc
+++ b/core/comboot.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -649,10 +650,7 @@ comapi_cleanup:
mov eax,[OrigFDCTabPtr]
mov [fdctab],eax
%endif
- ; Reset the floppy disk subsystem
- xor ax,ax
- xor dx,dx
- int 13h
+ call cleanup_hardware
clc
ret
@@ -667,13 +665,12 @@ comapi_chainboot:
mov [trackbuf+8],eax ; Total bytes
mov eax,7C00h
mov [trackbuf],eax ; Copy to
- mov [EntryPoint],eax ; CS:IP entry point
+ push eax ; Entry point on stack
mov esi,P_ESI
mov edx,P_EBX
mov bx,P_DS
jmp replace_bootstrap_one
-
;
; INT 22h AX=000Eh Get configuration file name
;
@@ -686,7 +683,6 @@ comapi_configfile:
;
; INT 22h AX=000Fh Get IPAPPEND strings
;
-%if IS_PXELINUX
comapi_ipappend:
mov P_ES,cs
mov P_CX,numIPAppends
@@ -694,18 +690,6 @@ comapi_ipappend:
clc
ret
- section .data
- alignb 2, db 0
-IPAppends dw IPOption
- dw BOOTIFStr
-numIPAppends equ ($-IPAppends)/2
-
-%else
-comapi_ipappend equ comapi_err
-%endif
-
- section .text
-
;
; INT 22h AX=0010h Resolve hostname
;
@@ -724,41 +708,12 @@ comapi_dnsresolv equ comapi_err
section .text
;
-; INT 22h AX=0011h Maximum number of shuffle descriptors
+; INT 22h AX=0011h Obsolete
;
-comapi_maxshuffle:
- mov P_CX,trackbufsize/12
- ret
;
-; INT 22h AX=0012h Cleanup, shuffle and boot
+; INT 22h AX=0012h Obsolete
;
-comapi_shuffle:
- cmp P_CX,(2*trackbufsize)/12
- ja .error
-
- call comapi_cleanup
-
- mov cx, P_CX
- push cx ; On stack: descriptor count
-
- lea cx,[ecx+ecx*2] ; CX *= 3
-
- mov fs,P_ES
- mov si,P_DI
- mov di,trackbuf
- push di ; On stack: descriptor list address
- fs rep movsd ; Copy the list
-
- mov eax,P_EBP
- mov [EntryPoint],eax ; CS:IP entry point
- mov esi,P_ESI
- mov edx,P_EBX
- mov bx,P_DS
- jmp replace_bootstrap
-.error:
- stc
- ret
;
; INT 22h AX=0013h Idle call
@@ -860,7 +815,7 @@ comapi_runkernel:
mov word [CmdOptPtr],zero_string
jmp kernel_good_saved
-.error equ comapi_shuffle.error
+.error equ comapi_usingvga.error
;
; INT 22h AX=0017h Report video mode change
@@ -922,102 +877,12 @@ comapi_readdisk equ comapi_err
%endif
;
-; INT 22h AX=001Ah Cleanup, shuffle and boot to flat protected mode
+; INT 22h AX=001Ah Obsolete
;
-comapi_shufflepm:
- cmp P_CX,(2*trackbufsize)/12
- ja .error
-
- call comapi_cleanup
-
- mov cx, P_CX
- push cx ; On stack: descriptor count
-
- lea cx,[ecx+ecx*2] ; CX *= 3
-
- mov fs,P_ES
- mov si,P_DI
- mov di,trackbuf
- push di ; On stack: descriptor list address
- fs rep movsd ; Copy the list
-
- mov fs,P_DS
- mov si,P_SI
- mov edi,TrampolineBuf
- mov al,0B8h ; MOV EAX opcode
- mov cl,9
-.maketramp:
- stosb ; MOV opcode
- inc ax ; Next register opcode
- fs movsd ; immediate value
- loop .maketramp
- mov byte [di-5],0E9h ; Last opcode is JMP
- sub [di-4],edi ; Make JMP target relative
-
- mov dword [EntryPoint],trampoline_to_pm
- xor bx,bx ; DS on entry
- jmp replace_bootstrap
-.error:
- stc
- ret
;
-; INT 22h AX=001Bh Cleanup, shuffle and boot with register setting
+; INT 22h AX=001Bh Obsolete
;
-comapi_shufflerm:
- cmp P_CX,(2*trackbufsize)/12
- ja .error
-
- call comapi_cleanup
-
- mov cx, P_CX
- push cx ; On stack: descriptor count
-
- lea cx,[ecx+ecx*2] ; CX *= 3
-
- mov fs,P_ES
- mov si,P_DI
- mov di,trackbuf
- push di ; On stack: descriptor list address
- fs rep movsd ; Copy the list
-
- mov fs,P_DS
- mov si,P_SI
- mov di,TrampolineBuf
-
- ; Generate segment-loading instructions
- mov bx,0C08Eh ; MOV ES,AX
- mov cl,6 ; 6 segment registers (incl CS)
-.segtramp:
- mov al,0B8h
- stosb ; MOV AX,imm16 opcode
- fs movsw ; imm16
- mov ax,bx
- add bh,8
- stosw ; MOV xS,AX
- loop .segtramp
-
- ; Clobber the MOV CS,AX instruction.
- mov word [di-22], 9090h ; NOP NOP
-
- ; Generate GPR-loading instructions
- mov ax,0B866h ; MOV EAX,imm32
- mov cl,8 ; 8 GPRs
-.gprtramp:
- stosw ; MOV ExX,imm32 opcode
- fs movsd ; imm32
- inc ah
- loop .gprtramp
-
- mov al,0EAh ; JMP FAR imm16:imm16 opcode
- stosb
- fs movsd ; CS:IP
-
- mov dword [EntryPoint],TrampolineBuf
- jmp replace_bootstrap
-.error:
- stc
- ret
;
; INT 22h AX=001Ch Get pointer to auxillary data vector
@@ -1113,6 +978,23 @@ comapi_closedir:
comapi_closedir equ comapi_err
%endif
+;
+; INT 22h AX=0023h Query shuffler size
+;
+comapi_shufsize:
+ mov P_CX,bcopyxx_safe
+ ret
+
+;
+; INT 22h AX=0024h Cleanup, shuffle and boot raw
+;
+comapi_shufraw:
+ call comapi_cleanup
+ mov edi,P_EDI
+ mov esi,P_ESI
+ mov ecx,P_ECX
+ jmp shuffle_and_boot_raw
+
section .data
%macro int21 2
@@ -1148,12 +1030,12 @@ int22_table:
dw comapi_derinfo ; 000A derivative-specific info
dw comapi_serialcfg ; 000B get serial port config
dw comapi_cleanup ; 000C perform final cleanup
- dw comapi_chainboot ; 000D clean up then bootstrap
+ dw comapi_err ; 000D clean up then bootstrap
dw comapi_configfile ; 000E get name of config file
dw comapi_ipappend ; 000F get ipappend strings
dw comapi_dnsresolv ; 0010 resolve hostname
- dw comapi_maxshuffle ; 0011 maximum shuffle descriptors
- dw comapi_shuffle ; 0012 cleanup, shuffle and boot
+ dw comapi_err ; 0011 maximum shuffle descriptors
+ dw comapi_err ; 0012 cleanup, shuffle and boot
dw comapi_idle ; 0013 idle call
dw comapi_localboot ; 0014 local boot
dw comapi_features ; 0015 feature flags
@@ -1161,8 +1043,8 @@ int22_table:
dw comapi_usingvga ; 0017 report video mode change
dw comapi_userfont ; 0018 query custom font
dw comapi_readdisk ; 0019 read disk
- dw comapi_shufflepm ; 001A cleanup, shuffle and boot to pm
- dw comapi_shufflerm ; 001B cleanup, shuffle and boot to rm
+ dw comapi_err ; 001A cleanup, shuffle and boot to pm
+ dw comapi_err ; 001B cleanup, shuffle and boot to rm
dw comapi_getadv ; 001C get pointer to ADV
dw comapi_writeadv ; 001D write ADV to disk
dw comapi_kbdtable ; 001E keyboard remapping table
@@ -1170,6 +1052,8 @@ int22_table:
dw comapi_opendir ; 0020 open directory
dw comapi_readdir ; 0021 read directory
dw comapi_closedir ; 0022 close directory
+ dw comapi_shufsize ; 0023 query shuffler size
+ dw comapi_shufraw ; 0024 cleanup, shuffle and boot raw
int22_count equ ($-int22_table)/2
APIKeyWait db 0
diff --git a/core/config.inc b/core/config.inc
index 8ac77758..782cc798 100644
--- a/core/config.inc
+++ b/core/config.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 2002-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 2002-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -33,17 +34,6 @@ MAX_FKEYS equ 12 ; Number of F-key help files
%assign HAS_LOCALBOOT 1
;
-; Set this to return the A20 gate to its previous state, instead of
-; leaving it open. This has caused problems, because there appear
-; to be a race condition between disabling the A20 gate and trying to
-; re-enter protected mode, causing the A20 gate disable to take effect
-; after we have already done the A20 enabled check, with disastrous
-; consequences. Plus, there seems to be little or no demand for it.
-;
-%assign DISABLE_A20 0
-
-
-;
; Version number definitinons
;
%include "../version.gen"
diff --git a/core/cpuinit.inc b/core/cpuinit.inc
index 63250703..400df407 100644
--- a/core/cpuinit.inc
+++ b/core/cpuinit.inc
@@ -40,14 +40,6 @@ enough_ram:
skip_checks:
;
-; Initialize the bcopy32 code in low memory
-;
- mov si,__bcopy32_lma
- mov di,__bcopy32_start
- mov cx,__bcopy32_dwords
- rep movsd
-
-;
; Check if we're 386 (as opposed to 486+); if so we need to blank out
; the WBINVD instruction
;
diff --git a/core/extlinux.asm b/core/extlinux.asm
index 5c6c023c..833cb2b0 100644
--- a/core/extlinux.asm
+++ b/core/extlinux.asm
@@ -5,7 +5,8 @@
;
; A program to boot Linux kernels off an ext2/ext3 filesystem.
;
-; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -1553,7 +1554,7 @@ build_curdir_str:
section .data
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
- db ' H. Peter Anvin and contributors', CR, LF, 0
+ db ' H. Peter Anvin et al', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: please change disks and press '
db 'a key to continue.', CR, LF, 0
config_name db 'extlinux.conf',0 ; Unmangled form
diff --git a/core/getc.inc b/core/getc.inc
index 3fb88566..bb12047b 100644
--- a/core/getc.inc
+++ b/core/getc.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
diff --git a/core/isolinux.asm b/core/isolinux.asm
index 2da96d4a..e3599d9c 100644
--- a/core/isolinux.asm
+++ b/core/isolinux.asm
@@ -9,6 +9,7 @@
; floppies.
;
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -1029,7 +1030,7 @@ writestr_early equ writestr
syslinux_banner db CR, LF, 'ISOLINUX ', VERSION_STR, ' ', DATE_STR, ' ', 0
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
- db ' H. Peter Anvin and contributors', CR, LF, 0
+ db ' H. Peter Anvin et al', CR, LF, 0
isolinux_str db 'isolinux: ', 0
%ifdef DEBUG_MESSAGES
startup_msg: db 'Starting up, DL = ', 0
diff --git a/core/layout.inc b/core/layout.inc
index 3033ab31..14cbabfd 100644
--- a/core/layout.inc
+++ b/core/layout.inc
@@ -1,6 +1,7 @@
; -----------------------------------------------------------------------
;
-; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -39,7 +40,6 @@ LATEBSS_START equ 0B800h
;
; Use .earlybss for things that MUST be in low memory.
section .earlybss nobits start=BSS_START
- section .bcopy32 exec nowrite progbits align=4
section .config write progbits align=4
section .config.end write nobits align=4
@@ -61,6 +61,7 @@ RBFG_brainfuck: resb 2048 ; Bigger than an Ethernet packet...
section .bss2 write nobits align=16
section .text exec write progbits align=16
+ section .bcopyxx exec write progbits align=16
section .data write progbits align=16
section .adv write nobits align=512
@@ -79,7 +80,6 @@ RBFG_brainfuck: resb 2048 ; Bigger than an Ethernet packet...
extern __%1_start, __%1_lma, __%1_end
extern __%1_len, __%1_dwords
%endmacro
- SECINFO bcopy32
SECINFO config
global _start
diff --git a/core/ldlinux.asm b/core/ldlinux.asm
index b05a7e1c..72a6d15d 100644
--- a/core/ldlinux.asm
+++ b/core/ldlinux.asm
@@ -12,6 +12,7 @@
; umsdos filesystem.
;
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -2056,7 +2057,7 @@ getfatsector:
section .data
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
- db ' H. Peter Anvin and contributors', CR, LF, 0
+ db ' H. Peter Anvin et al', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: please change disks and press '
db 'a key to continue.', CR, LF, 0
syslinux_cfg1 db '/boot' ; /boot/syslinux/syslinux.cfg
diff --git a/core/loadhigh.inc b/core/loadhigh.inc
index 21d4cc6f..8ff9da1c 100644
--- a/core/loadhigh.inc
+++ b/core/loadhigh.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
diff --git a/core/parsecmd.inc b/core/parsecmd.inc
index a7a00d5a..e63c205e 100644
--- a/core/parsecmd.inc
+++ b/core/parsecmd.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
diff --git a/core/parseconfig.inc b/core/parseconfig.inc
index 37fe97fe..0ea1f137 100644
--- a/core/parseconfig.inc
+++ b/core/parseconfig.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 6a38e5fe..370cc2bb 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -8,6 +8,7 @@
; MS-DOS floppies.
;
; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -205,7 +206,6 @@ PXEStack resd 1 ; Saved stack during PXE call
RebootTime resd 1 ; Reboot timeout, if set by option
StrucPtr resd 1 ; Pointer to PXENV+ or !PXE structure
APIVer resw 1 ; PXE API version found
-IPOptionLen resw 1 ; Length of IPOption
IdleTimer resw 1 ; Time to check for ARP?
LocalBootType resw 1 ; Local boot return code
PktTimeout resw 1 ; Timeout for current packet
@@ -794,25 +794,6 @@ config_scan:
; a couple of helper macros...
;
-; Handle "ipappend" option
-%define HAVE_SPECIAL_APPEND
-%macro SPECIAL_APPEND 0
- test byte [IPAppend],01h ; ip=
- jz .noipappend1
- mov si,IPOption
- mov cx,[IPOptionLen]
- rep movsb
- mov al,' '
- stosb
-.noipappend1:
- test byte [IPAppend],02h
- jz .noipappend2
- mov si,BOOTIFStr
- call strcpy
- mov byte [es:di-1],' ' ; Replace null with space
-.noipappend2:
-%endmacro
-
; Unload PXE stack
%define HAVE_UNLOAD_PREP
%macro UNLOAD_PREP 0
@@ -965,7 +946,7 @@ is_struc:
pop ax
.bad:
ret
-
+
is_pxe equ is_struc.pxe
is_pxenv equ is_struc.pxenv
@@ -2563,8 +2544,6 @@ genipopt:
stosb
mov eax,[Netmask]
call gendotquad ; Zero-terminates its output
- sub di,IPOption
- mov [IPOptionLen],di
popad
ret
@@ -2657,7 +2636,7 @@ writestr_early equ writestr
copyright_str db ' Copyright (C) 1994-'
asciidec YEAR
- db ' H. Peter Anvin and contributors', CR, LF, 0
+ db ' H. Peter Anvin et al', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0
bailmsg equ err_bootfailed
err_nopxe db "No !PXE or PXENV+ API found; we're dead...", CR, LF, 0
diff --git a/core/rllpack.inc b/core/rllpack.inc
index a556e00a..717ba6ab 100644
--- a/core/rllpack.inc
+++ b/core/rllpack.inc
@@ -1,6 +1,7 @@
; -*- fundamental -*- ---------------------------------------------------
;
-; Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+; Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -31,19 +32,22 @@
;
; rllpack:
; Pack CX bytes from SI into EDI.
-; Returns updated SI and EDI.
+; Returns updated (E)SI and EDI.
;
rllpack:
push word .pmentry
call simple_pm_call
ret
+ bits 32
.pmentry:
- push cx
+ push ecx
push ebx
push edx
+ movzx ecx,cx
+ movzx esi,si
.startseq:
- xor ax,ax ; Zero byte
+ xor eax,eax ; Zero byte
xor ebx,ebx ; Run length zero
dec edi
mov edx,edi ; Pointer to header byte
@@ -53,14 +57,14 @@ rllpack:
lodsb
dec edi
mov [edi],al
- dec cx
+ dec ecx
cmp ah,al
je .same
.diff:
mov ah,al
- xor bx,bx
+ xor ebx,ebx
.plainbyte:
- inc bx
+ inc ebx
inc byte [edx]
jcxz .startseq
jns .stdbyte
@@ -74,7 +78,7 @@ rllpack:
inc edi ; We killed a whole stretch,
; drop start byte
.normal:
- inc bx
+ inc ebx
add edi,ebx ; Remove the stored run bytes
.getrun:
jcxz .nomatch
@@ -83,8 +87,8 @@ rllpack:
jne .nomatch
cmp bx,(256-224)*256-1 ; Maximum run size
jae .nomatch
- inc bx
- dec cx
+ inc ebx
+ dec ecx
jmp .getrun
.nomatch:
cmp bx,224-126
@@ -101,26 +105,31 @@ rllpack:
.storebyte:
dec edi
mov [edi],ah
- dec si ; Reload subsequent byte
+ dec esi ; Reload subsequent byte
jmp .startseq
.done:
pop edx
pop ebx
- pop cx
+ pop ecx
ret
+
+ bits 16
;
; rllunpack:
-; Unpack bytes from ESI into DI
-; On return ESI, DI are updated and CX contains number of bytes output.
+; Unpack bytes from SI into EDI
+; On return (E)SI, EDI are updated and
+; (E)CX contains number of bytes output.
;
rllunpack:
push word .pmentry
call simple_pm_call
ret
+ bits 32
.pmentry:
- push di
- xor cx,cx
+ push edi
+ movzx esi,si
+ xor ecx,ecx
.header:
dec esi
mov cl,[esi]
@@ -150,7 +159,9 @@ rllunpack:
mov cl,[esi]
jmp .dorun
.done:
- pop cx
- sub cx,di
- neg cx
+ pop ecx
+ sub ecx,edi
+ neg ecx
ret
+
+ bits 16
diff --git a/core/runkernel.inc b/core/runkernel.inc
index b3968dbd..f13f1469 100644
--- a/core/runkernel.inc
+++ b/core/runkernel.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
@@ -19,11 +20,6 @@
;
; Hook macros, that may or may not be defined
;
-%ifndef HAVE_SPECIAL_APPEND
-%macro SPECIAL_APPEND 0
-%endmacro
-%endif
-
%ifndef HAVE_UNLOAD_PREP
%macro UNLOAD_PREP 0
%endmacro
@@ -87,7 +83,7 @@ construct_cmdline:
mov al,' ' ; Space
stosb
- SPECIAL_APPEND ; Module-specific hook
+ call do_ip_append ; Handle IPAppend
mov si,[CmdOptPtr] ; Options from user input
call strcpy
@@ -126,9 +122,10 @@ parse_cmdline:
; This either needs to have been an option with parameter,
; or be followed by EOL/whitespace
- cmp byte [di-1],'='
+ mov ax,[es:di-1] ; AL = last chr; AH = following
+ cmp al,'='
je .is_match
- cmp byte [di],' '
+ cmp ah,' '
ja .no_match
.is_match:
pop ax ; Drop option pointer on stack
@@ -458,15 +455,13 @@ setup_move:
inc cx
.no_initrd:
+ push dword run_linux_kernel
push cx ; Length of descriptor list
- push word trackbuf
- mov dword [EntryPoint],run_linux_kernel
; BX points to the final real mode segment, and will be loaded
; into DS.
jmp replace_bootstrap
-
run_linux_kernel:
;
; Set up segment registers and the Linux real-mode stack
@@ -687,7 +682,7 @@ CmdLineEnd resw 1 ; End of the command line in real_mode_seg
SetupSecs resw 1 ; Number of setup sectors (+bootsect)
KernelVersion resw 1 ; Kernel protocol version
;
-; These
+; These are derived from the command-line parser
;
InitRDPtr resw 1 ; Pointer to initrd= option in command line
LoadFlags resb 1 ; Loadflags from kernel
diff --git a/core/syslinux.ld b/core/syslinux.ld
index f59e5b15..6f7f5a78 100644
--- a/core/syslinux.ld
+++ b/core/syslinux.ld
@@ -1,3 +1,16 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
/*
* Linker script for the SYSLINUX core
*/
@@ -22,14 +35,14 @@ SECTIONS
__earlybss_len = __earlybss_end - __earlybss_start;
__earlybss_dwords = (__earlybss_len + 3) >> 2;
- .bcopy32 : AT (__bcopy32_lma) {
- FILL(0x90909090)
- __bcopy32_start = .;
- *(.bcopy32)
- __bcopy32_end = .;
+ .bss : {
+ __bss_start = .;
+ *(.bss)
+ *(.bss2)
+ __bss_end = .;
}
- __bcopy32_len = __bcopy32_end - __bcopy32_start;
- __bcopy32_dwords = (__bcopy32_len + 3) >> 2;
+ __bss_len = __bss_end - __bss_start;
+ __bss_dwords = (__bss_len + 3) >> 2;
.config : AT (__config_lma) {
__config_start = .;
@@ -39,19 +52,11 @@ SECTIONS
__config_len = __config_end - __config_start;
__config_dwords = (__config_len + 3) >> 2;
- .bss : AT(__bss_start) {
- __bss_start = .;
- *(.bss)
- *(.bss2)
- __bss_end = .;
- }
- __bss_len = __bss_end - __bss_start;
- __bss_dwords = (__bss_len + 3) >> 2;
-
/* Stack */
- . = 0x7c00 - STACK_LEN;
- .stack : {
+ STACK_BASE = 0x7c00 - STACK_LEN;
+ . = STACK_BASE;
+ .stack : AT(STACK_BASE) {
__stack_start = .;
. += STACK_LEN;
__stack_end = .;
@@ -71,9 +76,15 @@ SECTIONS
__text_len = __text_end - __text_start;
__text_dwords = (__text_len + 3) >> 2;
- . = ALIGN(4);
- __bcopy32_lma = .;
- . += SIZEOF(.bcopy32);
+ . = ALIGN(16);
+ .bcopyxx : {
+ FILL(0x90909090)
+ __bcopyxx_start = .;
+ *(.bcopyxx)
+ __bcopyxx_end = .;
+ }
+ __bcopyxx_len = __bcopyxx_end - __bcopyxx_start;
+ __bcopyxx_dwords = (__bcopyxx_len + 3) >> 2;
. = ALIGN(4);
.data : {
diff --git a/core/ui.inc b/core/ui.inc
index 937dd526..d59143bb 100644
--- a/core/ui.inc
+++ b/core/ui.inc
@@ -1,6 +1,7 @@
;; -----------------------------------------------------------------------
;;
-;; Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
+;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+;; Copyright 2009 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
diff --git a/doc/comboot.txt b/doc/comboot.txt
index 5f57da7b..b1334511 100644
--- a/doc/comboot.txt
+++ b/doc/comboot.txt
@@ -79,13 +79,14 @@ The following arguments are passed to the program on the stack:
Address Size Meaning
[ESP] dword Return (termination) address
- [ESP+4] dword Number of additional arguments (currently 5)
+ [ESP+4] dword Number of additional arguments (currently 7)
[ESP+8] dword Pointer to the command line arguments (null-terminated string)
[ESP+12] dword Pointer to INT call helper function
[ESP+16] dword Pointer to low memory bounce buffer
[ESP+20] dword Size of low memory bounce buffer
[ESP+24] dword Pointer to FAR call helper function (new in 2.05)
[ESP+28] dword Pointer to CDECL helper function (new in 3.54)
+ [ESP+32] dword Amount of memory controlled by the Syslinux core (new in 3.74)
This corresponds to the following C prototype, available in the file
com32/include/com32.h:
@@ -568,15 +569,7 @@ AX=0010h [3.00] Resolve hostname [PXELINUX]
all uses of IP addresses in PXE are also in network byte order.
-AX=0011h [3.05] Maximum number of shuffle descriptors
- Input: AX 0011h
- Output: CX maximum number of descriptors
-
- This routine reports the maximum number of shuffle descriptors
- permitted in a call to functions 0012h, 001Ah and 001Bh.
-
- This is guaranteed to be at least 64. For the current
- version, this is 682 for all derivatives.
+AX=0011h [3.05] Obsoleted in 3.80
AX=0012h [3.50] Cleanup, shuffle and boot
@@ -806,85 +799,10 @@ AX=0019h [3.50] Read disk [SYSLINUX, ISOLINUX, EXTLINUX]
2048-byte CD-ROM sector numbers.
-AX=001Ah [3.50] Cleanup, shuffle and boot to flat protected mode
- Input: AX 001Ah
- DX derivative-specific flags (see function 000Ch)
- ES:DI shuffle descriptor list (must be in low memory)
- CX number of shuffle descriptors
- DS:SI pointer to register values (must be in low memory)
- Output: Does not return
- (if CX is too large the routine returns with CF=1)
+AX=001Ah [3.50] Obsoleted in 3.80
- This routine performs final cleanup, then performs a sequence
- of copies, and jumps to a specified protected mode entry point.
- This is otherwise similar to function 0012h; see that function
- for the meaning of ES:DI and CX.
-
- DS:SI points to the initial register file, which is a structure
- of 9 dwords (available in <syslinux/bootpm.h>):
-
- struct syslinux_pm_regs {
- uint32_t eax; /* Offset 0 */
- uint32_t ecx; /* Offset 4 */
- uint32_t edx; /* Offset 8 */
- uint32_t ebx; /* Offset 12 */
- uint32_t esp; /* Offset 16 */
- uint32_t ebp; /* Offset 20 */
- uint32_t esi; /* Offset 24 */
- uint32_t edi; /* Offset 28 */
-
- uint32_t eip; /* Offset 32 */
- };
-
- Protected mode is entered with all data segments set up as a
- flat 32-bit read/write segment and the code segment a flat 32-bit
- read/execute segment. Interrupts and paging is off, CPL=0, DF=0;
- however, GDT, LDT and IDT are undefined, so it is up to the
- invoked code to set new descriptor tables to its liking.
-
-
-AX=001Bh [3.50] Cleanup, shuffle and boot to real mode
- Input: AX 001Bh
- DX derivative-specific flags (see function 000Ch)
- ES:DI shuffle descriptor list (must be in low memory)
- CX number of shuffle descriptors
- DS:SI pointer to register values (must be in low memory)
- Output: Does not return
- (if CX is too large the routine returns with CF=1)
- This routine performs final cleanup, then performs a sequence
- of copies, and jumps to a specified entry point.
- This is similar to function 0012h but allow more control over
- the initial register state; see that function for the meaning of
- ES:DI and CX.
-
- DS:SI points to the initial register file, which is a structure
- in the following format (available in <syslinux/bootrm.h>;
- note that this is a completely different structure from the
- com32sys_t structure described at the top of this document!):
-
- struct syslinux_rm_regs {
- uint16_t es; /* Offset 0 */
- uint16_t _unused_cs; /* Offset 2 */
- uint16_t ds; /* Offset 4 */
- uint16_t ss; /* Offset 6 */
- uint16_t fs; /* Offset 8 */
- uint16_t gs; /* Offset 10 */
-
- reg32_t eax; /* Offset 12 */
- reg32_t ecx; /* Offset 16 */
- reg32_t edx; /* Offset 20 */
- reg32_t ebx; /* Offset 24 */
- reg32_t esp; /* Offset 28 */
- reg32_t ebp; /* Offset 32 */
- reg32_t esi; /* Offset 36 */
- reg32_t edi; /* Offset 40 */
-
- uint16_t ip; /* Offset 44 */
- uint16_t cs; /* Offset 46 */
- };
-
- Interrupts are off and DF=0 on entry.
+AX=001Bh [3.50] Obsoleted in 3.80
AX=001Ch [3.60] Get pointer to auxilliary data vector
@@ -965,3 +883,67 @@ AX=0022h [3.74] Close directory
Output SI 0
Closes a directory.
+
+
+AX=0023h [3.80] Get shuffler parameters
+ Input: AX 0023h
+ Output: CX size of shuffler "safe area" in bytes
+ Other registers reserved for future use
+
+ This call gives the size of the required shuffler "safe area",
+ in bytes; for call 0024h. In the future, it may provide
+ additional parameters.
+
+
+AX=0024h [3.80] Cleanup, shuffle and boot, raw version
+ Input: AX 0024h
+ DX derivative-specific flags (see function 000Ch)
+ EDI shuffle descriptor list safe area
+ ESI shuffle descriptor list source
+ ECX byte count of shuffle descriptor list
+ Output: Does not return
+
+ This routine performs final cleanup, then performs a sequence
+ of copies, and jumps to a specified real mode entry point.
+ This is a more general version of function 000Dh, which can
+ also be used to load other types of programs.
+
+ Unlike previous obsolete versions of this function, there are
+ no restrictions that copies must not touch memory below
+ address 7C00h. Either the shuffle descriptor list or the safe
+ area (or both) may be located in high memory.
+
+ ESI points to a list of descriptors each of the form:
+
+ Offset Size Meaning
+ 0 dword destination address
+ 4 dword source address (-1 = zero)
+ 8 dword length in bytes (0 = end of list)
+
+ The copies are overlap-safe, like memmove().
+
+ Before actually executing the move list, the list is moved to
+ the address specified in EDI. The caller is responsibe to
+ ensure that the moved descriptor list plus a "safe area"
+ immediately afterwards (the size of which is specified by
+ function 0023h) is not disturbed by the copy sequence. It is,
+ however, safe to overwrite descriptors already consumed.
+
+ If the source address is -1 (FFFFFFFFh) then the block
+ specified by the destination address and the length is set to
+ all zero.
+
+ The list is terminated by an entry with length 0. For that
+ entry, the destination is used as an entry point, and the
+ source represents the type of entry point:
+
+ 0 Real mode (dst is CS:IP)
+ 1 Flat 32-bit protected mode (dst is EIP)
+
+ This routine does not set up any register state whatsoever,
+ including stack. It is the responsibility of the caller to
+ make sure the entry point provided sets up any registers
+ needed. This is particularly important that a real mode entry
+ point reloads all data segment registers at the earliest
+ possible point.
+
diff --git a/doc/menu.txt b/doc/menu.txt
index 379df321..72bc9dca 100644
--- a/doc/menu.txt
+++ b/doc/menu.txt
@@ -48,6 +48,12 @@ MENU HIDDEN
All that is displayed is a timeout message.
+MENU SHIFTKEY
+
+ Exit the menu system immediately unless either the Shift or Alt
+ key is pressed, or Caps Lock or Scroll Lock is set.
+
+
MENU SEPARATOR
Insert an empty line in the menu.
@@ -269,6 +275,23 @@ DEFAULT label
non-label. The menu system does not support that.
+MENU SAVE
+
+ Remember the last entry selected and make that the default for
+ the next boot. A password-protected menu entry is *not*
+ saved. This requires the ADV data storage mechanism, which is
+ currently only implemented for EXTLINUX, although the other
+ Syslinux derivatives will accept the command (and ignore it.)
+
+ NOTE: MENU SAVE stores the LABEL tag of the selected entry;
+ this mechanism therefore relies on LABEL tags being unique.
+ On the other hand, it handles changes in the configuration
+ file gracefully.
+
+ The MENU SAVE information can be cleared with
+ "extlinux --reset-adv".
+
+
INCLUDE filename [tagname]
MENU INCLUDE filename [tagname]
diff --git a/gpxe/Makefile b/gpxe/Makefile
index 7a34f8a7..b079d532 100644
--- a/gpxe/Makefile
+++ b/gpxe/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
## Copyright 2008-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
diff --git a/mbr/Makefile b/mbr/Makefile
index 0bdf7e3f..6cd677c0 100644
--- a/mbr/Makefile
+++ b/mbr/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
-## Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
@@ -17,30 +18,31 @@
topdir = ..
include $(topdir)/MCONFIG.embedded
-all: mbr.bin gptmbr.bin isohdpfx.bin
+all: mbr.bin altmbr.bin gptmbr.bin isohdpfx.bin \
+ mbr_c.bin altmbr_c.bin gptmbr_c.bin isohdpfx_c.bin \
+ mbr_f.bin altmbr_f.bin gptmbr_f.bin isohdpfx_f.bin
.PRECIOUS: %.o
-%.o: %.S
+%.o: %.S adjust.h
$(CC) $(SFLAGS) -Wa,-a=$*.lst -c -o $@ $<
+%_c.o: %.S adjust.h
+ $(CC) $(SFLAGS) -Wa,-a=$*_c.lst -DCTRL_80 -c -o $@ $<
+
+%_f.o: %.S adjust.h
+ $(CC) $(SFLAGS) -Wa,-a=$*_f.lst -DFORCE_80 -c -o $@ $<
+
.PRECIOUS: %.elf
%.elf: %.o mbr.ld
$(LD) $(LDFLAGS) -T mbr.ld -e _start -o $@ $<
-mbr.bin: mbr.elf checksize.pl
- $(OBJCOPY) -O binary $< $@
- $(PERL) checksize.pl $@ 440
-
-isohdpfx.bin: isohdpfx.elf checksize.pl
+%.bin: %.elf checksize.pl
$(OBJCOPY) -O binary $< $@
- $(PERL) checksize.pl $@ 432
+ $(PERL) checksize.pl $@
+ $(CHMOD) -x $@
mbr_bin.c: mbr.bin
-gptmbr.bin: gptmbr.elf checksize.pl
- $(OBJCOPY) -O binary $< $@
- $(PERL) checksize.pl $@ 424
-
tidy dist:
rm -f *.o *.elf *.lst
diff --git a/mbr/adjust.h b/mbr/adjust.h
new file mode 100644
index 00000000..42c12a35
--- /dev/null
+++ b/mbr/adjust.h
@@ -0,0 +1,53 @@
+/* -*- asm -*- -----------------------------------------------------------
+ *
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * adjust.h
+ *
+ * Macros to adjust the drive number
+ */
+
+#ifndef ADJUST_H
+#define ADJUST_H
+
+#ifdef CTRL_80
+ .macro ADJUST_DRIVE
+ testb $0x04, BIOS_kbdflags
+ jz 1f
+ movb $0x80, %dl
+1:
+ .endm
+#elif defined(FORCE_80)
+ .macro ADJUST_DRIVE
+ movb $0x80, %dl
+ .endm
+#else
+ .macro ADJUST_DRIVE
+ .endm
+#endif
+
+#endif /* ADJUST_H */
diff --git a/mbr/altmbr.S b/mbr/altmbr.S
new file mode 100644
index 00000000..4a502ed0
--- /dev/null
+++ b/mbr/altmbr.S
@@ -0,0 +1,306 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include "adjust.h"
+
+ .code16
+ .text
+
+ .globl bootsec
+stack = 0x7c00
+driveno = (stack-6)
+sectors = (stack-8)
+secpercyl = (stack-12)
+
+BIOS_kbdflags = 0x417
+BIOS_page = 0x462
+
+ /* gas/ld has issues with doing this as absolute addresses... */
+ .section ".bootsec", "a", @nobits
+ .globl bootsec
+bootsec:
+ .space 512
+
+ .text
+ .globl _start
+_start:
+ cli
+ xorw %ax, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw $stack, %sp
+ movw %sp, %si
+ pushw %es /* es:di -> $PnP header */
+ pushw %di
+ movw %ax, %es
+ sti
+ cld
+
+ /* Copy down to 0:0x600 */
+ movw $_start, %di
+ movw $(512/2), %cx
+ rep; movsw
+
+ ljmpw $0, $next
+next:
+
+ ADJUST_DRIVE
+ pushw %dx /* dl -> drive number */
+
+ /* Check to see if we have EBIOS */
+ pushw %dx /* drive number */
+ movb $0x41, %ah /* %al == 0 already */
+ movw $0x55aa, %bx
+ xorw %cx, %cx
+ xorb %dh, %dh
+ stc
+ int $0x13
+ jc 1f
+ cmpw $0xaa55, %bx
+ jne 1f
+ shrw %cx /* Bit 0 = fixed disk subset */
+ jnc 1f
+
+ /* We have EBIOS; patch in the following code at
+ read_sector_cbios: movb $0x42, %ah ; jmp read_common */
+ movl $0xeb42b4+((read_common-read_sector_cbios-4) << 24), \
+ (read_sector_cbios)
+
+1:
+ popw %dx
+
+ /* Get (C)HS geometry */
+ movb $0x08, %ah
+ int $0x13
+ andw $0x3f, %cx /* Sector count */
+ pushw %cx /* Save sectors on the stack */
+ movzbw %dh, %ax /* dh = max head */
+ incw %ax /* From 0-based max to count */
+ mulw %cx /* Heads*sectors -> sectors per cylinder */
+
+ /* Save sectors/cylinder on the stack */
+ pushw %dx /* High word */
+ pushw %ax /* Low word */
+
+ xorl %eax, %eax /* Base */
+ cdq /* Root (%edx <- 0) */
+ call scan_partition_table
+
+ /* If we get here, we have no OS */
+missing_os:
+ call error
+ .ascii "Missing operating system.\r\n"
+
+/*
+ * read_sector: read a single sector pointed to by %eax to 0x7c00.
+ * CF is set on error. All registers saved.
+ */
+read_sector:
+ pushal
+ xorl %edx, %edx
+ movw $bootsec, %bx
+ pushl %edx /* MSW of LBA */
+ pushl %eax /* LSW of LBA */
+ pushw %es /* Buffer segment */
+ pushw %bx /* Buffer offset */
+ pushw $1 /* Sector count */
+ pushw $16 /* Size of packet */
+ movw %sp, %si
+
+ /* This chunk is skipped if we have ebios */
+ /* Do not clobber %eax before this chunk! */
+ /* This also relies on %bx and %edx as set up above. */
+read_sector_cbios:
+ divl (secpercyl)
+ shlb $6, %ah
+ movb %ah, %cl
+ movb %al, %ch
+ xchgw %dx, %ax
+ divb (sectors)
+ movb %al, %dh
+ orb %ah, %cl
+ incw %cx /* Sectors are 1-based */
+ movw $0x0201, %ax
+
+read_common:
+ movb (driveno), %dl
+ int $0x13
+ leaw 16(%si), %sp /* Drop DAPA */
+ popal
+ ret
+
+/*
+ * read_partition_table:
+ * Read a partition table (pointed to by %eax), and copy
+ * the partition table into the ptab buffer.
+ *
+ * Clobbers %si, %di, and %cx, other registers preserved.
+ * %cx = 0 on exit.
+ *
+ * On error, CF is set and ptab is overwritten with junk.
+ */
+ptab = _start+446
+
+read_partition_table:
+ call read_sector
+ movw $bootsec+446, %si
+ movw $ptab, %di
+ movw $(16*4/2), %cx
+ rep ; movsw
+ ret
+
+/*
+ * scan_partition_table:
+ * Scan a partition table currently loaded in the partition table
+ * area. Preserve all registers.
+ *
+ * On entry:
+ * %eax - base (location of this partition table)
+ * %edx - root (offset from MBR, or 0 for MBR)
+ *
+ * These get pushed into stack slots:
+ * 28(%bp) - %eax - base
+ * 20(%bp) - %edx - root
+ */
+
+scan_partition_table:
+ pushal
+ movw %sp, %bp
+
+ /* Scan the primary partition table */
+ movw $ptab, %si
+ movw $4, %cx
+ push %si
+ push %cx
+
+ /* Is it a primary partition? */
+ andl %edx, %edx
+ jnz 6f
+
+5:
+ decb (partition)
+ jz boot
+ addw $16, %bx
+ loopw 5b
+
+6:
+ /* No active partitions found, look for extended partitions */
+ popw %cx /* %cx <- 4 */
+ popw %si /* %si <- ptab */
+7:
+ movl 20(%bp), %edx /* "Root" */
+
+ movb 4(%si), %al
+ cmpb $0x0f, %al /* 0x0f = Win9x extended */
+ je 8f
+ andb $~0x80, %al /* 0x85 = Linux extended */
+ cmpb $0x05, %al /* 0x05 = MS-DOS extended */
+ jne 9f
+
+ /* It is an extended partition. Read the extended partition and
+ try to scan it. If the scan returns, re-load the current
+ partition table and resume scan. */
+8:
+ movl 8(%si), %eax /* Partition table offset */
+ addl %edx, %eax /* Compute location of new ptab */
+ andl %edx, %edx /* Is this the MBR? */
+ jnz 10f
+ movl %eax, %edx /* Offset -> root if this was MBR */
+10:
+ call read_partition_table
+ jc 11f
+ call scan_partition_table
+11:
+ /* This returned, so we need to reload the current partition table */
+ movl 28(%bp), %eax /* "Base" */
+ call read_partition_table
+
+ /* fall through */
+9:
+ /* Not an extended partition */
+ andb %al, %al
+ jz 12f /* Not a valid partition */
+ andl %edx, %edx /* Are we inside an extended part? */
+ /* If so, this is a logical partition */
+ decb (partition)
+ je boot
+12:
+ addw $16, %si
+ loopw 7b
+
+ /* Nothing found, return */
+ popal
+ ret
+
+/*
+ * boot: invoke the actual bootstrap. (%si) points to the partition
+ * table entry, and 28(%bp) has the partition table base.
+ */
+boot:
+ cmpb $0, 4(%si)
+ je missing_os
+ movl 8(%si), %eax
+ addl 28(%bp), %eax
+ movl %eax, 8(%si) /* Adjust in-memory partition table entry */
+ call read_sector
+ jc disk_error
+ cmpw $0xaa55, (bootsec+510)
+ jne missing_os /* Not a valid boot sector */
+ movw $driveno, %sp /* driveno == bootsec-6 */
+ popw %dx /* dl -> drive number */
+ popw %di /* es:di -> $PnP vector */
+ popw %es
+ cli
+ jmpw *%sp /* %sp == bootsec */
+
+disk_error:
+ call error
+ .ascii "Operating system load error.\r\n"
+
+/*
+ * Print error messages. This is invoked with "call", with the
+ * error message at the return address.
+ */
+error:
+ popw %si
+2:
+ lodsb
+ movb $0x0e, %ah
+ movb (BIOS_page), %bh
+ movb $0x07, %bl
+ int $0x10 /* May destroy %bp */
+ cmpb $10, %al /* Newline? */
+ jne 2b
+
+ int $0x18 /* Boot failure */
+die:
+ hlt
+ jmp die
+
+/* Location of the partition configuration byte */
+partition = _start + 439
diff --git a/mbr/checksize.pl b/mbr/checksize.pl
index 68a035b7..4648c95c 100755
--- a/mbr/checksize.pl
+++ b/mbr/checksize.pl
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
-## Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
@@ -13,18 +14,41 @@
##
## checksize.pl
##
-## Check the size of a binary file
+## Check the size of a binary file and pad it with zeroes to that size
##
-($file, $maxsize) = @ARGV;
+use bytes;
-@st = stat($file);
+($file, $maxsize, $padsize) = @ARGV;
+
+if (!defined($maxsize)) {
+ # Defaults based on the filename
+ if ($file =~ /^mbr[^0-9a-z]/) {
+ $maxsize = $padsize = 440;
+ } elsif ($file =~ /^gptmbr[^0-9a-z]/) {
+ $maxsize = $padsize = 424;
+ } elsif ($file =~ /^isohdpfx[^0-9a-z]/) {
+ $maxsize = $padsize = 432;
+ } elsif ($file =~ /^altmbr[^0-9a-z]/) {
+ $maxsize = 439; $padsize = 440;
+ } else {
+ die "$0: no default size for filename: $file\n";
+ }
+}
+
+$padsize = $maxsize unless(defined($padsize));
+
+open(FILE, '+<', $file) or die;
+@st = stat(FILE);
if (!defined($size = $st[7])) {
die "$0: $file: $!\n";
}
if ($size > $maxsize) {
print STDERR "$file: too big ($size > $maxsize)\n";
exit 1;
-} else {
- exit 0;
+} elsif ($size < $padsize) {
+ seek(FILE, $size, 0);
+ print FILE "\0" x ($padsize-$size);
}
+
+exit 0;
diff --git a/mbr/gptmbr.S b/mbr/gptmbr.S
index 385afe74..8d42e8b8 100644
--- a/mbr/gptmbr.S
+++ b/mbr/gptmbr.S
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -25,6 +26,8 @@
*
* ----------------------------------------------------------------------- */
+#include "adjust.h"
+
.code16
.text
@@ -42,6 +45,7 @@ bootguid = _start + 0x1a8
/* Where we put DS:SI */
dssi_out = _start + 0x1be
+BIOS_kbdflags = 0x417
BIOS_page = 0x462
/* gas/ld has issues with doing this as absolute addresses... */
@@ -61,7 +65,6 @@ _start:
movw %sp, %si
pushw %es /* 4(%bp) es:di -> $PnP header */
pushw %di /* 2(%bp) */
- pushw %dx /* 0(%bp) = %dl -> drive number */
movw %ax, %es
sti
cld
@@ -72,8 +75,11 @@ _start:
rep; movsw
ljmpw $0, $next
-
next:
+
+ ADJUST_DRIVE
+ pushw %dx /* 0(%bp) = %dl -> drive number */
+
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
@@ -163,10 +169,10 @@ find_part:
found_part:
xchgw %ax,%cx /* Set up %cx for rep movsb further down */
-
+
movw $dssi_out,%di
pushw %di
-
+
/* 80 00 00 00 ee 00 00 00
- bootable partition, type EFI (EE), no CHS information */
xorl %eax,%eax
@@ -210,7 +216,7 @@ boot:
missing_os:
call error
- .ascii "Operating system not bootable\r\n"
+ .ascii "OS not bootable\r\n"
saturate_stosl:
pushl %eax
diff --git a/mbr/isohdpfx.S b/mbr/isohdpfx.S
index 9e9d55c3..f42b4b5b 100644
--- a/mbr/isohdpfx.S
+++ b/mbr/isohdpfx.S
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -32,12 +33,14 @@
* loader of a hard-coded offset, but that's good enough to load
* ISOLINUX.
*/
-
+
+#include "adjust.h"
+
.code16
.text
HYBRID_MAGIC = 0x7078c0fb
-isolinux_hybrid_signature = 0x7c00+64
+isolinux_hybrid_signature = 0x7c00+64
isolinux_start_hybrid = 0x7c00+64+4
.globl bootsec
@@ -49,7 +52,8 @@ sectors = (stack-10)
heads = (stack-12)
secpercyl = (stack-16)
-BIOS_page = 0x462
+BIOS_kbdflags = 0x417
+BIOS_page = 0x462
/* gas/ld has issues with doing this as absolute addresses... */
.section ".bootsec", "a", @nobits
@@ -69,7 +73,6 @@ _start:
movw %sp, %si
pushw %es /* es:di -> $PnP header */
pushw %di
- pushw %dx /* dl -> drive number */
movw %ax, %es
sti
cld
@@ -80,8 +83,11 @@ _start:
rep; movsw
ljmpw $0, $next
-
next:
+
+ ADJUST_DRIVE
+ pushw %dx /* dl -> drive number */
+
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
@@ -140,7 +146,7 @@ next:
*/
cmpl $HYBRID_MAGIC,(isolinux_hybrid_signature)
jne bad_signature
-
+
cli
movw $heads, %sp
diff --git a/mbr/mbr.S b/mbr/mbr.S
index 722d90db..7caf4fc4 100644
--- a/mbr/mbr.S
+++ b/mbr/mbr.S
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
*
- * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@@ -25,6 +26,8 @@
*
* ----------------------------------------------------------------------- */
+#include "adjust.h"
+
.code16
.text
@@ -34,7 +37,8 @@ driveno = (stack-6)
sectors = (stack-8)
secpercyl = (stack-12)
-BIOS_page = 0x462
+BIOS_kbdflags = 0x417
+BIOS_page = 0x462
/* gas/ld has issues with doing this as absolute addresses... */
.section ".bootsec", "a", @nobits
@@ -53,7 +57,6 @@ _start:
movw %sp, %si
pushw %es /* es:di -> $PnP header */
pushw %di
- pushw %dx /* dl -> drive number */
movw %ax, %es
sti
cld
@@ -64,8 +67,11 @@ _start:
rep; movsw
ljmpw $0, $next
-
next:
+
+ ADJUST_DRIVE
+ pushw %dx /* dl -> drive number */
+
/* Check to see if we have EBIOS */
pushw %dx /* drive number */
movb $0x41, %ah /* %al == 0 already */
diff --git a/memdisk/Makefile b/memdisk/Makefile
index d9c16206..7b557e11 100644
--- a/memdisk/Makefile
+++ b/memdisk/Makefile
@@ -1,6 +1,7 @@
## -----------------------------------------------------------------------
##
-## Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+## Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+## Copyright 2009 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
diff --git a/memdisk/memdisk.inc b/memdisk/memdisk.inc
index 0df6c770..27e9fdb1 100644
--- a/memdisk/memdisk.inc
+++ b/memdisk/memdisk.inc
@@ -7,6 +7,7 @@
; memory.
;
; Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+; Copyright 2009 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
@@ -151,7 +152,7 @@ Int13Start:
mov bp,sp ; Point BP to the entry stack frame
TRACER 'F'
; Note: AH == P_AH here
- cmp ah,[Int13FuncsCnt-1]
+ cmp ah,Int13FuncsCnt-1
ja Invalid_jump
xor al,al ; AL = 0 is standard entry condition
mov di,ax
diff --git a/memdisk/memdisk.ld b/memdisk/memdisk.ld
index 5b833c2a..51c3e35c 100644
--- a/memdisk/memdisk.ld
+++ b/memdisk/memdisk.ld
@@ -1,3 +1,15 @@
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
/*
* Linker script for MEMDISK
*/
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 1939a691..0fee9820 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -1,6 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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
@@ -20,7 +21,7 @@
const char memdisk_version[] =
"MEMDISK " VERSION_STR " " DATE;
const char copyright[] =
-"Copyright " FIRSTYEAR "-" YEAR_STR " H. Peter Anvin and contributors";
+"Copyright " FIRSTYEAR "-" YEAR_STR " H. Peter Anvin et al";
extern const char _binary_memdisk_chs_bin_start[];
extern const char _binary_memdisk_chs_bin_end[];
diff --git a/memdisk/start32.S b/memdisk/start32.S
index 073d049c..6c88d462 100644
--- a/memdisk/start32.S
+++ b/memdisk/start32.S
@@ -1,7 +1,20 @@
-#
-# Simple stub to get us to the right point in the 32-bit code;
-# this module must be linked first
-#
+/* -----------------------------------------------------------------------
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 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., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Simple stub to get us to the right point in the 32-bit code;
+ * this module must be linked first
+ */
.section ".init", "ax"
.globl _start
_start:
diff --git a/mime/image/x-lss16.xml b/mime/image/x-lss16.xml
new file mode 100644
index 00000000..b13f47e8
--- /dev/null
+++ b/mime/image/x-lss16.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <mime-type type="image/x-lss16">
+ <comment>LSS16 image</comment>
+ <comment xml:lang="be@latin">Vyjava LSS16</comment>
+ <comment xml:lang="bg">Изображение — LSS16</comment>
+ <comment xml:lang="ca">imatge LSS16</comment>
+ <comment xml:lang="cs">Obrázek LSS16</comment>
+ <comment xml:lang="de">LSS16-Bild</comment>
+ <comment xml:lang="en_GB">LSS16 image</comment>
+ <comment xml:lang="es">imagen LSS16</comment>
+ <comment xml:lang="eu">LSS16 irudia</comment>
+ <comment xml:lang="fi">LSS16-kuva</comment>
+ <comment xml:lang="fr">image LSS16</comment>
+ <comment xml:lang="ga">íomhá LSS16</comment>
+ <comment xml:lang="hu">LSS16 kép</comment>
+ <comment xml:lang="id">Citra LSS16</comment>
+ <comment xml:lang="it">Immagine LSS16</comment>
+ <comment xml:lang="ja">LSS16 画像</comment>
+ <comment xml:lang="ko">LSS16 그림</comment>
+ <comment xml:lang="lt">LSS16 paveikslėlis</comment>
+ <comment xml:lang="nb">LSS16-bilde</comment>
+ <comment xml:lang="nl">LSS16-afbeelding</comment>
+ <comment xml:lang="nn">LSS16-bilete</comment>
+ <comment xml:lang="pl">Obraz LSS16</comment>
+ <comment xml:lang="pt_BR">Imagem LSS16</comment>
+ <comment xml:lang="ru">изображение LSS16</comment>
+ <comment xml:lang="sq">Figurë LSS16</comment>
+ <comment xml:lang="sv">LSS16-bild</comment>
+ <comment xml:lang="uk">Зображення LSS16</comment>
+ <comment xml:lang="vi">Ảnh LSS16</comment>
+ <acronym>lss16</acronym>
+ <expanded-acronym>SYSLINUX' LSS16 image data</expanded-acronym>
+ <glob pattern="*.lss" />
+ <magic priority="50">
+ <match value="0x1413f33d" type="little32" offset="0"/>
+ </magic>
+ </mime-type>
+</mime-info>
diff --git a/modules/Makefile b/modules/Makefile
index 1ffe9ef3..a3af7b70 100644
--- a/modules/Makefile
+++ b/modules/Makefile
@@ -19,7 +19,7 @@ include $(topdir)/MCONFIG.embedded
INCLUDES = -I$(com32)/include
-BINS = pxechain.com
+BINS = pxechain.com gfxboot.com
all: $(BINS)
diff --git a/modules/gfxboot.asm b/modules/gfxboot.asm
new file mode 100644
index 00000000..e3aed13f
--- /dev/null
+++ b/modules/gfxboot.asm
@@ -0,0 +1,964 @@
+; ****************************************************************************
+;
+; gfxboot.asm
+;
+; Copyright 2008-2009 Sebastian Herbszt
+;
+; This module is based on the gfxboot integration patch by Steffen Winterfeldt:
+;
+; Copyright 2001-2008 Steffen Winterfeldt
+;
+; Some parts borrowed from Syslinux core:
+;
+; Copyright 1994-2009 H. Peter Anvin - 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
+; 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.
+;
+; ****************************************************************************
+
+ absolute 0
+pspInt20: resw 1
+pspNextP: resw 1
+ resb 124
+pspCmdLen: resb 1
+pspCmdArg: resb 127
+
+;%define DEBUG
+
+ section .text
+ org 100h
+
+_start:
+ mov ax,2
+ mov bx, msg_progname
+ int 22h
+
+ mov ax,2
+ mov bx, msg_crlf
+ int 22h
+
+ push es
+ mov ax,0ah
+ mov cl,9
+ int 22h
+ pop es
+ cmp al,32h
+ jnz not_pxelinux
+
+ mov dl,0 ; fake drive number
+ mov cl,11 ; fake sector size 2048 bytes
+
+not_pxelinux:
+ mov [derivative_id],al
+ mov [drivenumber],dl
+ mov [sectorshift],cl
+ mov ax,1
+ shl ax,cl
+ mov [sectorsize],ax
+ mov ax,trackbufsize
+ shr ax,cl
+ mov [BufSafe],ax
+
+ xor cx,cx
+ mov cl,[pspCmdLen]
+ dec cx
+ and cx,cx
+ jne continue
+
+ mov ax,2
+ mov bx, msg_usage
+ int 22h
+ ret
+continue:
+ mov di,pspCmdArg+1
+ add di,cx
+ dec di
+ std
+ mov al,' '
+ repe scasb
+ inc cx
+ cld
+ mov [pspCmdLen],cl
+ mov si,pspCmdArg+1
+ mov di,si
+ add di,cx
+ xor al,al
+ stosb
+ mov si,pspCmdArg+1
+
+; get config file name
+ mov ax,0eh
+ int 22h
+
+; open config file
+ mov si,bx ; es:bx config file name
+ mov ax,6
+ int 22h
+ jc no_config_file
+ and eax,eax
+ jz no_config_file
+ jmp got_config_file
+no_config_file:
+ push es
+ push bx
+ push cs
+ pop es
+ mov bx, msg_config_file
+ mov ax,2
+ int 22h
+ mov bx, msg_space
+ mov ax,2
+ int 22h
+ pop bx
+ pop es
+ mov ax,2
+ int 22h
+ push cs
+ pop es
+ mov bx, msg_space
+ mov ax,2
+ int 22h
+ mov bx, msg_missing
+ mov ax,2
+ int 22h
+ mov ax,2
+ mov bx, msg_crlf
+ int 22h
+ ret
+got_config_file:
+ push cs
+ pop es
+ call parse_config
+
+; get_gfx_file
+ mov ax,cs
+ add ax,2000h
+ mov word [gfx_mem_start_seg],ax
+ mov ax,[pspNextP]
+ mov word [gfx_mem_end_seg],ax
+
+ call gfx_init
+ jc error
+
+ call gfx_setup_menu
+ jc exit
+
+input:
+ call gfx_input
+ jc exit
+
+ cmp eax,1
+ jz exit
+
+ cmp eax,2
+ jz boot
+
+ jmp input
+
+boot:
+ call far [gfx_bc_done]
+ mov ax,cs
+ mov es,ax
+ mov bx,command_line
+ mov ax,3
+ int 22h
+exit:
+ call far [gfx_bc_done]
+error:
+ ret
+
+cb_table dw cb_status ; 0
+ dw cb_fopen ; 1
+ dw cb_fread ; 2
+ dw cb_getcwd ; 3
+ dw cb_chdir ; 4
+ dw cb_readsector ; 5
+cb_len equ ($-cb_table)/2
+
+gfx_cb:
+ push cs
+ pop ds
+
+ cmp al,cb_len
+ jae gfx_cb_error
+
+ movzx bx,al
+ add bx,bx
+ call word [bx+cb_table]
+ jmp gfx_cb_end
+gfx_cb_error:
+ mov al,0ffh
+gfx_cb_end:
+ retf
+
+; Return status info
+;
+; return:
+; edx filename buffer (64 bytes)
+;
+cb_status:
+ mov edx,cs
+ shl edx,4
+ add edx,fname_buf
+
+ xor al,al
+ ret
+
+; Open file
+;
+; return:
+; al 0: ok, 1: file not found
+; ecx file length (al = 0)
+;
+cb_fopen:
+ push ds
+ pop es
+ mov ax,6
+ mov si,fname_buf
+ int 22h
+ jnc cb_fopen_ok
+cb_fopen_failed:
+ mov al,1
+ jmp cb_fopen_end
+cb_fopen_ok:
+ mov ecx,eax
+ mov [f_handle],si
+ mov [f_size],ecx
+ xor al,al
+cb_fopen_end:
+ ret
+
+; Read next chunk
+;
+; return:
+; edx buffer address (linear)
+; ecx data length (< 64k)
+;
+cb_fread:
+ cmp dword [f_size],0
+ jz cb_fread_eof
+ push ds
+ pop es
+ mov ax,7
+ mov si,[f_handle]
+ mov bx,trackbuf
+ mov cx,[BufSafe]
+ int 22h
+ mov al,1
+ jc cb_fread_end
+ sub [f_size], ecx
+ or si,si
+ jnz cb_fread_noeof
+ and dword [f_size],0
+cb_fread_noeof:
+ mov edx,cs
+ shl edx,4
+ add edx,trackbuf
+ jmp cb_fread_ok
+cb_fread_eof:
+ xor ecx,ecx
+cb_fread_ok:
+ xor al,al
+cb_fread_end:
+ ret
+
+; Return current working directory
+;
+; return:
+; edx filename
+;
+cb_getcwd:
+ mov edx,cs
+ shl edx,4
+ add edx,gfx_slash
+ xor al,al
+ ret
+
+; Set current working directory
+;
+cb_chdir:
+ xor al,al
+ ret
+
+; Read sector
+;
+; edx sector
+;
+; return:
+; edx buffer (linear address)
+;
+; Note: does not return on error!
+;
+cb_readsector:
+ push esi
+ push edi
+ push ds
+ pop es
+ mov ax,19h
+ xor esi,esi
+ xor edi,edi
+ mov cx,1
+ mov bx,trackbuf
+ int 22h
+ pop edi
+ pop esi
+ mov al,1
+ jc cb_readsector_end
+ mov edx,ds
+ shl dx,4
+ add edx,trackbuf
+ xor al,al
+cb_readsector_end:
+ ret
+
+gfx_init:
+ mov ax,0e801h
+ xor bx,bx
+ xor cx,cx
+ xor dx,dx
+ int 15h
+ jnc got_e801
+
+ mov ax,2
+ mov bx, msg_memory
+ int 22h
+ stc
+ ret
+
+got_e801:
+ cmp ax,3c00h
+ jb mem_below_16mb
+ shl ebx,6
+ add eax,ebx
+
+mem_below_16mb:
+ shl eax,10
+ mov [gfx_bios_mem_size],eax
+ shr eax,20
+ cmp ax,16
+ jb skip_extended
+
+ mov word [gfx_xmem_0],88h ; 8MB at 8MB
+ mov dword [gfx_save_area1],7f0000h ; 8MB-64k
+
+skip_extended:
+ movzx ebx,word [gfx_mem_start_seg]
+ shl ebx,4
+
+ movzx ecx,word [gfx_mem_end_seg]
+ shl ecx,4
+
+ mov dword [gfx_mem],ebx
+ mov dword [gfx_mem0_start],ebx
+ mov dword [gfx_mem0_end],ecx
+
+ call gfx_read_file
+ jc gfx_init_end
+
+ call gfx_get_sysconfig
+
+ ; align 4
+ mov eax,[gfx_mem0_start]
+ add eax,3
+ and eax,~3
+ mov [gfx_mem0_start],eax
+
+; setup jump table
+ les bx,[gfx_bc_jt]
+
+ mov ax,[es:bx]
+ mov [gfx_bc_init],ax
+ mov [gfx_bc_init+2],es
+
+ mov ax,[es:bx+2]
+ mov [gfx_bc_done],ax
+ mov [gfx_bc_done+2],es
+
+ mov ax,[es:bx+4]
+ mov [gfx_bc_input],ax
+ mov [gfx_bc_input+2],es
+
+ mov ax,[es:bx+6]
+ mov [gfx_bc_menu_init],ax
+ mov [gfx_bc_menu_init+2],es
+
+; ...
+
+ mov esi,cs
+ shl esi,4
+ add esi,gfx_sysconfig
+ call far [gfx_bc_init]
+
+gfx_init_end:
+ ret
+
+gfx_read_file:
+; open file
+; es:si - file name
+
+ push cs
+ pop es
+ mov ax,6
+ mov si,pspCmdArg+1
+ int 22h
+ jnc gfx_file_read
+ stc
+ ret
+
+gfx_file_read:
+; si - file handle
+; eax - length of file in bytes, or -1
+; cx - file block size
+
+ mov edx,[gfx_mem0_end]
+ sub edx,[gfx_mem0_start]
+ sub edx,0fh ; space to allow for aligning later
+ ; edx: max allowed size
+
+ cmp eax,-1 ; unknown file size -> set to max allowed size
+ jnz .has_size
+ mov eax,edx
+.has_size:
+ cmp eax,edx
+ jbe read_bootlogo
+
+gfx_file_too_big:
+ mov ax,2
+ mov bx,msg_bootlogo_toobig
+ int 22h
+ stc
+ ret
+
+read_bootlogo:
+ mov [file_length],eax
+ mov edi,[gfx_mem]
+
+; read file
+; si - file handle
+; es:bx - buffer
+; cx - number of blocks to read
+
+read:
+ push eax
+ mov ax,7
+ mov bx,trackbuf
+ mov cx,[BufSafe]
+ int 22h
+
+ push edi
+ push ecx
+ push si
+ push es
+
+ mov si,trackbuf
+ push edi
+ call gfx_l2so
+ pop di
+ pop es
+
+ rep movsb ; move ds:si -> es:di, length ecx
+ pop es
+ pop si
+ pop ecx
+ pop edi
+
+ pop eax
+
+ ; si == 0: EOF
+ or si,si
+ jz gfx_read_done
+ add edi,ecx
+ sub eax,ecx
+ ja read
+ jmp gfx_file_too_big
+gfx_read_done:
+ sub eax,ecx
+ mov edx,[file_length]
+ sub edx,eax
+ ; edx = real file size
+ mov [gfx_archive_end],edx
+ add edx,[gfx_mem0_start]
+ add edx,0fh ; for alignment
+ mov [gfx_mem0_start],edx
+
+bootlogo_read_done:
+ call find_file
+ or eax,eax
+ jnz found_bootlogo
+ stc
+ ret
+
+found_bootlogo:
+ push edi
+ push eax
+ add eax,edi
+ push dword [gfx_mem]
+ pop dword [gfx_archive_start]
+ neg al
+ and eax,byte 0fh
+ jz no_align
+ add [gfx_archive_start],eax
+
+no_align:
+ pop eax
+ pop edi
+ sub edi,[gfx_mem]
+ mov ecx,[gfx_archive_start]
+ add edi,ecx
+ mov [gfx_file],edi
+ add [gfx_archive_end],ecx
+ add eax,edi
+ shr eax,4
+ mov [gfx_bc_jt+2],ax
+ ret
+
+gfx_get_sysconfig:
+ mov ah,0
+ cmp byte [derivative_id],33h
+ jnz not_isolinux
+ mov ah,2
+not_isolinux:
+ mov al,[drivenumber]
+ mov [gfx_boot_drive],al
+ cmp al,80h ; floppy ?
+ jae not_floppy
+ mov ah,1
+not_floppy:
+ mov byte [gfx_media_type],ah
+ mov ah,[sectorshift]
+ mov byte [gfx_sector_shift],ah
+ mov ax,cs
+ mov [gfx_bootloader_seg],ax
+ ret
+
+gfx_setup_menu:
+ push es
+ push ds
+ pop es
+
+ mov word [menu_desc+menu_ent_list],0
+ mov di,[menu_seg]
+ mov [menu_desc+menu_ent_list+2],di
+
+ mov word [menu_desc+menu_default],dentry_buf
+ mov [menu_desc+menu_default+2],cs
+
+ mov di,256
+ mov [menu_desc+menu_arg_list],di
+ mov di,[menu_seg]
+ mov [menu_desc+menu_arg_list+2],di
+
+ mov cx,[label_cnt]
+ mov [menu_desc+menu_entries],cx
+
+ mov cx,256*2
+ mov [menu_desc+menu_ent_size],cx
+ mov [menu_desc+menu_arg_size],cx
+
+ mov esi,ds
+ shl esi,4
+ add esi,menu_desc
+
+ call far [gfx_bc_menu_init]
+ pop es
+ ret
+
+magic_ok:
+ xor eax,eax
+ cmp dword [es:bx],0b2d97f00h ; header.magic_id
+ jnz magic_ok_end
+ cmp byte [es:bx+4],8 ; header.version
+ jnz magic_ok_end
+ mov eax,[es:bx+8]
+magic_ok_end:
+ ret
+
+find_file:
+ mov edi,[gfx_mem]
+ push edi
+ call gfx_l2so
+ pop bx
+ pop es
+ call magic_ok
+ or eax,eax
+ jnz find_file_end
+
+find_file_loop:
+ mov ecx,[gfx_mem0_start]
+ sub ecx,26 + 12 ; min cpio header + gfx header
+ cmp edi,ecx
+ jae find_file_end
+ push edi
+ call gfx_l2so
+ pop bx
+ pop es
+ cmp word [es:bx],71c7h
+ jnz find_file_end
+ mov ax,[es:bx+20] ; file name size
+ movzx esi,ax
+
+ inc si
+ and si,~1 ; align
+
+ mov eax,[es:bx+22] ; data size
+ rol eax,16 ; get word order right
+ mov ecx,eax
+
+ inc ecx
+ and ecx,byte ~1 ; align
+
+ add si,26 ; skip header
+
+ add edi,esi
+ add bx,si
+ call magic_ok
+ or eax,eax
+ jnz find_file_end
+
+ add edi,ecx
+ jmp find_file_loop
+
+find_file_end:
+ ret
+
+gfx_input:
+ mov edi,cs
+ shl edi,4
+ add edi, command_line ; buffer (0: no buffer)
+ mov ecx, max_cmd_len ; buffer size
+; xor eax,eax ; timeout value (0: no timeout)
+ mov eax,100 ; timeout value (0: no timeout)
+
+ call far [gfx_bc_input]
+ ret
+
+gfx_l2so:
+ push eax
+ mov eax,[esp + 6]
+ shr eax,4
+ mov [esp + 8],ax
+ and word [esp + 6],byte 0fh
+ pop eax
+ ret
+
+parse_config:
+ mov [f_handle],si
+ push es
+ mov ax,cs
+ add ax,1000h
+ mov es,ax
+ mov word [menu_seg],ax
+ xor eax,eax
+ mov cx,4000h
+ mov di,0
+ rep stosd
+ pop es
+.read:
+ call skipspace
+ jz .eof
+ jc .read
+ cmp al,'#'
+ je .nextline
+ or al,20h ; convert to lower case
+ mov di,configbuf
+ stosb
+.read_loop:
+ call getc
+ jc .eof
+ cmp al,' '
+ jbe .done
+ or al,20h ; convert to lower case
+ stosb
+ jmp .read_loop
+.done:
+ call ungetc
+
+ xor ax,ax
+ stosb
+%ifdef DEBUG
+ mov ax,2
+ mov bx, configbuf
+ int 22h
+
+ mov ax,2
+ mov bx, msg_crlf
+ int 22h
+%endif
+ push si
+ push di
+ xor ecx,ecx
+ mov si,configbuf
+ mov di,label_keyword+1
+ mov cl, byte [label_keyword]
+ call memcmp
+ pop di
+ pop si
+ jz .do_label
+
+ push si
+ push di
+ xor ecx,ecx
+ mov si,configbuf
+ mov di,default_keyword+1
+ mov cl, byte [default_keyword]
+ call memcmp
+ pop di
+ pop si
+ jz .do_default
+
+.nextline:
+ call skipline
+ jmp .read
+
+.do_label:
+ call skipspace
+ jz .eof
+ jc .noparm
+ call ungetc
+ push es
+ push di
+ mov ax,[menu_seg]
+ mov es,ax
+ mov di,[menu_off]
+ call getline
+ mov di,[menu_off]
+ add di,512
+ mov [menu_off],di
+ pop di
+ pop es
+ inc word [label_cnt]
+
+ jmp .read
+
+.do_default:
+ call skipspace
+ jz .eof
+ jc .noparm
+ call ungetc
+ push es
+ push di
+ push cs
+ pop es
+ mov di,dentry_buf
+ call getline
+ pop di
+ pop es
+
+ jmp .read
+
+.eof:
+.noparm:
+ ret
+
+skipline:
+ cmp al,10
+ je .end
+ call getc
+ jc .end
+ jmp skipline
+.end:
+ ret
+
+skipspace:
+.loop:
+ call getc
+ jc .eof
+ cmp al,0Ah
+ je .eoln
+ cmp al,' '
+ jbe .loop
+ ret
+.eof:
+ cmp al,al
+ stc
+ ret
+.eoln:
+ add al,0FFh
+ ret
+
+ungetc:
+ mov byte [ungetc_cnt],1
+ mov byte [ungetcdata],al
+ ret
+
+getc:
+ cmp byte [ungetc_cnt],1
+ jne .noungetc
+ mov byte [ungetc_cnt],0
+ mov al,[ungetcdata]
+ clc
+ ret
+.noungetc:
+ sub word [bufbytes],1
+ jc .get_data
+ mov si,trackbuf
+ add si,[bufdata]
+ mov al,[si]
+ inc word [bufdata]
+ clc
+ ret
+.get_data:
+ mov si,[f_handle]
+ and si,si
+ jz .empty
+ mov ax,7
+ mov bx,trackbuf
+ mov cx,[BufSafe]
+ int 22h
+ mov word [bufdata],0
+ jc .empty
+ mov [f_handle],si
+ mov [bufbytes],cx
+ jmp getc
+.empty:
+ mov word [f_handle],0
+ mov word [bufbytes],0
+ stc
+ ret
+
+getline:
+ call skipspace
+ jz .eof
+ jc .eoln
+ call ungetc
+.loop:
+ call getc
+ jc .ret
+ cmp al,' '
+ jna .ctrl
+.store:
+ stosb
+ jmp .loop
+.ctrl:
+ cmp al,10
+ je .ret
+ mov al,' '
+ jmp .store
+.eoln:
+ clc
+ jmp .ret
+.eof:
+ stc
+.ret:
+ xor al,al
+ stosb
+ ret
+
+
+memcmp:
+ push si
+ push di
+ push ax
+.loop:
+ mov al,[si]
+ mov ah,[di]
+ inc si
+ inc di
+ cmp al,ah
+ loope .loop
+ pop ax
+ pop di
+ pop si
+ ret
+
+ section .data
+derivative_id db 0
+drivenumber db 0
+sectorshift db 0
+sectorsize dw 0
+trackbufsize equ 16384
+trackbuf times trackbufsize db 0
+BufSafe dw 0
+file_length dd 0
+
+bufbytes dw 0
+bufdata dw 0
+configbuf times trackbufsize db 0
+ungetc_cnt db 0
+ungetcdata db 0
+label_keyword db 6,'label',0
+default_keyword db 7,'default',0
+label_cnt dw 0
+
+msg_progname db 'gfxboot: ',0
+msg_config_file db 'Configuration file',0
+msg_missing db 'missing',0
+msg_usage db 'Usage: gfxboot.com <bootlogo>',0dh,0ah,0
+msg_memory db 'Could not detect available memory size',0dh,0ah,0
+msg_bootlogo_toobig db 'bootlogo file too big',0dh,0ah,0
+msg_pxelinux db 'pxelinux is not supported',0dh,0ah,0
+msg_unknown_file_size db 'unknown file size',0dh,0ah,0
+msg_space db ' ',0
+msg_crlf db 0dh,0ah,0
+
+f_handle dw 0
+f_size dd 0
+fname_buf times 64 db 0
+fname_buf_len equ $ - fname_buf
+gfx_slash db '/', 0
+db0 db 0
+max_cmd_len equ 2047
+command_line times max_cmd_len+2 db 0
+dentry_buf times 512 db 0
+dentry_buf_len equ $ - dentry_buf
+
+; menu entry descriptor
+menu_entries equ 0
+menu_default equ 2 ; seg:ofs
+menu_ent_list equ 6 ; seg:ofs
+menu_ent_size equ 10
+menu_arg_list equ 12 ; seg:ofs
+menu_arg_size equ 16
+sizeof_menu_desc equ 18
+
+menu_desc times sizeof_menu_desc db 0
+menu_seg dw 0
+menu_off dw 0
+
+gfx_mem_start_seg dw 0
+gfx_mem_end_seg dw 0
+
+ align 4, db 0
+gfx_mem dd 0 ; linear address
+gfx_save_area1 dd 0 ; 64k
+gfx_save_area1_used db 0 ; != 0 if area1 is in use
+
+; interface to loadable gfx extension (seg:ofs values)
+gfx_bc_jt dd 0
+
+gfx_bc_init dd 0
+gfx_bc_done dd 0
+gfx_bc_input dd 0
+gfx_bc_menu_init dd 0
+
+; system config data (52 bytes)
+gfx_sysconfig equ $
+gfx_bootloader db 1 ; 0: boot loader type (0: lilo, 1: syslinux, 2: grub)
+gfx_sector_shift db 9 ; 1: sector shift
+gfx_media_type db 0 ; 2: media type (0: disk, 1: floppy, 2: cdrom)
+gfx_failsafe db 0 ; 3: turn on failsafe mode (bitmask)
+ ; 0: SHIFT pressed
+ ; 1: skip gfxboot
+ ; 2: skip monitor detection
+gfx_sysconfig_size db gfx_sysconfig_end-gfx_sysconfig ; 4: size of sysconfig data
+gfx_boot_drive db 0 ; 5: BIOS boot drive
+gfx_callback dw gfx_cb ; 6: offset to callback handler
+gfx_bootloader_seg dw 0 ; 8: code/data segment used by bootloader; must follow gfx_callback
+gfx_reserved_1 dw 0 ; 10
+gfx_user_info_0 dd 0 ; 12: data for info box
+gfx_user_info_1 dd 0 ; 16: data for info box
+gfx_bios_mem_size dd 0 ; 20: BIOS memory size (in bytes)
+gfx_xmem_0 dw 0 ; 24: extended mem area 0 (start:size in MB; 12:4 bits)
+gfx_xmem_1 dw 0 ; 26: extended mem area 1
+gfx_xmem_2 dw 0 ; 28: extended mem area 2
+gfx_xmem_3 dw 0 ; 20: extended mem area 3
+gfx_file dd 0 ; 32: start of gfx file
+gfx_archive_start dd 0 ; 36: start of cpio archive
+gfx_archive_end dd 0 ; 40: end of cpio archive
+gfx_mem0_start dd 0 ; 44: low free memory start
+gfx_mem0_end dd 0 ; 48: low free memory end
+gfx_sysconfig_end equ $
diff --git a/version b/version
index 8d748c3a..0d5a39f4 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-3.74 2009
+3.80 2009