Rearrange patches
authorFlorian Fainelli <florian@openwrt.org>
Mon, 10 Sep 2007 14:19:56 +0000 (14:19 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Mon, 10 Sep 2007 14:19:56 +0000 (14:19 +0000)
SVN-Revision: 8729

target/linux/generic-2.6/patches-2.6.22/000-eeprom_93cx6.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/000-git-newsetup.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/001-eeprom_93cx6.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/001-git-newsetup-fixup.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/002-eeprom_93cx6.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/003-eeprom_93cx6.patch [deleted file]
target/linux/generic-2.6/patches-2.6.22/014-x86_newsetup.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.22/015-x86_newsetup_fixup.patch [new file with mode: 0644]
target/linux/generic-2.6/patches-2.6.22/600-eeprom_93cx6.patch [new file with mode: 0644]

diff --git a/target/linux/generic-2.6/patches-2.6.22/000-eeprom_93cx6.patch b/target/linux/generic-2.6/patches-2.6.22/000-eeprom_93cx6.patch
deleted file mode 100644 (file)
index ff23846..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-From: Ivo van Doorn <ivdoorn@gmail.com>
-Date: Fri, 11 May 2007 19:59:40 +0000 (-0400)
-Subject: [PATCH] Add 93cx6 eeprom library
-X-Git-Tag: v2.6.23-rc1~1201^2~74
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9467d64b0e88763914c01f71ddf591b166c4f526
-
-[PATCH] Add 93cx6 eeprom library
-
-This patch adds a library for reading from 93cx6 eeproms.
-
-Signed-off-by: Michael Wu <flamingice@sourmilk.net>
-Signed-off-by: John W. Linville <linville@tuxdriver.com>
----
-
-diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
-index 616eee9..bd601ef 100644
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -34,6 +34,11 @@ config PHANTOM
-         If you choose to build module, its name will be phantom. If unsure,
-         say N here.
-+config EEPROM_93CX6
-+      tristate "EEPROM 93CX6 support"
-+      ---help---
-+        This is a driver for the EEPROM chipsets 93c46 and 93c66.
-+        The driver supports both read as well as write commands.
-         If unsure, say N.
-@@ -187,5 +192,4 @@ config THINKPAD_ACPI_BAY
-         If you are not sure, say Y here.
--
- endmenu
-diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
-index 8abbf2f..b5ce0e3 100644
---- a/drivers/misc/Makefile
-+++ b/drivers/misc/Makefile
-@@ -14,3 +14,4 @@ obj-$(CONFIG_PHANTOM)                += phantom.o
- obj-$(CONFIG_SGI_IOC4)                += ioc4.o
- obj-$(CONFIG_SONY_LAPTOP)     += sony-laptop.o
- obj-$(CONFIG_THINKPAD_ACPI)   += thinkpad_acpi.o
-+obj-$(CONFIG_EEPROM_93CX6)    += eeprom_93cx6.o
-diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
-new file mode 100644
-index 0000000..bfcb434
---- /dev/null
-+++ b/drivers/misc/eeprom_93cx6.c
-@@ -0,0 +1,229 @@
-+/*
-+      Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
-+      <http://rt2x00.serialmonkey.com>
-+
-+      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; either version 2 of the License, or
-+      (at your option) any later version.
-+
-+      This program is distributed in the hope that it will be useful,
-+      but WITHOUT ANY WARRANTY; without even the implied warranty of
-+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+      GNU General Public License for more details.
-+
-+      You should have received a copy of the GNU General Public License
-+      along with this program; if not, write to the
-+      Free Software Foundation, Inc.,
-+      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+/*
-+      Module: eeprom_93cx6
-+      Abstract: EEPROM reader routines for 93cx6 chipsets.
-+      Supported chipsets: 93c46 & 93c66.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/delay.h>
-+#include <linux/eeprom_93cx6.h>
-+
-+MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
-+MODULE_VERSION("1.0");
-+MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
-+MODULE_LICENSE("GPL");
-+
-+static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
-+{
-+      eeprom->reg_data_clock = 1;
-+      eeprom->register_write(eeprom);
-+      udelay(1);
-+}
-+
-+static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
-+{
-+      eeprom->reg_data_clock = 0;
-+      eeprom->register_write(eeprom);
-+      udelay(1);
-+}
-+
-+static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
-+{
-+      /*
-+       * Clear all flags, and enable chip select.
-+       */
-+      eeprom->register_read(eeprom);
-+      eeprom->reg_data_in = 0;
-+      eeprom->reg_data_out = 0;
-+      eeprom->reg_data_clock = 0;
-+      eeprom->reg_chip_select = 1;
-+      eeprom->register_write(eeprom);
-+
-+      /*
-+       * kick a pulse.
-+       */
-+      eeprom_93cx6_pulse_high(eeprom);
-+      eeprom_93cx6_pulse_low(eeprom);
-+}
-+
-+static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
-+{
-+      /*
-+       * Clear chip_select and data_in flags.
-+       */
-+      eeprom->register_read(eeprom);
-+      eeprom->reg_data_in = 0;
-+      eeprom->reg_chip_select = 0;
-+      eeprom->register_write(eeprom);
-+
-+      /*
-+       * kick a pulse.
-+       */
-+      eeprom_93cx6_pulse_high(eeprom);
-+      eeprom_93cx6_pulse_low(eeprom);
-+}
-+
-+static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
-+      const u16 data, const u16 count)
-+{
-+      unsigned int i;
-+
-+      eeprom->register_read(eeprom);
-+
-+      /*
-+       * Clear data flags.
-+       */
-+      eeprom->reg_data_in = 0;
-+      eeprom->reg_data_out = 0;
-+
-+      /*
-+       * Start writing all bits.
-+       */
-+      for (i = count; i > 0; i--) {
-+              /*
-+               * Check if this bit needs to be set.
-+               */
-+              eeprom->reg_data_in = !!(data & (1 << (i - 1)));
-+
-+              /*
-+               * Write the bit to the eeprom register.
-+               */
-+              eeprom->register_write(eeprom);
-+
-+              /*
-+               * Kick a pulse.
-+               */
-+              eeprom_93cx6_pulse_high(eeprom);
-+              eeprom_93cx6_pulse_low(eeprom);
-+      }
-+
-+      eeprom->reg_data_in = 0;
-+      eeprom->register_write(eeprom);
-+}
-+
-+static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
-+      u16 *data, const u16 count)
-+{
-+      unsigned int i;
-+      u16 buf = 0;
-+
-+      eeprom->register_read(eeprom);
-+
-+      /*
-+       * Clear data flags.
-+       */
-+      eeprom->reg_data_in = 0;
-+      eeprom->reg_data_out = 0;
-+
-+      /*
-+       * Start reading all bits.
-+       */
-+      for (i = count; i > 0; i--) {
-+              eeprom_93cx6_pulse_high(eeprom);
-+
-+              eeprom->register_read(eeprom);
-+
-+              /*
-+               * Clear data_in flag.
-+               */
-+              eeprom->reg_data_in = 0;
-+
-+              /*
-+               * Read if the bit has been set.
-+               */
-+              if (eeprom->reg_data_out)
-+                      buf |= (1 << (i - 1));
-+
-+              eeprom_93cx6_pulse_low(eeprom);
-+      }
-+
-+      *data = buf;
-+}
-+
-+/**
-+ * eeprom_93cx6_read - Read multiple words from eeprom
-+ * @eeprom: Pointer to eeprom structure
-+ * @word: Word index from where we should start reading
-+ * @data: target pointer where the information will have to be stored
-+ *
-+ * This function will read the eeprom data as host-endian word
-+ * into the given data pointer.
-+ */
-+void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
-+      u16 *data)
-+{
-+      u16 command;
-+
-+      /*
-+       * Initialize the eeprom register
-+       */
-+      eeprom_93cx6_startup(eeprom);
-+
-+      /*
-+       * Select the read opcode and the word to be read.
-+       */
-+      command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
-+      eeprom_93cx6_write_bits(eeprom, command,
-+              PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
-+
-+      /*
-+       * Read the requested 16 bits.
-+       */
-+      eeprom_93cx6_read_bits(eeprom, data, 16);
-+
-+      /*
-+       * Cleanup eeprom register.
-+       */
-+      eeprom_93cx6_cleanup(eeprom);
-+}
-+EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
-+
-+/**
-+ * eeprom_93cx6_multiread - Read multiple words from eeprom
-+ * @eeprom: Pointer to eeprom structure
-+ * @word: Word index from where we should start reading
-+ * @data: target pointer where the information will have to be stored
-+ * @words: Number of words that should be read.
-+ *
-+ * This function will read all requested words from the eeprom,
-+ * this is done by calling eeprom_93cx6_read() multiple times.
-+ * But with the additional change that while the eeprom_93cx6_read
-+ * will return host ordered bytes, this method will return little
-+ * endian words.
-+ */
-+void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
-+      __le16 *data, const u16 words)
-+{
-+      unsigned int i;
-+      u16 tmp;
-+
-+      for (i = 0; i < words; i++) {
-+              tmp = 0;
-+              eeprom_93cx6_read(eeprom, word + i, &tmp);
-+              data[i] = cpu_to_le16(tmp);
-+      }
-+}
-+EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
-+
-diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
-new file mode 100644
-index 0000000..d774b77
---- /dev/null
-+++ b/include/linux/eeprom_93cx6.h
-@@ -0,0 +1,72 @@
-+/*
-+      Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
-+      <http://rt2x00.serialmonkey.com>
-+
-+      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; either version 2 of the License, or
-+      (at your option) any later version.
-+
-+      This program is distributed in the hope that it will be useful,
-+      but WITHOUT ANY WARRANTY; without even the implied warranty of
-+      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+      GNU General Public License for more details.
-+
-+      You should have received a copy of the GNU General Public License
-+      along with this program; if not, write to the
-+      Free Software Foundation, Inc.,
-+      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ */
-+
-+/*
-+      Module: eeprom_93cx6
-+      Abstract: EEPROM reader datastructures for 93cx6 chipsets.
-+      Supported chipsets: 93c46 & 93c66.
-+ */
-+
-+/*
-+ * EEPROM operation defines.
-+ */
-+#define PCI_EEPROM_WIDTH_93C46        6
-+#define PCI_EEPROM_WIDTH_93C66        8
-+#define PCI_EEPROM_WIDTH_OPCODE       3
-+#define PCI_EEPROM_WRITE_OPCODE       0x05
-+#define PCI_EEPROM_READ_OPCODE        0x06
-+#define PCI_EEPROM_EWDS_OPCODE        0x10
-+#define PCI_EEPROM_EWEN_OPCODE        0x13
-+
-+/**
-+ * struct eeprom_93cx6 - control structure for setting the commands
-+ * for reading the eeprom data.
-+ * @data: private pointer for the driver.
-+ * @register_read(struct eeprom_93cx6 *eeprom): handler to
-+ * read the eeprom register, this function should set all reg_* fields.
-+ * @register_write(struct eeprom_93cx6 *eeprom): handler to
-+ * write to the eeprom register by using all reg_* fields.
-+ * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
-+ * @reg_data_in: register field to indicate data input
-+ * @reg_data_out: register field to indicate data output
-+ * @reg_data_clock: register field to set the data clock
-+ * @reg_chip_select: register field to set the chip select
-+ *
-+ * This structure is used for the communication between the driver
-+ * and the eeprom_93cx6 handlers for reading the eeprom.
-+ */
-+struct eeprom_93cx6 {
-+      void *data;
-+
-+      void (*register_read)(struct eeprom_93cx6 *eeprom);
-+      void (*register_write)(struct eeprom_93cx6 *eeprom);
-+
-+      int width;
-+
-+      char reg_data_in;
-+      char reg_data_out;
-+      char reg_data_clock;
-+      char reg_chip_select;
-+};
-+
-+extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
-+      const u8 word, u16 *data);
-+extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
-+      const u8 word, __le16 *data, const u16 words);
diff --git a/target/linux/generic-2.6/patches-2.6.22/000-git-newsetup.patch b/target/linux/generic-2.6/patches-2.6.22/000-git-newsetup.patch
deleted file mode 100644 (file)
index d73691f..0000000
+++ /dev/null
@@ -1,11942 +0,0 @@
-GIT 1783e2f0f21444020e3dee1be46b1e34af0ea3e7 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-newsetup.git
-
-commit 1783e2f0f21444020e3dee1be46b1e34af0ea3e7
-Author: Venki Pallipadi <venkatesh.pallipadi@intel.com>
-Date:   Wed Jun 20 14:12:39 2007 -0700
-
-    Use a new CPU feature word to cover all Intel features that are spread around
-    
-    in different CPUID leafs like 0x5, 0x6 and 0xA. Make this
-    feature detection code common across i386 and x86_64.
-    
-    Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
-    will be enabled automatically by current acpi-cpufreq driver.
-    
-    Refer to Intel Software Developer's Manual for more details about the feature.
-    
-    Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
-    scattered features data-driven.
-    
-    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit cd19eb67cd6636a4e5c9df99631422c7c7286f59
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed Jun 20 14:33:17 2007 -0700
-
-    x86 setup: move __bss_start into the .bss segment
-    
-    Move __bss_start into the .bss segment, and create __bss_end.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 100327ad6b609cd28970219be57d293847d1261d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed Jun 6 22:07:01 2007 -0700
-
-    x86 setup: remove TSC as a required feature
-    
-    Remove TSC as a required feature, in anticipation of CONFIG_X86_TSC
-    removal.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7c91a172b8af7d4ba087f1f88ed5b155ed459ca3
-Author: Antonino A. Daplas <adaplas@gmail.com>
-Date:   Tue Jun 5 19:21:05 2007 +0800
-
-    i386: Set 6-bit DAC channel properties in vesa video setup
-    
-    If the video BIOS is not capable of switching or failed to switch the
-    hardware to 8-bit DAC, the channel properties are not set.  This leads
-    to a blank (all black) display with vesafb at 8 bpp. Fix by defaulting
-    to a 6-bit DAC.
-    
-    Signed-off-by: Antonino Daplas <adaplas@gmail.com>
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 6eac2d442de8d87eac94a4ca8600bd87219fa06b
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue Jun 5 16:19:36 2007 -0700
-
-    x86 setup: arch/i386/boot/cpucheck.c whitespace cleanup
-    
-    Remove stealth whitespace
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit f7d89f05a30433034a1b4651143afdbb2a8a9c92
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 24 16:56:44 2007 -0700
-
-    hd.c: remove BIOS/CMOS queries
-    
-    An ST-506 disk these days is pretty much someone trying to pull ancient
-    data using an auxilliary controller.  Pulling data from the BIOS or CMOS
-    is just plain wrong, since it's likely to be the primary OS disk... and
-    would be user-entered data anyway.  Instead, require the user enters it
-    on the command line.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 14c2fdb3bbfd6a9a774980e446c2443150749891
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 24 15:25:10 2007 -0700
-
-    x86: add back pbe bit to visible CPUID flags
-    
-    Add pbe back to the visible CPUID flags.  We *do* correctly filter abuses
-    of this bit for 3DNow! in all the appropriate paths.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e071b068a3b9f318be314f0378e655e2eb50ac89
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 23 14:52:34 2007 -0700
-
-    x86 setup: VIA feature mask MSR doesn't just apply to model <= 9
-    
-    The VIA feature mask MSR is known to be present on model 10, and it
-    seems likely it will continue to be supported.  Since we only touch the
-    MSR if we're about to print an error message anyway, go ahead and be
-    aggressive.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit abe0c5aa1827932cda9c754a3842ec22b278d704
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 22 17:17:41 2007 -0700
-
-    x86 setup: correct inline assembly constraints in edd.c
-    
-    Fix the inline assembly constraints in edd.c.  In particular, "driveno"
-    was getting clobbered on some (buggy?) BIOSes.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit c2e5887ad275aab90673a3e33344f09946159cf7
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 18 10:02:55 2007 -0700
-
-    x86 setup: force the assembler to generate a 2-byte jump in header
-    
-    The jump instruction in the header only has two bytes available, so
-    it *better* be a 2-byte jump!  Unfortunately, the assembler will
-    always generate a 3/5-byte jump when the target is in a different
-    section.  Deal with that by generating the jump instruction
-    explicitly from .byte's, just like we do elsewhere when we need a
-    specific binary representation of a certain instruction.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit ce82e3b93eba48b6852822a03efa73c74e165d4f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 17 15:44:48 2007 -0700
-
-    x86 setup: move the symbol start_of_setup into the proper section.
-    
-    start_of_setup is the beginning of the executable code and should be
-    located in the appropriate section.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e5f3a529457a5bfaf8f8783fb86013221279a81c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 17 15:43:19 2007 -0700
-
-    x86 setup: add an ASSERT that the header ends up in the right place
-    
-    Just in case we have funnies involving the linker or people putting
-    inappropriate align statements, make the linker abort if the setup
-    header ends up in the wrong place.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit d9dbde725687ab99d1f529f49f14d1e280cc5cac
-Author: Alexander van Heukelum <heukelum@mailshack.com>
-Date:   Thu May 17 20:54:25 2007 +0200
-
-    x86 new setup: use appropriate sections for code and data
-    
-    An intermediate elf file is generated for the 16-bit setup code.
-    The generated code can be viewed using objdump -m i8086 -d. As it
-    stands, it also tries to disassemble the bugger_off_msg, which
-    results in garbage. This introduces two new sections to separate
-    the code and the data part of the bootsector stub. It also moves
-    some code from the .header section (a data section) to .inittext.
-    
-    Signed-off-by: Alexander van Heukelum <heukelum@mailshack.com>
-
-commit 0d7558a81cf61e9fd2332a54897c5fd18df0d7f2
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 22:03:16 2007 -0700
-
-    x86 setup: use -include code16gcc.h instead of explicit #include
-    
-    Use -include in the Makefile instead of #include to include code16gcc.h.
-    This really is more of a compiler switch than anything else, and is a lot
-    cleaner to do implicitly.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 017ce54e8a4a9628a76d6b510c7309a7e4e111a8
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 18:48:06 2007 -0700
-
-    x86 setup: enable features on Centaur (VIA) and Transmeta processors
-    
-    AMD are not the only ones who sometimes mask features which the kernel
-    may very well depend on.  VIA and Transmeta do, too.  Add code to enable
-    these features during checking.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit b794f5f9c5089709f3df38c6d91869fa38a9c1a4
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 16:37:47 2007 -0700
-
-    x86 setup: in older versions of ld, ASSERT() is an expression
-    
-    Older versions of ld (pre-2.15 or so) need:
-    
-       . = ASSERT(foo, "msg");
-    
-    instead of:
-    
-       ASSERT(foo, "msg")
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 21c2b7c99c417d07015ee8e516a634ec3d98c4ee
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 10:52:41 2007 -0700
-
-    x86 setup: print a warning message if the bootloader gave us no heap.
-    
-    If the bootloader is so old it doesn't set the CAN_USE_HEAP flag,
-    a lot of functionality will by necessity be disabled, so print a
-    warning message.  This means either a 2.00 protocol bootloader or
-    a buggy bootloader; the Qemu bootloader falls in this category.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 52ca0431390d389a2a2246f02fe652ea84c1ddd8
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 10:51:03 2007 -0700
-
-    x86 setup: rely on a compiled-in default for load high/load low
-    
-    When deciding if we should move the kernel from 0x10000 to 0x1000, as
-    is required for a zImage kernel, rely on a compiled-in default since
-    Qemu unconditionally zeroes the loadflags.  This, of course, is a bug
-    in Qemu, but still...
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 4db77a97793104a32e5fb83e62b943fa144b329d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 16 08:45:37 2007 -0700
-
-    x86 setup: correct assembly constraints.
-    
-    Double use of "d" in an asm() constraints; most gcc versions correctly
-    detect and avoid using it, but some version of gcc runs itself into
-    a brick wall instead.  Fix the one "d" which should have been "a".
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 4fbccbc1457d6710d3a9ce55ad70ec6cb0b75fc5
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 15 09:16:29 2007 -0700
-
-    x86 setup: include <asm/msr-index.h> not <asm/msr.h>
-    
-    <asm/msr.h> brings in the accessor functions, which may potentially
-    bring in all other kinds of kernel headers which are inappropriate for
-    the setup code.  For the setup code, include <asm/msr-index.h>
-    instead, which only includes the numeric constants.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 839cafa9c0020e7506722dd2a4fd82a71c2939cc
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 14 15:49:01 2007 -0700
-
-    x86 setup: protocol 2.0[01]: base for CL_OFFSET depends on setup_move_size
-    
-    Handle the use of boot protocol 2.00 and 2.01: the base segment for
-    CL_OFFSET depends on the value of setup_move_size.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit d60357ad68a694b03e9b952eadba5ac277c31df0
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 12 12:18:53 2007 -0700
-
-    x86 setup: remove unused variable
-    
-    Remove unused variable
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e21a2030b01081612259847321bcce13eae1e883
-Author: Sam Ravnborg <sam@ravnborg.org>
-Date:   Sat May 12 12:17:30 2007 -0700
-
-    x86 setup: share i386 Makefile with x86_64
-    
-    The boot Makefile for i386 and x86_64 are equal
-    except for the CFLAGS setting.
-    Teach x86_64 to use the Makefile from i386 and
-    make CFLAGS setting arch dependent in i386 Makefile.
-    
-    Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8618d92339d0d106045f98f34833d863c3235cdb
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 12 00:32:12 2007 -0700
-
-    x86 setup: video-bios.c missed the pointer to the set_mode method!
-    
-    We need the actual pointer to the set_mode method (oops!)
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 85dfc374ea9aad33b9e0315f07a4b2722dc11e3e
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 12 00:14:43 2007 -0700
-
-    x86 setup: when setting unknown BIOS modes and failing, try to revert
-    
-    If we set an unknown BIOS mode and fail, then explicitly try to revert
-    to the original mode.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit f4f7949f126d2f152b09fa9367b1ec693f2ea818
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 11 11:20:59 2007 -0700
-
-    x86 setup: fix typo "video_bios" should be "video-bios"
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 51ba7113ea5b07189b7f8a0534d400a072535197
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 11 11:09:55 2007 -0700
-
-    x86 setup: allow setting VESA modes "blind"
-    
-    Apparently, people really do set VESA modes "blind".  As a result, make
-    the framework for settting blind modes more general, to remove some
-    special cases.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 1b8f73d9b2bf7630a2914ddab606db16fddb509e
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 22:08:45 2007 -0700
-
-    x86_64: CONFIG_PHYSICAL_ALIGN should be 2 MB
-    
-    It's not actually used yet, but set CONFIG_PHYSICAL_ALIGN to 2 MB
-    as it should be, to prevent conflicts with other works in progress.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit b81f3c88923e4470cd0942d4596fafc0fb1cf4fd
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 19:11:32 2007 -0700
-
-    x86 setup: remove debugging statements
-    
-    Remove debugging statements in video.c that were not meant for
-    production.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit be58b6d7e9c14e482bce495e8343955999dea77f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 18:49:40 2007 -0700
-
-    x86 setup: only restore the screen image when needed
-    
-    Only restore the screen image when needed.  This is how the original
-    code behaves, so it's presumably the desired behaviour.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 22f6bd8cc23b512af28e34ae7d40036982a0ac63
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 18:44:08 2007 -0700
-
-    x86 setup: correct the definition of the GDT limit
-    
-    Like all other x86 segment limits, the GDT limit points to the last byte
-    that is *permitted* to access, so it needs to be sizeof(boot_gdt)-1.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7f73f1f4aa4c97745bffe07a3ebcf226a4965b00
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 15:47:48 2007 -0700
-
-    x86 setup: Re-implement scanning for hidden video modes
-    
-    Re-implement scanning for hidden video modes.  Every now and then,
-    apparently, you can find them hidden like easter eggs.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 6770176714bc12ec92372311ac02c14f0d22776e
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 10 15:24:27 2007 -0700
-
-    x86 setup: whitespace cleanup
-    
-    Clean up stealth whitespace.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit ba0480a3537cf471b08bdb99dae6d0780cfb1972
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 9 16:54:42 2007 -0700
-
-    x86: sync the CPU feature string arrays
-    
-    With <asm/cpufeature.h> unified, synchronize the CPU feature string
-    arrays.  The whole kernel/cpu directory really needs to be unified.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit ecb53b84efddbad3d9aa49e95598550831324348
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 8 22:06:04 2007 -0700
-
-    x86 setup: need to set orig_video_isVGA
-    
-    After detecting a VGA console, we need to set
-    boot_params.screen_info.orig_video_isVGA.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit dc97fc053faff17b984ec962686caea52bd27628
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 8 20:51:17 2007 -0700
-
-    x86 setup: boot sector should use ljmp, not jmpl
-    
-    We have an "jmpl" instruction in the boot sector, which was meant
-    to be an "ljmp" instruction.  It worked anyway because gas interpreted
-    a two-argument "jmpl" as an "ljmpl" instruction, however, use plain
-    "ljmp" (i.e. "ljmpw".)
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7907f05e9692557c53c9ac13647db5e5343c7c76
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 8 20:27:10 2007 -0700
-
-    x86 setup: only make VESA graphics modes selectable if CONFIG_FB
-    
-    If we select a VESA graphics mode, we better have framebuffer support
-    or the user will have no console.  Therefore, make these modes
-    non-selectable if CONFIG_FB is not set.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8e509f9ebc44f45544d231454e84f10bf78d5772
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 8 20:24:11 2007 -0700
-
-    x86 setup: need to probe VESA EDID block 0 only
-    
-    The VESA EDID BIOS call takes the EDID block number in %dx, and may
-    corrupt it by spec.  Pass it in properly.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9912b9aed7943773d1fadaa2e2e52f42af395048
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 18:22:04 2007 -0700
-
-    x86 setup: add missing file "bitops.h" missing from previous checkins
-    
-    The file "bitops.h" was missing from previous checkins.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 732eb3fac2d772980e6555b8c69902c8107c72aa
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 14:59:43 2007 -0700
-
-    x86 setup: add -fno-stack-protector; other Makefile fixes
-    
-    Add -fno-stack-protector for the gcc's that need that;
-    Use -ffreestanding consistently;
-    Use $(LINUXINCLUDE);
-    Handle linker scripts consistently with other Makefiles.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 2d5e47f21202e156fe97aba0a88d158d5c157a33
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 14:45:25 2007 -0700
-
-    x86 setup: swap cpu.c and cpucheck.c; rename functions
-    
-    Make cpucheck.c the reusable component; the generically-named cpu.c
-    gets to be the wrapper.  Accordingly, rename functions to make it
-    less confusing.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit bf2a428a4e7c1ee3ab9acb23cfafb45e818887a1
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 14:09:38 2007 -0700
-
-    x86 setup: remove code moved from cpucheck.c -> cpu.c
-    
-    Move all info about requirements into cpu.c.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9ea8429fabe5df6aed6393ac3a00d0b64445ba6a
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 09:42:51 2007 -0700
-
-    x86 setup: remove double nesting of a20_test()
-    
-    a20_test() was invoked as either a20_test() or a20_wait(), where the
-    latter was simply a loop around a loop.  Make the count a parameter
-    instead; this is clearer and saves a couple of bytes.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9edc55718f57195c664ee3175514d652f651cfd2
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 09:30:41 2007 -0700
-
-    x86 setup: compile with -fomit-frame-pointer
-    
-    Compiling with -fomit-frame-pointer reduces the size by about 2%.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e1003433f2d491bf17c79437cd75268da220dab5
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon May 7 09:30:04 2007 -0700
-
-    x86 setup: be more paranoid about the stack setup in header.S
-    
-    In particular, deal correctly with the stack pointer being zero on entry.
-    While we're at it, align the stack.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 853499c3dc3fcbeb192a613ac241d150ebc7c5a0
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sun May 6 23:25:10 2007 -0700
-
-    x86 setup: Factor out the environment-independent part of the CPU check.
-    
-    Factor out the environment-independent part of the CPU check so it can
-    be invoked from other parts of the kernel as well.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit f235a61f6d6dff57883efad351d746540bcb8caf
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 22:16:54 2007 -0700
-
-    x86 setup: when watching the setup size, take the stack into account
-    
-    When watching the setup size, we have to take the stack into account.
-    In particular, the stack is used not only by the setup code itself, but
-    by BIOS interrupt handlers and system calls.  Reserve a minimum of
-    512 bytes.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 0d0e10091be48f7e4c8888e9d5c2836c704994f5
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 19:25:51 2007 -0700
-
-    x86 setup: actually check the end of the heap.
-    
-    Keep track of where the heap ends and actually watch out for it.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 47aab0b8f4d012fad3c42b5b0754d3cb87961b37
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 15:47:58 2007 -0700
-
-    x86 setup: coppyright rPath, Inc.
-    
-    This work was done on the dime of rPath, Inc.; they own the copyright.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit d22571534d7eabf9408f29d9da423e1c6e04445f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 15:21:11 2007 -0700
-
-    x86 setup: implement screen contents save/restore
-    
-    The old setup code had screen contents save and restore, so implement
-    it for the new one as well.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e5145601a752bd998e783d159c187d3017d45d6d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 15:20:19 2007 -0700
-
-    x86 setup: whitespace cleanup
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 045ecb52f91a74eecad93ffc8791eefe59cf7fd1
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 14:22:39 2007 -0700
-
-    x86 setup: allow setting of VESA graphics modes; cleanups
-    
-    - Allow setting of VESA graphics modes (used by vesafb)
-    - Clean up the macros related to the heap
-    - #if 0 copy functions that aren't actually currently being used
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 58c04ed7e2d7d5979e1917a74b49bdc0f3dde211
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 12:06:14 2007 -0700
-
-    x86 setup: move all VESA-related code into video-vesa.c; add EDID
-    
-    - Move all VESA-related code into video-vesa.c
-    - Add VESA EDID query support
-    - Remove some totally obsolete definitions from video.h
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 07bc3931175fb98256140275c03194426d441b74
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Sat May 5 12:04:40 2007 -0700
-
-    x86-64: remove -traditional from AFLAGS
-    
-    In arch/x86_64/boot/compressed, remove -traditional from AFLAGS.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a830f615eeef838d461cbf7bbbee8c1c84708ec8
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 18:44:38 2007 -0700
-
-    x86 setup: share code between i386 and x86-64
-    
-    Share the boot (setup) code and tools between i386 and x86-64.
-    The compression code is now running in 64-bit mode in order to support
-    relocation, so do *not* share that code.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 3e159a323bdfa5d5a7be2c1f6be089ca22d598e0
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 18:43:35 2007 -0700
-
-    x86-64: use 0x1b4 as the scratch area in boot_params, not 0x3c
-    
-    Use 0x1b4 as the scratch area in boot_params rather than 0x3c.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 4cf4424e7a0f29f251b781f9b5e3655b0645cb7f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 18:26:18 2007 -0700
-
-    Revert "x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot"
-    
-    This reverts commit b2ad90f4969226fe8cf3edc5330711ed5fc20105.
-    
-    Restore arch/x86_64/boot as a separate directory hierarchy.
-    
-    Conflicts:
-
-commit 8ed1ae1d2f94410811b7cca4b1a426e37652457f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 17:00:33 2007 -0700
-
-    x86-64: It appears MTRR isn't a required feature after all.
-    
-    MTRR was documented as a required feature, but appears to boot fine
-    without it (tested since Bochs doesn't have MTRR support.)
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7c616d098579fb790662cdc703f2a0f26ea1668c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 16:22:57 2007 -0700
-
-    x86 setup: use 0x1e4 as scratch, instead of 0x3c
-    
-    The compressed relocation needs a 4-byte scratch area to obtain
-    its own address.
-    
-    0x3c is at the end of the video area, which is quite constrained -- it
-    only has 6 bytes left (12 if we recycle the obsolete fields which invade
-    this space.)  Define 0x1e4 as a scratch field, and use it.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 5bc1019227e94576e4876d05ee920f59195bce90
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 16:09:15 2007 -0700
-
-    x86 setup: boot_params.e820_map is just the map, not the count; adjust
-    
-    boot_params.e820_map is just a list of entries, whereas
-    "struct e820map" contains a count as well.  Thus, don't use
-    "struct e820map" to describe struct boot_params.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 0f96b52497f444be2d52d1184ca90be49f713ea3
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 15:49:03 2007 -0700
-
-    x86 setup: E820MAX is a definitional constant; no need to use sizeof hacks
-    
-    Now when we're using the standard headers for the setup code, we can use
-    E820MAX instead of playing sizeof games.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 3a23a428b20cbb31fd7ff5516a053b99afc447f7
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 12:08:46 2007 -0700
-
-    x86: move the bootparam structure definition into include/
-    
-    Move the bootparam structure definition into include/, and make other
-    things use it.  Haven't cleaned up all the macros yet, though.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e93ec58911995971aa059990f8a91a02b05f6c8f
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 12:07:50 2007 -0700
-
-    i386: change %lu to %u in arch/i386/kernel/e820.h
-    
-    It's an u32, print it with %u
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 2f47f004f614e2744867c0df274c55d8af2a42d5
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 12:06:04 2007 -0700
-
-    x86: fix differences between i386 and x86-64 <asm/e820.h>
-    
-    Fix minor differences between i386 and x86-64 <asm/e820.h>
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 56ec52f14e948f430af941052adee98019a617b7
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 11:45:17 2007 -0700
-
-    x86: fix the definition of struct screen_info
-    
-    Name the fields that aren't really struct screen_info, and declare
-    the structure packed (the "capabilities" field is misaligned.)
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 1d4429eaa564b0085d9ee3aa2de57e87a093a14e
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 11:43:10 2007 -0700
-
-    x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot
-    
-    Until such time that Kbuild allows for a cleaner solution, make
-    arch/x86-64/boot a symlink to arch/i386/boot.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 6a85f1b5fd041ea99d8604782559ce0502a60cc0
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:42:06 2007 -0700
-
-    x86-64: rearrange includes due to unifications and inclusion from setup
-    
-    Unification caused a circular dependency between <asm/alternative.h>
-    and <asm/cpufeature.h>; resolve this.
-    
-    Add #ifndef _SETUP in <asm/e820.h> so it can be included from the boot
-    code.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit f6bbdc254bdbd5f7cf7a40c4cd6f9844af90824a
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:40:26 2007 -0700
-
-    x86: Complete <asm/cpufeature.h> with the union of i386 and x86-64
-    
-    Add a feature to <asm/cpufeature.h> which was previously present
-    in x86-64 but missing in i386.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 1a0819281060489901732914f67869e0aa8f26fd
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:39:32 2007 -0700
-
-    x86: unify <asm/boot.h>
-    
-    Unify <asm/boot.h> between i386 and x86-64
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8d9c54585f4623e0310f970fb5c6eda7ec1614df
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:38:35 2007 -0700
-
-    x86-64: verify_cpu.S: use new masks
-    
-    Use the <asm/required-features.h> masks.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 6cf3308646bb7a3210f0f76bcb895b2dea76a93c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:37:26 2007 -0700
-
-    x86-64: fix compilation errors due to required-features.h change
-    
-    Fix compilation errors induced by required-features.h change.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 1324201a93ce380b46a3128826ecbd794e617e59
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:35:37 2007 -0700
-
-    x86-64: <asm/segment.h>: add boot segment descriptors
-    
-    Add boot segment descriptors to <asm/segment.h> to match i386.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a0b15a9e79ed0310813709cd0690d6838917fe82
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:34:37 2007 -0700
-
-    x86-64: add CONFIG_PHYSICAL_ALIGN to match i386
-    
-    Add CONFIG_PHYSICAL_ALIGN to match i386, even though we don't use it.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8f5d14d11a7318e257351ae477392c7f7e314602
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 10:33:54 2007 -0700
-
-    x86 setup: cleanups for compatibility with x86-64
-    
-    These changes are necessary to compile on x86-64.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a32f68b6d4023c1c6b1e62e8561189516c571ab9
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Fri May 4 08:40:07 2007 -0700
-
-    x86 setup: add missing linker script
-    
-    Add linker script for the setup code, apparently missing from previous
-    checkins.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 4f34ca8e926b2d0bf3a7502b99f8dfced8cdba9d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 17:42:29 2007 -0700
-
-    x86 setup: paranoia: clear the high half of %esp
-    
-    We're invoked in 16-bit mode from an unknown bootloader.  Make sure
-    we explicitly zero the upper half of %esp to avoid nasty surprises.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 19eb9b73cc1632a923003a002108b242af7a6080
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 17:35:41 2007 -0700
-
-    x86 setup: bootlin is *so* dead...
-    
-    Bootlin was never able to load bzImage kernels, so who cares about it.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 3b9fb73c65151ee043bc74c333d9e3c9b1872125
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 10:56:40 2007 -0700
-
-    x86 setup: apparently $(src) is insufficient, needs $(srctree)/$(src)
-    
-    For some unfanthomable reason the location of the source tree that
-    corresponds to the current directory has to be written as
-    $(srctree)/$(src) apparently.  There might be a good reason for it,
-    but shorthand would be appreciated, and $(src) really should be the
-    short form.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a6d01d375a2269be1e3a6b31bcc4d426ad5a473d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 10:51:45 2007 -0700
-
-    x86 setup: remove reference to obsolete cpureq.c
-    
-    cpureq.c has been removed; remove it from the Makefile too.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit cbe5b7585d800435080bcbf1b1fd242926982674
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 10:33:12 2007 -0700
-
-    x86 setup: use the required masks from <asm/required-features.h>
-    
-    Use the now-uniform features from <asm/required-features.h>.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 99ed30180ecc1bb4e93f6edda5f6bad1adf3e630
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 10:31:12 2007 -0700
-
-    x86: make the handling of required features consistent
-    
-    Make the handling of required features consistent between i386
-    and x86-64.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 1120d70a2be8f2deb6bda64047da288d8f86dad3
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 00:09:53 2007 -0700
-
-    x86: Kconfig.cpu: the minimum CPU model is always 3; WP_WORKS_OK = i486
-    
-    The minimum CPU model number is always 3 (i386), and if we have
-    WP_WORKS_OK it means we need an i486.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit ebc308c204149b86984ae2216f5b9b2e63932028
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Thu May 3 00:08:48 2007 -0700
-
-    x86 setup: use CONFIG_X86_MINIMUM_CPU_MODEL
-    
-    Use CONFIG_X86_MINIMUM_CPU_MODEL as defined in Kconfig.cpu.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8b50b640e015bf5d0f65502437da6fcab46c391b
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 23:45:42 2007 -0700
-
-    x86 setup: remove bogus "static"
-    
-    Remove invalid "static" declarations in cpu.c
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 35d23b60dfb110da81c24bcbfcda089cfc4fd264
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 23:37:50 2007 -0700
-
-    x86 setup: cpu detection cleanups
-    
-    - Use <asm/processor-flags.h>
-    - Make sure %cr0 isn't in a dangerous configuration before probing the FPU
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a1150a03247b355d11a4bb696b8aae1f46612992
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 23:36:55 2007 -0700
-
-    x86 setup: compile with -DSETUP
-    
-    Define SETUP to make it easier to share code with the rest of the kernel.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7eb52e8ad1bdf01886023d1a13b3313084cd7db6
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 23:34:57 2007 -0700
-
-    x86 setup: remove unused verify_cpu.S
-    
-    verify_cpu.S is obsoleted by boot/cpu.c.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit e90317a027c30176968220d18eb18bd6a9d9cc74
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 20:07:43 2007 -0700
-
-    x86 setup: files missing from previous checkin (cpu.c, cpureq.c)
-    
-    These files were missing from a previous checkin; CPU feature-checking
-    code and the list of CPU features to check for.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 060f9b3db33c67b5344b2b4110bc823eb776e5cd
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 19:51:34 2007 -0700
-
-    x86 setup: whitespace cleanup
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9f997a5569ec8fceaa15c2e9cf28e728e2ce118d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 19:07:14 2007 -0700
-
-    x86 setup: add CPU feature detect/abort on insufficient featurage
-    
-    The x86 setup is the right place to check features and abort if they
-    are not present, since we can still get a message to the user via the
-    firmware.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit de4e976376fddec340651ef40b16a45f6189619d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 19:05:34 2007 -0700
-
-    x86 setup: whitespace cleanup
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit bcd2d2f8de5d4568b6628aa133fce1ac40ece526
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 16:19:59 2007 -0700
-
-    x86 setup: tag functions noreturn; error message on A20 failure
-    
-    Tag appropriate functions noreturn.
-    If the A20 gate fails, output an error message and refuse to boot.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 752aef90cbfc888084bf11fd83f8f72b6a668fc9
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 15:45:08 2007 -0700
-
-    x86 setup: clobber registers in keyboard BIOS call
-    
-    Keyboard BIOS call to set repeat rate is known to clobber registers on
-    "many" BIOSes.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit dde94003e4759aab275732cf9f1834440cd381d0
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 15:44:21 2007 -0700
-
-    x86 setup: implement APM BIOS probe
-    
-    APM BIOS probe ported from assembly
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9403917d79e3349184318704476fa080836bd52c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 15:17:14 2007 -0700
-
-    x86 setup: remove references to obsolete probes
-    
-    Remove "Hello, World!" as well as references to probes which are no
-    longer used...
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 712f65ffbd1d4b55b4c55d68b4dcd32406c28fb8
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 12:17:15 2007 -0700
-
-    x86 setup: video.c: correct the handling of special mode numbers
-    
-    Special mode numbers with the high bit set need to be handled *before*
-    masking out the high bit.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 9cf083204fe14cda3b09840eba8d131d2e48ccdf
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:44:16 2007 -0700
-
-    x86 setup: Modern ATI cards pass the probe but lacks the modes.
-    
-    It appears modern ATI cards pass the probe for ATI-ness but lack the
-    modes.  Kill off the driver as being incorrect.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 890cbe950589e30af17eac9da800efc76e35e01d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:32:21 2007 -0700
-
-    x86 setup: a20.c: make empty_8042() return status
-    
-    Make functions which could reasonably return status do so.  It may
-    be relevant in the future, and it's a lot better if the programmer
-    doesn't have to figure out where everything should hook in.
-    
-    Just on principle.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 08a44dc655e0086d23fc3c70cb93eb51eaeec259
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:31:03 2007 -0700
-
-    x86 setup: video.c: clean up unused stuff
-    
-    Clean up unused variables that we have no intent on using, as well
-    as other cruft.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 57e69acff1f577de430cae1523fd49a5d113e885
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:18:13 2007 -0700
-
-    x86 setup: drop video mode range checking
-    
-    Drop video mode range checking.  If someone really has, say, 12x40 mode
-    visible through the BIOS then allow them to select it... odds are low
-    that it will actually conflict with the very sparse allocation we have
-    anyway.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit c0dda0b90f92d43872d55d295630a71cd357cfa6
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:15:53 2007 -0700
-
-    x86 setup: if no specific video mode ID is given, generate one
-    
-    If we don't specify a certain video mode ID in the driver, then
-    generate the 0xRRCC mode ID automatically.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 0db5086e79810e7c5d560006b1c9a7501a02d80c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 11:10:28 2007 -0700
-
-    x86 setup: Sadly, Cirrus removed extended text modes from their BIOS.
-    
-    In the later era of the Cirrus 54xx series, Cirrus removed extended text
-    modes from their BIOS.  Neither Qemu nor Bochs implement them in the BIOS.
-    If we can find a direct-register-poking method of setting them that
-    works in Bochs/Qemu it might be worthwhile to resurrect this; the probing
-    routine *does* work.
-    
-    Of course, the Right Thing[TM] would be to submit such a routine to the
-    Bochs/Qemu BIOS as a VESA text mode.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 41f3fddeeb764687bf3fb0cf77fd858128571d58
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Wed May 2 10:18:07 2007 -0700
-
-    x86 setup: remove assembly implementation of putchar and puts
-    
-    Already unused, remove assembly implementation of putchar and puts.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit dfa94cd86aca2c01d2f5e14b6e7c3e8258276195
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:41:28 2007 -0700
-
-    x86 setup: Call INT 15h AX=E820h properly
-    
-    The calling convention for BIOS call 15:E820 was messed up.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 2487575a36435c0a983febbb4f3751331bd2df7a
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:34:12 2007 -0700
-
-    x86 setup: advance one e820 descriptor at a time...
-    
-    Adding sizeof(foo) to a foo * is not just useless, it's pretty damaging...
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 530d4f4f1732335ae8725c0b8c332a618e63ea1d
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:33:28 2007 -0700
-
-    x86 setup: fix memcmp_[fg]s()
-    
-    Actually return a value from memcmp_[fg]s()...
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 8617cd56ff2e43303147da012b26c9dd46af726e
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:32:47 2007 -0700
-
-    x86 setup: fix missing semicolon in video-ati.c
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 7bbf7fa3e199b9cef4877c5a56128faff8636cc9
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:26:48 2007 -0700
-
-    x86 setup: make the video setup code actually do something...
-    
-    Basic video setup now works (there is still work to be done, however.)
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 45bcd4406e4b812b32d317d9b3b8db2e5f135a3c
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:25:20 2007 -0700
-
-    x86 setup: segment descriptors need to be Present
-    
-    The segment descriptors were missing the Present bit.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a39479d4ccf4dceffb623ad2ec7e2d708c38c637
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:24:32 2007 -0700
-
-    build: setup sectors doesn't include the boot sector
-    
-    The "setup sectors" field doesn't include the old boot sector,
-    even though the two are now one module.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit d8f3d4928ead72e8febe2fcd740d0fee71a61f42
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:23:44 2007 -0700
-
-    x86 setup: in tty.c, actually tell it what character to print
-    
-    putchar() was missing the actual passing of the character code to the
-    BIOS call, with very silly-looking results.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 4f1462ed0377e180484a223e622d62432baa64b7
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Tue May 1 21:22:46 2007 -0700
-
-    x86 setup: printf.c needs code16gcc.h
-    
-    printf.c was missing code16gcc.h, with predictable consequences.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit a5ba7e6df198bd204b0f87fc6e3f68388b9d14c1
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon Apr 30 20:56:42 2007 -0700
-
-    MAINTAINERS: formally take responsibility for the i386 boot code
-    
-    Change MAINTAINERS to formally take responsibility for the i386 boot code.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-
-commit 6c821fc005655a99eff6e86c2e4b13654de94dea
-Author: H. Peter Anvin <hpa@zytor.com>
-Date:   Mon Apr 30 20:54:07 2007 -0700
-
-    x86 setup code rewrite: initial development snapshot
-    
-    Clean up the setup code and rewrite it in C.
-    This is an initial development snapshot, not a working tree.
-    
-    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
-
- MAINTAINERS                                 |    4 
- arch/i386/Kconfig.cpu                       |    4 
- arch/i386/boot/Makefile                     |   45 
- arch/i386/boot/a20.c                        |  161 +
- arch/i386/boot/apm.c                        |   97 
- arch/i386/boot/bitops.h                     |   45 
- arch/i386/boot/boot.h                       |  290 ++
- arch/i386/boot/bootsect.S                   |   98 
- arch/i386/boot/cmdline.c                    |   97 
- arch/i386/boot/code16gcc.h                  |    9 
- arch/i386/boot/compressed/Makefile          |    7 
- arch/i386/boot/compressed/head.S            |    6 
- arch/i386/boot/compressed/misc.c            |    3 
- arch/i386/boot/copy.S                       |  101 
- arch/i386/boot/cpu.c                        |   69 
- arch/i386/boot/cpucheck.c                   |  266 ++
- arch/i386/boot/edd.S                        |  231 --
- arch/i386/boot/edd.c                        |  196 +
- arch/i386/boot/header.S                     |  283 ++
- arch/i386/boot/main.c                       |  161 +
- arch/i386/boot/mca.c                        |   43 
- arch/i386/boot/memory.c                     |   99 
- arch/i386/boot/pm.c                         |  170 +
- arch/i386/boot/pmjump.S                     |   54 
- arch/i386/boot/printf.c                     |  331 ++
- arch/i386/boot/setup.S                      | 1075 ---------
- arch/i386/boot/setup.ld                     |   54 
- arch/i386/boot/string.c                     |   34 
- arch/i386/boot/tools/build.c                |  156 -
- arch/i386/boot/tty.c                        |  112 
- arch/i386/boot/version.c                    |   23 
- arch/i386/boot/vesa.h                       |   79 
- arch/i386/boot/video-bios.c                 |  125 +
- arch/i386/boot/video-vesa.c                 |  283 ++
- arch/i386/boot/video-vga.c                  |  260 ++
- arch/i386/boot/video.S                      | 2043 ------------------
- arch/i386/boot/video.c                      |  456 ++++
- arch/i386/boot/video.h                      |  145 +
- arch/i386/boot/voyager.c                    |   46 
- arch/i386/kernel/cpu/addon_cpuid_features.c |   50 
- arch/i386/kernel/cpu/common.c               |    2 
- arch/i386/kernel/cpu/proc.c                 |   21 
- arch/i386/kernel/e820.c                     |    2 
- arch/i386/kernel/setup.c                    |   12 
- arch/i386/kernel/verify_cpu.S               |   94 
- arch/x86_64/Kconfig                         |    4 
- arch/x86_64/boot/Makefile                   |  136 -
- arch/x86_64/boot/bootsect.S                 |   98 
- arch/x86_64/boot/compressed/Makefile        |    9 
- arch/x86_64/boot/compressed/head.S          |    6 
- arch/x86_64/boot/install.sh                 |    2 
- arch/x86_64/boot/mtools.conf.in             |   17 
- arch/x86_64/boot/setup.S                    |  826 -------
- arch/x86_64/boot/tools/build.c              |  185 -
- arch/x86_64/kernel/Makefile                 |    2 
- arch/x86_64/kernel/setup.c                  |   21 
- arch/x86_64/kernel/verify_cpu.S             |   22 
- drivers/ide/legacy/hd.c                     |   73 
- include/asm-i386/boot.h                     |    6 
- include/asm-i386/bootparam.h                |   85 
- include/asm-i386/cpufeature.h               |   26 
- include/asm-i386/e820.h                     |   14 
- include/asm-i386/processor.h                |    1 
- include/asm-i386/required-features.h        |   37 
- include/asm-i386/setup.h                    |   10 
- include/asm-x86_64/alternative.h            |   68 
- include/asm-x86_64/boot.h                   |   16 
- include/asm-x86_64/bootparam.h              |    1 
- include/asm-x86_64/cpufeature.h             |  115 -
- include/asm-x86_64/e820.h                   |    6 
- include/asm-x86_64/processor.h              |    3 
- include/asm-x86_64/required-features.h      |   46 
- include/asm-x86_64/segment.h                |    8 
- include/linux/edd.h                         |    4 
- include/linux/screen_info.h                 |    9 
- 75 files changed, 4594 insertions(+), 5204 deletions(-)
-
-diff -puN MAINTAINERS~git-newsetup MAINTAINERS
---- a/MAINTAINERS~git-newsetup
-+++ a/MAINTAINERS
-@@ -1774,8 +1774,8 @@ T:       http://www.harbaum.org/till/i2c_tiny_
- S:    Maintained
- i386 BOOT CODE
--P:    Riley H. Williams
--M:    Riley@Williams.Name
-+P:    H. Peter Anvin
-+M:    hpa@zytor.com
- L:    Linux-Kernel@vger.kernel.org
- S:    Maintained
-diff -puN arch/i386/Kconfig.cpu~git-newsetup arch/i386/Kconfig.cpu
---- a/arch/i386/Kconfig.cpu~git-newsetup
-+++ a/arch/i386/Kconfig.cpu
-@@ -346,6 +346,6 @@ config X86_CMOV
- config X86_MINIMUM_CPU_MODEL
-       int
--      default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
--      default "0"
-+      default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
-+      default "3"
-diff -puN arch/i386/boot/Makefile~git-newsetup arch/i386/boot/Makefile
---- a/arch/i386/boot/Makefile~git-newsetup
-+++ a/arch/i386/boot/Makefile
-@@ -25,27 +25,53 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
- #RAMDISK := -DRAMDISK=512
--targets               := vmlinux.bin bootsect bootsect.o \
--                 setup setup.o zImage bzImage
-+targets               := vmlinux.bin setup.bin setup.elf zImage bzImage
- subdir-       := compressed
-+setup-y               += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
-+setup-y               += header.o main.o mca.o memory.o pm.o pmjump.o
-+setup-y               += printf.o string.o tty.o video.o version.o voyager.o
-+
-+# The link order of the video-*.o modules can matter.  In particular,
-+# video-vga.o *must* be listed first, followed by video-vesa.o.
-+# Hardware-specific drivers should follow in the order they should be
-+# probed, and video-bios.o should typically be last.
-+setup-y               += video-vga.o
-+setup-y               += video-vesa.o
-+setup-y               += video-bios.o
-+
- hostprogs-y   := tools/build
- HOSTCFLAGS_build.o := $(LINUXINCLUDE)
- # ---------------------------------------------------------------------------
-+# How to compile the 16-bit code.  Note we always compile for -march=i386,
-+# that way we can complain to the user if the CPU is insufficient.
-+cflags-i386   := 
-+cflags-x86_64 := -m32
-+CFLAGS                := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
-+                 $(cflags-$(ARCH)) \
-+                 -Wall -Wstrict-prototypes \
-+                 -march=i386 -mregparm=3 \
-+                 -include $(srctree)/$(src)/code16gcc.h \
-+                 -fno-strict-aliasing -fomit-frame-pointer \
-+                 $(call cc-option, -ffreestanding) \
-+                 $(call cc-option, -fno-stack-protector)
-+AFLAGS                := $(CFLAGS) -D__ASSEMBLY__
-+
- $(obj)/zImage:  IMAGE_OFFSET := 0x1000
- $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
- $(obj)/bzImage: IMAGE_OFFSET := 0x100000
-+$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
- $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
- $(obj)/bzImage: BUILDFLAGS   := -b
- quiet_cmd_image = BUILD   $@
--cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
-+cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
-           $(obj)/vmlinux.bin $(ROOT_DEV) > $@
--$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
-+$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
-                             $(obj)/vmlinux.bin $(obj)/tools/build FORCE
-       $(call if_changed,image)
-       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
-@@ -53,12 +79,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/boo
- $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
-       $(call if_changed,objcopy)
--LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
--LDFLAGS_setup  := -Ttext 0x0 -s --oformat binary -e begtext
-+SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
--$(obj)/setup $(obj)/bootsect: %: %.o FORCE
-+LDFLAGS_setup.elf     := -T
-+$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
-       $(call if_changed,ld)
-+OBJCOPYFLAGS_setup.bin        := -O binary
-+
-+$(obj)/setup.bin: $(obj)/setup.elf FORCE
-+      $(call if_changed,objcopy)
-+
- $(obj)/compressed/vmlinux: FORCE
-       $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
-diff -puN /dev/null arch/i386/boot/a20.c
---- /dev/null
-+++ a/arch/i386/boot/a20.c
-@@ -0,0 +1,161 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/a20.c
-+ *
-+ * Enable A20 gate (return -1 on failure)
-+ */
-+
-+#include "boot.h"
-+
-+#define MAX_8042_LOOPS        100000
-+
-+static int empty_8042(void)
-+{
-+      u8 status;
-+      int loops = MAX_8042_LOOPS;
-+
-+      while (loops--) {
-+              io_delay();
-+
-+              status = inb(0x64);
-+              if (status & 1) {
-+                      /* Read and discard input data */
-+                      io_delay();
-+                      (void)inb(0x60);
-+              } else if (!(status & 2)) {
-+                      /* Buffers empty, finished! */
-+                      return 0;
-+              }
-+      }
-+
-+      return -1;
-+}
-+
-+/* Returns nonzero if the A20 line is enabled.  The memory address
-+   used as a test is the int $0x80 vector, which should be safe. */
-+
-+#define A20_TEST_ADDR (4*0x80)
-+#define A20_TEST_SHORT  32
-+#define A20_TEST_LONG 2097152 /* 2^21 */
-+
-+static int a20_test(int loops)
-+{
-+      int ok = 0;
-+      int saved, ctr;
-+
-+      set_fs(0x0000);
-+      set_gs(0xffff);
-+
-+      saved = ctr = rdfs32(A20_TEST_ADDR);
-+
-+      while (loops--) {
-+              wrfs32(++ctr, A20_TEST_ADDR);
-+              io_delay();     /* Serialize and make delay constant */
-+              ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
-+              if (ok)
-+                      break;
-+      }
-+
-+      wrfs32(saved, A20_TEST_ADDR);
-+      return ok;
-+}
-+
-+/* Quick test to see if A20 is already enabled */
-+static int a20_test_short(void)
-+{
-+      return a20_test(A20_TEST_SHORT);
-+}
-+
-+/* Longer test that actually waits for A20 to come on line; this
-+   is useful when dealing with the KBC or other slow external circuitry. */
-+static int a20_test_long(void)
-+{
-+      return a20_test(A20_TEST_LONG);
-+}
-+
-+static void enable_a20_bios(void)
-+{
-+      asm volatile("pushfl; int $0x15; popfl"
-+                   : : "a" ((u16)0x2401));
-+}
-+
-+static void enable_a20_kbc(void)
-+{
-+      empty_8042();
-+
-+      outb(0xd1, 0x64);       /* Command write */
-+      empty_8042();
-+
-+      outb(0xdf, 0x60);       /* A20 on */
-+      empty_8042();
-+}
-+
-+static void enable_a20_fast(void)
-+{
-+      u8 port_a;
-+
-+      port_a = inb(0x92);     /* Configuration port A */
-+      port_a |=  0x02;        /* Enable A20 */
-+      port_a &= ~0x01;        /* Do not reset machine */
-+      outb(port_a, 0x92);
-+}
-+
-+/*
-+ * Actual routine to enable A20; return 0 on ok, -1 on failure
-+ */
-+
-+#define A20_ENABLE_LOOPS 255  /* Number of times to try */
-+
-+int enable_a20(void)
-+{
-+      int loops = A20_ENABLE_LOOPS;
-+
-+#if defined(CONFIG_X86_ELAN)
-+      /* Elan croaks if we try to touch the KBC */
-+      enable_a20_fast();
-+      while (!a20_test_long())
-+              ;
-+      return 0;
-+#elif defined(CONFIG_X86_VOYAGER)
-+      /* On Voyager, a20_test() is unsafe? */
-+      enable_a20_kbc();
-+      return 0;
-+#else
-+      while (loops--) {
-+              /* First, check to see if A20 is already enabled
-+                 (legacy free, etc.) */
-+              if (a20_test_short())
-+                      return 0;
-+
-+              /* Next, try the BIOS (INT 0x15, AX=0x2401) */
-+              enable_a20_bios();
-+              if (a20_test_short())
-+                      return 0;
-+
-+              /* Try enabling A20 through the keyboard controller */
-+              empty_8042();
-+              if (a20_test_short())
-+                      return 0; /* BIOS worked, but with delayed reaction */
-+
-+              enable_a20_kbc();
-+              if (a20_test_long())
-+                      return 0;
-+
-+              /* Finally, try enabling the "fast A20 gate" */
-+              enable_a20_fast();
-+              if (a20_test_long())
-+                      return 0;
-+      }
-+
-+      return -1;
-+#endif
-+}
-diff -puN /dev/null arch/i386/boot/apm.c
---- /dev/null
-+++ a/arch/i386/boot/apm.c
-@@ -0,0 +1,97 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
-+ *   (sfr@canb.auug.org.au)
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/apm.c
-+ *
-+ * Get APM BIOS information
-+ */
-+
-+#include "boot.h"
-+
-+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-+
-+int query_apm_bios(void)
-+{
-+      u16 ax, bx, cx, dx, di;
-+      u32 ebx, esi;
-+      u8 err;
-+
-+      /* APM BIOS installation check */
-+      ax = 0x5300;
-+      bx = cx = 0;
-+      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
-+                   : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
-+                   : : "esi", "edi");
-+
-+      if (err)
-+              return -1;              /* No APM BIOS */
-+
-+      if (bx != 0x504d)       /* "PM" signature */
-+              return -1;
-+
-+      if (cx & 0x02)          /* 32 bits supported? */
-+              return -1;
-+
-+      /* Disconnect first, just in case */
-+      ax = 0x5304;
-+      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
-+                   : "+a" (ax)
-+                   : : "ebx", "ecx", "edx", "esi", "edi");
-+
-+      /* Paranoia */
-+      ebx = esi = 0;
-+      cx = dx = di = 0;
-+
-+      /* 32-bit connect */
-+      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
-+                   : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
-+                     "+S" (esi), "+D" (di), "=m" (err)
-+                   : "a" (0x5303));
-+
-+      boot_params.apm_bios_info.cseg = ax;
-+      boot_params.apm_bios_info.offset = ebx;
-+      boot_params.apm_bios_info.cseg_16 = cx;
-+      boot_params.apm_bios_info.dseg = dx;
-+      boot_params.apm_bios_info.cseg_len = (u16)esi;
-+      boot_params.apm_bios_info.cseg_16_len = esi >> 16;
-+      boot_params.apm_bios_info.dseg_len = di;
-+
-+      if (err)
-+              return -1;
-+
-+      /* Redo the installation check as the 32-bit connect;
-+         some BIOSes return different flags this way... */
-+
-+      ax = 0x5300;
-+      bx = cx = 0;
-+      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
-+                   : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
-+                   : : "esi", "edi");
-+
-+      if (err || bx != 0x504d) {
-+              /* Failure with 32-bit connect, try to disconect and ignore */
-+              ax = 0x5304;
-+              bx = 0;
-+              asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
-+                           : "+a" (ax), "+b" (bx)
-+                           : : "ecx", "edx", "esi", "edi");
-+              return -1;
-+      }
-+
-+      boot_params.apm_bios_info.version = ax;
-+      boot_params.apm_bios_info.flags = cx;
-+      return 0;
-+}
-+
-+#endif
-diff -puN /dev/null arch/i386/boot/bitops.h
---- /dev/null
-+++ a/arch/i386/boot/bitops.h
-@@ -0,0 +1,45 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/bitops.h
-+ *
-+ * Very simple bitops for the boot code.
-+ */
-+
-+#ifndef BOOT_BITOPS_H
-+#define BOOT_BITOPS_H
-+#define _LINUX_BITOPS_H               /* Inhibit inclusion of <linux/bitops.h> */
-+
-+static inline int constant_test_bit(int nr, const void *addr)
-+{
-+      const u32 *p = (const u32 *)addr;
-+      return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
-+}
-+static inline int variable_test_bit(int nr, const void *addr)
-+{
-+      u8 v;
-+      const u32 *p = (const u32 *)addr;
-+
-+      asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
-+      return v;
-+}
-+
-+#define test_bit(nr,addr) \
-+(__builtin_constant_p(nr) ? \
-+ constant_test_bit((nr),(addr)) : \
-+ variable_test_bit((nr),(addr)))
-+
-+static inline void set_bit(int nr, void *addr)
-+{
-+      asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
-+}
-+
-+#endif /* BOOT_BITOPS_H */
-diff -puN /dev/null arch/i386/boot/boot.h
---- /dev/null
-+++ a/arch/i386/boot/boot.h
-@@ -0,0 +1,290 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/boot.h
-+ *
-+ * Header file for the real-mode kernel code
-+ */
-+
-+#ifndef BOOT_BOOT_H
-+#define BOOT_BOOT_H
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <stdarg.h>
-+#include <linux/types.h>
-+#include <linux/edd.h>
-+#include <asm/boot.h>
-+#include <asm/bootparam.h>
-+
-+/* Useful macros */
-+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-+
-+extern struct setup_header hdr;
-+extern struct boot_params boot_params;
-+
-+/* Basic port I/O */
-+static inline void outb(u8 v, u16 port)
-+{
-+      asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
-+}
-+static inline u8 inb(u16 port)
-+{
-+      u8 v;
-+      asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
-+      return v;
-+}
-+
-+static inline void outw(u16 v, u16 port)
-+{
-+      asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
-+}
-+static inline u16 inw(u16 port)
-+{
-+      u16 v;
-+      asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
-+      return v;
-+}
-+
-+static inline void outl(u32 v, u16 port)
-+{
-+      asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
-+}
-+static inline u32 inl(u32 port)
-+{
-+      u32 v;
-+      asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
-+      return v;
-+}
-+
-+static inline void io_delay(void)
-+{
-+      const u16 DELAY_PORT = 0x80;
-+      asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
-+}
-+
-+/* These functions are used to reference data in other segments. */
-+
-+static inline u16 ds(void)
-+{
-+      u16 seg;
-+      asm("movw %%ds,%0" : "=rm" (seg));
-+      return seg;
-+}
-+
-+static inline void set_fs(u16 seg)
-+{
-+      asm volatile("movw %0,%%fs" : : "rm" (seg));
-+}
-+static inline u16 fs(void)
-+{
-+      u16 seg;
-+      asm("movw %%fs,%0" : "=rm" (seg));
-+      return seg;
-+}
-+
-+static inline void set_gs(u16 seg)
-+{
-+      asm volatile("movw %0,%%gs" : : "rm" (seg));
-+}
-+static inline u16 gs(void)
-+{
-+      u16 seg;
-+      asm("movw %%gs,%0" : "=rm" (seg));
-+      return seg;
-+}
-+
-+typedef unsigned int addr_t;
-+
-+static inline u8 rdfs8(addr_t addr)
-+{
-+      u8 v;
-+      asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
-+      return v;
-+}
-+static inline u16 rdfs16(addr_t addr)
-+{
-+      u16 v;
-+      asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
-+      return v;
-+}
-+static inline u32 rdfs32(addr_t addr)
-+{
-+      u32 v;
-+      asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
-+      return v;
-+}
-+
-+static inline void wrfs8(u8 v, addr_t addr)
-+{
-+      asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
-+}
-+static inline void wrfs16(u16 v, addr_t addr)
-+{
-+      asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
-+}
-+static inline void wrfs32(u32 v, addr_t addr)
-+{
-+      asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
-+}
-+
-+static inline u8 rdgs8(addr_t addr)
-+{
-+      u8 v;
-+      asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
-+      return v;
-+}
-+static inline u16 rdgs16(addr_t addr)
-+{
-+      u16 v;
-+      asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
-+      return v;
-+}
-+static inline u32 rdgs32(addr_t addr)
-+{
-+      u32 v;
-+      asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
-+      return v;
-+}
-+
-+static inline void wrgs8(u8 v, addr_t addr)
-+{
-+      asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
-+}
-+static inline void wrgs16(u16 v, addr_t addr)
-+{
-+      asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
-+}
-+static inline void wrgs32(u32 v, addr_t addr)
-+{
-+      asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
-+}
-+
-+/* Note: these only return true/false, not a signed return value! */
-+static inline int memcmp(const void *s1, const void *s2, size_t len)
-+{
-+      u8 diff;
-+      asm("repe; cmpsb; setnz %0"
-+          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
-+      return diff;
-+}
-+
-+static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
-+{
-+      u8 diff;
-+      asm("fs; repe; cmpsb; setnz %0"
-+          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
-+      return diff;
-+}
-+static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
-+{
-+      u8 diff;
-+      asm("gs; repe; cmpsb; setnz %0"
-+          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
-+      return diff;
-+}
-+
-+/* Heap -- available for dynamic lists. */
-+#define STACK_SIZE    512     /* Minimum number of bytes for stack */
-+
-+extern char _end[];
-+extern char *HEAP;
-+extern char *heap_end;
-+#define RESET_HEAP() ((void *)( HEAP = _end ))
-+static inline char *__get_heap(size_t s, size_t a, size_t n)
-+{
-+      char *tmp;
-+
-+      HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
-+      tmp = HEAP;
-+      HEAP += s*n;
-+      return tmp;
-+}
-+#define GET_HEAP(type, n) \
-+      ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
-+
-+static inline int heap_free(void)
-+{
-+      return heap_end-HEAP;
-+}
-+
-+/* copy.S */
-+
-+void copy_to_fs(addr_t dst, void *src, size_t len);
-+void *copy_from_fs(void *dst, addr_t src, size_t len);
-+void copy_to_gs(addr_t dst, void *src, size_t len);
-+void *copy_from_gs(void *dst, addr_t src, size_t len);
-+void *memcpy(void *dst, void *src, size_t len);
-+void *memset(void *dst, int c, size_t len);
-+
-+#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
-+#define memset(d,c,l) __builtin_memset(d,c,l)
-+
-+/* a20.c */
-+int enable_a20(void);
-+
-+/* apm.c */
-+int query_apm_bios(void);
-+
-+/* cmdline.c */
-+int cmdline_find_option(const char *option, char *buffer, int bufsize);
-+
-+/* cpu.c, cpucheck.c */
-+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
-+int validate_cpu(void);
-+
-+/* edd.c */
-+void query_edd(void);
-+
-+/* header.S */
-+void __attribute__((noreturn)) die(void);
-+
-+/* mca.c */
-+int query_mca(void);
-+
-+/* memory.c */
-+int detect_memory(void);
-+
-+/* pm.c */
-+void __attribute__((noreturn)) go_to_protected_mode(void);
-+
-+/* pmjump.S */
-+void __attribute__((noreturn))
-+      protected_mode_jump(u32 entrypoint, u32 bootparams);
-+
-+/* printf.c */
-+unsigned int atou(const char *s);
-+int sprintf(char *buf, const char *fmt, ...);
-+int vsprintf(char *buf, const char *fmt, va_list args);
-+int printf(const char *fmt, ...);
-+
-+/* string.c */
-+int strcmp(const char *str1, const char *str2);
-+
-+/* tty.c */
-+void puts(const char *);
-+void putchar(int);
-+int getchar(void);
-+void kbd_flush(void);
-+int getchar_timeout(void);
-+
-+/* video.c */
-+void set_video(void);
-+
-+/* video-vesa.c */
-+void vesa_store_edid(void);
-+
-+/* voyager.c */
-+int query_voyager(void);
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif /* BOOT_BOOT_H */
-diff -puN arch/i386/boot/bootsect.S~git-newsetup /dev/null
---- a/arch/i386/boot/bootsect.S
-+++ /dev/null
-@@ -1,98 +0,0 @@
--/*
-- *    bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
-- *
-- *    modified by Drew Eckhardt
-- *    modified by Bruce Evans (bde)
-- *    modified by Chris Noe (May 1999) (as86 -> gas)
-- *    gutted by H. Peter Anvin (Jan 2003)
-- *
-- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
-- * addresses must be multiplied by 16 to obtain their respective linear
-- * addresses. To avoid confusion, linear addresses are written using leading
-- * hex while segment addresses are written as segment:offset.
-- *
-- */
--
--#include <asm/boot.h>
--
--SETUPSECTS    = 4                     /* default nr of setup-sectors */
--BOOTSEG               = 0x07C0                /* original address of boot-sector */
--INITSEG               = DEF_INITSEG           /* we move boot here - out of the way */
--SETUPSEG      = DEF_SETUPSEG          /* setup starts here */
--SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
--SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
--                                      /* to be loaded */
--ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
--SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
--
--#ifndef SVGA_MODE
--#define SVGA_MODE ASK_VGA
--#endif
--
--#ifndef RAMDISK
--#define RAMDISK 0
--#endif
--
--#ifndef ROOT_RDONLY
--#define ROOT_RDONLY 1
--#endif
--
--.code16
--.text
--
--.global _start
--_start:
--
--      # Normalize the start address
--      jmpl    $BOOTSEG, $start2
--
--start2:
--      movw    %cs, %ax
--      movw    %ax, %ds
--      movw    %ax, %es
--      movw    %ax, %ss
--      movw    $0x7c00, %sp
--      sti
--      cld
--
--      movw    $bugger_off_msg, %si
--
--msg_loop:
--      lodsb
--      andb    %al, %al
--      jz      die
--      movb    $0xe, %ah
--      movw    $7, %bx
--      int     $0x10
--      jmp     msg_loop
--
--die:
--      # Allow the user to press a key, then reboot
--      xorw    %ax, %ax
--      int     $0x16
--      int     $0x19
--
--      # int 0x19 should never return.  In case it does anyway,
--      # invoke the BIOS reset code...
--      ljmp    $0xf000,$0xfff0
--
--
--bugger_off_msg:
--      .ascii  "Direct booting from floppy is no longer supported.\r\n"
--      .ascii  "Please use a boot loader program instead.\r\n"
--      .ascii  "\n"
--      .ascii  "Remove disk and press any key to reboot . . .\r\n"
--      .byte   0
--
--
--      # Kernel attributes; used by setup
--
--      .org 497
--setup_sects:  .byte SETUPSECTS
--root_flags:   .word ROOT_RDONLY
--syssize:      .word SYSSIZE
--swap_dev:     .word SWAP_DEV
--ram_size:     .word RAMDISK
--vid_mode:     .word SVGA_MODE
--root_dev:     .word ROOT_DEV
--boot_flag:    .word 0xAA55
-diff -puN /dev/null arch/i386/boot/cmdline.c
---- /dev/null
-+++ a/arch/i386/boot/cmdline.c
-@@ -0,0 +1,97 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/cmdline.c
-+ *
-+ * Simple command-line parser for early boot.
-+ */
-+
-+#include "boot.h"
-+
-+static inline int myisspace(u8 c)
-+{
-+      return c <= ' ';        /* Close enough approximation */
-+}
-+
-+/*
-+ * Find a non-boolean option, that is, "option=argument".  In accordance
-+ * with standard Linux practice, if this option is repeated, this returns
-+ * the last instance on the command line.
-+ *
-+ * Returns the length of the argument (regardless of if it was
-+ * truncated to fit in the buffer), or -1 on not found.
-+ */
-+int cmdline_find_option(const char *option, char *buffer, int bufsize)
-+{
-+      u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
-+      addr_t cptr;
-+      char c;
-+      int len = -1;
-+      const char *opptr = NULL;
-+      char *bufptr = buffer;
-+      enum {
-+              st_wordstart,   /* Start of word/after whitespace */
-+              st_wordcmp,     /* Comparing this word */
-+              st_wordskip,    /* Miscompare, skip */
-+              st_bufcpy       /* Copying this to buffer */
-+      } state = st_wordstart;
-+
-+      if (!cmdline_ptr || cmdline_ptr >= 0x100000)
-+              return -1;      /* No command line, or inaccessible */
-+
-+      cptr = cmdline_ptr & 0xf;
-+      set_fs(cmdline_ptr >> 4);
-+
-+      while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
-+              switch (state) {
-+              case st_wordstart:
-+                      if (myisspace(c))
-+                              break;
-+
-+                      /* else */
-+                      state = st_wordcmp;
-+                      opptr = option;
-+                      /* fall through */
-+
-+              case st_wordcmp:
-+                      if (c == '=' && !*opptr) {
-+                              len = 0;
-+                              bufptr = buffer;
-+                              state = st_bufcpy;
-+                      } else if (myisspace(c)) {
-+                              state = st_wordstart;
-+                      } else if (c != *opptr++) {
-+                              state = st_wordskip;
-+                      }
-+                      break;
-+
-+              case st_wordskip:
-+                      if (myisspace(c))
-+                              state = st_wordstart;
-+                      break;
-+
-+              case st_bufcpy:
-+                      if (myisspace(c)) {
-+                              state = st_wordstart;
-+                      } else {
-+                              if (len < bufsize-1)
-+                                      *bufptr++ = c;
-+                              len++;
-+                      }
-+                      break;
-+              }
-+      }
-+
-+      if (bufsize)
-+              *bufptr = '\0';
-+
-+      return len;
-+}
-diff -puN /dev/null arch/i386/boot/code16gcc.h
---- /dev/null
-+++ a/arch/i386/boot/code16gcc.h
-@@ -0,0 +1,9 @@
-+/*
-+ * code16gcc.h
-+ *
-+ * This file is -include'd when compiling 16-bit C code.
-+ */
-+
-+#ifndef __ASSEMBLY__
-+asm(".code16gcc");
-+#endif
-diff -puN arch/i386/boot/compressed/Makefile~git-newsetup arch/i386/boot/compressed/Makefile
---- a/arch/i386/boot/compressed/Makefile~git-newsetup
-+++ a/arch/i386/boot/compressed/Makefile
-@@ -9,9 +9,14 @@ targets               := vmlinux vmlinux.bin vmlinux.
- EXTRA_AFLAGS  := -traditional
- LDFLAGS_vmlinux := -T
--CFLAGS_misc.o += -fPIC
- hostprogs-y   := relocs
-+CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
-+         -fno-strict-aliasing -fPIC \
-+         $(call cc-option,-ffreestanding) \
-+         $(call cc-option,-fno-stack-protector)
-+LDFLAGS := -m elf_i386
-+
- $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
-       $(call if_changed,ld)
-       @:
-diff -puN arch/i386/boot/compressed/head.S~git-newsetup arch/i386/boot/compressed/head.S
---- a/arch/i386/boot/compressed/head.S~git-newsetup
-+++ a/arch/i386/boot/compressed/head.S
-@@ -45,10 +45,10 @@ startup_32:
-  * at and where we were actually loaded at.  This can only be done
-  * with a short local call on x86.  Nothing  else will tell us what
-  * address we are running at.  The reserved chunk of the real-mode
-- * data at 0x34-0x3f are used as the stack for this calculation.
-- * Only 4 bytes are needed.
-+ * data at 0x1e4 (defined as a scratch field) are used as the stack
-+ * for this calculation. Only 4 bytes are needed.
-  */
--      leal 0x40(%esi), %esp
-+      leal (0x1e4+4)(%esi), %esp
-       call 1f
- 1:    popl %ebp
-       subl $1b, %ebp
-diff -puN arch/i386/boot/compressed/misc.c~git-newsetup arch/i386/boot/compressed/misc.c
---- a/arch/i386/boot/compressed/misc.c~git-newsetup
-+++ a/arch/i386/boot/compressed/misc.c
-@@ -11,7 +11,6 @@
- #undef CONFIG_PARAVIRT
- #include <linux/linkage.h>
--#include <linux/vmalloc.h>
- #include <linux/screen_info.h>
- #include <asm/io.h>
- #include <asm/page.h>
-@@ -364,8 +363,10 @@ asmlinkage void decompress_kernel(void *
-       if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
-               error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
-+#ifndef CONFIG_X86_64
-       if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
-               error("Destination address too large");
-+#endif
- #ifndef CONFIG_RELOCATABLE
-       if ((u32)output != LOAD_PHYSICAL_ADDR)
-               error("Wrong destination address");
-diff -puN /dev/null arch/i386/boot/copy.S
---- /dev/null
-+++ a/arch/i386/boot/copy.S
-@@ -0,0 +1,101 @@
-+/* ----------------------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/copy.S
-+ *
-+ * Memory copy routines
-+ */
-+
-+      .code16gcc
-+      .text
-+
-+      .globl  memcpy
-+      .type   memcpy, @function
-+memcpy:
-+      pushw   %si
-+      pushw   %di
-+      movw    %ax, %di
-+      movw    %dx, %si
-+      pushw   %cx
-+      shrw    $2, %cx
-+      rep; movsl
-+      popw    %cx
-+      andw    $3, %cx
-+      rep; movsb
-+      popw    %di
-+      popw    %si
-+      ret
-+      .size   memcpy, .-memcpy
-+
-+      .globl  memset
-+      .type   memset, @function
-+memset:
-+      pushw   %di
-+      movw    %ax, %di
-+      movzbl  %dl, %eax
-+      imull   $0x01010101,%eax
-+      pushw   %cx
-+      shrw    $2, %cx
-+      rep; stosl
-+      popw    %cx
-+      andw    $3, %cx
-+      rep; stosb
-+      popw    %di
-+      ret
-+      .size   memset, .-memset
-+
-+      .globl  copy_from_fs
-+      .type   copy_from_fs, @function
-+copy_from_fs:
-+      pushw   %ds
-+      pushw   %fs
-+      popw    %ds
-+      call    memcpy
-+      popw    %ds
-+      ret
-+      .size   copy_from_fs, .-copy_from_fs
-+
-+      .globl  copy_to_fs
-+      .type   copy_to_fs, @function
-+copy_to_fs:
-+      pushw   %es
-+      pushw   %fs
-+      popw    %es
-+      call    memcpy
-+      popw    %es
-+      ret
-+      .size   copy_to_fs, .-copy_to_fs
-+
-+#if 0 /* Not currently used, but can be enabled as needed */
-+
-+      .globl  copy_from_gs
-+      .type   copy_from_gs, @function
-+copy_from_gs:
-+      pushw   %ds
-+      pushw   %gs
-+      popw    %ds
-+      call    memcpy
-+      popw    %ds
-+      ret
-+      .size   copy_from_gs, .-copy_from_gs
-+      .globl  copy_to_gs
-+
-+      .type   copy_to_gs, @function
-+copy_to_gs:
-+      pushw   %es
-+      pushw   %gs
-+      popw    %es
-+      call    memcpy
-+      popw    %es
-+      ret
-+      .size   copy_to_gs, .-copy_to_gs
-+
-+#endif
-diff -puN /dev/null arch/i386/boot/cpu.c
---- /dev/null
-+++ a/arch/i386/boot/cpu.c
-@@ -0,0 +1,69 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/cpucheck.c
-+ *
-+ * Check for obligatory CPU features and abort if the features are not
-+ * present.
-+ */
-+
-+#include "boot.h"
-+#include "bitops.h"
-+#include <asm/cpufeature.h>
-+
-+static char *cpu_name(int level)
-+{
-+      static char buf[6];
-+
-+      if (level == 64) {
-+              return "x86-64";
-+      } else {
-+              sprintf(buf, "i%d86", level);
-+              return buf;
-+      }
-+}
-+
-+int validate_cpu(void)
-+{
-+      u32 *err_flags;
-+      int cpu_level, req_level;
-+
-+      check_cpu(&cpu_level, &req_level, &err_flags);
-+
-+      if (cpu_level < req_level) {
-+              printf("This kernel requires an %s CPU, ",
-+                     cpu_name(req_level));
-+              printf("but only detected an %s CPU.\n",
-+                     cpu_name(cpu_level));
-+              return -1;
-+      }
-+
-+      if (err_flags) {
-+              int i, j;
-+              puts("This kernel requires the following features "
-+                   "not present on the CPU:\n");
-+
-+              for (i = 0; i < NCAPINTS; i++) {
-+                      u32 e = err_flags[i];
-+
-+                      for (j = 0; j < 32; j++) {
-+                              if (e & 1)
-+                                      printf("%d:%d ", i, j);
-+
-+                              e >>= 1;
-+                      }
-+              }
-+              putchar('\n');
-+              return -1;
-+      } else {
-+              return 0;
-+      }
-+}
-diff -puN /dev/null arch/i386/boot/cpucheck.c
---- /dev/null
-+++ a/arch/i386/boot/cpucheck.c
-@@ -0,0 +1,266 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/cpu.c
-+ *
-+ * Check for obligatory CPU features and abort if the features are not
-+ * present.  This code should be compilable as 16-, 32- or 64-bit
-+ * code, so be very careful with types and inline assembly.
-+ *
-+ * This code should not contain any messages; that requires an
-+ * additional wrapper.
-+ *
-+ * As written, this code is not safe for inclusion into the kernel
-+ * proper (after FPU initialization, in particular).
-+ */
-+
-+#ifdef _SETUP
-+# include "boot.h"
-+# include "bitops.h"
-+#endif
-+#include <linux/types.h>
-+#include <asm/cpufeature.h>
-+#include <asm/processor-flags.h>
-+#include <asm/required-features.h>
-+#include <asm/msr-index.h>
-+
-+struct cpu_features {
-+      int level;
-+      int model;
-+      u32 flags[NCAPINTS];
-+};
-+
-+static struct cpu_features cpu;
-+static u32 cpu_vendor[3];
-+static u32 err_flags[NCAPINTS];
-+
-+#ifdef CONFIG_X86_64
-+static const int req_level = 64;
-+#elif defined(CONFIG_X86_MINIMUM_CPU_MODEL)
-+static const int req_level = CONFIG_X86_MINIMUM_CPU_MODEL;
-+#else
-+static const int req_level = 3;
-+#endif
-+
-+static const u32 req_flags[NCAPINTS] =
-+{
-+      REQUIRED_MASK0,
-+      REQUIRED_MASK1,
-+      REQUIRED_MASK2,
-+      REQUIRED_MASK3,
-+      REQUIRED_MASK4,
-+      REQUIRED_MASK5,
-+      REQUIRED_MASK6,
-+};
-+
-+#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
-+
-+static int is_amd(void)
-+{
-+      return cpu_vendor[0] == A32('A','u','t','h') &&
-+             cpu_vendor[1] == A32('e','n','t','i') &&
-+             cpu_vendor[2] == A32('c','A','M','D');
-+}
-+
-+static int is_centaur(void)
-+{
-+      return cpu_vendor[0] == A32('C','e','n','t') &&
-+             cpu_vendor[1] == A32('a','u','r','H') &&
-+             cpu_vendor[2] == A32('a','u','l','s');
-+}
-+
-+static int is_transmeta(void)
-+{
-+      return cpu_vendor[0] == A32('G','e','n','u') &&
-+             cpu_vendor[1] == A32('i','n','e','T') &&
-+             cpu_vendor[2] == A32('M','x','8','6');
-+}
-+
-+static int has_fpu(void)
-+{
-+      u16 fcw = -1, fsw = -1;
-+      u32 cr0;
-+
-+      asm("movl %%cr0,%0" : "=r" (cr0));
-+      if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
-+              cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
-+              asm volatile("movl %0,%%cr0" : : "r" (cr0));
-+      }
-+
-+      asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
-+
-+      return fsw == 0 && (fcw & 0x103f) == 0x003f;
-+}
-+
-+static int has_eflag(u32 mask)
-+{
-+      u32 f0, f1;
-+
-+      asm("pushfl ; "
-+          "pushfl ; "
-+          "popl %0 ; "
-+          "movl %0,%1 ; "
-+          "xorl %2,%1 ; "
-+          "pushl %1 ; "
-+          "popfl ; "
-+          "pushfl ; "
-+          "popl %1 ; "
-+          "popfl"
-+          : "=r" (f0), "=r" (f1)
-+          : "g" (mask));
-+
-+      return !!((f0^f1) & mask);
-+}
-+
-+static void get_flags(void)
-+{
-+      u32 max_intel_level, max_amd_level;
-+      u32 tfms;
-+
-+      if (has_fpu())
-+              set_bit(X86_FEATURE_FPU, cpu.flags);
-+
-+      if (has_eflag(X86_EFLAGS_ID)) {
-+              asm("cpuid"
-+                  : "=a" (max_intel_level),
-+                    "=b" (cpu_vendor[0]),
-+                    "=d" (cpu_vendor[1]),
-+                    "=c" (cpu_vendor[2])
-+                  : "a" (0));
-+
-+              if (max_intel_level >= 0x00000001 &&
-+                  max_intel_level <= 0x0000ffff) {
-+                      asm("cpuid"
-+                          : "=a" (tfms),
-+                            "=c" (cpu.flags[4]),
-+                            "=d" (cpu.flags[0])
-+                          : "a" (0x00000001)
-+                          : "ebx");
-+                      cpu.level = (tfms >> 8) & 15;
-+                      cpu.model = (tfms >> 4) & 15;
-+                      if (cpu.level >= 6)
-+                              cpu.model += ((tfms >> 16) & 0xf) << 4;
-+              }
-+
-+              asm("cpuid"
-+                  : "=a" (max_amd_level)
-+                  : "a" (0x80000000)
-+                  : "ebx", "ecx", "edx");
-+
-+              if (max_amd_level >= 0x80000001 &&
-+                  max_amd_level <= 0x8000ffff) {
-+                      u32 eax = 0x80000001;
-+                      asm("cpuid"
-+                          : "+a" (eax),
-+                            "=c" (cpu.flags[6]),
-+                            "=d" (cpu.flags[1])
-+                          : : "ebx");
-+              }
-+      }
-+}
-+
-+/* Returns a bitmask of which words we have error bits in */
-+static int check_flags(void)
-+{
-+      u32 err;
-+      int i;
-+
-+      err = 0;
-+      for (i = 0; i < NCAPINTS; i++) {
-+              err_flags[i] = req_flags[i] & ~cpu.flags[i];
-+              if (err_flags[i])
-+                      err |= 1 << i;
-+      }
-+
-+      return err;
-+}
-+
-+/*
-+ * Returns -1 on error.
-+ *
-+ * *cpu_level is set to the current CPU level; *req_level to the required
-+ * level.  x86-64 is considered level 64 for this purpose.
-+ *
-+ * *err_flags_ptr is set to the flags error array if there are flags missing.
-+ */
-+int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
-+{
-+      int err;
-+
-+      memset(&cpu.flags, 0, sizeof cpu.flags);
-+      cpu.level = 3;
-+
-+      if (has_eflag(X86_EFLAGS_AC))
-+              cpu.level = 4;
-+
-+      get_flags();
-+      err = check_flags();
-+
-+      if (test_bit(X86_FEATURE_LM, cpu.flags))
-+              cpu.level = 64;
-+
-+      if (err == 0x01 &&
-+          !(err_flags[0] &
-+            ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
-+          is_amd()) {
-+              /* If this is an AMD and we're only missing SSE+SSE2, try to
-+                 turn them on */
-+
-+              u32 ecx = MSR_K7_HWCR;
-+              u32 eax, edx;
-+
-+              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
-+              eax &= ~(1 << 15);
-+              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
-+
-+              get_flags();    /* Make sure it really did something */
-+              err = check_flags();
-+      } else if (err == 0x01 &&
-+                 !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
-+                 is_centaur() && cpu.model >= 6) {
-+              /* If this is a VIA C3, we might have to enable CX8
-+                 explicitly */
-+
-+              u32 ecx = MSR_VIA_FCR;
-+              u32 eax, edx;
-+
-+              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
-+              eax |= (1<<1)|(1<<7);
-+              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
-+
-+              set_bit(X86_FEATURE_CX8, cpu.flags);
-+              err = check_flags();
-+      } else if (err == 0x01 && is_transmeta()) {
-+              /* Transmeta might have masked feature bits in word 0 */
-+
-+              u32 ecx = 0x80860004;
-+              u32 eax, edx;
-+              u32 level = 1;
-+
-+              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
-+              asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
-+              asm("cpuid"
-+                  : "+a" (level), "=d" (cpu.flags[0])
-+                  : : "ecx", "ebx");
-+              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
-+
-+              err = check_flags();
-+      }
-+
-+      if (err_flags_ptr)
-+              *err_flags_ptr = err ? err_flags : NULL;
-+      if (cpu_level_ptr)
-+              *cpu_level_ptr = cpu.level;
-+      if (req_level_ptr)
-+              *req_level_ptr = req_level;
-+
-+      return (cpu.level < req_level || err) ? -1 : 0;
-+}
-diff -puN arch/i386/boot/edd.S~git-newsetup /dev/null
---- a/arch/i386/boot/edd.S
-+++ /dev/null
-@@ -1,231 +0,0 @@
--/*
-- * BIOS Enhanced Disk Drive support
-- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
-- * by Matt Domsch <Matt_Domsch@dell.com> October 2002
-- * conformant to T13 Committee www.t13.org
-- *   projects 1572D, 1484D, 1386D, 1226DT
-- * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
-- *    and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
-- * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
-- *      March 2004
-- * Command line option parsing, Matt Domsch, November 2004
-- */
--
--#include <linux/edd.h>
--#include <asm/setup.h>
--
--#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
--
--# It is assumed that %ds == INITSEG here
--
--      movb    $0, (EDD_MBR_SIG_NR_BUF)
--      movb    $0, (EDDNR)
--
--# Check the command line for options:
--# edd=of  disables EDD completely  (edd=off)
--# edd=sk  skips the MBR test    (edd=skipmbr)
--# edd=on  re-enables EDD (edd=on)
--
--      pushl   %esi
--      movw    $edd_mbr_sig_start, %di # Default to edd=on
--
--      movl    %cs:(cmd_line_ptr), %esi
--      andl    %esi, %esi
--      jz      old_cl                  # Old boot protocol?
--
--# Convert to a real-mode pointer in fs:si
--      movl    %esi, %eax
--      shrl    $4, %eax
--      movw    %ax, %fs
--      andw    $0xf, %si
--      jmp     have_cl_pointer
--
--# Old-style boot protocol?
--old_cl:
--      push    %ds                     # aka INITSEG
--      pop     %fs
--
--      cmpw    $0xa33f, (0x20)
--      jne     done_cl                 # No command line at all?
--      movw    (0x22), %si             # Pointer relative to INITSEG
--
--# fs:si has the pointer to the command line now
--have_cl_pointer:
--
--# Loop through kernel command line one byte at a time.  Just in
--# case the loader is buggy and failed to null-terminate the command line
--# terminate if we get close enough to the end of the segment that we
--# cannot fit "edd=XX"...
--cl_atspace:
--      cmpw    $-5, %si                # Watch for segment wraparound
--      jae     done_cl
--      movl    %fs:(%si), %eax
--      andb    %al, %al                # End of line?
--      jz      done_cl
--      cmpl    $EDD_CL_EQUALS, %eax
--      jz      found_edd_equals
--      cmpb    $0x20, %al              # <= space consider whitespace
--      ja      cl_skipword
--      incw    %si
--      jmp     cl_atspace
--
--cl_skipword:
--      cmpw    $-5, %si                # Watch for segment wraparound
--      jae     done_cl
--      movb    %fs:(%si), %al          # End of string?
--      andb    %al, %al
--      jz      done_cl
--      cmpb    $0x20, %al
--      jbe     cl_atspace
--      incw    %si
--      jmp     cl_skipword
--
--found_edd_equals:
--# only looking at first two characters after equals
--# late overrides early on the command line, so keep going after finding something
--      movw    %fs:4(%si), %ax
--      cmpw    $EDD_CL_OFF, %ax        # edd=of
--      je      do_edd_off
--      cmpw    $EDD_CL_SKIP, %ax       # edd=sk
--      je      do_edd_skipmbr
--      cmpw    $EDD_CL_ON, %ax         # edd=on
--      je      do_edd_on
--      jmp     cl_skipword
--do_edd_skipmbr:
--      movw    $edd_start, %di
--      jmp     cl_skipword
--do_edd_off:
--      movw    $edd_done, %di
--      jmp     cl_skipword
--do_edd_on:
--      movw    $edd_mbr_sig_start, %di
--      jmp     cl_skipword
--
--done_cl:
--      popl    %esi
--      jmpw    *%di
--
--# Read the first sector of each BIOS disk device and store the 4-byte signature
--edd_mbr_sig_start:
--      movb    $0x80, %dl                      # from device 80
--      movw    $EDD_MBR_SIG_BUF, %bx           # store buffer ptr in bx
--edd_mbr_sig_read:
--      movl    $0xFFFFFFFF, %eax
--      movl    %eax, (%bx)                     # assume failure
--      pushw   %bx
--      movb    $READ_SECTORS, %ah
--      movb    $1, %al                         # read 1 sector
--      movb    $0, %dh                         # at head 0
--      movw    $1, %cx                         # cylinder 0, sector 0
--      pushw   %es
--      pushw   %ds
--      popw    %es
--      movw    $EDDBUF, %bx                    # disk's data goes into EDDBUF
--      pushw   %dx             # work around buggy BIOSes
--      stc                     # work around buggy BIOSes
--      int     $0x13
--      sti                     # work around buggy BIOSes
--      popw    %dx
--      popw    %es
--      popw    %bx
--      jc      edd_mbr_sig_done                # on failure, we're done.
--      cmpb    $0, %ah         # some BIOSes do not set CF
--      jne     edd_mbr_sig_done                # on failure, we're done.
--      movl    (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
--      movl    %eax, (%bx)                     # store success
--      incb    (EDD_MBR_SIG_NR_BUF)            # note that we stored something
--      incb    %dl                             # increment to next device
--      addw    $4, %bx                         # increment sig buffer ptr
--      cmpb    $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)  # Out of space?
--      jb      edd_mbr_sig_read                # keep looping
--edd_mbr_sig_done:
--
--# Do the BIOS Enhanced Disk Drive calls
--# This consists of two calls:
--#    int 13h ah=41h "Check Extensions Present"
--#    int 13h ah=48h "Get Device Parameters"
--#    int 13h ah=08h "Legacy Get Device Parameters"
--#
--# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
--# in the boot_params at EDDBUF.  The first four bytes of which are
--# used to store the device number, interface support map and version
--# results from fn41.  The next four bytes are used to store the legacy
--# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
--# store the results from fn48.  Starting from device 80h, fn41, then fn48
--# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
--# Then the pointer is incremented to store the data for the next call.
--# This repeats until either a device doesn't exist, or until EDDMAXNR
--# devices have been stored.
--# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
--# the structure, and the fn41 and fn08 results are stored at offsets
--# from there.  This removes the need to increment the pointer for
--# every store, and leaves it ready for the fn48 call.
--# A second one-byte buffer, EDDNR, in the boot_params stores
--# the number of BIOS devices which exist, up to EDDMAXNR.
--# In setup.c, copy_edd() stores both boot_params buffers away
--# for later use, as they would get overwritten otherwise.
--# This code is sensitive to the size of the structs in edd.h
--edd_start:
--                                              # %ds points to the bootsector
--                                                      # result buffer for fn48
--      movw    $EDDBUF+EDDEXTSIZE, %si         # in ds:si, fn41 results
--                                              # kept just before that
--      movb    $0x80, %dl                      # BIOS device 0x80
--
--edd_check_ext:
--      movb    $CHECKEXTENSIONSPRESENT, %ah    # Function 41
--      movw    $EDDMAGIC1, %bx                 # magic
--      int     $0x13                           # make the call
--      jc      edd_done                        # no more BIOS devices
--
--      cmpw    $EDDMAGIC2, %bx                 # is magic right?
--      jne     edd_next                        # nope, next...
--
--      movb    %dl, %ds:-8(%si)                # store device number
--      movb    %ah, %ds:-7(%si)                # store version
--      movw    %cx, %ds:-6(%si)                # store extensions
--      incb    (EDDNR)                         # note that we stored something
--
--edd_get_device_params:
--      movw    $EDDPARMSIZE, %ds:(%si)         # put size
--      movw    $0x0, %ds:2(%si)                # work around buggy BIOSes
--      movb    $GETDEVICEPARAMETERS, %ah       # Function 48
--      int     $0x13                           # make the call
--                                              # Don't check for fail return
--                                              # it doesn't matter.
--edd_get_legacy_chs:
--      xorw    %ax, %ax
--      movw    %ax, %ds:-4(%si)
--      movw    %ax, %ds:-2(%si)
--        # Ralf Brown's Interrupt List says to set ES:DI to
--      # 0000h:0000h "to guard against BIOS bugs"
--      pushw   %es
--      movw    %ax, %es
--      movw    %ax, %di
--      pushw   %dx                             # legacy call clobbers %dl
--      movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
--      int     $0x13                           # make the call
--      jc      edd_legacy_done                 # failed
--      movb    %cl, %al                        # Low 6 bits are max
--      andb    $0x3F, %al                      #   sector number
--      movb    %al, %ds:-1(%si)                # Record max sect
--      movb    %dh, %ds:-2(%si)                # Record max head number
--      movb    %ch, %al                        # Low 8 bits of max cyl
--      shr     $6, %cl
--      movb    %cl, %ah                        # High 2 bits of max cyl
--      movw    %ax, %ds:-4(%si)
--
--edd_legacy_done:
--      popw    %dx
--      popw    %es
--      movw    %si, %ax                        # increment si
--      addw    $EDDPARMSIZE+EDDEXTSIZE, %ax
--      movw    %ax, %si
--
--edd_next:
--      incb    %dl                             # increment to next device
--      cmpb    $EDDMAXNR, (EDDNR)              # Out of space?
--      jb      edd_check_ext                   # keep looping
--
--edd_done:
--#endif
-diff -puN /dev/null arch/i386/boot/edd.c
---- /dev/null
-+++ a/arch/i386/boot/edd.c
-@@ -0,0 +1,196 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/edd.c
-+ *
-+ * Get EDD BIOS disk information
-+ */
-+
-+#include "boot.h"
-+#include <linux/edd.h>
-+
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-+
-+struct edd_dapa {
-+      u8      pkt_size;
-+      u8      rsvd;
-+      u16     sector_cnt;
-+      u16     buf_off, buf_seg;
-+      u64     lba;
-+      u64     buf_lin_addr;
-+};
-+
-+/*
-+ * Note: this uses the heap to hold the loaded sector.
-+ */
-+static int read_sector(u8 devno, u64 lba, void *buf)
-+{
-+      struct edd_dapa dapa;
-+      u16 ax, bx, cx, dx, si;
-+
-+      memset(&dapa, 0, sizeof dapa);
-+      dapa.pkt_size = sizeof(dapa);
-+      dapa.sector_cnt = 1;
-+      dapa.buf_off = (size_t)buf;
-+      dapa.buf_seg = ds();
-+      dapa.lba = lba;
-+
-+      ax = 0x4200;            /* Extended Read */
-+      si = (size_t)&dapa;
-+      dx = devno;
-+      asm("pushfl; stc; int $0x13; setc %%al; popfl"
-+          : "+a" (ax), "+S" (si), "+d" (dx)
-+          : "m" (dapa)
-+          : "ebx", "ecx", "edi", "memory");
-+
-+      if (!(u8)ax)
-+              return 0;       /* OK */
-+
-+      ax = 0x0201;            /* Legacy Read, one sector */
-+      cx = 0x0001;            /* Sector 0-0-1 */
-+      dx = devno;
-+      bx = (size_t)buf;
-+      asm("pushfl; stc; int $0x13; setc %%al; popfl"
-+          : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
-+          : : "esi", "edi", "memory");
-+
-+      return -(u8)ax;         /* 0 or -1 */
-+}
-+
-+static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
-+{
-+      int sector_size;
-+      char *mbrbuf_ptr, *mbrbuf_end;
-+      u32 mbrsig;
-+      u32 buf_base, mbr_base;
-+      extern char _end[];
-+      static char mbr_buf[1024];
-+
-+      sector_size = ei->params.bytes_per_sector;
-+      if (!sector_size)
-+              sector_size = 512; /* Best available guess */
-+
-+      buf_base = (ds() << 4) + (u32)&_end;
-+      mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
-+      mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
-+      mbrbuf_end = mbrbuf_ptr + sector_size;
-+
-+      if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
-+              return 0;
-+      if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
-+              return 0;
-+
-+      if (read_sector(devno, 0, mbrbuf_ptr))
-+              return 0;
-+
-+      mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
-+      return mbrsig;
-+}
-+
-+static int get_edd_info(u8 devno, struct edd_info *ei)
-+{
-+      u16 ax, bx, cx, dx, di;
-+
-+      memset(ei, 0, sizeof *ei);
-+
-+      /* Check Extensions Present */
-+
-+      ax = 0x4100;
-+      bx = EDDMAGIC1;
-+      dx = devno;
-+      asm("pushfl; stc; int $0x13; setc %%al; popfl"
-+          : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
-+          : : "esi", "edi");
-+
-+      if ((u8)ax)
-+              return -1;      /* No extended information */
-+
-+      if (bx != EDDMAGIC2)
-+              return -1;
-+
-+      ei->device  = devno;
-+      ei->version = ax >> 8;  /* EDD version number */
-+      ei->interface_support = cx; /* EDD functionality subsets */
-+
-+      /* Extended Get Device Parameters */
-+
-+      ei->params.length = sizeof(ei->params);
-+      ax = 0x4800;
-+      dx = devno;
-+      asm("pushfl; int $0x13; popfl"
-+          : "+a" (ax), "+d" (dx)
-+          : "S" (&ei->params)
-+          : "ebx", "ecx", "edi");
-+
-+      /* Get legacy CHS parameters */
-+
-+      /* Ralf Brown recommends setting ES:DI to 0:0 */
-+      ax = 0x0800;
-+      dx = devno;
-+      di = 0;
-+      asm("pushw %%es; "
-+          "movw %%di,%%es; "
-+          "pushfl; stc; int $0x13; setc %%al; popfl; "
-+          "popw %%es"
-+          : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
-+          : : "esi");
-+
-+      if ((u8)ax == 0) {
-+              ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
-+              ei->legacy_max_head = dx >> 8;
-+              ei->legacy_sectors_per_track = cx & 0x3f;
-+      }
-+
-+      return 0;
-+}
-+
-+void query_edd(void)
-+{
-+      char eddarg[8];
-+      int do_mbr = 1;
-+      int do_edd = 1;
-+      int devno;
-+      struct edd_info ei, *edp;
-+
-+      if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
-+              if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
-+                      do_mbr = 0;
-+              else if (!strcmp(eddarg, "off"))
-+                      do_edd = 0;
-+      }
-+
-+      edp = (struct edd_info *)boot_params.eddbuf;
-+
-+      if (!do_edd)
-+              return;
-+
-+      for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
-+              /*
-+               * Scan the BIOS-supported hard disks and query EDD
-+               * information...
-+               */
-+              get_edd_info(devno, &ei);
-+
-+              if (boot_params.eddbuf_entries < EDDMAXNR) {
-+                      memcpy(edp, &ei, sizeof ei);
-+                      edp++;
-+                      boot_params.eddbuf_entries++;
-+              }
-+
-+              if (do_mbr) {
-+                      u32 mbr_sig;
-+                      mbr_sig = read_mbr_sig(devno, &ei);
-+                      boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
-+              }
-+      }
-+}
-+
-+#endif
-diff -puN /dev/null arch/i386/boot/header.S
---- /dev/null
-+++ a/arch/i386/boot/header.S
-@@ -0,0 +1,283 @@
-+/*
-+ *    header.S
-+ *
-+ *    Copyright (C) 1991, 1992 Linus Torvalds
-+ *
-+ *    Based on bootsect.S and setup.S
-+ *    modified by more people than can be counted
-+ *
-+ *    Rewritten as a common file by H. Peter Anvin (Apr 2007)
-+ *
-+ * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
-+ * addresses must be multiplied by 16 to obtain their respective linear
-+ * addresses. To avoid confusion, linear addresses are written using leading
-+ * hex while segment addresses are written as segment:offset.
-+ *
-+ */
-+
-+#include <asm/segment.h>
-+#include <linux/utsrelease.h>
-+#include <asm/boot.h>
-+#include <asm/e820.h>
-+#include <asm/page.h>
-+#include <asm/setup.h>
-+#include "boot.h"
-+
-+SETUPSECTS    = 4                     /* default nr of setup-sectors */
-+BOOTSEG               = 0x07C0                /* original address of boot-sector */
-+SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
-+SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
-+                                      /* to be loaded */
-+ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
-+SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
-+
-+#ifndef SVGA_MODE
-+#define SVGA_MODE ASK_VGA
-+#endif
-+
-+#ifndef RAMDISK
-+#define RAMDISK 0
-+#endif
-+
-+#ifndef ROOT_RDONLY
-+#define ROOT_RDONLY 1
-+#endif
-+
-+      .code16
-+      .section ".bstext", "ax"
-+
-+      .global bootsect_start
-+bootsect_start:
-+
-+      # Normalize the start address
-+      ljmp    $BOOTSEG, $start2
-+
-+start2:
-+      movw    %cs, %ax
-+      movw    %ax, %ds
-+      movw    %ax, %es
-+      movw    %ax, %ss
-+      xorw    %sp, %sp
-+      sti
-+      cld
-+
-+      movw    $bugger_off_msg, %si
-+
-+msg_loop:
-+      lodsb
-+      andb    %al, %al
-+      jz      bs_die
-+      movb    $0xe, %ah
-+      movw    $7, %bx
-+      int     $0x10
-+      jmp     msg_loop
-+
-+bs_die:
-+      # Allow the user to press a key, then reboot
-+      xorw    %ax, %ax
-+      int     $0x16
-+      int     $0x19
-+
-+      # int 0x19 should never return.  In case it does anyway,
-+      # invoke the BIOS reset code...
-+      ljmp    $0xf000,$0xfff0
-+
-+      .section ".bsdata", "a"
-+bugger_off_msg:
-+      .ascii  "Direct booting from floppy is no longer supported.\r\n"
-+      .ascii  "Please use a boot loader program instead.\r\n"
-+      .ascii  "\n"
-+      .ascii  "Remove disk and press any key to reboot . . .\r\n"
-+      .byte   0
-+
-+
-+      # Kernel attributes; used by setup.  This is part 1 of the
-+      # header, from the old boot sector.
-+
-+      .section ".header", "a"
-+      .globl  hdr
-+hdr:
-+setup_sects:  .byte SETUPSECTS
-+root_flags:   .word ROOT_RDONLY
-+syssize:      .long SYSSIZE
-+ram_size:     .word RAMDISK
-+vid_mode:     .word SVGA_MODE
-+root_dev:     .word ROOT_DEV
-+boot_flag:    .word 0xAA55
-+
-+      # offset 512, entry point
-+
-+      .globl  _start
-+_start:
-+              # Explicitly enter this as bytes, or the assembler
-+              # tries to generate a 3-byte jump here, which causes
-+              # everything else to push off to the wrong offset.
-+              .byte   0xeb            # short (2-byte) jump
-+              .byte   start_of_setup-1f
-+1:
-+
-+      # Part 2 of the header, from the old setup.S
-+
-+              .ascii  "HdrS"          # header signature
-+              .word   0x0206          # header version number (>= 0x0105)
-+                                      # or else old loadlin-1.5 will fail)
-+              .globl realmode_swtch
-+realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
-+start_sys_seg:        .word   SYSSEG
-+              .word   kernel_version-512 # pointing to kernel version string
-+                                      # above section of header is compatible
-+                                      # with loadlin-1.5 (header v1.5). Don't
-+                                      # change it.
-+
-+type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
-+                                      #      Bootlin, SYSLX, bootsect...)
-+                                      # See Documentation/i386/boot.txt for
-+                                      # assigned ids
-+
-+# flags, unused bits must be zero (RFU) bit within loadflags
-+loadflags:
-+LOADED_HIGH   = 1                     # If set, the kernel is loaded high
-+CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
-+                                      # heap_end_ptr to tell how much
-+                                      # space behind setup.S can be used for
-+                                      # heap purposes.
-+                                      # Only the loader knows what is free
-+#ifndef __BIG_KERNEL__
-+              .byte   0
-+#else
-+              .byte   LOADED_HIGH
-+#endif
-+
-+setup_move_size: .word  0x8000                # size to move, when setup is not
-+                                      # loaded at 0x90000. We will move setup
-+                                      # to 0x90000 then just before jumping
-+                                      # into the kernel. However, only the
-+                                      # loader knows how much data behind
-+                                      # us also needs to be loaded.
-+
-+code32_start:                         # here loaders can put a different
-+                                      # start address for 32-bit code.
-+#ifndef __BIG_KERNEL__
-+              .long   0x1000          #   0x1000 = default for zImage
-+#else
-+              .long   0x100000        # 0x100000 = default for big kernel
-+#endif
-+
-+ramdisk_image:        .long   0               # address of loaded ramdisk image
-+                                      # Here the loader puts the 32-bit
-+                                      # address where it loaded the image.
-+                                      # This only will be read by the kernel.
-+
-+ramdisk_size: .long   0               # its size in bytes
-+
-+bootsect_kludge:
-+              .long   0               # obsolete
-+
-+heap_end_ptr: .word   _end+1024       # (Header version 0x0201 or later)
-+                                      # space from here (exclusive) down to
-+                                      # end of setup code can be used by setup
-+                                      # for local heap purposes.
-+
-+pad1:         .word   0
-+cmd_line_ptr: .long   0               # (Header version 0x0202 or later)
-+                                      # If nonzero, a 32-bit pointer
-+                                      # to the kernel command line.
-+                                      # The command line should be
-+                                      # located between the start of
-+                                      # setup and the end of low
-+                                      # memory (0xa0000), or it may
-+                                      # get overwritten before it
-+                                      # gets read.  If this field is
-+                                      # used, there is no longer
-+                                      # anything magical about the
-+                                      # 0x90000 segment; the setup
-+                                      # can be located anywhere in
-+                                      # low memory 0x10000 or higher.
-+
-+ramdisk_max:  .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
-+                                      # (Header version 0x0203 or later)
-+                                      # The highest safe address for
-+                                      # the contents of an initrd
-+
-+kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN        #physical addr alignment
-+                                              #required for protected mode
-+                                              #kernel
-+#ifdef CONFIG_RELOCATABLE
-+relocatable_kernel:    .byte 1
-+#else
-+relocatable_kernel:    .byte 0
-+#endif
-+pad2:                 .byte 0
-+pad3:                 .word 0
-+
-+cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
-+                                                #added with boot protocol
-+                                                #version 2.06
-+
-+# End of setup header #####################################################
-+
-+      .section ".inittext", "ax"
-+start_of_setup:
-+#ifdef SAFE_RESET_DISK_CONTROLLER
-+# Reset the disk controller.
-+      movw    $0x0000, %ax            # Reset disk controller
-+      movb    $0x80, %dl              # All disks
-+      int     $0x13
-+#endif
-+
-+# We will have entired with %cs = %ds+0x20, normalize %cs so
-+# it is on par with the other segments.
-+      pushw   %ds
-+      pushw   $setup2
-+      lretw
-+
-+setup2:
-+# Force %es = %ds
-+      movw    %ds, %ax
-+      movw    %ax, %es
-+      cld
-+
-+# Stack paranoia: align the stack and make sure it is good
-+# for both 16- and 32-bit references.  In particular, if we
-+# were meant to have been using the full 16-bit segment, the
-+# caller might have set %sp to zero, which breaks %esp-based
-+# references.
-+      andw    $~3, %sp        # dword align (might as well...)
-+      jnz     1f
-+      movw    $0xfffc, %sp    # Make sure we're not zero
-+1:    movzwl  %sp, %esp       # Clear upper half of %esp
-+      sti
-+
-+# Check signature at end of setup
-+      cmpl    $0x5a5aaa55, setup_sig
-+      jne     setup_bad
-+
-+# Zero the bss
-+      movw    $__bss_start, %di
-+      movw    $_end+3, %cx
-+      xorl    %eax, %eax
-+      subw    %di, %cx
-+      shrw    $2, %cx
-+      rep; stosl
-+
-+# Jump to C code (should not return)
-+      calll   main
-+
-+# Setup corrupt somehow...
-+setup_bad:
-+      movl    $setup_corrupt, %eax
-+      calll   puts
-+      # Fall through...
-+
-+      .globl  die
-+      .type   die, @function
-+die:
-+      hlt
-+      jmp     die
-+
-+      .size   die, .-due
-+
-+      .section ".initdata", "a"
-+setup_corrupt:
-+      .byte   7
-+      .string "No setup signature found..."
-diff -puN /dev/null arch/i386/boot/main.c
---- /dev/null
-+++ a/arch/i386/boot/main.c
-@@ -0,0 +1,161 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/main.c
-+ *
-+ * Main module for the real-mode kernel code
-+ */
-+
-+#include "boot.h"
-+
-+struct boot_params boot_params __attribute__((aligned(16)));
-+
-+char *HEAP = _end;
-+char *heap_end = _end;                /* Default end of heap = no heap */
-+
-+/*
-+ * Copy the header into the boot parameter block.  Since this
-+ * screws up the old-style command line protocol, adjust by
-+ * filling in the new-style command line pointer instead.
-+ */
-+#define OLD_CL_MAGIC  0xA33F
-+#define OLD_CL_ADDRESS        0x20
-+
-+static void copy_boot_params(void)
-+{
-+      struct old_cmdline {
-+              u16 cl_magic;
-+              u16 cl_offset;
-+      };
-+      const struct old_cmdline * const oldcmd =
-+              (const struct old_cmdline *)OLD_CL_ADDRESS;
-+
-+      BUILD_BUG_ON(sizeof boot_params != 4096);
-+      memcpy(&boot_params.hdr, &hdr, sizeof hdr);
-+
-+      if (!boot_params.hdr.cmd_line_ptr &&
-+          oldcmd->cl_magic == OLD_CL_MAGIC) {
-+              /* Old-style command line protocol. */
-+              u16 cmdline_seg;
-+
-+              /* Figure out if the command line falls in the region
-+                 of memory that an old kernel would have copied up
-+                 to 0x90000... */
-+              if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
-+                      cmdline_seg = ds();
-+              else
-+                      cmdline_seg = 0x9000;
-+
-+              boot_params.hdr.cmd_line_ptr =
-+                      (cmdline_seg << 4) + oldcmd->cl_offset;
-+      }
-+}
-+
-+/*
-+ * Set the keyboard repeat rate to maximum.  Unclear why this
-+ * is done here; this might be possible to kill off as stale code.
-+ */
-+static void keyboard_set_repeat(void)
-+{
-+      u16 ax = 0x0305;
-+      u16 bx = 0;
-+      asm volatile("int $0x16"
-+                   : "+a" (ax), "+b" (bx)
-+                   : : "ecx", "edx", "esi", "edi");
-+}
-+
-+/*
-+ * Get Intel SpeedStep IST information.
-+ */
-+static void query_speedstep_ist(void)
-+{
-+      asm("int $0x15"
-+          : "=a" (boot_params.speedstep_info[0]),
-+            "=b" (boot_params.speedstep_info[1]),
-+            "=c" (boot_params.speedstep_info[2]),
-+            "=d" (boot_params.speedstep_info[3])
-+          : "a" (0x0000e980),  /* IST Support */
-+            "d" (0x47534943)); /* Request value */
-+}
-+
-+/*
-+ * Tell the BIOS what CPU mode we intend to run in.
-+ */
-+static void set_bios_mode(void)
-+{
-+#ifdef CONFIG_X86_64
-+      u32 eax, ebx;
-+
-+      eax = 0xec00;
-+      ebx = 2;
-+      asm volatile("int $0x15"
-+                   : "+a" (eax), "+b" (ebx)
-+                   : : "ecx", "edx", "esi", "edi");
-+#endif
-+}
-+
-+void main(void)
-+{
-+      /* First, copy the boot header into the "zeropage" */
-+      copy_boot_params();
-+
-+      /* End of heap check */
-+      if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
-+              heap_end = (char *)(boot_params.hdr.heap_end_ptr
-+                                  +0x200-STACK_SIZE);
-+      } else {
-+              /* Boot protocol 2.00 only, no heap available */
-+              puts("WARNING: Ancient bootloader, some functionality "
-+                   "may be limited!\n");
-+      }
-+
-+      /* Make sure we have all the proper CPU support */
-+      if (validate_cpu()) {
-+              puts("Unable to boot - please use a kernel appropriate "
-+                   "for your CPU.\n");
-+              die();
-+      }
-+
-+      /* Tell the BIOS what CPU mode we intend to run in. */
-+      set_bios_mode();
-+
-+      /* Detect memory layout */
-+      detect_memory();
-+
-+      /* Set keyboard repeat rate (why?) */
-+      keyboard_set_repeat();
-+
-+      /* Set the video mode */
-+      set_video();
-+
-+      /* Query MCA information */
-+      query_mca();
-+
-+      /* Voyager */
-+#ifdef CONFIG_X86_VOYAGER
-+      query_voyager();
-+#endif
-+
-+      /* Query SpeedStep IST information */
-+      query_speedstep_ist();
-+
-+      /* Query APM information */
-+#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
-+      query_apm_bios();
-+#endif
-+
-+      /* Query EDD information */
-+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
-+      query_edd();
-+#endif
-+      /* Do the last things and invoke protected mode */
-+      go_to_protected_mode();
-+}
-diff -puN /dev/null arch/i386/boot/mca.c
---- /dev/null
-+++ a/arch/i386/boot/mca.c
-@@ -0,0 +1,43 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/mca.c
-+ *
-+ * Get the MCA system description table
-+ */
-+
-+#include "boot.h"
-+
-+int query_mca(void)
-+{
-+      u8 err;
-+      u16 es, bx, len;
-+
-+      asm("pushw %%es ; "
-+          "int $0x15 ; "
-+          "setc %0 ; "
-+          "movw %%es, %1 ; "
-+          "popw %%es"
-+          : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
-+          : "a" (0xc000));
-+
-+      if (err)
-+              return -1;      /* No MCA present */
-+
-+      set_fs(es);
-+      len = rdfs16(bx);
-+
-+      if (len > sizeof(boot_params.sys_desc_table))
-+              len = sizeof(boot_params.sys_desc_table);
-+
-+      copy_from_fs(&boot_params.sys_desc_table, bx, len);
-+      return 0;
-+}
-diff -puN /dev/null arch/i386/boot/memory.c
---- /dev/null
-+++ a/arch/i386/boot/memory.c
-@@ -0,0 +1,99 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/memory.c
-+ *
-+ * Memory detection code
-+ */
-+
-+#include "boot.h"
-+
-+#define SMAP  0x534d4150      /* ASCII "SMAP" */
-+
-+static int detect_memory_e820(void)
-+{
-+      u32 next = 0;
-+      u32 size, id;
-+      u8 err;
-+      struct e820entry *desc = boot_params.e820_map;
-+
-+      do {
-+              size = sizeof(struct e820entry);
-+              id = SMAP;
-+              asm("int $0x15; setc %0"
-+                  : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
-+                    "=m" (*desc)
-+                  : "D" (desc), "a" (0xe820));
-+
-+              if (err || id != SMAP)
-+                      break;
-+
-+              boot_params.e820_entries++;
-+              desc++;
-+      } while (next && boot_params.e820_entries < E820MAX);
-+
-+      return boot_params.e820_entries;
-+}
-+
-+static int detect_memory_e801(void)
-+{
-+      u16 ax, bx, cx, dx;
-+      u8 err;
-+
-+      bx = cx = dx = 0;
-+      ax = 0xe801;
-+      asm("stc; int $0x15; setc %0"
-+          : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
-+
-+      if (err)
-+              return -1;
-+
-+      /* Do we really need to do this? */
-+      if (cx || dx) {
-+              ax = cx;
-+              bx = dx;
-+      }
-+
-+      if (ax > 15*1024)
-+              return -1;      /* Bogus! */
-+
-+      /* This ignores memory above 16MB if we have a memory hole
-+         there.  If someone actually finds a machine with a memory
-+         hole at 16MB and no support for 0E820h they should probably
-+         generate a fake e820 map. */
-+      boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
-+
-+      return 0;
-+}
-+
-+static int detect_memory_88(void)
-+{
-+      u16 ax;
-+      u8 err;
-+
-+      ax = 0x8800;
-+      asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
-+
-+      boot_params.screen_info.ext_mem_k = ax;
-+
-+      return -err;
-+}
-+
-+int detect_memory(void)
-+{
-+      if (detect_memory_e820() > 0)
-+              return 0;
-+
-+      if (!detect_memory_e801())
-+              return 0;
-+
-+      return detect_memory_88();
-+}
-diff -puN /dev/null arch/i386/boot/pm.c
---- /dev/null
-+++ a/arch/i386/boot/pm.c
-@@ -0,0 +1,170 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/pm.c
-+ *
-+ * Prepare the machine for transition to protected mode.
-+ */
-+
-+#include "boot.h"
-+#include <asm/segment.h>
-+
-+/*
-+ * Invoke the realmode switch hook if present; otherwise
-+ * disable all interrupts.
-+ */
-+static void realmode_switch_hook(void)
-+{
-+      if (boot_params.hdr.realmode_swtch) {
-+              asm volatile("lcallw *%0"
-+                           : : "m" (boot_params.hdr.realmode_swtch)
-+                           : "eax", "ebx", "ecx", "edx");
-+      } else {
-+              asm volatile("cli");
-+              outb(0x80, 0x70); /* Disable NMI */
-+              io_delay();
-+      }
-+}
-+
-+/*
-+ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
-+ * A bzImage kernel is loaded and runs at 0x100000.
-+ */
-+static void move_kernel_around(void)
-+{
-+      /* Note: rely on the compile-time option here rather than
-+         the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
-+         sets the loadflags to zero. */
-+#ifndef __BIG_KERNEL__
-+      u16 dst_seg, src_seg;
-+      u32 syssize;
-+
-+      dst_seg =  0x1000 >> 4;
-+      src_seg = 0x10000 >> 4;
-+      syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
-+
-+      while (syssize) {
-+              int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
-+              int dwords = paras << 2;
-+
-+              asm volatile("pushw %%es ; "
-+                           "pushw %%ds ; "
-+                           "movw %1,%%es ; "
-+                           "movw %2,%%ds ; "
-+                           "xorw %%di,%%di ; "
-+                           "xorw %%si,%%si ; "
-+                           "rep;movsl ; "
-+                           "popw %%ds ; "
-+                           "popw %%es"
-+                           : "+c" (dwords)
-+                           : "rm" (dst_seg), "rm" (src_seg)
-+                           : "esi", "edi");
-+
-+              syssize -= paras;
-+              dst_seg += paras;
-+              src_seg += paras;
-+      }
-+#endif
-+}
-+
-+/*
-+ * Disable all interrupts at the legacy PIC.
-+ */
-+static void mask_all_interrupts(void)
-+{
-+      outb(0xff, 0xa1);       /* Mask all interrupts on the seconday PIC */
-+      io_delay();
-+      outb(0xfb, 0x21);       /* Mask all but cascade on the primary PIC */
-+      io_delay();
-+}
-+
-+/*
-+ * Reset IGNNE# if asserted in the FPU.
-+ */
-+static void reset_coprocessor(void)
-+{
-+      outb(0, 0xf0);
-+      io_delay();
-+      outb(0, 0xf1);
-+      io_delay();
-+}
-+
-+/*
-+ * Set up the GDT
-+ */
-+#define GDT_ENTRY(flags,base,limit)           \
-+      (((u64)(base & 0xff000000) << 32) |     \
-+       ((u64)flags << 40) |                   \
-+       ((u64)(limit & 0x00ff0000) << 32) |    \
-+       ((u64)(base & 0x00ffff00) << 16) |     \
-+       ((u64)(limit & 0x0000ffff)))
-+
-+struct gdt_ptr {
-+      u16 len;
-+      u32 ptr;
-+} __attribute__((packed));
-+
-+static void setup_gdt(void)
-+{
-+      /* There are machines which are known to not boot with the GDT
-+         being 8-byte unaligned.  Intel recommends 16 byte alignment. */
-+      static const u64 boot_gdt[] __attribute__((aligned(16))) = {
-+              /* CS: code, read/execute, 4 GB, base 0 */
-+              [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
-+              /* DS: data, read/write, 4 GB, base 0 */
-+              [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
-+      };
-+      struct gdt_ptr gdt;
-+
-+      gdt.len = sizeof(boot_gdt)-1;
-+      gdt.ptr = (u32)&boot_gdt + (ds() << 4);
-+
-+      asm volatile("lgdtl %0" : : "m" (gdt));
-+}
-+
-+/*
-+ * Set up the IDT
-+ */
-+static void setup_idt(void)
-+{
-+      static const struct gdt_ptr null_idt = {0, 0};
-+      asm volatile("lidtl %0" : : "m" (null_idt));
-+}
-+
-+/*
-+ * Actual invocation sequence
-+ */
-+void go_to_protected_mode(void)
-+{
-+      /* Hook before leaving real mode, also disables interrupts */
-+      realmode_switch_hook();
-+
-+      /* Move the kernel/setup to their final resting places */
-+      move_kernel_around();
-+
-+      /* Enable the A20 gate */
-+      if (enable_a20()) {
-+              puts("A20 gate not responding, unable to boot...\n");
-+              die();
-+      }
-+
-+      /* Reset coprocessor (IGNNE#) */
-+      reset_coprocessor();
-+
-+      /* Mask all interrupts in the PIC */
-+      mask_all_interrupts();
-+
-+      /* Actual transition to protected mode... */
-+      setup_idt();
-+      setup_gdt();
-+      protected_mode_jump(boot_params.hdr.code32_start,
-+                          (u32)&boot_params + (ds() << 4));
-+}
-diff -puN /dev/null arch/i386/boot/pmjump.S
---- /dev/null
-+++ a/arch/i386/boot/pmjump.S
-@@ -0,0 +1,54 @@
-+/* ----------------------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/pmjump.S
-+ *
-+ * The actual transition into protected mode
-+ */
-+
-+#include <asm/boot.h>
-+#include <asm/segment.h>
-+
-+      .text
-+
-+      .globl  protected_mode_jump
-+      .type   protected_mode_jump, @function
-+
-+      .code16
-+
-+/*
-+ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
-+ */
-+protected_mode_jump:
-+      xorl    %ebx, %ebx              # Flag to indicate this is a boot
-+      movl    %edx, %esi              # Pointer to boot_params table
-+      movl    %eax, 2f                # Patch ljmpl instruction
-+      jmp     1f                      # Short jump to flush instruction q.
-+
-+1:
-+      movw    $__BOOT_DS, %cx
-+
-+      movl    %cr0, %edx
-+      orb     $1, %dl                 # Protected mode (PE) bit
-+      movl    %edx, %cr0
-+
-+      movw    %cx, %ds
-+      movw    %cx, %es
-+      movw    %cx, %fs
-+      movw    %cx, %gs
-+      movw    %cx, %ss
-+
-+      # Jump to the 32-bit entrypoint
-+      .byte   0x66, 0xea              # ljmpl opcode
-+2:    .long   0                       # offset
-+      .word   __BOOT_CS               # segment
-+
-+      .size   protected_mode_jump, .-protected_mode_jump
-diff -puN /dev/null arch/i386/boot/printf.c
---- /dev/null
-+++ a/arch/i386/boot/printf.c
-@@ -0,0 +1,331 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/printf.c
-+ *
-+ * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
-+ * version of printf() does not include 64-bit support.  "Live with
-+ * it."
-+ *
-+ */
-+
-+#include "boot.h"
-+
-+static inline int isdigit(int ch)
-+{
-+      return (ch >= '0') && (ch <= '9');
-+}
-+
-+static int skip_atoi(const char **s)
-+{
-+      int i = 0;
-+
-+      while (isdigit(**s))
-+              i = i * 10 + *((*s)++) - '0';
-+      return i;
-+}
-+
-+unsigned int atou(const char *s)
-+{
-+      unsigned int i = 0;
-+      while (isdigit(*s))
-+              i = i * 10 + (*s++ - '0');
-+      return i;
-+}
-+
-+static int strnlen(const char *s, int maxlen)
-+{
-+      const char *es = s;
-+      while (*es && maxlen) {
-+              es++;
-+              maxlen--;
-+      }
-+
-+      return (es - s);
-+}
-+
-+#define ZEROPAD       1               /* pad with zero */
-+#define SIGN  2               /* unsigned/signed long */
-+#define PLUS  4               /* show plus */
-+#define SPACE 8               /* space if plus */
-+#define LEFT  16              /* left justified */
-+#define SPECIAL       32              /* 0x */
-+#define LARGE 64              /* use 'ABCDEF' instead of 'abcdef' */
-+
-+#define do_div(n,base) ({ \
-+int __res; \
-+__res = ((unsigned long) n) % (unsigned) base; \
-+n = ((unsigned long) n) / (unsigned) base; \
-+__res; })
-+
-+static char *number(char *str, long num, int base, int size, int precision,
-+                  int type)
-+{
-+      char c, sign, tmp[66];
-+      const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
-+      int i;
-+
-+      if (type & LARGE)
-+              digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-+      if (type & LEFT)
-+              type &= ~ZEROPAD;
-+      if (base < 2 || base > 36)
-+              return 0;
-+      c = (type & ZEROPAD) ? '0' : ' ';
-+      sign = 0;
-+      if (type & SIGN) {
-+              if (num < 0) {
-+                      sign = '-';
-+                      num = -num;
-+                      size--;
-+              } else if (type & PLUS) {
-+                      sign = '+';
-+                      size--;
-+              } else if (type & SPACE) {
-+                      sign = ' ';
-+                      size--;
-+              }
-+      }
-+      if (type & SPECIAL) {
-+              if (base == 16)
-+                      size -= 2;
-+              else if (base == 8)
-+                      size--;
-+      }
-+      i = 0;
-+      if (num == 0)
-+              tmp[i++] = '0';
-+      else
-+              while (num != 0)
-+                      tmp[i++] = digits[do_div(num, base)];
-+      if (i > precision)
-+              precision = i;
-+      size -= precision;
-+      if (!(type & (ZEROPAD + LEFT)))
-+              while (size-- > 0)
-+                      *str++ = ' ';
-+      if (sign)
-+              *str++ = sign;
-+      if (type & SPECIAL) {
-+              if (base == 8)
-+                      *str++ = '0';
-+              else if (base == 16) {
-+                      *str++ = '0';
-+                      *str++ = digits[33];
-+              }
-+      }
-+      if (!(type & LEFT))
-+              while (size-- > 0)
-+                      *str++ = c;
-+      while (i < precision--)
-+              *str++ = '0';
-+      while (i-- > 0)
-+              *str++ = tmp[i];
-+      while (size-- > 0)
-+              *str++ = ' ';
-+      return str;
-+}
-+
-+int vsprintf(char *buf, const char *fmt, va_list args)
-+{
-+      int len;
-+      unsigned long num;
-+      int i, base;
-+      char *str;
-+      const char *s;
-+
-+      int flags;              /* flags to number() */
-+
-+      int field_width;        /* width of output field */
-+      int precision;          /* min. # of digits for integers; max
-+                                 number of chars for from string */
-+      int qualifier;          /* 'h', 'l', or 'L' for integer fields */
-+
-+      for (str = buf; *fmt; ++fmt) {
-+              if (*fmt != '%') {
-+                      *str++ = *fmt;
-+                      continue;
-+              }
-+
-+              /* process flags */
-+              flags = 0;
-+            repeat:
-+              ++fmt;          /* this also skips first '%' */
-+              switch (*fmt) {
-+              case '-':
-+                      flags |= LEFT;
-+                      goto repeat;
-+              case '+':
-+                      flags |= PLUS;
-+                      goto repeat;
-+              case ' ':
-+                      flags |= SPACE;
-+                      goto repeat;
-+              case '#':
-+                      flags |= SPECIAL;
-+                      goto repeat;
-+              case '0':
-+                      flags |= ZEROPAD;
-+                      goto repeat;
-+              }
-+
-+              /* get field width */
-+              field_width = -1;
-+              if (isdigit(*fmt))
-+                      field_width = skip_atoi(&fmt);
-+              else if (*fmt == '*') {
-+                      ++fmt;
-+                      /* it's the next argument */
-+                      field_width = va_arg(args, int);
-+                      if (field_width < 0) {
-+                              field_width = -field_width;
-+                              flags |= LEFT;
-+                      }
-+              }
-+
-+              /* get the precision */
-+              precision = -1;
-+              if (*fmt == '.') {
-+                      ++fmt;
-+                      if (isdigit(*fmt))
-+                              precision = skip_atoi(&fmt);
-+                      else if (*fmt == '*') {
-+                              ++fmt;
-+                              /* it's the next argument */
-+                              precision = va_arg(args, int);
-+                      }
-+                      if (precision < 0)
-+                              precision = 0;
-+              }
-+
-+              /* get the conversion qualifier */
-+              qualifier = -1;
-+              if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
-+                      qualifier = *fmt;
-+                      ++fmt;
-+              }
-+
-+              /* default base */
-+              base = 10;
-+
-+              switch (*fmt) {
-+              case 'c':
-+                      if (!(flags & LEFT))
-+                              while (--field_width > 0)
-+                                      *str++ = ' ';
-+                      *str++ = (unsigned char)va_arg(args, int);
-+                      while (--field_width > 0)
-+                              *str++ = ' ';
-+                      continue;
-+
-+              case 's':
-+                      s = va_arg(args, char *);
-+                      len = strnlen(s, precision);
-+
-+                      if (!(flags & LEFT))
-+                              while (len < field_width--)
-+                                      *str++ = ' ';
-+                      for (i = 0; i < len; ++i)
-+                              *str++ = *s++;
-+                      while (len < field_width--)
-+                              *str++ = ' ';
-+                      continue;
-+
-+              case 'p':
-+                      if (field_width == -1) {
-+                              field_width = 2 * sizeof(void *);
-+                              flags |= ZEROPAD;
-+                      }
-+                      str = number(str,
-+                                   (unsigned long)va_arg(args, void *), 16,
-+                                   field_width, precision, flags);
-+                      continue;
-+
-+              case 'n':
-+                      if (qualifier == 'l') {
-+                              long *ip = va_arg(args, long *);
-+                              *ip = (str - buf);
-+                      } else {
-+                              int *ip = va_arg(args, int *);
-+                              *ip = (str - buf);
-+                      }
-+                      continue;
-+
-+              case '%':
-+                      *str++ = '%';
-+                      continue;
-+
-+                      /* integer number formats - set up the flags and "break" */
-+              case 'o':
-+                      base = 8;
-+                      break;
-+
-+              case 'X':
-+                      flags |= LARGE;
-+              case 'x':
-+                      base = 16;
-+                      break;
-+
-+              case 'd':
-+              case 'i':
-+                      flags |= SIGN;
-+              case 'u':
-+                      break;
-+
-+              default:
-+                      *str++ = '%';
-+                      if (*fmt)
-+                              *str++ = *fmt;
-+                      else
-+                              --fmt;
-+                      continue;
-+              }
-+              if (qualifier == 'l')
-+                      num = va_arg(args, unsigned long);
-+              else if (qualifier == 'h') {
-+                      num = (unsigned short)va_arg(args, int);
-+                      if (flags & SIGN)
-+                              num = (short)num;
-+              } else if (flags & SIGN)
-+                      num = va_arg(args, int);
-+              else
-+                      num = va_arg(args, unsigned int);
-+              str = number(str, num, base, field_width, precision, flags);
-+      }
-+      *str = '\0';
-+      return str - buf;
-+}
-+
-+int sprintf(char *buf, const char *fmt, ...)
-+{
-+      va_list args;
-+      int i;
-+
-+      va_start(args, fmt);
-+      i = vsprintf(buf, fmt, args);
-+      va_end(args);
-+      return i;
-+}
-+
-+int printf(const char *fmt, ...)
-+{
-+      char printf_buf[1024];
-+      va_list args;
-+      int printed;
-+
-+      va_start(args, fmt);
-+      printed = vsprintf(printf_buf, fmt, args);
-+      va_end(args);
-+
-+      puts(printf_buf);
-+
-+      return printed;
-+}
-diff -puN arch/i386/boot/setup.S~git-newsetup /dev/null
---- a/arch/i386/boot/setup.S
-+++ /dev/null
-@@ -1,1075 +0,0 @@
--/*
-- *    setup.S         Copyright (C) 1991, 1992 Linus Torvalds
-- *
-- * setup.s is responsible for getting the system data from the BIOS,
-- * and putting them into the appropriate places in system memory.
-- * both setup.s and system has been loaded by the bootblock.
-- *
-- * This code asks the bios for memory/disk/other parameters, and
-- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
-- * boot-block used to be. It is then up to the protected mode
-- * system to read them from there before the area is overwritten
-- * for buffer-blocks.
-- *
-- * Move PS/2 aux init code to psaux.c
-- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
-- *
-- * some changes and additional features by Christoph Niemann,
-- * March 1993/June 1994 (Christoph.Niemann@linux.org)
-- *
-- * add APM BIOS checking by Stephen Rothwell, May 1994
-- * (sfr@canb.auug.org.au)
-- *
-- * High load stuff, initrd support and position independency
-- * by Hans Lermen & Werner Almesberger, February 1996
-- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
-- *
-- * Video handling moved to video.S by Martin Mares, March 1996
-- * <mj@k332.feld.cvut.cz>
-- *
-- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
-- * parsons) to avoid loadlin confusion, July 1997
-- *
-- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
-- * <stiker@northlink.com>
-- *
-- * Fix to work around buggy BIOSes which don't use carry bit correctly
-- * and/or report extended memory in CX/DX for e801h memory size detection 
-- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
-- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
-- * anyway.  So to avoid breaking many machines (presumably there was a reason
-- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
-- * if CX/DX have been changed in the e801 call and if so use AX/BX .
-- * Michael Miller, April 2001 <michaelm@mjmm.org>
-- *
-- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
-- * by Robert Schwebel, December 2001 <robert@schwebel.de>
-- */
--
--#include <asm/segment.h>
--#include <linux/utsrelease.h>
--#include <linux/compile.h>
--#include <asm/boot.h>
--#include <asm/e820.h>
--#include <asm/page.h>
--#include <asm/setup.h>
--      
--/* Signature words to ensure LILO loaded us right */
--#define SIG1  0xAA55
--#define SIG2  0x5A5A
--
--INITSEG  = DEF_INITSEG                # 0x9000, we move boot here, out of the way
--SYSSEG   = DEF_SYSSEG         # 0x1000, system loaded at 0x10000 (65536).
--SETUPSEG = DEF_SETUPSEG               # 0x9020, this is the current segment
--                              # ... and the former contents of CS
--
--DELTA_INITSEG = SETUPSEG - INITSEG    # 0x0020
--
--.code16
--.globl begtext, begdata, begbss, endtext, enddata, endbss
--
--.text
--begtext:
--.data
--begdata:
--.bss
--begbss:
--.text
--
--start:
--      jmp     trampoline
--
--# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
--
--              .ascii  "HdrS"          # header signature
--              .word   0x0206          # header version number (>= 0x0105)
--                                      # or else old loadlin-1.5 will fail)
--realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
--start_sys_seg:        .word   SYSSEG
--              .word   kernel_version  # pointing to kernel version string
--                                      # above section of header is compatible
--                                      # with loadlin-1.5 (header v1.5). Don't
--                                      # change it.
--
--type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
--                                      #      Bootlin, SYSLX, bootsect...)
--                                      # See Documentation/i386/boot.txt for
--                                      # assigned ids
--      
--# flags, unused bits must be zero (RFU) bit within loadflags
--loadflags:
--LOADED_HIGH   = 1                     # If set, the kernel is loaded high
--CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
--                                      # heap_end_ptr to tell how much
--                                      # space behind setup.S can be used for
--                                      # heap purposes.
--                                      # Only the loader knows what is free
--#ifndef __BIG_KERNEL__
--              .byte   0
--#else
--              .byte   LOADED_HIGH
--#endif
--
--setup_move_size: .word  0x8000                # size to move, when setup is not
--                                      # loaded at 0x90000. We will move setup 
--                                      # to 0x90000 then just before jumping
--                                      # into the kernel. However, only the
--                                      # loader knows how much data behind
--                                      # us also needs to be loaded.
--
--code32_start:                         # here loaders can put a different
--                                      # start address for 32-bit code.
--#ifndef __BIG_KERNEL__
--              .long   0x1000          #   0x1000 = default for zImage
--#else
--              .long   0x100000        # 0x100000 = default for big kernel
--#endif
--
--ramdisk_image:        .long   0               # address of loaded ramdisk image
--                                      # Here the loader puts the 32-bit
--                                      # address where it loaded the image.
--                                      # This only will be read by the kernel.
--
--ramdisk_size: .long   0               # its size in bytes
--
--bootsect_kludge:
--              .long   0               # obsolete
--
--heap_end_ptr: .word   modelist+1024   # (Header version 0x0201 or later)
--                                      # space from here (exclusive) down to
--                                      # end of setup code can be used by setup
--                                      # for local heap purposes.
--
--pad1:         .word   0
--cmd_line_ptr: .long 0                 # (Header version 0x0202 or later)
--                                      # If nonzero, a 32-bit pointer
--                                      # to the kernel command line.
--                                      # The command line should be
--                                      # located between the start of
--                                      # setup and the end of low
--                                      # memory (0xa0000), or it may
--                                      # get overwritten before it
--                                      # gets read.  If this field is
--                                      # used, there is no longer
--                                      # anything magical about the
--                                      # 0x90000 segment; the setup
--                                      # can be located anywhere in
--                                      # low memory 0x10000 or higher.
--
--ramdisk_max:  .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
--                                      # (Header version 0x0203 or later)
--                                      # The highest safe address for
--                                      # the contents of an initrd
--
--kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN        #physical addr alignment
--                                              #required for protected mode
--                                              #kernel
--#ifdef CONFIG_RELOCATABLE
--relocatable_kernel:    .byte 1
--#else
--relocatable_kernel:    .byte 0
--#endif
--pad2:                 .byte 0
--pad3:                 .word 0
--
--cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
--                                                #added with boot protocol
--                                                #version 2.06
--
--trampoline:   call    start_of_setup
--              .align 16
--                                      # The offset at this point is 0x240
--              .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
--# End of setup header #####################################################
--
--start_of_setup:
--# Bootlin depends on this being done early
--      movw    $0x01500, %ax
--      movb    $0x81, %dl
--      int     $0x13
--
--#ifdef SAFE_RESET_DISK_CONTROLLER
--# Reset the disk controller.
--      movw    $0x0000, %ax
--      movb    $0x80, %dl
--      int     $0x13
--#endif
--
--# Set %ds = %cs, we know that SETUPSEG = %cs at this point
--      movw    %cs, %ax                # aka SETUPSEG
--      movw    %ax, %ds
--# Check signature at end of setup
--      cmpw    $SIG1, setup_sig1
--      jne     bad_sig
--
--      cmpw    $SIG2, setup_sig2
--      jne     bad_sig
--
--      jmp     good_sig1
--
--# Routine to print asciiz string at ds:si
--prtstr:
--      lodsb
--      andb    %al, %al
--      jz      fin
--
--      call    prtchr
--      jmp     prtstr
--
--fin:  ret
--
--# Space printing
--prtsp2:       call    prtspc          # Print double space
--prtspc:       movb    $0x20, %al      # Print single space (note: fall-thru)
--
--# Part of above routine, this one just prints ascii al
--prtchr:       pushw   %ax
--      pushw   %cx
--      movw    $7,%bx
--      movw    $0x01, %cx
--      movb    $0x0e, %ah
--      int     $0x10
--      popw    %cx
--      popw    %ax
--      ret
--
--beep: movb    $0x07, %al
--      jmp     prtchr
--      
--no_sig_mess: .string  "No setup signature found ..."
--
--good_sig1:
--      jmp     good_sig
--
--# We now have to find the rest of the setup code/data
--bad_sig:
--      movw    %cs, %ax                        # SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # INITSEG
--      movw    %ax, %ds
--      xorb    %bh, %bh
--      movb    (497), %bl                      # get setup sect from bootsect
--      subw    $4, %bx                         # LILO loads 4 sectors of setup
--      shlw    $8, %bx                         # convert to words (1sect=2^8 words)
--      movw    %bx, %cx
--      shrw    $3, %bx                         # convert to segment
--      addw    $SYSSEG, %bx
--      movw    %bx, %cs:start_sys_seg
--# Move rest of setup code/data to here
--      movw    $2048, %di                      # four sectors loaded by LILO
--      subw    %si, %si
--      pushw   %cs
--      popw    %es
--      movw    $SYSSEG, %ax
--      movw    %ax, %ds
--      rep
--      movsw
--      movw    %cs, %ax                        # aka SETUPSEG
--      movw    %ax, %ds
--      cmpw    $SIG1, setup_sig1
--      jne     no_sig
--
--      cmpw    $SIG2, setup_sig2
--      jne     no_sig
--
--      jmp     good_sig
--
--no_sig:
--      lea     no_sig_mess, %si
--      call    prtstr
--
--no_sig_loop:
--      hlt
--      jmp     no_sig_loop
--
--good_sig:
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %ds
--# Check if an old loader tries to load a big-kernel
--      testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
--      jz      loader_ok                       # No, no danger for old loaders.
--
--      cmpb    $0, %cs:type_of_loader          # Do we have a loader that
--                                              # can deal with us?
--      jnz     loader_ok                       # Yes, continue.
--
--      pushw   %cs                             # No, we have an old loader,
--      popw    %ds                             # die. 
--      lea     loader_panic_mess, %si
--      call    prtstr
--
--      jmp     no_sig_loop
--
--loader_panic_mess: .string "Wrong loader, giving up..."
--
--# check minimum cpuid
--# we do this here because it is the last place we can actually
--# show a user visible error message. Later the video modus
--# might be already messed up.
--loader_ok:
--      call verify_cpu
--      testl  %eax,%eax
--      jz      cpu_ok
--      movw    %cs,%ax         # aka SETUPSEG
--      movw    %ax,%ds
--      lea     cpu_panic_mess,%si
--      call    prtstr
--1:    jmp     1b
--
--cpu_panic_mess:
--      .asciz  "PANIC: CPU too old for this kernel."
--
--#include "../kernel/verify_cpu.S"
--
--cpu_ok:
--# Get memory size (extended mem, kB)
--
--      xorl    %eax, %eax
--      movl    %eax, (0x1e0)
--#ifndef STANDARD_MEMORY_BIOS_CALL
--      movb    %al, (E820NR)
--# Try three different memory detection schemes.  First, try
--# e820h, which lets us assemble a memory map, then try e801h,
--# which returns a 32-bit memory size, and finally 88h, which
--# returns 0-64m
--
--# method E820H:
--# the memory map from hell.  e820h returns memory classified into
--# a whole bunch of different types, and allows memory holes and
--# everything.  We scan through this memory map and build a list
--# of the first 32 memory areas, which we return at [E820MAP].
--# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
--
--#define SMAP  0x534d4150
--
--meme820:
--      xorl    %ebx, %ebx                      # continuation counter
--      movw    $E820MAP, %di                   # point into the whitelist
--                                              # so we can have the bios
--                                              # directly write into it.
--
--jmpe820:
--      movl    $0x0000e820, %eax               # e820, upper word zeroed
--      movl    $SMAP, %edx                     # ascii 'SMAP'
--      movl    $20, %ecx                       # size of the e820rec
--      pushw   %ds                             # data record.
--      popw    %es
--      int     $0x15                           # make the call
--      jc      bail820                         # fall to e801 if it fails
--
--      cmpl    $SMAP, %eax                     # check the return is `SMAP'
--      jne     bail820                         # fall to e801 if it fails
--
--#     cmpl    $1, 16(%di)                     # is this usable memory?
--#     jne     again820
--
--      # If this is usable memory, we save it by simply advancing %di by
--      # sizeof(e820rec).
--      #
--good820:
--      movb    (E820NR), %al                   # up to 128 entries
--      cmpb    $E820MAX, %al
--      jae     bail820
--
--      incb    (E820NR)
--      movw    %di, %ax
--      addw    $20, %ax
--      movw    %ax, %di
--again820:
--      cmpl    $0, %ebx                        # check to see if
--      jne     jmpe820                         # %ebx is set to EOF
--bail820:
--
--
--# method E801H:
--# memory size is in 1k chunksizes, to avoid confusing loadlin.
--# we store the 0xe801 memory size in a completely different place,
--# because it will most likely be longer than 16 bits.
--# (use 1e0 because that's what Larry Augustine uses in his
--# alternative new memory detection scheme, and it's sensible
--# to write everything into the same place.)
--
--meme801:
--      stc                                     # fix to work around buggy
--      xorw    %cx,%cx                         # BIOSes which don't clear/set
--      xorw    %dx,%dx                         # carry on pass/error of
--                                              # e801h memory size call
--                                              # or merely pass cx,dx though
--                                              # without changing them.
--      movw    $0xe801, %ax
--      int     $0x15
--      jc      mem88
--
--      cmpw    $0x0, %cx                       # Kludge to handle BIOSes
--      jne     e801usecxdx                     # which report their extended
--      cmpw    $0x0, %dx                       # memory in AX/BX rather than
--      jne     e801usecxdx                     # CX/DX.  The spec I have read
--      movw    %ax, %cx                        # seems to indicate AX/BX 
--      movw    %bx, %dx                        # are more reasonable anyway...
--
--e801usecxdx:
--      andl    $0xffff, %edx                   # clear sign extend
--      shll    $6, %edx                        # and go from 64k to 1k chunks
--      movl    %edx, (0x1e0)                   # store extended memory size
--      andl    $0xffff, %ecx                   # clear sign extend
--      addl    %ecx, (0x1e0)                   # and add lower memory into
--                                              # total size.
--
--# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
--# 64mb, depending on the bios) in ax.
--mem88:
--
--#endif
--      movb    $0x88, %ah
--      int     $0x15
--      movw    %ax, (2)
--
--# Set the keyboard repeat rate to the max
--      movw    $0x0305, %ax
--      xorw    %bx, %bx
--      int     $0x16
--
--# Check for video adapter and its parameters and allow the
--# user to browse video modes.
--      call    video                           # NOTE: we need %ds pointing
--                                              # to bootsector
--
--# Get hd0 data...
--      xorw    %ax, %ax
--      movw    %ax, %ds
--      ldsw    (4 * 0x41), %si
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      pushw   %ax
--      movw    %ax, %es
--      movw    $0x0080, %di
--      movw    $0x10, %cx
--      pushw   %cx
--      cld
--      rep
--      movsb
--# Get hd1 data...
--      xorw    %ax, %ax
--      movw    %ax, %ds
--      ldsw    (4 * 0x46), %si
--      popw    %cx
--      popw    %es
--      movw    $0x0090, %di
--      rep
--      movsb
--# Check that there IS a hd1 :-)
--      movw    $0x01500, %ax
--      movb    $0x81, %dl
--      int     $0x13
--      jc      no_disk1
--      
--      cmpb    $3, %ah
--      je      is_disk1
--
--no_disk1:
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %es
--      movw    $0x0090, %di
--      movw    $0x10, %cx
--      xorw    %ax, %ax
--      cld
--      rep
--      stosb
--is_disk1:
--# check for Micro Channel (MCA) bus
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %ds
--      xorw    %ax, %ax
--      movw    %ax, (0xa0)                     # set table length to 0
--      movb    $0xc0, %ah
--      stc
--      int     $0x15                           # moves feature table to es:bx
--      jc      no_mca
--
--      pushw   %ds
--      movw    %es, %ax
--      movw    %ax, %ds
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %es
--      movw    %bx, %si
--      movw    $0xa0, %di
--      movw    (%si), %cx
--      addw    $2, %cx                         # table length is a short
--      cmpw    $0x10, %cx
--      jc      sysdesc_ok
--
--      movw    $0x10, %cx                      # we keep only first 16 bytes
--sysdesc_ok:
--      rep
--      movsb
--      popw    %ds
--no_mca:
--#ifdef CONFIG_X86_VOYAGER
--      movb    $0xff, 0x40     # flag on config found
--      movb    $0xc0, %al
--      mov     $0xff, %ah
--      int     $0x15           # put voyager config info at es:di
--      jc      no_voyager
--      movw    $0x40, %si      # place voyager info in apm table
--      cld
--      movw    $7, %cx
--voyager_rep:
--      movb    %es:(%di), %al
--      movb    %al,(%si)
--      incw    %di
--      incw    %si
--      decw    %cx
--      jnz     voyager_rep
--no_voyager:   
--#endif
--# Check for PS/2 pointing device
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %ds
--      movb    $0, (0x1ff)                     # default is no pointing device
--      int     $0x11                           # int 0x11: equipment list
--      testb   $0x04, %al                      # check if mouse installed
--      jz      no_psmouse
--
--      movb    $0xAA, (0x1ff)                  # device present
--no_psmouse:
--
--#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
--      movl    $0x0000E980, %eax               # IST Support 
--      movl    $0x47534943, %edx               # Request value
--      int     $0x15
--
--      movl    %eax, (96)
--      movl    %ebx, (100)
--      movl    %ecx, (104)
--      movl    %edx, (108)
--#endif
--
--#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
--# Then check for an APM BIOS...
--                                              # %ds points to the bootsector
--      movw    $0, 0x40                        # version = 0 means no APM BIOS
--      movw    $0x05300, %ax                   # APM BIOS installation check
--      xorw    %bx, %bx
--      int     $0x15
--      jc      done_apm_bios                   # Nope, no APM BIOS
--      
--      cmpw    $0x0504d, %bx                   # Check for "PM" signature
--      jne     done_apm_bios                   # No signature, no APM BIOS
--
--      andw    $0x02, %cx                      # Is 32 bit supported?
--      je      done_apm_bios                   # No 32-bit, no (good) APM BIOS
--
--      movw    $0x05304, %ax                   # Disconnect first just in case
--      xorw    %bx, %bx
--      int     $0x15                           # ignore return code
--      movw    $0x05303, %ax                   # 32 bit connect
--      xorl    %ebx, %ebx
--      xorw    %cx, %cx                        # paranoia :-)
--      xorw    %dx, %dx                        #   ...
--      xorl    %esi, %esi                      #   ...
--      xorw    %di, %di                        #   ...
--      int     $0x15
--      jc      no_32_apm_bios                  # Ack, error. 
--
--      movw    %ax,  (66)                      # BIOS code segment
--      movl    %ebx, (68)                      # BIOS entry point offset
--      movw    %cx,  (72)                      # BIOS 16 bit code segment
--      movw    %dx,  (74)                      # BIOS data segment
--      movl    %esi, (78)                      # BIOS code segment lengths
--      movw    %di,  (82)                      # BIOS data segment length
--# Redo the installation check as the 32 bit connect
--# modifies the flags returned on some BIOSs
--      movw    $0x05300, %ax                   # APM BIOS installation check
--      xorw    %bx, %bx
--      xorw    %cx, %cx                        # paranoia
--      int     $0x15
--      jc      apm_disconnect                  # error -> shouldn't happen
--
--      cmpw    $0x0504d, %bx                   # check for "PM" signature
--      jne     apm_disconnect                  # no sig -> shouldn't happen
--
--      movw    %ax, (64)                       # record the APM BIOS version
--      movw    %cx, (76)                       # and flags
--      jmp     done_apm_bios
--
--apm_disconnect:                                       # Tidy up
--      movw    $0x05304, %ax                   # Disconnect
--      xorw    %bx, %bx
--      int     $0x15                           # ignore return code
--
--      jmp     done_apm_bios
--
--no_32_apm_bios:
--      andw    $0xfffd, (76)                   # remove 32 bit support bit
--done_apm_bios:
--#endif
--
--#include "edd.S"
--
--# Now we want to move to protected mode ...
--      cmpw    $0, %cs:realmode_swtch
--      jz      rmodeswtch_normal
--
--      lcall   *%cs:realmode_swtch
--
--      jmp     rmodeswtch_end
--
--rmodeswtch_normal:
--        pushw %cs
--      call    default_switch
--
--rmodeswtch_end:
--# Now we move the system to its rightful place ... but we check if we have a
--# big-kernel. In that case we *must* not move it ...
--      testb   $LOADED_HIGH, %cs:loadflags
--      jz      do_move0                        # .. then we have a normal low
--                                              # loaded zImage
--                                              # .. or else we have a high
--                                              # loaded bzImage
--      jmp     end_move                        # ... and we skip moving
--
--do_move0:
--      movw    $0x100, %ax                     # start of destination segment
--      movw    %cs, %bp                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %bp             # aka INITSEG
--      movw    %cs:start_sys_seg, %bx          # start of source segment
--      cld
--do_move:
--      movw    %ax, %es                        # destination segment
--      incb    %ah                             # instead of add ax,#0x100
--      movw    %bx, %ds                        # source segment
--      addw    $0x100, %bx
--      subw    %di, %di
--      subw    %si, %si
--      movw    $0x800, %cx
--      rep
--      movsw
--      cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
--                                              # so we will perhaps read one
--                                              # page more than needed, but
--                                              # never overwrite INITSEG
--                                              # because destination is a
--                                              # minimum one page below source
--      jb      do_move
--
--end_move:
--# then we load the segment descriptors
--      movw    %cs, %ax                        # aka SETUPSEG
--      movw    %ax, %ds
--              
--# Check whether we need to be downward compatible with version <=201
--      cmpl    $0, cmd_line_ptr
--      jne     end_move_self           # loader uses version >=202 features
--      cmpb    $0x20, type_of_loader
--      je      end_move_self           # bootsect loader, we know of it
--
--# Boot loader doesnt support boot protocol version 2.02.
--# If we have our code not at 0x90000, we need to move it there now.
--# We also then need to move the params behind it (commandline)
--# Because we would overwrite the code on the current IP, we move
--# it in two steps, jumping high after the first one.
--      movw    %cs, %ax
--      cmpw    $SETUPSEG, %ax
--      je      end_move_self
--
--      cli                                     # make sure we really have
--                                              # interrupts disabled !
--                                              # because after this the stack
--                                              # should not be used
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ss, %dx
--      cmpw    %ax, %dx
--      jb      move_self_1
--
--      addw    $INITSEG, %dx
--      subw    %ax, %dx                        # this will go into %ss after
--                                              # the move
--move_self_1:
--      movw    %ax, %ds
--      movw    $INITSEG, %ax                   # real INITSEG
--      movw    %ax, %es
--      movw    %cs:setup_move_size, %cx
--      std                                     # we have to move up, so we use
--                                              # direction down because the
--                                              # areas may overlap
--      movw    %cx, %di
--      decw    %di
--      movw    %di, %si
--      subw    $move_self_here+0x200, %cx
--      rep
--      movsb
--      ljmp    $SETUPSEG, $move_self_here
--
--move_self_here:
--      movw    $move_self_here+0x200, %cx
--      rep
--      movsb
--      movw    $SETUPSEG, %ax
--      movw    %ax, %ds
--      movw    %dx, %ss
--end_move_self:                                        # now we are at the right place
--
--#
--# Enable A20.  This is at the very best an annoying procedure.
--# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
--# AMD Elan bug fix by Robert Schwebel.
--#
--
--#if defined(CONFIG_X86_ELAN)
--      movb $0x02, %al                 # alternate A20 gate
--      outb %al, $0x92                 # this works on SC410/SC520
--a20_elan_wait:
--      call a20_test
--      jz a20_elan_wait
--      jmp a20_done
--#endif
--
--
--A20_TEST_LOOPS                =  32           # Iterations per wait
--A20_ENABLE_LOOPS      = 255           # Total loops to try            
--
--
--#ifndef CONFIG_X86_VOYAGER
--a20_try_loop:
--
--      # First, see if we are on a system with no A20 gate.
--a20_none:
--      call    a20_test
--      jnz     a20_done
--
--      # Next, try the BIOS (INT 0x15, AX=0x2401)
--a20_bios:
--      movw    $0x2401, %ax
--      pushfl                                  # Be paranoid about flags
--      int     $0x15
--      popfl
--
--      call    a20_test
--      jnz     a20_done
--
--      # Try enabling A20 through the keyboard controller
--#endif /* CONFIG_X86_VOYAGER */
--a20_kbc:
--      call    empty_8042
--
--#ifndef CONFIG_X86_VOYAGER
--      call    a20_test                        # Just in case the BIOS worked
--      jnz     a20_done                        # but had a delayed reaction.
--#endif
--
--      movb    $0xD1, %al                      # command write
--      outb    %al, $0x64
--      call    empty_8042
--
--      movb    $0xDF, %al                      # A20 on
--      outb    %al, $0x60
--      call    empty_8042
--
--#ifndef CONFIG_X86_VOYAGER
--      # Wait until a20 really *is* enabled; it can take a fair amount of
--      # time on certain systems; Toshiba Tecras are known to have this
--      # problem.
--a20_kbc_wait:
--      xorw    %cx, %cx
--a20_kbc_wait_loop:
--      call    a20_test
--      jnz     a20_done
--      loop    a20_kbc_wait_loop
--
--      # Final attempt: use "configuration port A"
--a20_fast:
--      inb     $0x92, %al                      # Configuration Port A
--      orb     $0x02, %al                      # "fast A20" version
--      andb    $0xFE, %al                      # don't accidentally reset
--      outb    %al, $0x92
--
--      # Wait for configuration port A to take effect
--a20_fast_wait:
--      xorw    %cx, %cx
--a20_fast_wait_loop:
--      call    a20_test
--      jnz     a20_done
--      loop    a20_fast_wait_loop
--
--      # A20 is still not responding.  Try frobbing it again.
--      # 
--      decb    (a20_tries)
--      jnz     a20_try_loop
--      
--      movw    $a20_err_msg, %si
--      call    prtstr
--
--a20_die:
--      hlt
--      jmp     a20_die
--
--a20_tries:
--      .byte   A20_ENABLE_LOOPS
--
--a20_err_msg:
--      .ascii  "linux: fatal error: A20 gate not responding!"
--      .byte   13, 10, 0
--
--      # If we get here, all is good
--a20_done:
--
--#endif /* CONFIG_X86_VOYAGER */
--# set up gdt and idt and 32bit start address
--      lidt    idt_48                          # load idt with 0,0
--      xorl    %eax, %eax                      # Compute gdt_base
--      movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
--      shll    $4, %eax
--      addl    %eax, code32
--      addl    $gdt, %eax
--      movl    %eax, (gdt_48+2)
--      lgdt    gdt_48                          # load gdt with whatever is
--                                              # appropriate
--
--# make sure any possible coprocessor is properly reset..
--      xorw    %ax, %ax
--      outb    %al, $0xf0
--      call    delay
--
--      outb    %al, $0xf1
--      call    delay
--
--# well, that went ok, I hope. Now we mask all interrupts - the rest
--# is done in init_IRQ().
--      movb    $0xFF, %al                      # mask all interrupts for now
--      outb    %al, $0xA1
--      call    delay
--      
--      movb    $0xFB, %al                      # mask all irq's but irq2 which
--      outb    %al, $0x21                      # is cascaded
--
--# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
--# need no steenking BIOS anyway (except for the initial loading :-).
--# The BIOS-routine wants lots of unnecessary data, and it's less
--# "interesting" anyway. This is how REAL programmers do it.
--#
--# Well, now's the time to actually move into protected mode. To make
--# things as simple as possible, we do no register set-up or anything,
--# we let the gnu-compiled 32-bit programs do that. We just jump to
--# absolute address 0x1000 (or the loader supplied one),
--# in 32-bit protected mode.
--#
--# Note that the short jump isn't strictly needed, although there are
--# reasons why it might be a good idea. It won't hurt in any case.
--      movw    $1, %ax                         # protected mode (PE) bit
--      lmsw    %ax                             # This is it!
--      jmp     flush_instr
--
--flush_instr:
--      xorw    %bx, %bx                        # Flag to indicate a boot
--      xorl    %esi, %esi                      # Pointer to real-mode code
--      movw    %cs, %si
--      subw    $DELTA_INITSEG, %si
--      shll    $4, %esi                        # Convert to 32-bit pointer
--
--# jump to startup_32 in arch/i386/boot/compressed/head.S
--#     
--# NOTE: For high loaded big kernels we need a
--#     jmpi    0x100000,__BOOT_CS
--#
--#     but we yet haven't reloaded the CS register, so the default size 
--#     of the target offset still is 16 bit.
--#     However, using an operand prefix (0x66), the CPU will properly
--#     take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
--#     Manual, Mixing 16-bit and 32-bit code, page 16-6)
--
--      .byte 0x66, 0xea                        # prefix + jmpi-opcode
--code32:       .long   startup_32                      # will be set to %cs+startup_32
--      .word   __BOOT_CS
--.code32
--startup_32:
--      movl $(__BOOT_DS), %eax
--      movl %eax, %ds
--      movl %eax, %es
--      movl %eax, %fs
--      movl %eax, %gs
--      movl %eax, %ss
--
--      xorl %eax, %eax
--1:    incl %eax                               # check that A20 really IS enabled
--      movl %eax, 0x00000000                   # loop forever if it isn't
--      cmpl %eax, 0x00100000
--      je 1b
--
--      # Jump to the 32bit entry point
--      jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
--.code16
--
--# Here's a bunch of information about your current kernel..
--kernel_version:       .ascii  UTS_RELEASE
--              .ascii  " ("
--              .ascii  LINUX_COMPILE_BY
--              .ascii  "@"
--              .ascii  LINUX_COMPILE_HOST
--              .ascii  ") "
--              .ascii  UTS_VERSION
--              .byte   0
--
--# This is the default real mode switch routine.
--# to be called just before protected mode transition
--default_switch:
--      cli                                     # no interrupts allowed !
--      movb    $0x80, %al                      # disable NMI for bootup
--                                              # sequence
--      outb    %al, $0x70
--      lret
--
--
--#ifndef CONFIG_X86_VOYAGER
--# This routine tests whether or not A20 is enabled.  If so, it
--# exits with zf = 0.
--#
--# The memory address used, 0x200, is the int $0x80 vector, which
--# should be safe.
--
--A20_TEST_ADDR = 4*0x80
--
--a20_test:
--      pushw   %cx
--      pushw   %ax
--      xorw    %cx, %cx
--      movw    %cx, %fs                        # Low memory
--      decw    %cx
--      movw    %cx, %gs                        # High memory area
--      movw    $A20_TEST_LOOPS, %cx
--      movw    %fs:(A20_TEST_ADDR), %ax
--      pushw   %ax
--a20_test_wait:
--      incw    %ax
--      movw    %ax, %fs:(A20_TEST_ADDR)
--      call    delay                           # Serialize and make delay constant
--      cmpw    %gs:(A20_TEST_ADDR+0x10), %ax
--      loope   a20_test_wait
--
--      popw    %fs:(A20_TEST_ADDR)
--      popw    %ax
--      popw    %cx
--      ret     
--
--#endif /* CONFIG_X86_VOYAGER */
--
--# This routine checks that the keyboard command queue is empty
--# (after emptying the output buffers)
--#
--# Some machines have delusions that the keyboard buffer is always full
--# with no keyboard attached...
--#
--# If there is no keyboard controller, we will usually get 0xff
--# to all the reads.  With each IO taking a microsecond and
--# a timeout of 100,000 iterations, this can take about half a
--# second ("delay" == outb to port 0x80). That should be ok,
--# and should also be plenty of time for a real keyboard controller
--# to empty.
--#
--
--empty_8042:
--      pushl   %ecx
--      movl    $100000, %ecx
--
--empty_8042_loop:
--      decl    %ecx
--      jz      empty_8042_end_loop
--
--      call    delay
--
--      inb     $0x64, %al                      # 8042 status port
--      testb   $1, %al                         # output buffer?
--      jz      no_output
--
--      call    delay
--      inb     $0x60, %al                      # read it
--      jmp     empty_8042_loop
--
--no_output:
--      testb   $2, %al                         # is input buffer full?
--      jnz     empty_8042_loop                 # yes - loop
--empty_8042_end_loop:
--      popl    %ecx
--      ret
--
--# Read the cmos clock. Return the seconds in al
--gettime:
--      pushw   %cx
--      movb    $0x02, %ah
--      int     $0x1a
--      movb    %dh, %al                        # %dh contains the seconds
--      andb    $0x0f, %al
--      movb    %dh, %ah
--      movb    $0x04, %cl
--      shrb    %cl, %ah
--      aad
--      popw    %cx
--      ret
--
--# Delay is needed after doing I/O
--delay:
--      outb    %al,$0x80
--      ret
--
--# Descriptor tables
--#
--# NOTE: The intel manual says gdt should be sixteen bytes aligned for
--# efficiency reasons.  However, there are machines which are known not
--# to boot with misaligned GDTs, so alter this at your peril!  If you alter
--# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
--# empty GDT entries (one for NULL and one reserved).
--#
--# NOTE:       On some CPUs, the GDT must be 8 byte aligned.  This is
--# true for the Voyager Quad CPU card which will not boot without
--# This directive.  16 byte aligment is recommended by intel.
--#
--      .align 16
--gdt:
--      .fill GDT_ENTRY_BOOT_CS,8,0
--
--      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
--      .word   0                               # base address = 0
--      .word   0x9A00                          # code read/exec
--      .word   0x00CF                          # granularity = 4096, 386
--                                              #  (+5th nibble of limit)
--
--      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
--      .word   0                               # base address = 0
--      .word   0x9200                          # data read/write
--      .word   0x00CF                          # granularity = 4096, 386
--                                              #  (+5th nibble of limit)
--gdt_end:
--      .align  4
--      
--      .word   0                               # alignment byte
--idt_48:
--      .word   0                               # idt limit = 0
--      .word   0, 0                            # idt base = 0L
--
--      .word   0                               # alignment byte
--gdt_48:
--      .word   gdt_end - gdt - 1               # gdt limit
--      .word   0, 0                            # gdt base (filled in later)
--
--# Include video setup & detection code
--
--#include "video.S"
--
--# Setup signature -- must be last
--setup_sig1:   .word   SIG1
--setup_sig2:   .word   SIG2
--
--# After this point, there is some free space which is used by the video mode
--# handling code to store the temporary mode table (not used by the kernel).
--
--modelist:
--
--.text
--endtext:
--.data
--enddata:
--.bss
--endbss:
-diff -puN /dev/null arch/i386/boot/setup.ld
---- /dev/null
-+++ a/arch/i386/boot/setup.ld
-@@ -0,0 +1,54 @@
-+/*
-+ * setup.ld
-+ *
-+ * Linker script for the i386 setup code
-+ */
-+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-+OUTPUT_ARCH(i386)
-+ENTRY(_start)
-+
-+SECTIONS
-+{
-+      . = 0;
-+      .bstext         : { *(.bstext) }
-+      .bsdata         : { *(.bsdata) }
-+
-+      . = 497;
-+      .header         : { *(.header) }
-+      .inittext       : { *(.inittext) }
-+      .initdata       : { *(.initdata) }
-+      .text           : { *(.text*) }
-+
-+      . = ALIGN(16);
-+      .rodata         : { *(.rodata*) }
-+
-+      .videocards     : {
-+              video_cards = .;
-+              *(.videocards)
-+              video_cards_end = .;
-+      }
-+
-+      . = ALIGN(16);
-+      .data           : { *(.data*) }
-+
-+      .signature      : {
-+              setup_sig = .;
-+              LONG(0x5a5aaa55)
-+      }
-+
-+
-+      . = ALIGN(16);
-+      .bss            :
-+      {
-+              __bss_start = .;
-+              *(.bss)
-+              __bss_end = .;
-+      }
-+      . = ALIGN(16);
-+      _end = .;
-+
-+      /DISCARD/ : { *(.note*) }
-+
-+      . = ASSERT(_end <= 0x8000, "Setup too big!");
-+      . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
-+}
-diff -puN /dev/null arch/i386/boot/string.c
---- /dev/null
-+++ a/arch/i386/boot/string.c
-@@ -0,0 +1,34 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/string.c
-+ *
-+ * Very basic string functions
-+ */
-+
-+#include "boot.h"
-+#include <linux/edd.h>
-+
-+int strcmp(const char *str1, const char *str2)
-+{
-+      const unsigned char *s1 = (const unsigned char *)str1;
-+      const unsigned char *s2 = (const unsigned char *)str2;
-+      int delta = 0;
-+
-+      while (*s1 || *s2) {
-+              delta = *s2 - *s1;
-+              if (delta)
-+                      return delta;
-+              s1++;
-+              s2++;
-+      }
-+      return 0;
-+}
-diff -puN arch/i386/boot/tools/build.c~git-newsetup arch/i386/boot/tools/build.c
---- a/arch/i386/boot/tools/build.c~git-newsetup
-+++ a/arch/i386/boot/tools/build.c
-@@ -1,13 +1,12 @@
- /*
-  *  Copyright (C) 1991, 1992  Linus Torvalds
-  *  Copyright (C) 1997 Martin Mares
-+ *  Copyright (C) 2007 H. Peter Anvin
-  */
- /*
-  * This file builds a disk-image from three different files:
-  *
-- * - bootsect: compatibility mbr which prints an error message if
-- *             someone tries to boot the kernel directly.
-  * - setup: 8086 machine code, sets up system parm
-  * - system: 80386 code for actual system
-  *
-@@ -21,6 +20,7 @@
-  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
-  * Cross compiling fixes by Gertjan van Wingerde, July 1996
-  * Rewritten by Martin Mares, April 1997
-+ * Substantially overhauled by H. Peter Anvin, April 2007
-  */
- #include <stdio.h>
-@@ -32,23 +32,25 @@
- #include <sys/sysmacros.h>
- #include <unistd.h>
- #include <fcntl.h>
-+#include <sys/mman.h>
- #include <asm/boot.h>
--typedef unsigned char byte;
--typedef unsigned short word;
--typedef unsigned long u32;
-+typedef unsigned char  u8;
-+typedef unsigned short u16;
-+typedef unsigned long  u32;
- #define DEFAULT_MAJOR_ROOT 0
- #define DEFAULT_MINOR_ROOT 0
--/* Minimal number of setup sectors (see also bootsect.S) */
--#define SETUP_SECTS 4
-+/* Minimal number of setup sectors */
-+#define SETUP_SECT_MIN 5
-+#define SETUP_SECT_MAX 64
--byte buf[1024];
--int fd;
-+/* This must be large enough to hold the entire setup */
-+u8 buf[SETUP_SECT_MAX*512];
- int is_big_kernel;
--void die(const char * str, ...)
-+static void die(const char * str, ...)
- {
-       va_list args;
-       va_start(args, str);
-@@ -57,15 +59,9 @@ void die(const char * str, ...)
-       exit(1);
- }
--void file_open(const char *name)
-+static void usage(void)
- {
--      if ((fd = open(name, O_RDONLY, 0)) < 0)
--              die("Unable to open `%s': %m", name);
--}
--
--void usage(void)
--{
--      die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
-+      die("Usage: build [-b] setup system [rootdev] [> image]");
- }
- int main(int argc, char ** argv)
-@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
-       unsigned int i, sz, setup_sectors;
-       int c;
-       u32 sys_size;
--      byte major_root, minor_root;
-+      u8 major_root, minor_root;
-       struct stat sb;
-+      FILE *file;
-+      int fd;
-+      void *kernel;
-       if (argc > 2 && !strcmp(argv[1], "-b"))
-         {
-           is_big_kernel = 1;
-           argc--, argv++;
-         }
--      if ((argc < 4) || (argc > 5))
-+      if ((argc < 3) || (argc > 4))
-               usage();
--      if (argc > 4) {
--              if (!strcmp(argv[4], "CURRENT")) {
-+      if (argc > 3) {
-+              if (!strcmp(argv[3], "CURRENT")) {
-                       if (stat("/", &sb)) {
-                               perror("/");
-                               die("Couldn't stat /");
-                       }
-                       major_root = major(sb.st_dev);
-                       minor_root = minor(sb.st_dev);
--              } else if (strcmp(argv[4], "FLOPPY")) {
--                      if (stat(argv[4], &sb)) {
--                              perror(argv[4]);
-+              } else if (strcmp(argv[3], "FLOPPY")) {
-+                      if (stat(argv[3], &sb)) {
-+                              perror(argv[3]);
-                               die("Couldn't stat root device.");
-                       }
-                       major_root = major(sb.st_rdev);
-@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
-       }
-       fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
--      file_open(argv[1]);
--      i = read(fd, buf, sizeof(buf));
--      fprintf(stderr,"Boot sector %d bytes.\n",i);
--      if (i != 512)
--              die("Boot block must be exactly 512 bytes");
-+      /* Copy the setup code */
-+      file = fopen(argv[1], "r");
-+      if (!file)
-+              die("Unable to open `%s': %m", argv[1]);
-+      c = fread(buf, 1, sizeof(buf), file);
-+      if (ferror(file))
-+              die("read-error on `setup'");
-+      if (c < 1024)
-+              die("The setup must be at least 1024 bytes");
-       if (buf[510] != 0x55 || buf[511] != 0xaa)
-               die("Boot block hasn't got boot flag (0xAA55)");
-+      fclose(file);
-+
-+      /* Pad unused space with zeros */
-+      setup_sectors = (c + 511) / 512;
-+      if (setup_sectors < SETUP_SECT_MIN)
-+              setup_sectors = SETUP_SECT_MIN;
-+      i = setup_sectors*512;
-+      memset(buf+c, 0, i-c);
-+
-+      /* Set the default root device */
-       buf[508] = minor_root;
-       buf[509] = major_root;
--      if (write(1, buf, 512) != 512)
--              die("Write call failed");
--      close (fd);
--
--      file_open(argv[2]);                                 /* Copy the setup code */
--      for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
--              if (write(1, buf, c) != c)
--                      die("Write call failed");
--      if (c != 0)
--              die("read-error on `setup'");
--      close (fd);
--      setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
--      /* for compatibility with ancient versions of LILO. */
--      if (setup_sectors < SETUP_SECTS)
--              setup_sectors = SETUP_SECTS;
--      fprintf(stderr, "Setup is %d bytes.\n", i);
--      memset(buf, 0, sizeof(buf));
--      while (i < setup_sectors * 512) {
--              c = setup_sectors * 512 - i;
--              if (c > sizeof(buf))
--                      c = sizeof(buf);
--              if (write(1, buf, c) != c)
--                      die("Write call failed");
--              i += c;
--      }
-+      fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
--      file_open(argv[3]);
--      if (fstat (fd, &sb))
--              die("Unable to stat `%s': %m", argv[3]);
-+      /* Open and stat the kernel file */
-+      fd = open(argv[2], O_RDONLY);
-+      if (fd < 0)
-+              die("Unable to open `%s': %m", argv[2]);
-+      if (fstat(fd, &sb))
-+              die("Unable to stat `%s': %m", argv[2]);
-       sz = sb.st_size;
--      fprintf (stderr, "System is %d kB\n", sz/1024);
-+      fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
-+      kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
-+      if (kernel == MAP_FAILED)
-+              die("Unable to mmap '%s': %m", argv[2]);
-       sys_size = (sz + 15) / 16;
-       if (!is_big_kernel && sys_size > DEF_SYSSIZE)
-               die("System is too big. Try using bzImage or modules.");
--      while (sz > 0) {
--              int l, n;
--              l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
--              if ((n=read(fd, buf, l)) != l) {
--                      if (n < 0)
--                              die("Error reading %s: %m", argv[3]);
--                      else
--                              die("%s: Unexpected EOF", argv[3]);
--              }
--              if (write(1, buf, l) != l)
--                      die("Write failed");
--              sz -= l;
--      }
-+      /* Patch the setup code with the appropriate size parameters */
-+      buf[0x1f1] = setup_sectors-1;
-+      buf[0x1f4] = sys_size;
-+      buf[0x1f5] = sys_size >> 8;
-+      buf[0x1f6] = sys_size >> 16;
-+      buf[0x1f7] = sys_size >> 24;
-+
-+      if (fwrite(buf, 1, i, stdout) != i)
-+              die("Writing setup failed");
-+
-+      /* Copy the kernel code */
-+      if (fwrite(kernel, 1, sz, stdout) != sz)
-+              die("Writing kernel failed");
-       close(fd);
--      if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
--              die("Output: seek failed");
--      buf[0] = setup_sectors;
--      if (write(1, buf, 1) != 1)
--              die("Write of setup sector count failed");
--      if (lseek(1, 500, SEEK_SET) != 500)
--              die("Output: seek failed");
--      buf[0] = (sys_size & 0xff);
--      buf[1] = ((sys_size >> 8) & 0xff);
--      buf[2] = ((sys_size >> 16) & 0xff);
--      buf[3] = ((sys_size >> 24) & 0xff);
--      if (write(1, buf, 4) != 4)
--              die("Write of image length failed");
--
--      return 0;                                           /* Everything is OK */
-+      /* Everything is OK */
-+      return 0;
- }
-diff -puN /dev/null arch/i386/boot/tty.c
---- /dev/null
-+++ a/arch/i386/boot/tty.c
-@@ -0,0 +1,112 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/tty.c
-+ *
-+ * Very simple screen I/O
-+ * XXX: Probably should add very simple serial I/O?
-+ */
-+
-+#include "boot.h"
-+
-+/*
-+ * These functions are in .inittext so they can be used to signal
-+ * error during initialization.
-+ */
-+
-+void __attribute__((section(".inittext"))) putchar(int ch)
-+{
-+      unsigned char c = ch;
-+
-+      if (c == '\n')
-+              putchar('\r');  /* \n -> \r\n */
-+
-+      /* int $0x10 is known to have bugs involving touching registers
-+         it shouldn't.  Be extra conservative... */
-+      asm volatile("pushal; int $0x10; popal"
-+                   : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
-+}
-+
-+void __attribute__((section(".inittext"))) puts(const char *str)
-+{
-+      int n = 0;
-+      while (*str) {
-+              putchar(*str++);
-+              n++;
-+      }
-+}
-+
-+/*
-+ * Read the CMOS clock through the BIOS, and return the
-+ * seconds in BCD.
-+ */
-+
-+static u8 gettime(void)
-+{
-+      u16 ax = 0x0200;
-+      u16 cx, dx;
-+
-+      asm("int $0x1a"
-+          : "+a" (ax), "=c" (cx), "=d" (dx)
-+          : : "ebx", "esi", "edi");
-+
-+      return dx >> 8;
-+}
-+
-+/*
-+ * Read from the keyboard
-+ */
-+int getchar(void)
-+{
-+      u16 ax = 0;
-+      asm("int $0x16" : "+a" (ax));
-+
-+      return ax & 0xff;
-+}
-+
-+static int kbd_pending(void)
-+{
-+      u8 pending;
-+      asm("int $0x16; setnz %0"
-+          : "=rm" (pending)
-+          : "a" (0x0100));
-+      return pending;
-+}
-+
-+void kbd_flush(void)
-+{
-+      for (;;) {
-+              if (!kbd_pending())
-+                      break;
-+              getchar();
-+      }
-+}
-+
-+int getchar_timeout(void)
-+{
-+      int cnt = 30;
-+      int t0, t1;
-+
-+      t0 = gettime();
-+
-+      while (cnt) {
-+              if (kbd_pending())
-+                      return getchar();
-+
-+              t1 = gettime();
-+              if (t0 != t1) {
-+                      cnt--;
-+                      t0 = t1;
-+              }
-+      }
-+
-+      return 0;               /* Timeout! */
-+}
-diff -puN /dev/null arch/i386/boot/version.c
---- /dev/null
-+++ a/arch/i386/boot/version.c
-@@ -0,0 +1,23 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/version.c
-+ *
-+ * Kernel version string
-+ */
-+
-+#include "boot.h"
-+#include <linux/utsrelease.h>
-+#include <linux/compile.h>
-+
-+const char kernel_version[] =
-+      UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
-+      UTS_VERSION;
-diff -puN /dev/null arch/i386/boot/vesa.h
---- /dev/null
-+++ a/arch/i386/boot/vesa.h
-@@ -0,0 +1,79 @@
-+/* ----------------------------------------------------------------------- *
-+ *
-+ *   Copyright 1999-2007 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.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+#ifndef BOOT_VESA_H
-+#define BOOT_VESA_H
-+
-+typedef struct {
-+      u16 off, seg;
-+} far_ptr;
-+
-+/* VESA General Information table */
-+struct vesa_general_info {
-+  u32   signature;            /* 0 Magic number = "VESA" */
-+  u16   version;              /* 4 */
-+  far_ptr vendor_string;      /* 6 */
-+  u32   capabilities;         /* 10 */
-+  far_ptr video_mode_ptr;     /* 14 */
-+  u16     total_memory;               /* 18 */
-+
-+  u16     oem_software_rev;   /* 20 */
-+  far_ptr oem_vendor_name_ptr;        /* 22 */
-+  far_ptr oem_product_name_ptr;       /* 26 */
-+  far_ptr oem_product_rev_ptr;        /* 30 */
-+
-+  u8      reserved[222];      /* 34 */
-+  u8      oem_data[256];      /* 256 */
-+} __attribute__((packed));
-+
-+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
-+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
-+
-+struct vesa_mode_info {
-+  u16     mode_attr;          /* 0 */
-+  u8      win_attr[2];                /* 2 */
-+  u16     win_grain;          /* 4 */
-+  u16     win_size;           /* 6 */
-+  u16     win_seg[2];         /* 8 */
-+  far_ptr win_scheme;         /* 12 */
-+  u16     logical_scan;               /* 16 */
-+
-+  u16     h_res;              /* 18 */
-+  u16     v_res;              /* 20 */
-+  u8      char_width;         /* 22 */
-+  u8      char_height;                /* 23 */
-+  u8      memory_planes;      /* 24 */
-+  u8      bpp;                        /* 25 */
-+  u8      banks;              /* 26 */
-+  u8      memory_layout;      /* 27 */
-+  u8      bank_size;          /* 28 */
-+  u8      image_planes;               /* 29 */
-+  u8      page_function;      /* 30 */
-+
-+  u8      rmask;              /* 31 */
-+  u8      rpos;                       /* 32 */
-+  u8      gmask;              /* 33 */
-+  u8      gpos;                       /* 34 */
-+  u8      bmask;              /* 35 */
-+  u8      bpos;                       /* 36 */
-+  u8      resv_mask;          /* 37 */
-+  u8      resv_pos;           /* 38 */
-+  u8      dcm_info;           /* 39 */
-+
-+  u32     lfb_ptr;            /* 40 Linear frame buffer address */
-+  u32     offscreen_ptr;      /* 44 Offscreen memory address */
-+  u16     offscreen_size;     /* 48 */
-+
-+  u8      reserved[206];      /* 50 */
-+} __attribute__((packed));
-+
-+#endif /* LIB_SYS_VESA_H */
-diff -puN /dev/null arch/i386/boot/video-bios.c
---- /dev/null
-+++ a/arch/i386/boot/video-bios.c
-@@ -0,0 +1,125 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/video-bios.c
-+ *
-+ * Standard video BIOS modes
-+ *
-+ * We have two options for this; silent and scanned.
-+ */
-+
-+#include "boot.h"
-+#include "video.h"
-+
-+__videocard video_bios;
-+
-+/* Set a conventional BIOS mode */
-+static int set_bios_mode(u8 mode);
-+
-+static int bios_set_mode(struct mode_info *mi)
-+{
-+      return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
-+}
-+
-+static int set_bios_mode(u8 mode)
-+{
-+      u16 ax;
-+      u8 new_mode;
-+
-+      ax = mode;              /* AH=0x00 Set Video Mode */
-+      asm volatile(INT10
-+                   : "+a" (ax)
-+                   : : "ebx", "ecx", "edx", "esi", "edi");
-+
-+      ax = 0x0f00;            /* Get Current Video Mode */
-+      asm volatile(INT10
-+                   : "+a" (ax)
-+                   : : "ebx", "ecx", "edx", "esi", "edi");
-+
-+      do_restore = 1;         /* Assume video contents was lost */
-+      new_mode = ax & 0x7f;   /* Not all BIOSes are clean with the top bit */
-+
-+      if (new_mode == mode)
-+              return 0;       /* Mode change OK */
-+
-+      if (new_mode != boot_params.screen_info.orig_video_mode) {
-+              /* Mode setting failed, but we didn't end up where we
-+                 started.  That's bad.  Try to revert to the original
-+                 video mode. */
-+              ax = boot_params.screen_info.orig_video_mode;
-+              asm volatile(INT10
-+                           : "+a" (ax)
-+                           : : "ebx", "ecx", "edx", "esi", "edi");
-+      }
-+      return -1;
-+}
-+
-+static int bios_probe(void)
-+{
-+      u8 mode;
-+      u8 saved_mode = boot_params.screen_info.orig_video_mode;
-+      u16 crtc;
-+      struct mode_info *mi;
-+      int nmodes = 0;
-+
-+      if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
-+              return 0;
-+
-+      set_fs(0);
-+      crtc = vga_crtc();
-+
-+      video_bios.modes = GET_HEAP(struct mode_info, 0);
-+
-+      for (mode = 0x14; mode <= 0x7f; mode++) {
-+              if (heap_free() < sizeof(struct mode_info))
-+                      break;
-+
-+              if (mode_defined(VIDEO_FIRST_BIOS+mode))
-+                      continue;
-+
-+              if (set_bios_mode(mode))
-+                      continue;
-+
-+              /* Try to verify that it's a text mode. */
-+
-+              /* Attribute Controller: make graphics controller disabled */
-+              if (in_idx(0x3c0, 0x10) & 0x01)
-+                      continue;
-+
-+              /* Graphics Controller: verify Alpha addressing enabled */
-+              if (in_idx(0x3ce, 0x06) & 0x01)
-+                      continue;
-+
-+              /* CRTC cursor location low should be zero(?) */
-+              if (in_idx(crtc, 0x0f))
-+                      continue;
-+
-+              mi = GET_HEAP(struct mode_info, 1);
-+              mi->mode = VIDEO_FIRST_BIOS+mode;
-+              mi->x = rdfs16(0x44a);
-+              mi->y = rdfs8(0x484)+1;
-+              nmodes++;
-+      }
-+
-+      set_bios_mode(saved_mode);
-+
-+      return nmodes;
-+}
-+
-+__videocard video_bios =
-+{
-+      .card_name      = "BIOS (scanned)",
-+      .probe          = bios_probe,
-+      .set_mode       = bios_set_mode,
-+      .unsafe         = 1,
-+      .xmode_first    = VIDEO_FIRST_BIOS,
-+      .xmode_n        = 0x80,
-+};
-diff -puN /dev/null arch/i386/boot/video-vesa.c
---- /dev/null
-+++ a/arch/i386/boot/video-vesa.c
-@@ -0,0 +1,283 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/video-vesa.c
-+ *
-+ * VESA text modes
-+ */
-+
-+#include "boot.h"
-+#include "video.h"
-+#include "vesa.h"
-+
-+/* VESA information */
-+static struct vesa_general_info vginfo;
-+static struct vesa_mode_info vminfo;
-+
-+__videocard video_vesa;
-+
-+static void vesa_store_mode_params_graphics(void);
-+
-+static int vesa_probe(void)
-+{
-+#ifdef CONFIG_VIDEO_VESA
-+      u16 ax;
-+      u16 mode;
-+      addr_t mode_ptr;
-+      struct mode_info *mi;
-+      int nmodes = 0;
-+
-+      video_vesa.modes = GET_HEAP(struct mode_info, 0);
-+
-+      vginfo.signature = VBE2_MAGIC;
-+
-+      /* Optimistically assume a VESA BIOS is register-clean... */
-+      ax = 0x4f00;
-+      asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
-+
-+      if (ax != 0x004f ||
-+          vginfo.signature != VESA_MAGIC ||
-+          vginfo.version < 0x0102)
-+              return 0;       /* Not present */
-+
-+      set_fs(vginfo.video_mode_ptr.seg);
-+      mode_ptr = vginfo.video_mode_ptr.off;
-+
-+      while ((mode = rdfs16(mode_ptr)) != 0xffff) {
-+              mode_ptr += 2;
-+
-+              if (heap_free() < sizeof(struct mode_info))
-+                      break;  /* Heap full, can't save mode info */
-+
-+              if (mode & ~0x1ff)
-+                      continue;
-+
-+              memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
-+
-+              ax = 0x4f01;
-+              asm("int $0x10"
-+                  : "+a" (ax), "=m" (vminfo)
-+                  : "c" (mode), "D" (&vminfo));
-+
-+              if (ax != 0x004f)
-+                      continue;
-+
-+              if ((vminfo.mode_attr & 0x15) == 0x05) {
-+                      /* Text Mode, TTY BIOS supported,
-+                         supported by hardware */
-+                      mi = GET_HEAP(struct mode_info, 1);
-+                      mi->mode = mode + VIDEO_FIRST_VESA;
-+                      mi->x    = vminfo.h_res;
-+                      mi->y    = vminfo.v_res;
-+                      nmodes++;
-+              } else if ((vminfo.mode_attr & 0x99) == 0x99) {
-+#ifdef CONFIG_FB
-+                      /* Graphics mode, color, linear frame buffer
-+                         supported -- register the mode but hide from
-+                         the menu.  Only do this if framebuffer is
-+                         configured, however, otherwise the user will
-+                         be left without a screen. */
-+                      mi = GET_HEAP(struct mode_info, 1);
-+                      mi->mode = mode + VIDEO_FIRST_VESA;
-+                      mi->x = mi->y = 0;
-+                      nmodes++;
-+#endif
-+              }
-+      }
-+
-+      return nmodes;
-+#else
-+      return 0;
-+#endif
-+}
-+
-+static int vesa_set_mode(struct mode_info *mode)
-+{
-+      u16 ax;
-+      int is_graphic;
-+      u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
-+
-+      memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
-+
-+      ax = 0x4f01;
-+      asm("int $0x10"
-+          : "+a" (ax), "=m" (vminfo)
-+          : "c" (vesa_mode), "D" (&vminfo));
-+
-+      if (ax != 0x004f)
-+              return -1;
-+
-+      if ((vminfo.mode_attr & 0x15) == 0x05) {
-+              /* It's a supported text mode */
-+              is_graphic = 0;
-+      } else if ((vminfo.mode_attr & 0x99) == 0x99) {
-+              /* It's a graphics mode with linear frame buffer */
-+              is_graphic = 1;
-+              vesa_mode |= 0x4000; /* Request linear frame buffer */
-+      } else {
-+              return -1;      /* Invalid mode */
-+      }
-+
-+
-+      ax = 0x4f02;
-+      asm volatile("int $0x10"
-+                   : "+a" (ax)
-+                   : "b" (vesa_mode), "D" (0));
-+
-+      if (ax != 0x004f)
-+              return -1;
-+
-+      graphic_mode = is_graphic;
-+      if (!is_graphic) {
-+              /* Text mode */
-+              force_x = mode->x;
-+              force_y = mode->y;
-+              do_restore = 1;
-+      } else {
-+              /* Graphics mode */
-+              vesa_store_mode_params_graphics();
-+      }
-+
-+      return 0;
-+}
-+
-+
-+/* Switch DAC to 8-bit mode */
-+static void vesa_dac_set_8bits(void)
-+{
-+      u8 dac_size = 6;
-+
-+      /* If possible, switch the DAC to 8-bit mode */
-+      if (vginfo.capabilities & 1) {
-+              u16 ax, bx;
-+
-+              ax = 0x4f08;
-+              bx = 0x0800;
-+              asm volatile(INT10
-+                           : "+a" (ax), "+b" (bx)
-+                           : : "ecx", "edx", "esi", "edi");
-+
-+              if (ax == 0x004f)
-+                      dac_size = bx >> 8;
-+      }
-+
-+      /* Set the color sizes to the DAC size, and offsets to 0 */
-+      boot_params.screen_info.red_size = dac_size;
-+      boot_params.screen_info.green_size = dac_size;
-+      boot_params.screen_info.blue_size = dac_size;
-+      boot_params.screen_info.rsvd_size = dac_size;
-+
-+      boot_params.screen_info.red_pos = 0;
-+      boot_params.screen_info.green_pos = 0;
-+      boot_params.screen_info.blue_pos = 0;
-+      boot_params.screen_info.rsvd_pos = 0;
-+}
-+
-+/* Save the VESA protected mode info */
-+static void vesa_store_pm_info(void)
-+{
-+      u16 ax, bx, di, es;
-+
-+      ax = 0x4f0a;
-+      bx = di = 0;
-+      asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
-+          : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
-+          : : "ecx", "esi");
-+
-+      if (ax != 0x004f)
-+              return;
-+
-+      boot_params.screen_info.vesapm_seg = es;
-+      boot_params.screen_info.vesapm_off = di;
-+}
-+
-+/*
-+ * Save video mode parameters for graphics mode
-+ */
-+static void vesa_store_mode_params_graphics(void)
-+{
-+      /* Tell the kernel we're in VESA graphics mode */
-+      boot_params.screen_info.orig_video_isVGA = 0x23;
-+
-+      /* Mode parameters */
-+      boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
-+      boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
-+      boot_params.screen_info.lfb_width = vminfo.h_res;
-+      boot_params.screen_info.lfb_height = vminfo.v_res;
-+      boot_params.screen_info.lfb_depth = vminfo.bpp;
-+      boot_params.screen_info.pages = vminfo.image_planes;
-+      boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
-+      memcpy(&boot_params.screen_info.red_size,
-+             &vminfo.rmask, 8);
-+
-+      /* General parameters */
-+      boot_params.screen_info.lfb_size = vginfo.total_memory;
-+
-+      if (vminfo.bpp <= 8)
-+              vesa_dac_set_8bits();
-+
-+      vesa_store_pm_info();
-+}
-+
-+/*
-+ * Save EDID information for the kernel; this is invoked, separately,
-+ * after mode-setting.
-+ */
-+void vesa_store_edid(void)
-+{
-+#ifdef CONFIG_FIRMWARE_EDID
-+      u16 ax, bx, cx, dx, di;
-+
-+      /* Apparently used as a nonsense token... */
-+      memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
-+
-+      if (vginfo.version < 0x0200)
-+              return;         /* EDID requires VBE 2.0+ */
-+
-+      ax = 0x4f15;            /* VBE DDC */
-+      bx = 0x0000;            /* Report DDC capabilities */
-+      cx = 0;                 /* Controller 0 */
-+      di = 0;                 /* ES:DI must be 0 by spec */
-+
-+      /* Note: The VBE DDC spec is different from the main VESA spec;
-+         we genuinely have to assume all registers are destroyed here. */
-+
-+      asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
-+          : "+a" (ax), "+b" (bx)
-+          :  "c" (cx), "D" (di)
-+          : "esi");
-+
-+      if (ax != 0x004f)
-+              return;         /* No EDID */
-+
-+      /* BH = time in seconds to transfer EDD information */
-+      /* BL = DDC level supported */
-+
-+      ax = 0x4f15;            /* VBE DDC */
-+      bx = 0x0001;            /* Read EDID */
-+      cx = 0;                 /* Controller 0 */
-+      dx = 0;                 /* EDID block number */
-+      di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
-+      asm(INT10
-+          : "+a" (ax), "+b" (bx), "+d" (dx)
-+          : "c" (cx), "D" (di)
-+          : "esi");
-+#endif /* CONFIG_FIRMWARE_EDID */
-+}
-+
-+__videocard video_vesa =
-+{
-+      .card_name      = "VESA",
-+      .probe          = vesa_probe,
-+      .set_mode       = vesa_set_mode,
-+      .xmode_first    = VIDEO_FIRST_VESA,
-+      .xmode_n        = 0x200,
-+};
-diff -puN /dev/null arch/i386/boot/video-vga.c
---- /dev/null
-+++ a/arch/i386/boot/video-vga.c
-@@ -0,0 +1,260 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/video-vga.c
-+ *
-+ * Common all-VGA modes
-+ */
-+
-+#include "boot.h"
-+#include "video.h"
-+
-+static struct mode_info vga_modes[] = {
-+      { VIDEO_80x25,  80, 25 },
-+      { VIDEO_8POINT, 80, 50 },
-+      { VIDEO_80x43,  80, 43 },
-+      { VIDEO_80x28,  80, 28 },
-+      { VIDEO_80x30,  80, 30 },
-+      { VIDEO_80x34,  80, 34 },
-+      { VIDEO_80x60,  80, 60 },
-+};
-+
-+static struct mode_info ega_modes[] = {
-+      { VIDEO_80x25,  80, 25 },
-+      { VIDEO_8POINT, 80, 43 },
-+};
-+
-+static struct mode_info cga_modes[] = {
-+      { VIDEO_80x25,  80, 25 },
-+};
-+
-+__videocard video_vga;
-+
-+/* Set basic 80x25 mode */
-+static u8 vga_set_basic_mode(void)
-+{
-+      u16 ax;
-+      u8 rows;
-+      u8 mode;
-+
-+#ifdef CONFIG_VIDEO_400_HACK
-+      if (adapter >= ADAPTER_VGA) {
-+              asm(INT10
-+                  : : "a" (0x1202), "b" (0x0030)
-+                  : "ecx", "edx", "esi", "edi");
-+      }
-+#endif
-+
-+      ax = 0x0f00;
-+      asm(INT10
-+          : "+a" (ax)
-+          : : "ebx", "ecx", "edx", "esi", "edi");
-+
-+      mode = (u8)ax;
-+
-+      set_fs(0);
-+      rows = rdfs8(0x484);    /* rows minus one */
-+
-+#ifndef CONFIG_VIDEO_400_HACK
-+      if ((ax == 0x5003 || ax == 0x5007) &&
-+          (rows == 0 || rows == 24))
-+              return mode;
-+#endif
-+
-+      if (mode != 3 && mode != 7)
-+              mode = 3;
-+
-+      /* Set the mode */
-+      asm volatile(INT10
-+                   : : "a" (mode)
-+                   : "ebx", "ecx", "edx", "esi", "edi");
-+      do_restore = 1;
-+      return mode;
-+}
-+
-+static void vga_set_8font(void)
-+{
-+      /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
-+
-+      /* Set 8x8 font */
-+      asm volatile(INT10 : : "a" (0x1112), "b" (0));
-+
-+      /* Use alternate print screen */
-+      asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
-+
-+      /* Turn off cursor emulation */
-+      asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
-+
-+      /* Cursor is scan lines 6-7 */
-+      asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
-+}
-+
-+static void vga_set_14font(void)
-+{
-+      /* Set 9x14 font - 80x28 on VGA */
-+
-+      /* Set 9x14 font */
-+      asm volatile(INT10 : : "a" (0x1111), "b" (0));
-+
-+      /* Turn off cursor emulation */
-+      asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
-+
-+      /* Cursor is scan lines 11-12 */
-+      asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
-+}
-+
-+static void vga_set_80x43(void)
-+{
-+      /* Set 80x43 mode on VGA (not EGA) */
-+
-+      /* Set 350 scans */
-+      asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
-+
-+      /* Reset video mode */
-+      asm volatile(INT10 : : "a" (0x0003));
-+
-+      vga_set_8font();
-+}
-+
-+/* I/O address of the VGA CRTC */
-+u16 vga_crtc(void)
-+{
-+      return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
-+}
-+
-+static void vga_set_480_scanlines(int end)
-+{
-+      u16 crtc;
-+      u8  csel;
-+
-+      crtc = vga_crtc();
-+
-+      out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
-+      out_idx(0x0b, crtc, 0x06); /* Vertical total */
-+      out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
-+      out_idx(0xea, crtc, 0x10); /* Vertical sync start */
-+      out_idx(end, crtc, 0x12); /* Vertical display end */
-+      out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
-+      out_idx(0x04, crtc, 0x16); /* Vertical blank end */
-+      csel = inb(0x3cc);
-+      csel &= 0x0d;
-+      csel |= 0xe2;
-+      outb(csel, 0x3cc);
-+}
-+
-+static void vga_set_80x30(void)
-+{
-+      vga_set_480_scanlines(0xdf);
-+}
-+
-+static void vga_set_80x34(void)
-+{
-+      vga_set_14font();
-+      vga_set_480_scanlines(0xdb);
-+}
-+
-+static void vga_set_80x60(void)
-+{
-+      vga_set_8font();
-+      vga_set_480_scanlines(0xdf);
-+}
-+
-+static int vga_set_mode(struct mode_info *mode)
-+{
-+      /* Set the basic mode */
-+      vga_set_basic_mode();
-+
-+      /* Override a possibly broken BIOS */
-+      force_x = mode->x;
-+      force_y = mode->y;
-+
-+      switch (mode->mode) {
-+      case VIDEO_80x25:
-+              break;
-+      case VIDEO_8POINT:
-+              vga_set_8font();
-+              break;
-+      case VIDEO_80x43:
-+              vga_set_80x43();
-+              break;
-+      case VIDEO_80x28:
-+              vga_set_14font();
-+              break;
-+      case VIDEO_80x30:
-+              vga_set_80x30();
-+              break;
-+      case VIDEO_80x34:
-+              vga_set_80x34();
-+              break;
-+      case VIDEO_80x60:
-+              vga_set_80x60();
-+              break;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * Note: this probe includes basic information required by all
-+ * systems.  It should be executed first, by making sure
-+ * video-vga.c is listed first in the Makefile.
-+ */
-+static int vga_probe(void)
-+{
-+      static const char *card_name[] = {
-+              "CGA/MDA/HGC", "EGA", "VGA"
-+      };
-+      static struct mode_info *mode_lists[] = {
-+              cga_modes,
-+              ega_modes,
-+              vga_modes,
-+      };
-+      static int mode_count[] = {
-+              sizeof(cga_modes)/sizeof(struct mode_info),
-+              sizeof(ega_modes)/sizeof(struct mode_info),
-+              sizeof(vga_modes)/sizeof(struct mode_info),
-+      };
-+      u8 vga_flag;
-+
-+      asm(INT10
-+          : "=b" (boot_params.screen_info.orig_video_ega_bx)
-+          : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
-+          : "ecx", "edx", "esi", "edi");
-+
-+      /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
-+      if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
-+              /* EGA/VGA */
-+              asm(INT10
-+                  : "=a" (vga_flag)
-+                  : "a" (0x1a00)
-+                  : "ebx", "ecx", "edx", "esi", "edi");
-+
-+              if (vga_flag == 0x1a) {
-+                      adapter = ADAPTER_VGA;
-+                      boot_params.screen_info.orig_video_isVGA = 1;
-+              } else {
-+                      adapter = ADAPTER_EGA;
-+              }
-+      } else {
-+              adapter = ADAPTER_CGA;
-+      }
-+
-+      video_vga.modes = mode_lists[adapter];
-+      video_vga.card_name = card_name[adapter];
-+      return mode_count[adapter];
-+}
-+
-+__videocard video_vga =
-+{
-+      .card_name      = "VGA",
-+      .probe          = vga_probe,
-+      .set_mode       = vga_set_mode,
-+};
-diff -puN arch/i386/boot/video.S~git-newsetup /dev/null
---- a/arch/i386/boot/video.S
-+++ /dev/null
-@@ -1,2043 +0,0 @@
--/*    video.S
-- *
-- *    Display adapter & video mode setup, version 2.13 (14-May-99)
-- *
-- *    Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
-- *    Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
-- *
-- *    Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
-- *
-- *    For further information, look at Documentation/svga.txt.
-- *
-- */
--
--/* Enable autodetection of SVGA adapters and modes. */
--#undef CONFIG_VIDEO_SVGA
--
--/* Enable autodetection of VESA modes */
--#define CONFIG_VIDEO_VESA
--
--/* Enable compacting of mode table */
--#define CONFIG_VIDEO_COMPACT
--
--/* Retain screen contents when switching modes */
--#define CONFIG_VIDEO_RETAIN
--
--/* Enable local mode list */
--#undef CONFIG_VIDEO_LOCAL
--
--/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
--#undef CONFIG_VIDEO_400_HACK
--
--/* Hack that lets you force specific BIOS mode ID and specific dimensions */
--#undef CONFIG_VIDEO_GFX_HACK
--#define VIDEO_GFX_BIOS_AX 0x4f02      /* 800x600 on ThinkPad */
--#define VIDEO_GFX_BIOS_BX 0x0102
--#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425     /* 100x37 */
--
--/* This code uses an extended set of video mode numbers. These include:
-- * Aliases for standard modes
-- *    NORMAL_VGA (-1)
-- *    EXTENDED_VGA (-2)
-- *    ASK_VGA (-3)
-- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
-- * of compatibility when extending the table. These are between 0x00 and 0xff.
-- */
--#define VIDEO_FIRST_MENU 0x0000
--
--/* Standard BIOS video modes (BIOS number + 0x0100) */
--#define VIDEO_FIRST_BIOS 0x0100
--
--/* VESA BIOS video modes (VESA number + 0x0200) */
--#define VIDEO_FIRST_VESA 0x0200
--
--/* Video7 special modes (BIOS number + 0x0900) */
--#define VIDEO_FIRST_V7 0x0900
--
--/* Special video modes */
--#define VIDEO_FIRST_SPECIAL 0x0f00
--#define VIDEO_80x25 0x0f00
--#define VIDEO_8POINT 0x0f01
--#define VIDEO_80x43 0x0f02
--#define VIDEO_80x28 0x0f03
--#define VIDEO_CURRENT_MODE 0x0f04
--#define VIDEO_80x30 0x0f05
--#define VIDEO_80x34 0x0f06
--#define VIDEO_80x60 0x0f07
--#define VIDEO_GFX_HACK 0x0f08
--#define VIDEO_LAST_SPECIAL 0x0f09
--
--/* Video modes given by resolution */
--#define VIDEO_FIRST_RESOLUTION 0x1000
--
--/* The "recalculate timings" flag */
--#define VIDEO_RECALC 0x8000
--
--/* Positions of various video parameters passed to the kernel */
--/* (see also include/linux/tty.h) */
--#define PARAM_CURSOR_POS      0x00
--#define PARAM_VIDEO_PAGE      0x04
--#define PARAM_VIDEO_MODE      0x06
--#define PARAM_VIDEO_COLS      0x07
--#define PARAM_VIDEO_EGA_BX    0x0a
--#define PARAM_VIDEO_LINES     0x0e
--#define PARAM_HAVE_VGA                0x0f
--#define PARAM_FONT_POINTS     0x10
--
--#define PARAM_LFB_WIDTH               0x12
--#define PARAM_LFB_HEIGHT      0x14
--#define PARAM_LFB_DEPTH               0x16
--#define PARAM_LFB_BASE                0x18
--#define PARAM_LFB_SIZE                0x1c
--#define PARAM_LFB_LINELENGTH  0x24
--#define PARAM_LFB_COLORS      0x26
--#define PARAM_VESAPM_SEG      0x2e
--#define PARAM_VESAPM_OFF      0x30
--#define PARAM_LFB_PAGES               0x32
--#define PARAM_VESA_ATTRIB     0x34
--#define PARAM_CAPABILITIES    0x36
--
--/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
--#ifdef CONFIG_VIDEO_RETAIN
--#define DO_STORE call store_screen
--#else
--#define DO_STORE
--#endif /* CONFIG_VIDEO_RETAIN */
--
--# This is the main entry point called by setup.S
--# %ds *must* be pointing to the bootsector
--video:        pushw   %ds             # We use different segments
--      pushw   %ds             # FS contains original DS
--      popw    %fs
--      pushw   %cs             # DS is equal to CS
--      popw    %ds
--      pushw   %cs             # ES is equal to CS
--      popw    %es
--      xorw    %ax, %ax
--      movw    %ax, %gs        # GS is zero
--      cld
--      call    basic_detect    # Basic adapter type testing (EGA/VGA/MDA/CGA)
--#ifdef CONFIG_VIDEO_SELECT
--      movw    %fs:(0x01fa), %ax               # User selected video mode
--      cmpw    $ASK_VGA, %ax                   # Bring up the menu
--      jz      vid2
--
--      call    mode_set                        # Set the mode
--      jc      vid1
--
--      leaw    badmdt, %si                     # Invalid mode ID
--      call    prtstr
--vid2: call    mode_menu
--vid1:
--#ifdef CONFIG_VIDEO_RETAIN
--      call    restore_screen                  # Restore screen contents
--#endif /* CONFIG_VIDEO_RETAIN */
--      call    store_edid
--#endif /* CONFIG_VIDEO_SELECT */
--      call    mode_params                     # Store mode parameters
--      popw    %ds                             # Restore original DS
--      ret
--
--# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
--basic_detect:
--      movb    $0, %fs:(PARAM_HAVE_VGA)
--      movb    $0x12, %ah      # Check EGA/VGA
--      movb    $0x10, %bl
--      int     $0x10
--      movw    %bx, %fs:(PARAM_VIDEO_EGA_BX)   # Identifies EGA to the kernel
--      cmpb    $0x10, %bl                      # No, it's a CGA/MDA/HGA card.
--      je      basret
--
--      incb    adapter
--      movw    $0x1a00, %ax                    # Check EGA or VGA?
--      int     $0x10
--      cmpb    $0x1a, %al                      # 1a means VGA...
--      jne     basret                          # anything else is EGA.
--      
--      incb    %fs:(PARAM_HAVE_VGA)            # We've detected a VGA
--      incb    adapter
--basret:       ret
--
--# Store the video mode parameters for later usage by the kernel.
--# This is done by asking the BIOS except for the rows/columns
--# parameters in the default 80x25 mode -- these are set directly,
--# because some very obscure BIOSes supply insane values.
--mode_params:
--#ifdef CONFIG_VIDEO_SELECT
--      cmpb    $0, graphic_mode
--      jnz     mopar_gr
--#endif
--      movb    $0x03, %ah                      # Read cursor position
--      xorb    %bh, %bh
--      int     $0x10
--      movw    %dx, %fs:(PARAM_CURSOR_POS)
--      movb    $0x0f, %ah                      # Read page/mode/width
--      int     $0x10
--      movw    %bx, %fs:(PARAM_VIDEO_PAGE)
--      movw    %ax, %fs:(PARAM_VIDEO_MODE)     # Video mode and screen width
--      cmpb    $0x7, %al                       # MDA/HGA => segment differs
--      jnz     mopar0
--
--      movw    $0xb000, video_segment
--mopar0: movw  %gs:(0x485), %ax                # Font size
--      movw    %ax, %fs:(PARAM_FONT_POINTS)    # (valid only on EGA/VGA)
--      movw    force_size, %ax                 # Forced size?
--      orw     %ax, %ax
--      jz      mopar1
--
--      movb    %ah, %fs:(PARAM_VIDEO_COLS)
--      movb    %al, %fs:(PARAM_VIDEO_LINES)
--      ret
--
--mopar1:       movb    $25, %al
--      cmpb    $0, adapter                     # If we are on CGA/MDA/HGA, the
--      jz      mopar2                          # screen must have 25 lines.
--
--      movb    %gs:(0x484), %al                # On EGA/VGA, use the EGA+ BIOS
--      incb    %al                             # location of max lines.
--mopar2: movb  %al, %fs:(PARAM_VIDEO_LINES)
--      ret
--
--#ifdef CONFIG_VIDEO_SELECT
--# Fetching of VESA frame buffer parameters
--mopar_gr:
--      leaw    modelist+1024, %di
--      movb    $0x23, %fs:(PARAM_HAVE_VGA)
--      movw    16(%di), %ax
--      movw    %ax, %fs:(PARAM_LFB_LINELENGTH)
--      movw    18(%di), %ax
--      movw    %ax, %fs:(PARAM_LFB_WIDTH)
--      movw    20(%di), %ax
--      movw    %ax, %fs:(PARAM_LFB_HEIGHT)
--      movb    25(%di), %al
--      movb    $0, %ah
--      movw    %ax, %fs:(PARAM_LFB_DEPTH)
--      movb    29(%di), %al    
--      movb    $0, %ah
--      movw    %ax, %fs:(PARAM_LFB_PAGES)
--      movl    40(%di), %eax
--      movl    %eax, %fs:(PARAM_LFB_BASE)
--      movl    31(%di), %eax
--      movl    %eax, %fs:(PARAM_LFB_COLORS)
--      movl    35(%di), %eax
--      movl    %eax, %fs:(PARAM_LFB_COLORS+4)
--      movw    0(%di), %ax
--      movw    %ax, %fs:(PARAM_VESA_ATTRIB)
--
--# get video mem size
--      leaw    modelist+1024, %di
--      movw    $0x4f00, %ax
--      int     $0x10
--      xorl    %eax, %eax
--      movw    18(%di), %ax
--      movl    %eax, %fs:(PARAM_LFB_SIZE)
--
--# store mode capabilities
--      movl 10(%di), %eax
--      movl %eax, %fs:(PARAM_CAPABILITIES)
--
--# switching the DAC to 8-bit is for <= 8 bpp only
--      movw    %fs:(PARAM_LFB_DEPTH), %ax
--      cmpw    $8, %ax
--      jg      dac_done
--
--# get DAC switching capability
--      xorl    %eax, %eax
--      movb    10(%di), %al
--      testb   $1, %al
--      jz      dac_set
--
--# attempt to switch DAC to 8-bit
--      movw    $0x4f08, %ax
--      movw    $0x0800, %bx
--      int     $0x10
--      cmpw    $0x004f, %ax
--      jne     dac_set
--      movb    %bh, dac_size           # store actual DAC size
--
--dac_set:
--# set color size to DAC size
--      movb    dac_size, %al
--      movb    %al, %fs:(PARAM_LFB_COLORS+0)
--      movb    %al, %fs:(PARAM_LFB_COLORS+2)
--      movb    %al, %fs:(PARAM_LFB_COLORS+4)
--      movb    %al, %fs:(PARAM_LFB_COLORS+6)
--
--# set color offsets to 0
--      movb    $0, %fs:(PARAM_LFB_COLORS+1)
--      movb    $0, %fs:(PARAM_LFB_COLORS+3)
--      movb    $0, %fs:(PARAM_LFB_COLORS+5)
--      movb    $0, %fs:(PARAM_LFB_COLORS+7)
--
--dac_done:
--# get protected mode interface informations
--      movw    $0x4f0a, %ax
--      xorw    %bx, %bx
--      xorw    %di, %di
--      int     $0x10
--      cmp     $0x004f, %ax
--      jnz     no_pm
--
--      movw    %es, %fs:(PARAM_VESAPM_SEG)
--      movw    %di, %fs:(PARAM_VESAPM_OFF)
--no_pm:        ret
--
--# The video mode menu
--mode_menu:
--      leaw    keymsg, %si                     # "Return/Space/Timeout" message
--      call    prtstr
--      call    flush
--nokey:        call    getkt
--
--      cmpb    $0x0d, %al                      # ENTER ?
--      je      listm                           # yes - manual mode selection
--
--      cmpb    $0x20, %al                      # SPACE ?
--      je      defmd1                          # no - repeat
--
--      call    beep
--      jmp     nokey
--
--defmd1:       ret                                     # No mode chosen? Default 80x25
--
--listm:        call    mode_table                      # List mode table
--listm0:       leaw    name_bann, %si                  # Print adapter name
--      call    prtstr
--      movw    card_name, %si
--      orw     %si, %si
--      jnz     an2
--
--      movb    adapter, %al
--      leaw    old_name, %si
--      orb     %al, %al
--      jz      an1
--
--      leaw    ega_name, %si
--      decb    %al
--      jz      an1
--
--      leaw    vga_name, %si
--      jmp     an1
--
--an2:  call    prtstr
--      leaw    svga_name, %si
--an1:  call    prtstr
--      leaw    listhdr, %si                    # Table header
--      call    prtstr
--      movb    $0x30, %dl                      # DL holds mode number
--      leaw    modelist, %si
--lm1:  cmpw    $ASK_VGA, (%si)                 # End?
--      jz      lm2
--
--      movb    %dl, %al                        # Menu selection number
--      call    prtchr
--      call    prtsp2
--      lodsw
--      call    prthw                           # Mode ID
--      call    prtsp2
--      movb    0x1(%si), %al
--      call    prtdec                          # Rows
--      movb    $0x78, %al                      # the letter 'x'
--      call    prtchr
--      lodsw
--      call    prtdec                          # Columns
--      movb    $0x0d, %al                      # New line
--      call    prtchr
--      movb    $0x0a, %al
--      call    prtchr
--      incb    %dl                             # Next character
--      cmpb    $0x3a, %dl
--      jnz     lm1
--
--      movb    $0x61, %dl
--      jmp     lm1
--
--lm2:  leaw    prompt, %si                     # Mode prompt
--      call    prtstr
--      leaw    edit_buf, %di                   # Editor buffer
--lm3:  call    getkey
--      cmpb    $0x0d, %al                      # Enter?
--      jz      lment
--
--      cmpb    $0x08, %al                      # Backspace?
--      jz      lmbs
--
--      cmpb    $0x20, %al                      # Printable?
--      jc      lm3
--
--      cmpw    $edit_buf+4, %di                # Enough space?
--      jz      lm3
--
--      stosb
--      call    prtchr
--      jmp     lm3
--
--lmbs: cmpw    $edit_buf, %di                  # Backspace
--      jz      lm3
--
--      decw    %di
--      movb    $0x08, %al
--      call    prtchr
--      call    prtspc
--      movb    $0x08, %al
--      call    prtchr
--      jmp     lm3
--      
--lment:        movb    $0, (%di)
--      leaw    crlft, %si
--      call    prtstr
--      leaw    edit_buf, %si
--      cmpb    $0, (%si)                       # Empty string = default mode
--      jz      lmdef
--
--      cmpb    $0, 1(%si)                      # One character = menu selection
--      jz      mnusel
--
--      cmpw    $0x6373, (%si)                  # "scan" => mode scanning
--      jnz     lmhx
--
--      cmpw    $0x6e61, 2(%si)
--      jz      lmscan
--
--lmhx: xorw    %bx, %bx                        # Else => mode ID in hex
--lmhex:        lodsb
--      orb     %al, %al
--      jz      lmuse1
--
--      subb    $0x30, %al
--      jc      lmbad
--
--      cmpb    $10, %al
--      jc      lmhx1
--
--      subb    $7, %al
--      andb    $0xdf, %al
--      cmpb    $10, %al
--      jc      lmbad
--
--      cmpb    $16, %al
--      jnc     lmbad
--
--lmhx1:        shlw    $4, %bx
--      orb     %al, %bl
--      jmp     lmhex
--
--lmuse1:       movw    %bx, %ax
--      jmp     lmuse
--
--mnusel:       lodsb                                   # Menu selection
--      xorb    %ah, %ah
--      subb    $0x30, %al
--      jc      lmbad
--
--      cmpb    $10, %al
--      jc      lmuse
--      
--      cmpb    $0x61-0x30, %al
--      jc      lmbad
--      
--      subb    $0x61-0x30-10, %al
--      cmpb    $36, %al
--      jnc     lmbad
--
--lmuse:        call    mode_set
--      jc      lmdef
--
--lmbad:        leaw    unknt, %si
--      call    prtstr
--      jmp     lm2
--lmscan:       cmpb    $0, adapter                     # Scanning only on EGA/VGA
--      jz      lmbad
--
--      movw    $0, mt_end                      # Scanning of modes is
--      movb    $1, scanning                    # done as new autodetection.
--      call    mode_table
--      jmp     listm0
--lmdef:        ret
--
--# Additional parts of mode_set... (relative jumps, you know)
--setv7:                                                # Video7 extended modes
--      DO_STORE
--      subb    $VIDEO_FIRST_V7>>8, %bh
--      movw    $0x6f05, %ax
--      int     $0x10
--      stc
--      ret
--
--_setrec:      jmp     setrec                  # Ugly...
--_set_80x25:   jmp     set_80x25
--
--# Aliases for backward compatibility.
--setalias:
--      movw    $VIDEO_80x25, %ax
--      incw    %bx
--      jz      mode_set
--
--      movb    $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
--      incw    %bx
--      jnz     setbad                          # Fall-through!
--
--# Setting of user mode (AX=mode ID) => CF=success
--mode_set:
--      movw    %ax, %fs:(0x01fa)               # Store mode for use in acpi_wakeup.S
--      movw    %ax, %bx
--      cmpb    $0xff, %ah
--      jz      setalias
--
--      testb   $VIDEO_RECALC>>8, %ah
--      jnz     _setrec
--
--      cmpb    $VIDEO_FIRST_RESOLUTION>>8, %ah
--      jnc     setres
--      
--      cmpb    $VIDEO_FIRST_SPECIAL>>8, %ah
--      jz      setspc
--      
--      cmpb    $VIDEO_FIRST_V7>>8, %ah
--      jz      setv7
--      
--      cmpb    $VIDEO_FIRST_VESA>>8, %ah
--      jnc     check_vesa
--      
--      orb     %ah, %ah
--      jz      setmenu
--      
--      decb    %ah
--      jz      setbios
--
--setbad:       clc
--      movb    $0, do_restore                  # The screen needn't be restored
--      ret
--
--setvesa:
--      DO_STORE
--      subb    $VIDEO_FIRST_VESA>>8, %bh
--      movw    $0x4f02, %ax                    # VESA BIOS mode set call
--      int     $0x10
--      cmpw    $0x004f, %ax                    # AL=4f if implemented
--      jnz     setbad                          # AH=0 if OK
--
--      stc
--      ret
--
--setbios:
--      DO_STORE
--      int     $0x10                           # Standard BIOS mode set call
--      pushw   %bx
--      movb    $0x0f, %ah                      # Check if really set
--      int     $0x10
--      popw    %bx
--      cmpb    %bl, %al
--      jnz     setbad
--      
--      stc
--      ret
--
--setspc:       xorb    %bh, %bh                        # Set special mode
--      cmpb    $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
--      jnc     setbad
--      
--      addw    %bx, %bx
--      jmp     *spec_inits(%bx)
--
--setmenu:
--      orb     %al, %al                        # 80x25 is an exception
--      jz      _set_80x25
--      
--      pushw   %bx                             # Set mode chosen from menu
--      call    mode_table                      # Build the mode table
--      popw    %ax
--      shlw    $2, %ax
--      addw    %ax, %si
--      cmpw    %di, %si
--      jnc     setbad
--      
--      movw    (%si), %ax                      # Fetch mode ID
--_m_s: jmp     mode_set
--
--setres:       pushw   %bx                             # Set mode chosen by resolution
--      call    mode_table
--      popw    %bx
--      xchgb   %bl, %bh
--setr1:        lodsw
--      cmpw    $ASK_VGA, %ax                   # End of the list?
--      jz      setbad
--      
--      lodsw
--      cmpw    %bx, %ax
--      jnz     setr1
--      
--      movw    -4(%si), %ax                    # Fetch mode ID
--      jmp     _m_s
--
--check_vesa:
--#ifdef CONFIG_FIRMWARE_EDID
--      leaw    modelist+1024, %di
--      movw    $0x4f00, %ax
--      int     $0x10
--      cmpw    $0x004f, %ax
--      jnz     setbad
--
--      movw    4(%di), %ax
--      movw    %ax, vbe_version
--#endif
--      leaw    modelist+1024, %di
--      subb    $VIDEO_FIRST_VESA>>8, %bh
--      movw    %bx, %cx                        # Get mode information structure
--      movw    $0x4f01, %ax
--      int     $0x10
--      addb    $VIDEO_FIRST_VESA>>8, %bh
--      cmpw    $0x004f, %ax
--      jnz     setbad
--
--      movb    (%di), %al                      # Check capabilities.
--      andb    $0x19, %al
--      cmpb    $0x09, %al
--      jz      setvesa                         # This is a text mode
--
--      movb    (%di), %al                      # Check capabilities.
--      andb    $0x99, %al
--      cmpb    $0x99, %al
--      jnz     _setbad                         # Doh! No linear frame buffer.
--
--      subb    $VIDEO_FIRST_VESA>>8, %bh
--      orw     $0x4000, %bx                    # Use linear frame buffer
--      movw    $0x4f02, %ax                    # VESA BIOS mode set call
--      int     $0x10
--      cmpw    $0x004f, %ax                    # AL=4f if implemented
--      jnz     _setbad                         # AH=0 if OK
--
--      movb    $1, graphic_mode                # flag graphic mode
--      movb    $0, do_restore                  # no screen restore
--      stc
--      ret
--
--_setbad:      jmp     setbad                  # Ugly...
--
--# Recalculate vertical display end registers -- this fixes various
--# inconsistencies of extended modes on many adapters. Called when
--# the VIDEO_RECALC flag is set in the mode ID.
--
--setrec:       subb    $VIDEO_RECALC>>8, %ah           # Set the base mode
--      call    mode_set
--      jnc     rct3
--
--      movw    %gs:(0x485), %ax                # Font size in pixels
--      movb    %gs:(0x484), %bl                # Number of rows
--      incb    %bl
--      mulb    %bl                             # Number of visible
--      decw    %ax                             # scan lines - 1
--      movw    $0x3d4, %dx
--      movw    %ax, %bx
--      movb    $0x12, %al                      # Lower 8 bits
--      movb    %bl, %ah
--      outw    %ax, %dx
--      movb    $0x07, %al              # Bits 8 and 9 in the overflow register
--      call    inidx
--      xchgb   %al, %ah
--      andb    $0xbd, %ah
--      shrb    %bh
--      jnc     rct1
--      orb     $0x02, %ah
--rct1: shrb    %bh
--      jnc     rct2
--      orb     $0x40, %ah
--rct2: movb    $0x07, %al
--      outw    %ax, %dx
--      stc
--rct3: ret
--
--# Table of routines for setting of the special modes.
--spec_inits:
--      .word   set_80x25
--      .word   set_8pixel
--      .word   set_80x43
--      .word   set_80x28
--      .word   set_current
--      .word   set_80x30
--      .word   set_80x34
--      .word   set_80x60
--      .word   set_gfx
--
--# Set the 80x25 mode. If already set, do nothing.
--set_80x25:
--      movw    $0x5019, force_size             # Override possibly broken BIOS
--use_80x25:
--#ifdef CONFIG_VIDEO_400_HACK
--      movw    $0x1202, %ax                    # Force 400 scan lines
--      movb    $0x30, %bl
--      int     $0x10
--#else
--      movb    $0x0f, %ah                      # Get current mode ID
--      int     $0x10
--      cmpw    $0x5007, %ax    # Mode 7 (80x25 mono) is the only one available
--      jz      st80            # on CGA/MDA/HGA and is also available on EGAM
--
--      cmpw    $0x5003, %ax    # Unknown mode, force 80x25 color
--      jnz     force3
--
--st80: cmpb    $0, adapter     # CGA/MDA/HGA => mode 3/7 is always 80x25
--      jz      set80
--
--      movb    %gs:(0x0484), %al       # This is EGA+ -- beware of 80x50 etc.
--      orb     %al, %al                # Some buggy BIOS'es set 0 rows
--      jz      set80
--      
--      cmpb    $24, %al                # It's hopefully correct
--      jz      set80
--#endif /* CONFIG_VIDEO_400_HACK */
--force3:       DO_STORE
--      movw    $0x0003, %ax                    # Forced set
--      int     $0x10
--set80:        stc
--      ret
--
--# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
--set_8pixel:
--      DO_STORE
--      call    use_80x25                       # The base is 80x25
--set_8pt:
--      movw    $0x1112, %ax                    # Use 8x8 font
--      xorb    %bl, %bl
--      int     $0x10
--      movw    $0x1200, %ax                    # Use alternate print screen
--      movb    $0x20, %bl
--      int     $0x10
--      movw    $0x1201, %ax                    # Turn off cursor emulation
--      movb    $0x34, %bl
--      int     $0x10
--      movb    $0x01, %ah                      # Define cursor scan lines 6-7
--      movw    $0x0607, %cx
--      int     $0x10
--set_current:
--      stc
--      ret
--
--# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
--# 80x25 mode with 14-point fonts instead of 16-point.
--set_80x28:
--      DO_STORE
--      call    use_80x25                       # The base is 80x25
--set14:        movw    $0x1111, %ax                    # Use 9x14 font
--      xorb    %bl, %bl
--      int     $0x10
--      movb    $0x01, %ah                      # Define cursor scan lines 11-12
--      movw    $0x0b0c, %cx
--      int     $0x10
--      stc
--      ret
--
--# Set the 80x43 mode. This mode is works on all VGA's.
--# It's a 350-scanline mode with 8-pixel font.
--set_80x43:
--      DO_STORE
--      movw    $0x1201, %ax                    # Set 350 scans
--      movb    $0x30, %bl
--      int     $0x10
--      movw    $0x0003, %ax                    # Reset video mode
--      int     $0x10
--      jmp     set_8pt                         # Use 8-pixel font
--
--# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
--set_80x30:
--      call    use_80x25                       # Start with real 80x25
--      DO_STORE
--      movw    $0x3cc, %dx                     # Get CRTC port
--      inb     %dx, %al
--      movb    $0xd4, %dl
--      rorb    %al                             # Mono or color?
--      jc      set48a
--
--      movb    $0xb4, %dl
--set48a:       movw    $0x0c11, %ax            # Vertical sync end (also unlocks CR0-7)
--      call    outidx
--      movw    $0x0b06, %ax                    # Vertical total
--      call    outidx
--      movw    $0x3e07, %ax                    # (Vertical) overflow
--      call    outidx
--      movw    $0xea10, %ax                    # Vertical sync start
--      call    outidx
--      movw    $0xdf12, %ax                    # Vertical display end
--      call    outidx
--      movw    $0xe715, %ax                    # Vertical blank start
--      call    outidx
--      movw    $0x0416, %ax                    # Vertical blank end
--      call    outidx
--      pushw   %dx
--      movb    $0xcc, %dl                      # Misc output register (read)
--      inb     %dx, %al
--      movb    $0xc2, %dl                      # (write)
--      andb    $0x0d, %al      # Preserve clock select bits and color bit
--      orb     $0xe2, %al                      # Set correct sync polarity
--      outb    %al, %dx
--      popw    %dx
--      movw    $0x501e, force_size
--      stc                                     # That's all.
--      ret
--
--# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
--set_80x34:
--      call    set_80x30                       # Set 480 scans
--      call    set14                           # And 14-pt font
--      movw    $0xdb12, %ax                    # VGA vertical display end
--      movw    $0x5022, force_size
--setvde:       call    outidx
--      stc
--      ret
--
--# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
--set_80x60:
--      call    set_80x30                       # Set 480 scans
--      call    set_8pt                         # And 8-pt font
--      movw    $0xdf12, %ax                    # VGA vertical display end
--      movw    $0x503c, force_size
--      jmp     setvde
--
--# Special hack for ThinkPad graphics
--set_gfx:
--#ifdef CONFIG_VIDEO_GFX_HACK
--      movw    $VIDEO_GFX_BIOS_AX, %ax
--      movw    $VIDEO_GFX_BIOS_BX, %bx
--      int     $0x10
--      movw    $VIDEO_GFX_DUMMY_RESOLUTION, force_size
--      stc
--#endif
--      ret
--
--#ifdef CONFIG_VIDEO_RETAIN
--
--# Store screen contents to temporary buffer.
--store_screen:
--      cmpb    $0, do_restore                  # Already stored?
--      jnz     stsr
--
--      testb   $CAN_USE_HEAP, loadflags        # Have we space for storing?
--      jz      stsr
--      
--      pushw   %ax
--      pushw   %bx
--      pushw   force_size                      # Don't force specific size
--      movw    $0, force_size
--      call    mode_params                     # Obtain params of current mode
--      popw    force_size
--      movb    %fs:(PARAM_VIDEO_LINES), %ah
--      movb    %fs:(PARAM_VIDEO_COLS), %al
--      movw    %ax, %bx                        # BX=dimensions
--      mulb    %ah
--      movw    %ax, %cx                        # CX=number of characters
--      addw    %ax, %ax                        # Calculate image size
--      addw    $modelist+1024+4, %ax
--      cmpw    heap_end_ptr, %ax
--      jnc     sts1                            # Unfortunately, out of memory
--
--      movw    %fs:(PARAM_CURSOR_POS), %ax     # Store mode params
--      leaw    modelist+1024, %di
--      stosw
--      movw    %bx, %ax
--      stosw
--      pushw   %ds                             # Store the screen
--      movw    video_segment, %ds
--      xorw    %si, %si
--      rep
--      movsw
--      popw    %ds
--      incb    do_restore                      # Screen will be restored later
--sts1: popw    %bx
--      popw    %ax
--stsr: ret
--
--# Restore screen contents from temporary buffer.
--restore_screen:
--      cmpb    $0, do_restore                  # Has the screen been stored?
--      jz      res1
--
--      call    mode_params                     # Get parameters of current mode
--      movb    %fs:(PARAM_VIDEO_LINES), %cl
--      movb    %fs:(PARAM_VIDEO_COLS), %ch
--      leaw    modelist+1024, %si              # Screen buffer
--      lodsw                                   # Set cursor position
--      movw    %ax, %dx
--      cmpb    %cl, %dh
--      jc      res2
--      
--      movb    %cl, %dh
--      decb    %dh
--res2: cmpb    %ch, %dl
--      jc      res3
--      
--      movb    %ch, %dl
--      decb    %dl
--res3: movb    $0x02, %ah
--      movb    $0x00, %bh
--      int     $0x10
--      lodsw                                   # Display size
--      movb    %ah, %dl                        # DL=number of lines
--      movb    $0, %ah                         # BX=phys. length of orig. line
--      movw    %ax, %bx
--      cmpb    %cl, %dl                        # Too many?
--      jc      res4
--
--      pushw   %ax
--      movb    %dl, %al
--      subb    %cl, %al
--      mulb    %bl
--      addw    %ax, %si
--      addw    %ax, %si
--      popw    %ax
--      movb    %cl, %dl
--res4: cmpb    %ch, %al                        # Too wide?
--      jc      res5
--      
--      movb    %ch, %al                        # AX=width of src. line
--res5: movb    $0, %cl
--      xchgb   %ch, %cl
--      movw    %cx, %bp                        # BP=width of dest. line
--      pushw   %es
--      movw    video_segment, %es
--      xorw    %di, %di                        # Move the data
--      addw    %bx, %bx                        # Convert BX and BP to _bytes_
--      addw    %bp, %bp
--res6: pushw   %si
--      pushw   %di
--      movw    %ax, %cx
--      rep
--      movsw
--      popw    %di
--      popw    %si
--      addw    %bp, %di
--      addw    %bx, %si
--      decb    %dl
--      jnz     res6
--      
--      popw    %es                             # Done
--res1: ret
--#endif /* CONFIG_VIDEO_RETAIN */
--
--# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
--outidx:       outb    %al, %dx
--      pushw   %ax
--      movb    %ah, %al
--      incw    %dx
--      outb    %al, %dx
--      decw    %dx
--      popw    %ax
--      ret
--
--# Build the table of video modes (stored after the setup.S code at the
--# `modelist' label. Each video mode record looks like:
--#     .word   MODE-ID         (our special mode ID (see above))
--#     .byte   rows            (number of rows)
--#     .byte   columns         (number of columns)
--# Returns address of the end of the table in DI, the end is marked
--# with a ASK_VGA ID.
--mode_table:
--      movw    mt_end, %di                     # Already filled?
--      orw     %di, %di
--      jnz     mtab1x
--      
--      leaw    modelist, %di                   # Store standard modes:
--      movl    $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
--      stosl
--      movb    adapter, %al                    # CGA/MDA/HGA -- no more modes
--      orb     %al, %al
--      jz      mtabe
--      
--      decb    %al
--      jnz     mtabv
--      
--      movl    $VIDEO_8POINT + 0x502b0000, %eax        # The 80x43 EGA mode
--      stosl
--      jmp     mtabe
--
--mtab1x:       jmp     mtab1
--
--mtabv:        leaw    vga_modes, %si                  # All modes for std VGA
--      movw    $vga_modes_end-vga_modes, %cx
--      rep     # I'm unable to use movsw as I don't know how to store a half
--      movsb   # of the expression above to cx without using explicit shr.
--
--      cmpb    $0, scanning                    # Mode scan requested?
--      jz      mscan1
--      
--      call    mode_scan
--mscan1:
--
--#ifdef CONFIG_VIDEO_LOCAL
--      call    local_modes
--#endif /* CONFIG_VIDEO_LOCAL */
--
--#ifdef CONFIG_VIDEO_VESA
--      call    vesa_modes                      # Detect VESA VGA modes
--#endif /* CONFIG_VIDEO_VESA */
--
--#ifdef CONFIG_VIDEO_SVGA
--      cmpb    $0, scanning                    # Bypass when scanning
--      jnz     mscan2
--      
--      call    svga_modes                      # Detect SVGA cards & modes
--mscan2:
--#endif /* CONFIG_VIDEO_SVGA */
--
--mtabe:
--
--#ifdef CONFIG_VIDEO_COMPACT
--      leaw    modelist, %si
--      movw    %di, %dx
--      movw    %si, %di
--cmt1: cmpw    %dx, %si                        # Scan all modes
--      jz      cmt2
--
--      leaw    modelist, %bx                   # Find in previous entries
--      movw    2(%si), %cx
--cmt3: cmpw    %bx, %si
--      jz      cmt4
--
--      cmpw    2(%bx), %cx                     # Found => don't copy this entry
--      jz      cmt5
--
--      addw    $4, %bx
--      jmp     cmt3
--
--cmt4: movsl                                   # Copy entry
--      jmp     cmt1
--
--cmt5: addw    $4, %si                         # Skip entry
--      jmp     cmt1
--
--cmt2:
--#endif        /* CONFIG_VIDEO_COMPACT */
--
--      movw    $ASK_VGA, (%di)                 # End marker
--      movw    %di, mt_end
--mtab1:        leaw    modelist, %si                   # SI=mode list, DI=list end
--ret0: ret
--
--# Modes usable on all standard VGAs
--vga_modes:
--      .word   VIDEO_8POINT
--      .word   0x5032                          # 80x50
--      .word   VIDEO_80x43
--      .word   0x502b                          # 80x43
--      .word   VIDEO_80x28
--      .word   0x501c                          # 80x28
--      .word   VIDEO_80x30
--      .word   0x501e                          # 80x30
--      .word   VIDEO_80x34
--      .word   0x5022                          # 80x34
--      .word   VIDEO_80x60
--      .word   0x503c                          # 80x60
--#ifdef CONFIG_VIDEO_GFX_HACK
--      .word   VIDEO_GFX_HACK
--      .word   VIDEO_GFX_DUMMY_RESOLUTION
--#endif
--
--vga_modes_end:
--# Detect VESA modes.
--
--#ifdef CONFIG_VIDEO_VESA
--vesa_modes:
--      cmpb    $2, adapter                     # VGA only
--      jnz     ret0
--
--      movw    %di, %bp                        # BP=original mode table end
--      addw    $0x200, %di                     # Buffer space
--      movw    $0x4f00, %ax                    # VESA Get card info call
--      int     $0x10
--      movw    %bp, %di
--      cmpw    $0x004f, %ax                    # Successful?
--      jnz     ret0
--      
--      cmpw    $0x4556, 0x200(%di)
--      jnz     ret0
--      
--      cmpw    $0x4153, 0x202(%di)
--      jnz     ret0
--      
--      movw    $vesa_name, card_name           # Set name to "VESA VGA"
--      pushw   %gs
--      lgsw    0x20e(%di), %si                 # GS:SI=mode list
--      movw    $128, %cx                       # Iteration limit
--vesa1:
--# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
--# XXX:        lodsw   %gs:(%si), %ax                  # Get next mode in the list
--      gs; lodsw
--      cmpw    $0xffff, %ax                    # End of the table?
--      jz      vesar
--      
--      cmpw    $0x0080, %ax                    # Check validity of mode ID
--      jc      vesa2
--      
--      orb     %ah, %ah                # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
--      jz      vesan                   # Certain BIOSes report 0x80-0xff!
--
--      cmpw    $0x0800, %ax
--      jnc     vesae
--
--vesa2:        pushw   %cx
--      movw    %ax, %cx                        # Get mode information structure
--      movw    $0x4f01, %ax
--      int     $0x10
--      movw    %cx, %bx                        # BX=mode number
--      addb    $VIDEO_FIRST_VESA>>8, %bh
--      popw    %cx
--      cmpw    $0x004f, %ax
--      jnz     vesan                   # Don't report errors (buggy BIOSES)
--
--      movb    (%di), %al                      # Check capabilities. We require
--      andb    $0x19, %al                      # a color text mode.
--      cmpb    $0x09, %al
--      jnz     vesan
--      
--      cmpw    $0xb800, 8(%di)         # Standard video memory address required
--      jnz     vesan
--
--      testb   $2, (%di)                       # Mode characteristics supplied?
--      movw    %bx, (%di)                      # Store mode number
--      jz      vesa3
--      
--      xorw    %dx, %dx
--      movw    0x12(%di), %bx                  # Width
--      orb     %bh, %bh
--      jnz     vesan
--      
--      movb    %bl, 0x3(%di)
--      movw    0x14(%di), %ax                  # Height
--      orb     %ah, %ah
--      jnz     vesan
--      
--      movb    %al, 2(%di)
--      mulb    %bl
--      cmpw    $8193, %ax              # Small enough for Linux console driver?
--      jnc     vesan
--
--      jmp     vesaok
--
--vesa3:        subw    $0x8108, %bx    # This mode has no detailed info specified,
--      jc      vesan           # so it must be a standard VESA mode.
--
--      cmpw    $5, %bx
--      jnc     vesan
--
--      movw    vesa_text_mode_table(%bx), %ax
--      movw    %ax, 2(%di)
--vesaok:       addw    $4, %di                         # The mode is valid. Store it.
--vesan:        loop    vesa1                   # Next mode. Limit exceeded => error
--vesae:        leaw    vesaer, %si
--      call    prtstr
--      movw    %bp, %di                        # Discard already found modes.
--vesar:        popw    %gs
--      ret
--
--# Dimensions of standard VESA text modes
--vesa_text_mode_table:
--      .byte   60, 80                          # 0108
--      .byte   25, 132                         # 0109
--      .byte   43, 132                         # 010A
--      .byte   50, 132                         # 010B
--      .byte   60, 132                         # 010C
--#endif        /* CONFIG_VIDEO_VESA */
--
--# Scan for video modes. A bit dirty, but should work.
--mode_scan:
--      movw    $0x0100, %cx                    # Start with mode 0
--scm1: movb    $0, %ah                         # Test the mode
--      movb    %cl, %al
--      int     $0x10
--      movb    $0x0f, %ah
--      int     $0x10
--      cmpb    %cl, %al
--      jnz     scm2                            # Mode not set
--
--      movw    $0x3c0, %dx                     # Test if it's a text mode
--      movb    $0x10, %al                      # Mode bits
--      call    inidx
--      andb    $0x03, %al
--      jnz     scm2
--      
--      movb    $0xce, %dl                      # Another set of mode bits
--      movb    $0x06, %al
--      call    inidx
--      shrb    %al
--      jc      scm2
--      
--      movb    $0xd4, %dl                      # Cursor location
--      movb    $0x0f, %al
--      call    inidx
--      orb     %al, %al
--      jnz     scm2
--      
--      movw    %cx, %ax                        # Ok, store the mode
--      stosw
--      movb    %gs:(0x484), %al                # Number of rows
--      incb    %al
--      stosb
--      movw    %gs:(0x44a), %ax                # Number of columns
--      stosb
--scm2: incb    %cl
--      jns     scm1
--      
--      movw    $0x0003, %ax                    # Return back to mode 3
--      int     $0x10
--      ret
--
--tstidx:       outw    %ax, %dx                        # OUT DX,AX and inidx
--inidx:        outb    %al, %dx                        # Read from indexed VGA register
--      incw    %dx                     # AL=index, DX=index reg port -> AL=data
--      inb     %dx, %al
--      decw    %dx
--      ret
--
--# Try to detect type of SVGA card and supply (usually approximate) video
--# mode table for it.
--
--#ifdef CONFIG_VIDEO_SVGA
--svga_modes:
--      leaw    svga_table, %si                 # Test all known SVGA adapters
--dosvga:       lodsw
--      movw    %ax, %bp                        # Default mode table
--      orw     %ax, %ax
--      jz      didsv1
--
--      lodsw                                   # Pointer to test routine
--      pushw   %si
--      pushw   %di
--      pushw   %es
--      movw    $0xc000, %bx
--      movw    %bx, %es
--      call    *%ax                            # Call test routine
--      popw    %es
--      popw    %di
--      popw    %si
--      orw     %bp, %bp
--      jz      dosvga
--      
--      movw    %bp, %si                        # Found, copy the modes
--      movb    svga_prefix, %ah
--cpsvga:       lodsb
--      orb     %al, %al
--      jz      didsv
--      
--      stosw
--      movsw
--      jmp     cpsvga
--
--didsv:        movw    %si, card_name                  # Store pointer to card name
--didsv1:       ret
--
--# Table of all known SVGA cards. For each card, we store a pointer to
--# a table of video modes supported by the card and a pointer to a routine
--# used for testing of presence of the card. The video mode table is always
--# followed by the name of the card or the chipset.
--svga_table:
--      .word   ati_md, ati_test
--      .word   oak_md, oak_test
--      .word   paradise_md, paradise_test
--      .word   realtek_md, realtek_test
--      .word   s3_md, s3_test
--      .word   chips_md, chips_test
--      .word   video7_md, video7_test
--      .word   cirrus5_md, cirrus5_test
--      .word   cirrus6_md, cirrus6_test
--      .word   cirrus1_md, cirrus1_test
--      .word   ahead_md, ahead_test
--      .word   everex_md, everex_test
--      .word   genoa_md, genoa_test
--      .word   trident_md, trident_test
--      .word   tseng_md, tseng_test
--      .word   0
--
--# Test routines and mode tables:
--
--# S3 - The test algorithm was taken from the SuperProbe package
--# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
--s3_test:
--      movw    $0x0f35, %cx    # we store some constants in cl/ch
--      movw    $0x03d4, %dx
--      movb    $0x38, %al
--      call    inidx
--      movb    %al, %bh        # store current CRT-register 0x38
--      movw    $0x0038, %ax
--      call    outidx          # disable writing to special regs
--      movb    %cl, %al        # check whether we can write special reg 0x35
--      call    inidx
--      movb    %al, %bl        # save the current value of CRT reg 0x35
--      andb    $0xf0, %al      # clear bits 0-3
--      movb    %al, %ah
--      movb    %cl, %al        # and write it to CRT reg 0x35
--      call    outidx
--      call    inidx           # now read it back
--      andb    %ch, %al        # clear the upper 4 bits
--      jz      s3_2            # the first test failed. But we have a
--
--      movb    %bl, %ah        # second chance
--      movb    %cl, %al
--      call    outidx
--      jmp     s3_1            # do the other tests
--
--s3_2: movw    %cx, %ax        # load ah with 0xf and al with 0x35
--      orb     %bl, %ah        # set the upper 4 bits of ah with the orig value
--      call    outidx          # write ...
--      call    inidx           # ... and reread 
--      andb    %cl, %al        # turn off the upper 4 bits
--      pushw   %ax
--      movb    %bl, %ah        # restore old value in register 0x35
--      movb    %cl, %al
--      call    outidx
--      popw    %ax
--      cmpb    %ch, %al        # setting lower 4 bits was successful => bad
--      je      no_s3           # writing is allowed => this is not an S3
--
--s3_1: movw    $0x4838, %ax    # allow writing to special regs by putting
--      call    outidx          # magic number into CRT-register 0x38
--      movb    %cl, %al        # check whether we can write special reg 0x35
--      call    inidx
--      movb    %al, %bl
--      andb    $0xf0, %al
--      movb    %al, %ah
--      movb    %cl, %al
--      call    outidx
--      call    inidx
--      andb    %ch, %al
--      jnz     no_s3           # no, we can't write => no S3
--
--      movw    %cx, %ax
--      orb     %bl, %ah
--      call    outidx
--      call    inidx
--      andb    %ch, %al
--      pushw   %ax
--      movb    %bl, %ah        # restore old value in register 0x35
--      movb    %cl, %al
--      call    outidx
--      popw    %ax
--      cmpb    %ch, %al
--      jne     no_s31          # writing not possible => no S3
--      movb    $0x30, %al
--      call    inidx           # now get the S3 id ...
--      leaw    idS3, %di
--      movw    $0x10, %cx
--      repne
--      scasb
--      je      no_s31
--
--      movb    %bh, %ah
--      movb    $0x38, %al
--      jmp     s3rest
--
--no_s3:        movb    $0x35, %al      # restore CRT register 0x35
--      movb    %bl, %ah
--      call    outidx
--no_s31:       xorw    %bp, %bp        # Detection failed
--s3rest:       movb    %bh, %ah
--      movb    $0x38, %al      # restore old value of CRT register 0x38
--      jmp     outidx
--
--idS3: .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
--      .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
--
--s3_md:        .byte   0x54, 0x2b, 0x84
--      .byte   0x55, 0x19, 0x84
--      .byte   0
--      .ascii  "S3"
--      .byte   0
--
--# ATI cards.
--ati_test:
--      leaw    idati, %si
--      movw    $0x31, %di
--      movw    $0x09, %cx
--      repe
--      cmpsb
--      je      atiok
--
--      xorw    %bp, %bp
--atiok:        ret
--
--idati:        .ascii  "761295520"
--
--ati_md:       .byte   0x23, 0x19, 0x84
--      .byte   0x33, 0x2c, 0x84
--      .byte   0x22, 0x1e, 0x64
--      .byte   0x21, 0x19, 0x64
--      .byte   0x58, 0x21, 0x50
--      .byte   0x5b, 0x1e, 0x50
--      .byte   0
--      .ascii  "ATI"
--      .byte   0
--
--# AHEAD
--ahead_test:
--      movw    $0x200f, %ax
--      movw    $0x3ce, %dx
--      outw    %ax, %dx
--      incw    %dx
--      inb     %dx, %al
--      cmpb    $0x20, %al
--      je      isahed
--
--      cmpb    $0x21, %al
--      je      isahed
--      
--      xorw    %bp, %bp
--isahed:       ret
--
--ahead_md:
--      .byte   0x22, 0x2c, 0x84
--      .byte   0x23, 0x19, 0x84
--      .byte   0x24, 0x1c, 0x84
--      .byte   0x2f, 0x32, 0xa0
--      .byte   0x32, 0x22, 0x50
--      .byte   0x34, 0x42, 0x50
--      .byte   0
--      .ascii  "Ahead"
--      .byte   0
--
--# Chips & Tech.
--chips_test:
--      movw    $0x3c3, %dx
--      inb     %dx, %al
--      orb     $0x10, %al
--      outb    %al, %dx
--      movw    $0x104, %dx
--      inb     %dx, %al
--      movb    %al, %bl
--      movw    $0x3c3, %dx
--      inb     %dx, %al
--      andb    $0xef, %al
--      outb    %al, %dx
--      cmpb    $0xa5, %bl
--      je      cantok
--      
--      xorw    %bp, %bp
--cantok:       ret
--
--chips_md:
--      .byte   0x60, 0x19, 0x84
--      .byte   0x61, 0x32, 0x84
--      .byte   0
--      .ascii  "Chips & Technologies"
--      .byte   0
--
--# Cirrus Logic 5X0
--cirrus1_test:
--      movw    $0x3d4, %dx
--      movb    $0x0c, %al
--      outb    %al, %dx
--      incw    %dx
--      inb     %dx, %al
--      movb    %al, %bl
--      xorb    %al, %al
--      outb    %al, %dx
--      decw    %dx
--      movb    $0x1f, %al
--      outb    %al, %dx
--      incw    %dx
--      inb     %dx, %al
--      movb    %al, %bh
--      xorb    %ah, %ah
--      shlb    $4, %al
--      movw    %ax, %cx
--      movb    %bh, %al
--      shrb    $4, %al
--      addw    %ax, %cx
--      shlw    $8, %cx
--      addw    $6, %cx
--      movw    %cx, %ax
--      movw    $0x3c4, %dx
--      outw    %ax, %dx
--      incw    %dx
--      inb     %dx, %al
--      andb    %al, %al
--      jnz     nocirr
--      
--      movb    %bh, %al
--      outb    %al, %dx
--      inb     %dx, %al
--      cmpb    $0x01, %al
--      je      iscirr
--
--nocirr:       xorw    %bp, %bp
--iscirr: movw  $0x3d4, %dx
--      movb    %bl, %al
--      xorb    %ah, %ah
--      shlw    $8, %ax
--      addw    $0x0c, %ax
--      outw    %ax, %dx
--      ret
--
--cirrus1_md:
--      .byte   0x1f, 0x19, 0x84
--      .byte   0x20, 0x2c, 0x84
--      .byte   0x22, 0x1e, 0x84
--      .byte   0x31, 0x25, 0x64
--      .byte   0
--      .ascii  "Cirrus Logic 5X0"
--      .byte   0
--
--# Cirrus Logic 54XX
--cirrus5_test:
--      movw    $0x3c4, %dx
--      movb    $6, %al
--      call    inidx
--      movb    %al, %bl                        # BL=backup
--      movw    $6, %ax
--      call    tstidx
--      cmpb    $0x0f, %al
--      jne     c5fail
--      
--      movw    $0x1206, %ax
--      call    tstidx
--      cmpb    $0x12, %al
--      jne     c5fail
--      
--      movb    $0x1e, %al
--      call    inidx
--      movb    %al, %bh
--      movb    %bh, %ah
--      andb    $0xc0, %ah
--      movb    $0x1e, %al
--      call    tstidx
--      andb    $0x3f, %al
--      jne     c5xx
--      
--      movb    $0x1e, %al
--      movb    %bh, %ah
--      orb     $0x3f, %ah
--      call    tstidx
--      xorb    $0x3f, %al
--      andb    $0x3f, %al
--c5xx: pushf
--      movb    $0x1e, %al
--      movb    %bh, %ah
--      outw    %ax, %dx
--      popf
--      je      c5done
--
--c5fail:       xorw    %bp, %bp
--c5done:       movb    $6, %al
--      movb    %bl, %ah
--      outw    %ax, %dx
--      ret
--
--cirrus5_md:
--      .byte   0x14, 0x19, 0x84
--      .byte   0x54, 0x2b, 0x84
--      .byte   0
--      .ascii  "Cirrus Logic 54XX"
--      .byte   0
--
--# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
--# it's misidentified by the Ahead test.
--cirrus6_test:
--      movw    $0x3ce, %dx
--      movb    $0x0a, %al
--      call    inidx
--      movb    %al, %bl        # BL=backup
--      movw    $0xce0a, %ax
--      call    tstidx
--      orb     %al, %al
--      jne     c2fail
--      
--      movw    $0xec0a, %ax
--      call    tstidx
--      cmpb    $0x01, %al
--      jne     c2fail
--      
--      movb    $0xaa, %al
--      call    inidx           # 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
--      shrb    $4, %al
--      subb    $4, %al
--      jz      c6done
--      
--      decb    %al
--      jz      c6done
--      
--      subb    $2, %al
--      jz      c6done
--      
--      decb    %al
--      jz      c6done
--      
--c2fail:       xorw    %bp, %bp
--c6done:       movb    $0x0a, %al
--      movb    %bl, %ah
--      outw    %ax, %dx
--      ret
--
--cirrus6_md:
--      .byte   0
--      .ascii  "Cirrus Logic 64XX"
--      .byte   0
--
--# Everex / Trident
--everex_test:
--      movw    $0x7000, %ax
--      xorw    %bx, %bx
--      int     $0x10
--      cmpb    $0x70, %al
--      jne     noevrx
--      
--      shrw    $4, %dx
--      cmpw    $0x678, %dx
--      je      evtrid
--      
--      cmpw    $0x236, %dx
--      jne     evrxok
--
--evtrid:       leaw    trident_md, %bp
--evrxok:       ret
--
--noevrx:       xorw    %bp, %bp
--      ret
--
--everex_md:
--      .byte   0x03, 0x22, 0x50
--      .byte   0x04, 0x3c, 0x50
--      .byte   0x07, 0x2b, 0x64
--      .byte   0x08, 0x4b, 0x64
--      .byte   0x0a, 0x19, 0x84
--      .byte   0x0b, 0x2c, 0x84
--      .byte   0x16, 0x1e, 0x50
--      .byte   0x18, 0x1b, 0x64
--      .byte   0x21, 0x40, 0xa0
--      .byte   0x40, 0x1e, 0x84
--      .byte   0
--      .ascii  "Everex/Trident"
--      .byte   0
--
--# Genoa.
--genoa_test:
--      leaw    idgenoa, %si                    # Check Genoa 'clues'
--      xorw    %ax, %ax
--      movb    %es:(0x37), %al
--      movw    %ax, %di
--      movw    $0x04, %cx
--      decw    %si
--      decw    %di
--l1:   incw    %si
--      incw    %di
--      movb    (%si), %al
--      testb   %al, %al
--      jz      l2
--
--      cmpb    %es:(%di), %al
--l2:   loope   l1
--      orw     %cx, %cx
--      je      isgen
--      
--      xorw    %bp, %bp
--isgen:        ret
--
--idgenoa: .byte        0x77, 0x00, 0x99, 0x66
--
--genoa_md:
--      .byte   0x58, 0x20, 0x50
--      .byte   0x5a, 0x2a, 0x64
--      .byte   0x60, 0x19, 0x84
--      .byte   0x61, 0x1d, 0x84
--      .byte   0x62, 0x20, 0x84
--      .byte   0x63, 0x2c, 0x84
--      .byte   0x64, 0x3c, 0x84
--      .byte   0x6b, 0x4f, 0x64
--      .byte   0x72, 0x3c, 0x50
--      .byte   0x74, 0x42, 0x50
--      .byte   0x78, 0x4b, 0x64
--      .byte   0
--      .ascii  "Genoa"
--      .byte   0
--
--# OAK
--oak_test:
--      leaw    idoakvga, %si
--      movw    $0x08, %di
--      movw    $0x08, %cx
--      repe
--      cmpsb
--      je      isoak
--      
--      xorw    %bp, %bp
--isoak:        ret
--
--idoakvga: .ascii  "OAK VGA "
--
--oak_md: .byte 0x4e, 0x3c, 0x50
--      .byte   0x4f, 0x3c, 0x84
--      .byte   0x50, 0x19, 0x84
--      .byte   0x51, 0x2b, 0x84
--      .byte   0
--      .ascii  "OAK"
--      .byte   0
--
--# WD Paradise.
--paradise_test:
--      leaw    idparadise, %si
--      movw    $0x7d, %di
--      movw    $0x04, %cx
--      repe
--      cmpsb
--      je      ispara
--      
--      xorw    %bp, %bp
--ispara:       ret
--
--idparadise:   .ascii  "VGA="
--
--paradise_md:
--      .byte   0x41, 0x22, 0x50
--      .byte   0x47, 0x1c, 0x84
--      .byte   0x55, 0x19, 0x84
--      .byte   0x54, 0x2c, 0x84
--      .byte   0
--      .ascii  "Paradise"
--      .byte   0
--
--# Trident.
--trident_test:
--      movw    $0x3c4, %dx
--      movb    $0x0e, %al
--      outb    %al, %dx
--      incw    %dx
--      inb     %dx, %al
--      xchgb   %al, %ah
--      xorb    %al, %al
--      outb    %al, %dx
--      inb     %dx, %al
--      xchgb   %ah, %al
--      movb    %al, %bl        # Strange thing ... in the book this wasn't
--      andb    $0x02, %bl      # necessary but it worked on my card which
--      jz      setb2           # is a trident. Without it the screen goes
--                              # blurred ...
--      andb    $0xfd, %al
--      jmp     clrb2           
--
--setb2:        orb     $0x02, %al      
--clrb2:        outb    %al, %dx
--      andb    $0x0f, %ah
--      cmpb    $0x02, %ah
--      je      istrid
--
--      xorw    %bp, %bp
--istrid:       ret
--
--trident_md:
--      .byte   0x50, 0x1e, 0x50
--      .byte   0x51, 0x2b, 0x50
--      .byte   0x52, 0x3c, 0x50
--      .byte   0x57, 0x19, 0x84
--      .byte   0x58, 0x1e, 0x84
--      .byte   0x59, 0x2b, 0x84
--      .byte   0x5a, 0x3c, 0x84
--      .byte   0
--      .ascii  "Trident"
--      .byte   0
--
--# Tseng.
--tseng_test:
--      movw    $0x3cd, %dx
--      inb     %dx, %al        # Could things be this simple ! :-)
--      movb    %al, %bl
--      movb    $0x55, %al
--      outb    %al, %dx
--      inb     %dx, %al
--      movb    %al, %ah
--      movb    %bl, %al
--      outb    %al, %dx
--      cmpb    $0x55, %ah
--      je      istsen
--
--isnot:        xorw    %bp, %bp
--istsen:       ret
--
--tseng_md:
--      .byte   0x26, 0x3c, 0x50
--      .byte   0x2a, 0x28, 0x64
--      .byte   0x23, 0x19, 0x84
--      .byte   0x24, 0x1c, 0x84
--      .byte   0x22, 0x2c, 0x84
--      .byte   0x21, 0x3c, 0x84
--      .byte   0
--      .ascii  "Tseng"
--      .byte   0
--
--# Video7.
--video7_test:
--      movw    $0x3cc, %dx
--      inb     %dx, %al
--      movw    $0x3b4, %dx
--      andb    $0x01, %al
--      jz      even7
--
--      movw    $0x3d4, %dx
--even7:        movb    $0x0c, %al
--      outb    %al, %dx
--      incw    %dx
--      inb     %dx, %al
--      movb    %al, %bl
--      movb    $0x55, %al
--      outb    %al, %dx
--      inb     %dx, %al
--      decw    %dx
--      movb    $0x1f, %al
--      outb    %al, %dx
--      incw    %dx
--      inb     %dx, %al
--      movb    %al, %bh
--      decw    %dx
--      movb    $0x0c, %al
--      outb    %al, %dx
--      incw    %dx
--      movb    %bl, %al
--      outb    %al, %dx
--      movb    $0x55, %al
--      xorb    $0xea, %al
--      cmpb    %bh, %al
--      jne     isnot
--      
--      movb    $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
--      ret
--
--video7_md:
--      .byte   0x40, 0x2b, 0x50
--      .byte   0x43, 0x3c, 0x50
--      .byte   0x44, 0x3c, 0x64
--      .byte   0x41, 0x19, 0x84
--      .byte   0x42, 0x2c, 0x84
--      .byte   0x45, 0x1c, 0x84
--      .byte   0
--      .ascii  "Video 7"
--      .byte   0
--
--# Realtek VGA
--realtek_test:
--      leaw    idrtvga, %si
--      movw    $0x45, %di
--      movw    $0x0b, %cx
--      repe
--      cmpsb
--      je      isrt
--      
--      xorw    %bp, %bp
--isrt: ret
--
--idrtvga:      .ascii  "REALTEK VGA"
--
--realtek_md:
--      .byte   0x1a, 0x3c, 0x50
--      .byte   0x1b, 0x19, 0x84
--      .byte   0x1c, 0x1e, 0x84
--      .byte   0x1d, 0x2b, 0x84
--      .byte   0x1e, 0x3c, 0x84
--      .byte   0
--      .ascii  "REALTEK"
--      .byte   0
--
--#endif        /* CONFIG_VIDEO_SVGA */
--
--# User-defined local mode table (VGA only)
--#ifdef CONFIG_VIDEO_LOCAL
--local_modes:
--      leaw    local_mode_table, %si
--locm1:        lodsw
--      orw     %ax, %ax
--      jz      locm2
--      
--      stosw
--      movsw
--      jmp     locm1
--
--locm2:        ret
--
--# This is the table of local video modes which can be supplied manually
--# by the user. Each entry consists of mode ID (word) and dimensions
--# (byte for column count and another byte for row count). These modes
--# are placed before all SVGA and VESA modes and override them if table
--# compacting is enabled. The table must end with a zero word followed
--# by NUL-terminated video adapter name.
--local_mode_table:
--      .word   0x0100                          # Example: 40x25
--      .byte   25,40
--      .word   0
--      .ascii  "Local"
--      .byte   0
--#endif        /* CONFIG_VIDEO_LOCAL */
--
--# Read a key and return the ASCII code in al, scan code in ah
--getkey:       xorb    %ah, %ah
--      int     $0x16
--      ret
--
--# Read a key with a timeout of 30 seconds.
--# The hardware clock is used to get the time.
--getkt:        call    gettime
--      addb    $30, %al                        # Wait 30 seconds
--      cmpb    $60, %al
--      jl      lminute
--
--      subb    $60, %al
--lminute:
--      movb    %al, %cl
--again:        movb    $0x01, %ah
--      int     $0x16
--      jnz     getkey                          # key pressed, so get it
--
--      call    gettime
--      cmpb    %cl, %al
--      jne     again
--
--      movb    $0x20, %al                      # timeout, return `space'
--      ret
--
--# Flush the keyboard buffer
--flush:        movb    $0x01, %ah
--      int     $0x16
--      jz      empty
--      
--      xorb    %ah, %ah
--      int     $0x16
--      jmp     flush
--
--empty:        ret
--
--# Print hexadecimal number.
--prthw:        pushw   %ax
--      movb    %ah, %al
--      call    prthb
--      popw    %ax
--prthb:        pushw   %ax
--      shrb    $4, %al
--      call    prthn
--      popw    %ax
--      andb    $0x0f, %al
--prthn:        cmpb    $0x0a, %al
--      jc      prth1
--
--      addb    $0x07, %al
--prth1:        addb    $0x30, %al
--      jmp     prtchr
--
--# Print decimal number in al
--prtdec:       pushw   %ax
--      pushw   %cx
--      xorb    %ah, %ah
--      movb    $0x0a, %cl
--      idivb   %cl
--      cmpb    $0x09, %al
--      jbe     lt100
--
--      call    prtdec
--      jmp     skip10
--
--lt100:        addb    $0x30, %al
--      call    prtchr
--skip10:       movb    %ah, %al
--      addb    $0x30, %al
--      call    prtchr  
--      popw    %cx
--      popw    %ax
--      ret
--
--store_edid:
--#ifdef CONFIG_FIRMWARE_EDID
--      pushw   %es                             # just save all registers
--      pushw   %ax
--      pushw   %bx
--      pushw   %cx
--      pushw   %dx
--      pushw   %di
--
--      pushw   %fs
--      popw    %es
--
--      movl    $0x13131313, %eax               # memset block with 0x13
--      movw    $32, %cx
--      movw    $0x140, %di
--      cld
--      rep
--      stosl
--
--      cmpw    $0x0200, vbe_version            # only do EDID on >= VBE2.0
--      jl      no_edid
--
--      pushw   %es                             # save ES
--      xorw    %di, %di                        # Report Capability
--      pushw   %di
--      popw    %es                             # ES:DI must be 0:0
--      movw    $0x4f15, %ax
--      xorw    %bx, %bx
--      xorw    %cx, %cx
--      int     $0x10
--      popw    %es                             # restore ES
--
--      cmpb    $0x00, %ah                      # call successful
--      jne     no_edid
--
--      cmpb    $0x4f, %al                      # function supported
--      jne     no_edid
--
--      movw    $0x4f15, %ax                    # do VBE/DDC
--      movw    $0x01, %bx
--      movw    $0x00, %cx
--      movw    $0x00, %dx
--      movw    $0x140, %di
--      int     $0x10
--
--no_edid:
--      popw    %di                             # restore all registers
--      popw    %dx
--      popw    %cx
--      popw    %bx
--      popw    %ax
--      popw    %es
--#endif
--      ret
--
--# VIDEO_SELECT-only variables
--mt_end:               .word   0       # End of video mode table if built
--edit_buf:     .space  6       # Line editor buffer
--card_name:    .word   0       # Pointer to adapter name
--scanning:     .byte   0       # Performing mode scan
--do_restore:   .byte   0       # Screen contents altered during mode change
--svga_prefix:  .byte   VIDEO_FIRST_BIOS>>8     # Default prefix for BIOS modes
--graphic_mode: .byte   0       # Graphic mode with a linear frame buffer
--dac_size:     .byte   6       # DAC bit depth
--vbe_version:  .word   0       # VBE bios version
--
--# Status messages
--keymsg:               .ascii  "Press <RETURN> to see video modes available, "
--              .ascii  "<SPACE> to continue or wait 30 secs"
--              .byte   0x0d, 0x0a, 0
--
--listhdr:      .byte   0x0d, 0x0a
--              .ascii  "Mode:    COLSxROWS:"
--
--crlft:                .byte   0x0d, 0x0a, 0
--
--prompt:               .byte   0x0d, 0x0a
--              .asciz  "Enter mode number or `scan': "
--
--unknt:                .asciz  "Unknown mode ID. Try again."
--
--badmdt:               .ascii  "You passed an undefined mode number."
--              .byte   0x0d, 0x0a, 0
--
--vesaer:               .ascii  "Error: Scanning of VESA modes failed. Please "
--              .ascii  "report to <mj@ucw.cz>."
--              .byte   0x0d, 0x0a, 0
--
--old_name:     .asciz  "CGA/MDA/HGA"
--
--ega_name:     .asciz  "EGA"
--
--svga_name:    .ascii  " "
--
--vga_name:     .asciz  "VGA"
--
--vesa_name:    .asciz  "VESA"
--
--name_bann:    .asciz  "Video adapter: "
--#endif /* CONFIG_VIDEO_SELECT */
--
--# Other variables:
--adapter:      .byte   0       # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
--video_segment:        .word   0xb800  # Video memory segment
--force_size:   .word   0       # Use this size instead of the one in BIOS vars
-diff -puN /dev/null arch/i386/boot/video.c
---- /dev/null
-+++ a/arch/i386/boot/video.c
-@@ -0,0 +1,456 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/video.c
-+ *
-+ * Select video mode
-+ */
-+
-+#include "boot.h"
-+#include "video.h"
-+#include "vesa.h"
-+
-+/*
-+ * Mode list variables
-+ */
-+static struct card_info cards[];    /* List of cards to probe for */
-+
-+/*
-+ * Common variables
-+ */
-+int adapter;                  /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
-+u16 video_segment;
-+int force_x, force_y; /* Don't query the BIOS for cols/rows */
-+
-+int do_restore = 0;   /* Screen contents changed during mode flip */
-+int graphic_mode;     /* Graphic mode with linear frame buffer */
-+
-+static void store_cursor_position(void)
-+{
-+      u16 curpos;
-+      u16 ax, bx;
-+
-+      ax = 0x0300;
-+      bx = 0;
-+      asm(INT10
-+          : "=d" (curpos), "+a" (ax), "+b" (bx)
-+          : : "ecx", "esi", "edi");
-+
-+      boot_params.screen_info.orig_x = curpos;
-+      boot_params.screen_info.orig_y = curpos >> 8;
-+}
-+
-+static void store_video_mode(void)
-+{
-+      u16 ax, page;
-+
-+      /* N.B.: the saving of the video page here is a bit silly,
-+         since we pretty much assume page 0 everywhere. */
-+      ax = 0x0f00;
-+      asm(INT10
-+          : "+a" (ax), "=b" (page)
-+          : : "ecx", "edx", "esi", "edi");
-+
-+      /* Not all BIOSes are clean with respect to the top bit */
-+      boot_params.screen_info.orig_video_mode = ax & 0x7f;
-+      boot_params.screen_info.orig_video_page = page;
-+}
-+
-+/*
-+ * Store the video mode parameters for later usage by the kernel.
-+ * This is done by asking the BIOS except for the rows/columns
-+ * parameters in the default 80x25 mode -- these are set directly,
-+ * because some very obscure BIOSes supply insane values.
-+ */
-+static void store_mode_params(void)
-+{
-+      u16 font_size;
-+      int x, y;
-+
-+      /* For graphics mode, it is up to the mode-setting driver
-+         (currently only video-vesa.c) to store the parameters */
-+      if (graphic_mode)
-+              return;
-+
-+      store_cursor_position();
-+      store_video_mode();
-+
-+      if (boot_params.screen_info.orig_video_mode == 0x07) {
-+              /* MDA, HGC, or VGA in monochrome mode */
-+              video_segment = 0xb000;
-+      } else {
-+              /* CGA, EGA, VGA and so forth */
-+              video_segment = 0xb800;
-+      }
-+
-+      set_fs(0);
-+      font_size = rdfs16(0x485); /* Font size, BIOS area */
-+      boot_params.screen_info.orig_video_points = font_size;
-+
-+      x = rdfs16(0x44a);
-+      y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
-+
-+      if (force_x)
-+              x = force_x;
-+      if (force_y)
-+              y = force_y;
-+
-+      boot_params.screen_info.orig_video_cols  = x;
-+      boot_params.screen_info.orig_video_lines = y;
-+}
-+
-+/* Probe the video drivers and have them generate their mode lists. */
-+static void probe_cards(int unsafe)
-+{
-+      struct card_info *card;
-+      static u8 probed[2];
-+
-+      if (probed[unsafe])
-+              return;
-+
-+      probed[unsafe] = 1;
-+
-+      for (card = video_cards; card < video_cards_end; card++) {
-+              if (card->unsafe == unsafe) {
-+                      if (card->probe)
-+                              card->nmodes = card->probe();
-+                      else
-+                              card->nmodes = 0;
-+              }
-+      }
-+}
-+
-+/* Test if a mode is defined */
-+int mode_defined(u16 mode)
-+{
-+      struct card_info *card;
-+      struct mode_info *mi;
-+      int i;
-+
-+      for (card = video_cards; card < video_cards_end; card++) {
-+              mi = card->modes;
-+              for (i = 0; i < card->nmodes; i++, mi++) {
-+                      if (mi->mode == mode)
-+                              return 1;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
-+/* Set mode (without recalc) */
-+static int raw_set_mode(u16 mode)
-+{
-+      int nmode, i;
-+      struct card_info *card;
-+      struct mode_info *mi;
-+
-+      /* Drop the recalc bit if set */
-+      mode &= ~VIDEO_RECALC;
-+
-+      /* Scan for mode based on fixed ID, position, or resolution */
-+      nmode = 0;
-+      for (card = video_cards; card < video_cards_end; card++) {
-+              mi = card->modes;
-+              for (i = 0; i < card->nmodes; i++, mi++) {
-+                      int visible = mi->x || mi->y;
-+
-+                      if ((mode == nmode && visible) ||
-+                          mode == mi->mode ||
-+                          mode == (mi->y << 8)+mi->x)
-+                              return card->set_mode(mi);
-+
-+                      if (visible)
-+                              nmode++;
-+              }
-+      }
-+
-+      /* Nothing found?  Is it an "exceptional" (unprobed) mode? */
-+      for (card = video_cards; card < video_cards_end; card++) {
-+              if (mode >= card->xmode_first &&
-+                  mode < card->xmode_first+card->xmode_n) {
-+                      struct mode_info mix;
-+                      mix.mode = mode;
-+                      mix.x = mix.y = 0;
-+                      return card->set_mode(&mix);
-+              }
-+      }
-+
-+      /* Otherwise, failure... */
-+      return -1;
-+}
-+
-+/*
-+ * Recalculate the vertical video cutoff (hack!)
-+ */
-+static void vga_recalc_vertical(void)
-+{
-+      unsigned int font_size, rows;
-+      u16 crtc;
-+      u8 ov;
-+
-+      set_fs(0);
-+      font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
-+      rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
-+
-+      rows *= font_size;      /* Visible scan lines */
-+      rows--;                 /* ... minus one */
-+
-+      crtc = vga_crtc();
-+
-+      out_idx((u8)rows, crtc, 0x12); /* Lower height register */
-+      ov = in_idx(crtc, 0x07); /* Overflow register */
-+      ov &= 0xbd;
-+      ov |= (rows >> (8-1)) & 0x02;
-+      ov |= (rows >> (9-6)) & 0x40;
-+      out_idx(ov, crtc, 0x07);
-+}
-+
-+/* Set mode (with recalc if specified) */
-+static int set_mode(u16 mode)
-+{
-+      int rv;
-+
-+      /* Very special mode numbers... */
-+      if (mode == VIDEO_CURRENT_MODE)
-+              return 0;       /* Nothing to do... */
-+      else if (mode == NORMAL_VGA)
-+              mode = VIDEO_80x25;
-+      else if (mode == EXTENDED_VGA)
-+              mode = VIDEO_8POINT;
-+
-+      rv = raw_set_mode(mode);
-+      if (rv)
-+              return rv;
-+
-+      if (mode & VIDEO_RECALC)
-+              vga_recalc_vertical();
-+
-+      return 0;
-+}
-+
-+static unsigned int get_entry(void)
-+{
-+      char entry_buf[4];
-+      int i, len = 0;
-+      int key;
-+      unsigned int v;
-+
-+      do {
-+              key = getchar();
-+
-+              if (key == '\b') {
-+                      if (len > 0) {
-+                              puts("\b \b");
-+                              len--;
-+                      }
-+              } else if ((key >= '0' && key <= '9') ||
-+                         (key >= 'A' && key <= 'Z') ||
-+                         (key >= 'a' && key <= 'z')) {
-+                      if (len < sizeof entry_buf) {
-+                              entry_buf[len++] = key;
-+                              putchar(key);
-+                      }
-+              }
-+      } while (key != '\r');
-+      putchar('\n');
-+
-+      if (len == 0)
-+              return VIDEO_CURRENT_MODE; /* Default */
-+
-+      v = 0;
-+      for (i = 0; i < len; i++) {
-+              v <<= 4;
-+              key = entry_buf[i] | 0x20;
-+              v += (key > '9') ? key-'a'+10 : key-'0';
-+      }
-+
-+      return v;
-+}
-+
-+static void display_menu(void)
-+{
-+      struct card_info *card;
-+      struct mode_info *mi;
-+      char ch;
-+      int i;
-+
-+      puts("Mode:    COLSxROWS:\n");
-+
-+      ch = '0';
-+      for (card = video_cards; card < video_cards_end; card++) {
-+              mi = card->modes;
-+              for (i = 0; i < card->nmodes; i++, mi++) {
-+                      int visible = mi->x && mi->y;
-+                      u16 mode_id = mi->mode ? mi->mode :
-+                              (mi->y << 8)+mi->x;
-+
-+                      if (!visible)
-+                              continue; /* Hidden mode */
-+
-+                      printf("%c  %04X  %3dx%-3d  %s\n",
-+                             ch, mode_id, mi->x, mi->y, card->card_name);
-+
-+                      if (ch == '9')
-+                              ch = 'a';
-+                      else if (ch == 'z' || ch == ' ')
-+                              ch = ' '; /* Out of keys... */
-+                      else
-+                              ch++;
-+              }
-+      }
-+}
-+
-+#define H(x)  ((x)-'a'+10)
-+#define SCAN  ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
-+
-+static unsigned int mode_menu(void)
-+{
-+      int key;
-+      unsigned int sel;
-+
-+      puts("Press <ENTER> to see video modes available, "
-+           "<SPACE> to continue, or wait 30 sec\n");
-+
-+      kbd_flush();
-+      while (1) {
-+              key = getchar_timeout();
-+              if (key == ' ' || key == 0)
-+                      return VIDEO_CURRENT_MODE; /* Default */
-+              if (key == '\r')
-+                      break;
-+              putchar('\a');  /* Beep! */
-+      }
-+
-+
-+      for (;;) {
-+              display_menu();
-+
-+              puts("Enter a video mode or \"scan\" to scan for "
-+                   "additional modes: ");
-+              sel = get_entry();
-+              if (sel != SCAN)
-+                      return sel;
-+
-+              probe_cards(1);
-+      }
-+}
-+
-+#ifdef CONFIG_VIDEO_RETAIN
-+/* Save screen content to the heap */
-+struct saved_screen {
-+      int x, y;
-+      int curx, cury;
-+      u16 *data;
-+} saved;
-+
-+static void save_screen(void)
-+{
-+      /* Should be called after store_mode_params() */
-+      saved.x = boot_params.screen_info.orig_video_cols;
-+      saved.y = boot_params.screen_info.orig_video_lines;
-+      saved.curx = boot_params.screen_info.orig_x;
-+      saved.cury = boot_params.screen_info.orig_y;
-+
-+      if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
-+              return;         /* Not enough heap to save the screen */
-+
-+      saved.data = GET_HEAP(u16, saved.x*saved.y);
-+
-+      set_fs(video_segment);
-+      copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
-+}
-+
-+static void restore_screen(void)
-+{
-+      /* Should be called after store_mode_params() */
-+      int xs = boot_params.screen_info.orig_video_cols;
-+      int ys = boot_params.screen_info.orig_video_lines;
-+      int y;
-+      addr_t dst = 0;
-+      u16 *src = saved.data;
-+      u16 ax, bx, dx;
-+
-+      if (graphic_mode)
-+              return;         /* Can't restore onto a graphic mode */
-+
-+      if (!src)
-+              return;         /* No saved screen contents */
-+
-+      /* Restore screen contents */
-+
-+      set_fs(video_segment);
-+      for (y = 0; y < ys; y++) {
-+              int npad;
-+
-+              if (y < saved.y) {
-+                      int copy = (xs < saved.x) ? xs : saved.x;
-+                      copy_to_fs(dst, src, copy*sizeof(u16));
-+                      dst += copy*sizeof(u16);
-+                      src += saved.x;
-+                      npad = (xs < saved.x) ? 0 : xs-saved.x;
-+              } else {
-+                      npad = xs;
-+              }
-+
-+              /* Writes "npad" blank characters to
-+                 video_segment:dst and advances dst */
-+              asm volatile("pushw %%es ; "
-+                           "movw %2,%%es ; "
-+                           "shrw %%cx ; "
-+                           "jnc 1f ; "
-+                           "stosw \n\t"
-+                           "1: rep;stosl ; "
-+                           "popw %%es"
-+                           : "+D" (dst), "+c" (npad)
-+                           : "bdSm" (video_segment),
-+                             "a" (0x07200720));
-+      }
-+
-+      /* Restore cursor position */
-+      ax = 0x0200;            /* Set cursor position */
-+      bx = 0;                 /* Page number (<< 8) */
-+      dx = (saved.cury << 8)+saved.curx;
-+      asm volatile(INT10
-+                   : "+a" (ax), "+b" (bx), "+d" (dx)
-+                   : : "ecx", "esi", "edi");
-+}
-+#else
-+#define save_screen()         ((void)0)
-+#define restore_screen()      ((void)0)
-+#endif
-+
-+void set_video(void)
-+{
-+      u16 mode = boot_params.hdr.vid_mode;
-+
-+      RESET_HEAP();
-+
-+      store_mode_params();
-+      save_screen();
-+      probe_cards(0);
-+
-+      for (;;) {
-+              if (mode == ASK_VGA)
-+                      mode = mode_menu();
-+
-+              if (!set_mode(mode))
-+                      break;
-+
-+              printf("Undefined video mode number: %x\n", mode);
-+              mode = ASK_VGA;
-+      }
-+      vesa_store_edid();
-+      store_mode_params();
-+
-+      if (do_restore)
-+              restore_screen();
-+}
-diff -puN /dev/null arch/i386/boot/video.h
---- /dev/null
-+++ a/arch/i386/boot/video.h
-@@ -0,0 +1,145 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/video.h
-+ *
-+ * Header file for the real-mode video probing code
-+ */
-+
-+#ifndef BOOT_VIDEO_H
-+#define BOOT_VIDEO_H
-+
-+#include <linux/types.h>
-+
-+/* Enable autodetection of SVGA adapters and modes. */
-+#undef CONFIG_VIDEO_SVGA
-+
-+/* Enable autodetection of VESA modes */
-+#define CONFIG_VIDEO_VESA
-+
-+/* Retain screen contents when switching modes */
-+#define CONFIG_VIDEO_RETAIN
-+
-+/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
-+#undef CONFIG_VIDEO_400_HACK
-+
-+/* This code uses an extended set of video mode numbers. These include:
-+ * Aliases for standard modes
-+ *      NORMAL_VGA (-1)
-+ *      EXTENDED_VGA (-2)
-+ *      ASK_VGA (-3)
-+ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
-+ * of compatibility when extending the table. These are between 0x00 and 0xff.
-+ */
-+#define VIDEO_FIRST_MENU 0x0000
-+
-+/* Standard BIOS video modes (BIOS number + 0x0100) */
-+#define VIDEO_FIRST_BIOS 0x0100
-+
-+/* VESA BIOS video modes (VESA number + 0x0200) */
-+#define VIDEO_FIRST_VESA 0x0200
-+
-+/* Video7 special modes (BIOS number + 0x0900) */
-+#define VIDEO_FIRST_V7 0x0900
-+
-+/* Special video modes */
-+#define VIDEO_FIRST_SPECIAL 0x0f00
-+#define VIDEO_80x25 0x0f00
-+#define VIDEO_8POINT 0x0f01
-+#define VIDEO_80x43 0x0f02
-+#define VIDEO_80x28 0x0f03
-+#define VIDEO_CURRENT_MODE 0x0f04
-+#define VIDEO_80x30 0x0f05
-+#define VIDEO_80x34 0x0f06
-+#define VIDEO_80x60 0x0f07
-+#define VIDEO_GFX_HACK 0x0f08
-+#define VIDEO_LAST_SPECIAL 0x0f09
-+
-+/* Video modes given by resolution */
-+#define VIDEO_FIRST_RESOLUTION 0x1000
-+
-+/* The "recalculate timings" flag */
-+#define VIDEO_RECALC 0x8000
-+
-+/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
-+#ifdef CONFIG_VIDEO_RETAIN
-+void store_screen(void);
-+#define DO_STORE() store_screen()
-+#else
-+#define DO_STORE() ((void)0)
-+#endif /* CONFIG_VIDEO_RETAIN */
-+
-+/*
-+ * Mode table structures
-+ */
-+
-+struct mode_info {
-+      u16 mode;               /* Mode number (vga= style) */
-+      u8  x, y;               /* Width, height */
-+};
-+
-+struct card_info {
-+      const char *card_name;
-+      int (*set_mode)(struct mode_info *mode);
-+      int (*probe)(void);
-+      struct mode_info *modes;
-+      int nmodes;             /* Number of probed modes so far */
-+      int unsafe;             /* Probing is unsafe, only do after "scan" */
-+      u16 xmode_first;        /* Unprobed modes to try to call anyway */
-+      u16 xmode_n;            /* Size of unprobed mode range */
-+};
-+
-+#define __videocard struct card_info __attribute__((section(".videocards")))
-+extern struct card_info video_cards[], video_cards_end[];
-+
-+int mode_defined(u16 mode);   /* video.c */
-+
-+/* Basic video information */
-+#define ADAPTER_CGA   0       /* CGA/MDA/HGC */
-+#define ADAPTER_EGA   1
-+#define ADAPTER_VGA   2
-+
-+extern int adapter;
-+extern u16 video_segment;
-+extern int force_x, force_y;  /* Don't query the BIOS for cols/rows */
-+extern int do_restore;                /* Restore screen contents */
-+extern int graphic_mode;      /* Graphics mode with linear frame buffer */
-+
-+/*
-+ * int $0x10 is notorious for touching registers it shouldn't.
-+ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
-+ * sequence here.
-+ */
-+#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
-+
-+/* Accessing VGA indexed registers */
-+static inline u8 in_idx(u16 port, u8 index)
-+{
-+      outb(index, port);
-+      return inb(port+1);
-+}
-+
-+static inline void out_idx(u8 v, u16 port, u8 index)
-+{
-+      outw(index+(v << 8), port);
-+}
-+
-+/* Writes a value to an indexed port and then reads the port again */
-+static inline u8 tst_idx(u8 v, u16 port, u8 index)
-+{
-+      out_idx(port, index, v);
-+      return in_idx(port, index);
-+}
-+
-+/* Get the I/O port of the VGA CRTC */
-+u16 vga_crtc(void);           /* video-vga.c */
-+
-+#endif /* BOOT_VIDEO_H */
-diff -puN /dev/null arch/i386/boot/voyager.c
---- /dev/null
-+++ a/arch/i386/boot/voyager.c
-@@ -0,0 +1,46 @@
-+/* -*- linux-c -*- ------------------------------------------------------- *
-+ *
-+ *   Copyright (C) 1991, 1992 Linus Torvalds
-+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
-+ *
-+ *   This file is part of the Linux kernel, and is made available under
-+ *   the terms of the GNU General Public License version 2.
-+ *
-+ * ----------------------------------------------------------------------- */
-+
-+/*
-+ * arch/i386/boot/voyager.c
-+ *
-+ * Get the Voyager config information
-+ */
-+
-+#include "boot.h"
-+
-+#ifdef CONFIG_X86_VOYAGER
-+
-+int query_voyager(void)
-+{
-+      u8 err;
-+      u16 es, di;
-+      /* Abuse the apm_bios_info area for this */
-+      u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
-+
-+      data_ptr[0] = 0xff;     /* Flag on config not found(?) */
-+
-+      asm("pushw %%es ; "
-+          "int $0x15 ; "
-+          "setc %0 ; "
-+          "movw %%es, %1 ; "
-+          "popw %%es"
-+          : "=qm" (err), "=rm" (es), "=D" (di)
-+          : "a" (0xffc0));
-+
-+      if (err)
-+              return -1;      /* Not Voyager */
-+
-+      set_fs(es);
-+      copy_from_fs(data_ptr, di, 7);  /* Table is 7 bytes apparently */
-+      return 0;
-+}
-+
-+#endif /* CONFIG_X86_VOYAGER */
-diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup arch/i386/kernel/cpu/Makefile
-diff -puN /dev/null arch/i386/kernel/cpu/addon_cpuid_features.c
---- /dev/null
-+++ a/arch/i386/kernel/cpu/addon_cpuid_features.c
-@@ -0,0 +1,50 @@
-+
-+/*
-+ *    Routines to indentify additional cpu features that are scattered in
-+ *    cpuid space.
-+ */
-+
-+#include <linux/cpu.h>
-+
-+#include <asm/processor.h>
-+
-+struct cpuid_bit {
-+      u16 feature;
-+      u8 reg;
-+      u8 bit;
-+      u32 level;
-+};
-+
-+enum cpuid_regs {
-+      CR_EAX = 0,
-+      CR_ECX,
-+      CR_EDX,
-+      CR_EBX
-+};
-+
-+void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
-+{
-+      u32 max_level;
-+      u32 regs[4];
-+      const struct cpuid_bit *cb;
-+
-+      static const struct cpuid_bit cpuid_bits[] = {
-+              { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
-+              { 0, 0, 0, 0 }
-+      };
-+
-+      for (cb = cpuid_bits; cb->feature; cb++) {
-+
-+              /* Verify that the level is valid */
-+              max_level = cpuid_eax(cb->level & 0xffff0000);
-+              if (max_level < cb->level ||
-+                  max_level > (cb->level | 0xffff))
-+                      continue;
-+
-+              cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
-+                      &regs[CR_ECX], &regs[CR_EDX]);
-+
-+              if (regs[cb->reg] & (1 << cb->bit))
-+                      set_bit(cb->feature, c->x86_capability);
-+      }
-+}
-diff -puN arch/i386/kernel/cpu/common.c~git-newsetup arch/i386/kernel/cpu/common.c
---- a/arch/i386/kernel/cpu/common.c~git-newsetup
-+++ a/arch/i386/kernel/cpu/common.c
-@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(s
-                       if ( xlvl >= 0x80000004 )
-                               get_model_name(c); /* Default name */
-               }
-+
-+              init_scattered_cpuid_features(c);
-       }
-       early_intel_workaround(c);
-diff -puN arch/i386/kernel/cpu/proc.c~git-newsetup arch/i386/kernel/cpu/proc.c
---- a/arch/i386/kernel/cpu/proc.c~git-newsetup
-+++ a/arch/i386/kernel/cpu/proc.c
-@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file 
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
--              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
-+              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
-+              "3dnowext", "3dnow",
-               /* Transmeta-defined */
-               "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
-@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file 
-               /* Other (Linux-defined) */
-               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
-               NULL, NULL, NULL, NULL,
--              "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              "constant_tsc", "up", NULL, "arch_perfmon",
-+              "pebs", "bts", NULL, "sync_rdtsc",
-+              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               /* Intel-defined (#2) */
-@@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file 
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               /* AMD-defined (#2) */
--              "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
--              "sse4a", "misalignsse",
--              "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
-+              "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
-+              "altmovcr8", "abm", "sse4a",
-+              "misalignsse", "3dnowprefetch",
-+              "osvw", "ibs", NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* Auxiliary (Linux-defined) */
-+              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-       };
-diff -puN arch/i386/kernel/e820.c~git-newsetup arch/i386/kernel/e820.c
---- a/arch/i386/kernel/e820.c~git-newsetup
-+++ a/arch/i386/kernel/e820.c
-@@ -766,7 +766,7 @@ void __init print_memory_map(char *who)
-               case E820_NVS:
-                               printk("(ACPI NVS)\n");
-                               break;
--              default:        printk("type %lu\n", e820.map[i].type);
-+              default:        printk("type %u\n", e820.map[i].type);
-                               break;
-               }
-       }
-diff -puN arch/i386/kernel/setup.c~git-newsetup arch/i386/kernel/setup.c
---- a/arch/i386/kernel/setup.c~git-newsetup
-+++ a/arch/i386/kernel/setup.c
-@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
- /*
-  * Setup options
-  */
--struct drive_info_struct { char dummy[32]; } drive_info;
--#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
--    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
--EXPORT_SYMBOL(drive_info);
--#endif
- struct screen_info screen_info;
- EXPORT_SYMBOL(screen_info);
- struct apm_info apm_info;
- EXPORT_SYMBOL(apm_info);
--struct sys_desc_table_struct {
--      unsigned short length;
--      unsigned char table[0];
--};
- struct edid_info edid_info;
- EXPORT_SYMBOL_GPL(edid_info);
- struct ist_info ist_info;
-@@ -134,7 +125,7 @@ unsigned long saved_videomode;
- static char __initdata command_line[COMMAND_LINE_SIZE];
--unsigned char __initdata boot_params[PARAM_SIZE];
-+struct boot_params __initdata boot_params;
- #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
- struct edd edd;
-@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
- #endif
-       ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
--      drive_info = DRIVE_INFO;
-       screen_info = SCREEN_INFO;
-       edid_info = EDID_INFO;
-       apm_info.bios = APM_BIOS_INFO;
-diff -puN arch/i386/kernel/verify_cpu.S~git-newsetup /dev/null
---- a/arch/i386/kernel/verify_cpu.S
-+++ /dev/null
-@@ -1,94 +0,0 @@
--/* Check if CPU has some minimum CPUID bits
--   This runs in 16bit mode so that the caller can still use the BIOS
--   to output errors on the screen */
--#include <asm/cpufeature.h>
--#include <asm/msr.h>
--
--verify_cpu:
--      pushfl                          # Save caller passed flags
--      pushl   $0                      # Kill any dangerous flags
--      popfl
--
--#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
--      pushfl
--      pop     %eax
--      orl     $(1<<18),%eax           # try setting AC
--      push    %eax
--      popfl
--      pushfl
--      popl    %eax
--      testl   $(1<<18),%eax
--      jz      bad
--#endif
--#if REQUIRED_MASK1 != 0
--      pushfl                          # standard way to check for cpuid
--      popl    %eax
--      movl    %eax,%ebx
--      xorl    $0x200000,%eax
--      pushl   %eax
--      popfl
--      pushfl
--      popl    %eax
--      cmpl    %eax,%ebx
--      pushfl                          # standard way to check for cpuid
--      popl    %eax
--      movl    %eax,%ebx
--      xorl    $0x200000,%eax
--      pushl   %eax
--      popfl
--      pushfl
--      popl    %eax
--      cmpl    %eax,%ebx
--      jz      bad                     # REQUIRED_MASK1 != 0 requires CPUID
--
--      movl    $0x0,%eax               # See if cpuid 1 is implemented
--      cpuid
--      cmpl    $0x1,%eax
--      jb      bad                     # no cpuid 1
--
--#if REQUIRED_MASK1 & NEED_CMPXCHG64
--      /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
--      cmpl    $0x746e6543,%ebx        # Cent
--      jne     1f
--      cmpl    $0x48727561,%edx        # aurH
--      jne     1f
--      cmpl    $0x736c7561,%ecx        # auls
--      jne     1f
--      movl    $1,%eax                 # check model
--      cpuid
--      movl    %eax,%ebx
--      shr     $8,%ebx
--      andl    $0xf,%ebx
--      cmp     $6,%ebx                 # check family == 6
--      jne     1f
--      shr     $4,%eax
--      andl    $0xf,%eax
--      cmpl    $6,%eax                 # check model >= 6
--      jb      1f
--      # assume models >= 6 all support this MSR
--      movl    $MSR_VIA_FCR,%ecx
--      rdmsr
--      orl     $((1<<1)|(1<<7)),%eax   # enable CMPXCHG64 and PGE
--      wrmsr
--1:
--#endif
--      movl    $0x1,%eax               # Does the cpu have what it takes
--      cpuid
--
--#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
--#error        add proper model checking here
--#endif
--
--      andl    $REQUIRED_MASK1,%edx
--      xorl    $REQUIRED_MASK1,%edx
--      jnz     bad
--#endif /* REQUIRED_MASK1 */
--
--      popfl
--      xor     %eax,%eax
--      ret
--
--bad:
--      popfl
--      movl    $1,%eax
--      ret
-diff -puN arch/x86_64/Kconfig~git-newsetup arch/x86_64/Kconfig
---- a/arch/x86_64/Kconfig~git-newsetup
-+++ a/arch/x86_64/Kconfig
-@@ -453,6 +453,10 @@ config NR_CPUS
-         This is purely to save memory - each supported CPU requires
-         memory in the static kernel configuration.
-+config PHYSICAL_ALIGN
-+      hex
-+      default "0x200000"
-+
- config HOTPLUG_CPU
-       bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
-       depends on SMP && HOTPLUG && EXPERIMENTAL
-diff -puN arch/x86_64/boot/Makefile~git-newsetup arch/x86_64/boot/Makefile
---- a/arch/x86_64/boot/Makefile~git-newsetup
-+++ a/arch/x86_64/boot/Makefile
-@@ -1,135 +1,9 @@
- #
- # arch/x86_64/boot/Makefile
- #
--# This file is subject to the terms and conditions of the GNU General Public
--# License.  See the file "COPYING" in the main directory of this archive
--# for more details.
--#
--# Copyright (C) 1994 by Linus Torvalds
--#
--
--# ROOT_DEV specifies the default root-device when making the image.
--# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
--# the default of FLOPPY is used by 'build'.
--
--ROOT_DEV := CURRENT
--
--# If you want to preset the SVGA mode, uncomment the next line and
--# set SVGA_MODE to whatever number you want.
--# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
--# The number is the same as you would ordinarily press at bootup.
--
--SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
--
--# If you want the RAM disk device, define this to be the size in blocks.
--
--#RAMDISK := -DRAMDISK=512
--
--targets               := vmlinux.bin bootsect bootsect.o \
--                 setup setup.o bzImage mtools.conf
--
--EXTRA_CFLAGS := -m32
--
--hostprogs-y   := tools/build
--HOST_EXTRACFLAGS += $(LINUXINCLUDE)
--subdir-               := compressed/  #Let make clean descend in compressed/
--# ---------------------------------------------------------------------------
--
--$(obj)/bzImage: IMAGE_OFFSET := 0x100000
--$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
--$(obj)/bzImage: BUILDFLAGS   := -b
--
--quiet_cmd_image = BUILD   $@
--cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
--          $(obj)/vmlinux.bin $(ROOT_DEV) > $@
--
--$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
--                            $(obj)/vmlinux.bin $(obj)/tools/build FORCE
--      $(call if_changed,image)
--      @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
--
--$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
--      $(call if_changed,objcopy)
--
--LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
--LDFLAGS_setup  := -Ttext 0x0 -s --oformat binary -e begtext
--
--$(obj)/setup $(obj)/bootsect: %: %.o FORCE
--      $(call if_changed,ld)
--
--$(obj)/compressed/vmlinux: FORCE
--      $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
--
--# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
--FDARGS = 
--# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
--FDINITRD =
--
--image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
--
--$(obj)/mtools.conf: $(src)/mtools.conf.in
--      sed -e 's|@OBJ@|$(obj)|g' < $< > $@
--
--# This requires write access to /dev/fd0
--zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
--      MTOOLSRC=$(obj)/mtools.conf mformat a:                  ; sync
--      syslinux /dev/fd0                                       ; sync
--      echo '$(image_cmdline)' | \
--              MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
--      if [ -f '$(FDINITRD)' ] ; then \
--              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
--      fi
--      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux  ; sync
--
--# These require being root or having syslinux 2.02 or higher installed
--fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
--      dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
--      MTOOLSRC=$(obj)/mtools.conf mformat v:                  ; sync
--      syslinux $(obj)/fdimage                                 ; sync
--      echo '$(image_cmdline)' | \
--              MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
--      if [ -f '$(FDINITRD)' ] ; then \
--              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
--      fi
--      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux  ; sync
--
--fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
--      dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
--      MTOOLSRC=$(obj)/mtools.conf mformat w:                  ; sync
--      syslinux $(obj)/fdimage                                 ; sync
--      echo '$(image_cmdline)' | \
--              MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
--      if [ -f '$(FDINITRD)' ] ; then \
--              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
--      fi
--      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux  ; sync
--
--isoimage: $(BOOTIMAGE)
--      -rm -rf $(obj)/isoimage
--      mkdir $(obj)/isoimage
--      for i in lib lib64 share end ; do \
--              if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
--                      cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
--                      break ; \
--              fi ; \
--              if [ $$i = end ] ; then exit 1 ; fi ; \
--      done
--      cp $(BOOTIMAGE) $(obj)/isoimage/linux
--      echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
--      if [ -f '$(FDINITRD)' ] ; then \
--              cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
--      fi
--      mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
--              -no-emul-boot -boot-load-size 4 -boot-info-table \
--              $(obj)/isoimage
--      rm -rf $(obj)/isoimage
--
--zlilo: $(BOOTIMAGE)
--      if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
--      if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
--      cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
--      cp System.map $(INSTALL_PATH)/
--      if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
-+# The actual boot code is shared with i386 including the Makefile.
-+# So tell kbuild that we fetch the code from i386 and include the
-+# Makefile from i386 too.
--install:
--      sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
-+src := arch/i386/boot
-+include $(src)/Makefile
-diff -puN arch/x86_64/boot/bootsect.S~git-newsetup /dev/null
---- a/arch/x86_64/boot/bootsect.S
-+++ /dev/null
-@@ -1,98 +0,0 @@
--/*
-- *    bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
-- *
-- *    modified by Drew Eckhardt
-- *    modified by Bruce Evans (bde)
-- *    modified by Chris Noe (May 1999) (as86 -> gas)
-- *    gutted by H. Peter Anvin (Jan 2003)
-- *
-- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
-- * addresses must be multiplied by 16 to obtain their respective linear
-- * addresses. To avoid confusion, linear addresses are written using leading
-- * hex while segment addresses are written as segment:offset.
-- *
-- */
--
--#include <asm/boot.h>
--
--SETUPSECTS    = 4                     /* default nr of setup-sectors */
--BOOTSEG               = 0x07C0                /* original address of boot-sector */
--INITSEG               = DEF_INITSEG           /* we move boot here - out of the way */
--SETUPSEG      = DEF_SETUPSEG          /* setup starts here */
--SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
--SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
--                                      /* to be loaded */
--ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
--SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
--
--#ifndef SVGA_MODE
--#define SVGA_MODE ASK_VGA
--#endif
--
--#ifndef RAMDISK
--#define RAMDISK 0
--#endif
--
--#ifndef ROOT_RDONLY
--#define ROOT_RDONLY 1
--#endif
--
--.code16
--.text
--
--.global _start
--_start:
--
--      # Normalize the start address
--      jmpl    $BOOTSEG, $start2
--
--start2:
--      movw    %cs, %ax
--      movw    %ax, %ds
--      movw    %ax, %es
--      movw    %ax, %ss
--      movw    $0x7c00, %sp
--      sti
--      cld
--
--      movw    $bugger_off_msg, %si
--
--msg_loop:
--      lodsb
--      andb    %al, %al
--      jz      die
--      movb    $0xe, %ah
--      movw    $7, %bx
--      int     $0x10
--      jmp     msg_loop
--
--die:
--      # Allow the user to press a key, then reboot
--      xorw    %ax, %ax
--      int     $0x16
--      int     $0x19
--
--      # int 0x19 should never return.  In case it does anyway,
--      # invoke the BIOS reset code...
--      ljmp    $0xf000,$0xfff0
--
--
--bugger_off_msg:
--      .ascii  "Direct booting from floppy is no longer supported.\r\n"
--      .ascii  "Please use a boot loader program instead.\r\n"
--      .ascii  "\n"
--      .ascii  "Remove disk and press any key to reboot . . .\r\n"
--      .byte   0
--
--
--      # Kernel attributes; used by setup
--
--      .org 497
--setup_sects:  .byte SETUPSECTS
--root_flags:   .word ROOT_RDONLY
--syssize:      .word SYSSIZE
--swap_dev:     .word SWAP_DEV
--ram_size:     .word RAMDISK
--vid_mode:     .word SVGA_MODE
--root_dev:     .word ROOT_DEV
--boot_flag:    .word 0xAA55
-diff -puN arch/x86_64/boot/compressed/Makefile~git-newsetup arch/x86_64/boot/compressed/Makefile
---- a/arch/x86_64/boot/compressed/Makefile~git-newsetup
-+++ a/arch/x86_64/boot/compressed/Makefile
-@@ -7,11 +7,12 @@
- #
- targets               := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
--EXTRA_AFLAGS  := -traditional
--# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
--# -m32
--CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
-+CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
-+        -fno-strict-aliasing -fPIC -mcmodel=small \
-+         $(call cc-option, -ffreestanding) \
-+         $(call cc-option, -fno-stack-protector)
-+AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
- LDFLAGS := -m elf_x86_64
- LDFLAGS_vmlinux := -T
-diff -puN arch/x86_64/boot/compressed/head.S~git-newsetup arch/x86_64/boot/compressed/head.S
---- a/arch/x86_64/boot/compressed/head.S~git-newsetup
-+++ a/arch/x86_64/boot/compressed/head.S
-@@ -46,10 +46,10 @@ startup_32:
-  * at and where we were actually loaded at.  This can only be done
-  * with a short local call on x86.  Nothing  else will tell us what
-  * address we are running at.  The reserved chunk of the real-mode
-- * data at 0x34-0x3f are used as the stack for this calculation.
-- * Only 4 bytes are needed.
-+ * data at 0x1e4 (defined as a scratch field) are used as the stack
-+ * for this calculation. Only 4 bytes are needed.
-  */
--      leal    0x40(%esi), %esp
-+      leal    (0x1e4+4)(%esi), %esp
-       call    1f
- 1:    popl    %ebp
-       subl    $1b, %ebp
-diff -puN arch/x86_64/boot/install.sh~git-newsetup /dev/null
---- a/arch/x86_64/boot/install.sh
-+++ /dev/null
-@@ -1,2 +0,0 @@
--#!/bin/sh
--. $srctree/arch/i386/boot/install.sh
-diff -puN arch/x86_64/boot/mtools.conf.in~git-newsetup /dev/null
---- a/arch/x86_64/boot/mtools.conf.in
-+++ /dev/null
-@@ -1,17 +0,0 @@
--#
--# mtools configuration file for "make (b)zdisk"
--#
--
--# Actual floppy drive
--drive a:
--  file="/dev/fd0"
--
--# 1.44 MB floppy disk image
--drive v:
--  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
--
--# 2.88 MB floppy disk image (mostly for virtual uses)
--drive w:
--  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
--
--
-diff -puN arch/x86_64/boot/setup.S~git-newsetup /dev/null
---- a/arch/x86_64/boot/setup.S
-+++ /dev/null
-@@ -1,826 +0,0 @@
--/*
-- *    setup.S         Copyright (C) 1991, 1992 Linus Torvalds
-- *
-- * setup.s is responsible for getting the system data from the BIOS,
-- * and putting them into the appropriate places in system memory.
-- * both setup.s and system has been loaded by the bootblock.
-- *
-- * This code asks the bios for memory/disk/other parameters, and
-- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
-- * boot-block used to be. It is then up to the protected mode
-- * system to read them from there before the area is overwritten
-- * for buffer-blocks.
-- *
-- * Move PS/2 aux init code to psaux.c
-- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
-- *
-- * some changes and additional features by Christoph Niemann,
-- * March 1993/June 1994 (Christoph.Niemann@linux.org)
-- *
-- * add APM BIOS checking by Stephen Rothwell, May 1994
-- * (sfr@canb.auug.org.au)
-- *
-- * High load stuff, initrd support and position independency
-- * by Hans Lermen & Werner Almesberger, February 1996
-- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
-- *
-- * Video handling moved to video.S by Martin Mares, March 1996
-- * <mj@k332.feld.cvut.cz>
-- *
-- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
-- * parsons) to avoid loadlin confusion, July 1997
-- *
-- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
-- * <stiker@northlink.com>
-- *
-- * Fix to work around buggy BIOSes which don't use carry bit correctly
-- * and/or report extended memory in CX/DX for e801h memory size detection 
-- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
-- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
-- * anyway.  So to avoid breaking many machines (presumably there was a reason
-- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
-- * if CX/DX have been changed in the e801 call and if so use AX/BX .
-- * Michael Miller, April 2001 <michaelm@mjmm.org>
-- *
-- * Added long mode checking and SSE force. March 2003, Andi Kleen.            
-- */
--
--#include <asm/segment.h>
--#include <linux/utsrelease.h>
--#include <linux/compile.h>
--#include <asm/boot.h>
--#include <asm/e820.h>
--#include <asm/page.h>
--#include <asm/setup.h>
--
--/* Signature words to ensure LILO loaded us right */
--#define SIG1  0xAA55
--#define SIG2  0x5A5A
--
--INITSEG  = DEF_INITSEG                # 0x9000, we move boot here, out of the way
--SYSSEG   = DEF_SYSSEG         # 0x1000, system loaded at 0x10000 (65536).
--SETUPSEG = DEF_SETUPSEG               # 0x9020, this is the current segment
--                              # ... and the former contents of CS
--
--DELTA_INITSEG = SETUPSEG - INITSEG    # 0x0020
--
--.code16
--.globl begtext, begdata, begbss, endtext, enddata, endbss
--
--.text
--begtext:
--.data
--begdata:
--.bss
--begbss:
--.text
--
--start:
--      jmp     trampoline
--
--# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
--
--              .ascii  "HdrS"          # header signature
--              .word   0x0206          # header version number (>= 0x0105)
--                                      # or else old loadlin-1.5 will fail)
--realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
--start_sys_seg:        .word   SYSSEG
--              .word   kernel_version  # pointing to kernel version string
--                                      # above section of header is compatible
--                                      # with loadlin-1.5 (header v1.5). Don't
--                                      # change it.
--
--type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
--                                      #      Bootlin, SYSLX, bootsect...)
--                                      # See Documentation/i386/boot.txt for
--                                      # assigned ids
--      
--# flags, unused bits must be zero (RFU) bit within loadflags
--loadflags:
--LOADED_HIGH   = 1                     # If set, the kernel is loaded high
--CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
--                                      # heap_end_ptr to tell how much
--                                      # space behind setup.S can be used for
--                                      # heap purposes.
--                                      # Only the loader knows what is free
--#ifndef __BIG_KERNEL__
--              .byte   0
--#else
--              .byte   LOADED_HIGH
--#endif
--
--setup_move_size: .word  0x8000                # size to move, when setup is not
--                                      # loaded at 0x90000. We will move setup 
--                                      # to 0x90000 then just before jumping
--                                      # into the kernel. However, only the
--                                      # loader knows how much data behind
--                                      # us also needs to be loaded.
--
--code32_start:                         # here loaders can put a different
--                                      # start address for 32-bit code.
--#ifndef __BIG_KERNEL__
--              .long   0x1000          #   0x1000 = default for zImage
--#else
--              .long   0x100000        # 0x100000 = default for big kernel
--#endif
--
--ramdisk_image:        .long   0               # address of loaded ramdisk image
--                                      # Here the loader puts the 32-bit
--                                      # address where it loaded the image.
--                                      # This only will be read by the kernel.
--
--ramdisk_size: .long   0               # its size in bytes
--
--bootsect_kludge:
--              .long   0               # obsolete
--
--heap_end_ptr: .word   modelist+1024   # (Header version 0x0201 or later)
--                                      # space from here (exclusive) down to
--                                      # end of setup code can be used by setup
--                                      # for local heap purposes.
--
--pad1:         .word   0
--cmd_line_ptr: .long 0                 # (Header version 0x0202 or later)
--                                      # If nonzero, a 32-bit pointer
--                                      # to the kernel command line.
--                                      # The command line should be
--                                      # located between the start of
--                                      # setup and the end of low
--                                      # memory (0xa0000), or it may
--                                      # get overwritten before it
--                                      # gets read.  If this field is
--                                      # used, there is no longer
--                                      # anything magical about the
--                                      # 0x90000 segment; the setup
--                                      # can be located anywhere in
--                                      # low memory 0x10000 or higher.
--
--ramdisk_max:  .long 0xffffffff
--kernel_alignment:  .long 0x200000       # physical addr alignment required for
--                                      # protected mode relocatable kernel
--#ifdef CONFIG_RELOCATABLE
--relocatable_kernel:    .byte 1
--#else
--relocatable_kernel:    .byte 0
--#endif
--pad2:                  .byte 0
--pad3:                  .word 0
--
--cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
--                                                #added with boot protocol
--                                                #version 2.06
--
--trampoline:   call    start_of_setup
--              .align 16
--                                      # The offset at this point is 0x240
--              .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
--# End of setup header #####################################################
--
--start_of_setup:
--# Bootlin depends on this being done early
--      movw    $0x01500, %ax
--      movb    $0x81, %dl
--      int     $0x13
--
--#ifdef SAFE_RESET_DISK_CONTROLLER
--# Reset the disk controller.
--      movw    $0x0000, %ax
--      movb    $0x80, %dl
--      int     $0x13
--#endif
--
--# Set %ds = %cs, we know that SETUPSEG = %cs at this point
--      movw    %cs, %ax                # aka SETUPSEG
--      movw    %ax, %ds
--# Check signature at end of setup
--      cmpw    $SIG1, setup_sig1
--      jne     bad_sig
--
--      cmpw    $SIG2, setup_sig2
--      jne     bad_sig
--
--      jmp     good_sig1
--
--# Routine to print asciiz string at ds:si
--prtstr:
--      lodsb
--      andb    %al, %al
--      jz      fin
--
--      call    prtchr
--      jmp     prtstr
--
--fin:  ret
--
--# Space printing
--prtsp2:       call    prtspc          # Print double space
--prtspc:       movb    $0x20, %al      # Print single space (note: fall-thru)
--
--prtchr:       
--      pushw   %ax
--      pushw   %cx
--      movw    $0007,%bx
--      movw    $0x01, %cx
--      movb    $0x0e, %ah
--      int     $0x10
--      popw    %cx
--      popw    %ax
--      ret
--
--beep: movb    $0x07, %al
--      jmp     prtchr
--      
--no_sig_mess: .string  "No setup signature found ..."
--
--good_sig1:
--      jmp     good_sig
--
--# We now have to find the rest of the setup code/data
--bad_sig:
--      movw    %cs, %ax                        # SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # INITSEG
--      movw    %ax, %ds
--      xorb    %bh, %bh
--      movb    (497), %bl                      # get setup sect from bootsect
--      subw    $4, %bx                         # LILO loads 4 sectors of setup
--      shlw    $8, %bx                         # convert to words (1sect=2^8 words)
--      movw    %bx, %cx
--      shrw    $3, %bx                         # convert to segment
--      addw    $SYSSEG, %bx
--      movw    %bx, %cs:start_sys_seg
--# Move rest of setup code/data to here
--      movw    $2048, %di                      # four sectors loaded by LILO
--      subw    %si, %si
--      movw    %cs, %ax                        # aka SETUPSEG
--      movw    %ax, %es
--      movw    $SYSSEG, %ax
--      movw    %ax, %ds
--      rep
--      movsw
--      movw    %cs, %ax                        # aka SETUPSEG
--      movw    %ax, %ds
--      cmpw    $SIG1, setup_sig1
--      jne     no_sig
--
--      cmpw    $SIG2, setup_sig2
--      jne     no_sig
--
--      jmp     good_sig
--
--no_sig:
--      lea     no_sig_mess, %si
--      call    prtstr
--
--no_sig_loop:
--      jmp     no_sig_loop
--
--good_sig:
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %ds
--# Check if an old loader tries to load a big-kernel
--      testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
--      jz      loader_ok                       # No, no danger for old loaders.
--
--      cmpb    $0, %cs:type_of_loader          # Do we have a loader that
--                                              # can deal with us?
--      jnz     loader_ok                       # Yes, continue.
--
--      pushw   %cs                             # No, we have an old loader,
--      popw    %ds                             # die. 
--      lea     loader_panic_mess, %si
--      call    prtstr
--
--      jmp     no_sig_loop
--
--loader_panic_mess: .string "Wrong loader, giving up..."
--
--loader_ok:
--      /* check for long mode. */
--      /* we have to do this before the VESA setup, otherwise the user
--         can't see the error message. */
--      
--      pushw   %ds
--      movw    %cs,%ax
--      movw    %ax,%ds
--      
--      call verify_cpu
--      testl %eax,%eax
--      jz sse_ok
--
--no_longmode:
--      call    beep
--      lea     long_mode_panic,%si
--      call    prtstr
--no_longmode_loop:             
--      jmp     no_longmode_loop
--long_mode_panic:
--      .string "Your CPU does not support long mode. Use a 32bit distribution."
--      .byte 0
--
--#include "../kernel/verify_cpu.S"
--sse_ok:
--      popw    %ds
--      
--# tell BIOS we want to go to long mode
--      movl  $0xec00,%eax      # declare target operating mode
--      movl  $2,%ebx           # long mode
--      int $0x15                       
--      
--# Get memory size (extended mem, kB)
--
--      xorl    %eax, %eax
--      movl    %eax, (0x1e0)
--#ifndef STANDARD_MEMORY_BIOS_CALL
--      movb    %al, (E820NR)
--# Try three different memory detection schemes.  First, try
--# e820h, which lets us assemble a memory map, then try e801h,
--# which returns a 32-bit memory size, and finally 88h, which
--# returns 0-64m
--
--# method E820H:
--# the memory map from hell.  e820h returns memory classified into
--# a whole bunch of different types, and allows memory holes and
--# everything.  We scan through this memory map and build a list
--# of the first 32 memory areas, which we return at [E820MAP].
--# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
--
--#define SMAP  0x534d4150
--
--meme820:
--      xorl    %ebx, %ebx                      # continuation counter
--      movw    $E820MAP, %di                   # point into the whitelist
--                                              # so we can have the bios
--                                              # directly write into it.
--
--jmpe820:
--      movl    $0x0000e820, %eax               # e820, upper word zeroed
--      movl    $SMAP, %edx                     # ascii 'SMAP'
--      movl    $20, %ecx                       # size of the e820rec
--      pushw   %ds                             # data record.
--      popw    %es
--      int     $0x15                           # make the call
--      jc      bail820                         # fall to e801 if it fails
--
--      cmpl    $SMAP, %eax                     # check the return is `SMAP'
--      jne     bail820                         # fall to e801 if it fails
--
--#     cmpl    $1, 16(%di)                     # is this usable memory?
--#     jne     again820
--
--      # If this is usable memory, we save it by simply advancing %di by
--      # sizeof(e820rec).
--      #
--good820:
--      movb    (E820NR), %al                   # up to 128 entries
--      cmpb    $E820MAX, %al
--      jae     bail820
--
--      incb    (E820NR)
--      movw    %di, %ax
--      addw    $20, %ax
--      movw    %ax, %di
--again820:
--      cmpl    $0, %ebx                        # check to see if
--      jne     jmpe820                         # %ebx is set to EOF
--bail820:
--
--
--# method E801H:
--# memory size is in 1k chunksizes, to avoid confusing loadlin.
--# we store the 0xe801 memory size in a completely different place,
--# because it will most likely be longer than 16 bits.
--# (use 1e0 because that's what Larry Augustine uses in his
--# alternative new memory detection scheme, and it's sensible
--# to write everything into the same place.)
--
--meme801:
--      stc                                     # fix to work around buggy
--      xorw    %cx,%cx                         # BIOSes which don't clear/set
--      xorw    %dx,%dx                         # carry on pass/error of
--                                              # e801h memory size call
--                                              # or merely pass cx,dx though
--                                              # without changing them.
--      movw    $0xe801, %ax
--      int     $0x15
--      jc      mem88
--
--      cmpw    $0x0, %cx                       # Kludge to handle BIOSes
--      jne     e801usecxdx                     # which report their extended
--      cmpw    $0x0, %dx                       # memory in AX/BX rather than
--      jne     e801usecxdx                     # CX/DX.  The spec I have read
--      movw    %ax, %cx                        # seems to indicate AX/BX 
--      movw    %bx, %dx                        # are more reasonable anyway...
--
--e801usecxdx:
--      andl    $0xffff, %edx                   # clear sign extend
--      shll    $6, %edx                        # and go from 64k to 1k chunks
--      movl    %edx, (0x1e0)                   # store extended memory size
--      andl    $0xffff, %ecx                   # clear sign extend
--      addl    %ecx, (0x1e0)                   # and add lower memory into
--                                              # total size.
--
--# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
--# 64mb, depending on the bios) in ax.
--mem88:
--
--#endif
--      movb    $0x88, %ah
--      int     $0x15
--      movw    %ax, (2)
--
--# Set the keyboard repeat rate to the max
--      movw    $0x0305, %ax
--      xorw    %bx, %bx
--      int     $0x16
--
--# Check for video adapter and its parameters and allow the
--# user to browse video modes.
--      call    video                           # NOTE: we need %ds pointing
--                                              # to bootsector
--
--# Get hd0 data...
--      xorw    %ax, %ax
--      movw    %ax, %ds
--      ldsw    (4 * 0x41), %si
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      pushw   %ax
--      movw    %ax, %es
--      movw    $0x0080, %di
--      movw    $0x10, %cx
--      pushw   %cx
--      cld
--      rep
--      movsb
--# Get hd1 data...
--      xorw    %ax, %ax
--      movw    %ax, %ds
--      ldsw    (4 * 0x46), %si
--      popw    %cx
--      popw    %es
--      movw    $0x0090, %di
--      rep
--      movsb
--# Check that there IS a hd1 :-)
--      movw    $0x01500, %ax
--      movb    $0x81, %dl
--      int     $0x13
--      jc      no_disk1
--      
--      cmpb    $3, %ah
--      je      is_disk1
--
--no_disk1:
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %es
--      movw    $0x0090, %di
--      movw    $0x10, %cx
--      xorw    %ax, %ax
--      cld
--      rep
--      stosb
--is_disk1:
--
--# Check for PS/2 pointing device
--      movw    %cs, %ax                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ax, %ds
--      movb    $0, (0x1ff)                     # default is no pointing device
--      int     $0x11                           # int 0x11: equipment list
--      testb   $0x04, %al                      # check if mouse installed
--      jz      no_psmouse
--
--      movb    $0xAA, (0x1ff)                  # device present
--no_psmouse:
--
--#include "../../i386/boot/edd.S"
--
--# Now we want to move to protected mode ...
--      cmpw    $0, %cs:realmode_swtch
--      jz      rmodeswtch_normal
--
--      lcall   *%cs:realmode_swtch
--
--      jmp     rmodeswtch_end
--
--rmodeswtch_normal:
--        pushw %cs
--      call    default_switch
--
--rmodeswtch_end:
--# we get the code32 start address and modify the below 'jmpi'
--# (loader may have changed it)
--      movl    %cs:code32_start, %eax
--      movl    %eax, %cs:code32
--
--# Now we move the system to its rightful place ... but we check if we have a
--# big-kernel. In that case we *must* not move it ...
--      testb   $LOADED_HIGH, %cs:loadflags
--      jz      do_move0                        # .. then we have a normal low
--                                              # loaded zImage
--                                              # .. or else we have a high
--                                              # loaded bzImage
--      jmp     end_move                        # ... and we skip moving
--
--do_move0:
--      movw    $0x100, %ax                     # start of destination segment
--      movw    %cs, %bp                        # aka SETUPSEG
--      subw    $DELTA_INITSEG, %bp             # aka INITSEG
--      movw    %cs:start_sys_seg, %bx          # start of source segment
--      cld
--do_move:
--      movw    %ax, %es                        # destination segment
--      incb    %ah                             # instead of add ax,#0x100
--      movw    %bx, %ds                        # source segment
--      addw    $0x100, %bx
--      subw    %di, %di
--      subw    %si, %si
--      movw    $0x800, %cx
--      rep
--      movsw
--      cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
--                                              # so we will perhaps read one
--                                              # page more than needed, but
--                                              # never overwrite INITSEG
--                                              # because destination is a
--                                              # minimum one page below source
--      jb      do_move
--
--end_move:
--# then we load the segment descriptors
--      movw    %cs, %ax                        # aka SETUPSEG
--      movw    %ax, %ds
--              
--# Check whether we need to be downward compatible with version <=201
--      cmpl    $0, cmd_line_ptr
--      jne     end_move_self           # loader uses version >=202 features
--      cmpb    $0x20, type_of_loader
--      je      end_move_self           # bootsect loader, we know of it
--
--# Boot loader doesnt support boot protocol version 2.02.
--# If we have our code not at 0x90000, we need to move it there now.
--# We also then need to move the params behind it (commandline)
--# Because we would overwrite the code on the current IP, we move
--# it in two steps, jumping high after the first one.
--      movw    %cs, %ax
--      cmpw    $SETUPSEG, %ax
--      je      end_move_self
--
--      cli                                     # make sure we really have
--                                              # interrupts disabled !
--                                              # because after this the stack
--                                              # should not be used
--      subw    $DELTA_INITSEG, %ax             # aka INITSEG
--      movw    %ss, %dx
--      cmpw    %ax, %dx
--      jb      move_self_1
--
--      addw    $INITSEG, %dx
--      subw    %ax, %dx                        # this will go into %ss after
--                                              # the move
--move_self_1:
--      movw    %ax, %ds
--      movw    $INITSEG, %ax                   # real INITSEG
--      movw    %ax, %es
--      movw    %cs:setup_move_size, %cx
--      std                                     # we have to move up, so we use
--                                              # direction down because the
--                                              # areas may overlap
--      movw    %cx, %di
--      decw    %di
--      movw    %di, %si
--      subw    $move_self_here+0x200, %cx
--      rep
--      movsb
--      ljmp    $SETUPSEG, $move_self_here
--
--move_self_here:
--      movw    $move_self_here+0x200, %cx
--      rep
--      movsb
--      movw    $SETUPSEG, %ax
--      movw    %ax, %ds
--      movw    %dx, %ss
--end_move_self:                                        # now we are at the right place
--      lidt    idt_48                          # load idt with 0,0
--      xorl    %eax, %eax                      # Compute gdt_base
--      movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
--      shll    $4, %eax
--      addl    $gdt, %eax
--      movl    %eax, (gdt_48+2)
--      lgdt    gdt_48                          # load gdt with whatever is
--                                              # appropriate
--
--# that was painless, now we enable a20
--      call    empty_8042
--
--      movb    $0xD1, %al                      # command write
--      outb    %al, $0x64
--      call    empty_8042
--
--      movb    $0xDF, %al                      # A20 on
--      outb    %al, $0x60
--      call    empty_8042
--
--#
--#     You must preserve the other bits here. Otherwise embarrasing things
--#     like laptops powering off on boot happen. Corrected version by Kira
--#     Brown from Linux 2.2
--#
--      inb     $0x92, %al                      # 
--      orb     $02, %al                        # "fast A20" version
--      outb    %al, $0x92                      # some chips have only this
--
--# wait until a20 really *is* enabled; it can take a fair amount of
--# time on certain systems; Toshiba Tecras are known to have this
--# problem.  The memory location used here (0x200) is the int 0x80
--# vector, which should be safe to use.
--
--      xorw    %ax, %ax                        # segment 0x0000
--      movw    %ax, %fs
--      decw    %ax                             # segment 0xffff (HMA)
--      movw    %ax, %gs
--a20_wait:
--      incw    %ax                             # unused memory location <0xfff0
--      movw    %ax, %fs:(0x200)                # we use the "int 0x80" vector
--      cmpw    %gs:(0x210), %ax                # and its corresponding HMA addr
--      je      a20_wait                        # loop until no longer aliased
--
--# make sure any possible coprocessor is properly reset..
--      xorw    %ax, %ax
--      outb    %al, $0xf0
--      call    delay
--
--      outb    %al, $0xf1
--      call    delay
--
--# well, that went ok, I hope. Now we mask all interrupts - the rest
--# is done in init_IRQ().
--      movb    $0xFF, %al                      # mask all interrupts for now
--      outb    %al, $0xA1
--      call    delay
--      
--      movb    $0xFB, %al                      # mask all irq's but irq2 which
--      outb    %al, $0x21                      # is cascaded
--
--# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
--# need no steenking BIOS anyway (except for the initial loading :-).
--# The BIOS-routine wants lots of unnecessary data, and it's less
--# "interesting" anyway. This is how REAL programmers do it.
--#
--# Well, now's the time to actually move into protected mode. To make
--# things as simple as possible, we do no register set-up or anything,
--# we let the gnu-compiled 32-bit programs do that. We just jump to
--# absolute address 0x1000 (or the loader supplied one),
--# in 32-bit protected mode.
--#
--# Note that the short jump isn't strictly needed, although there are
--# reasons why it might be a good idea. It won't hurt in any case.
--      movw    $1, %ax                         # protected mode (PE) bit
--      lmsw    %ax                             # This is it!
--      jmp     flush_instr
--
--flush_instr:
--      xorw    %bx, %bx                        # Flag to indicate a boot
--      xorl    %esi, %esi                      # Pointer to real-mode code
--      movw    %cs, %si
--      subw    $DELTA_INITSEG, %si
--      shll    $4, %esi                        # Convert to 32-bit pointer
--# NOTE: For high loaded big kernels we need a
--#     jmpi    0x100000,__KERNEL_CS
--#
--#     but we yet haven't reloaded the CS register, so the default size 
--#     of the target offset still is 16 bit.
--#     However, using an operand prefix (0x66), the CPU will properly
--#     take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
--#     Manual, Mixing 16-bit and 32-bit code, page 16-6)
--
--      .byte 0x66, 0xea                        # prefix + jmpi-opcode
--code32:       .long   0x1000                          # will be set to 0x100000
--                                              # for big kernels
--      .word   __KERNEL_CS
--
--# Here's a bunch of information about your current kernel..
--kernel_version:       .ascii  UTS_RELEASE
--              .ascii  " ("
--              .ascii  LINUX_COMPILE_BY
--              .ascii  "@"
--              .ascii  LINUX_COMPILE_HOST
--              .ascii  ") "
--              .ascii  UTS_VERSION
--              .byte   0
--
--# This is the default real mode switch routine.
--# to be called just before protected mode transition
--default_switch:
--      cli                                     # no interrupts allowed !
--      movb    $0x80, %al                      # disable NMI for bootup
--                                              # sequence
--      outb    %al, $0x70
--      lret
--
--
--# This routine checks that the keyboard command queue is empty
--# (after emptying the output buffers)
--#
--# Some machines have delusions that the keyboard buffer is always full
--# with no keyboard attached...
--#
--# If there is no keyboard controller, we will usually get 0xff
--# to all the reads.  With each IO taking a microsecond and
--# a timeout of 100,000 iterations, this can take about half a
--# second ("delay" == outb to port 0x80). That should be ok,
--# and should also be plenty of time for a real keyboard controller
--# to empty.
--#
--
--empty_8042:
--      pushl   %ecx
--      movl    $100000, %ecx
--
--empty_8042_loop:
--      decl    %ecx
--      jz      empty_8042_end_loop
--
--      call    delay
--
--      inb     $0x64, %al                      # 8042 status port
--      testb   $1, %al                         # output buffer?
--      jz      no_output
--
--      call    delay
--      inb     $0x60, %al                      # read it
--      jmp     empty_8042_loop
--
--no_output:
--      testb   $2, %al                         # is input buffer full?
--      jnz     empty_8042_loop                 # yes - loop
--empty_8042_end_loop:
--      popl    %ecx
--      ret
--
--# Read the cmos clock. Return the seconds in al
--gettime:
--      pushw   %cx
--      movb    $0x02, %ah
--      int     $0x1a
--      movb    %dh, %al                        # %dh contains the seconds
--      andb    $0x0f, %al
--      movb    %dh, %ah
--      movb    $0x04, %cl
--      shrb    %cl, %ah
--      aad
--      popw    %cx
--      ret
--
--# Delay is needed after doing I/O
--delay:
--      outb    %al,$0x80
--      ret
--
--# Descriptor tables
--gdt:
--      .word   0, 0, 0, 0                      # dummy
--
--      .word   0, 0, 0, 0                      # unused
--
--      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
--      .word   0                               # base address = 0
--      .word   0x9A00                          # code read/exec
--      .word   0x00CF                          # granularity = 4096, 386
--                                              #  (+5th nibble of limit)
--
--      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
--      .word   0                               # base address = 0
--      .word   0x9200                          # data read/write
--      .word   0x00CF                          # granularity = 4096, 386
--                                              #  (+5th nibble of limit)
--gdt_end:
--idt_48:
--      .word   0                               # idt limit = 0
--      .word   0, 0                            # idt base = 0L
--gdt_48:
--      .word   gdt_end-gdt-1                   # gdt limit
--      .word   0, 0                            # gdt base (filled in later)
--
--# Include video setup & detection code
--
--#include "../../i386/boot/video.S"
--
--# Setup signature -- must be last
--setup_sig1:   .word   SIG1
--setup_sig2:   .word   SIG2
--
--# After this point, there is some free space which is used by the video mode
--# handling code to store the temporary mode table (not used by the kernel).
--
--modelist:
--
--.text
--endtext:
--.data
--enddata:
--.bss
--endbss:
-diff -puN arch/x86_64/boot/tools/build.c~git-newsetup /dev/null
---- a/arch/x86_64/boot/tools/build.c
-+++ /dev/null
-@@ -1,185 +0,0 @@
--/*
-- *  Copyright (C) 1991, 1992  Linus Torvalds
-- *  Copyright (C) 1997 Martin Mares
-- */
--
--/*
-- * This file builds a disk-image from three different files:
-- *
-- * - bootsect: compatibility mbr which prints an error message if
-- *             someone tries to boot the kernel directly.
-- * - setup: 8086 machine code, sets up system parm
-- * - system: 80386 code for actual system
-- *
-- * It does some checking that all files are of the correct type, and
-- * just writes the result to stdout, removing headers and padding to
-- * the right amount. It also writes some system data to stderr.
-- */
--
--/*
-- * Changes by tytso to allow root device specification
-- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
-- * Cross compiling fixes by Gertjan van Wingerde, July 1996
-- * Rewritten by Martin Mares, April 1997
-- */
--
--#include <stdio.h>
--#include <string.h>
--#include <stdlib.h>
--#include <stdarg.h>
--#include <sys/types.h>
--#include <sys/stat.h>
--#include <sys/sysmacros.h>
--#include <unistd.h>
--#include <fcntl.h>
--#include <asm/boot.h>
--
--typedef unsigned char byte;
--typedef unsigned short word;
--typedef unsigned long u32;
--
--#define DEFAULT_MAJOR_ROOT 0
--#define DEFAULT_MINOR_ROOT 0
--
--/* Minimal number of setup sectors (see also bootsect.S) */
--#define SETUP_SECTS 4
--
--byte buf[1024];
--int fd;
--int is_big_kernel;
--
--void die(const char * str, ...)
--{
--      va_list args;
--      va_start(args, str);
--      vfprintf(stderr, str, args);
--      fputc('\n', stderr);
--      exit(1);
--}
--
--void file_open(const char *name)
--{
--      if ((fd = open(name, O_RDONLY, 0)) < 0)
--              die("Unable to open `%s': %m", name);
--}
--
--void usage(void)
--{
--      die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
--}
--
--int main(int argc, char ** argv)
--{
--      unsigned int i, c, sz, setup_sectors;
--      u32 sys_size;
--      byte major_root, minor_root;
--      struct stat sb;
--
--      if (argc > 2 && !strcmp(argv[1], "-b"))
--        {
--          is_big_kernel = 1;
--          argc--, argv++;
--        }
--      if ((argc < 4) || (argc > 5))
--              usage();
--      if (argc > 4) {
--              if (!strcmp(argv[4], "CURRENT")) {
--                      if (stat("/", &sb)) {
--                              perror("/");
--                              die("Couldn't stat /");
--                      }
--                      major_root = major(sb.st_dev);
--                      minor_root = minor(sb.st_dev);
--              } else if (strcmp(argv[4], "FLOPPY")) {
--                      if (stat(argv[4], &sb)) {
--                              perror(argv[4]);
--                              die("Couldn't stat root device.");
--                      }
--                      major_root = major(sb.st_rdev);
--                      minor_root = minor(sb.st_rdev);
--              } else {
--                      major_root = 0;
--                      minor_root = 0;
--              }
--      } else {
--              major_root = DEFAULT_MAJOR_ROOT;
--              minor_root = DEFAULT_MINOR_ROOT;
--      }
--      fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
--
--      file_open(argv[1]);
--      i = read(fd, buf, sizeof(buf));
--      fprintf(stderr,"Boot sector %d bytes.\n",i);
--      if (i != 512)
--              die("Boot block must be exactly 512 bytes");
--      if (buf[510] != 0x55 || buf[511] != 0xaa)
--              die("Boot block hasn't got boot flag (0xAA55)");
--      buf[508] = minor_root;
--      buf[509] = major_root;
--      if (write(1, buf, 512) != 512)
--              die("Write call failed");
--      close (fd);
--
--      file_open(argv[2]);                                 /* Copy the setup code */
--      for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
--              if (write(1, buf, c) != c)
--                      die("Write call failed");
--      if (c != 0)
--              die("read-error on `setup'");
--      close (fd);
--
--      setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
--      /* for compatibility with ancient versions of LILO. */
--      if (setup_sectors < SETUP_SECTS)
--              setup_sectors = SETUP_SECTS;
--      fprintf(stderr, "Setup is %d bytes.\n", i);
--      memset(buf, 0, sizeof(buf));
--      while (i < setup_sectors * 512) {
--              c = setup_sectors * 512 - i;
--              if (c > sizeof(buf))
--                      c = sizeof(buf);
--              if (write(1, buf, c) != c)
--                      die("Write call failed");
--              i += c;
--      }
--
--      file_open(argv[3]);
--      if (fstat (fd, &sb))
--              die("Unable to stat `%s': %m", argv[3]);
--      sz = sb.st_size;
--      fprintf (stderr, "System is %d kB\n", sz/1024);
--      sys_size = (sz + 15) / 16;
--      if (!is_big_kernel && sys_size > DEF_SYSSIZE)
--              die("System is too big. Try using bzImage or modules.");
--      while (sz > 0) {
--              int l, n;
--
--              l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
--              if ((n=read(fd, buf, l)) != l) {
--                      if (n < 0)
--                              die("Error reading %s: %m", argv[3]);
--                      else
--                              die("%s: Unexpected EOF", argv[3]);
--              }
--              if (write(1, buf, l) != l)
--                      die("Write failed");
--              sz -= l;
--      }
--      close(fd);
--
--      if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
--              die("Output: seek failed");
--      buf[0] = setup_sectors;
--      if (write(1, buf, 1) != 1)
--              die("Write of setup sector count failed");
--      if (lseek(1, 500, SEEK_SET) != 500)
--              die("Output: seek failed");
--      buf[0] = (sys_size & 0xff);
--      buf[1] = ((sys_size >> 8) & 0xff);
--      buf[2] = ((sys_size >> 16) & 0xff);
--      buf[3] = ((sys_size >> 24) & 0xff);
--      if (write(1, buf, 4) != 4)
--              die("Write of image length failed");
--
--      return 0;                                           /* Everything is OK */
--}
-diff -puN arch/x86_64/kernel/Makefile~git-newsetup arch/x86_64/kernel/Makefile
---- a/arch/x86_64/kernel/Makefile~git-newsetup
-+++ a/arch/x86_64/kernel/Makefile
-@@ -45,6 +45,7 @@ obj-$(CONFIG_PCI)            += early-quirks.o
- obj-y                         += topology.o
- obj-y                         += intel_cacheinfo.o
-+obj-y                         += addon_cpuid_features.o
- obj-y                         += pcspeaker.o
- CFLAGS_vsyscall.o             := $(PROFILING) -g0
-@@ -58,6 +59,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  
- topology-y                     += ../../i386/kernel/topology.o
- microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
- intel_cacheinfo-y             += ../../i386/kernel/cpu/intel_cacheinfo.o
-+addon_cpuid_features-y                += ../../i386/kernel/cpu/addon_cpuid_features.o
- quirks-y                      += ../../i386/kernel/quirks.o
- i8237-y                               += ../../i386/kernel/i8237.o
- msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
-diff -puN arch/x86_64/kernel/setup.c~git-newsetup arch/x86_64/kernel/setup.c
---- a/arch/x86_64/kernel/setup.c~git-newsetup
-+++ a/arch/x86_64/kernel/setup.c
-@@ -855,6 +855,8 @@ void __cpuinit identify_cpu(struct cpuin
-                       c->x86_capability[2] = cpuid_edx(0x80860001);
-       }
-+      init_scattered_cpuid_features(c);
-+
-       c->apicid = phys_pkg_id(0);
-       /*
-@@ -940,7 +942,7 @@ static int show_cpuinfo(struct seq_file 
-               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-               "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
--              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
-+              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
-               /* AMD-defined */
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-@@ -956,10 +958,11 @@ static int show_cpuinfo(struct seq_file 
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               /* Other (Linux-defined) */
--              "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
--              "constant_tsc", NULL, NULL,
--              "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
-+              NULL, NULL, NULL, NULL,
-+              "constant_tsc", "up", NULL, "arch_perfmon",
-+              "pebs", "bts", NULL, "sync_rdtsc",
-+              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               /* Intel-defined (#2) */
-@@ -970,7 +973,7 @@ static int show_cpuinfo(struct seq_file 
-               /* VIA/Cyrix/Centaur-defined */
-               NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
--              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-@@ -981,6 +984,12 @@ static int show_cpuinfo(struct seq_file 
-               "osvw", "ibs", NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+
-+              /* Auxiliary (Linux-defined) */
-+              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-+              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-       };
-       static char *x86_power_flags[] = { 
-               "ts",   /* temperature sensor */
-diff -puN arch/x86_64/kernel/verify_cpu.S~git-newsetup arch/x86_64/kernel/verify_cpu.S
---- a/arch/x86_64/kernel/verify_cpu.S~git-newsetup
-+++ a/arch/x86_64/kernel/verify_cpu.S
-@@ -37,20 +37,6 @@ verify_cpu:
-       pushl   $0                      # Kill any dangerous flags
-       popfl
--      /* minimum CPUID flags for x86-64 as defined by AMD */
--#define M(x) (1<<(x))
--#define M2(a,b) M(a)|M(b)
--#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
--
--#define SSE_MASK \
--      (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
--#define REQUIRED_MASK1 \
--      (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
--       M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
--       M(X86_FEATURE_FXSR))
--#define REQUIRED_MASK2 \
--      (M(X86_FEATURE_LM - 32))
--
-       pushfl                          # standard way to check for cpuid
-       popl    %eax
-       movl    %eax,%ebx
-@@ -79,8 +65,8 @@ verify_cpu:
- verify_cpu_noamd:
-       movl    $0x1,%eax               # Does the cpu have what it takes
-       cpuid
--      andl    $REQUIRED_MASK1,%edx
--      xorl    $REQUIRED_MASK1,%edx
-+      andl    $REQUIRED_MASK0,%edx
-+      xorl    $REQUIRED_MASK0,%edx
-       jnz     verify_cpu_no_longmode
-       movl    $0x80000000,%eax        # See if extended cpuid is implemented
-@@ -90,8 +76,8 @@ verify_cpu_noamd:
-       movl    $0x80000001,%eax        # Does the cpu have what it takes
-       cpuid
--      andl    $REQUIRED_MASK2,%edx
--      xorl    $REQUIRED_MASK2,%edx
-+      andl    $REQUIRED_MASK1,%edx
-+      xorl    $REQUIRED_MASK1,%edx
-       jnz     verify_cpu_no_longmode
- verify_cpu_sse_test:
-diff -puN drivers/ide/legacy/hd.c~git-newsetup drivers/ide/legacy/hd.c
---- a/drivers/ide/legacy/hd.c~git-newsetup
-+++ a/drivers/ide/legacy/hd.c
-@@ -718,74 +718,25 @@ static int __init hd_init(void)
-       device_timer.function = hd_times_out;
-       blk_queue_hardsect_size(hd_queue, 512);
--#ifdef __i386__
-       if (!NR_HD) {
--              extern struct drive_info drive_info;
--              unsigned char *BIOS = (unsigned char *) &drive_info;
--              unsigned long flags;
--              int cmos_disks;
--
--              for (drive=0 ; drive<2 ; drive++) {
--                      hd_info[drive].cyl = *(unsigned short *) BIOS;
--                      hd_info[drive].head = *(2+BIOS);
--                      hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
--                      hd_info[drive].ctl = *(8+BIOS);
--                      hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
--                      hd_info[drive].sect = *(14+BIOS);
--#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
--                      if (hd_info[drive].cyl && NR_HD == drive)
--                              NR_HD++;
--#endif
--                      BIOS += 16;
--              }
--
--      /*
--              We query CMOS about hard disks : it could be that 
--              we have a SCSI/ESDI/etc controller that is BIOS
--              compatible with ST-506, and thus showing up in our
--              BIOS table, but not register compatible, and therefore
--              not present in CMOS.
--
--              Furthermore, we will assume that our ST-506 drives
--              <if any> are the primary drives in the system, and 
--              the ones reflected as drive 1 or 2.
--
--              The first drive is stored in the high nibble of CMOS
--              byte 0x12, the second in the low nibble.  This will be
--              either a 4 bit drive type or 0xf indicating use byte 0x19 
--              for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
--
--              Needless to say, a non-zero value means we have 
--              an AT controller hard disk for that drive.
--
--              Currently the rtc_lock is a bit academic since this
--              driver is non-modular, but someday... ?         Paul G.
--      */
--
--              spin_lock_irqsave(&rtc_lock, flags);
--              cmos_disks = CMOS_READ(0x12);
--              spin_unlock_irqrestore(&rtc_lock, flags);
--
--              if (cmos_disks & 0xf0) {
--                      if (cmos_disks & 0x0f)
--                              NR_HD = 2;
--                      else
--                              NR_HD = 1;
--              }
--      }
--#endif /* __i386__ */
--#ifdef __arm__
--      if (!NR_HD) {
--              /* We don't know anything about the drive.  This means
-+              /*
-+               * We don't know anything about the drive.  This means
-                * that you *MUST* specify the drive parameters to the
-                * kernel yourself.
-+               *
-+               * If we were on an i386, we used to read this info from
-+               * the BIOS or CMOS.  This doesn't work all that well,
-+               * since this assumes that this is a primary or secondary
-+               * drive, and if we're using this legacy driver, it's
-+               * probably an auxilliary controller added to recover
-+               * legacy data off an ST-506 drive.  Either way, it's
-+               * definitely safest to have the user explicitly specify
-+               * the information.
-                */
-               printk("hd: no drives specified - use hd=cyl,head,sectors"
-                       " on kernel command line\n");
--      }
--#endif
--      if (!NR_HD)
-               goto out;
-+      }
-       for (drive=0 ; drive < NR_HD ; drive++) {
-               struct gendisk *disk = alloc_disk(64);
-diff -puN include/asm-i386/boot.h~git-newsetup include/asm-i386/boot.h
---- a/include/asm-i386/boot.h~git-newsetup
-+++ a/include/asm-i386/boot.h
-@@ -1,5 +1,5 @@
--#ifndef _LINUX_BOOT_H
--#define _LINUX_BOOT_H
-+#ifndef _ASM_BOOT_H
-+#define _ASM_BOOT_H
- /* Don't touch these, unless you really know what you're doing. */
- #define DEF_INITSEG   0x9000
-@@ -17,4 +17,4 @@
-                               + (CONFIG_PHYSICAL_ALIGN - 1)) \
-                               & ~(CONFIG_PHYSICAL_ALIGN - 1))
--#endif /* _LINUX_BOOT_H */
-+#endif /* _ASM_BOOT_H */
-diff -puN /dev/null include/asm-i386/bootparam.h
---- /dev/null
-+++ a/include/asm-i386/bootparam.h
-@@ -0,0 +1,85 @@
-+#ifndef _ASM_BOOTPARAM_H
-+#define _ASM_BOOTPARAM_H
-+
-+#include <linux/types.h>
-+#include <linux/screen_info.h>
-+#include <linux/apm_bios.h>
-+#include <asm/e820.h>
-+#include <linux/edd.h>
-+#include <video/edid.h>
-+
-+struct setup_header {
-+      u8      setup_sects;
-+      u16     root_flags;
-+      u32     syssize;
-+      u16     ram_size;
-+      u16     vid_mode;
-+      u16     root_dev;
-+      u16     boot_flag;
-+      u16     jump;
-+      u32     header;
-+      u16     version;
-+      u32     realmode_swtch;
-+      u16     start_sys;
-+      u16     kernel_version;
-+      u8      type_of_loader;
-+      u8      loadflags;
-+#define LOADED_HIGH   0x01
-+#define CAN_USE_HEAP  0x80
-+      u16     setup_move_size;
-+      u32     code32_start;
-+      u32     ramdisk_image;
-+      u32     ramdisk_size;
-+      u32     bootsect_kludge;
-+      u16     heap_end_ptr;
-+      u16     _pad1;
-+      u32     cmd_line_ptr;
-+      u32     initrd_addr_max;
-+      u32     kernel_alignment;
-+      u8      relocatable_kernel;
-+} __attribute__((packed));
-+
-+struct sys_desc_table {
-+      u16 length;
-+      u8  table[14];
-+};
-+
-+struct efi_info {
-+      u32 _pad1;
-+      u32 efi_systab;
-+      u32 efi_memdesc_size;
-+      u32 efi_memdec_version;
-+      u32 efi_memmap;
-+      u32 fi_memmap_size;
-+      u32 _pad2[2];
-+};
-+
-+/* The so-called "zeropage" */
-+struct boot_params {
-+      struct screen_info screen_info;                 /* 0x000 */
-+      struct apm_bios_info apm_bios_info;             /* 0x040 */
-+      u8  _pad2[12];                                  /* 0x054 */
-+      u32 speedstep_info[4];                          /* 0x060 */
-+      u8  _pad3[16];                                  /* 0x070 */
-+      u8  hd0_info[16];       /* obsolete! */         /* 0x080 */
-+      u8  hd1_info[16];       /* obsolete! */         /* 0x090 */
-+      struct sys_desc_table sys_desc_table;           /* 0x0a0 */
-+      u8  _pad4[144];                                 /* 0x0b0 */
-+      struct edid_info edid_info;                     /* 0x140 */
-+      struct efi_info efi_info;                       /* 0x1c0 */
-+      u32 alt_mem_k;                                  /* 0x1e0 */
-+      u32 scratch;            /* Scratch field! */    /* 0x1e4 */
-+      u8  e820_entries;                               /* 0x1e8 */
-+      u8  eddbuf_entries;                             /* 0x1e9 */
-+      u8  edd_mbr_sig_buf_entries;                    /* 0x1ea */
-+      u8  _pad6[6];                                   /* 0x1eb */
-+      struct setup_header hdr;    /* setup header */  /* 0x1f1 */
-+      u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
-+      u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];        /* 0x290 */
-+      struct e820entry e820_map[E820MAX];             /* 0x2d0 */
-+      u8  _pad8[48];                                  /* 0xcd0 */
-+      struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
-+      u8  _pad9[276];                                 /* 0xeec */
-+} __attribute__((packed));
-+
-+#endif /* _ASM_BOOTPARAM_H */
-diff -puN include/asm-i386/cpufeature.h~git-newsetup include/asm-i386/cpufeature.h
---- a/include/asm-i386/cpufeature.h~git-newsetup
-+++ a/include/asm-i386/cpufeature.h
-@@ -12,7 +12,7 @@
- #endif
- #include <asm/required-features.h>
--#define NCAPINTS      7       /* N 32-bit words worth of info */
-+#define NCAPINTS      8       /* N 32-bit words worth of info */
- /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
- #define X86_FEATURE_FPU               (0*32+ 0) /* Onboard FPU */
-@@ -81,6 +81,7 @@
- #define X86_FEATURE_BTS               (3*32+13)  /* Branch Trace Store */
- #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
- #define X86_FEATURE_SYNC_RDTSC        (3*32+15)  /* RDTSC synchronizes the CPU */
-+#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
- /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
- #define X86_FEATURE_XMM3      (4*32+ 0) /* Streaming SIMD Extensions-3 */
-@@ -108,11 +109,24 @@
- #define X86_FEATURE_LAHF_LM   (6*32+ 0) /* LAHF/SAHF in long mode */
- #define X86_FEATURE_CMP_LEGACY        (6*32+ 1) /* If yes HyperThreading not valid */
--#define cpu_has(c, bit)                                       \
--      ((__builtin_constant_p(bit) && (bit) < 32 &&    \
--              (1UL << (bit)) & REQUIRED_MASK1) ?      \
--              1 :                                     \
--      test_bit(bit, (c)->x86_capability))
-+/*
-+ * Auxiliary flags: Linux defined - For features scattered in various
-+ * CPUID levels like 0x6, 0xA etc
-+ */
-+#define X86_FEATURE_IDA               (7*32+ 0) /* Intel Dynamic Acceleration */
-+
-+#define cpu_has(c, bit)                                                       \
-+      (__builtin_constant_p(bit) &&                                   \
-+       ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
-+         (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||     \
-+         (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||     \
-+         (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||     \
-+         (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
-+         (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
-+         (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
-+         (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
-+        ? 1 :                                                         \
-+        test_bit(bit, (c)->x86_capability))
- #define boot_cpu_has(bit)     cpu_has(&boot_cpu_data, bit)
- #define cpu_has_fpu           boot_cpu_has(X86_FEATURE_FPU)
-diff -puN include/asm-i386/e820.h~git-newsetup include/asm-i386/e820.h
---- a/include/asm-i386/e820.h~git-newsetup
-+++ a/include/asm-i386/e820.h
-@@ -25,13 +25,15 @@
- #ifndef __ASSEMBLY__
-+struct e820entry {
-+      u64 addr;       /* start of memory segment */
-+      u64 size;       /* size of memory segment */
-+      u32 type;       /* type of memory segment */
-+} __attribute__((packed));
-+
- struct e820map {
--    int nr_map;
--    struct e820entry {
--      unsigned long long addr;        /* start of memory segment */
--      unsigned long long size;        /* size of memory segment */
--      unsigned long type;             /* type of memory segment */
--    } map[E820MAX];
-+      u32 nr_map;
-+      struct e820entry map[E820MAX];
- };
- extern struct e820map e820;
-diff -puN include/asm-i386/processor.h~git-newsetup include/asm-i386/processor.h
---- a/include/asm-i386/processor.h~git-newsetup
-+++ a/include/asm-i386/processor.h
-@@ -118,6 +118,7 @@ void __init cpu_detect(struct cpuinfo_x8
- extern void identify_boot_cpu(void);
- extern void identify_secondary_cpu(struct cpuinfo_x86 *);
- extern void print_cpu_info(struct cpuinfo_x86 *);
-+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
- extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
- extern unsigned short num_cache_leaves;
-diff -puN include/asm-i386/required-features.h~git-newsetup include/asm-i386/required-features.h
---- a/include/asm-i386/required-features.h~git-newsetup
-+++ a/include/asm-i386/required-features.h
-@@ -3,7 +3,7 @@
- /* Define minimum CPUID feature set for kernel These bits are checked
-    really early to actually display a visible error message before the
--   kernel dies.  Only add word 0 bits here
-+   kernel dies.  Make sure to assign features to the proper mask!
-    Some requirements that are not in CPUID yet are also in the
-    CONFIG_X86_MINIMUM_CPU mode which is checked too.
-@@ -11,24 +11,45 @@
-    The real information is in arch/i386/Kconfig.cpu, this just converts
-    the CONFIGs into a bitmask */
-+#ifndef CONFIG_MATH_EMULATION
-+# define NEED_FPU     (1<<(X86_FEATURE_FPU & 31))
-+#else
-+# define NEED_FPU     0
-+#endif
-+
- #ifdef CONFIG_X86_PAE
--#define NEED_PAE      (1<<X86_FEATURE_PAE)
-+# define NEED_PAE     (1<<(X86_FEATURE_PAE & 31))
- #else
--#define NEED_PAE      0
-+# define NEED_PAE     0
- #endif
- #ifdef CONFIG_X86_CMOV
--#define NEED_CMOV     (1<<X86_FEATURE_CMOV)
-+# define NEED_CMOV    (1<<(X86_FEATURE_CMOV & 31))
- #else
--#define NEED_CMOV     0
-+# define NEED_CMOV    0
- #endif
- #ifdef CONFIG_X86_CMPXCHG64
--#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
-+# define NEED_CX8     (1<<(X86_FEATURE_CX8 & 31))
-+#else
-+# define NEED_CX8     0
-+#endif
-+
-+#define REQUIRED_MASK0        (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
-+
-+#ifdef CONFIG_X86_USE_3DNOW
-+# define NEED_3DNOW   (1<<(X86_FEATURE_3DNOW & 31))
- #else
--#define NEED_CMPXCHG64  0
-+# define NEED_3DNOW   0
- #endif
--#define REQUIRED_MASK1        (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
-+#define REQUIRED_MASK1        (NEED_3DNOW)
-+
-+#define REQUIRED_MASK2        0
-+#define REQUIRED_MASK3        0
-+#define REQUIRED_MASK4        0
-+#define REQUIRED_MASK5        0
-+#define REQUIRED_MASK6        0
-+#define REQUIRED_MASK7        0
- #endif
-diff -puN include/asm-i386/setup.h~git-newsetup include/asm-i386/setup.h
---- a/include/asm-i386/setup.h~git-newsetup
-+++ a/include/asm-i386/setup.h
-@@ -26,12 +26,15 @@
- #define NEW_CL_POINTER                0x228   /* Relative to real mode data */
- #ifndef __ASSEMBLY__
-+
-+#include <asm/bootparam.h>
-+
- /*
-  * This is set up by the setup-routine at boot-time
-  */
--extern unsigned char boot_params[PARAM_SIZE];
-+extern struct boot_params boot_params;
--#define PARAM (boot_params)
-+#define PARAM ((char *)&boot_params)
- #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
- #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
- #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
-@@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_S
- #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
- #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
- #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
--#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
--#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
-+#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
- #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
- #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
- #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
-diff -puN include/asm-x86_64/alternative.h~git-newsetup include/asm-x86_64/alternative.h
---- a/include/asm-x86_64/alternative.h~git-newsetup
-+++ a/include/asm-x86_64/alternative.h
-@@ -5,6 +5,41 @@
- #include <linux/types.h>
- #include <linux/stddef.h>
-+
-+/*
-+ * Alternative inline assembly for SMP.
-+ *
-+ * The LOCK_PREFIX macro defined here replaces the LOCK and
-+ * LOCK_PREFIX macros used everywhere in the source tree.
-+ *
-+ * SMP alternatives use the same data structures as the other
-+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
-+ * UP system running a SMP kernel.  The existing apply_alternatives()
-+ * works fine for patching a SMP kernel for UP.
-+ *
-+ * The SMP alternative tables can be kept after boot and contain both
-+ * UP and SMP versions of the instructions to allow switching back to
-+ * SMP at runtime, when hotplugging in a new CPU, which is especially
-+ * useful in virtualized environments.
-+ *
-+ * The very common lock prefix is handled as special case in a
-+ * separate table which is a pure address list without replacement ptr
-+ * and size information.  That keeps the table sizes small.
-+ */
-+
-+#ifdef CONFIG_SMP
-+#define LOCK_PREFIX \
-+              ".section .smp_locks,\"a\"\n"   \
-+              "  .align 8\n"                  \
-+              "  .quad 661f\n" /* address */  \
-+              ".previous\n"                   \
-+              "661:\n\tlock; "
-+
-+#else /* ! CONFIG_SMP */
-+#define LOCK_PREFIX ""
-+#endif
-+
-+/* This must be included *after* the definition of LOCK_PREFIX */
- #include <asm/cpufeature.h>
- struct alt_instr {
-@@ -108,39 +143,6 @@ static inline void alternatives_smp_swit
-  */
- #define ASM_OUTPUT2(a, b) a, b
--/*
-- * Alternative inline assembly for SMP.
-- *
-- * The LOCK_PREFIX macro defined here replaces the LOCK and
-- * LOCK_PREFIX macros used everywhere in the source tree.
-- *
-- * SMP alternatives use the same data structures as the other
-- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
-- * UP system running a SMP kernel.  The existing apply_alternatives()
-- * works fine for patching a SMP kernel for UP.
-- *
-- * The SMP alternative tables can be kept after boot and contain both
-- * UP and SMP versions of the instructions to allow switching back to
-- * SMP at runtime, when hotplugging in a new CPU, which is especially
-- * useful in virtualized environments.
-- *
-- * The very common lock prefix is handled as special case in a
-- * separate table which is a pure address list without replacement ptr
-- * and size information.  That keeps the table sizes small.
-- */
--
--#ifdef CONFIG_SMP
--#define LOCK_PREFIX \
--              ".section .smp_locks,\"a\"\n"   \
--              "  .align 8\n"                  \
--              "  .quad 661f\n" /* address */  \
--              ".previous\n"                   \
--              "661:\n\tlock; "
--
--#else /* ! CONFIG_SMP */
--#define LOCK_PREFIX ""
--#endif
--
- struct paravirt_patch;
- #ifdef CONFIG_PARAVIRT
- void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
-diff -puN include/asm-x86_64/boot.h~git-newsetup include/asm-x86_64/boot.h
---- a/include/asm-x86_64/boot.h~git-newsetup
-+++ a/include/asm-x86_64/boot.h
-@@ -1,15 +1 @@
--#ifndef _LINUX_BOOT_H
--#define _LINUX_BOOT_H
--
--/* Don't touch these, unless you really know what you're doing. */
--#define DEF_INITSEG   0x9000
--#define DEF_SYSSEG    0x1000
--#define DEF_SETUPSEG  0x9020
--#define DEF_SYSSIZE   0x7F00
--
--/* Internal svga startup constants */
--#define NORMAL_VGA    0xffff          /* 80x25 mode */
--#define EXTENDED_VGA  0xfffe          /* 80x50 mode */
--#define ASK_VGA               0xfffd          /* ask for it at bootup */
--
--#endif
-+#include <asm-i386/boot.h>
-diff -puN /dev/null include/asm-x86_64/bootparam.h
---- /dev/null
-+++ a/include/asm-x86_64/bootparam.h
-@@ -0,0 +1 @@
-+#include <asm-i386/bootparam.h>
-diff -puN include/asm-x86_64/cpufeature.h~git-newsetup include/asm-x86_64/cpufeature.h
---- a/include/asm-x86_64/cpufeature.h~git-newsetup
-+++ a/include/asm-x86_64/cpufeature.h
-@@ -7,115 +7,24 @@
- #ifndef __ASM_X8664_CPUFEATURE_H
- #define __ASM_X8664_CPUFEATURE_H
--#define NCAPINTS      7       /* N 32-bit words worth of info */
-+#include <asm-i386/cpufeature.h>
--/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
--#define X86_FEATURE_FPU               (0*32+ 0) /* Onboard FPU */
--#define X86_FEATURE_VME               (0*32+ 1) /* Virtual Mode Extensions */
--#define X86_FEATURE_DE                (0*32+ 2) /* Debugging Extensions */
--#define X86_FEATURE_PSE       (0*32+ 3) /* Page Size Extensions */
--#define X86_FEATURE_TSC               (0*32+ 4) /* Time Stamp Counter */
--#define X86_FEATURE_MSR               (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
--#define X86_FEATURE_PAE               (0*32+ 6) /* Physical Address Extensions */
--#define X86_FEATURE_MCE               (0*32+ 7) /* Machine Check Architecture */
--#define X86_FEATURE_CX8               (0*32+ 8) /* CMPXCHG8 instruction */
--#define X86_FEATURE_APIC      (0*32+ 9) /* Onboard APIC */
--#define X86_FEATURE_SEP               (0*32+11) /* SYSENTER/SYSEXIT */
--#define X86_FEATURE_MTRR      (0*32+12) /* Memory Type Range Registers */
--#define X86_FEATURE_PGE               (0*32+13) /* Page Global Enable */
--#define X86_FEATURE_MCA               (0*32+14) /* Machine Check Architecture */
--#define X86_FEATURE_CMOV      (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
--#define X86_FEATURE_PAT               (0*32+16) /* Page Attribute Table */
--#define X86_FEATURE_PSE36     (0*32+17) /* 36-bit PSEs */
--#define X86_FEATURE_PN                (0*32+18) /* Processor serial number */
--#define X86_FEATURE_CLFLSH    (0*32+19) /* Supports the CLFLUSH instruction */
--#define X86_FEATURE_DS                (0*32+21) /* Debug Store */
--#define X86_FEATURE_ACPI      (0*32+22) /* ACPI via MSR */
--#define X86_FEATURE_MMX               (0*32+23) /* Multimedia Extensions */
--#define X86_FEATURE_FXSR      (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
--                                        /* of FPU context), and CR4.OSFXSR available */
--#define X86_FEATURE_XMM               (0*32+25) /* Streaming SIMD Extensions */
--#define X86_FEATURE_XMM2      (0*32+26) /* Streaming SIMD Extensions-2 */
--#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
--#define X86_FEATURE_HT                (0*32+28) /* Hyper-Threading */
--#define X86_FEATURE_ACC               (0*32+29) /* Automatic clock control */
--#define X86_FEATURE_IA64      (0*32+30) /* IA-64 processor */
--
--/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
--/* Don't duplicate feature flags which are redundant with Intel! */
--#define X86_FEATURE_SYSCALL   (1*32+11) /* SYSCALL/SYSRET */
--#define X86_FEATURE_MMXEXT    (1*32+22) /* AMD MMX extensions */
--#define X86_FEATURE_FXSR_OPT  (1*32+25) /* FXSR optimizations */
--#define X86_FEATURE_RDTSCP    (1*32+27) /* RDTSCP */
--#define X86_FEATURE_LM                (1*32+29) /* Long Mode (x86-64) */
--#define X86_FEATURE_3DNOWEXT  (1*32+30) /* AMD 3DNow! extensions */
--#define X86_FEATURE_3DNOW     (1*32+31) /* 3DNow! */
--
--/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
--#define X86_FEATURE_RECOVERY  (2*32+ 0) /* CPU in recovery mode */
--#define X86_FEATURE_LONGRUN   (2*32+ 1) /* Longrun power control */
--#define X86_FEATURE_LRTI      (2*32+ 3) /* LongRun table interface */
--
--/* Other features, Linux-defined mapping, word 3 */
--/* This range is used for feature bits which conflict or are synthesized */
--#define X86_FEATURE_CXMMX     (3*32+ 0) /* Cyrix MMX extensions */
--#define X86_FEATURE_K6_MTRR   (3*32+ 1) /* AMD K6 nonstandard MTRRs */
--#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
--#define X86_FEATURE_CENTAUR_MCR       (3*32+ 3) /* Centaur MCRs (= MTRRs) */
--#define X86_FEATURE_REP_GOOD  (3*32+ 4) /* rep microcode works well on this CPU */
--#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
--#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
--#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
--#define X86_FEATURE_UP                (3*32+8) /* SMP kernel running on UP */
--#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
--#define X86_FEATURE_PEBS      (3*32+10) /* Precise-Event Based Sampling */
--#define X86_FEATURE_BTS               (3*32+11) /* Branch Trace Store */
--
--/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
--#define X86_FEATURE_XMM3      (4*32+ 0) /* Streaming SIMD Extensions-3 */
--#define X86_FEATURE_MWAIT     (4*32+ 3) /* Monitor/Mwait support */
--#define X86_FEATURE_DSCPL     (4*32+ 4) /* CPL Qualified Debug Store */
--#define X86_FEATURE_EST               (4*32+ 7) /* Enhanced SpeedStep */
--#define X86_FEATURE_TM2               (4*32+ 8) /* Thermal Monitor 2 */
--#define X86_FEATURE_CID               (4*32+10) /* Context ID */
--#define X86_FEATURE_CX16      (4*32+13) /* CMPXCHG16B */
--#define X86_FEATURE_XTPR      (4*32+14) /* Send Task Priority Messages */
--
--/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
--#define X86_FEATURE_XSTORE    (5*32+ 2) /* on-CPU RNG present (xstore insn) */
--#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */
--#define X86_FEATURE_XCRYPT    (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
--#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */
--
--/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
--#define X86_FEATURE_LAHF_LM   (6*32+ 0) /* LAHF/SAHF in long mode */
--#define X86_FEATURE_CMP_LEGACY        (6*32+ 1) /* If yes HyperThreading not valid */
--
--#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
--#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
--
--#define cpu_has_fpu            1
-+#undef  cpu_has_vme
- #define cpu_has_vme            0
--#define cpu_has_de             1
--#define cpu_has_pse            1
--#define cpu_has_tsc            1
-+
-+#undef  cpu_has_pae
- #define cpu_has_pae            ___BUG___
--#define cpu_has_pge            1
--#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
--#define cpu_has_mtrr           1
--#define cpu_has_mmx            1
--#define cpu_has_fxsr           1
--#define cpu_has_xmm            1
--#define cpu_has_xmm2           1
--#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
--#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
-+
-+#undef  cpu_has_mp
- #define cpu_has_mp             1 /* XXX */
-+
-+#undef  cpu_has_k6_mtrr
- #define cpu_has_k6_mtrr        0
-+
-+#undef  cpu_has_cyrix_arr
- #define cpu_has_cyrix_arr      0
-+
-+#undef  cpu_has_centaur_mcr
- #define cpu_has_centaur_mcr    0
--#define cpu_has_clflush              boot_cpu_has(X86_FEATURE_CLFLSH)
--#define cpu_has_ds           boot_cpu_has(X86_FEATURE_DS)
--#define cpu_has_pebs         boot_cpu_has(X86_FEATURE_PEBS)
--#define cpu_has_bts          boot_cpu_has(X86_FEATURE_BTS)
- #endif /* __ASM_X8664_CPUFEATURE_H */
-diff -puN include/asm-x86_64/e820.h~git-newsetup include/asm-x86_64/e820.h
---- a/include/asm-x86_64/e820.h~git-newsetup
-+++ a/include/asm-x86_64/e820.h
-@@ -11,7 +11,9 @@
- #ifndef __E820_HEADER
- #define __E820_HEADER
--#include <linux/mmzone.h>
-+#ifndef _SETUP
-+# include <linux/mmzone.h>
-+#endif
- #define E820MAP       0x2d0           /* our map */
- #define E820MAX       128             /* number of entries in E820MAP */
-@@ -30,7 +32,7 @@ struct e820entry {
- } __attribute__((packed));
- struct e820map {
--    int nr_map;
-+      u32 nr_map;
-       struct e820entry map[E820MAX];
- };
-diff -puN include/asm-x86_64/processor.h~git-newsetup include/asm-x86_64/processor.h
---- a/include/asm-x86_64/processor.h~git-newsetup
-+++ a/include/asm-x86_64/processor.h
-@@ -99,6 +99,7 @@ extern char ignore_irq13;
- extern void identify_cpu(struct cpuinfo_x86 *);
- extern void print_cpu_info(struct cpuinfo_x86 *);
-+extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
- extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
- extern unsigned short num_cache_leaves;
-@@ -367,8 +368,6 @@ static inline void sync_core(void)
-       asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
- } 
--#define cpu_has_fpu 1
--
- #define ARCH_HAS_PREFETCH
- static inline void prefetch(void *x) 
- { 
-diff -puN /dev/null include/asm-x86_64/required-features.h
---- /dev/null
-+++ a/include/asm-x86_64/required-features.h
-@@ -0,0 +1,46 @@
-+#ifndef _ASM_REQUIRED_FEATURES_H
-+#define _ASM_REQUIRED_FEATURES_H 1
-+
-+/* Define minimum CPUID feature set for kernel These bits are checked
-+   really early to actually display a visible error message before the
-+   kernel dies.  Make sure to assign features to the proper mask!
-+
-+   The real information is in arch/x86_64/Kconfig.cpu, this just converts
-+   the CONFIGs into a bitmask */
-+
-+/* x86-64 baseline features */
-+#define NEED_FPU      (1<<(X86_FEATURE_FPU & 31))
-+#define NEED_PSE      (1<<(X86_FEATURE_PSE & 31))
-+#define NEED_MSR      (1<<(X86_FEATURE_MSR & 31))
-+#define NEED_PAE      (1<<(X86_FEATURE_PAE & 31))
-+#define NEED_CX8      (1<<(X86_FEATURE_CX8 & 31))
-+#define NEED_PGE      (1<<(X86_FEATURE_PGE & 31))
-+#define NEED_FXSR     (1<<(X86_FEATURE_FXSR & 31))
-+#define NEED_CMOV     (1<<(X86_FEATURE_CMOV & 31))
-+#define NEED_XMM      (1<<(X86_FEATURE_XMM & 31))
-+#define NEED_XMM2     (1<<(X86_FEATURE_XMM2 & 31))
-+
-+#define REQUIRED_MASK0        (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
-+                       NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
-+                       NEED_XMM|NEED_XMM2)
-+#define SSE_MASK      (NEED_XMM|NEED_XMM2)
-+
-+/* x86-64 baseline features */
-+#define NEED_LM               (1<<(X86_FEATURE_LM & 31))
-+
-+#ifdef CONFIG_X86_USE_3DNOW
-+# define NEED_3DNOW   (1<<(X86_FEATURE_3DNOW & 31))
-+#else
-+# define NEED_3DNOW   0
-+#endif
-+
-+#define REQUIRED_MASK1        (NEED_LM|NEED_3DNOW)
-+
-+#define REQUIRED_MASK2        0
-+#define REQUIRED_MASK3        0
-+#define REQUIRED_MASK4        0
-+#define REQUIRED_MASK5        0
-+#define REQUIRED_MASK6        0
-+#define REQUIRED_MASK7        0
-+
-+#endif
-diff -puN include/asm-x86_64/segment.h~git-newsetup include/asm-x86_64/segment.h
---- a/include/asm-x86_64/segment.h~git-newsetup
-+++ a/include/asm-x86_64/segment.h
-@@ -3,6 +3,14 @@
- #include <asm/cache.h>
-+/* Simple and small GDT entries for booting only */
-+
-+#define GDT_ENTRY_BOOT_CS             2
-+#define __BOOT_CS     (GDT_ENTRY_BOOT_CS * 8)
-+
-+#define GDT_ENTRY_BOOT_DS             (GDT_ENTRY_BOOT_CS + 1)
-+#define __BOOT_DS     (GDT_ENTRY_BOOT_DS * 8)
-+
- #define __KERNEL_CS   0x10
- #define __KERNEL_DS   0x18
-diff -puN include/linux/edd.h~git-newsetup include/linux/edd.h
---- a/include/linux/edd.h~git-newsetup
-+++ a/include/linux/edd.h
-@@ -49,10 +49,6 @@
- #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
- #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
-                                    in boot_params - treat this as 1 byte  */
--#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
--#define EDD_CL_OFF      0x666f         /* "of" for off  */
--#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
--#define EDD_CL_ON       0x6e6f               /* "on" for on */
- #ifndef __ASSEMBLY__
-diff -puN include/linux/screen_info.h~git-newsetup include/linux/screen_info.h
---- a/include/linux/screen_info.h~git-newsetup
-+++ a/include/linux/screen_info.h
-@@ -10,7 +10,7 @@
- struct screen_info {
-       u8  orig_x;             /* 0x00 */
-       u8  orig_y;             /* 0x01 */
--      u16 dontuse1;           /* 0x02 -- EXT_MEM_K sits here */
-+      u16 ext_mem_k;          /* 0x02 */
-       u16 orig_video_page;    /* 0x04 */
-       u8  orig_video_mode;    /* 0x06 */
-       u8  orig_video_cols;    /* 0x07 */
-@@ -27,7 +27,7 @@ struct screen_info {
-       u16 lfb_depth;          /* 0x16 */
-       u32 lfb_base;           /* 0x18 */
-       u32 lfb_size;           /* 0x1c */
--      u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
-+      u16 cl_magic, cl_offset; /* 0x20 */
-       u16 lfb_linelength;     /* 0x24 */
-       u8  red_size;           /* 0x26 */
-       u8  red_pos;            /* 0x27 */
-@@ -42,9 +42,8 @@ struct screen_info {
-       u16 pages;              /* 0x32 */
-       u16 vesa_attributes;    /* 0x34 */
-       u32 capabilities;       /* 0x36 */
--                              /* 0x3a -- 0x3b reserved for future expansion */
--                              /* 0x3c -- 0x3f micro stack for relocatable kernels */
--};
-+      u8  _reserved[6];       /* 0x3a */
-+} __attribute__((packed));
- extern struct screen_info screen_info;
-_
diff --git a/target/linux/generic-2.6/patches-2.6.22/001-eeprom_93cx6.patch b/target/linux/generic-2.6/patches-2.6.22/001-eeprom_93cx6.patch
deleted file mode 100644 (file)
index 9bc19fb..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From: Ivo van Doorn <ivdoorn@gmail.com>
-Date: Mon, 14 May 2007 21:06:01 +0000 (+0200)
-Subject: [PATCH] eeprom_93cx6: Add comment for 1us delay after pulse
-X-Git-Tag: v2.6.23-rc1~1201^2~73
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4b914dc0493edff19ff698a18198a173a14ba9d2
-
-[PATCH] eeprom_93cx6: Add comment for 1us delay after pulse
-
-This will add a comment for the 1us delay which is taken
-after the pulse has been switched. The 1us delay is based
-on the specifications so that should be made clear.
-
-Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
-Signed-off-by: John W. Linville <linville@tuxdriver.com>
----
-
-diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
-index bfcb434..0d6d742 100644
---- a/drivers/misc/eeprom_93cx6.c
-+++ b/drivers/misc/eeprom_93cx6.c
-@@ -39,6 +39,12 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
- {
-       eeprom->reg_data_clock = 1;
-       eeprom->register_write(eeprom);
-+
-+      /*
-+       * Add a short delay for the pulse to work.
-+       * According to the specifications the minimal time
-+       * should be 450ns so a 1us delay is sufficient.
-+       */
-       udelay(1);
- }
-@@ -46,6 +52,12 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
- {
-       eeprom->reg_data_clock = 0;
-       eeprom->register_write(eeprom);
-+
-+      /*
-+       * Add a short delay for the pulse to work.
-+       * According to the specifications the minimal time
-+       * should be 450ns so a 1us delay is sufficient.
-+       */
-       udelay(1);
- }
diff --git a/target/linux/generic-2.6/patches-2.6.22/001-git-newsetup-fixup.patch b/target/linux/generic-2.6/patches-2.6.22/001-git-newsetup-fixup.patch
deleted file mode 100644 (file)
index fad5435..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Andrew Morton <akpm@linux-foundation.org>
-
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
----
-
- arch/i386/kernel/cpu/Makefile |    2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup-fixup arch/i386/kernel/cpu/Makefile
---- a/arch/i386/kernel/cpu/Makefile~git-newsetup-fixup
-+++ a/arch/i386/kernel/cpu/Makefile
-@@ -8,7 +8,7 @@ obj-y  +=      amd.o
- obj-y +=      cyrix.o
- obj-y +=      centaur.o
- obj-y +=      transmeta.o
--obj-y +=      intel.o intel_cacheinfo.o
-+obj-y +=      intel.o intel_cacheinfo.o addon_cpuid_features.o
- obj-y +=      rise.o
- obj-y +=      nexgen.o
- obj-y +=      umc.o
-_
diff --git a/target/linux/generic-2.6/patches-2.6.22/002-eeprom_93cx6.patch b/target/linux/generic-2.6/patches-2.6.22/002-eeprom_93cx6.patch
deleted file mode 100644 (file)
index 7f2b125..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-From: John W. Linville <linville@tuxdriver.com>
-Date: Tue, 12 Jun 2007 01:37:46 +0000 (-0400)
-Subject: [PATCH] eeprom_93cx6: shorten pulse timing to match spec
-X-Git-Tag: v2.6.23-rc1~1201^2~71
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7e9400f178d291b2208c4ed9aac0f425c1364000
-
-[PATCH] eeprom_93cx6: shorten pulse timing to match spec
-
-93cx6 datasheet available here:
-
-        http://ww1.microchip.com/downloads/en/DeviceDoc/21749F.pdf
-
-Figure 1-1 and Table 1-2 on pages 4-5 indicate that both Clock High
-Time and Clock Low Time have largest minimum times of 450ns.
-
-Signed-off-by: John W. Linville <linville@tuxdriver.com>
----
-
-diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
-index 0d6d742..ac515b0 100644
---- a/drivers/misc/eeprom_93cx6.c
-+++ b/drivers/misc/eeprom_93cx6.c
-@@ -42,10 +42,10 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
-       /*
-        * Add a short delay for the pulse to work.
--       * According to the specifications the minimal time
--       * should be 450ns so a 1us delay is sufficient.
-+       * According to the specifications the "maximum minimum"
-+       * time should be 450ns.
-        */
--      udelay(1);
-+      ndelay(450);
- }
- static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
diff --git a/target/linux/generic-2.6/patches-2.6.22/003-eeprom_93cx6.patch b/target/linux/generic-2.6/patches-2.6.22/003-eeprom_93cx6.patch
deleted file mode 100644 (file)
index ae11f82..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From: Francois Romieu <romieu@fr.zoreil.com>
-Date: Tue, 3 Jul 2007 22:31:44 +0000 (+0200)
-Subject: eeprom_93cx6: shorten pulse timing to match spec (bis)
-X-Git-Tag: v2.6.23-rc1~1151^2~11
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8abd531e3f77188de2fc41e677d075cc66e61631
-
-eeprom_93cx6: shorten pulse timing to match spec (bis)
-
-Based on an original idea by John W. Linville.
-
-It is the missing part of 42d45ccd60636c28e35c2016f091783bc14ad99c
-
-Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
-Signed-off-by: Jeff Garzik <jeff@garzik.org>
----
-
-diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
-index ac515b0..ea55654 100644
---- a/drivers/misc/eeprom_93cx6.c
-+++ b/drivers/misc/eeprom_93cx6.c
-@@ -55,10 +55,10 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
-       /*
-        * Add a short delay for the pulse to work.
--       * According to the specifications the minimal time
--       * should be 450ns so a 1us delay is sufficient.
-+       * According to the specifications the "maximum minimum"
-+       * time should be 450ns.
-        */
--      udelay(1);
-+      ndelay(450);
- }
- static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
diff --git a/target/linux/generic-2.6/patches-2.6.22/014-x86_newsetup.patch b/target/linux/generic-2.6/patches-2.6.22/014-x86_newsetup.patch
new file mode 100644 (file)
index 0000000..d73691f
--- /dev/null
@@ -0,0 +1,11942 @@
+GIT 1783e2f0f21444020e3dee1be46b1e34af0ea3e7 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-newsetup.git
+
+commit 1783e2f0f21444020e3dee1be46b1e34af0ea3e7
+Author: Venki Pallipadi <venkatesh.pallipadi@intel.com>
+Date:   Wed Jun 20 14:12:39 2007 -0700
+
+    Use a new CPU feature word to cover all Intel features that are spread around
+    
+    in different CPUID leafs like 0x5, 0x6 and 0xA. Make this
+    feature detection code common across i386 and x86_64.
+    
+    Display Intel Dynamic Acceleration feature in /proc/cpuinfo. This feature
+    will be enabled automatically by current acpi-cpufreq driver.
+    
+    Refer to Intel Software Developer's Manual for more details about the feature.
+    
+    Thanks to hpa (H Peter Anvin) for the making the actual code detecting the
+    scattered features data-driven.
+    
+    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit cd19eb67cd6636a4e5c9df99631422c7c7286f59
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed Jun 20 14:33:17 2007 -0700
+
+    x86 setup: move __bss_start into the .bss segment
+    
+    Move __bss_start into the .bss segment, and create __bss_end.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 100327ad6b609cd28970219be57d293847d1261d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed Jun 6 22:07:01 2007 -0700
+
+    x86 setup: remove TSC as a required feature
+    
+    Remove TSC as a required feature, in anticipation of CONFIG_X86_TSC
+    removal.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7c91a172b8af7d4ba087f1f88ed5b155ed459ca3
+Author: Antonino A. Daplas <adaplas@gmail.com>
+Date:   Tue Jun 5 19:21:05 2007 +0800
+
+    i386: Set 6-bit DAC channel properties in vesa video setup
+    
+    If the video BIOS is not capable of switching or failed to switch the
+    hardware to 8-bit DAC, the channel properties are not set.  This leads
+    to a blank (all black) display with vesafb at 8 bpp. Fix by defaulting
+    to a 6-bit DAC.
+    
+    Signed-off-by: Antonino Daplas <adaplas@gmail.com>
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 6eac2d442de8d87eac94a4ca8600bd87219fa06b
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue Jun 5 16:19:36 2007 -0700
+
+    x86 setup: arch/i386/boot/cpucheck.c whitespace cleanup
+    
+    Remove stealth whitespace
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit f7d89f05a30433034a1b4651143afdbb2a8a9c92
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 24 16:56:44 2007 -0700
+
+    hd.c: remove BIOS/CMOS queries
+    
+    An ST-506 disk these days is pretty much someone trying to pull ancient
+    data using an auxilliary controller.  Pulling data from the BIOS or CMOS
+    is just plain wrong, since it's likely to be the primary OS disk... and
+    would be user-entered data anyway.  Instead, require the user enters it
+    on the command line.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 14c2fdb3bbfd6a9a774980e446c2443150749891
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 24 15:25:10 2007 -0700
+
+    x86: add back pbe bit to visible CPUID flags
+    
+    Add pbe back to the visible CPUID flags.  We *do* correctly filter abuses
+    of this bit for 3DNow! in all the appropriate paths.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e071b068a3b9f318be314f0378e655e2eb50ac89
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 23 14:52:34 2007 -0700
+
+    x86 setup: VIA feature mask MSR doesn't just apply to model <= 9
+    
+    The VIA feature mask MSR is known to be present on model 10, and it
+    seems likely it will continue to be supported.  Since we only touch the
+    MSR if we're about to print an error message anyway, go ahead and be
+    aggressive.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit abe0c5aa1827932cda9c754a3842ec22b278d704
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 22 17:17:41 2007 -0700
+
+    x86 setup: correct inline assembly constraints in edd.c
+    
+    Fix the inline assembly constraints in edd.c.  In particular, "driveno"
+    was getting clobbered on some (buggy?) BIOSes.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit c2e5887ad275aab90673a3e33344f09946159cf7
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 18 10:02:55 2007 -0700
+
+    x86 setup: force the assembler to generate a 2-byte jump in header
+    
+    The jump instruction in the header only has two bytes available, so
+    it *better* be a 2-byte jump!  Unfortunately, the assembler will
+    always generate a 3/5-byte jump when the target is in a different
+    section.  Deal with that by generating the jump instruction
+    explicitly from .byte's, just like we do elsewhere when we need a
+    specific binary representation of a certain instruction.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit ce82e3b93eba48b6852822a03efa73c74e165d4f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 17 15:44:48 2007 -0700
+
+    x86 setup: move the symbol start_of_setup into the proper section.
+    
+    start_of_setup is the beginning of the executable code and should be
+    located in the appropriate section.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e5f3a529457a5bfaf8f8783fb86013221279a81c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 17 15:43:19 2007 -0700
+
+    x86 setup: add an ASSERT that the header ends up in the right place
+    
+    Just in case we have funnies involving the linker or people putting
+    inappropriate align statements, make the linker abort if the setup
+    header ends up in the wrong place.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit d9dbde725687ab99d1f529f49f14d1e280cc5cac
+Author: Alexander van Heukelum <heukelum@mailshack.com>
+Date:   Thu May 17 20:54:25 2007 +0200
+
+    x86 new setup: use appropriate sections for code and data
+    
+    An intermediate elf file is generated for the 16-bit setup code.
+    The generated code can be viewed using objdump -m i8086 -d. As it
+    stands, it also tries to disassemble the bugger_off_msg, which
+    results in garbage. This introduces two new sections to separate
+    the code and the data part of the bootsector stub. It also moves
+    some code from the .header section (a data section) to .inittext.
+    
+    Signed-off-by: Alexander van Heukelum <heukelum@mailshack.com>
+
+commit 0d7558a81cf61e9fd2332a54897c5fd18df0d7f2
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 22:03:16 2007 -0700
+
+    x86 setup: use -include code16gcc.h instead of explicit #include
+    
+    Use -include in the Makefile instead of #include to include code16gcc.h.
+    This really is more of a compiler switch than anything else, and is a lot
+    cleaner to do implicitly.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 017ce54e8a4a9628a76d6b510c7309a7e4e111a8
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 18:48:06 2007 -0700
+
+    x86 setup: enable features on Centaur (VIA) and Transmeta processors
+    
+    AMD are not the only ones who sometimes mask features which the kernel
+    may very well depend on.  VIA and Transmeta do, too.  Add code to enable
+    these features during checking.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit b794f5f9c5089709f3df38c6d91869fa38a9c1a4
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 16:37:47 2007 -0700
+
+    x86 setup: in older versions of ld, ASSERT() is an expression
+    
+    Older versions of ld (pre-2.15 or so) need:
+    
+       . = ASSERT(foo, "msg");
+    
+    instead of:
+    
+       ASSERT(foo, "msg")
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 21c2b7c99c417d07015ee8e516a634ec3d98c4ee
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 10:52:41 2007 -0700
+
+    x86 setup: print a warning message if the bootloader gave us no heap.
+    
+    If the bootloader is so old it doesn't set the CAN_USE_HEAP flag,
+    a lot of functionality will by necessity be disabled, so print a
+    warning message.  This means either a 2.00 protocol bootloader or
+    a buggy bootloader; the Qemu bootloader falls in this category.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 52ca0431390d389a2a2246f02fe652ea84c1ddd8
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 10:51:03 2007 -0700
+
+    x86 setup: rely on a compiled-in default for load high/load low
+    
+    When deciding if we should move the kernel from 0x10000 to 0x1000, as
+    is required for a zImage kernel, rely on a compiled-in default since
+    Qemu unconditionally zeroes the loadflags.  This, of course, is a bug
+    in Qemu, but still...
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 4db77a97793104a32e5fb83e62b943fa144b329d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 16 08:45:37 2007 -0700
+
+    x86 setup: correct assembly constraints.
+    
+    Double use of "d" in an asm() constraints; most gcc versions correctly
+    detect and avoid using it, but some version of gcc runs itself into
+    a brick wall instead.  Fix the one "d" which should have been "a".
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 4fbccbc1457d6710d3a9ce55ad70ec6cb0b75fc5
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 15 09:16:29 2007 -0700
+
+    x86 setup: include <asm/msr-index.h> not <asm/msr.h>
+    
+    <asm/msr.h> brings in the accessor functions, which may potentially
+    bring in all other kinds of kernel headers which are inappropriate for
+    the setup code.  For the setup code, include <asm/msr-index.h>
+    instead, which only includes the numeric constants.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 839cafa9c0020e7506722dd2a4fd82a71c2939cc
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 14 15:49:01 2007 -0700
+
+    x86 setup: protocol 2.0[01]: base for CL_OFFSET depends on setup_move_size
+    
+    Handle the use of boot protocol 2.00 and 2.01: the base segment for
+    CL_OFFSET depends on the value of setup_move_size.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit d60357ad68a694b03e9b952eadba5ac277c31df0
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 12 12:18:53 2007 -0700
+
+    x86 setup: remove unused variable
+    
+    Remove unused variable
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e21a2030b01081612259847321bcce13eae1e883
+Author: Sam Ravnborg <sam@ravnborg.org>
+Date:   Sat May 12 12:17:30 2007 -0700
+
+    x86 setup: share i386 Makefile with x86_64
+    
+    The boot Makefile for i386 and x86_64 are equal
+    except for the CFLAGS setting.
+    Teach x86_64 to use the Makefile from i386 and
+    make CFLAGS setting arch dependent in i386 Makefile.
+    
+    Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8618d92339d0d106045f98f34833d863c3235cdb
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 12 00:32:12 2007 -0700
+
+    x86 setup: video-bios.c missed the pointer to the set_mode method!
+    
+    We need the actual pointer to the set_mode method (oops!)
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 85dfc374ea9aad33b9e0315f07a4b2722dc11e3e
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 12 00:14:43 2007 -0700
+
+    x86 setup: when setting unknown BIOS modes and failing, try to revert
+    
+    If we set an unknown BIOS mode and fail, then explicitly try to revert
+    to the original mode.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit f4f7949f126d2f152b09fa9367b1ec693f2ea818
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 11 11:20:59 2007 -0700
+
+    x86 setup: fix typo "video_bios" should be "video-bios"
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 51ba7113ea5b07189b7f8a0534d400a072535197
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 11 11:09:55 2007 -0700
+
+    x86 setup: allow setting VESA modes "blind"
+    
+    Apparently, people really do set VESA modes "blind".  As a result, make
+    the framework for settting blind modes more general, to remove some
+    special cases.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 1b8f73d9b2bf7630a2914ddab606db16fddb509e
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 22:08:45 2007 -0700
+
+    x86_64: CONFIG_PHYSICAL_ALIGN should be 2 MB
+    
+    It's not actually used yet, but set CONFIG_PHYSICAL_ALIGN to 2 MB
+    as it should be, to prevent conflicts with other works in progress.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit b81f3c88923e4470cd0942d4596fafc0fb1cf4fd
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 19:11:32 2007 -0700
+
+    x86 setup: remove debugging statements
+    
+    Remove debugging statements in video.c that were not meant for
+    production.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit be58b6d7e9c14e482bce495e8343955999dea77f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 18:49:40 2007 -0700
+
+    x86 setup: only restore the screen image when needed
+    
+    Only restore the screen image when needed.  This is how the original
+    code behaves, so it's presumably the desired behaviour.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 22f6bd8cc23b512af28e34ae7d40036982a0ac63
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 18:44:08 2007 -0700
+
+    x86 setup: correct the definition of the GDT limit
+    
+    Like all other x86 segment limits, the GDT limit points to the last byte
+    that is *permitted* to access, so it needs to be sizeof(boot_gdt)-1.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7f73f1f4aa4c97745bffe07a3ebcf226a4965b00
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 15:47:48 2007 -0700
+
+    x86 setup: Re-implement scanning for hidden video modes
+    
+    Re-implement scanning for hidden video modes.  Every now and then,
+    apparently, you can find them hidden like easter eggs.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 6770176714bc12ec92372311ac02c14f0d22776e
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 10 15:24:27 2007 -0700
+
+    x86 setup: whitespace cleanup
+    
+    Clean up stealth whitespace.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit ba0480a3537cf471b08bdb99dae6d0780cfb1972
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 9 16:54:42 2007 -0700
+
+    x86: sync the CPU feature string arrays
+    
+    With <asm/cpufeature.h> unified, synchronize the CPU feature string
+    arrays.  The whole kernel/cpu directory really needs to be unified.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit ecb53b84efddbad3d9aa49e95598550831324348
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 8 22:06:04 2007 -0700
+
+    x86 setup: need to set orig_video_isVGA
+    
+    After detecting a VGA console, we need to set
+    boot_params.screen_info.orig_video_isVGA.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit dc97fc053faff17b984ec962686caea52bd27628
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 8 20:51:17 2007 -0700
+
+    x86 setup: boot sector should use ljmp, not jmpl
+    
+    We have an "jmpl" instruction in the boot sector, which was meant
+    to be an "ljmp" instruction.  It worked anyway because gas interpreted
+    a two-argument "jmpl" as an "ljmpl" instruction, however, use plain
+    "ljmp" (i.e. "ljmpw".)
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7907f05e9692557c53c9ac13647db5e5343c7c76
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 8 20:27:10 2007 -0700
+
+    x86 setup: only make VESA graphics modes selectable if CONFIG_FB
+    
+    If we select a VESA graphics mode, we better have framebuffer support
+    or the user will have no console.  Therefore, make these modes
+    non-selectable if CONFIG_FB is not set.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8e509f9ebc44f45544d231454e84f10bf78d5772
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 8 20:24:11 2007 -0700
+
+    x86 setup: need to probe VESA EDID block 0 only
+    
+    The VESA EDID BIOS call takes the EDID block number in %dx, and may
+    corrupt it by spec.  Pass it in properly.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9912b9aed7943773d1fadaa2e2e52f42af395048
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 18:22:04 2007 -0700
+
+    x86 setup: add missing file "bitops.h" missing from previous checkins
+    
+    The file "bitops.h" was missing from previous checkins.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 732eb3fac2d772980e6555b8c69902c8107c72aa
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 14:59:43 2007 -0700
+
+    x86 setup: add -fno-stack-protector; other Makefile fixes
+    
+    Add -fno-stack-protector for the gcc's that need that;
+    Use -ffreestanding consistently;
+    Use $(LINUXINCLUDE);
+    Handle linker scripts consistently with other Makefiles.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 2d5e47f21202e156fe97aba0a88d158d5c157a33
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 14:45:25 2007 -0700
+
+    x86 setup: swap cpu.c and cpucheck.c; rename functions
+    
+    Make cpucheck.c the reusable component; the generically-named cpu.c
+    gets to be the wrapper.  Accordingly, rename functions to make it
+    less confusing.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit bf2a428a4e7c1ee3ab9acb23cfafb45e818887a1
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 14:09:38 2007 -0700
+
+    x86 setup: remove code moved from cpucheck.c -> cpu.c
+    
+    Move all info about requirements into cpu.c.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9ea8429fabe5df6aed6393ac3a00d0b64445ba6a
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 09:42:51 2007 -0700
+
+    x86 setup: remove double nesting of a20_test()
+    
+    a20_test() was invoked as either a20_test() or a20_wait(), where the
+    latter was simply a loop around a loop.  Make the count a parameter
+    instead; this is clearer and saves a couple of bytes.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9edc55718f57195c664ee3175514d652f651cfd2
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 09:30:41 2007 -0700
+
+    x86 setup: compile with -fomit-frame-pointer
+    
+    Compiling with -fomit-frame-pointer reduces the size by about 2%.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e1003433f2d491bf17c79437cd75268da220dab5
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon May 7 09:30:04 2007 -0700
+
+    x86 setup: be more paranoid about the stack setup in header.S
+    
+    In particular, deal correctly with the stack pointer being zero on entry.
+    While we're at it, align the stack.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 853499c3dc3fcbeb192a613ac241d150ebc7c5a0
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sun May 6 23:25:10 2007 -0700
+
+    x86 setup: Factor out the environment-independent part of the CPU check.
+    
+    Factor out the environment-independent part of the CPU check so it can
+    be invoked from other parts of the kernel as well.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit f235a61f6d6dff57883efad351d746540bcb8caf
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 22:16:54 2007 -0700
+
+    x86 setup: when watching the setup size, take the stack into account
+    
+    When watching the setup size, we have to take the stack into account.
+    In particular, the stack is used not only by the setup code itself, but
+    by BIOS interrupt handlers and system calls.  Reserve a minimum of
+    512 bytes.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 0d0e10091be48f7e4c8888e9d5c2836c704994f5
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 19:25:51 2007 -0700
+
+    x86 setup: actually check the end of the heap.
+    
+    Keep track of where the heap ends and actually watch out for it.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 47aab0b8f4d012fad3c42b5b0754d3cb87961b37
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 15:47:58 2007 -0700
+
+    x86 setup: coppyright rPath, Inc.
+    
+    This work was done on the dime of rPath, Inc.; they own the copyright.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit d22571534d7eabf9408f29d9da423e1c6e04445f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 15:21:11 2007 -0700
+
+    x86 setup: implement screen contents save/restore
+    
+    The old setup code had screen contents save and restore, so implement
+    it for the new one as well.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e5145601a752bd998e783d159c187d3017d45d6d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 15:20:19 2007 -0700
+
+    x86 setup: whitespace cleanup
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 045ecb52f91a74eecad93ffc8791eefe59cf7fd1
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 14:22:39 2007 -0700
+
+    x86 setup: allow setting of VESA graphics modes; cleanups
+    
+    - Allow setting of VESA graphics modes (used by vesafb)
+    - Clean up the macros related to the heap
+    - #if 0 copy functions that aren't actually currently being used
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 58c04ed7e2d7d5979e1917a74b49bdc0f3dde211
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 12:06:14 2007 -0700
+
+    x86 setup: move all VESA-related code into video-vesa.c; add EDID
+    
+    - Move all VESA-related code into video-vesa.c
+    - Add VESA EDID query support
+    - Remove some totally obsolete definitions from video.h
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 07bc3931175fb98256140275c03194426d441b74
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Sat May 5 12:04:40 2007 -0700
+
+    x86-64: remove -traditional from AFLAGS
+    
+    In arch/x86_64/boot/compressed, remove -traditional from AFLAGS.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a830f615eeef838d461cbf7bbbee8c1c84708ec8
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 18:44:38 2007 -0700
+
+    x86 setup: share code between i386 and x86-64
+    
+    Share the boot (setup) code and tools between i386 and x86-64.
+    The compression code is now running in 64-bit mode in order to support
+    relocation, so do *not* share that code.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 3e159a323bdfa5d5a7be2c1f6be089ca22d598e0
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 18:43:35 2007 -0700
+
+    x86-64: use 0x1b4 as the scratch area in boot_params, not 0x3c
+    
+    Use 0x1b4 as the scratch area in boot_params rather than 0x3c.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 4cf4424e7a0f29f251b781f9b5e3655b0645cb7f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 18:26:18 2007 -0700
+
+    Revert "x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot"
+    
+    This reverts commit b2ad90f4969226fe8cf3edc5330711ed5fc20105.
+    
+    Restore arch/x86_64/boot as a separate directory hierarchy.
+    
+    Conflicts:
+
+commit 8ed1ae1d2f94410811b7cca4b1a426e37652457f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 17:00:33 2007 -0700
+
+    x86-64: It appears MTRR isn't a required feature after all.
+    
+    MTRR was documented as a required feature, but appears to boot fine
+    without it (tested since Bochs doesn't have MTRR support.)
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7c616d098579fb790662cdc703f2a0f26ea1668c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 16:22:57 2007 -0700
+
+    x86 setup: use 0x1e4 as scratch, instead of 0x3c
+    
+    The compressed relocation needs a 4-byte scratch area to obtain
+    its own address.
+    
+    0x3c is at the end of the video area, which is quite constrained -- it
+    only has 6 bytes left (12 if we recycle the obsolete fields which invade
+    this space.)  Define 0x1e4 as a scratch field, and use it.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 5bc1019227e94576e4876d05ee920f59195bce90
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 16:09:15 2007 -0700
+
+    x86 setup: boot_params.e820_map is just the map, not the count; adjust
+    
+    boot_params.e820_map is just a list of entries, whereas
+    "struct e820map" contains a count as well.  Thus, don't use
+    "struct e820map" to describe struct boot_params.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 0f96b52497f444be2d52d1184ca90be49f713ea3
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 15:49:03 2007 -0700
+
+    x86 setup: E820MAX is a definitional constant; no need to use sizeof hacks
+    
+    Now when we're using the standard headers for the setup code, we can use
+    E820MAX instead of playing sizeof games.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 3a23a428b20cbb31fd7ff5516a053b99afc447f7
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 12:08:46 2007 -0700
+
+    x86: move the bootparam structure definition into include/
+    
+    Move the bootparam structure definition into include/, and make other
+    things use it.  Haven't cleaned up all the macros yet, though.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e93ec58911995971aa059990f8a91a02b05f6c8f
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 12:07:50 2007 -0700
+
+    i386: change %lu to %u in arch/i386/kernel/e820.h
+    
+    It's an u32, print it with %u
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 2f47f004f614e2744867c0df274c55d8af2a42d5
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 12:06:04 2007 -0700
+
+    x86: fix differences between i386 and x86-64 <asm/e820.h>
+    
+    Fix minor differences between i386 and x86-64 <asm/e820.h>
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 56ec52f14e948f430af941052adee98019a617b7
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 11:45:17 2007 -0700
+
+    x86: fix the definition of struct screen_info
+    
+    Name the fields that aren't really struct screen_info, and declare
+    the structure packed (the "capabilities" field is misaligned.)
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 1d4429eaa564b0085d9ee3aa2de57e87a093a14e
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 11:43:10 2007 -0700
+
+    x86-64: Make arch/x86-64/boot a symlink to arch/i386/boot
+    
+    Until such time that Kbuild allows for a cleaner solution, make
+    arch/x86-64/boot a symlink to arch/i386/boot.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 6a85f1b5fd041ea99d8604782559ce0502a60cc0
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:42:06 2007 -0700
+
+    x86-64: rearrange includes due to unifications and inclusion from setup
+    
+    Unification caused a circular dependency between <asm/alternative.h>
+    and <asm/cpufeature.h>; resolve this.
+    
+    Add #ifndef _SETUP in <asm/e820.h> so it can be included from the boot
+    code.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit f6bbdc254bdbd5f7cf7a40c4cd6f9844af90824a
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:40:26 2007 -0700
+
+    x86: Complete <asm/cpufeature.h> with the union of i386 and x86-64
+    
+    Add a feature to <asm/cpufeature.h> which was previously present
+    in x86-64 but missing in i386.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 1a0819281060489901732914f67869e0aa8f26fd
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:39:32 2007 -0700
+
+    x86: unify <asm/boot.h>
+    
+    Unify <asm/boot.h> between i386 and x86-64
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8d9c54585f4623e0310f970fb5c6eda7ec1614df
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:38:35 2007 -0700
+
+    x86-64: verify_cpu.S: use new masks
+    
+    Use the <asm/required-features.h> masks.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 6cf3308646bb7a3210f0f76bcb895b2dea76a93c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:37:26 2007 -0700
+
+    x86-64: fix compilation errors due to required-features.h change
+    
+    Fix compilation errors induced by required-features.h change.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 1324201a93ce380b46a3128826ecbd794e617e59
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:35:37 2007 -0700
+
+    x86-64: <asm/segment.h>: add boot segment descriptors
+    
+    Add boot segment descriptors to <asm/segment.h> to match i386.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a0b15a9e79ed0310813709cd0690d6838917fe82
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:34:37 2007 -0700
+
+    x86-64: add CONFIG_PHYSICAL_ALIGN to match i386
+    
+    Add CONFIG_PHYSICAL_ALIGN to match i386, even though we don't use it.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8f5d14d11a7318e257351ae477392c7f7e314602
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 10:33:54 2007 -0700
+
+    x86 setup: cleanups for compatibility with x86-64
+    
+    These changes are necessary to compile on x86-64.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a32f68b6d4023c1c6b1e62e8561189516c571ab9
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Fri May 4 08:40:07 2007 -0700
+
+    x86 setup: add missing linker script
+    
+    Add linker script for the setup code, apparently missing from previous
+    checkins.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 4f34ca8e926b2d0bf3a7502b99f8dfced8cdba9d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 17:42:29 2007 -0700
+
+    x86 setup: paranoia: clear the high half of %esp
+    
+    We're invoked in 16-bit mode from an unknown bootloader.  Make sure
+    we explicitly zero the upper half of %esp to avoid nasty surprises.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 19eb9b73cc1632a923003a002108b242af7a6080
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 17:35:41 2007 -0700
+
+    x86 setup: bootlin is *so* dead...
+    
+    Bootlin was never able to load bzImage kernels, so who cares about it.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 3b9fb73c65151ee043bc74c333d9e3c9b1872125
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 10:56:40 2007 -0700
+
+    x86 setup: apparently $(src) is insufficient, needs $(srctree)/$(src)
+    
+    For some unfanthomable reason the location of the source tree that
+    corresponds to the current directory has to be written as
+    $(srctree)/$(src) apparently.  There might be a good reason for it,
+    but shorthand would be appreciated, and $(src) really should be the
+    short form.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a6d01d375a2269be1e3a6b31bcc4d426ad5a473d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 10:51:45 2007 -0700
+
+    x86 setup: remove reference to obsolete cpureq.c
+    
+    cpureq.c has been removed; remove it from the Makefile too.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit cbe5b7585d800435080bcbf1b1fd242926982674
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 10:33:12 2007 -0700
+
+    x86 setup: use the required masks from <asm/required-features.h>
+    
+    Use the now-uniform features from <asm/required-features.h>.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 99ed30180ecc1bb4e93f6edda5f6bad1adf3e630
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 10:31:12 2007 -0700
+
+    x86: make the handling of required features consistent
+    
+    Make the handling of required features consistent between i386
+    and x86-64.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 1120d70a2be8f2deb6bda64047da288d8f86dad3
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 00:09:53 2007 -0700
+
+    x86: Kconfig.cpu: the minimum CPU model is always 3; WP_WORKS_OK = i486
+    
+    The minimum CPU model number is always 3 (i386), and if we have
+    WP_WORKS_OK it means we need an i486.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit ebc308c204149b86984ae2216f5b9b2e63932028
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Thu May 3 00:08:48 2007 -0700
+
+    x86 setup: use CONFIG_X86_MINIMUM_CPU_MODEL
+    
+    Use CONFIG_X86_MINIMUM_CPU_MODEL as defined in Kconfig.cpu.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8b50b640e015bf5d0f65502437da6fcab46c391b
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 23:45:42 2007 -0700
+
+    x86 setup: remove bogus "static"
+    
+    Remove invalid "static" declarations in cpu.c
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 35d23b60dfb110da81c24bcbfcda089cfc4fd264
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 23:37:50 2007 -0700
+
+    x86 setup: cpu detection cleanups
+    
+    - Use <asm/processor-flags.h>
+    - Make sure %cr0 isn't in a dangerous configuration before probing the FPU
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a1150a03247b355d11a4bb696b8aae1f46612992
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 23:36:55 2007 -0700
+
+    x86 setup: compile with -DSETUP
+    
+    Define SETUP to make it easier to share code with the rest of the kernel.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7eb52e8ad1bdf01886023d1a13b3313084cd7db6
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 23:34:57 2007 -0700
+
+    x86 setup: remove unused verify_cpu.S
+    
+    verify_cpu.S is obsoleted by boot/cpu.c.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit e90317a027c30176968220d18eb18bd6a9d9cc74
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 20:07:43 2007 -0700
+
+    x86 setup: files missing from previous checkin (cpu.c, cpureq.c)
+    
+    These files were missing from a previous checkin; CPU feature-checking
+    code and the list of CPU features to check for.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 060f9b3db33c67b5344b2b4110bc823eb776e5cd
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 19:51:34 2007 -0700
+
+    x86 setup: whitespace cleanup
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9f997a5569ec8fceaa15c2e9cf28e728e2ce118d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 19:07:14 2007 -0700
+
+    x86 setup: add CPU feature detect/abort on insufficient featurage
+    
+    The x86 setup is the right place to check features and abort if they
+    are not present, since we can still get a message to the user via the
+    firmware.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit de4e976376fddec340651ef40b16a45f6189619d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 19:05:34 2007 -0700
+
+    x86 setup: whitespace cleanup
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit bcd2d2f8de5d4568b6628aa133fce1ac40ece526
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 16:19:59 2007 -0700
+
+    x86 setup: tag functions noreturn; error message on A20 failure
+    
+    Tag appropriate functions noreturn.
+    If the A20 gate fails, output an error message and refuse to boot.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 752aef90cbfc888084bf11fd83f8f72b6a668fc9
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 15:45:08 2007 -0700
+
+    x86 setup: clobber registers in keyboard BIOS call
+    
+    Keyboard BIOS call to set repeat rate is known to clobber registers on
+    "many" BIOSes.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit dde94003e4759aab275732cf9f1834440cd381d0
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 15:44:21 2007 -0700
+
+    x86 setup: implement APM BIOS probe
+    
+    APM BIOS probe ported from assembly
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9403917d79e3349184318704476fa080836bd52c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 15:17:14 2007 -0700
+
+    x86 setup: remove references to obsolete probes
+    
+    Remove "Hello, World!" as well as references to probes which are no
+    longer used...
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 712f65ffbd1d4b55b4c55d68b4dcd32406c28fb8
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 12:17:15 2007 -0700
+
+    x86 setup: video.c: correct the handling of special mode numbers
+    
+    Special mode numbers with the high bit set need to be handled *before*
+    masking out the high bit.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 9cf083204fe14cda3b09840eba8d131d2e48ccdf
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:44:16 2007 -0700
+
+    x86 setup: Modern ATI cards pass the probe but lacks the modes.
+    
+    It appears modern ATI cards pass the probe for ATI-ness but lack the
+    modes.  Kill off the driver as being incorrect.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 890cbe950589e30af17eac9da800efc76e35e01d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:32:21 2007 -0700
+
+    x86 setup: a20.c: make empty_8042() return status
+    
+    Make functions which could reasonably return status do so.  It may
+    be relevant in the future, and it's a lot better if the programmer
+    doesn't have to figure out where everything should hook in.
+    
+    Just on principle.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 08a44dc655e0086d23fc3c70cb93eb51eaeec259
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:31:03 2007 -0700
+
+    x86 setup: video.c: clean up unused stuff
+    
+    Clean up unused variables that we have no intent on using, as well
+    as other cruft.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 57e69acff1f577de430cae1523fd49a5d113e885
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:18:13 2007 -0700
+
+    x86 setup: drop video mode range checking
+    
+    Drop video mode range checking.  If someone really has, say, 12x40 mode
+    visible through the BIOS then allow them to select it... odds are low
+    that it will actually conflict with the very sparse allocation we have
+    anyway.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit c0dda0b90f92d43872d55d295630a71cd357cfa6
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:15:53 2007 -0700
+
+    x86 setup: if no specific video mode ID is given, generate one
+    
+    If we don't specify a certain video mode ID in the driver, then
+    generate the 0xRRCC mode ID automatically.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 0db5086e79810e7c5d560006b1c9a7501a02d80c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 11:10:28 2007 -0700
+
+    x86 setup: Sadly, Cirrus removed extended text modes from their BIOS.
+    
+    In the later era of the Cirrus 54xx series, Cirrus removed extended text
+    modes from their BIOS.  Neither Qemu nor Bochs implement them in the BIOS.
+    If we can find a direct-register-poking method of setting them that
+    works in Bochs/Qemu it might be worthwhile to resurrect this; the probing
+    routine *does* work.
+    
+    Of course, the Right Thing[TM] would be to submit such a routine to the
+    Bochs/Qemu BIOS as a VESA text mode.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 41f3fddeeb764687bf3fb0cf77fd858128571d58
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Wed May 2 10:18:07 2007 -0700
+
+    x86 setup: remove assembly implementation of putchar and puts
+    
+    Already unused, remove assembly implementation of putchar and puts.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit dfa94cd86aca2c01d2f5e14b6e7c3e8258276195
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:41:28 2007 -0700
+
+    x86 setup: Call INT 15h AX=E820h properly
+    
+    The calling convention for BIOS call 15:E820 was messed up.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 2487575a36435c0a983febbb4f3751331bd2df7a
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:34:12 2007 -0700
+
+    x86 setup: advance one e820 descriptor at a time...
+    
+    Adding sizeof(foo) to a foo * is not just useless, it's pretty damaging...
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 530d4f4f1732335ae8725c0b8c332a618e63ea1d
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:33:28 2007 -0700
+
+    x86 setup: fix memcmp_[fg]s()
+    
+    Actually return a value from memcmp_[fg]s()...
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 8617cd56ff2e43303147da012b26c9dd46af726e
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:32:47 2007 -0700
+
+    x86 setup: fix missing semicolon in video-ati.c
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 7bbf7fa3e199b9cef4877c5a56128faff8636cc9
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:26:48 2007 -0700
+
+    x86 setup: make the video setup code actually do something...
+    
+    Basic video setup now works (there is still work to be done, however.)
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 45bcd4406e4b812b32d317d9b3b8db2e5f135a3c
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:25:20 2007 -0700
+
+    x86 setup: segment descriptors need to be Present
+    
+    The segment descriptors were missing the Present bit.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a39479d4ccf4dceffb623ad2ec7e2d708c38c637
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:24:32 2007 -0700
+
+    build: setup sectors doesn't include the boot sector
+    
+    The "setup sectors" field doesn't include the old boot sector,
+    even though the two are now one module.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit d8f3d4928ead72e8febe2fcd740d0fee71a61f42
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:23:44 2007 -0700
+
+    x86 setup: in tty.c, actually tell it what character to print
+    
+    putchar() was missing the actual passing of the character code to the
+    BIOS call, with very silly-looking results.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 4f1462ed0377e180484a223e622d62432baa64b7
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Tue May 1 21:22:46 2007 -0700
+
+    x86 setup: printf.c needs code16gcc.h
+    
+    printf.c was missing code16gcc.h, with predictable consequences.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit a5ba7e6df198bd204b0f87fc6e3f68388b9d14c1
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon Apr 30 20:56:42 2007 -0700
+
+    MAINTAINERS: formally take responsibility for the i386 boot code
+    
+    Change MAINTAINERS to formally take responsibility for the i386 boot code.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+
+commit 6c821fc005655a99eff6e86c2e4b13654de94dea
+Author: H. Peter Anvin <hpa@zytor.com>
+Date:   Mon Apr 30 20:54:07 2007 -0700
+
+    x86 setup code rewrite: initial development snapshot
+    
+    Clean up the setup code and rewrite it in C.
+    This is an initial development snapshot, not a working tree.
+    
+    Signed-off-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+
+ MAINTAINERS                                 |    4 
+ arch/i386/Kconfig.cpu                       |    4 
+ arch/i386/boot/Makefile                     |   45 
+ arch/i386/boot/a20.c                        |  161 +
+ arch/i386/boot/apm.c                        |   97 
+ arch/i386/boot/bitops.h                     |   45 
+ arch/i386/boot/boot.h                       |  290 ++
+ arch/i386/boot/bootsect.S                   |   98 
+ arch/i386/boot/cmdline.c                    |   97 
+ arch/i386/boot/code16gcc.h                  |    9 
+ arch/i386/boot/compressed/Makefile          |    7 
+ arch/i386/boot/compressed/head.S            |    6 
+ arch/i386/boot/compressed/misc.c            |    3 
+ arch/i386/boot/copy.S                       |  101 
+ arch/i386/boot/cpu.c                        |   69 
+ arch/i386/boot/cpucheck.c                   |  266 ++
+ arch/i386/boot/edd.S                        |  231 --
+ arch/i386/boot/edd.c                        |  196 +
+ arch/i386/boot/header.S                     |  283 ++
+ arch/i386/boot/main.c                       |  161 +
+ arch/i386/boot/mca.c                        |   43 
+ arch/i386/boot/memory.c                     |   99 
+ arch/i386/boot/pm.c                         |  170 +
+ arch/i386/boot/pmjump.S                     |   54 
+ arch/i386/boot/printf.c                     |  331 ++
+ arch/i386/boot/setup.S                      | 1075 ---------
+ arch/i386/boot/setup.ld                     |   54 
+ arch/i386/boot/string.c                     |   34 
+ arch/i386/boot/tools/build.c                |  156 -
+ arch/i386/boot/tty.c                        |  112 
+ arch/i386/boot/version.c                    |   23 
+ arch/i386/boot/vesa.h                       |   79 
+ arch/i386/boot/video-bios.c                 |  125 +
+ arch/i386/boot/video-vesa.c                 |  283 ++
+ arch/i386/boot/video-vga.c                  |  260 ++
+ arch/i386/boot/video.S                      | 2043 ------------------
+ arch/i386/boot/video.c                      |  456 ++++
+ arch/i386/boot/video.h                      |  145 +
+ arch/i386/boot/voyager.c                    |   46 
+ arch/i386/kernel/cpu/addon_cpuid_features.c |   50 
+ arch/i386/kernel/cpu/common.c               |    2 
+ arch/i386/kernel/cpu/proc.c                 |   21 
+ arch/i386/kernel/e820.c                     |    2 
+ arch/i386/kernel/setup.c                    |   12 
+ arch/i386/kernel/verify_cpu.S               |   94 
+ arch/x86_64/Kconfig                         |    4 
+ arch/x86_64/boot/Makefile                   |  136 -
+ arch/x86_64/boot/bootsect.S                 |   98 
+ arch/x86_64/boot/compressed/Makefile        |    9 
+ arch/x86_64/boot/compressed/head.S          |    6 
+ arch/x86_64/boot/install.sh                 |    2 
+ arch/x86_64/boot/mtools.conf.in             |   17 
+ arch/x86_64/boot/setup.S                    |  826 -------
+ arch/x86_64/boot/tools/build.c              |  185 -
+ arch/x86_64/kernel/Makefile                 |    2 
+ arch/x86_64/kernel/setup.c                  |   21 
+ arch/x86_64/kernel/verify_cpu.S             |   22 
+ drivers/ide/legacy/hd.c                     |   73 
+ include/asm-i386/boot.h                     |    6 
+ include/asm-i386/bootparam.h                |   85 
+ include/asm-i386/cpufeature.h               |   26 
+ include/asm-i386/e820.h                     |   14 
+ include/asm-i386/processor.h                |    1 
+ include/asm-i386/required-features.h        |   37 
+ include/asm-i386/setup.h                    |   10 
+ include/asm-x86_64/alternative.h            |   68 
+ include/asm-x86_64/boot.h                   |   16 
+ include/asm-x86_64/bootparam.h              |    1 
+ include/asm-x86_64/cpufeature.h             |  115 -
+ include/asm-x86_64/e820.h                   |    6 
+ include/asm-x86_64/processor.h              |    3 
+ include/asm-x86_64/required-features.h      |   46 
+ include/asm-x86_64/segment.h                |    8 
+ include/linux/edd.h                         |    4 
+ include/linux/screen_info.h                 |    9 
+ 75 files changed, 4594 insertions(+), 5204 deletions(-)
+
+diff -puN MAINTAINERS~git-newsetup MAINTAINERS
+--- a/MAINTAINERS~git-newsetup
++++ a/MAINTAINERS
+@@ -1774,8 +1774,8 @@ T:       http://www.harbaum.org/till/i2c_tiny_
+ S:    Maintained
+ i386 BOOT CODE
+-P:    Riley H. Williams
+-M:    Riley@Williams.Name
++P:    H. Peter Anvin
++M:    hpa@zytor.com
+ L:    Linux-Kernel@vger.kernel.org
+ S:    Maintained
+diff -puN arch/i386/Kconfig.cpu~git-newsetup arch/i386/Kconfig.cpu
+--- a/arch/i386/Kconfig.cpu~git-newsetup
++++ a/arch/i386/Kconfig.cpu
+@@ -346,6 +346,6 @@ config X86_CMOV
+ config X86_MINIMUM_CPU_MODEL
+       int
+-      default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP
+-      default "0"
++      default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK
++      default "3"
+diff -puN arch/i386/boot/Makefile~git-newsetup arch/i386/boot/Makefile
+--- a/arch/i386/boot/Makefile~git-newsetup
++++ a/arch/i386/boot/Makefile
+@@ -25,27 +25,53 @@ SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+ #RAMDISK := -DRAMDISK=512
+-targets               := vmlinux.bin bootsect bootsect.o \
+-                 setup setup.o zImage bzImage
++targets               := vmlinux.bin setup.bin setup.elf zImage bzImage
+ subdir-       := compressed
++setup-y               += a20.o apm.o cmdline.o copy.o cpu.o cpucheck.o edd.o
++setup-y               += header.o main.o mca.o memory.o pm.o pmjump.o
++setup-y               += printf.o string.o tty.o video.o version.o voyager.o
++
++# The link order of the video-*.o modules can matter.  In particular,
++# video-vga.o *must* be listed first, followed by video-vesa.o.
++# Hardware-specific drivers should follow in the order they should be
++# probed, and video-bios.o should typically be last.
++setup-y               += video-vga.o
++setup-y               += video-vesa.o
++setup-y               += video-bios.o
++
+ hostprogs-y   := tools/build
+ HOSTCFLAGS_build.o := $(LINUXINCLUDE)
+ # ---------------------------------------------------------------------------
++# How to compile the 16-bit code.  Note we always compile for -march=i386,
++# that way we can complain to the user if the CPU is insufficient.
++cflags-i386   := 
++cflags-x86_64 := -m32
++CFLAGS                := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
++                 $(cflags-$(ARCH)) \
++                 -Wall -Wstrict-prototypes \
++                 -march=i386 -mregparm=3 \
++                 -include $(srctree)/$(src)/code16gcc.h \
++                 -fno-strict-aliasing -fomit-frame-pointer \
++                 $(call cc-option, -ffreestanding) \
++                 $(call cc-option, -fno-stack-protector)
++AFLAGS                := $(CFLAGS) -D__ASSEMBLY__
++
+ $(obj)/zImage:  IMAGE_OFFSET := 0x1000
+ $(obj)/zImage:  EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK)
+ $(obj)/bzImage: IMAGE_OFFSET := 0x100000
++$(obj)/bzImage: EXTRA_CFLAGS := -D__BIG_KERNEL__
+ $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
+ $(obj)/bzImage: BUILDFLAGS   := -b
+ quiet_cmd_image = BUILD   $@
+-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
++cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/setup.bin \
+           $(obj)/vmlinux.bin $(ROOT_DEV) > $@
+-$(obj)/zImage $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
++$(obj)/zImage $(obj)/bzImage: $(obj)/setup.bin \
+                             $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+       $(call if_changed,image)
+       @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+@@ -53,12 +79,17 @@ $(obj)/zImage $(obj)/bzImage: $(obj)/boo
+ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
+       $(call if_changed,objcopy)
+-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
+-LDFLAGS_setup  := -Ttext 0x0 -s --oformat binary -e begtext
++SETUP_OBJS = $(addprefix $(obj)/,$(setup-y))
+-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
++LDFLAGS_setup.elf     := -T
++$(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE
+       $(call if_changed,ld)
++OBJCOPYFLAGS_setup.bin        := -O binary
++
++$(obj)/setup.bin: $(obj)/setup.elf FORCE
++      $(call if_changed,objcopy)
++
+ $(obj)/compressed/vmlinux: FORCE
+       $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
+diff -puN /dev/null arch/i386/boot/a20.c
+--- /dev/null
++++ a/arch/i386/boot/a20.c
+@@ -0,0 +1,161 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/a20.c
++ *
++ * Enable A20 gate (return -1 on failure)
++ */
++
++#include "boot.h"
++
++#define MAX_8042_LOOPS        100000
++
++static int empty_8042(void)
++{
++      u8 status;
++      int loops = MAX_8042_LOOPS;
++
++      while (loops--) {
++              io_delay();
++
++              status = inb(0x64);
++              if (status & 1) {
++                      /* Read and discard input data */
++                      io_delay();
++                      (void)inb(0x60);
++              } else if (!(status & 2)) {
++                      /* Buffers empty, finished! */
++                      return 0;
++              }
++      }
++
++      return -1;
++}
++
++/* Returns nonzero if the A20 line is enabled.  The memory address
++   used as a test is the int $0x80 vector, which should be safe. */
++
++#define A20_TEST_ADDR (4*0x80)
++#define A20_TEST_SHORT  32
++#define A20_TEST_LONG 2097152 /* 2^21 */
++
++static int a20_test(int loops)
++{
++      int ok = 0;
++      int saved, ctr;
++
++      set_fs(0x0000);
++      set_gs(0xffff);
++
++      saved = ctr = rdfs32(A20_TEST_ADDR);
++
++      while (loops--) {
++              wrfs32(++ctr, A20_TEST_ADDR);
++              io_delay();     /* Serialize and make delay constant */
++              ok = rdgs32(A20_TEST_ADDR+0x10) ^ ctr;
++              if (ok)
++                      break;
++      }
++
++      wrfs32(saved, A20_TEST_ADDR);
++      return ok;
++}
++
++/* Quick test to see if A20 is already enabled */
++static int a20_test_short(void)
++{
++      return a20_test(A20_TEST_SHORT);
++}
++
++/* Longer test that actually waits for A20 to come on line; this
++   is useful when dealing with the KBC or other slow external circuitry. */
++static int a20_test_long(void)
++{
++      return a20_test(A20_TEST_LONG);
++}
++
++static void enable_a20_bios(void)
++{
++      asm volatile("pushfl; int $0x15; popfl"
++                   : : "a" ((u16)0x2401));
++}
++
++static void enable_a20_kbc(void)
++{
++      empty_8042();
++
++      outb(0xd1, 0x64);       /* Command write */
++      empty_8042();
++
++      outb(0xdf, 0x60);       /* A20 on */
++      empty_8042();
++}
++
++static void enable_a20_fast(void)
++{
++      u8 port_a;
++
++      port_a = inb(0x92);     /* Configuration port A */
++      port_a |=  0x02;        /* Enable A20 */
++      port_a &= ~0x01;        /* Do not reset machine */
++      outb(port_a, 0x92);
++}
++
++/*
++ * Actual routine to enable A20; return 0 on ok, -1 on failure
++ */
++
++#define A20_ENABLE_LOOPS 255  /* Number of times to try */
++
++int enable_a20(void)
++{
++      int loops = A20_ENABLE_LOOPS;
++
++#if defined(CONFIG_X86_ELAN)
++      /* Elan croaks if we try to touch the KBC */
++      enable_a20_fast();
++      while (!a20_test_long())
++              ;
++      return 0;
++#elif defined(CONFIG_X86_VOYAGER)
++      /* On Voyager, a20_test() is unsafe? */
++      enable_a20_kbc();
++      return 0;
++#else
++      while (loops--) {
++              /* First, check to see if A20 is already enabled
++                 (legacy free, etc.) */
++              if (a20_test_short())
++                      return 0;
++
++              /* Next, try the BIOS (INT 0x15, AX=0x2401) */
++              enable_a20_bios();
++              if (a20_test_short())
++                      return 0;
++
++              /* Try enabling A20 through the keyboard controller */
++              empty_8042();
++              if (a20_test_short())
++                      return 0; /* BIOS worked, but with delayed reaction */
++
++              enable_a20_kbc();
++              if (a20_test_long())
++                      return 0;
++
++              /* Finally, try enabling the "fast A20 gate" */
++              enable_a20_fast();
++              if (a20_test_long())
++                      return 0;
++      }
++
++      return -1;
++#endif
++}
+diff -puN /dev/null arch/i386/boot/apm.c
+--- /dev/null
++++ a/arch/i386/boot/apm.c
+@@ -0,0 +1,97 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   Original APM BIOS checking by Stephen Rothwell, May 1994
++ *   (sfr@canb.auug.org.au)
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/apm.c
++ *
++ * Get APM BIOS information
++ */
++
++#include "boot.h"
++
++#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
++
++int query_apm_bios(void)
++{
++      u16 ax, bx, cx, dx, di;
++      u32 ebx, esi;
++      u8 err;
++
++      /* APM BIOS installation check */
++      ax = 0x5300;
++      bx = cx = 0;
++      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
++                   : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
++                   : : "esi", "edi");
++
++      if (err)
++              return -1;              /* No APM BIOS */
++
++      if (bx != 0x504d)       /* "PM" signature */
++              return -1;
++
++      if (cx & 0x02)          /* 32 bits supported? */
++              return -1;
++
++      /* Disconnect first, just in case */
++      ax = 0x5304;
++      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
++                   : "+a" (ax)
++                   : : "ebx", "ecx", "edx", "esi", "edi");
++
++      /* Paranoia */
++      ebx = esi = 0;
++      cx = dx = di = 0;
++
++      /* 32-bit connect */
++      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %6"
++                   : "=a" (ax), "+b" (ebx), "+c" (cx), "+d" (dx),
++                     "+S" (esi), "+D" (di), "=m" (err)
++                   : "a" (0x5303));
++
++      boot_params.apm_bios_info.cseg = ax;
++      boot_params.apm_bios_info.offset = ebx;
++      boot_params.apm_bios_info.cseg_16 = cx;
++      boot_params.apm_bios_info.dseg = dx;
++      boot_params.apm_bios_info.cseg_len = (u16)esi;
++      boot_params.apm_bios_info.cseg_16_len = esi >> 16;
++      boot_params.apm_bios_info.dseg_len = di;
++
++      if (err)
++              return -1;
++
++      /* Redo the installation check as the 32-bit connect;
++         some BIOSes return different flags this way... */
++
++      ax = 0x5300;
++      bx = cx = 0;
++      asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp ; setc %0"
++                   : "=d" (err), "+a" (ax), "+b" (bx), "+c" (cx)
++                   : : "esi", "edi");
++
++      if (err || bx != 0x504d) {
++              /* Failure with 32-bit connect, try to disconect and ignore */
++              ax = 0x5304;
++              bx = 0;
++              asm volatile("pushl %%ebp ; int $0x15 ; popl %%ebp"
++                           : "+a" (ax), "+b" (bx)
++                           : : "ecx", "edx", "esi", "edi");
++              return -1;
++      }
++
++      boot_params.apm_bios_info.version = ax;
++      boot_params.apm_bios_info.flags = cx;
++      return 0;
++}
++
++#endif
+diff -puN /dev/null arch/i386/boot/bitops.h
+--- /dev/null
++++ a/arch/i386/boot/bitops.h
+@@ -0,0 +1,45 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/bitops.h
++ *
++ * Very simple bitops for the boot code.
++ */
++
++#ifndef BOOT_BITOPS_H
++#define BOOT_BITOPS_H
++#define _LINUX_BITOPS_H               /* Inhibit inclusion of <linux/bitops.h> */
++
++static inline int constant_test_bit(int nr, const void *addr)
++{
++      const u32 *p = (const u32 *)addr;
++      return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
++}
++static inline int variable_test_bit(int nr, const void *addr)
++{
++      u8 v;
++      const u32 *p = (const u32 *)addr;
++
++      asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
++      return v;
++}
++
++#define test_bit(nr,addr) \
++(__builtin_constant_p(nr) ? \
++ constant_test_bit((nr),(addr)) : \
++ variable_test_bit((nr),(addr)))
++
++static inline void set_bit(int nr, void *addr)
++{
++      asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
++}
++
++#endif /* BOOT_BITOPS_H */
+diff -puN /dev/null arch/i386/boot/boot.h
+--- /dev/null
++++ a/arch/i386/boot/boot.h
+@@ -0,0 +1,290 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/boot.h
++ *
++ * Header file for the real-mode kernel code
++ */
++
++#ifndef BOOT_BOOT_H
++#define BOOT_BOOT_H
++
++#ifndef __ASSEMBLY__
++
++#include <stdarg.h>
++#include <linux/types.h>
++#include <linux/edd.h>
++#include <asm/boot.h>
++#include <asm/bootparam.h>
++
++/* Useful macros */
++#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
++
++extern struct setup_header hdr;
++extern struct boot_params boot_params;
++
++/* Basic port I/O */
++static inline void outb(u8 v, u16 port)
++{
++      asm volatile("outb %0,%1" : : "a" (v), "dN" (port));
++}
++static inline u8 inb(u16 port)
++{
++      u8 v;
++      asm volatile("inb %1,%0" : "=a" (v) : "dN" (port));
++      return v;
++}
++
++static inline void outw(u16 v, u16 port)
++{
++      asm volatile("outw %0,%1" : : "a" (v), "dN" (port));
++}
++static inline u16 inw(u16 port)
++{
++      u16 v;
++      asm volatile("inw %1,%0" : "=a" (v) : "dN" (port));
++      return v;
++}
++
++static inline void outl(u32 v, u16 port)
++{
++      asm volatile("outl %0,%1" : : "a" (v), "dn" (port));
++}
++static inline u32 inl(u32 port)
++{
++      u32 v;
++      asm volatile("inl %1,%0" : "=a" (v) : "dN" (port));
++      return v;
++}
++
++static inline void io_delay(void)
++{
++      const u16 DELAY_PORT = 0x80;
++      asm volatile("outb %%al,%0" : : "dN" (DELAY_PORT));
++}
++
++/* These functions are used to reference data in other segments. */
++
++static inline u16 ds(void)
++{
++      u16 seg;
++      asm("movw %%ds,%0" : "=rm" (seg));
++      return seg;
++}
++
++static inline void set_fs(u16 seg)
++{
++      asm volatile("movw %0,%%fs" : : "rm" (seg));
++}
++static inline u16 fs(void)
++{
++      u16 seg;
++      asm("movw %%fs,%0" : "=rm" (seg));
++      return seg;
++}
++
++static inline void set_gs(u16 seg)
++{
++      asm volatile("movw %0,%%gs" : : "rm" (seg));
++}
++static inline u16 gs(void)
++{
++      u16 seg;
++      asm("movw %%gs,%0" : "=rm" (seg));
++      return seg;
++}
++
++typedef unsigned int addr_t;
++
++static inline u8 rdfs8(addr_t addr)
++{
++      u8 v;
++      asm("movb %%fs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
++      return v;
++}
++static inline u16 rdfs16(addr_t addr)
++{
++      u16 v;
++      asm("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
++      return v;
++}
++static inline u32 rdfs32(addr_t addr)
++{
++      u32 v;
++      asm("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
++      return v;
++}
++
++static inline void wrfs8(u8 v, addr_t addr)
++{
++      asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "r" (v));
++}
++static inline void wrfs16(u16 v, addr_t addr)
++{
++      asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "r" (v));
++}
++static inline void wrfs32(u32 v, addr_t addr)
++{
++      asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "r" (v));
++}
++
++static inline u8 rdgs8(addr_t addr)
++{
++      u8 v;
++      asm("movb %%gs:%1,%0" : "=r" (v) : "m" (*(u8 *)addr));
++      return v;
++}
++static inline u16 rdgs16(addr_t addr)
++{
++      u16 v;
++      asm("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
++      return v;
++}
++static inline u32 rdgs32(addr_t addr)
++{
++      u32 v;
++      asm("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
++      return v;
++}
++
++static inline void wrgs8(u8 v, addr_t addr)
++{
++      asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "r" (v));
++}
++static inline void wrgs16(u16 v, addr_t addr)
++{
++      asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "r" (v));
++}
++static inline void wrgs32(u32 v, addr_t addr)
++{
++      asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "r" (v));
++}
++
++/* Note: these only return true/false, not a signed return value! */
++static inline int memcmp(const void *s1, const void *s2, size_t len)
++{
++      u8 diff;
++      asm("repe; cmpsb; setnz %0"
++          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
++      return diff;
++}
++
++static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
++{
++      u8 diff;
++      asm("fs; repe; cmpsb; setnz %0"
++          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
++      return diff;
++}
++static inline int memcmp_gs(const void *s1, addr_t s2, size_t len)
++{
++      u8 diff;
++      asm("gs; repe; cmpsb; setnz %0"
++          : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
++      return diff;
++}
++
++/* Heap -- available for dynamic lists. */
++#define STACK_SIZE    512     /* Minimum number of bytes for stack */
++
++extern char _end[];
++extern char *HEAP;
++extern char *heap_end;
++#define RESET_HEAP() ((void *)( HEAP = _end ))
++static inline char *__get_heap(size_t s, size_t a, size_t n)
++{
++      char *tmp;
++
++      HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
++      tmp = HEAP;
++      HEAP += s*n;
++      return tmp;
++}
++#define GET_HEAP(type, n) \
++      ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
++
++static inline int heap_free(void)
++{
++      return heap_end-HEAP;
++}
++
++/* copy.S */
++
++void copy_to_fs(addr_t dst, void *src, size_t len);
++void *copy_from_fs(void *dst, addr_t src, size_t len);
++void copy_to_gs(addr_t dst, void *src, size_t len);
++void *copy_from_gs(void *dst, addr_t src, size_t len);
++void *memcpy(void *dst, void *src, size_t len);
++void *memset(void *dst, int c, size_t len);
++
++#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
++#define memset(d,c,l) __builtin_memset(d,c,l)
++
++/* a20.c */
++int enable_a20(void);
++
++/* apm.c */
++int query_apm_bios(void);
++
++/* cmdline.c */
++int cmdline_find_option(const char *option, char *buffer, int bufsize);
++
++/* cpu.c, cpucheck.c */
++int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
++int validate_cpu(void);
++
++/* edd.c */
++void query_edd(void);
++
++/* header.S */
++void __attribute__((noreturn)) die(void);
++
++/* mca.c */
++int query_mca(void);
++
++/* memory.c */
++int detect_memory(void);
++
++/* pm.c */
++void __attribute__((noreturn)) go_to_protected_mode(void);
++
++/* pmjump.S */
++void __attribute__((noreturn))
++      protected_mode_jump(u32 entrypoint, u32 bootparams);
++
++/* printf.c */
++unsigned int atou(const char *s);
++int sprintf(char *buf, const char *fmt, ...);
++int vsprintf(char *buf, const char *fmt, va_list args);
++int printf(const char *fmt, ...);
++
++/* string.c */
++int strcmp(const char *str1, const char *str2);
++
++/* tty.c */
++void puts(const char *);
++void putchar(int);
++int getchar(void);
++void kbd_flush(void);
++int getchar_timeout(void);
++
++/* video.c */
++void set_video(void);
++
++/* video-vesa.c */
++void vesa_store_edid(void);
++
++/* voyager.c */
++int query_voyager(void);
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* BOOT_BOOT_H */
+diff -puN arch/i386/boot/bootsect.S~git-newsetup /dev/null
+--- a/arch/i386/boot/bootsect.S
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- *    bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
+- *
+- *    modified by Drew Eckhardt
+- *    modified by Bruce Evans (bde)
+- *    modified by Chris Noe (May 1999) (as86 -> gas)
+- *    gutted by H. Peter Anvin (Jan 2003)
+- *
+- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
+- * addresses must be multiplied by 16 to obtain their respective linear
+- * addresses. To avoid confusion, linear addresses are written using leading
+- * hex while segment addresses are written as segment:offset.
+- *
+- */
+-
+-#include <asm/boot.h>
+-
+-SETUPSECTS    = 4                     /* default nr of setup-sectors */
+-BOOTSEG               = 0x07C0                /* original address of boot-sector */
+-INITSEG               = DEF_INITSEG           /* we move boot here - out of the way */
+-SETUPSEG      = DEF_SETUPSEG          /* setup starts here */
+-SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
+-SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
+-                                      /* to be loaded */
+-ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
+-SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
+-
+-#ifndef SVGA_MODE
+-#define SVGA_MODE ASK_VGA
+-#endif
+-
+-#ifndef RAMDISK
+-#define RAMDISK 0
+-#endif
+-
+-#ifndef ROOT_RDONLY
+-#define ROOT_RDONLY 1
+-#endif
+-
+-.code16
+-.text
+-
+-.global _start
+-_start:
+-
+-      # Normalize the start address
+-      jmpl    $BOOTSEG, $start2
+-
+-start2:
+-      movw    %cs, %ax
+-      movw    %ax, %ds
+-      movw    %ax, %es
+-      movw    %ax, %ss
+-      movw    $0x7c00, %sp
+-      sti
+-      cld
+-
+-      movw    $bugger_off_msg, %si
+-
+-msg_loop:
+-      lodsb
+-      andb    %al, %al
+-      jz      die
+-      movb    $0xe, %ah
+-      movw    $7, %bx
+-      int     $0x10
+-      jmp     msg_loop
+-
+-die:
+-      # Allow the user to press a key, then reboot
+-      xorw    %ax, %ax
+-      int     $0x16
+-      int     $0x19
+-
+-      # int 0x19 should never return.  In case it does anyway,
+-      # invoke the BIOS reset code...
+-      ljmp    $0xf000,$0xfff0
+-
+-
+-bugger_off_msg:
+-      .ascii  "Direct booting from floppy is no longer supported.\r\n"
+-      .ascii  "Please use a boot loader program instead.\r\n"
+-      .ascii  "\n"
+-      .ascii  "Remove disk and press any key to reboot . . .\r\n"
+-      .byte   0
+-
+-
+-      # Kernel attributes; used by setup
+-
+-      .org 497
+-setup_sects:  .byte SETUPSECTS
+-root_flags:   .word ROOT_RDONLY
+-syssize:      .word SYSSIZE
+-swap_dev:     .word SWAP_DEV
+-ram_size:     .word RAMDISK
+-vid_mode:     .word SVGA_MODE
+-root_dev:     .word ROOT_DEV
+-boot_flag:    .word 0xAA55
+diff -puN /dev/null arch/i386/boot/cmdline.c
+--- /dev/null
++++ a/arch/i386/boot/cmdline.c
+@@ -0,0 +1,97 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/cmdline.c
++ *
++ * Simple command-line parser for early boot.
++ */
++
++#include "boot.h"
++
++static inline int myisspace(u8 c)
++{
++      return c <= ' ';        /* Close enough approximation */
++}
++
++/*
++ * Find a non-boolean option, that is, "option=argument".  In accordance
++ * with standard Linux practice, if this option is repeated, this returns
++ * the last instance on the command line.
++ *
++ * Returns the length of the argument (regardless of if it was
++ * truncated to fit in the buffer), or -1 on not found.
++ */
++int cmdline_find_option(const char *option, char *buffer, int bufsize)
++{
++      u32 cmdline_ptr = boot_params.hdr.cmd_line_ptr;
++      addr_t cptr;
++      char c;
++      int len = -1;
++      const char *opptr = NULL;
++      char *bufptr = buffer;
++      enum {
++              st_wordstart,   /* Start of word/after whitespace */
++              st_wordcmp,     /* Comparing this word */
++              st_wordskip,    /* Miscompare, skip */
++              st_bufcpy       /* Copying this to buffer */
++      } state = st_wordstart;
++
++      if (!cmdline_ptr || cmdline_ptr >= 0x100000)
++              return -1;      /* No command line, or inaccessible */
++
++      cptr = cmdline_ptr & 0xf;
++      set_fs(cmdline_ptr >> 4);
++
++      while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
++              switch (state) {
++              case st_wordstart:
++                      if (myisspace(c))
++                              break;
++
++                      /* else */
++                      state = st_wordcmp;
++                      opptr = option;
++                      /* fall through */
++
++              case st_wordcmp:
++                      if (c == '=' && !*opptr) {
++                              len = 0;
++                              bufptr = buffer;
++                              state = st_bufcpy;
++                      } else if (myisspace(c)) {
++                              state = st_wordstart;
++                      } else if (c != *opptr++) {
++                              state = st_wordskip;
++                      }
++                      break;
++
++              case st_wordskip:
++                      if (myisspace(c))
++                              state = st_wordstart;
++                      break;
++
++              case st_bufcpy:
++                      if (myisspace(c)) {
++                              state = st_wordstart;
++                      } else {
++                              if (len < bufsize-1)
++                                      *bufptr++ = c;
++                              len++;
++                      }
++                      break;
++              }
++      }
++
++      if (bufsize)
++              *bufptr = '\0';
++
++      return len;
++}
+diff -puN /dev/null arch/i386/boot/code16gcc.h
+--- /dev/null
++++ a/arch/i386/boot/code16gcc.h
+@@ -0,0 +1,9 @@
++/*
++ * code16gcc.h
++ *
++ * This file is -include'd when compiling 16-bit C code.
++ */
++
++#ifndef __ASSEMBLY__
++asm(".code16gcc");
++#endif
+diff -puN arch/i386/boot/compressed/Makefile~git-newsetup arch/i386/boot/compressed/Makefile
+--- a/arch/i386/boot/compressed/Makefile~git-newsetup
++++ a/arch/i386/boot/compressed/Makefile
+@@ -9,9 +9,14 @@ targets               := vmlinux vmlinux.bin vmlinux.
+ EXTRA_AFLAGS  := -traditional
+ LDFLAGS_vmlinux := -T
+-CFLAGS_misc.o += -fPIC
+ hostprogs-y   := relocs
++CFLAGS  := -m32 -D__KERNEL__ $(LINUX_INCLUDE) -O2 \
++         -fno-strict-aliasing -fPIC \
++         $(call cc-option,-ffreestanding) \
++         $(call cc-option,-fno-stack-protector)
++LDFLAGS := -m elf_i386
++
+ $(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE
+       $(call if_changed,ld)
+       @:
+diff -puN arch/i386/boot/compressed/head.S~git-newsetup arch/i386/boot/compressed/head.S
+--- a/arch/i386/boot/compressed/head.S~git-newsetup
++++ a/arch/i386/boot/compressed/head.S
+@@ -45,10 +45,10 @@ startup_32:
+  * at and where we were actually loaded at.  This can only be done
+  * with a short local call on x86.  Nothing  else will tell us what
+  * address we are running at.  The reserved chunk of the real-mode
+- * data at 0x34-0x3f are used as the stack for this calculation.
+- * Only 4 bytes are needed.
++ * data at 0x1e4 (defined as a scratch field) are used as the stack
++ * for this calculation. Only 4 bytes are needed.
+  */
+-      leal 0x40(%esi), %esp
++      leal (0x1e4+4)(%esi), %esp
+       call 1f
+ 1:    popl %ebp
+       subl $1b, %ebp
+diff -puN arch/i386/boot/compressed/misc.c~git-newsetup arch/i386/boot/compressed/misc.c
+--- a/arch/i386/boot/compressed/misc.c~git-newsetup
++++ a/arch/i386/boot/compressed/misc.c
+@@ -11,7 +11,6 @@
+ #undef CONFIG_PARAVIRT
+ #include <linux/linkage.h>
+-#include <linux/vmalloc.h>
+ #include <linux/screen_info.h>
+ #include <asm/io.h>
+ #include <asm/page.h>
+@@ -364,8 +363,10 @@ asmlinkage void decompress_kernel(void *
+       if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1))
+               error("Destination address not CONFIG_PHYSICAL_ALIGN aligned");
++#ifndef CONFIG_X86_64
+       if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff))
+               error("Destination address too large");
++#endif
+ #ifndef CONFIG_RELOCATABLE
+       if ((u32)output != LOAD_PHYSICAL_ADDR)
+               error("Wrong destination address");
+diff -puN /dev/null arch/i386/boot/copy.S
+--- /dev/null
++++ a/arch/i386/boot/copy.S
+@@ -0,0 +1,101 @@
++/* ----------------------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/copy.S
++ *
++ * Memory copy routines
++ */
++
++      .code16gcc
++      .text
++
++      .globl  memcpy
++      .type   memcpy, @function
++memcpy:
++      pushw   %si
++      pushw   %di
++      movw    %ax, %di
++      movw    %dx, %si
++      pushw   %cx
++      shrw    $2, %cx
++      rep; movsl
++      popw    %cx
++      andw    $3, %cx
++      rep; movsb
++      popw    %di
++      popw    %si
++      ret
++      .size   memcpy, .-memcpy
++
++      .globl  memset
++      .type   memset, @function
++memset:
++      pushw   %di
++      movw    %ax, %di
++      movzbl  %dl, %eax
++      imull   $0x01010101,%eax
++      pushw   %cx
++      shrw    $2, %cx
++      rep; stosl
++      popw    %cx
++      andw    $3, %cx
++      rep; stosb
++      popw    %di
++      ret
++      .size   memset, .-memset
++
++      .globl  copy_from_fs
++      .type   copy_from_fs, @function
++copy_from_fs:
++      pushw   %ds
++      pushw   %fs
++      popw    %ds
++      call    memcpy
++      popw    %ds
++      ret
++      .size   copy_from_fs, .-copy_from_fs
++
++      .globl  copy_to_fs
++      .type   copy_to_fs, @function
++copy_to_fs:
++      pushw   %es
++      pushw   %fs
++      popw    %es
++      call    memcpy
++      popw    %es
++      ret
++      .size   copy_to_fs, .-copy_to_fs
++
++#if 0 /* Not currently used, but can be enabled as needed */
++
++      .globl  copy_from_gs
++      .type   copy_from_gs, @function
++copy_from_gs:
++      pushw   %ds
++      pushw   %gs
++      popw    %ds
++      call    memcpy
++      popw    %ds
++      ret
++      .size   copy_from_gs, .-copy_from_gs
++      .globl  copy_to_gs
++
++      .type   copy_to_gs, @function
++copy_to_gs:
++      pushw   %es
++      pushw   %gs
++      popw    %es
++      call    memcpy
++      popw    %es
++      ret
++      .size   copy_to_gs, .-copy_to_gs
++
++#endif
+diff -puN /dev/null arch/i386/boot/cpu.c
+--- /dev/null
++++ a/arch/i386/boot/cpu.c
+@@ -0,0 +1,69 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/cpucheck.c
++ *
++ * Check for obligatory CPU features and abort if the features are not
++ * present.
++ */
++
++#include "boot.h"
++#include "bitops.h"
++#include <asm/cpufeature.h>
++
++static char *cpu_name(int level)
++{
++      static char buf[6];
++
++      if (level == 64) {
++              return "x86-64";
++      } else {
++              sprintf(buf, "i%d86", level);
++              return buf;
++      }
++}
++
++int validate_cpu(void)
++{
++      u32 *err_flags;
++      int cpu_level, req_level;
++
++      check_cpu(&cpu_level, &req_level, &err_flags);
++
++      if (cpu_level < req_level) {
++              printf("This kernel requires an %s CPU, ",
++                     cpu_name(req_level));
++              printf("but only detected an %s CPU.\n",
++                     cpu_name(cpu_level));
++              return -1;
++      }
++
++      if (err_flags) {
++              int i, j;
++              puts("This kernel requires the following features "
++                   "not present on the CPU:\n");
++
++              for (i = 0; i < NCAPINTS; i++) {
++                      u32 e = err_flags[i];
++
++                      for (j = 0; j < 32; j++) {
++                              if (e & 1)
++                                      printf("%d:%d ", i, j);
++
++                              e >>= 1;
++                      }
++              }
++              putchar('\n');
++              return -1;
++      } else {
++              return 0;
++      }
++}
+diff -puN /dev/null arch/i386/boot/cpucheck.c
+--- /dev/null
++++ a/arch/i386/boot/cpucheck.c
+@@ -0,0 +1,266 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/cpu.c
++ *
++ * Check for obligatory CPU features and abort if the features are not
++ * present.  This code should be compilable as 16-, 32- or 64-bit
++ * code, so be very careful with types and inline assembly.
++ *
++ * This code should not contain any messages; that requires an
++ * additional wrapper.
++ *
++ * As written, this code is not safe for inclusion into the kernel
++ * proper (after FPU initialization, in particular).
++ */
++
++#ifdef _SETUP
++# include "boot.h"
++# include "bitops.h"
++#endif
++#include <linux/types.h>
++#include <asm/cpufeature.h>
++#include <asm/processor-flags.h>
++#include <asm/required-features.h>
++#include <asm/msr-index.h>
++
++struct cpu_features {
++      int level;
++      int model;
++      u32 flags[NCAPINTS];
++};
++
++static struct cpu_features cpu;
++static u32 cpu_vendor[3];
++static u32 err_flags[NCAPINTS];
++
++#ifdef CONFIG_X86_64
++static const int req_level = 64;
++#elif defined(CONFIG_X86_MINIMUM_CPU_MODEL)
++static const int req_level = CONFIG_X86_MINIMUM_CPU_MODEL;
++#else
++static const int req_level = 3;
++#endif
++
++static const u32 req_flags[NCAPINTS] =
++{
++      REQUIRED_MASK0,
++      REQUIRED_MASK1,
++      REQUIRED_MASK2,
++      REQUIRED_MASK3,
++      REQUIRED_MASK4,
++      REQUIRED_MASK5,
++      REQUIRED_MASK6,
++};
++
++#define A32(a,b,c,d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
++
++static int is_amd(void)
++{
++      return cpu_vendor[0] == A32('A','u','t','h') &&
++             cpu_vendor[1] == A32('e','n','t','i') &&
++             cpu_vendor[2] == A32('c','A','M','D');
++}
++
++static int is_centaur(void)
++{
++      return cpu_vendor[0] == A32('C','e','n','t') &&
++             cpu_vendor[1] == A32('a','u','r','H') &&
++             cpu_vendor[2] == A32('a','u','l','s');
++}
++
++static int is_transmeta(void)
++{
++      return cpu_vendor[0] == A32('G','e','n','u') &&
++             cpu_vendor[1] == A32('i','n','e','T') &&
++             cpu_vendor[2] == A32('M','x','8','6');
++}
++
++static int has_fpu(void)
++{
++      u16 fcw = -1, fsw = -1;
++      u32 cr0;
++
++      asm("movl %%cr0,%0" : "=r" (cr0));
++      if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
++              cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
++              asm volatile("movl %0,%%cr0" : : "r" (cr0));
++      }
++
++      asm("fninit ; fnstsw %0 ; fnstcw %1" : "+m" (fsw), "+m" (fcw));
++
++      return fsw == 0 && (fcw & 0x103f) == 0x003f;
++}
++
++static int has_eflag(u32 mask)
++{
++      u32 f0, f1;
++
++      asm("pushfl ; "
++          "pushfl ; "
++          "popl %0 ; "
++          "movl %0,%1 ; "
++          "xorl %2,%1 ; "
++          "pushl %1 ; "
++          "popfl ; "
++          "pushfl ; "
++          "popl %1 ; "
++          "popfl"
++          : "=r" (f0), "=r" (f1)
++          : "g" (mask));
++
++      return !!((f0^f1) & mask);
++}
++
++static void get_flags(void)
++{
++      u32 max_intel_level, max_amd_level;
++      u32 tfms;
++
++      if (has_fpu())
++              set_bit(X86_FEATURE_FPU, cpu.flags);
++
++      if (has_eflag(X86_EFLAGS_ID)) {
++              asm("cpuid"
++                  : "=a" (max_intel_level),
++                    "=b" (cpu_vendor[0]),
++                    "=d" (cpu_vendor[1]),
++                    "=c" (cpu_vendor[2])
++                  : "a" (0));
++
++              if (max_intel_level >= 0x00000001 &&
++                  max_intel_level <= 0x0000ffff) {
++                      asm("cpuid"
++                          : "=a" (tfms),
++                            "=c" (cpu.flags[4]),
++                            "=d" (cpu.flags[0])
++                          : "a" (0x00000001)
++                          : "ebx");
++                      cpu.level = (tfms >> 8) & 15;
++                      cpu.model = (tfms >> 4) & 15;
++                      if (cpu.level >= 6)
++                              cpu.model += ((tfms >> 16) & 0xf) << 4;
++              }
++
++              asm("cpuid"
++                  : "=a" (max_amd_level)
++                  : "a" (0x80000000)
++                  : "ebx", "ecx", "edx");
++
++              if (max_amd_level >= 0x80000001 &&
++                  max_amd_level <= 0x8000ffff) {
++                      u32 eax = 0x80000001;
++                      asm("cpuid"
++                          : "+a" (eax),
++                            "=c" (cpu.flags[6]),
++                            "=d" (cpu.flags[1])
++                          : : "ebx");
++              }
++      }
++}
++
++/* Returns a bitmask of which words we have error bits in */
++static int check_flags(void)
++{
++      u32 err;
++      int i;
++
++      err = 0;
++      for (i = 0; i < NCAPINTS; i++) {
++              err_flags[i] = req_flags[i] & ~cpu.flags[i];
++              if (err_flags[i])
++                      err |= 1 << i;
++      }
++
++      return err;
++}
++
++/*
++ * Returns -1 on error.
++ *
++ * *cpu_level is set to the current CPU level; *req_level to the required
++ * level.  x86-64 is considered level 64 for this purpose.
++ *
++ * *err_flags_ptr is set to the flags error array if there are flags missing.
++ */
++int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)
++{
++      int err;
++
++      memset(&cpu.flags, 0, sizeof cpu.flags);
++      cpu.level = 3;
++
++      if (has_eflag(X86_EFLAGS_AC))
++              cpu.level = 4;
++
++      get_flags();
++      err = check_flags();
++
++      if (test_bit(X86_FEATURE_LM, cpu.flags))
++              cpu.level = 64;
++
++      if (err == 0x01 &&
++          !(err_flags[0] &
++            ~((1 << X86_FEATURE_XMM)|(1 << X86_FEATURE_XMM2))) &&
++          is_amd()) {
++              /* If this is an AMD and we're only missing SSE+SSE2, try to
++                 turn them on */
++
++              u32 ecx = MSR_K7_HWCR;
++              u32 eax, edx;
++
++              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++              eax &= ~(1 << 15);
++              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++
++              get_flags();    /* Make sure it really did something */
++              err = check_flags();
++      } else if (err == 0x01 &&
++                 !(err_flags[0] & ~(1 << X86_FEATURE_CX8)) &&
++                 is_centaur() && cpu.model >= 6) {
++              /* If this is a VIA C3, we might have to enable CX8
++                 explicitly */
++
++              u32 ecx = MSR_VIA_FCR;
++              u32 eax, edx;
++
++              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++              eax |= (1<<1)|(1<<7);
++              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++
++              set_bit(X86_FEATURE_CX8, cpu.flags);
++              err = check_flags();
++      } else if (err == 0x01 && is_transmeta()) {
++              /* Transmeta might have masked feature bits in word 0 */
++
++              u32 ecx = 0x80860004;
++              u32 eax, edx;
++              u32 level = 1;
++
++              asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
++              asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
++              asm("cpuid"
++                  : "+a" (level), "=d" (cpu.flags[0])
++                  : : "ecx", "ebx");
++              asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
++
++              err = check_flags();
++      }
++
++      if (err_flags_ptr)
++              *err_flags_ptr = err ? err_flags : NULL;
++      if (cpu_level_ptr)
++              *cpu_level_ptr = cpu.level;
++      if (req_level_ptr)
++              *req_level_ptr = req_level;
++
++      return (cpu.level < req_level || err) ? -1 : 0;
++}
+diff -puN arch/i386/boot/edd.S~git-newsetup /dev/null
+--- a/arch/i386/boot/edd.S
++++ /dev/null
+@@ -1,231 +0,0 @@
+-/*
+- * BIOS Enhanced Disk Drive support
+- * Copyright (C) 2002, 2003, 2004 Dell, Inc.
+- * by Matt Domsch <Matt_Domsch@dell.com> October 2002
+- * conformant to T13 Committee www.t13.org
+- *   projects 1572D, 1484D, 1386D, 1226DT
+- * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
+- *    and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
+- * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
+- *      March 2004
+- * Command line option parsing, Matt Domsch, November 2004
+- */
+-
+-#include <linux/edd.h>
+-#include <asm/setup.h>
+-
+-#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+-
+-# It is assumed that %ds == INITSEG here
+-
+-      movb    $0, (EDD_MBR_SIG_NR_BUF)
+-      movb    $0, (EDDNR)
+-
+-# Check the command line for options:
+-# edd=of  disables EDD completely  (edd=off)
+-# edd=sk  skips the MBR test    (edd=skipmbr)
+-# edd=on  re-enables EDD (edd=on)
+-
+-      pushl   %esi
+-      movw    $edd_mbr_sig_start, %di # Default to edd=on
+-
+-      movl    %cs:(cmd_line_ptr), %esi
+-      andl    %esi, %esi
+-      jz      old_cl                  # Old boot protocol?
+-
+-# Convert to a real-mode pointer in fs:si
+-      movl    %esi, %eax
+-      shrl    $4, %eax
+-      movw    %ax, %fs
+-      andw    $0xf, %si
+-      jmp     have_cl_pointer
+-
+-# Old-style boot protocol?
+-old_cl:
+-      push    %ds                     # aka INITSEG
+-      pop     %fs
+-
+-      cmpw    $0xa33f, (0x20)
+-      jne     done_cl                 # No command line at all?
+-      movw    (0x22), %si             # Pointer relative to INITSEG
+-
+-# fs:si has the pointer to the command line now
+-have_cl_pointer:
+-
+-# Loop through kernel command line one byte at a time.  Just in
+-# case the loader is buggy and failed to null-terminate the command line
+-# terminate if we get close enough to the end of the segment that we
+-# cannot fit "edd=XX"...
+-cl_atspace:
+-      cmpw    $-5, %si                # Watch for segment wraparound
+-      jae     done_cl
+-      movl    %fs:(%si), %eax
+-      andb    %al, %al                # End of line?
+-      jz      done_cl
+-      cmpl    $EDD_CL_EQUALS, %eax
+-      jz      found_edd_equals
+-      cmpb    $0x20, %al              # <= space consider whitespace
+-      ja      cl_skipword
+-      incw    %si
+-      jmp     cl_atspace
+-
+-cl_skipword:
+-      cmpw    $-5, %si                # Watch for segment wraparound
+-      jae     done_cl
+-      movb    %fs:(%si), %al          # End of string?
+-      andb    %al, %al
+-      jz      done_cl
+-      cmpb    $0x20, %al
+-      jbe     cl_atspace
+-      incw    %si
+-      jmp     cl_skipword
+-
+-found_edd_equals:
+-# only looking at first two characters after equals
+-# late overrides early on the command line, so keep going after finding something
+-      movw    %fs:4(%si), %ax
+-      cmpw    $EDD_CL_OFF, %ax        # edd=of
+-      je      do_edd_off
+-      cmpw    $EDD_CL_SKIP, %ax       # edd=sk
+-      je      do_edd_skipmbr
+-      cmpw    $EDD_CL_ON, %ax         # edd=on
+-      je      do_edd_on
+-      jmp     cl_skipword
+-do_edd_skipmbr:
+-      movw    $edd_start, %di
+-      jmp     cl_skipword
+-do_edd_off:
+-      movw    $edd_done, %di
+-      jmp     cl_skipword
+-do_edd_on:
+-      movw    $edd_mbr_sig_start, %di
+-      jmp     cl_skipword
+-
+-done_cl:
+-      popl    %esi
+-      jmpw    *%di
+-
+-# Read the first sector of each BIOS disk device and store the 4-byte signature
+-edd_mbr_sig_start:
+-      movb    $0x80, %dl                      # from device 80
+-      movw    $EDD_MBR_SIG_BUF, %bx           # store buffer ptr in bx
+-edd_mbr_sig_read:
+-      movl    $0xFFFFFFFF, %eax
+-      movl    %eax, (%bx)                     # assume failure
+-      pushw   %bx
+-      movb    $READ_SECTORS, %ah
+-      movb    $1, %al                         # read 1 sector
+-      movb    $0, %dh                         # at head 0
+-      movw    $1, %cx                         # cylinder 0, sector 0
+-      pushw   %es
+-      pushw   %ds
+-      popw    %es
+-      movw    $EDDBUF, %bx                    # disk's data goes into EDDBUF
+-      pushw   %dx             # work around buggy BIOSes
+-      stc                     # work around buggy BIOSes
+-      int     $0x13
+-      sti                     # work around buggy BIOSes
+-      popw    %dx
+-      popw    %es
+-      popw    %bx
+-      jc      edd_mbr_sig_done                # on failure, we're done.
+-      cmpb    $0, %ah         # some BIOSes do not set CF
+-      jne     edd_mbr_sig_done                # on failure, we're done.
+-      movl    (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
+-      movl    %eax, (%bx)                     # store success
+-      incb    (EDD_MBR_SIG_NR_BUF)            # note that we stored something
+-      incb    %dl                             # increment to next device
+-      addw    $4, %bx                         # increment sig buffer ptr
+-      cmpb    $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF)  # Out of space?
+-      jb      edd_mbr_sig_read                # keep looping
+-edd_mbr_sig_done:
+-
+-# Do the BIOS Enhanced Disk Drive calls
+-# This consists of two calls:
+-#    int 13h ah=41h "Check Extensions Present"
+-#    int 13h ah=48h "Get Device Parameters"
+-#    int 13h ah=08h "Legacy Get Device Parameters"
+-#
+-# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
+-# in the boot_params at EDDBUF.  The first four bytes of which are
+-# used to store the device number, interface support map and version
+-# results from fn41.  The next four bytes are used to store the legacy
+-# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
+-# store the results from fn48.  Starting from device 80h, fn41, then fn48
+-# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
+-# Then the pointer is incremented to store the data for the next call.
+-# This repeats until either a device doesn't exist, or until EDDMAXNR
+-# devices have been stored.
+-# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
+-# the structure, and the fn41 and fn08 results are stored at offsets
+-# from there.  This removes the need to increment the pointer for
+-# every store, and leaves it ready for the fn48 call.
+-# A second one-byte buffer, EDDNR, in the boot_params stores
+-# the number of BIOS devices which exist, up to EDDMAXNR.
+-# In setup.c, copy_edd() stores both boot_params buffers away
+-# for later use, as they would get overwritten otherwise.
+-# This code is sensitive to the size of the structs in edd.h
+-edd_start:
+-                                              # %ds points to the bootsector
+-                                                      # result buffer for fn48
+-      movw    $EDDBUF+EDDEXTSIZE, %si         # in ds:si, fn41 results
+-                                              # kept just before that
+-      movb    $0x80, %dl                      # BIOS device 0x80
+-
+-edd_check_ext:
+-      movb    $CHECKEXTENSIONSPRESENT, %ah    # Function 41
+-      movw    $EDDMAGIC1, %bx                 # magic
+-      int     $0x13                           # make the call
+-      jc      edd_done                        # no more BIOS devices
+-
+-      cmpw    $EDDMAGIC2, %bx                 # is magic right?
+-      jne     edd_next                        # nope, next...
+-
+-      movb    %dl, %ds:-8(%si)                # store device number
+-      movb    %ah, %ds:-7(%si)                # store version
+-      movw    %cx, %ds:-6(%si)                # store extensions
+-      incb    (EDDNR)                         # note that we stored something
+-
+-edd_get_device_params:
+-      movw    $EDDPARMSIZE, %ds:(%si)         # put size
+-      movw    $0x0, %ds:2(%si)                # work around buggy BIOSes
+-      movb    $GETDEVICEPARAMETERS, %ah       # Function 48
+-      int     $0x13                           # make the call
+-                                              # Don't check for fail return
+-                                              # it doesn't matter.
+-edd_get_legacy_chs:
+-      xorw    %ax, %ax
+-      movw    %ax, %ds:-4(%si)
+-      movw    %ax, %ds:-2(%si)
+-        # Ralf Brown's Interrupt List says to set ES:DI to
+-      # 0000h:0000h "to guard against BIOS bugs"
+-      pushw   %es
+-      movw    %ax, %es
+-      movw    %ax, %di
+-      pushw   %dx                             # legacy call clobbers %dl
+-      movb    $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
+-      int     $0x13                           # make the call
+-      jc      edd_legacy_done                 # failed
+-      movb    %cl, %al                        # Low 6 bits are max
+-      andb    $0x3F, %al                      #   sector number
+-      movb    %al, %ds:-1(%si)                # Record max sect
+-      movb    %dh, %ds:-2(%si)                # Record max head number
+-      movb    %ch, %al                        # Low 8 bits of max cyl
+-      shr     $6, %cl
+-      movb    %cl, %ah                        # High 2 bits of max cyl
+-      movw    %ax, %ds:-4(%si)
+-
+-edd_legacy_done:
+-      popw    %dx
+-      popw    %es
+-      movw    %si, %ax                        # increment si
+-      addw    $EDDPARMSIZE+EDDEXTSIZE, %ax
+-      movw    %ax, %si
+-
+-edd_next:
+-      incb    %dl                             # increment to next device
+-      cmpb    $EDDMAXNR, (EDDNR)              # Out of space?
+-      jb      edd_check_ext                   # keep looping
+-
+-edd_done:
+-#endif
+diff -puN /dev/null arch/i386/boot/edd.c
+--- /dev/null
++++ a/arch/i386/boot/edd.c
+@@ -0,0 +1,196 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/edd.c
++ *
++ * Get EDD BIOS disk information
++ */
++
++#include "boot.h"
++#include <linux/edd.h>
++
++#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
++
++struct edd_dapa {
++      u8      pkt_size;
++      u8      rsvd;
++      u16     sector_cnt;
++      u16     buf_off, buf_seg;
++      u64     lba;
++      u64     buf_lin_addr;
++};
++
++/*
++ * Note: this uses the heap to hold the loaded sector.
++ */
++static int read_sector(u8 devno, u64 lba, void *buf)
++{
++      struct edd_dapa dapa;
++      u16 ax, bx, cx, dx, si;
++
++      memset(&dapa, 0, sizeof dapa);
++      dapa.pkt_size = sizeof(dapa);
++      dapa.sector_cnt = 1;
++      dapa.buf_off = (size_t)buf;
++      dapa.buf_seg = ds();
++      dapa.lba = lba;
++
++      ax = 0x4200;            /* Extended Read */
++      si = (size_t)&dapa;
++      dx = devno;
++      asm("pushfl; stc; int $0x13; setc %%al; popfl"
++          : "+a" (ax), "+S" (si), "+d" (dx)
++          : "m" (dapa)
++          : "ebx", "ecx", "edi", "memory");
++
++      if (!(u8)ax)
++              return 0;       /* OK */
++
++      ax = 0x0201;            /* Legacy Read, one sector */
++      cx = 0x0001;            /* Sector 0-0-1 */
++      dx = devno;
++      bx = (size_t)buf;
++      asm("pushfl; stc; int $0x13; setc %%al; popfl"
++          : "+a" (ax), "+c" (cx), "+d" (dx), "+b" (bx)
++          : : "esi", "edi", "memory");
++
++      return -(u8)ax;         /* 0 or -1 */
++}
++
++static u32 read_mbr_sig(u8 devno, struct edd_info *ei)
++{
++      int sector_size;
++      char *mbrbuf_ptr, *mbrbuf_end;
++      u32 mbrsig;
++      u32 buf_base, mbr_base;
++      extern char _end[];
++      static char mbr_buf[1024];
++
++      sector_size = ei->params.bytes_per_sector;
++      if (!sector_size)
++              sector_size = 512; /* Best available guess */
++
++      buf_base = (ds() << 4) + (u32)&_end;
++      mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
++      mbrbuf_ptr = mbr_buf + (mbr_base-buf_base);
++      mbrbuf_end = mbrbuf_ptr + sector_size;
++
++      if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
++              return 0;
++      if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
++              return 0;
++
++      if (read_sector(devno, 0, mbrbuf_ptr))
++              return 0;
++
++      mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
++      return mbrsig;
++}
++
++static int get_edd_info(u8 devno, struct edd_info *ei)
++{
++      u16 ax, bx, cx, dx, di;
++
++      memset(ei, 0, sizeof *ei);
++
++      /* Check Extensions Present */
++
++      ax = 0x4100;
++      bx = EDDMAGIC1;
++      dx = devno;
++      asm("pushfl; stc; int $0x13; setc %%al; popfl"
++          : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
++          : : "esi", "edi");
++
++      if ((u8)ax)
++              return -1;      /* No extended information */
++
++      if (bx != EDDMAGIC2)
++              return -1;
++
++      ei->device  = devno;
++      ei->version = ax >> 8;  /* EDD version number */
++      ei->interface_support = cx; /* EDD functionality subsets */
++
++      /* Extended Get Device Parameters */
++
++      ei->params.length = sizeof(ei->params);
++      ax = 0x4800;
++      dx = devno;
++      asm("pushfl; int $0x13; popfl"
++          : "+a" (ax), "+d" (dx)
++          : "S" (&ei->params)
++          : "ebx", "ecx", "edi");
++
++      /* Get legacy CHS parameters */
++
++      /* Ralf Brown recommends setting ES:DI to 0:0 */
++      ax = 0x0800;
++      dx = devno;
++      di = 0;
++      asm("pushw %%es; "
++          "movw %%di,%%es; "
++          "pushfl; stc; int $0x13; setc %%al; popfl; "
++          "popw %%es"
++          : "+a" (ax), "=b" (bx), "=c" (cx), "+d" (dx), "+D" (di)
++          : : "esi");
++
++      if ((u8)ax == 0) {
++              ei->legacy_max_cylinder = (cx >> 8) + ((cx & 0xc0) << 2);
++              ei->legacy_max_head = dx >> 8;
++              ei->legacy_sectors_per_track = cx & 0x3f;
++      }
++
++      return 0;
++}
++
++void query_edd(void)
++{
++      char eddarg[8];
++      int do_mbr = 1;
++      int do_edd = 1;
++      int devno;
++      struct edd_info ei, *edp;
++
++      if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) {
++              if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip"))
++                      do_mbr = 0;
++              else if (!strcmp(eddarg, "off"))
++                      do_edd = 0;
++      }
++
++      edp = (struct edd_info *)boot_params.eddbuf;
++
++      if (!do_edd)
++              return;
++
++      for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
++              /*
++               * Scan the BIOS-supported hard disks and query EDD
++               * information...
++               */
++              get_edd_info(devno, &ei);
++
++              if (boot_params.eddbuf_entries < EDDMAXNR) {
++                      memcpy(edp, &ei, sizeof ei);
++                      edp++;
++                      boot_params.eddbuf_entries++;
++              }
++
++              if (do_mbr) {
++                      u32 mbr_sig;
++                      mbr_sig = read_mbr_sig(devno, &ei);
++                      boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig;
++              }
++      }
++}
++
++#endif
+diff -puN /dev/null arch/i386/boot/header.S
+--- /dev/null
++++ a/arch/i386/boot/header.S
+@@ -0,0 +1,283 @@
++/*
++ *    header.S
++ *
++ *    Copyright (C) 1991, 1992 Linus Torvalds
++ *
++ *    Based on bootsect.S and setup.S
++ *    modified by more people than can be counted
++ *
++ *    Rewritten as a common file by H. Peter Anvin (Apr 2007)
++ *
++ * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
++ * addresses must be multiplied by 16 to obtain their respective linear
++ * addresses. To avoid confusion, linear addresses are written using leading
++ * hex while segment addresses are written as segment:offset.
++ *
++ */
++
++#include <asm/segment.h>
++#include <linux/utsrelease.h>
++#include <asm/boot.h>
++#include <asm/e820.h>
++#include <asm/page.h>
++#include <asm/setup.h>
++#include "boot.h"
++
++SETUPSECTS    = 4                     /* default nr of setup-sectors */
++BOOTSEG               = 0x07C0                /* original address of boot-sector */
++SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
++SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
++                                      /* to be loaded */
++ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
++SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
++
++#ifndef SVGA_MODE
++#define SVGA_MODE ASK_VGA
++#endif
++
++#ifndef RAMDISK
++#define RAMDISK 0
++#endif
++
++#ifndef ROOT_RDONLY
++#define ROOT_RDONLY 1
++#endif
++
++      .code16
++      .section ".bstext", "ax"
++
++      .global bootsect_start
++bootsect_start:
++
++      # Normalize the start address
++      ljmp    $BOOTSEG, $start2
++
++start2:
++      movw    %cs, %ax
++      movw    %ax, %ds
++      movw    %ax, %es
++      movw    %ax, %ss
++      xorw    %sp, %sp
++      sti
++      cld
++
++      movw    $bugger_off_msg, %si
++
++msg_loop:
++      lodsb
++      andb    %al, %al
++      jz      bs_die
++      movb    $0xe, %ah
++      movw    $7, %bx
++      int     $0x10
++      jmp     msg_loop
++
++bs_die:
++      # Allow the user to press a key, then reboot
++      xorw    %ax, %ax
++      int     $0x16
++      int     $0x19
++
++      # int 0x19 should never return.  In case it does anyway,
++      # invoke the BIOS reset code...
++      ljmp    $0xf000,$0xfff0
++
++      .section ".bsdata", "a"
++bugger_off_msg:
++      .ascii  "Direct booting from floppy is no longer supported.\r\n"
++      .ascii  "Please use a boot loader program instead.\r\n"
++      .ascii  "\n"
++      .ascii  "Remove disk and press any key to reboot . . .\r\n"
++      .byte   0
++
++
++      # Kernel attributes; used by setup.  This is part 1 of the
++      # header, from the old boot sector.
++
++      .section ".header", "a"
++      .globl  hdr
++hdr:
++setup_sects:  .byte SETUPSECTS
++root_flags:   .word ROOT_RDONLY
++syssize:      .long SYSSIZE
++ram_size:     .word RAMDISK
++vid_mode:     .word SVGA_MODE
++root_dev:     .word ROOT_DEV
++boot_flag:    .word 0xAA55
++
++      # offset 512, entry point
++
++      .globl  _start
++_start:
++              # Explicitly enter this as bytes, or the assembler
++              # tries to generate a 3-byte jump here, which causes
++              # everything else to push off to the wrong offset.
++              .byte   0xeb            # short (2-byte) jump
++              .byte   start_of_setup-1f
++1:
++
++      # Part 2 of the header, from the old setup.S
++
++              .ascii  "HdrS"          # header signature
++              .word   0x0206          # header version number (>= 0x0105)
++                                      # or else old loadlin-1.5 will fail)
++              .globl realmode_swtch
++realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
++start_sys_seg:        .word   SYSSEG
++              .word   kernel_version-512 # pointing to kernel version string
++                                      # above section of header is compatible
++                                      # with loadlin-1.5 (header v1.5). Don't
++                                      # change it.
++
++type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
++                                      #      Bootlin, SYSLX, bootsect...)
++                                      # See Documentation/i386/boot.txt for
++                                      # assigned ids
++
++# flags, unused bits must be zero (RFU) bit within loadflags
++loadflags:
++LOADED_HIGH   = 1                     # If set, the kernel is loaded high
++CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
++                                      # heap_end_ptr to tell how much
++                                      # space behind setup.S can be used for
++                                      # heap purposes.
++                                      # Only the loader knows what is free
++#ifndef __BIG_KERNEL__
++              .byte   0
++#else
++              .byte   LOADED_HIGH
++#endif
++
++setup_move_size: .word  0x8000                # size to move, when setup is not
++                                      # loaded at 0x90000. We will move setup
++                                      # to 0x90000 then just before jumping
++                                      # into the kernel. However, only the
++                                      # loader knows how much data behind
++                                      # us also needs to be loaded.
++
++code32_start:                         # here loaders can put a different
++                                      # start address for 32-bit code.
++#ifndef __BIG_KERNEL__
++              .long   0x1000          #   0x1000 = default for zImage
++#else
++              .long   0x100000        # 0x100000 = default for big kernel
++#endif
++
++ramdisk_image:        .long   0               # address of loaded ramdisk image
++                                      # Here the loader puts the 32-bit
++                                      # address where it loaded the image.
++                                      # This only will be read by the kernel.
++
++ramdisk_size: .long   0               # its size in bytes
++
++bootsect_kludge:
++              .long   0               # obsolete
++
++heap_end_ptr: .word   _end+1024       # (Header version 0x0201 or later)
++                                      # space from here (exclusive) down to
++                                      # end of setup code can be used by setup
++                                      # for local heap purposes.
++
++pad1:         .word   0
++cmd_line_ptr: .long   0               # (Header version 0x0202 or later)
++                                      # If nonzero, a 32-bit pointer
++                                      # to the kernel command line.
++                                      # The command line should be
++                                      # located between the start of
++                                      # setup and the end of low
++                                      # memory (0xa0000), or it may
++                                      # get overwritten before it
++                                      # gets read.  If this field is
++                                      # used, there is no longer
++                                      # anything magical about the
++                                      # 0x90000 segment; the setup
++                                      # can be located anywhere in
++                                      # low memory 0x10000 or higher.
++
++ramdisk_max:  .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
++                                      # (Header version 0x0203 or later)
++                                      # The highest safe address for
++                                      # the contents of an initrd
++
++kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN        #physical addr alignment
++                                              #required for protected mode
++                                              #kernel
++#ifdef CONFIG_RELOCATABLE
++relocatable_kernel:    .byte 1
++#else
++relocatable_kernel:    .byte 0
++#endif
++pad2:                 .byte 0
++pad3:                 .word 0
++
++cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
++                                                #added with boot protocol
++                                                #version 2.06
++
++# End of setup header #####################################################
++
++      .section ".inittext", "ax"
++start_of_setup:
++#ifdef SAFE_RESET_DISK_CONTROLLER
++# Reset the disk controller.
++      movw    $0x0000, %ax            # Reset disk controller
++      movb    $0x80, %dl              # All disks
++      int     $0x13
++#endif
++
++# We will have entired with %cs = %ds+0x20, normalize %cs so
++# it is on par with the other segments.
++      pushw   %ds
++      pushw   $setup2
++      lretw
++
++setup2:
++# Force %es = %ds
++      movw    %ds, %ax
++      movw    %ax, %es
++      cld
++
++# Stack paranoia: align the stack and make sure it is good
++# for both 16- and 32-bit references.  In particular, if we
++# were meant to have been using the full 16-bit segment, the
++# caller might have set %sp to zero, which breaks %esp-based
++# references.
++      andw    $~3, %sp        # dword align (might as well...)
++      jnz     1f
++      movw    $0xfffc, %sp    # Make sure we're not zero
++1:    movzwl  %sp, %esp       # Clear upper half of %esp
++      sti
++
++# Check signature at end of setup
++      cmpl    $0x5a5aaa55, setup_sig
++      jne     setup_bad
++
++# Zero the bss
++      movw    $__bss_start, %di
++      movw    $_end+3, %cx
++      xorl    %eax, %eax
++      subw    %di, %cx
++      shrw    $2, %cx
++      rep; stosl
++
++# Jump to C code (should not return)
++      calll   main
++
++# Setup corrupt somehow...
++setup_bad:
++      movl    $setup_corrupt, %eax
++      calll   puts
++      # Fall through...
++
++      .globl  die
++      .type   die, @function
++die:
++      hlt
++      jmp     die
++
++      .size   die, .-due
++
++      .section ".initdata", "a"
++setup_corrupt:
++      .byte   7
++      .string "No setup signature found..."
+diff -puN /dev/null arch/i386/boot/main.c
+--- /dev/null
++++ a/arch/i386/boot/main.c
+@@ -0,0 +1,161 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/main.c
++ *
++ * Main module for the real-mode kernel code
++ */
++
++#include "boot.h"
++
++struct boot_params boot_params __attribute__((aligned(16)));
++
++char *HEAP = _end;
++char *heap_end = _end;                /* Default end of heap = no heap */
++
++/*
++ * Copy the header into the boot parameter block.  Since this
++ * screws up the old-style command line protocol, adjust by
++ * filling in the new-style command line pointer instead.
++ */
++#define OLD_CL_MAGIC  0xA33F
++#define OLD_CL_ADDRESS        0x20
++
++static void copy_boot_params(void)
++{
++      struct old_cmdline {
++              u16 cl_magic;
++              u16 cl_offset;
++      };
++      const struct old_cmdline * const oldcmd =
++              (const struct old_cmdline *)OLD_CL_ADDRESS;
++
++      BUILD_BUG_ON(sizeof boot_params != 4096);
++      memcpy(&boot_params.hdr, &hdr, sizeof hdr);
++
++      if (!boot_params.hdr.cmd_line_ptr &&
++          oldcmd->cl_magic == OLD_CL_MAGIC) {
++              /* Old-style command line protocol. */
++              u16 cmdline_seg;
++
++              /* Figure out if the command line falls in the region
++                 of memory that an old kernel would have copied up
++                 to 0x90000... */
++              if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
++                      cmdline_seg = ds();
++              else
++                      cmdline_seg = 0x9000;
++
++              boot_params.hdr.cmd_line_ptr =
++                      (cmdline_seg << 4) + oldcmd->cl_offset;
++      }
++}
++
++/*
++ * Set the keyboard repeat rate to maximum.  Unclear why this
++ * is done here; this might be possible to kill off as stale code.
++ */
++static void keyboard_set_repeat(void)
++{
++      u16 ax = 0x0305;
++      u16 bx = 0;
++      asm volatile("int $0x16"
++                   : "+a" (ax), "+b" (bx)
++                   : : "ecx", "edx", "esi", "edi");
++}
++
++/*
++ * Get Intel SpeedStep IST information.
++ */
++static void query_speedstep_ist(void)
++{
++      asm("int $0x15"
++          : "=a" (boot_params.speedstep_info[0]),
++            "=b" (boot_params.speedstep_info[1]),
++            "=c" (boot_params.speedstep_info[2]),
++            "=d" (boot_params.speedstep_info[3])
++          : "a" (0x0000e980),  /* IST Support */
++            "d" (0x47534943)); /* Request value */
++}
++
++/*
++ * Tell the BIOS what CPU mode we intend to run in.
++ */
++static void set_bios_mode(void)
++{
++#ifdef CONFIG_X86_64
++      u32 eax, ebx;
++
++      eax = 0xec00;
++      ebx = 2;
++      asm volatile("int $0x15"
++                   : "+a" (eax), "+b" (ebx)
++                   : : "ecx", "edx", "esi", "edi");
++#endif
++}
++
++void main(void)
++{
++      /* First, copy the boot header into the "zeropage" */
++      copy_boot_params();
++
++      /* End of heap check */
++      if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
++              heap_end = (char *)(boot_params.hdr.heap_end_ptr
++                                  +0x200-STACK_SIZE);
++      } else {
++              /* Boot protocol 2.00 only, no heap available */
++              puts("WARNING: Ancient bootloader, some functionality "
++                   "may be limited!\n");
++      }
++
++      /* Make sure we have all the proper CPU support */
++      if (validate_cpu()) {
++              puts("Unable to boot - please use a kernel appropriate "
++                   "for your CPU.\n");
++              die();
++      }
++
++      /* Tell the BIOS what CPU mode we intend to run in. */
++      set_bios_mode();
++
++      /* Detect memory layout */
++      detect_memory();
++
++      /* Set keyboard repeat rate (why?) */
++      keyboard_set_repeat();
++
++      /* Set the video mode */
++      set_video();
++
++      /* Query MCA information */
++      query_mca();
++
++      /* Voyager */
++#ifdef CONFIG_X86_VOYAGER
++      query_voyager();
++#endif
++
++      /* Query SpeedStep IST information */
++      query_speedstep_ist();
++
++      /* Query APM information */
++#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
++      query_apm_bios();
++#endif
++
++      /* Query EDD information */
++#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
++      query_edd();
++#endif
++      /* Do the last things and invoke protected mode */
++      go_to_protected_mode();
++}
+diff -puN /dev/null arch/i386/boot/mca.c
+--- /dev/null
++++ a/arch/i386/boot/mca.c
+@@ -0,0 +1,43 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/mca.c
++ *
++ * Get the MCA system description table
++ */
++
++#include "boot.h"
++
++int query_mca(void)
++{
++      u8 err;
++      u16 es, bx, len;
++
++      asm("pushw %%es ; "
++          "int $0x15 ; "
++          "setc %0 ; "
++          "movw %%es, %1 ; "
++          "popw %%es"
++          : "=acdSDm" (err), "=acdSDm" (es), "=b" (bx)
++          : "a" (0xc000));
++
++      if (err)
++              return -1;      /* No MCA present */
++
++      set_fs(es);
++      len = rdfs16(bx);
++
++      if (len > sizeof(boot_params.sys_desc_table))
++              len = sizeof(boot_params.sys_desc_table);
++
++      copy_from_fs(&boot_params.sys_desc_table, bx, len);
++      return 0;
++}
+diff -puN /dev/null arch/i386/boot/memory.c
+--- /dev/null
++++ a/arch/i386/boot/memory.c
+@@ -0,0 +1,99 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/memory.c
++ *
++ * Memory detection code
++ */
++
++#include "boot.h"
++
++#define SMAP  0x534d4150      /* ASCII "SMAP" */
++
++static int detect_memory_e820(void)
++{
++      u32 next = 0;
++      u32 size, id;
++      u8 err;
++      struct e820entry *desc = boot_params.e820_map;
++
++      do {
++              size = sizeof(struct e820entry);
++              id = SMAP;
++              asm("int $0x15; setc %0"
++                  : "=am" (err), "+b" (next), "+d" (id), "+c" (size),
++                    "=m" (*desc)
++                  : "D" (desc), "a" (0xe820));
++
++              if (err || id != SMAP)
++                      break;
++
++              boot_params.e820_entries++;
++              desc++;
++      } while (next && boot_params.e820_entries < E820MAX);
++
++      return boot_params.e820_entries;
++}
++
++static int detect_memory_e801(void)
++{
++      u16 ax, bx, cx, dx;
++      u8 err;
++
++      bx = cx = dx = 0;
++      ax = 0xe801;
++      asm("stc; int $0x15; setc %0"
++          : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
++
++      if (err)
++              return -1;
++
++      /* Do we really need to do this? */
++      if (cx || dx) {
++              ax = cx;
++              bx = dx;
++      }
++
++      if (ax > 15*1024)
++              return -1;      /* Bogus! */
++
++      /* This ignores memory above 16MB if we have a memory hole
++         there.  If someone actually finds a machine with a memory
++         hole at 16MB and no support for 0E820h they should probably
++         generate a fake e820 map. */
++      boot_params.alt_mem_k = (ax == 15*1024) ? (dx << 6)+ax : ax;
++
++      return 0;
++}
++
++static int detect_memory_88(void)
++{
++      u16 ax;
++      u8 err;
++
++      ax = 0x8800;
++      asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
++
++      boot_params.screen_info.ext_mem_k = ax;
++
++      return -err;
++}
++
++int detect_memory(void)
++{
++      if (detect_memory_e820() > 0)
++              return 0;
++
++      if (!detect_memory_e801())
++              return 0;
++
++      return detect_memory_88();
++}
+diff -puN /dev/null arch/i386/boot/pm.c
+--- /dev/null
++++ a/arch/i386/boot/pm.c
+@@ -0,0 +1,170 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/pm.c
++ *
++ * Prepare the machine for transition to protected mode.
++ */
++
++#include "boot.h"
++#include <asm/segment.h>
++
++/*
++ * Invoke the realmode switch hook if present; otherwise
++ * disable all interrupts.
++ */
++static void realmode_switch_hook(void)
++{
++      if (boot_params.hdr.realmode_swtch) {
++              asm volatile("lcallw *%0"
++                           : : "m" (boot_params.hdr.realmode_swtch)
++                           : "eax", "ebx", "ecx", "edx");
++      } else {
++              asm volatile("cli");
++              outb(0x80, 0x70); /* Disable NMI */
++              io_delay();
++      }
++}
++
++/*
++ * A zImage kernel is loaded at 0x10000 but wants to run at 0x1000.
++ * A bzImage kernel is loaded and runs at 0x100000.
++ */
++static void move_kernel_around(void)
++{
++      /* Note: rely on the compile-time option here rather than
++         the LOADED_HIGH flag.  The Qemu kernel loader unconditionally
++         sets the loadflags to zero. */
++#ifndef __BIG_KERNEL__
++      u16 dst_seg, src_seg;
++      u32 syssize;
++
++      dst_seg =  0x1000 >> 4;
++      src_seg = 0x10000 >> 4;
++      syssize = boot_params.hdr.syssize; /* Size in 16-byte paragraps */
++
++      while (syssize) {
++              int paras  = (syssize >= 0x1000) ? 0x1000 : syssize;
++              int dwords = paras << 2;
++
++              asm volatile("pushw %%es ; "
++                           "pushw %%ds ; "
++                           "movw %1,%%es ; "
++                           "movw %2,%%ds ; "
++                           "xorw %%di,%%di ; "
++                           "xorw %%si,%%si ; "
++                           "rep;movsl ; "
++                           "popw %%ds ; "
++                           "popw %%es"
++                           : "+c" (dwords)
++                           : "rm" (dst_seg), "rm" (src_seg)
++                           : "esi", "edi");
++
++              syssize -= paras;
++              dst_seg += paras;
++              src_seg += paras;
++      }
++#endif
++}
++
++/*
++ * Disable all interrupts at the legacy PIC.
++ */
++static void mask_all_interrupts(void)
++{
++      outb(0xff, 0xa1);       /* Mask all interrupts on the seconday PIC */
++      io_delay();
++      outb(0xfb, 0x21);       /* Mask all but cascade on the primary PIC */
++      io_delay();
++}
++
++/*
++ * Reset IGNNE# if asserted in the FPU.
++ */
++static void reset_coprocessor(void)
++{
++      outb(0, 0xf0);
++      io_delay();
++      outb(0, 0xf1);
++      io_delay();
++}
++
++/*
++ * Set up the GDT
++ */
++#define GDT_ENTRY(flags,base,limit)           \
++      (((u64)(base & 0xff000000) << 32) |     \
++       ((u64)flags << 40) |                   \
++       ((u64)(limit & 0x00ff0000) << 32) |    \
++       ((u64)(base & 0x00ffff00) << 16) |     \
++       ((u64)(limit & 0x0000ffff)))
++
++struct gdt_ptr {
++      u16 len;
++      u32 ptr;
++} __attribute__((packed));
++
++static void setup_gdt(void)
++{
++      /* There are machines which are known to not boot with the GDT
++         being 8-byte unaligned.  Intel recommends 16 byte alignment. */
++      static const u64 boot_gdt[] __attribute__((aligned(16))) = {
++              /* CS: code, read/execute, 4 GB, base 0 */
++              [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
++              /* DS: data, read/write, 4 GB, base 0 */
++              [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
++      };
++      struct gdt_ptr gdt;
++
++      gdt.len = sizeof(boot_gdt)-1;
++      gdt.ptr = (u32)&boot_gdt + (ds() << 4);
++
++      asm volatile("lgdtl %0" : : "m" (gdt));
++}
++
++/*
++ * Set up the IDT
++ */
++static void setup_idt(void)
++{
++      static const struct gdt_ptr null_idt = {0, 0};
++      asm volatile("lidtl %0" : : "m" (null_idt));
++}
++
++/*
++ * Actual invocation sequence
++ */
++void go_to_protected_mode(void)
++{
++      /* Hook before leaving real mode, also disables interrupts */
++      realmode_switch_hook();
++
++      /* Move the kernel/setup to their final resting places */
++      move_kernel_around();
++
++      /* Enable the A20 gate */
++      if (enable_a20()) {
++              puts("A20 gate not responding, unable to boot...\n");
++              die();
++      }
++
++      /* Reset coprocessor (IGNNE#) */
++      reset_coprocessor();
++
++      /* Mask all interrupts in the PIC */
++      mask_all_interrupts();
++
++      /* Actual transition to protected mode... */
++      setup_idt();
++      setup_gdt();
++      protected_mode_jump(boot_params.hdr.code32_start,
++                          (u32)&boot_params + (ds() << 4));
++}
+diff -puN /dev/null arch/i386/boot/pmjump.S
+--- /dev/null
++++ a/arch/i386/boot/pmjump.S
+@@ -0,0 +1,54 @@
++/* ----------------------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/pmjump.S
++ *
++ * The actual transition into protected mode
++ */
++
++#include <asm/boot.h>
++#include <asm/segment.h>
++
++      .text
++
++      .globl  protected_mode_jump
++      .type   protected_mode_jump, @function
++
++      .code16
++
++/*
++ * void protected_mode_jump(u32 entrypoint, u32 bootparams);
++ */
++protected_mode_jump:
++      xorl    %ebx, %ebx              # Flag to indicate this is a boot
++      movl    %edx, %esi              # Pointer to boot_params table
++      movl    %eax, 2f                # Patch ljmpl instruction
++      jmp     1f                      # Short jump to flush instruction q.
++
++1:
++      movw    $__BOOT_DS, %cx
++
++      movl    %cr0, %edx
++      orb     $1, %dl                 # Protected mode (PE) bit
++      movl    %edx, %cr0
++
++      movw    %cx, %ds
++      movw    %cx, %es
++      movw    %cx, %fs
++      movw    %cx, %gs
++      movw    %cx, %ss
++
++      # Jump to the 32-bit entrypoint
++      .byte   0x66, 0xea              # ljmpl opcode
++2:    .long   0                       # offset
++      .word   __BOOT_CS               # segment
++
++      .size   protected_mode_jump, .-protected_mode_jump
+diff -puN /dev/null arch/i386/boot/printf.c
+--- /dev/null
++++ a/arch/i386/boot/printf.c
+@@ -0,0 +1,331 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/printf.c
++ *
++ * Oh, it's a waste of space, but oh-so-yummy for debugging.  This
++ * version of printf() does not include 64-bit support.  "Live with
++ * it."
++ *
++ */
++
++#include "boot.h"
++
++static inline int isdigit(int ch)
++{
++      return (ch >= '0') && (ch <= '9');
++}
++
++static int skip_atoi(const char **s)
++{
++      int i = 0;
++
++      while (isdigit(**s))
++              i = i * 10 + *((*s)++) - '0';
++      return i;
++}
++
++unsigned int atou(const char *s)
++{
++      unsigned int i = 0;
++      while (isdigit(*s))
++              i = i * 10 + (*s++ - '0');
++      return i;
++}
++
++static int strnlen(const char *s, int maxlen)
++{
++      const char *es = s;
++      while (*es && maxlen) {
++              es++;
++              maxlen--;
++      }
++
++      return (es - s);
++}
++
++#define ZEROPAD       1               /* pad with zero */
++#define SIGN  2               /* unsigned/signed long */
++#define PLUS  4               /* show plus */
++#define SPACE 8               /* space if plus */
++#define LEFT  16              /* left justified */
++#define SPECIAL       32              /* 0x */
++#define LARGE 64              /* use 'ABCDEF' instead of 'abcdef' */
++
++#define do_div(n,base) ({ \
++int __res; \
++__res = ((unsigned long) n) % (unsigned) base; \
++n = ((unsigned long) n) / (unsigned) base; \
++__res; })
++
++static char *number(char *str, long num, int base, int size, int precision,
++                  int type)
++{
++      char c, sign, tmp[66];
++      const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
++      int i;
++
++      if (type & LARGE)
++              digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
++      if (type & LEFT)
++              type &= ~ZEROPAD;
++      if (base < 2 || base > 36)
++              return 0;
++      c = (type & ZEROPAD) ? '0' : ' ';
++      sign = 0;
++      if (type & SIGN) {
++              if (num < 0) {
++                      sign = '-';
++                      num = -num;
++                      size--;
++              } else if (type & PLUS) {
++                      sign = '+';
++                      size--;
++              } else if (type & SPACE) {
++                      sign = ' ';
++                      size--;
++              }
++      }
++      if (type & SPECIAL) {
++              if (base == 16)
++                      size -= 2;
++              else if (base == 8)
++                      size--;
++      }
++      i = 0;
++      if (num == 0)
++              tmp[i++] = '0';
++      else
++              while (num != 0)
++                      tmp[i++] = digits[do_div(num, base)];
++      if (i > precision)
++              precision = i;
++      size -= precision;
++      if (!(type & (ZEROPAD + LEFT)))
++              while (size-- > 0)
++                      *str++ = ' ';
++      if (sign)
++              *str++ = sign;
++      if (type & SPECIAL) {
++              if (base == 8)
++                      *str++ = '0';
++              else if (base == 16) {
++                      *str++ = '0';
++                      *str++ = digits[33];
++              }
++      }
++      if (!(type & LEFT))
++              while (size-- > 0)
++                      *str++ = c;
++      while (i < precision--)
++              *str++ = '0';
++      while (i-- > 0)
++              *str++ = tmp[i];
++      while (size-- > 0)
++              *str++ = ' ';
++      return str;
++}
++
++int vsprintf(char *buf, const char *fmt, va_list args)
++{
++      int len;
++      unsigned long num;
++      int i, base;
++      char *str;
++      const char *s;
++
++      int flags;              /* flags to number() */
++
++      int field_width;        /* width of output field */
++      int precision;          /* min. # of digits for integers; max
++                                 number of chars for from string */
++      int qualifier;          /* 'h', 'l', or 'L' for integer fields */
++
++      for (str = buf; *fmt; ++fmt) {
++              if (*fmt != '%') {
++                      *str++ = *fmt;
++                      continue;
++              }
++
++              /* process flags */
++              flags = 0;
++            repeat:
++              ++fmt;          /* this also skips first '%' */
++              switch (*fmt) {
++              case '-':
++                      flags |= LEFT;
++                      goto repeat;
++              case '+':
++                      flags |= PLUS;
++                      goto repeat;
++              case ' ':
++                      flags |= SPACE;
++                      goto repeat;
++              case '#':
++                      flags |= SPECIAL;
++                      goto repeat;
++              case '0':
++                      flags |= ZEROPAD;
++                      goto repeat;
++              }
++
++              /* get field width */
++              field_width = -1;
++              if (isdigit(*fmt))
++                      field_width = skip_atoi(&fmt);
++              else if (*fmt == '*') {
++                      ++fmt;
++                      /* it's the next argument */
++                      field_width = va_arg(args, int);
++                      if (field_width < 0) {
++                              field_width = -field_width;
++                              flags |= LEFT;
++                      }
++              }
++
++              /* get the precision */
++              precision = -1;
++              if (*fmt == '.') {
++                      ++fmt;
++                      if (isdigit(*fmt))
++                              precision = skip_atoi(&fmt);
++                      else if (*fmt == '*') {
++                              ++fmt;
++                              /* it's the next argument */
++                              precision = va_arg(args, int);
++                      }
++                      if (precision < 0)
++                              precision = 0;
++              }
++
++              /* get the conversion qualifier */
++              qualifier = -1;
++              if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
++                      qualifier = *fmt;
++                      ++fmt;
++              }
++
++              /* default base */
++              base = 10;
++
++              switch (*fmt) {
++              case 'c':
++                      if (!(flags & LEFT))
++                              while (--field_width > 0)
++                                      *str++ = ' ';
++                      *str++ = (unsigned char)va_arg(args, int);
++                      while (--field_width > 0)
++                              *str++ = ' ';
++                      continue;
++
++              case 's':
++                      s = va_arg(args, char *);
++                      len = strnlen(s, precision);
++
++                      if (!(flags & LEFT))
++                              while (len < field_width--)
++                                      *str++ = ' ';
++                      for (i = 0; i < len; ++i)
++                              *str++ = *s++;
++                      while (len < field_width--)
++                              *str++ = ' ';
++                      continue;
++
++              case 'p':
++                      if (field_width == -1) {
++                              field_width = 2 * sizeof(void *);
++                              flags |= ZEROPAD;
++                      }
++                      str = number(str,
++                                   (unsigned long)va_arg(args, void *), 16,
++                                   field_width, precision, flags);
++                      continue;
++
++              case 'n':
++                      if (qualifier == 'l') {
++                              long *ip = va_arg(args, long *);
++                              *ip = (str - buf);
++                      } else {
++                              int *ip = va_arg(args, int *);
++                              *ip = (str - buf);
++                      }
++                      continue;
++
++              case '%':
++                      *str++ = '%';
++                      continue;
++
++                      /* integer number formats - set up the flags and "break" */
++              case 'o':
++                      base = 8;
++                      break;
++
++              case 'X':
++                      flags |= LARGE;
++              case 'x':
++                      base = 16;
++                      break;
++
++              case 'd':
++              case 'i':
++                      flags |= SIGN;
++              case 'u':
++                      break;
++
++              default:
++                      *str++ = '%';
++                      if (*fmt)
++                              *str++ = *fmt;
++                      else
++                              --fmt;
++                      continue;
++              }
++              if (qualifier == 'l')
++                      num = va_arg(args, unsigned long);
++              else if (qualifier == 'h') {
++                      num = (unsigned short)va_arg(args, int);
++                      if (flags & SIGN)
++                              num = (short)num;
++              } else if (flags & SIGN)
++                      num = va_arg(args, int);
++              else
++                      num = va_arg(args, unsigned int);
++              str = number(str, num, base, field_width, precision, flags);
++      }
++      *str = '\0';
++      return str - buf;
++}
++
++int sprintf(char *buf, const char *fmt, ...)
++{
++      va_list args;
++      int i;
++
++      va_start(args, fmt);
++      i = vsprintf(buf, fmt, args);
++      va_end(args);
++      return i;
++}
++
++int printf(const char *fmt, ...)
++{
++      char printf_buf[1024];
++      va_list args;
++      int printed;
++
++      va_start(args, fmt);
++      printed = vsprintf(printf_buf, fmt, args);
++      va_end(args);
++
++      puts(printf_buf);
++
++      return printed;
++}
+diff -puN arch/i386/boot/setup.S~git-newsetup /dev/null
+--- a/arch/i386/boot/setup.S
++++ /dev/null
+@@ -1,1075 +0,0 @@
+-/*
+- *    setup.S         Copyright (C) 1991, 1992 Linus Torvalds
+- *
+- * setup.s is responsible for getting the system data from the BIOS,
+- * and putting them into the appropriate places in system memory.
+- * both setup.s and system has been loaded by the bootblock.
+- *
+- * This code asks the bios for memory/disk/other parameters, and
+- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
+- * boot-block used to be. It is then up to the protected mode
+- * system to read them from there before the area is overwritten
+- * for buffer-blocks.
+- *
+- * Move PS/2 aux init code to psaux.c
+- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
+- *
+- * some changes and additional features by Christoph Niemann,
+- * March 1993/June 1994 (Christoph.Niemann@linux.org)
+- *
+- * add APM BIOS checking by Stephen Rothwell, May 1994
+- * (sfr@canb.auug.org.au)
+- *
+- * High load stuff, initrd support and position independency
+- * by Hans Lermen & Werner Almesberger, February 1996
+- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
+- *
+- * Video handling moved to video.S by Martin Mares, March 1996
+- * <mj@k332.feld.cvut.cz>
+- *
+- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
+- * parsons) to avoid loadlin confusion, July 1997
+- *
+- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
+- * <stiker@northlink.com>
+- *
+- * Fix to work around buggy BIOSes which don't use carry bit correctly
+- * and/or report extended memory in CX/DX for e801h memory size detection 
+- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
+- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
+- * anyway.  So to avoid breaking many machines (presumably there was a reason
+- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
+- * if CX/DX have been changed in the e801 call and if so use AX/BX .
+- * Michael Miller, April 2001 <michaelm@mjmm.org>
+- *
+- * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
+- * by Robert Schwebel, December 2001 <robert@schwebel.de>
+- */
+-
+-#include <asm/segment.h>
+-#include <linux/utsrelease.h>
+-#include <linux/compile.h>
+-#include <asm/boot.h>
+-#include <asm/e820.h>
+-#include <asm/page.h>
+-#include <asm/setup.h>
+-      
+-/* Signature words to ensure LILO loaded us right */
+-#define SIG1  0xAA55
+-#define SIG2  0x5A5A
+-
+-INITSEG  = DEF_INITSEG                # 0x9000, we move boot here, out of the way
+-SYSSEG   = DEF_SYSSEG         # 0x1000, system loaded at 0x10000 (65536).
+-SETUPSEG = DEF_SETUPSEG               # 0x9020, this is the current segment
+-                              # ... and the former contents of CS
+-
+-DELTA_INITSEG = SETUPSEG - INITSEG    # 0x0020
+-
+-.code16
+-.globl begtext, begdata, begbss, endtext, enddata, endbss
+-
+-.text
+-begtext:
+-.data
+-begdata:
+-.bss
+-begbss:
+-.text
+-
+-start:
+-      jmp     trampoline
+-
+-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+-
+-              .ascii  "HdrS"          # header signature
+-              .word   0x0206          # header version number (>= 0x0105)
+-                                      # or else old loadlin-1.5 will fail)
+-realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
+-start_sys_seg:        .word   SYSSEG
+-              .word   kernel_version  # pointing to kernel version string
+-                                      # above section of header is compatible
+-                                      # with loadlin-1.5 (header v1.5). Don't
+-                                      # change it.
+-
+-type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
+-                                      #      Bootlin, SYSLX, bootsect...)
+-                                      # See Documentation/i386/boot.txt for
+-                                      # assigned ids
+-      
+-# flags, unused bits must be zero (RFU) bit within loadflags
+-loadflags:
+-LOADED_HIGH   = 1                     # If set, the kernel is loaded high
+-CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
+-                                      # heap_end_ptr to tell how much
+-                                      # space behind setup.S can be used for
+-                                      # heap purposes.
+-                                      # Only the loader knows what is free
+-#ifndef __BIG_KERNEL__
+-              .byte   0
+-#else
+-              .byte   LOADED_HIGH
+-#endif
+-
+-setup_move_size: .word  0x8000                # size to move, when setup is not
+-                                      # loaded at 0x90000. We will move setup 
+-                                      # to 0x90000 then just before jumping
+-                                      # into the kernel. However, only the
+-                                      # loader knows how much data behind
+-                                      # us also needs to be loaded.
+-
+-code32_start:                         # here loaders can put a different
+-                                      # start address for 32-bit code.
+-#ifndef __BIG_KERNEL__
+-              .long   0x1000          #   0x1000 = default for zImage
+-#else
+-              .long   0x100000        # 0x100000 = default for big kernel
+-#endif
+-
+-ramdisk_image:        .long   0               # address of loaded ramdisk image
+-                                      # Here the loader puts the 32-bit
+-                                      # address where it loaded the image.
+-                                      # This only will be read by the kernel.
+-
+-ramdisk_size: .long   0               # its size in bytes
+-
+-bootsect_kludge:
+-              .long   0               # obsolete
+-
+-heap_end_ptr: .word   modelist+1024   # (Header version 0x0201 or later)
+-                                      # space from here (exclusive) down to
+-                                      # end of setup code can be used by setup
+-                                      # for local heap purposes.
+-
+-pad1:         .word   0
+-cmd_line_ptr: .long 0                 # (Header version 0x0202 or later)
+-                                      # If nonzero, a 32-bit pointer
+-                                      # to the kernel command line.
+-                                      # The command line should be
+-                                      # located between the start of
+-                                      # setup and the end of low
+-                                      # memory (0xa0000), or it may
+-                                      # get overwritten before it
+-                                      # gets read.  If this field is
+-                                      # used, there is no longer
+-                                      # anything magical about the
+-                                      # 0x90000 segment; the setup
+-                                      # can be located anywhere in
+-                                      # low memory 0x10000 or higher.
+-
+-ramdisk_max:  .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff
+-                                      # (Header version 0x0203 or later)
+-                                      # The highest safe address for
+-                                      # the contents of an initrd
+-
+-kernel_alignment:  .long CONFIG_PHYSICAL_ALIGN        #physical addr alignment
+-                                              #required for protected mode
+-                                              #kernel
+-#ifdef CONFIG_RELOCATABLE
+-relocatable_kernel:    .byte 1
+-#else
+-relocatable_kernel:    .byte 0
+-#endif
+-pad2:                 .byte 0
+-pad3:                 .word 0
+-
+-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
+-                                                #added with boot protocol
+-                                                #version 2.06
+-
+-trampoline:   call    start_of_setup
+-              .align 16
+-                                      # The offset at this point is 0x240
+-              .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
+-# End of setup header #####################################################
+-
+-start_of_setup:
+-# Bootlin depends on this being done early
+-      movw    $0x01500, %ax
+-      movb    $0x81, %dl
+-      int     $0x13
+-
+-#ifdef SAFE_RESET_DISK_CONTROLLER
+-# Reset the disk controller.
+-      movw    $0x0000, %ax
+-      movb    $0x80, %dl
+-      int     $0x13
+-#endif
+-
+-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
+-      movw    %cs, %ax                # aka SETUPSEG
+-      movw    %ax, %ds
+-# Check signature at end of setup
+-      cmpw    $SIG1, setup_sig1
+-      jne     bad_sig
+-
+-      cmpw    $SIG2, setup_sig2
+-      jne     bad_sig
+-
+-      jmp     good_sig1
+-
+-# Routine to print asciiz string at ds:si
+-prtstr:
+-      lodsb
+-      andb    %al, %al
+-      jz      fin
+-
+-      call    prtchr
+-      jmp     prtstr
+-
+-fin:  ret
+-
+-# Space printing
+-prtsp2:       call    prtspc          # Print double space
+-prtspc:       movb    $0x20, %al      # Print single space (note: fall-thru)
+-
+-# Part of above routine, this one just prints ascii al
+-prtchr:       pushw   %ax
+-      pushw   %cx
+-      movw    $7,%bx
+-      movw    $0x01, %cx
+-      movb    $0x0e, %ah
+-      int     $0x10
+-      popw    %cx
+-      popw    %ax
+-      ret
+-
+-beep: movb    $0x07, %al
+-      jmp     prtchr
+-      
+-no_sig_mess: .string  "No setup signature found ..."
+-
+-good_sig1:
+-      jmp     good_sig
+-
+-# We now have to find the rest of the setup code/data
+-bad_sig:
+-      movw    %cs, %ax                        # SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # INITSEG
+-      movw    %ax, %ds
+-      xorb    %bh, %bh
+-      movb    (497), %bl                      # get setup sect from bootsect
+-      subw    $4, %bx                         # LILO loads 4 sectors of setup
+-      shlw    $8, %bx                         # convert to words (1sect=2^8 words)
+-      movw    %bx, %cx
+-      shrw    $3, %bx                         # convert to segment
+-      addw    $SYSSEG, %bx
+-      movw    %bx, %cs:start_sys_seg
+-# Move rest of setup code/data to here
+-      movw    $2048, %di                      # four sectors loaded by LILO
+-      subw    %si, %si
+-      pushw   %cs
+-      popw    %es
+-      movw    $SYSSEG, %ax
+-      movw    %ax, %ds
+-      rep
+-      movsw
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      movw    %ax, %ds
+-      cmpw    $SIG1, setup_sig1
+-      jne     no_sig
+-
+-      cmpw    $SIG2, setup_sig2
+-      jne     no_sig
+-
+-      jmp     good_sig
+-
+-no_sig:
+-      lea     no_sig_mess, %si
+-      call    prtstr
+-
+-no_sig_loop:
+-      hlt
+-      jmp     no_sig_loop
+-
+-good_sig:
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %ds
+-# Check if an old loader tries to load a big-kernel
+-      testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
+-      jz      loader_ok                       # No, no danger for old loaders.
+-
+-      cmpb    $0, %cs:type_of_loader          # Do we have a loader that
+-                                              # can deal with us?
+-      jnz     loader_ok                       # Yes, continue.
+-
+-      pushw   %cs                             # No, we have an old loader,
+-      popw    %ds                             # die. 
+-      lea     loader_panic_mess, %si
+-      call    prtstr
+-
+-      jmp     no_sig_loop
+-
+-loader_panic_mess: .string "Wrong loader, giving up..."
+-
+-# check minimum cpuid
+-# we do this here because it is the last place we can actually
+-# show a user visible error message. Later the video modus
+-# might be already messed up.
+-loader_ok:
+-      call verify_cpu
+-      testl  %eax,%eax
+-      jz      cpu_ok
+-      movw    %cs,%ax         # aka SETUPSEG
+-      movw    %ax,%ds
+-      lea     cpu_panic_mess,%si
+-      call    prtstr
+-1:    jmp     1b
+-
+-cpu_panic_mess:
+-      .asciz  "PANIC: CPU too old for this kernel."
+-
+-#include "../kernel/verify_cpu.S"
+-
+-cpu_ok:
+-# Get memory size (extended mem, kB)
+-
+-      xorl    %eax, %eax
+-      movl    %eax, (0x1e0)
+-#ifndef STANDARD_MEMORY_BIOS_CALL
+-      movb    %al, (E820NR)
+-# Try three different memory detection schemes.  First, try
+-# e820h, which lets us assemble a memory map, then try e801h,
+-# which returns a 32-bit memory size, and finally 88h, which
+-# returns 0-64m
+-
+-# method E820H:
+-# the memory map from hell.  e820h returns memory classified into
+-# a whole bunch of different types, and allows memory holes and
+-# everything.  We scan through this memory map and build a list
+-# of the first 32 memory areas, which we return at [E820MAP].
+-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
+-
+-#define SMAP  0x534d4150
+-
+-meme820:
+-      xorl    %ebx, %ebx                      # continuation counter
+-      movw    $E820MAP, %di                   # point into the whitelist
+-                                              # so we can have the bios
+-                                              # directly write into it.
+-
+-jmpe820:
+-      movl    $0x0000e820, %eax               # e820, upper word zeroed
+-      movl    $SMAP, %edx                     # ascii 'SMAP'
+-      movl    $20, %ecx                       # size of the e820rec
+-      pushw   %ds                             # data record.
+-      popw    %es
+-      int     $0x15                           # make the call
+-      jc      bail820                         # fall to e801 if it fails
+-
+-      cmpl    $SMAP, %eax                     # check the return is `SMAP'
+-      jne     bail820                         # fall to e801 if it fails
+-
+-#     cmpl    $1, 16(%di)                     # is this usable memory?
+-#     jne     again820
+-
+-      # If this is usable memory, we save it by simply advancing %di by
+-      # sizeof(e820rec).
+-      #
+-good820:
+-      movb    (E820NR), %al                   # up to 128 entries
+-      cmpb    $E820MAX, %al
+-      jae     bail820
+-
+-      incb    (E820NR)
+-      movw    %di, %ax
+-      addw    $20, %ax
+-      movw    %ax, %di
+-again820:
+-      cmpl    $0, %ebx                        # check to see if
+-      jne     jmpe820                         # %ebx is set to EOF
+-bail820:
+-
+-
+-# method E801H:
+-# memory size is in 1k chunksizes, to avoid confusing loadlin.
+-# we store the 0xe801 memory size in a completely different place,
+-# because it will most likely be longer than 16 bits.
+-# (use 1e0 because that's what Larry Augustine uses in his
+-# alternative new memory detection scheme, and it's sensible
+-# to write everything into the same place.)
+-
+-meme801:
+-      stc                                     # fix to work around buggy
+-      xorw    %cx,%cx                         # BIOSes which don't clear/set
+-      xorw    %dx,%dx                         # carry on pass/error of
+-                                              # e801h memory size call
+-                                              # or merely pass cx,dx though
+-                                              # without changing them.
+-      movw    $0xe801, %ax
+-      int     $0x15
+-      jc      mem88
+-
+-      cmpw    $0x0, %cx                       # Kludge to handle BIOSes
+-      jne     e801usecxdx                     # which report their extended
+-      cmpw    $0x0, %dx                       # memory in AX/BX rather than
+-      jne     e801usecxdx                     # CX/DX.  The spec I have read
+-      movw    %ax, %cx                        # seems to indicate AX/BX 
+-      movw    %bx, %dx                        # are more reasonable anyway...
+-
+-e801usecxdx:
+-      andl    $0xffff, %edx                   # clear sign extend
+-      shll    $6, %edx                        # and go from 64k to 1k chunks
+-      movl    %edx, (0x1e0)                   # store extended memory size
+-      andl    $0xffff, %ecx                   # clear sign extend
+-      addl    %ecx, (0x1e0)                   # and add lower memory into
+-                                              # total size.
+-
+-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
+-# 64mb, depending on the bios) in ax.
+-mem88:
+-
+-#endif
+-      movb    $0x88, %ah
+-      int     $0x15
+-      movw    %ax, (2)
+-
+-# Set the keyboard repeat rate to the max
+-      movw    $0x0305, %ax
+-      xorw    %bx, %bx
+-      int     $0x16
+-
+-# Check for video adapter and its parameters and allow the
+-# user to browse video modes.
+-      call    video                           # NOTE: we need %ds pointing
+-                                              # to bootsector
+-
+-# Get hd0 data...
+-      xorw    %ax, %ax
+-      movw    %ax, %ds
+-      ldsw    (4 * 0x41), %si
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      pushw   %ax
+-      movw    %ax, %es
+-      movw    $0x0080, %di
+-      movw    $0x10, %cx
+-      pushw   %cx
+-      cld
+-      rep
+-      movsb
+-# Get hd1 data...
+-      xorw    %ax, %ax
+-      movw    %ax, %ds
+-      ldsw    (4 * 0x46), %si
+-      popw    %cx
+-      popw    %es
+-      movw    $0x0090, %di
+-      rep
+-      movsb
+-# Check that there IS a hd1 :-)
+-      movw    $0x01500, %ax
+-      movb    $0x81, %dl
+-      int     $0x13
+-      jc      no_disk1
+-      
+-      cmpb    $3, %ah
+-      je      is_disk1
+-
+-no_disk1:
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %es
+-      movw    $0x0090, %di
+-      movw    $0x10, %cx
+-      xorw    %ax, %ax
+-      cld
+-      rep
+-      stosb
+-is_disk1:
+-# check for Micro Channel (MCA) bus
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %ds
+-      xorw    %ax, %ax
+-      movw    %ax, (0xa0)                     # set table length to 0
+-      movb    $0xc0, %ah
+-      stc
+-      int     $0x15                           # moves feature table to es:bx
+-      jc      no_mca
+-
+-      pushw   %ds
+-      movw    %es, %ax
+-      movw    %ax, %ds
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %es
+-      movw    %bx, %si
+-      movw    $0xa0, %di
+-      movw    (%si), %cx
+-      addw    $2, %cx                         # table length is a short
+-      cmpw    $0x10, %cx
+-      jc      sysdesc_ok
+-
+-      movw    $0x10, %cx                      # we keep only first 16 bytes
+-sysdesc_ok:
+-      rep
+-      movsb
+-      popw    %ds
+-no_mca:
+-#ifdef CONFIG_X86_VOYAGER
+-      movb    $0xff, 0x40     # flag on config found
+-      movb    $0xc0, %al
+-      mov     $0xff, %ah
+-      int     $0x15           # put voyager config info at es:di
+-      jc      no_voyager
+-      movw    $0x40, %si      # place voyager info in apm table
+-      cld
+-      movw    $7, %cx
+-voyager_rep:
+-      movb    %es:(%di), %al
+-      movb    %al,(%si)
+-      incw    %di
+-      incw    %si
+-      decw    %cx
+-      jnz     voyager_rep
+-no_voyager:   
+-#endif
+-# Check for PS/2 pointing device
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %ds
+-      movb    $0, (0x1ff)                     # default is no pointing device
+-      int     $0x11                           # int 0x11: equipment list
+-      testb   $0x04, %al                      # check if mouse installed
+-      jz      no_psmouse
+-
+-      movb    $0xAA, (0x1ff)                  # device present
+-no_psmouse:
+-
+-#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
+-      movl    $0x0000E980, %eax               # IST Support 
+-      movl    $0x47534943, %edx               # Request value
+-      int     $0x15
+-
+-      movl    %eax, (96)
+-      movl    %ebx, (100)
+-      movl    %ecx, (104)
+-      movl    %edx, (108)
+-#endif
+-
+-#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+-# Then check for an APM BIOS...
+-                                              # %ds points to the bootsector
+-      movw    $0, 0x40                        # version = 0 means no APM BIOS
+-      movw    $0x05300, %ax                   # APM BIOS installation check
+-      xorw    %bx, %bx
+-      int     $0x15
+-      jc      done_apm_bios                   # Nope, no APM BIOS
+-      
+-      cmpw    $0x0504d, %bx                   # Check for "PM" signature
+-      jne     done_apm_bios                   # No signature, no APM BIOS
+-
+-      andw    $0x02, %cx                      # Is 32 bit supported?
+-      je      done_apm_bios                   # No 32-bit, no (good) APM BIOS
+-
+-      movw    $0x05304, %ax                   # Disconnect first just in case
+-      xorw    %bx, %bx
+-      int     $0x15                           # ignore return code
+-      movw    $0x05303, %ax                   # 32 bit connect
+-      xorl    %ebx, %ebx
+-      xorw    %cx, %cx                        # paranoia :-)
+-      xorw    %dx, %dx                        #   ...
+-      xorl    %esi, %esi                      #   ...
+-      xorw    %di, %di                        #   ...
+-      int     $0x15
+-      jc      no_32_apm_bios                  # Ack, error. 
+-
+-      movw    %ax,  (66)                      # BIOS code segment
+-      movl    %ebx, (68)                      # BIOS entry point offset
+-      movw    %cx,  (72)                      # BIOS 16 bit code segment
+-      movw    %dx,  (74)                      # BIOS data segment
+-      movl    %esi, (78)                      # BIOS code segment lengths
+-      movw    %di,  (82)                      # BIOS data segment length
+-# Redo the installation check as the 32 bit connect
+-# modifies the flags returned on some BIOSs
+-      movw    $0x05300, %ax                   # APM BIOS installation check
+-      xorw    %bx, %bx
+-      xorw    %cx, %cx                        # paranoia
+-      int     $0x15
+-      jc      apm_disconnect                  # error -> shouldn't happen
+-
+-      cmpw    $0x0504d, %bx                   # check for "PM" signature
+-      jne     apm_disconnect                  # no sig -> shouldn't happen
+-
+-      movw    %ax, (64)                       # record the APM BIOS version
+-      movw    %cx, (76)                       # and flags
+-      jmp     done_apm_bios
+-
+-apm_disconnect:                                       # Tidy up
+-      movw    $0x05304, %ax                   # Disconnect
+-      xorw    %bx, %bx
+-      int     $0x15                           # ignore return code
+-
+-      jmp     done_apm_bios
+-
+-no_32_apm_bios:
+-      andw    $0xfffd, (76)                   # remove 32 bit support bit
+-done_apm_bios:
+-#endif
+-
+-#include "edd.S"
+-
+-# Now we want to move to protected mode ...
+-      cmpw    $0, %cs:realmode_swtch
+-      jz      rmodeswtch_normal
+-
+-      lcall   *%cs:realmode_swtch
+-
+-      jmp     rmodeswtch_end
+-
+-rmodeswtch_normal:
+-        pushw %cs
+-      call    default_switch
+-
+-rmodeswtch_end:
+-# Now we move the system to its rightful place ... but we check if we have a
+-# big-kernel. In that case we *must* not move it ...
+-      testb   $LOADED_HIGH, %cs:loadflags
+-      jz      do_move0                        # .. then we have a normal low
+-                                              # loaded zImage
+-                                              # .. or else we have a high
+-                                              # loaded bzImage
+-      jmp     end_move                        # ... and we skip moving
+-
+-do_move0:
+-      movw    $0x100, %ax                     # start of destination segment
+-      movw    %cs, %bp                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %bp             # aka INITSEG
+-      movw    %cs:start_sys_seg, %bx          # start of source segment
+-      cld
+-do_move:
+-      movw    %ax, %es                        # destination segment
+-      incb    %ah                             # instead of add ax,#0x100
+-      movw    %bx, %ds                        # source segment
+-      addw    $0x100, %bx
+-      subw    %di, %di
+-      subw    %si, %si
+-      movw    $0x800, %cx
+-      rep
+-      movsw
+-      cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
+-                                              # so we will perhaps read one
+-                                              # page more than needed, but
+-                                              # never overwrite INITSEG
+-                                              # because destination is a
+-                                              # minimum one page below source
+-      jb      do_move
+-
+-end_move:
+-# then we load the segment descriptors
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      movw    %ax, %ds
+-              
+-# Check whether we need to be downward compatible with version <=201
+-      cmpl    $0, cmd_line_ptr
+-      jne     end_move_self           # loader uses version >=202 features
+-      cmpb    $0x20, type_of_loader
+-      je      end_move_self           # bootsect loader, we know of it
+-
+-# Boot loader doesnt support boot protocol version 2.02.
+-# If we have our code not at 0x90000, we need to move it there now.
+-# We also then need to move the params behind it (commandline)
+-# Because we would overwrite the code on the current IP, we move
+-# it in two steps, jumping high after the first one.
+-      movw    %cs, %ax
+-      cmpw    $SETUPSEG, %ax
+-      je      end_move_self
+-
+-      cli                                     # make sure we really have
+-                                              # interrupts disabled !
+-                                              # because after this the stack
+-                                              # should not be used
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ss, %dx
+-      cmpw    %ax, %dx
+-      jb      move_self_1
+-
+-      addw    $INITSEG, %dx
+-      subw    %ax, %dx                        # this will go into %ss after
+-                                              # the move
+-move_self_1:
+-      movw    %ax, %ds
+-      movw    $INITSEG, %ax                   # real INITSEG
+-      movw    %ax, %es
+-      movw    %cs:setup_move_size, %cx
+-      std                                     # we have to move up, so we use
+-                                              # direction down because the
+-                                              # areas may overlap
+-      movw    %cx, %di
+-      decw    %di
+-      movw    %di, %si
+-      subw    $move_self_here+0x200, %cx
+-      rep
+-      movsb
+-      ljmp    $SETUPSEG, $move_self_here
+-
+-move_self_here:
+-      movw    $move_self_here+0x200, %cx
+-      rep
+-      movsb
+-      movw    $SETUPSEG, %ax
+-      movw    %ax, %ds
+-      movw    %dx, %ss
+-end_move_self:                                        # now we are at the right place
+-
+-#
+-# Enable A20.  This is at the very best an annoying procedure.
+-# A20 code ported from SYSLINUX 1.52-1.63 by H. Peter Anvin.
+-# AMD Elan bug fix by Robert Schwebel.
+-#
+-
+-#if defined(CONFIG_X86_ELAN)
+-      movb $0x02, %al                 # alternate A20 gate
+-      outb %al, $0x92                 # this works on SC410/SC520
+-a20_elan_wait:
+-      call a20_test
+-      jz a20_elan_wait
+-      jmp a20_done
+-#endif
+-
+-
+-A20_TEST_LOOPS                =  32           # Iterations per wait
+-A20_ENABLE_LOOPS      = 255           # Total loops to try            
+-
+-
+-#ifndef CONFIG_X86_VOYAGER
+-a20_try_loop:
+-
+-      # First, see if we are on a system with no A20 gate.
+-a20_none:
+-      call    a20_test
+-      jnz     a20_done
+-
+-      # Next, try the BIOS (INT 0x15, AX=0x2401)
+-a20_bios:
+-      movw    $0x2401, %ax
+-      pushfl                                  # Be paranoid about flags
+-      int     $0x15
+-      popfl
+-
+-      call    a20_test
+-      jnz     a20_done
+-
+-      # Try enabling A20 through the keyboard controller
+-#endif /* CONFIG_X86_VOYAGER */
+-a20_kbc:
+-      call    empty_8042
+-
+-#ifndef CONFIG_X86_VOYAGER
+-      call    a20_test                        # Just in case the BIOS worked
+-      jnz     a20_done                        # but had a delayed reaction.
+-#endif
+-
+-      movb    $0xD1, %al                      # command write
+-      outb    %al, $0x64
+-      call    empty_8042
+-
+-      movb    $0xDF, %al                      # A20 on
+-      outb    %al, $0x60
+-      call    empty_8042
+-
+-#ifndef CONFIG_X86_VOYAGER
+-      # Wait until a20 really *is* enabled; it can take a fair amount of
+-      # time on certain systems; Toshiba Tecras are known to have this
+-      # problem.
+-a20_kbc_wait:
+-      xorw    %cx, %cx
+-a20_kbc_wait_loop:
+-      call    a20_test
+-      jnz     a20_done
+-      loop    a20_kbc_wait_loop
+-
+-      # Final attempt: use "configuration port A"
+-a20_fast:
+-      inb     $0x92, %al                      # Configuration Port A
+-      orb     $0x02, %al                      # "fast A20" version
+-      andb    $0xFE, %al                      # don't accidentally reset
+-      outb    %al, $0x92
+-
+-      # Wait for configuration port A to take effect
+-a20_fast_wait:
+-      xorw    %cx, %cx
+-a20_fast_wait_loop:
+-      call    a20_test
+-      jnz     a20_done
+-      loop    a20_fast_wait_loop
+-
+-      # A20 is still not responding.  Try frobbing it again.
+-      # 
+-      decb    (a20_tries)
+-      jnz     a20_try_loop
+-      
+-      movw    $a20_err_msg, %si
+-      call    prtstr
+-
+-a20_die:
+-      hlt
+-      jmp     a20_die
+-
+-a20_tries:
+-      .byte   A20_ENABLE_LOOPS
+-
+-a20_err_msg:
+-      .ascii  "linux: fatal error: A20 gate not responding!"
+-      .byte   13, 10, 0
+-
+-      # If we get here, all is good
+-a20_done:
+-
+-#endif /* CONFIG_X86_VOYAGER */
+-# set up gdt and idt and 32bit start address
+-      lidt    idt_48                          # load idt with 0,0
+-      xorl    %eax, %eax                      # Compute gdt_base
+-      movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
+-      shll    $4, %eax
+-      addl    %eax, code32
+-      addl    $gdt, %eax
+-      movl    %eax, (gdt_48+2)
+-      lgdt    gdt_48                          # load gdt with whatever is
+-                                              # appropriate
+-
+-# make sure any possible coprocessor is properly reset..
+-      xorw    %ax, %ax
+-      outb    %al, $0xf0
+-      call    delay
+-
+-      outb    %al, $0xf1
+-      call    delay
+-
+-# well, that went ok, I hope. Now we mask all interrupts - the rest
+-# is done in init_IRQ().
+-      movb    $0xFF, %al                      # mask all interrupts for now
+-      outb    %al, $0xA1
+-      call    delay
+-      
+-      movb    $0xFB, %al                      # mask all irq's but irq2 which
+-      outb    %al, $0x21                      # is cascaded
+-
+-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
+-# need no steenking BIOS anyway (except for the initial loading :-).
+-# The BIOS-routine wants lots of unnecessary data, and it's less
+-# "interesting" anyway. This is how REAL programmers do it.
+-#
+-# Well, now's the time to actually move into protected mode. To make
+-# things as simple as possible, we do no register set-up or anything,
+-# we let the gnu-compiled 32-bit programs do that. We just jump to
+-# absolute address 0x1000 (or the loader supplied one),
+-# in 32-bit protected mode.
+-#
+-# Note that the short jump isn't strictly needed, although there are
+-# reasons why it might be a good idea. It won't hurt in any case.
+-      movw    $1, %ax                         # protected mode (PE) bit
+-      lmsw    %ax                             # This is it!
+-      jmp     flush_instr
+-
+-flush_instr:
+-      xorw    %bx, %bx                        # Flag to indicate a boot
+-      xorl    %esi, %esi                      # Pointer to real-mode code
+-      movw    %cs, %si
+-      subw    $DELTA_INITSEG, %si
+-      shll    $4, %esi                        # Convert to 32-bit pointer
+-
+-# jump to startup_32 in arch/i386/boot/compressed/head.S
+-#     
+-# NOTE: For high loaded big kernels we need a
+-#     jmpi    0x100000,__BOOT_CS
+-#
+-#     but we yet haven't reloaded the CS register, so the default size 
+-#     of the target offset still is 16 bit.
+-#     However, using an operand prefix (0x66), the CPU will properly
+-#     take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
+-#     Manual, Mixing 16-bit and 32-bit code, page 16-6)
+-
+-      .byte 0x66, 0xea                        # prefix + jmpi-opcode
+-code32:       .long   startup_32                      # will be set to %cs+startup_32
+-      .word   __BOOT_CS
+-.code32
+-startup_32:
+-      movl $(__BOOT_DS), %eax
+-      movl %eax, %ds
+-      movl %eax, %es
+-      movl %eax, %fs
+-      movl %eax, %gs
+-      movl %eax, %ss
+-
+-      xorl %eax, %eax
+-1:    incl %eax                               # check that A20 really IS enabled
+-      movl %eax, 0x00000000                   # loop forever if it isn't
+-      cmpl %eax, 0x00100000
+-      je 1b
+-
+-      # Jump to the 32bit entry point
+-      jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
+-.code16
+-
+-# Here's a bunch of information about your current kernel..
+-kernel_version:       .ascii  UTS_RELEASE
+-              .ascii  " ("
+-              .ascii  LINUX_COMPILE_BY
+-              .ascii  "@"
+-              .ascii  LINUX_COMPILE_HOST
+-              .ascii  ") "
+-              .ascii  UTS_VERSION
+-              .byte   0
+-
+-# This is the default real mode switch routine.
+-# to be called just before protected mode transition
+-default_switch:
+-      cli                                     # no interrupts allowed !
+-      movb    $0x80, %al                      # disable NMI for bootup
+-                                              # sequence
+-      outb    %al, $0x70
+-      lret
+-
+-
+-#ifndef CONFIG_X86_VOYAGER
+-# This routine tests whether or not A20 is enabled.  If so, it
+-# exits with zf = 0.
+-#
+-# The memory address used, 0x200, is the int $0x80 vector, which
+-# should be safe.
+-
+-A20_TEST_ADDR = 4*0x80
+-
+-a20_test:
+-      pushw   %cx
+-      pushw   %ax
+-      xorw    %cx, %cx
+-      movw    %cx, %fs                        # Low memory
+-      decw    %cx
+-      movw    %cx, %gs                        # High memory area
+-      movw    $A20_TEST_LOOPS, %cx
+-      movw    %fs:(A20_TEST_ADDR), %ax
+-      pushw   %ax
+-a20_test_wait:
+-      incw    %ax
+-      movw    %ax, %fs:(A20_TEST_ADDR)
+-      call    delay                           # Serialize and make delay constant
+-      cmpw    %gs:(A20_TEST_ADDR+0x10), %ax
+-      loope   a20_test_wait
+-
+-      popw    %fs:(A20_TEST_ADDR)
+-      popw    %ax
+-      popw    %cx
+-      ret     
+-
+-#endif /* CONFIG_X86_VOYAGER */
+-
+-# This routine checks that the keyboard command queue is empty
+-# (after emptying the output buffers)
+-#
+-# Some machines have delusions that the keyboard buffer is always full
+-# with no keyboard attached...
+-#
+-# If there is no keyboard controller, we will usually get 0xff
+-# to all the reads.  With each IO taking a microsecond and
+-# a timeout of 100,000 iterations, this can take about half a
+-# second ("delay" == outb to port 0x80). That should be ok,
+-# and should also be plenty of time for a real keyboard controller
+-# to empty.
+-#
+-
+-empty_8042:
+-      pushl   %ecx
+-      movl    $100000, %ecx
+-
+-empty_8042_loop:
+-      decl    %ecx
+-      jz      empty_8042_end_loop
+-
+-      call    delay
+-
+-      inb     $0x64, %al                      # 8042 status port
+-      testb   $1, %al                         # output buffer?
+-      jz      no_output
+-
+-      call    delay
+-      inb     $0x60, %al                      # read it
+-      jmp     empty_8042_loop
+-
+-no_output:
+-      testb   $2, %al                         # is input buffer full?
+-      jnz     empty_8042_loop                 # yes - loop
+-empty_8042_end_loop:
+-      popl    %ecx
+-      ret
+-
+-# Read the cmos clock. Return the seconds in al
+-gettime:
+-      pushw   %cx
+-      movb    $0x02, %ah
+-      int     $0x1a
+-      movb    %dh, %al                        # %dh contains the seconds
+-      andb    $0x0f, %al
+-      movb    %dh, %ah
+-      movb    $0x04, %cl
+-      shrb    %cl, %ah
+-      aad
+-      popw    %cx
+-      ret
+-
+-# Delay is needed after doing I/O
+-delay:
+-      outb    %al,$0x80
+-      ret
+-
+-# Descriptor tables
+-#
+-# NOTE: The intel manual says gdt should be sixteen bytes aligned for
+-# efficiency reasons.  However, there are machines which are known not
+-# to boot with misaligned GDTs, so alter this at your peril!  If you alter
+-# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
+-# empty GDT entries (one for NULL and one reserved).
+-#
+-# NOTE:       On some CPUs, the GDT must be 8 byte aligned.  This is
+-# true for the Voyager Quad CPU card which will not boot without
+-# This directive.  16 byte aligment is recommended by intel.
+-#
+-      .align 16
+-gdt:
+-      .fill GDT_ENTRY_BOOT_CS,8,0
+-
+-      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
+-      .word   0                               # base address = 0
+-      .word   0x9A00                          # code read/exec
+-      .word   0x00CF                          # granularity = 4096, 386
+-                                              #  (+5th nibble of limit)
+-
+-      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
+-      .word   0                               # base address = 0
+-      .word   0x9200                          # data read/write
+-      .word   0x00CF                          # granularity = 4096, 386
+-                                              #  (+5th nibble of limit)
+-gdt_end:
+-      .align  4
+-      
+-      .word   0                               # alignment byte
+-idt_48:
+-      .word   0                               # idt limit = 0
+-      .word   0, 0                            # idt base = 0L
+-
+-      .word   0                               # alignment byte
+-gdt_48:
+-      .word   gdt_end - gdt - 1               # gdt limit
+-      .word   0, 0                            # gdt base (filled in later)
+-
+-# Include video setup & detection code
+-
+-#include "video.S"
+-
+-# Setup signature -- must be last
+-setup_sig1:   .word   SIG1
+-setup_sig2:   .word   SIG2
+-
+-# After this point, there is some free space which is used by the video mode
+-# handling code to store the temporary mode table (not used by the kernel).
+-
+-modelist:
+-
+-.text
+-endtext:
+-.data
+-enddata:
+-.bss
+-endbss:
+diff -puN /dev/null arch/i386/boot/setup.ld
+--- /dev/null
++++ a/arch/i386/boot/setup.ld
+@@ -0,0 +1,54 @@
++/*
++ * setup.ld
++ *
++ * Linker script for the i386 setup code
++ */
++OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
++OUTPUT_ARCH(i386)
++ENTRY(_start)
++
++SECTIONS
++{
++      . = 0;
++      .bstext         : { *(.bstext) }
++      .bsdata         : { *(.bsdata) }
++
++      . = 497;
++      .header         : { *(.header) }
++      .inittext       : { *(.inittext) }
++      .initdata       : { *(.initdata) }
++      .text           : { *(.text*) }
++
++      . = ALIGN(16);
++      .rodata         : { *(.rodata*) }
++
++      .videocards     : {
++              video_cards = .;
++              *(.videocards)
++              video_cards_end = .;
++      }
++
++      . = ALIGN(16);
++      .data           : { *(.data*) }
++
++      .signature      : {
++              setup_sig = .;
++              LONG(0x5a5aaa55)
++      }
++
++
++      . = ALIGN(16);
++      .bss            :
++      {
++              __bss_start = .;
++              *(.bss)
++              __bss_end = .;
++      }
++      . = ALIGN(16);
++      _end = .;
++
++      /DISCARD/ : { *(.note*) }
++
++      . = ASSERT(_end <= 0x8000, "Setup too big!");
++      . = ASSERT(hdr == 0x1f1, "The setup header has the wrong offset!");
++}
+diff -puN /dev/null arch/i386/boot/string.c
+--- /dev/null
++++ a/arch/i386/boot/string.c
+@@ -0,0 +1,34 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/string.c
++ *
++ * Very basic string functions
++ */
++
++#include "boot.h"
++#include <linux/edd.h>
++
++int strcmp(const char *str1, const char *str2)
++{
++      const unsigned char *s1 = (const unsigned char *)str1;
++      const unsigned char *s2 = (const unsigned char *)str2;
++      int delta = 0;
++
++      while (*s1 || *s2) {
++              delta = *s2 - *s1;
++              if (delta)
++                      return delta;
++              s1++;
++              s2++;
++      }
++      return 0;
++}
+diff -puN arch/i386/boot/tools/build.c~git-newsetup arch/i386/boot/tools/build.c
+--- a/arch/i386/boot/tools/build.c~git-newsetup
++++ a/arch/i386/boot/tools/build.c
+@@ -1,13 +1,12 @@
+ /*
+  *  Copyright (C) 1991, 1992  Linus Torvalds
+  *  Copyright (C) 1997 Martin Mares
++ *  Copyright (C) 2007 H. Peter Anvin
+  */
+ /*
+  * This file builds a disk-image from three different files:
+  *
+- * - bootsect: compatibility mbr which prints an error message if
+- *             someone tries to boot the kernel directly.
+  * - setup: 8086 machine code, sets up system parm
+  * - system: 80386 code for actual system
+  *
+@@ -21,6 +20,7 @@
+  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+  * Cross compiling fixes by Gertjan van Wingerde, July 1996
+  * Rewritten by Martin Mares, April 1997
++ * Substantially overhauled by H. Peter Anvin, April 2007
+  */
+ #include <stdio.h>
+@@ -32,23 +32,25 @@
+ #include <sys/sysmacros.h>
+ #include <unistd.h>
+ #include <fcntl.h>
++#include <sys/mman.h>
+ #include <asm/boot.h>
+-typedef unsigned char byte;
+-typedef unsigned short word;
+-typedef unsigned long u32;
++typedef unsigned char  u8;
++typedef unsigned short u16;
++typedef unsigned long  u32;
+ #define DEFAULT_MAJOR_ROOT 0
+ #define DEFAULT_MINOR_ROOT 0
+-/* Minimal number of setup sectors (see also bootsect.S) */
+-#define SETUP_SECTS 4
++/* Minimal number of setup sectors */
++#define SETUP_SECT_MIN 5
++#define SETUP_SECT_MAX 64
+-byte buf[1024];
+-int fd;
++/* This must be large enough to hold the entire setup */
++u8 buf[SETUP_SECT_MAX*512];
+ int is_big_kernel;
+-void die(const char * str, ...)
++static void die(const char * str, ...)
+ {
+       va_list args;
+       va_start(args, str);
+@@ -57,15 +59,9 @@ void die(const char * str, ...)
+       exit(1);
+ }
+-void file_open(const char *name)
++static void usage(void)
+ {
+-      if ((fd = open(name, O_RDONLY, 0)) < 0)
+-              die("Unable to open `%s': %m", name);
+-}
+-
+-void usage(void)
+-{
+-      die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
++      die("Usage: build [-b] setup system [rootdev] [> image]");
+ }
+ int main(int argc, char ** argv)
+@@ -73,27 +69,30 @@ int main(int argc, char ** argv)
+       unsigned int i, sz, setup_sectors;
+       int c;
+       u32 sys_size;
+-      byte major_root, minor_root;
++      u8 major_root, minor_root;
+       struct stat sb;
++      FILE *file;
++      int fd;
++      void *kernel;
+       if (argc > 2 && !strcmp(argv[1], "-b"))
+         {
+           is_big_kernel = 1;
+           argc--, argv++;
+         }
+-      if ((argc < 4) || (argc > 5))
++      if ((argc < 3) || (argc > 4))
+               usage();
+-      if (argc > 4) {
+-              if (!strcmp(argv[4], "CURRENT")) {
++      if (argc > 3) {
++              if (!strcmp(argv[3], "CURRENT")) {
+                       if (stat("/", &sb)) {
+                               perror("/");
+                               die("Couldn't stat /");
+                       }
+                       major_root = major(sb.st_dev);
+                       minor_root = minor(sb.st_dev);
+-              } else if (strcmp(argv[4], "FLOPPY")) {
+-                      if (stat(argv[4], &sb)) {
+-                              perror(argv[4]);
++              } else if (strcmp(argv[3], "FLOPPY")) {
++                      if (stat(argv[3], &sb)) {
++                              perror(argv[3]);
+                               die("Couldn't stat root device.");
+                       }
+                       major_root = major(sb.st_rdev);
+@@ -108,79 +107,62 @@ int main(int argc, char ** argv)
+       }
+       fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
+-      file_open(argv[1]);
+-      i = read(fd, buf, sizeof(buf));
+-      fprintf(stderr,"Boot sector %d bytes.\n",i);
+-      if (i != 512)
+-              die("Boot block must be exactly 512 bytes");
++      /* Copy the setup code */
++      file = fopen(argv[1], "r");
++      if (!file)
++              die("Unable to open `%s': %m", argv[1]);
++      c = fread(buf, 1, sizeof(buf), file);
++      if (ferror(file))
++              die("read-error on `setup'");
++      if (c < 1024)
++              die("The setup must be at least 1024 bytes");
+       if (buf[510] != 0x55 || buf[511] != 0xaa)
+               die("Boot block hasn't got boot flag (0xAA55)");
++      fclose(file);
++
++      /* Pad unused space with zeros */
++      setup_sectors = (c + 511) / 512;
++      if (setup_sectors < SETUP_SECT_MIN)
++              setup_sectors = SETUP_SECT_MIN;
++      i = setup_sectors*512;
++      memset(buf+c, 0, i-c);
++
++      /* Set the default root device */
+       buf[508] = minor_root;
+       buf[509] = major_root;
+-      if (write(1, buf, 512) != 512)
+-              die("Write call failed");
+-      close (fd);
+-
+-      file_open(argv[2]);                                 /* Copy the setup code */
+-      for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
+-              if (write(1, buf, c) != c)
+-                      die("Write call failed");
+-      if (c != 0)
+-              die("read-error on `setup'");
+-      close (fd);
+-      setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
+-      /* for compatibility with ancient versions of LILO. */
+-      if (setup_sectors < SETUP_SECTS)
+-              setup_sectors = SETUP_SECTS;
+-      fprintf(stderr, "Setup is %d bytes.\n", i);
+-      memset(buf, 0, sizeof(buf));
+-      while (i < setup_sectors * 512) {
+-              c = setup_sectors * 512 - i;
+-              if (c > sizeof(buf))
+-                      c = sizeof(buf);
+-              if (write(1, buf, c) != c)
+-                      die("Write call failed");
+-              i += c;
+-      }
++      fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
+-      file_open(argv[3]);
+-      if (fstat (fd, &sb))
+-              die("Unable to stat `%s': %m", argv[3]);
++      /* Open and stat the kernel file */
++      fd = open(argv[2], O_RDONLY);
++      if (fd < 0)
++              die("Unable to open `%s': %m", argv[2]);
++      if (fstat(fd, &sb))
++              die("Unable to stat `%s': %m", argv[2]);
+       sz = sb.st_size;
+-      fprintf (stderr, "System is %d kB\n", sz/1024);
++      fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
++      kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
++      if (kernel == MAP_FAILED)
++              die("Unable to mmap '%s': %m", argv[2]);
+       sys_size = (sz + 15) / 16;
+       if (!is_big_kernel && sys_size > DEF_SYSSIZE)
+               die("System is too big. Try using bzImage or modules.");
+-      while (sz > 0) {
+-              int l, n;
+-              l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
+-              if ((n=read(fd, buf, l)) != l) {
+-                      if (n < 0)
+-                              die("Error reading %s: %m", argv[3]);
+-                      else
+-                              die("%s: Unexpected EOF", argv[3]);
+-              }
+-              if (write(1, buf, l) != l)
+-                      die("Write failed");
+-              sz -= l;
+-      }
++      /* Patch the setup code with the appropriate size parameters */
++      buf[0x1f1] = setup_sectors-1;
++      buf[0x1f4] = sys_size;
++      buf[0x1f5] = sys_size >> 8;
++      buf[0x1f6] = sys_size >> 16;
++      buf[0x1f7] = sys_size >> 24;
++
++      if (fwrite(buf, 1, i, stdout) != i)
++              die("Writing setup failed");
++
++      /* Copy the kernel code */
++      if (fwrite(kernel, 1, sz, stdout) != sz)
++              die("Writing kernel failed");
+       close(fd);
+-      if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
+-              die("Output: seek failed");
+-      buf[0] = setup_sectors;
+-      if (write(1, buf, 1) != 1)
+-              die("Write of setup sector count failed");
+-      if (lseek(1, 500, SEEK_SET) != 500)
+-              die("Output: seek failed");
+-      buf[0] = (sys_size & 0xff);
+-      buf[1] = ((sys_size >> 8) & 0xff);
+-      buf[2] = ((sys_size >> 16) & 0xff);
+-      buf[3] = ((sys_size >> 24) & 0xff);
+-      if (write(1, buf, 4) != 4)
+-              die("Write of image length failed");
+-
+-      return 0;                                           /* Everything is OK */
++      /* Everything is OK */
++      return 0;
+ }
+diff -puN /dev/null arch/i386/boot/tty.c
+--- /dev/null
++++ a/arch/i386/boot/tty.c
+@@ -0,0 +1,112 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/tty.c
++ *
++ * Very simple screen I/O
++ * XXX: Probably should add very simple serial I/O?
++ */
++
++#include "boot.h"
++
++/*
++ * These functions are in .inittext so they can be used to signal
++ * error during initialization.
++ */
++
++void __attribute__((section(".inittext"))) putchar(int ch)
++{
++      unsigned char c = ch;
++
++      if (c == '\n')
++              putchar('\r');  /* \n -> \r\n */
++
++      /* int $0x10 is known to have bugs involving touching registers
++         it shouldn't.  Be extra conservative... */
++      asm volatile("pushal; int $0x10; popal"
++                   : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
++}
++
++void __attribute__((section(".inittext"))) puts(const char *str)
++{
++      int n = 0;
++      while (*str) {
++              putchar(*str++);
++              n++;
++      }
++}
++
++/*
++ * Read the CMOS clock through the BIOS, and return the
++ * seconds in BCD.
++ */
++
++static u8 gettime(void)
++{
++      u16 ax = 0x0200;
++      u16 cx, dx;
++
++      asm("int $0x1a"
++          : "+a" (ax), "=c" (cx), "=d" (dx)
++          : : "ebx", "esi", "edi");
++
++      return dx >> 8;
++}
++
++/*
++ * Read from the keyboard
++ */
++int getchar(void)
++{
++      u16 ax = 0;
++      asm("int $0x16" : "+a" (ax));
++
++      return ax & 0xff;
++}
++
++static int kbd_pending(void)
++{
++      u8 pending;
++      asm("int $0x16; setnz %0"
++          : "=rm" (pending)
++          : "a" (0x0100));
++      return pending;
++}
++
++void kbd_flush(void)
++{
++      for (;;) {
++              if (!kbd_pending())
++                      break;
++              getchar();
++      }
++}
++
++int getchar_timeout(void)
++{
++      int cnt = 30;
++      int t0, t1;
++
++      t0 = gettime();
++
++      while (cnt) {
++              if (kbd_pending())
++                      return getchar();
++
++              t1 = gettime();
++              if (t0 != t1) {
++                      cnt--;
++                      t0 = t1;
++              }
++      }
++
++      return 0;               /* Timeout! */
++}
+diff -puN /dev/null arch/i386/boot/version.c
+--- /dev/null
++++ a/arch/i386/boot/version.c
+@@ -0,0 +1,23 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/version.c
++ *
++ * Kernel version string
++ */
++
++#include "boot.h"
++#include <linux/utsrelease.h>
++#include <linux/compile.h>
++
++const char kernel_version[] =
++      UTS_RELEASE " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
++      UTS_VERSION;
+diff -puN /dev/null arch/i386/boot/vesa.h
+--- /dev/null
++++ a/arch/i386/boot/vesa.h
+@@ -0,0 +1,79 @@
++/* ----------------------------------------------------------------------- *
++ *
++ *   Copyright 1999-2007 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.
++ *
++ * ----------------------------------------------------------------------- */
++
++#ifndef BOOT_VESA_H
++#define BOOT_VESA_H
++
++typedef struct {
++      u16 off, seg;
++} far_ptr;
++
++/* VESA General Information table */
++struct vesa_general_info {
++  u32   signature;            /* 0 Magic number = "VESA" */
++  u16   version;              /* 4 */
++  far_ptr vendor_string;      /* 6 */
++  u32   capabilities;         /* 10 */
++  far_ptr video_mode_ptr;     /* 14 */
++  u16     total_memory;               /* 18 */
++
++  u16     oem_software_rev;   /* 20 */
++  far_ptr oem_vendor_name_ptr;        /* 22 */
++  far_ptr oem_product_name_ptr;       /* 26 */
++  far_ptr oem_product_rev_ptr;        /* 30 */
++
++  u8      reserved[222];      /* 34 */
++  u8      oem_data[256];      /* 256 */
++} __attribute__((packed));
++
++#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
++#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
++
++struct vesa_mode_info {
++  u16     mode_attr;          /* 0 */
++  u8      win_attr[2];                /* 2 */
++  u16     win_grain;          /* 4 */
++  u16     win_size;           /* 6 */
++  u16     win_seg[2];         /* 8 */
++  far_ptr win_scheme;         /* 12 */
++  u16     logical_scan;               /* 16 */
++
++  u16     h_res;              /* 18 */
++  u16     v_res;              /* 20 */
++  u8      char_width;         /* 22 */
++  u8      char_height;                /* 23 */
++  u8      memory_planes;      /* 24 */
++  u8      bpp;                        /* 25 */
++  u8      banks;              /* 26 */
++  u8      memory_layout;      /* 27 */
++  u8      bank_size;          /* 28 */
++  u8      image_planes;               /* 29 */
++  u8      page_function;      /* 30 */
++
++  u8      rmask;              /* 31 */
++  u8      rpos;                       /* 32 */
++  u8      gmask;              /* 33 */
++  u8      gpos;                       /* 34 */
++  u8      bmask;              /* 35 */
++  u8      bpos;                       /* 36 */
++  u8      resv_mask;          /* 37 */
++  u8      resv_pos;           /* 38 */
++  u8      dcm_info;           /* 39 */
++
++  u32     lfb_ptr;            /* 40 Linear frame buffer address */
++  u32     offscreen_ptr;      /* 44 Offscreen memory address */
++  u16     offscreen_size;     /* 48 */
++
++  u8      reserved[206];      /* 50 */
++} __attribute__((packed));
++
++#endif /* LIB_SYS_VESA_H */
+diff -puN /dev/null arch/i386/boot/video-bios.c
+--- /dev/null
++++ a/arch/i386/boot/video-bios.c
+@@ -0,0 +1,125 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/video-bios.c
++ *
++ * Standard video BIOS modes
++ *
++ * We have two options for this; silent and scanned.
++ */
++
++#include "boot.h"
++#include "video.h"
++
++__videocard video_bios;
++
++/* Set a conventional BIOS mode */
++static int set_bios_mode(u8 mode);
++
++static int bios_set_mode(struct mode_info *mi)
++{
++      return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS);
++}
++
++static int set_bios_mode(u8 mode)
++{
++      u16 ax;
++      u8 new_mode;
++
++      ax = mode;              /* AH=0x00 Set Video Mode */
++      asm volatile(INT10
++                   : "+a" (ax)
++                   : : "ebx", "ecx", "edx", "esi", "edi");
++
++      ax = 0x0f00;            /* Get Current Video Mode */
++      asm volatile(INT10
++                   : "+a" (ax)
++                   : : "ebx", "ecx", "edx", "esi", "edi");
++
++      do_restore = 1;         /* Assume video contents was lost */
++      new_mode = ax & 0x7f;   /* Not all BIOSes are clean with the top bit */
++
++      if (new_mode == mode)
++              return 0;       /* Mode change OK */
++
++      if (new_mode != boot_params.screen_info.orig_video_mode) {
++              /* Mode setting failed, but we didn't end up where we
++                 started.  That's bad.  Try to revert to the original
++                 video mode. */
++              ax = boot_params.screen_info.orig_video_mode;
++              asm volatile(INT10
++                           : "+a" (ax)
++                           : : "ebx", "ecx", "edx", "esi", "edi");
++      }
++      return -1;
++}
++
++static int bios_probe(void)
++{
++      u8 mode;
++      u8 saved_mode = boot_params.screen_info.orig_video_mode;
++      u16 crtc;
++      struct mode_info *mi;
++      int nmodes = 0;
++
++      if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA)
++              return 0;
++
++      set_fs(0);
++      crtc = vga_crtc();
++
++      video_bios.modes = GET_HEAP(struct mode_info, 0);
++
++      for (mode = 0x14; mode <= 0x7f; mode++) {
++              if (heap_free() < sizeof(struct mode_info))
++                      break;
++
++              if (mode_defined(VIDEO_FIRST_BIOS+mode))
++                      continue;
++
++              if (set_bios_mode(mode))
++                      continue;
++
++              /* Try to verify that it's a text mode. */
++
++              /* Attribute Controller: make graphics controller disabled */
++              if (in_idx(0x3c0, 0x10) & 0x01)
++                      continue;
++
++              /* Graphics Controller: verify Alpha addressing enabled */
++              if (in_idx(0x3ce, 0x06) & 0x01)
++                      continue;
++
++              /* CRTC cursor location low should be zero(?) */
++              if (in_idx(crtc, 0x0f))
++                      continue;
++
++              mi = GET_HEAP(struct mode_info, 1);
++              mi->mode = VIDEO_FIRST_BIOS+mode;
++              mi->x = rdfs16(0x44a);
++              mi->y = rdfs8(0x484)+1;
++              nmodes++;
++      }
++
++      set_bios_mode(saved_mode);
++
++      return nmodes;
++}
++
++__videocard video_bios =
++{
++      .card_name      = "BIOS (scanned)",
++      .probe          = bios_probe,
++      .set_mode       = bios_set_mode,
++      .unsafe         = 1,
++      .xmode_first    = VIDEO_FIRST_BIOS,
++      .xmode_n        = 0x80,
++};
+diff -puN /dev/null arch/i386/boot/video-vesa.c
+--- /dev/null
++++ a/arch/i386/boot/video-vesa.c
+@@ -0,0 +1,283 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/video-vesa.c
++ *
++ * VESA text modes
++ */
++
++#include "boot.h"
++#include "video.h"
++#include "vesa.h"
++
++/* VESA information */
++static struct vesa_general_info vginfo;
++static struct vesa_mode_info vminfo;
++
++__videocard video_vesa;
++
++static void vesa_store_mode_params_graphics(void);
++
++static int vesa_probe(void)
++{
++#ifdef CONFIG_VIDEO_VESA
++      u16 ax;
++      u16 mode;
++      addr_t mode_ptr;
++      struct mode_info *mi;
++      int nmodes = 0;
++
++      video_vesa.modes = GET_HEAP(struct mode_info, 0);
++
++      vginfo.signature = VBE2_MAGIC;
++
++      /* Optimistically assume a VESA BIOS is register-clean... */
++      ax = 0x4f00;
++      asm("int $0x10" : "+a" (ax), "=m" (vginfo) : "D" (&vginfo));
++
++      if (ax != 0x004f ||
++          vginfo.signature != VESA_MAGIC ||
++          vginfo.version < 0x0102)
++              return 0;       /* Not present */
++
++      set_fs(vginfo.video_mode_ptr.seg);
++      mode_ptr = vginfo.video_mode_ptr.off;
++
++      while ((mode = rdfs16(mode_ptr)) != 0xffff) {
++              mode_ptr += 2;
++
++              if (heap_free() < sizeof(struct mode_info))
++                      break;  /* Heap full, can't save mode info */
++
++              if (mode & ~0x1ff)
++                      continue;
++
++              memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
++
++              ax = 0x4f01;
++              asm("int $0x10"
++                  : "+a" (ax), "=m" (vminfo)
++                  : "c" (mode), "D" (&vminfo));
++
++              if (ax != 0x004f)
++                      continue;
++
++              if ((vminfo.mode_attr & 0x15) == 0x05) {
++                      /* Text Mode, TTY BIOS supported,
++                         supported by hardware */
++                      mi = GET_HEAP(struct mode_info, 1);
++                      mi->mode = mode + VIDEO_FIRST_VESA;
++                      mi->x    = vminfo.h_res;
++                      mi->y    = vminfo.v_res;
++                      nmodes++;
++              } else if ((vminfo.mode_attr & 0x99) == 0x99) {
++#ifdef CONFIG_FB
++                      /* Graphics mode, color, linear frame buffer
++                         supported -- register the mode but hide from
++                         the menu.  Only do this if framebuffer is
++                         configured, however, otherwise the user will
++                         be left without a screen. */
++                      mi = GET_HEAP(struct mode_info, 1);
++                      mi->mode = mode + VIDEO_FIRST_VESA;
++                      mi->x = mi->y = 0;
++                      nmodes++;
++#endif
++              }
++      }
++
++      return nmodes;
++#else
++      return 0;
++#endif
++}
++
++static int vesa_set_mode(struct mode_info *mode)
++{
++      u16 ax;
++      int is_graphic;
++      u16 vesa_mode = mode->mode - VIDEO_FIRST_VESA;
++
++      memset(&vminfo, 0, sizeof vminfo); /* Just in case... */
++
++      ax = 0x4f01;
++      asm("int $0x10"
++          : "+a" (ax), "=m" (vminfo)
++          : "c" (vesa_mode), "D" (&vminfo));
++
++      if (ax != 0x004f)
++              return -1;
++
++      if ((vminfo.mode_attr & 0x15) == 0x05) {
++              /* It's a supported text mode */
++              is_graphic = 0;
++      } else if ((vminfo.mode_attr & 0x99) == 0x99) {
++              /* It's a graphics mode with linear frame buffer */
++              is_graphic = 1;
++              vesa_mode |= 0x4000; /* Request linear frame buffer */
++      } else {
++              return -1;      /* Invalid mode */
++      }
++
++
++      ax = 0x4f02;
++      asm volatile("int $0x10"
++                   : "+a" (ax)
++                   : "b" (vesa_mode), "D" (0));
++
++      if (ax != 0x004f)
++              return -1;
++
++      graphic_mode = is_graphic;
++      if (!is_graphic) {
++              /* Text mode */
++              force_x = mode->x;
++              force_y = mode->y;
++              do_restore = 1;
++      } else {
++              /* Graphics mode */
++              vesa_store_mode_params_graphics();
++      }
++
++      return 0;
++}
++
++
++/* Switch DAC to 8-bit mode */
++static void vesa_dac_set_8bits(void)
++{
++      u8 dac_size = 6;
++
++      /* If possible, switch the DAC to 8-bit mode */
++      if (vginfo.capabilities & 1) {
++              u16 ax, bx;
++
++              ax = 0x4f08;
++              bx = 0x0800;
++              asm volatile(INT10
++                           : "+a" (ax), "+b" (bx)
++                           : : "ecx", "edx", "esi", "edi");
++
++              if (ax == 0x004f)
++                      dac_size = bx >> 8;
++      }
++
++      /* Set the color sizes to the DAC size, and offsets to 0 */
++      boot_params.screen_info.red_size = dac_size;
++      boot_params.screen_info.green_size = dac_size;
++      boot_params.screen_info.blue_size = dac_size;
++      boot_params.screen_info.rsvd_size = dac_size;
++
++      boot_params.screen_info.red_pos = 0;
++      boot_params.screen_info.green_pos = 0;
++      boot_params.screen_info.blue_pos = 0;
++      boot_params.screen_info.rsvd_pos = 0;
++}
++
++/* Save the VESA protected mode info */
++static void vesa_store_pm_info(void)
++{
++      u16 ax, bx, di, es;
++
++      ax = 0x4f0a;
++      bx = di = 0;
++      asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
++          : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
++          : : "ecx", "esi");
++
++      if (ax != 0x004f)
++              return;
++
++      boot_params.screen_info.vesapm_seg = es;
++      boot_params.screen_info.vesapm_off = di;
++}
++
++/*
++ * Save video mode parameters for graphics mode
++ */
++static void vesa_store_mode_params_graphics(void)
++{
++      /* Tell the kernel we're in VESA graphics mode */
++      boot_params.screen_info.orig_video_isVGA = 0x23;
++
++      /* Mode parameters */
++      boot_params.screen_info.vesa_attributes = vminfo.mode_attr;
++      boot_params.screen_info.lfb_linelength = vminfo.logical_scan;
++      boot_params.screen_info.lfb_width = vminfo.h_res;
++      boot_params.screen_info.lfb_height = vminfo.v_res;
++      boot_params.screen_info.lfb_depth = vminfo.bpp;
++      boot_params.screen_info.pages = vminfo.image_planes;
++      boot_params.screen_info.lfb_base = vminfo.lfb_ptr;
++      memcpy(&boot_params.screen_info.red_size,
++             &vminfo.rmask, 8);
++
++      /* General parameters */
++      boot_params.screen_info.lfb_size = vginfo.total_memory;
++
++      if (vminfo.bpp <= 8)
++              vesa_dac_set_8bits();
++
++      vesa_store_pm_info();
++}
++
++/*
++ * Save EDID information for the kernel; this is invoked, separately,
++ * after mode-setting.
++ */
++void vesa_store_edid(void)
++{
++#ifdef CONFIG_FIRMWARE_EDID
++      u16 ax, bx, cx, dx, di;
++
++      /* Apparently used as a nonsense token... */
++      memset(&boot_params.edid_info, 0x13, sizeof boot_params.edid_info);
++
++      if (vginfo.version < 0x0200)
++              return;         /* EDID requires VBE 2.0+ */
++
++      ax = 0x4f15;            /* VBE DDC */
++      bx = 0x0000;            /* Report DDC capabilities */
++      cx = 0;                 /* Controller 0 */
++      di = 0;                 /* ES:DI must be 0 by spec */
++
++      /* Note: The VBE DDC spec is different from the main VESA spec;
++         we genuinely have to assume all registers are destroyed here. */
++
++      asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
++          : "+a" (ax), "+b" (bx)
++          :  "c" (cx), "D" (di)
++          : "esi");
++
++      if (ax != 0x004f)
++              return;         /* No EDID */
++
++      /* BH = time in seconds to transfer EDD information */
++      /* BL = DDC level supported */
++
++      ax = 0x4f15;            /* VBE DDC */
++      bx = 0x0001;            /* Read EDID */
++      cx = 0;                 /* Controller 0 */
++      dx = 0;                 /* EDID block number */
++      di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
++      asm(INT10
++          : "+a" (ax), "+b" (bx), "+d" (dx)
++          : "c" (cx), "D" (di)
++          : "esi");
++#endif /* CONFIG_FIRMWARE_EDID */
++}
++
++__videocard video_vesa =
++{
++      .card_name      = "VESA",
++      .probe          = vesa_probe,
++      .set_mode       = vesa_set_mode,
++      .xmode_first    = VIDEO_FIRST_VESA,
++      .xmode_n        = 0x200,
++};
+diff -puN /dev/null arch/i386/boot/video-vga.c
+--- /dev/null
++++ a/arch/i386/boot/video-vga.c
+@@ -0,0 +1,260 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/video-vga.c
++ *
++ * Common all-VGA modes
++ */
++
++#include "boot.h"
++#include "video.h"
++
++static struct mode_info vga_modes[] = {
++      { VIDEO_80x25,  80, 25 },
++      { VIDEO_8POINT, 80, 50 },
++      { VIDEO_80x43,  80, 43 },
++      { VIDEO_80x28,  80, 28 },
++      { VIDEO_80x30,  80, 30 },
++      { VIDEO_80x34,  80, 34 },
++      { VIDEO_80x60,  80, 60 },
++};
++
++static struct mode_info ega_modes[] = {
++      { VIDEO_80x25,  80, 25 },
++      { VIDEO_8POINT, 80, 43 },
++};
++
++static struct mode_info cga_modes[] = {
++      { VIDEO_80x25,  80, 25 },
++};
++
++__videocard video_vga;
++
++/* Set basic 80x25 mode */
++static u8 vga_set_basic_mode(void)
++{
++      u16 ax;
++      u8 rows;
++      u8 mode;
++
++#ifdef CONFIG_VIDEO_400_HACK
++      if (adapter >= ADAPTER_VGA) {
++              asm(INT10
++                  : : "a" (0x1202), "b" (0x0030)
++                  : "ecx", "edx", "esi", "edi");
++      }
++#endif
++
++      ax = 0x0f00;
++      asm(INT10
++          : "+a" (ax)
++          : : "ebx", "ecx", "edx", "esi", "edi");
++
++      mode = (u8)ax;
++
++      set_fs(0);
++      rows = rdfs8(0x484);    /* rows minus one */
++
++#ifndef CONFIG_VIDEO_400_HACK
++      if ((ax == 0x5003 || ax == 0x5007) &&
++          (rows == 0 || rows == 24))
++              return mode;
++#endif
++
++      if (mode != 3 && mode != 7)
++              mode = 3;
++
++      /* Set the mode */
++      asm volatile(INT10
++                   : : "a" (mode)
++                   : "ebx", "ecx", "edx", "esi", "edi");
++      do_restore = 1;
++      return mode;
++}
++
++static void vga_set_8font(void)
++{
++      /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
++
++      /* Set 8x8 font */
++      asm volatile(INT10 : : "a" (0x1112), "b" (0));
++
++      /* Use alternate print screen */
++      asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
++
++      /* Turn off cursor emulation */
++      asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
++
++      /* Cursor is scan lines 6-7 */
++      asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
++}
++
++static void vga_set_14font(void)
++{
++      /* Set 9x14 font - 80x28 on VGA */
++
++      /* Set 9x14 font */
++      asm volatile(INT10 : : "a" (0x1111), "b" (0));
++
++      /* Turn off cursor emulation */
++      asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
++
++      /* Cursor is scan lines 11-12 */
++      asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
++}
++
++static void vga_set_80x43(void)
++{
++      /* Set 80x43 mode on VGA (not EGA) */
++
++      /* Set 350 scans */
++      asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
++
++      /* Reset video mode */
++      asm volatile(INT10 : : "a" (0x0003));
++
++      vga_set_8font();
++}
++
++/* I/O address of the VGA CRTC */
++u16 vga_crtc(void)
++{
++      return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
++}
++
++static void vga_set_480_scanlines(int end)
++{
++      u16 crtc;
++      u8  csel;
++
++      crtc = vga_crtc();
++
++      out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
++      out_idx(0x0b, crtc, 0x06); /* Vertical total */
++      out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
++      out_idx(0xea, crtc, 0x10); /* Vertical sync start */
++      out_idx(end, crtc, 0x12); /* Vertical display end */
++      out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
++      out_idx(0x04, crtc, 0x16); /* Vertical blank end */
++      csel = inb(0x3cc);
++      csel &= 0x0d;
++      csel |= 0xe2;
++      outb(csel, 0x3cc);
++}
++
++static void vga_set_80x30(void)
++{
++      vga_set_480_scanlines(0xdf);
++}
++
++static void vga_set_80x34(void)
++{
++      vga_set_14font();
++      vga_set_480_scanlines(0xdb);
++}
++
++static void vga_set_80x60(void)
++{
++      vga_set_8font();
++      vga_set_480_scanlines(0xdf);
++}
++
++static int vga_set_mode(struct mode_info *mode)
++{
++      /* Set the basic mode */
++      vga_set_basic_mode();
++
++      /* Override a possibly broken BIOS */
++      force_x = mode->x;
++      force_y = mode->y;
++
++      switch (mode->mode) {
++      case VIDEO_80x25:
++              break;
++      case VIDEO_8POINT:
++              vga_set_8font();
++              break;
++      case VIDEO_80x43:
++              vga_set_80x43();
++              break;
++      case VIDEO_80x28:
++              vga_set_14font();
++              break;
++      case VIDEO_80x30:
++              vga_set_80x30();
++              break;
++      case VIDEO_80x34:
++              vga_set_80x34();
++              break;
++      case VIDEO_80x60:
++              vga_set_80x60();
++              break;
++      }
++
++      return 0;
++}
++
++/*
++ * Note: this probe includes basic information required by all
++ * systems.  It should be executed first, by making sure
++ * video-vga.c is listed first in the Makefile.
++ */
++static int vga_probe(void)
++{
++      static const char *card_name[] = {
++              "CGA/MDA/HGC", "EGA", "VGA"
++      };
++      static struct mode_info *mode_lists[] = {
++              cga_modes,
++              ega_modes,
++              vga_modes,
++      };
++      static int mode_count[] = {
++              sizeof(cga_modes)/sizeof(struct mode_info),
++              sizeof(ega_modes)/sizeof(struct mode_info),
++              sizeof(vga_modes)/sizeof(struct mode_info),
++      };
++      u8 vga_flag;
++
++      asm(INT10
++          : "=b" (boot_params.screen_info.orig_video_ega_bx)
++          : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
++          : "ecx", "edx", "esi", "edi");
++
++      /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
++      if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
++              /* EGA/VGA */
++              asm(INT10
++                  : "=a" (vga_flag)
++                  : "a" (0x1a00)
++                  : "ebx", "ecx", "edx", "esi", "edi");
++
++              if (vga_flag == 0x1a) {
++                      adapter = ADAPTER_VGA;
++                      boot_params.screen_info.orig_video_isVGA = 1;
++              } else {
++                      adapter = ADAPTER_EGA;
++              }
++      } else {
++              adapter = ADAPTER_CGA;
++      }
++
++      video_vga.modes = mode_lists[adapter];
++      video_vga.card_name = card_name[adapter];
++      return mode_count[adapter];
++}
++
++__videocard video_vga =
++{
++      .card_name      = "VGA",
++      .probe          = vga_probe,
++      .set_mode       = vga_set_mode,
++};
+diff -puN arch/i386/boot/video.S~git-newsetup /dev/null
+--- a/arch/i386/boot/video.S
++++ /dev/null
+@@ -1,2043 +0,0 @@
+-/*    video.S
+- *
+- *    Display adapter & video mode setup, version 2.13 (14-May-99)
+- *
+- *    Copyright (C) 1995 -- 1998 Martin Mares <mj@ucw.cz>
+- *    Based on the original setup.S code (C) Linus Torvalds and Mats Anderson
+- *
+- *    Rewritten to use GNU 'as' by Chris Noe <stiker@northlink.com> May 1999
+- *
+- *    For further information, look at Documentation/svga.txt.
+- *
+- */
+-
+-/* Enable autodetection of SVGA adapters and modes. */
+-#undef CONFIG_VIDEO_SVGA
+-
+-/* Enable autodetection of VESA modes */
+-#define CONFIG_VIDEO_VESA
+-
+-/* Enable compacting of mode table */
+-#define CONFIG_VIDEO_COMPACT
+-
+-/* Retain screen contents when switching modes */
+-#define CONFIG_VIDEO_RETAIN
+-
+-/* Enable local mode list */
+-#undef CONFIG_VIDEO_LOCAL
+-
+-/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
+-#undef CONFIG_VIDEO_400_HACK
+-
+-/* Hack that lets you force specific BIOS mode ID and specific dimensions */
+-#undef CONFIG_VIDEO_GFX_HACK
+-#define VIDEO_GFX_BIOS_AX 0x4f02      /* 800x600 on ThinkPad */
+-#define VIDEO_GFX_BIOS_BX 0x0102
+-#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425     /* 100x37 */
+-
+-/* This code uses an extended set of video mode numbers. These include:
+- * Aliases for standard modes
+- *    NORMAL_VGA (-1)
+- *    EXTENDED_VGA (-2)
+- *    ASK_VGA (-3)
+- * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
+- * of compatibility when extending the table. These are between 0x00 and 0xff.
+- */
+-#define VIDEO_FIRST_MENU 0x0000
+-
+-/* Standard BIOS video modes (BIOS number + 0x0100) */
+-#define VIDEO_FIRST_BIOS 0x0100
+-
+-/* VESA BIOS video modes (VESA number + 0x0200) */
+-#define VIDEO_FIRST_VESA 0x0200
+-
+-/* Video7 special modes (BIOS number + 0x0900) */
+-#define VIDEO_FIRST_V7 0x0900
+-
+-/* Special video modes */
+-#define VIDEO_FIRST_SPECIAL 0x0f00
+-#define VIDEO_80x25 0x0f00
+-#define VIDEO_8POINT 0x0f01
+-#define VIDEO_80x43 0x0f02
+-#define VIDEO_80x28 0x0f03
+-#define VIDEO_CURRENT_MODE 0x0f04
+-#define VIDEO_80x30 0x0f05
+-#define VIDEO_80x34 0x0f06
+-#define VIDEO_80x60 0x0f07
+-#define VIDEO_GFX_HACK 0x0f08
+-#define VIDEO_LAST_SPECIAL 0x0f09
+-
+-/* Video modes given by resolution */
+-#define VIDEO_FIRST_RESOLUTION 0x1000
+-
+-/* The "recalculate timings" flag */
+-#define VIDEO_RECALC 0x8000
+-
+-/* Positions of various video parameters passed to the kernel */
+-/* (see also include/linux/tty.h) */
+-#define PARAM_CURSOR_POS      0x00
+-#define PARAM_VIDEO_PAGE      0x04
+-#define PARAM_VIDEO_MODE      0x06
+-#define PARAM_VIDEO_COLS      0x07
+-#define PARAM_VIDEO_EGA_BX    0x0a
+-#define PARAM_VIDEO_LINES     0x0e
+-#define PARAM_HAVE_VGA                0x0f
+-#define PARAM_FONT_POINTS     0x10
+-
+-#define PARAM_LFB_WIDTH               0x12
+-#define PARAM_LFB_HEIGHT      0x14
+-#define PARAM_LFB_DEPTH               0x16
+-#define PARAM_LFB_BASE                0x18
+-#define PARAM_LFB_SIZE                0x1c
+-#define PARAM_LFB_LINELENGTH  0x24
+-#define PARAM_LFB_COLORS      0x26
+-#define PARAM_VESAPM_SEG      0x2e
+-#define PARAM_VESAPM_OFF      0x30
+-#define PARAM_LFB_PAGES               0x32
+-#define PARAM_VESA_ATTRIB     0x34
+-#define PARAM_CAPABILITIES    0x36
+-
+-/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
+-#ifdef CONFIG_VIDEO_RETAIN
+-#define DO_STORE call store_screen
+-#else
+-#define DO_STORE
+-#endif /* CONFIG_VIDEO_RETAIN */
+-
+-# This is the main entry point called by setup.S
+-# %ds *must* be pointing to the bootsector
+-video:        pushw   %ds             # We use different segments
+-      pushw   %ds             # FS contains original DS
+-      popw    %fs
+-      pushw   %cs             # DS is equal to CS
+-      popw    %ds
+-      pushw   %cs             # ES is equal to CS
+-      popw    %es
+-      xorw    %ax, %ax
+-      movw    %ax, %gs        # GS is zero
+-      cld
+-      call    basic_detect    # Basic adapter type testing (EGA/VGA/MDA/CGA)
+-#ifdef CONFIG_VIDEO_SELECT
+-      movw    %fs:(0x01fa), %ax               # User selected video mode
+-      cmpw    $ASK_VGA, %ax                   # Bring up the menu
+-      jz      vid2
+-
+-      call    mode_set                        # Set the mode
+-      jc      vid1
+-
+-      leaw    badmdt, %si                     # Invalid mode ID
+-      call    prtstr
+-vid2: call    mode_menu
+-vid1:
+-#ifdef CONFIG_VIDEO_RETAIN
+-      call    restore_screen                  # Restore screen contents
+-#endif /* CONFIG_VIDEO_RETAIN */
+-      call    store_edid
+-#endif /* CONFIG_VIDEO_SELECT */
+-      call    mode_params                     # Store mode parameters
+-      popw    %ds                             # Restore original DS
+-      ret
+-
+-# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel.
+-basic_detect:
+-      movb    $0, %fs:(PARAM_HAVE_VGA)
+-      movb    $0x12, %ah      # Check EGA/VGA
+-      movb    $0x10, %bl
+-      int     $0x10
+-      movw    %bx, %fs:(PARAM_VIDEO_EGA_BX)   # Identifies EGA to the kernel
+-      cmpb    $0x10, %bl                      # No, it's a CGA/MDA/HGA card.
+-      je      basret
+-
+-      incb    adapter
+-      movw    $0x1a00, %ax                    # Check EGA or VGA?
+-      int     $0x10
+-      cmpb    $0x1a, %al                      # 1a means VGA...
+-      jne     basret                          # anything else is EGA.
+-      
+-      incb    %fs:(PARAM_HAVE_VGA)            # We've detected a VGA
+-      incb    adapter
+-basret:       ret
+-
+-# Store the video mode parameters for later usage by the kernel.
+-# This is done by asking the BIOS except for the rows/columns
+-# parameters in the default 80x25 mode -- these are set directly,
+-# because some very obscure BIOSes supply insane values.
+-mode_params:
+-#ifdef CONFIG_VIDEO_SELECT
+-      cmpb    $0, graphic_mode
+-      jnz     mopar_gr
+-#endif
+-      movb    $0x03, %ah                      # Read cursor position
+-      xorb    %bh, %bh
+-      int     $0x10
+-      movw    %dx, %fs:(PARAM_CURSOR_POS)
+-      movb    $0x0f, %ah                      # Read page/mode/width
+-      int     $0x10
+-      movw    %bx, %fs:(PARAM_VIDEO_PAGE)
+-      movw    %ax, %fs:(PARAM_VIDEO_MODE)     # Video mode and screen width
+-      cmpb    $0x7, %al                       # MDA/HGA => segment differs
+-      jnz     mopar0
+-
+-      movw    $0xb000, video_segment
+-mopar0: movw  %gs:(0x485), %ax                # Font size
+-      movw    %ax, %fs:(PARAM_FONT_POINTS)    # (valid only on EGA/VGA)
+-      movw    force_size, %ax                 # Forced size?
+-      orw     %ax, %ax
+-      jz      mopar1
+-
+-      movb    %ah, %fs:(PARAM_VIDEO_COLS)
+-      movb    %al, %fs:(PARAM_VIDEO_LINES)
+-      ret
+-
+-mopar1:       movb    $25, %al
+-      cmpb    $0, adapter                     # If we are on CGA/MDA/HGA, the
+-      jz      mopar2                          # screen must have 25 lines.
+-
+-      movb    %gs:(0x484), %al                # On EGA/VGA, use the EGA+ BIOS
+-      incb    %al                             # location of max lines.
+-mopar2: movb  %al, %fs:(PARAM_VIDEO_LINES)
+-      ret
+-
+-#ifdef CONFIG_VIDEO_SELECT
+-# Fetching of VESA frame buffer parameters
+-mopar_gr:
+-      leaw    modelist+1024, %di
+-      movb    $0x23, %fs:(PARAM_HAVE_VGA)
+-      movw    16(%di), %ax
+-      movw    %ax, %fs:(PARAM_LFB_LINELENGTH)
+-      movw    18(%di), %ax
+-      movw    %ax, %fs:(PARAM_LFB_WIDTH)
+-      movw    20(%di), %ax
+-      movw    %ax, %fs:(PARAM_LFB_HEIGHT)
+-      movb    25(%di), %al
+-      movb    $0, %ah
+-      movw    %ax, %fs:(PARAM_LFB_DEPTH)
+-      movb    29(%di), %al    
+-      movb    $0, %ah
+-      movw    %ax, %fs:(PARAM_LFB_PAGES)
+-      movl    40(%di), %eax
+-      movl    %eax, %fs:(PARAM_LFB_BASE)
+-      movl    31(%di), %eax
+-      movl    %eax, %fs:(PARAM_LFB_COLORS)
+-      movl    35(%di), %eax
+-      movl    %eax, %fs:(PARAM_LFB_COLORS+4)
+-      movw    0(%di), %ax
+-      movw    %ax, %fs:(PARAM_VESA_ATTRIB)
+-
+-# get video mem size
+-      leaw    modelist+1024, %di
+-      movw    $0x4f00, %ax
+-      int     $0x10
+-      xorl    %eax, %eax
+-      movw    18(%di), %ax
+-      movl    %eax, %fs:(PARAM_LFB_SIZE)
+-
+-# store mode capabilities
+-      movl 10(%di), %eax
+-      movl %eax, %fs:(PARAM_CAPABILITIES)
+-
+-# switching the DAC to 8-bit is for <= 8 bpp only
+-      movw    %fs:(PARAM_LFB_DEPTH), %ax
+-      cmpw    $8, %ax
+-      jg      dac_done
+-
+-# get DAC switching capability
+-      xorl    %eax, %eax
+-      movb    10(%di), %al
+-      testb   $1, %al
+-      jz      dac_set
+-
+-# attempt to switch DAC to 8-bit
+-      movw    $0x4f08, %ax
+-      movw    $0x0800, %bx
+-      int     $0x10
+-      cmpw    $0x004f, %ax
+-      jne     dac_set
+-      movb    %bh, dac_size           # store actual DAC size
+-
+-dac_set:
+-# set color size to DAC size
+-      movb    dac_size, %al
+-      movb    %al, %fs:(PARAM_LFB_COLORS+0)
+-      movb    %al, %fs:(PARAM_LFB_COLORS+2)
+-      movb    %al, %fs:(PARAM_LFB_COLORS+4)
+-      movb    %al, %fs:(PARAM_LFB_COLORS+6)
+-
+-# set color offsets to 0
+-      movb    $0, %fs:(PARAM_LFB_COLORS+1)
+-      movb    $0, %fs:(PARAM_LFB_COLORS+3)
+-      movb    $0, %fs:(PARAM_LFB_COLORS+5)
+-      movb    $0, %fs:(PARAM_LFB_COLORS+7)
+-
+-dac_done:
+-# get protected mode interface informations
+-      movw    $0x4f0a, %ax
+-      xorw    %bx, %bx
+-      xorw    %di, %di
+-      int     $0x10
+-      cmp     $0x004f, %ax
+-      jnz     no_pm
+-
+-      movw    %es, %fs:(PARAM_VESAPM_SEG)
+-      movw    %di, %fs:(PARAM_VESAPM_OFF)
+-no_pm:        ret
+-
+-# The video mode menu
+-mode_menu:
+-      leaw    keymsg, %si                     # "Return/Space/Timeout" message
+-      call    prtstr
+-      call    flush
+-nokey:        call    getkt
+-
+-      cmpb    $0x0d, %al                      # ENTER ?
+-      je      listm                           # yes - manual mode selection
+-
+-      cmpb    $0x20, %al                      # SPACE ?
+-      je      defmd1                          # no - repeat
+-
+-      call    beep
+-      jmp     nokey
+-
+-defmd1:       ret                                     # No mode chosen? Default 80x25
+-
+-listm:        call    mode_table                      # List mode table
+-listm0:       leaw    name_bann, %si                  # Print adapter name
+-      call    prtstr
+-      movw    card_name, %si
+-      orw     %si, %si
+-      jnz     an2
+-
+-      movb    adapter, %al
+-      leaw    old_name, %si
+-      orb     %al, %al
+-      jz      an1
+-
+-      leaw    ega_name, %si
+-      decb    %al
+-      jz      an1
+-
+-      leaw    vga_name, %si
+-      jmp     an1
+-
+-an2:  call    prtstr
+-      leaw    svga_name, %si
+-an1:  call    prtstr
+-      leaw    listhdr, %si                    # Table header
+-      call    prtstr
+-      movb    $0x30, %dl                      # DL holds mode number
+-      leaw    modelist, %si
+-lm1:  cmpw    $ASK_VGA, (%si)                 # End?
+-      jz      lm2
+-
+-      movb    %dl, %al                        # Menu selection number
+-      call    prtchr
+-      call    prtsp2
+-      lodsw
+-      call    prthw                           # Mode ID
+-      call    prtsp2
+-      movb    0x1(%si), %al
+-      call    prtdec                          # Rows
+-      movb    $0x78, %al                      # the letter 'x'
+-      call    prtchr
+-      lodsw
+-      call    prtdec                          # Columns
+-      movb    $0x0d, %al                      # New line
+-      call    prtchr
+-      movb    $0x0a, %al
+-      call    prtchr
+-      incb    %dl                             # Next character
+-      cmpb    $0x3a, %dl
+-      jnz     lm1
+-
+-      movb    $0x61, %dl
+-      jmp     lm1
+-
+-lm2:  leaw    prompt, %si                     # Mode prompt
+-      call    prtstr
+-      leaw    edit_buf, %di                   # Editor buffer
+-lm3:  call    getkey
+-      cmpb    $0x0d, %al                      # Enter?
+-      jz      lment
+-
+-      cmpb    $0x08, %al                      # Backspace?
+-      jz      lmbs
+-
+-      cmpb    $0x20, %al                      # Printable?
+-      jc      lm3
+-
+-      cmpw    $edit_buf+4, %di                # Enough space?
+-      jz      lm3
+-
+-      stosb
+-      call    prtchr
+-      jmp     lm3
+-
+-lmbs: cmpw    $edit_buf, %di                  # Backspace
+-      jz      lm3
+-
+-      decw    %di
+-      movb    $0x08, %al
+-      call    prtchr
+-      call    prtspc
+-      movb    $0x08, %al
+-      call    prtchr
+-      jmp     lm3
+-      
+-lment:        movb    $0, (%di)
+-      leaw    crlft, %si
+-      call    prtstr
+-      leaw    edit_buf, %si
+-      cmpb    $0, (%si)                       # Empty string = default mode
+-      jz      lmdef
+-
+-      cmpb    $0, 1(%si)                      # One character = menu selection
+-      jz      mnusel
+-
+-      cmpw    $0x6373, (%si)                  # "scan" => mode scanning
+-      jnz     lmhx
+-
+-      cmpw    $0x6e61, 2(%si)
+-      jz      lmscan
+-
+-lmhx: xorw    %bx, %bx                        # Else => mode ID in hex
+-lmhex:        lodsb
+-      orb     %al, %al
+-      jz      lmuse1
+-
+-      subb    $0x30, %al
+-      jc      lmbad
+-
+-      cmpb    $10, %al
+-      jc      lmhx1
+-
+-      subb    $7, %al
+-      andb    $0xdf, %al
+-      cmpb    $10, %al
+-      jc      lmbad
+-
+-      cmpb    $16, %al
+-      jnc     lmbad
+-
+-lmhx1:        shlw    $4, %bx
+-      orb     %al, %bl
+-      jmp     lmhex
+-
+-lmuse1:       movw    %bx, %ax
+-      jmp     lmuse
+-
+-mnusel:       lodsb                                   # Menu selection
+-      xorb    %ah, %ah
+-      subb    $0x30, %al
+-      jc      lmbad
+-
+-      cmpb    $10, %al
+-      jc      lmuse
+-      
+-      cmpb    $0x61-0x30, %al
+-      jc      lmbad
+-      
+-      subb    $0x61-0x30-10, %al
+-      cmpb    $36, %al
+-      jnc     lmbad
+-
+-lmuse:        call    mode_set
+-      jc      lmdef
+-
+-lmbad:        leaw    unknt, %si
+-      call    prtstr
+-      jmp     lm2
+-lmscan:       cmpb    $0, adapter                     # Scanning only on EGA/VGA
+-      jz      lmbad
+-
+-      movw    $0, mt_end                      # Scanning of modes is
+-      movb    $1, scanning                    # done as new autodetection.
+-      call    mode_table
+-      jmp     listm0
+-lmdef:        ret
+-
+-# Additional parts of mode_set... (relative jumps, you know)
+-setv7:                                                # Video7 extended modes
+-      DO_STORE
+-      subb    $VIDEO_FIRST_V7>>8, %bh
+-      movw    $0x6f05, %ax
+-      int     $0x10
+-      stc
+-      ret
+-
+-_setrec:      jmp     setrec                  # Ugly...
+-_set_80x25:   jmp     set_80x25
+-
+-# Aliases for backward compatibility.
+-setalias:
+-      movw    $VIDEO_80x25, %ax
+-      incw    %bx
+-      jz      mode_set
+-
+-      movb    $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al
+-      incw    %bx
+-      jnz     setbad                          # Fall-through!
+-
+-# Setting of user mode (AX=mode ID) => CF=success
+-mode_set:
+-      movw    %ax, %fs:(0x01fa)               # Store mode for use in acpi_wakeup.S
+-      movw    %ax, %bx
+-      cmpb    $0xff, %ah
+-      jz      setalias
+-
+-      testb   $VIDEO_RECALC>>8, %ah
+-      jnz     _setrec
+-
+-      cmpb    $VIDEO_FIRST_RESOLUTION>>8, %ah
+-      jnc     setres
+-      
+-      cmpb    $VIDEO_FIRST_SPECIAL>>8, %ah
+-      jz      setspc
+-      
+-      cmpb    $VIDEO_FIRST_V7>>8, %ah
+-      jz      setv7
+-      
+-      cmpb    $VIDEO_FIRST_VESA>>8, %ah
+-      jnc     check_vesa
+-      
+-      orb     %ah, %ah
+-      jz      setmenu
+-      
+-      decb    %ah
+-      jz      setbios
+-
+-setbad:       clc
+-      movb    $0, do_restore                  # The screen needn't be restored
+-      ret
+-
+-setvesa:
+-      DO_STORE
+-      subb    $VIDEO_FIRST_VESA>>8, %bh
+-      movw    $0x4f02, %ax                    # VESA BIOS mode set call
+-      int     $0x10
+-      cmpw    $0x004f, %ax                    # AL=4f if implemented
+-      jnz     setbad                          # AH=0 if OK
+-
+-      stc
+-      ret
+-
+-setbios:
+-      DO_STORE
+-      int     $0x10                           # Standard BIOS mode set call
+-      pushw   %bx
+-      movb    $0x0f, %ah                      # Check if really set
+-      int     $0x10
+-      popw    %bx
+-      cmpb    %bl, %al
+-      jnz     setbad
+-      
+-      stc
+-      ret
+-
+-setspc:       xorb    %bh, %bh                        # Set special mode
+-      cmpb    $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl
+-      jnc     setbad
+-      
+-      addw    %bx, %bx
+-      jmp     *spec_inits(%bx)
+-
+-setmenu:
+-      orb     %al, %al                        # 80x25 is an exception
+-      jz      _set_80x25
+-      
+-      pushw   %bx                             # Set mode chosen from menu
+-      call    mode_table                      # Build the mode table
+-      popw    %ax
+-      shlw    $2, %ax
+-      addw    %ax, %si
+-      cmpw    %di, %si
+-      jnc     setbad
+-      
+-      movw    (%si), %ax                      # Fetch mode ID
+-_m_s: jmp     mode_set
+-
+-setres:       pushw   %bx                             # Set mode chosen by resolution
+-      call    mode_table
+-      popw    %bx
+-      xchgb   %bl, %bh
+-setr1:        lodsw
+-      cmpw    $ASK_VGA, %ax                   # End of the list?
+-      jz      setbad
+-      
+-      lodsw
+-      cmpw    %bx, %ax
+-      jnz     setr1
+-      
+-      movw    -4(%si), %ax                    # Fetch mode ID
+-      jmp     _m_s
+-
+-check_vesa:
+-#ifdef CONFIG_FIRMWARE_EDID
+-      leaw    modelist+1024, %di
+-      movw    $0x4f00, %ax
+-      int     $0x10
+-      cmpw    $0x004f, %ax
+-      jnz     setbad
+-
+-      movw    4(%di), %ax
+-      movw    %ax, vbe_version
+-#endif
+-      leaw    modelist+1024, %di
+-      subb    $VIDEO_FIRST_VESA>>8, %bh
+-      movw    %bx, %cx                        # Get mode information structure
+-      movw    $0x4f01, %ax
+-      int     $0x10
+-      addb    $VIDEO_FIRST_VESA>>8, %bh
+-      cmpw    $0x004f, %ax
+-      jnz     setbad
+-
+-      movb    (%di), %al                      # Check capabilities.
+-      andb    $0x19, %al
+-      cmpb    $0x09, %al
+-      jz      setvesa                         # This is a text mode
+-
+-      movb    (%di), %al                      # Check capabilities.
+-      andb    $0x99, %al
+-      cmpb    $0x99, %al
+-      jnz     _setbad                         # Doh! No linear frame buffer.
+-
+-      subb    $VIDEO_FIRST_VESA>>8, %bh
+-      orw     $0x4000, %bx                    # Use linear frame buffer
+-      movw    $0x4f02, %ax                    # VESA BIOS mode set call
+-      int     $0x10
+-      cmpw    $0x004f, %ax                    # AL=4f if implemented
+-      jnz     _setbad                         # AH=0 if OK
+-
+-      movb    $1, graphic_mode                # flag graphic mode
+-      movb    $0, do_restore                  # no screen restore
+-      stc
+-      ret
+-
+-_setbad:      jmp     setbad                  # Ugly...
+-
+-# Recalculate vertical display end registers -- this fixes various
+-# inconsistencies of extended modes on many adapters. Called when
+-# the VIDEO_RECALC flag is set in the mode ID.
+-
+-setrec:       subb    $VIDEO_RECALC>>8, %ah           # Set the base mode
+-      call    mode_set
+-      jnc     rct3
+-
+-      movw    %gs:(0x485), %ax                # Font size in pixels
+-      movb    %gs:(0x484), %bl                # Number of rows
+-      incb    %bl
+-      mulb    %bl                             # Number of visible
+-      decw    %ax                             # scan lines - 1
+-      movw    $0x3d4, %dx
+-      movw    %ax, %bx
+-      movb    $0x12, %al                      # Lower 8 bits
+-      movb    %bl, %ah
+-      outw    %ax, %dx
+-      movb    $0x07, %al              # Bits 8 and 9 in the overflow register
+-      call    inidx
+-      xchgb   %al, %ah
+-      andb    $0xbd, %ah
+-      shrb    %bh
+-      jnc     rct1
+-      orb     $0x02, %ah
+-rct1: shrb    %bh
+-      jnc     rct2
+-      orb     $0x40, %ah
+-rct2: movb    $0x07, %al
+-      outw    %ax, %dx
+-      stc
+-rct3: ret
+-
+-# Table of routines for setting of the special modes.
+-spec_inits:
+-      .word   set_80x25
+-      .word   set_8pixel
+-      .word   set_80x43
+-      .word   set_80x28
+-      .word   set_current
+-      .word   set_80x30
+-      .word   set_80x34
+-      .word   set_80x60
+-      .word   set_gfx
+-
+-# Set the 80x25 mode. If already set, do nothing.
+-set_80x25:
+-      movw    $0x5019, force_size             # Override possibly broken BIOS
+-use_80x25:
+-#ifdef CONFIG_VIDEO_400_HACK
+-      movw    $0x1202, %ax                    # Force 400 scan lines
+-      movb    $0x30, %bl
+-      int     $0x10
+-#else
+-      movb    $0x0f, %ah                      # Get current mode ID
+-      int     $0x10
+-      cmpw    $0x5007, %ax    # Mode 7 (80x25 mono) is the only one available
+-      jz      st80            # on CGA/MDA/HGA and is also available on EGAM
+-
+-      cmpw    $0x5003, %ax    # Unknown mode, force 80x25 color
+-      jnz     force3
+-
+-st80: cmpb    $0, adapter     # CGA/MDA/HGA => mode 3/7 is always 80x25
+-      jz      set80
+-
+-      movb    %gs:(0x0484), %al       # This is EGA+ -- beware of 80x50 etc.
+-      orb     %al, %al                # Some buggy BIOS'es set 0 rows
+-      jz      set80
+-      
+-      cmpb    $24, %al                # It's hopefully correct
+-      jz      set80
+-#endif /* CONFIG_VIDEO_400_HACK */
+-force3:       DO_STORE
+-      movw    $0x0003, %ax                    # Forced set
+-      int     $0x10
+-set80:        stc
+-      ret
+-
+-# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls.
+-set_8pixel:
+-      DO_STORE
+-      call    use_80x25                       # The base is 80x25
+-set_8pt:
+-      movw    $0x1112, %ax                    # Use 8x8 font
+-      xorb    %bl, %bl
+-      int     $0x10
+-      movw    $0x1200, %ax                    # Use alternate print screen
+-      movb    $0x20, %bl
+-      int     $0x10
+-      movw    $0x1201, %ax                    # Turn off cursor emulation
+-      movb    $0x34, %bl
+-      int     $0x10
+-      movb    $0x01, %ah                      # Define cursor scan lines 6-7
+-      movw    $0x0607, %cx
+-      int     $0x10
+-set_current:
+-      stc
+-      ret
+-
+-# Set the 80x28 mode. This mode works on all VGA's, because it's a standard
+-# 80x25 mode with 14-point fonts instead of 16-point.
+-set_80x28:
+-      DO_STORE
+-      call    use_80x25                       # The base is 80x25
+-set14:        movw    $0x1111, %ax                    # Use 9x14 font
+-      xorb    %bl, %bl
+-      int     $0x10
+-      movb    $0x01, %ah                      # Define cursor scan lines 11-12
+-      movw    $0x0b0c, %cx
+-      int     $0x10
+-      stc
+-      ret
+-
+-# Set the 80x43 mode. This mode is works on all VGA's.
+-# It's a 350-scanline mode with 8-pixel font.
+-set_80x43:
+-      DO_STORE
+-      movw    $0x1201, %ax                    # Set 350 scans
+-      movb    $0x30, %bl
+-      int     $0x10
+-      movw    $0x0003, %ax                    # Reset video mode
+-      int     $0x10
+-      jmp     set_8pt                         # Use 8-pixel font
+-
+-# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font.
+-set_80x30:
+-      call    use_80x25                       # Start with real 80x25
+-      DO_STORE
+-      movw    $0x3cc, %dx                     # Get CRTC port
+-      inb     %dx, %al
+-      movb    $0xd4, %dl
+-      rorb    %al                             # Mono or color?
+-      jc      set48a
+-
+-      movb    $0xb4, %dl
+-set48a:       movw    $0x0c11, %ax            # Vertical sync end (also unlocks CR0-7)
+-      call    outidx
+-      movw    $0x0b06, %ax                    # Vertical total
+-      call    outidx
+-      movw    $0x3e07, %ax                    # (Vertical) overflow
+-      call    outidx
+-      movw    $0xea10, %ax                    # Vertical sync start
+-      call    outidx
+-      movw    $0xdf12, %ax                    # Vertical display end
+-      call    outidx
+-      movw    $0xe715, %ax                    # Vertical blank start
+-      call    outidx
+-      movw    $0x0416, %ax                    # Vertical blank end
+-      call    outidx
+-      pushw   %dx
+-      movb    $0xcc, %dl                      # Misc output register (read)
+-      inb     %dx, %al
+-      movb    $0xc2, %dl                      # (write)
+-      andb    $0x0d, %al      # Preserve clock select bits and color bit
+-      orb     $0xe2, %al                      # Set correct sync polarity
+-      outb    %al, %dx
+-      popw    %dx
+-      movw    $0x501e, force_size
+-      stc                                     # That's all.
+-      ret
+-
+-# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font.
+-set_80x34:
+-      call    set_80x30                       # Set 480 scans
+-      call    set14                           # And 14-pt font
+-      movw    $0xdb12, %ax                    # VGA vertical display end
+-      movw    $0x5022, force_size
+-setvde:       call    outidx
+-      stc
+-      ret
+-
+-# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font.
+-set_80x60:
+-      call    set_80x30                       # Set 480 scans
+-      call    set_8pt                         # And 8-pt font
+-      movw    $0xdf12, %ax                    # VGA vertical display end
+-      movw    $0x503c, force_size
+-      jmp     setvde
+-
+-# Special hack for ThinkPad graphics
+-set_gfx:
+-#ifdef CONFIG_VIDEO_GFX_HACK
+-      movw    $VIDEO_GFX_BIOS_AX, %ax
+-      movw    $VIDEO_GFX_BIOS_BX, %bx
+-      int     $0x10
+-      movw    $VIDEO_GFX_DUMMY_RESOLUTION, force_size
+-      stc
+-#endif
+-      ret
+-
+-#ifdef CONFIG_VIDEO_RETAIN
+-
+-# Store screen contents to temporary buffer.
+-store_screen:
+-      cmpb    $0, do_restore                  # Already stored?
+-      jnz     stsr
+-
+-      testb   $CAN_USE_HEAP, loadflags        # Have we space for storing?
+-      jz      stsr
+-      
+-      pushw   %ax
+-      pushw   %bx
+-      pushw   force_size                      # Don't force specific size
+-      movw    $0, force_size
+-      call    mode_params                     # Obtain params of current mode
+-      popw    force_size
+-      movb    %fs:(PARAM_VIDEO_LINES), %ah
+-      movb    %fs:(PARAM_VIDEO_COLS), %al
+-      movw    %ax, %bx                        # BX=dimensions
+-      mulb    %ah
+-      movw    %ax, %cx                        # CX=number of characters
+-      addw    %ax, %ax                        # Calculate image size
+-      addw    $modelist+1024+4, %ax
+-      cmpw    heap_end_ptr, %ax
+-      jnc     sts1                            # Unfortunately, out of memory
+-
+-      movw    %fs:(PARAM_CURSOR_POS), %ax     # Store mode params
+-      leaw    modelist+1024, %di
+-      stosw
+-      movw    %bx, %ax
+-      stosw
+-      pushw   %ds                             # Store the screen
+-      movw    video_segment, %ds
+-      xorw    %si, %si
+-      rep
+-      movsw
+-      popw    %ds
+-      incb    do_restore                      # Screen will be restored later
+-sts1: popw    %bx
+-      popw    %ax
+-stsr: ret
+-
+-# Restore screen contents from temporary buffer.
+-restore_screen:
+-      cmpb    $0, do_restore                  # Has the screen been stored?
+-      jz      res1
+-
+-      call    mode_params                     # Get parameters of current mode
+-      movb    %fs:(PARAM_VIDEO_LINES), %cl
+-      movb    %fs:(PARAM_VIDEO_COLS), %ch
+-      leaw    modelist+1024, %si              # Screen buffer
+-      lodsw                                   # Set cursor position
+-      movw    %ax, %dx
+-      cmpb    %cl, %dh
+-      jc      res2
+-      
+-      movb    %cl, %dh
+-      decb    %dh
+-res2: cmpb    %ch, %dl
+-      jc      res3
+-      
+-      movb    %ch, %dl
+-      decb    %dl
+-res3: movb    $0x02, %ah
+-      movb    $0x00, %bh
+-      int     $0x10
+-      lodsw                                   # Display size
+-      movb    %ah, %dl                        # DL=number of lines
+-      movb    $0, %ah                         # BX=phys. length of orig. line
+-      movw    %ax, %bx
+-      cmpb    %cl, %dl                        # Too many?
+-      jc      res4
+-
+-      pushw   %ax
+-      movb    %dl, %al
+-      subb    %cl, %al
+-      mulb    %bl
+-      addw    %ax, %si
+-      addw    %ax, %si
+-      popw    %ax
+-      movb    %cl, %dl
+-res4: cmpb    %ch, %al                        # Too wide?
+-      jc      res5
+-      
+-      movb    %ch, %al                        # AX=width of src. line
+-res5: movb    $0, %cl
+-      xchgb   %ch, %cl
+-      movw    %cx, %bp                        # BP=width of dest. line
+-      pushw   %es
+-      movw    video_segment, %es
+-      xorw    %di, %di                        # Move the data
+-      addw    %bx, %bx                        # Convert BX and BP to _bytes_
+-      addw    %bp, %bp
+-res6: pushw   %si
+-      pushw   %di
+-      movw    %ax, %cx
+-      rep
+-      movsw
+-      popw    %di
+-      popw    %si
+-      addw    %bp, %di
+-      addw    %bx, %si
+-      decb    %dl
+-      jnz     res6
+-      
+-      popw    %es                             # Done
+-res1: ret
+-#endif /* CONFIG_VIDEO_RETAIN */
+-
+-# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port)
+-outidx:       outb    %al, %dx
+-      pushw   %ax
+-      movb    %ah, %al
+-      incw    %dx
+-      outb    %al, %dx
+-      decw    %dx
+-      popw    %ax
+-      ret
+-
+-# Build the table of video modes (stored after the setup.S code at the
+-# `modelist' label. Each video mode record looks like:
+-#     .word   MODE-ID         (our special mode ID (see above))
+-#     .byte   rows            (number of rows)
+-#     .byte   columns         (number of columns)
+-# Returns address of the end of the table in DI, the end is marked
+-# with a ASK_VGA ID.
+-mode_table:
+-      movw    mt_end, %di                     # Already filled?
+-      orw     %di, %di
+-      jnz     mtab1x
+-      
+-      leaw    modelist, %di                   # Store standard modes:
+-      movl    $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL)
+-      stosl
+-      movb    adapter, %al                    # CGA/MDA/HGA -- no more modes
+-      orb     %al, %al
+-      jz      mtabe
+-      
+-      decb    %al
+-      jnz     mtabv
+-      
+-      movl    $VIDEO_8POINT + 0x502b0000, %eax        # The 80x43 EGA mode
+-      stosl
+-      jmp     mtabe
+-
+-mtab1x:       jmp     mtab1
+-
+-mtabv:        leaw    vga_modes, %si                  # All modes for std VGA
+-      movw    $vga_modes_end-vga_modes, %cx
+-      rep     # I'm unable to use movsw as I don't know how to store a half
+-      movsb   # of the expression above to cx without using explicit shr.
+-
+-      cmpb    $0, scanning                    # Mode scan requested?
+-      jz      mscan1
+-      
+-      call    mode_scan
+-mscan1:
+-
+-#ifdef CONFIG_VIDEO_LOCAL
+-      call    local_modes
+-#endif /* CONFIG_VIDEO_LOCAL */
+-
+-#ifdef CONFIG_VIDEO_VESA
+-      call    vesa_modes                      # Detect VESA VGA modes
+-#endif /* CONFIG_VIDEO_VESA */
+-
+-#ifdef CONFIG_VIDEO_SVGA
+-      cmpb    $0, scanning                    # Bypass when scanning
+-      jnz     mscan2
+-      
+-      call    svga_modes                      # Detect SVGA cards & modes
+-mscan2:
+-#endif /* CONFIG_VIDEO_SVGA */
+-
+-mtabe:
+-
+-#ifdef CONFIG_VIDEO_COMPACT
+-      leaw    modelist, %si
+-      movw    %di, %dx
+-      movw    %si, %di
+-cmt1: cmpw    %dx, %si                        # Scan all modes
+-      jz      cmt2
+-
+-      leaw    modelist, %bx                   # Find in previous entries
+-      movw    2(%si), %cx
+-cmt3: cmpw    %bx, %si
+-      jz      cmt4
+-
+-      cmpw    2(%bx), %cx                     # Found => don't copy this entry
+-      jz      cmt5
+-
+-      addw    $4, %bx
+-      jmp     cmt3
+-
+-cmt4: movsl                                   # Copy entry
+-      jmp     cmt1
+-
+-cmt5: addw    $4, %si                         # Skip entry
+-      jmp     cmt1
+-
+-cmt2:
+-#endif        /* CONFIG_VIDEO_COMPACT */
+-
+-      movw    $ASK_VGA, (%di)                 # End marker
+-      movw    %di, mt_end
+-mtab1:        leaw    modelist, %si                   # SI=mode list, DI=list end
+-ret0: ret
+-
+-# Modes usable on all standard VGAs
+-vga_modes:
+-      .word   VIDEO_8POINT
+-      .word   0x5032                          # 80x50
+-      .word   VIDEO_80x43
+-      .word   0x502b                          # 80x43
+-      .word   VIDEO_80x28
+-      .word   0x501c                          # 80x28
+-      .word   VIDEO_80x30
+-      .word   0x501e                          # 80x30
+-      .word   VIDEO_80x34
+-      .word   0x5022                          # 80x34
+-      .word   VIDEO_80x60
+-      .word   0x503c                          # 80x60
+-#ifdef CONFIG_VIDEO_GFX_HACK
+-      .word   VIDEO_GFX_HACK
+-      .word   VIDEO_GFX_DUMMY_RESOLUTION
+-#endif
+-
+-vga_modes_end:
+-# Detect VESA modes.
+-
+-#ifdef CONFIG_VIDEO_VESA
+-vesa_modes:
+-      cmpb    $2, adapter                     # VGA only
+-      jnz     ret0
+-
+-      movw    %di, %bp                        # BP=original mode table end
+-      addw    $0x200, %di                     # Buffer space
+-      movw    $0x4f00, %ax                    # VESA Get card info call
+-      int     $0x10
+-      movw    %bp, %di
+-      cmpw    $0x004f, %ax                    # Successful?
+-      jnz     ret0
+-      
+-      cmpw    $0x4556, 0x200(%di)
+-      jnz     ret0
+-      
+-      cmpw    $0x4153, 0x202(%di)
+-      jnz     ret0
+-      
+-      movw    $vesa_name, card_name           # Set name to "VESA VGA"
+-      pushw   %gs
+-      lgsw    0x20e(%di), %si                 # GS:SI=mode list
+-      movw    $128, %cx                       # Iteration limit
+-vesa1:
+-# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
+-# XXX:        lodsw   %gs:(%si), %ax                  # Get next mode in the list
+-      gs; lodsw
+-      cmpw    $0xffff, %ax                    # End of the table?
+-      jz      vesar
+-      
+-      cmpw    $0x0080, %ax                    # Check validity of mode ID
+-      jc      vesa2
+-      
+-      orb     %ah, %ah                # Valid IDs: 0x0000-0x007f/0x0100-0x07ff
+-      jz      vesan                   # Certain BIOSes report 0x80-0xff!
+-
+-      cmpw    $0x0800, %ax
+-      jnc     vesae
+-
+-vesa2:        pushw   %cx
+-      movw    %ax, %cx                        # Get mode information structure
+-      movw    $0x4f01, %ax
+-      int     $0x10
+-      movw    %cx, %bx                        # BX=mode number
+-      addb    $VIDEO_FIRST_VESA>>8, %bh
+-      popw    %cx
+-      cmpw    $0x004f, %ax
+-      jnz     vesan                   # Don't report errors (buggy BIOSES)
+-
+-      movb    (%di), %al                      # Check capabilities. We require
+-      andb    $0x19, %al                      # a color text mode.
+-      cmpb    $0x09, %al
+-      jnz     vesan
+-      
+-      cmpw    $0xb800, 8(%di)         # Standard video memory address required
+-      jnz     vesan
+-
+-      testb   $2, (%di)                       # Mode characteristics supplied?
+-      movw    %bx, (%di)                      # Store mode number
+-      jz      vesa3
+-      
+-      xorw    %dx, %dx
+-      movw    0x12(%di), %bx                  # Width
+-      orb     %bh, %bh
+-      jnz     vesan
+-      
+-      movb    %bl, 0x3(%di)
+-      movw    0x14(%di), %ax                  # Height
+-      orb     %ah, %ah
+-      jnz     vesan
+-      
+-      movb    %al, 2(%di)
+-      mulb    %bl
+-      cmpw    $8193, %ax              # Small enough for Linux console driver?
+-      jnc     vesan
+-
+-      jmp     vesaok
+-
+-vesa3:        subw    $0x8108, %bx    # This mode has no detailed info specified,
+-      jc      vesan           # so it must be a standard VESA mode.
+-
+-      cmpw    $5, %bx
+-      jnc     vesan
+-
+-      movw    vesa_text_mode_table(%bx), %ax
+-      movw    %ax, 2(%di)
+-vesaok:       addw    $4, %di                         # The mode is valid. Store it.
+-vesan:        loop    vesa1                   # Next mode. Limit exceeded => error
+-vesae:        leaw    vesaer, %si
+-      call    prtstr
+-      movw    %bp, %di                        # Discard already found modes.
+-vesar:        popw    %gs
+-      ret
+-
+-# Dimensions of standard VESA text modes
+-vesa_text_mode_table:
+-      .byte   60, 80                          # 0108
+-      .byte   25, 132                         # 0109
+-      .byte   43, 132                         # 010A
+-      .byte   50, 132                         # 010B
+-      .byte   60, 132                         # 010C
+-#endif        /* CONFIG_VIDEO_VESA */
+-
+-# Scan for video modes. A bit dirty, but should work.
+-mode_scan:
+-      movw    $0x0100, %cx                    # Start with mode 0
+-scm1: movb    $0, %ah                         # Test the mode
+-      movb    %cl, %al
+-      int     $0x10
+-      movb    $0x0f, %ah
+-      int     $0x10
+-      cmpb    %cl, %al
+-      jnz     scm2                            # Mode not set
+-
+-      movw    $0x3c0, %dx                     # Test if it's a text mode
+-      movb    $0x10, %al                      # Mode bits
+-      call    inidx
+-      andb    $0x03, %al
+-      jnz     scm2
+-      
+-      movb    $0xce, %dl                      # Another set of mode bits
+-      movb    $0x06, %al
+-      call    inidx
+-      shrb    %al
+-      jc      scm2
+-      
+-      movb    $0xd4, %dl                      # Cursor location
+-      movb    $0x0f, %al
+-      call    inidx
+-      orb     %al, %al
+-      jnz     scm2
+-      
+-      movw    %cx, %ax                        # Ok, store the mode
+-      stosw
+-      movb    %gs:(0x484), %al                # Number of rows
+-      incb    %al
+-      stosb
+-      movw    %gs:(0x44a), %ax                # Number of columns
+-      stosb
+-scm2: incb    %cl
+-      jns     scm1
+-      
+-      movw    $0x0003, %ax                    # Return back to mode 3
+-      int     $0x10
+-      ret
+-
+-tstidx:       outw    %ax, %dx                        # OUT DX,AX and inidx
+-inidx:        outb    %al, %dx                        # Read from indexed VGA register
+-      incw    %dx                     # AL=index, DX=index reg port -> AL=data
+-      inb     %dx, %al
+-      decw    %dx
+-      ret
+-
+-# Try to detect type of SVGA card and supply (usually approximate) video
+-# mode table for it.
+-
+-#ifdef CONFIG_VIDEO_SVGA
+-svga_modes:
+-      leaw    svga_table, %si                 # Test all known SVGA adapters
+-dosvga:       lodsw
+-      movw    %ax, %bp                        # Default mode table
+-      orw     %ax, %ax
+-      jz      didsv1
+-
+-      lodsw                                   # Pointer to test routine
+-      pushw   %si
+-      pushw   %di
+-      pushw   %es
+-      movw    $0xc000, %bx
+-      movw    %bx, %es
+-      call    *%ax                            # Call test routine
+-      popw    %es
+-      popw    %di
+-      popw    %si
+-      orw     %bp, %bp
+-      jz      dosvga
+-      
+-      movw    %bp, %si                        # Found, copy the modes
+-      movb    svga_prefix, %ah
+-cpsvga:       lodsb
+-      orb     %al, %al
+-      jz      didsv
+-      
+-      stosw
+-      movsw
+-      jmp     cpsvga
+-
+-didsv:        movw    %si, card_name                  # Store pointer to card name
+-didsv1:       ret
+-
+-# Table of all known SVGA cards. For each card, we store a pointer to
+-# a table of video modes supported by the card and a pointer to a routine
+-# used for testing of presence of the card. The video mode table is always
+-# followed by the name of the card or the chipset.
+-svga_table:
+-      .word   ati_md, ati_test
+-      .word   oak_md, oak_test
+-      .word   paradise_md, paradise_test
+-      .word   realtek_md, realtek_test
+-      .word   s3_md, s3_test
+-      .word   chips_md, chips_test
+-      .word   video7_md, video7_test
+-      .word   cirrus5_md, cirrus5_test
+-      .word   cirrus6_md, cirrus6_test
+-      .word   cirrus1_md, cirrus1_test
+-      .word   ahead_md, ahead_test
+-      .word   everex_md, everex_test
+-      .word   genoa_md, genoa_test
+-      .word   trident_md, trident_test
+-      .word   tseng_md, tseng_test
+-      .word   0
+-
+-# Test routines and mode tables:
+-
+-# S3 - The test algorithm was taken from the SuperProbe package
+-# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org
+-s3_test:
+-      movw    $0x0f35, %cx    # we store some constants in cl/ch
+-      movw    $0x03d4, %dx
+-      movb    $0x38, %al
+-      call    inidx
+-      movb    %al, %bh        # store current CRT-register 0x38
+-      movw    $0x0038, %ax
+-      call    outidx          # disable writing to special regs
+-      movb    %cl, %al        # check whether we can write special reg 0x35
+-      call    inidx
+-      movb    %al, %bl        # save the current value of CRT reg 0x35
+-      andb    $0xf0, %al      # clear bits 0-3
+-      movb    %al, %ah
+-      movb    %cl, %al        # and write it to CRT reg 0x35
+-      call    outidx
+-      call    inidx           # now read it back
+-      andb    %ch, %al        # clear the upper 4 bits
+-      jz      s3_2            # the first test failed. But we have a
+-
+-      movb    %bl, %ah        # second chance
+-      movb    %cl, %al
+-      call    outidx
+-      jmp     s3_1            # do the other tests
+-
+-s3_2: movw    %cx, %ax        # load ah with 0xf and al with 0x35
+-      orb     %bl, %ah        # set the upper 4 bits of ah with the orig value
+-      call    outidx          # write ...
+-      call    inidx           # ... and reread 
+-      andb    %cl, %al        # turn off the upper 4 bits
+-      pushw   %ax
+-      movb    %bl, %ah        # restore old value in register 0x35
+-      movb    %cl, %al
+-      call    outidx
+-      popw    %ax
+-      cmpb    %ch, %al        # setting lower 4 bits was successful => bad
+-      je      no_s3           # writing is allowed => this is not an S3
+-
+-s3_1: movw    $0x4838, %ax    # allow writing to special regs by putting
+-      call    outidx          # magic number into CRT-register 0x38
+-      movb    %cl, %al        # check whether we can write special reg 0x35
+-      call    inidx
+-      movb    %al, %bl
+-      andb    $0xf0, %al
+-      movb    %al, %ah
+-      movb    %cl, %al
+-      call    outidx
+-      call    inidx
+-      andb    %ch, %al
+-      jnz     no_s3           # no, we can't write => no S3
+-
+-      movw    %cx, %ax
+-      orb     %bl, %ah
+-      call    outidx
+-      call    inidx
+-      andb    %ch, %al
+-      pushw   %ax
+-      movb    %bl, %ah        # restore old value in register 0x35
+-      movb    %cl, %al
+-      call    outidx
+-      popw    %ax
+-      cmpb    %ch, %al
+-      jne     no_s31          # writing not possible => no S3
+-      movb    $0x30, %al
+-      call    inidx           # now get the S3 id ...
+-      leaw    idS3, %di
+-      movw    $0x10, %cx
+-      repne
+-      scasb
+-      je      no_s31
+-
+-      movb    %bh, %ah
+-      movb    $0x38, %al
+-      jmp     s3rest
+-
+-no_s3:        movb    $0x35, %al      # restore CRT register 0x35
+-      movb    %bl, %ah
+-      call    outidx
+-no_s31:       xorw    %bp, %bp        # Detection failed
+-s3rest:       movb    %bh, %ah
+-      movb    $0x38, %al      # restore old value of CRT register 0x38
+-      jmp     outidx
+-
+-idS3: .byte   0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
+-      .byte   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
+-
+-s3_md:        .byte   0x54, 0x2b, 0x84
+-      .byte   0x55, 0x19, 0x84
+-      .byte   0
+-      .ascii  "S3"
+-      .byte   0
+-
+-# ATI cards.
+-ati_test:
+-      leaw    idati, %si
+-      movw    $0x31, %di
+-      movw    $0x09, %cx
+-      repe
+-      cmpsb
+-      je      atiok
+-
+-      xorw    %bp, %bp
+-atiok:        ret
+-
+-idati:        .ascii  "761295520"
+-
+-ati_md:       .byte   0x23, 0x19, 0x84
+-      .byte   0x33, 0x2c, 0x84
+-      .byte   0x22, 0x1e, 0x64
+-      .byte   0x21, 0x19, 0x64
+-      .byte   0x58, 0x21, 0x50
+-      .byte   0x5b, 0x1e, 0x50
+-      .byte   0
+-      .ascii  "ATI"
+-      .byte   0
+-
+-# AHEAD
+-ahead_test:
+-      movw    $0x200f, %ax
+-      movw    $0x3ce, %dx
+-      outw    %ax, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      cmpb    $0x20, %al
+-      je      isahed
+-
+-      cmpb    $0x21, %al
+-      je      isahed
+-      
+-      xorw    %bp, %bp
+-isahed:       ret
+-
+-ahead_md:
+-      .byte   0x22, 0x2c, 0x84
+-      .byte   0x23, 0x19, 0x84
+-      .byte   0x24, 0x1c, 0x84
+-      .byte   0x2f, 0x32, 0xa0
+-      .byte   0x32, 0x22, 0x50
+-      .byte   0x34, 0x42, 0x50
+-      .byte   0
+-      .ascii  "Ahead"
+-      .byte   0
+-
+-# Chips & Tech.
+-chips_test:
+-      movw    $0x3c3, %dx
+-      inb     %dx, %al
+-      orb     $0x10, %al
+-      outb    %al, %dx
+-      movw    $0x104, %dx
+-      inb     %dx, %al
+-      movb    %al, %bl
+-      movw    $0x3c3, %dx
+-      inb     %dx, %al
+-      andb    $0xef, %al
+-      outb    %al, %dx
+-      cmpb    $0xa5, %bl
+-      je      cantok
+-      
+-      xorw    %bp, %bp
+-cantok:       ret
+-
+-chips_md:
+-      .byte   0x60, 0x19, 0x84
+-      .byte   0x61, 0x32, 0x84
+-      .byte   0
+-      .ascii  "Chips & Technologies"
+-      .byte   0
+-
+-# Cirrus Logic 5X0
+-cirrus1_test:
+-      movw    $0x3d4, %dx
+-      movb    $0x0c, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      movb    %al, %bl
+-      xorb    %al, %al
+-      outb    %al, %dx
+-      decw    %dx
+-      movb    $0x1f, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      movb    %al, %bh
+-      xorb    %ah, %ah
+-      shlb    $4, %al
+-      movw    %ax, %cx
+-      movb    %bh, %al
+-      shrb    $4, %al
+-      addw    %ax, %cx
+-      shlw    $8, %cx
+-      addw    $6, %cx
+-      movw    %cx, %ax
+-      movw    $0x3c4, %dx
+-      outw    %ax, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      andb    %al, %al
+-      jnz     nocirr
+-      
+-      movb    %bh, %al
+-      outb    %al, %dx
+-      inb     %dx, %al
+-      cmpb    $0x01, %al
+-      je      iscirr
+-
+-nocirr:       xorw    %bp, %bp
+-iscirr: movw  $0x3d4, %dx
+-      movb    %bl, %al
+-      xorb    %ah, %ah
+-      shlw    $8, %ax
+-      addw    $0x0c, %ax
+-      outw    %ax, %dx
+-      ret
+-
+-cirrus1_md:
+-      .byte   0x1f, 0x19, 0x84
+-      .byte   0x20, 0x2c, 0x84
+-      .byte   0x22, 0x1e, 0x84
+-      .byte   0x31, 0x25, 0x64
+-      .byte   0
+-      .ascii  "Cirrus Logic 5X0"
+-      .byte   0
+-
+-# Cirrus Logic 54XX
+-cirrus5_test:
+-      movw    $0x3c4, %dx
+-      movb    $6, %al
+-      call    inidx
+-      movb    %al, %bl                        # BL=backup
+-      movw    $6, %ax
+-      call    tstidx
+-      cmpb    $0x0f, %al
+-      jne     c5fail
+-      
+-      movw    $0x1206, %ax
+-      call    tstidx
+-      cmpb    $0x12, %al
+-      jne     c5fail
+-      
+-      movb    $0x1e, %al
+-      call    inidx
+-      movb    %al, %bh
+-      movb    %bh, %ah
+-      andb    $0xc0, %ah
+-      movb    $0x1e, %al
+-      call    tstidx
+-      andb    $0x3f, %al
+-      jne     c5xx
+-      
+-      movb    $0x1e, %al
+-      movb    %bh, %ah
+-      orb     $0x3f, %ah
+-      call    tstidx
+-      xorb    $0x3f, %al
+-      andb    $0x3f, %al
+-c5xx: pushf
+-      movb    $0x1e, %al
+-      movb    %bh, %ah
+-      outw    %ax, %dx
+-      popf
+-      je      c5done
+-
+-c5fail:       xorw    %bp, %bp
+-c5done:       movb    $6, %al
+-      movb    %bl, %ah
+-      outw    %ax, %dx
+-      ret
+-
+-cirrus5_md:
+-      .byte   0x14, 0x19, 0x84
+-      .byte   0x54, 0x2b, 0x84
+-      .byte   0
+-      .ascii  "Cirrus Logic 54XX"
+-      .byte   0
+-
+-# Cirrus Logic 64XX -- no known extra modes, but must be identified, because
+-# it's misidentified by the Ahead test.
+-cirrus6_test:
+-      movw    $0x3ce, %dx
+-      movb    $0x0a, %al
+-      call    inidx
+-      movb    %al, %bl        # BL=backup
+-      movw    $0xce0a, %ax
+-      call    tstidx
+-      orb     %al, %al
+-      jne     c2fail
+-      
+-      movw    $0xec0a, %ax
+-      call    tstidx
+-      cmpb    $0x01, %al
+-      jne     c2fail
+-      
+-      movb    $0xaa, %al
+-      call    inidx           # 4X, 5X, 7X and 8X are valid 64XX chip ID's. 
+-      shrb    $4, %al
+-      subb    $4, %al
+-      jz      c6done
+-      
+-      decb    %al
+-      jz      c6done
+-      
+-      subb    $2, %al
+-      jz      c6done
+-      
+-      decb    %al
+-      jz      c6done
+-      
+-c2fail:       xorw    %bp, %bp
+-c6done:       movb    $0x0a, %al
+-      movb    %bl, %ah
+-      outw    %ax, %dx
+-      ret
+-
+-cirrus6_md:
+-      .byte   0
+-      .ascii  "Cirrus Logic 64XX"
+-      .byte   0
+-
+-# Everex / Trident
+-everex_test:
+-      movw    $0x7000, %ax
+-      xorw    %bx, %bx
+-      int     $0x10
+-      cmpb    $0x70, %al
+-      jne     noevrx
+-      
+-      shrw    $4, %dx
+-      cmpw    $0x678, %dx
+-      je      evtrid
+-      
+-      cmpw    $0x236, %dx
+-      jne     evrxok
+-
+-evtrid:       leaw    trident_md, %bp
+-evrxok:       ret
+-
+-noevrx:       xorw    %bp, %bp
+-      ret
+-
+-everex_md:
+-      .byte   0x03, 0x22, 0x50
+-      .byte   0x04, 0x3c, 0x50
+-      .byte   0x07, 0x2b, 0x64
+-      .byte   0x08, 0x4b, 0x64
+-      .byte   0x0a, 0x19, 0x84
+-      .byte   0x0b, 0x2c, 0x84
+-      .byte   0x16, 0x1e, 0x50
+-      .byte   0x18, 0x1b, 0x64
+-      .byte   0x21, 0x40, 0xa0
+-      .byte   0x40, 0x1e, 0x84
+-      .byte   0
+-      .ascii  "Everex/Trident"
+-      .byte   0
+-
+-# Genoa.
+-genoa_test:
+-      leaw    idgenoa, %si                    # Check Genoa 'clues'
+-      xorw    %ax, %ax
+-      movb    %es:(0x37), %al
+-      movw    %ax, %di
+-      movw    $0x04, %cx
+-      decw    %si
+-      decw    %di
+-l1:   incw    %si
+-      incw    %di
+-      movb    (%si), %al
+-      testb   %al, %al
+-      jz      l2
+-
+-      cmpb    %es:(%di), %al
+-l2:   loope   l1
+-      orw     %cx, %cx
+-      je      isgen
+-      
+-      xorw    %bp, %bp
+-isgen:        ret
+-
+-idgenoa: .byte        0x77, 0x00, 0x99, 0x66
+-
+-genoa_md:
+-      .byte   0x58, 0x20, 0x50
+-      .byte   0x5a, 0x2a, 0x64
+-      .byte   0x60, 0x19, 0x84
+-      .byte   0x61, 0x1d, 0x84
+-      .byte   0x62, 0x20, 0x84
+-      .byte   0x63, 0x2c, 0x84
+-      .byte   0x64, 0x3c, 0x84
+-      .byte   0x6b, 0x4f, 0x64
+-      .byte   0x72, 0x3c, 0x50
+-      .byte   0x74, 0x42, 0x50
+-      .byte   0x78, 0x4b, 0x64
+-      .byte   0
+-      .ascii  "Genoa"
+-      .byte   0
+-
+-# OAK
+-oak_test:
+-      leaw    idoakvga, %si
+-      movw    $0x08, %di
+-      movw    $0x08, %cx
+-      repe
+-      cmpsb
+-      je      isoak
+-      
+-      xorw    %bp, %bp
+-isoak:        ret
+-
+-idoakvga: .ascii  "OAK VGA "
+-
+-oak_md: .byte 0x4e, 0x3c, 0x50
+-      .byte   0x4f, 0x3c, 0x84
+-      .byte   0x50, 0x19, 0x84
+-      .byte   0x51, 0x2b, 0x84
+-      .byte   0
+-      .ascii  "OAK"
+-      .byte   0
+-
+-# WD Paradise.
+-paradise_test:
+-      leaw    idparadise, %si
+-      movw    $0x7d, %di
+-      movw    $0x04, %cx
+-      repe
+-      cmpsb
+-      je      ispara
+-      
+-      xorw    %bp, %bp
+-ispara:       ret
+-
+-idparadise:   .ascii  "VGA="
+-
+-paradise_md:
+-      .byte   0x41, 0x22, 0x50
+-      .byte   0x47, 0x1c, 0x84
+-      .byte   0x55, 0x19, 0x84
+-      .byte   0x54, 0x2c, 0x84
+-      .byte   0
+-      .ascii  "Paradise"
+-      .byte   0
+-
+-# Trident.
+-trident_test:
+-      movw    $0x3c4, %dx
+-      movb    $0x0e, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      xchgb   %al, %ah
+-      xorb    %al, %al
+-      outb    %al, %dx
+-      inb     %dx, %al
+-      xchgb   %ah, %al
+-      movb    %al, %bl        # Strange thing ... in the book this wasn't
+-      andb    $0x02, %bl      # necessary but it worked on my card which
+-      jz      setb2           # is a trident. Without it the screen goes
+-                              # blurred ...
+-      andb    $0xfd, %al
+-      jmp     clrb2           
+-
+-setb2:        orb     $0x02, %al      
+-clrb2:        outb    %al, %dx
+-      andb    $0x0f, %ah
+-      cmpb    $0x02, %ah
+-      je      istrid
+-
+-      xorw    %bp, %bp
+-istrid:       ret
+-
+-trident_md:
+-      .byte   0x50, 0x1e, 0x50
+-      .byte   0x51, 0x2b, 0x50
+-      .byte   0x52, 0x3c, 0x50
+-      .byte   0x57, 0x19, 0x84
+-      .byte   0x58, 0x1e, 0x84
+-      .byte   0x59, 0x2b, 0x84
+-      .byte   0x5a, 0x3c, 0x84
+-      .byte   0
+-      .ascii  "Trident"
+-      .byte   0
+-
+-# Tseng.
+-tseng_test:
+-      movw    $0x3cd, %dx
+-      inb     %dx, %al        # Could things be this simple ! :-)
+-      movb    %al, %bl
+-      movb    $0x55, %al
+-      outb    %al, %dx
+-      inb     %dx, %al
+-      movb    %al, %ah
+-      movb    %bl, %al
+-      outb    %al, %dx
+-      cmpb    $0x55, %ah
+-      je      istsen
+-
+-isnot:        xorw    %bp, %bp
+-istsen:       ret
+-
+-tseng_md:
+-      .byte   0x26, 0x3c, 0x50
+-      .byte   0x2a, 0x28, 0x64
+-      .byte   0x23, 0x19, 0x84
+-      .byte   0x24, 0x1c, 0x84
+-      .byte   0x22, 0x2c, 0x84
+-      .byte   0x21, 0x3c, 0x84
+-      .byte   0
+-      .ascii  "Tseng"
+-      .byte   0
+-
+-# Video7.
+-video7_test:
+-      movw    $0x3cc, %dx
+-      inb     %dx, %al
+-      movw    $0x3b4, %dx
+-      andb    $0x01, %al
+-      jz      even7
+-
+-      movw    $0x3d4, %dx
+-even7:        movb    $0x0c, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      movb    %al, %bl
+-      movb    $0x55, %al
+-      outb    %al, %dx
+-      inb     %dx, %al
+-      decw    %dx
+-      movb    $0x1f, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      inb     %dx, %al
+-      movb    %al, %bh
+-      decw    %dx
+-      movb    $0x0c, %al
+-      outb    %al, %dx
+-      incw    %dx
+-      movb    %bl, %al
+-      outb    %al, %dx
+-      movb    $0x55, %al
+-      xorb    $0xea, %al
+-      cmpb    %bh, %al
+-      jne     isnot
+-      
+-      movb    $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching
+-      ret
+-
+-video7_md:
+-      .byte   0x40, 0x2b, 0x50
+-      .byte   0x43, 0x3c, 0x50
+-      .byte   0x44, 0x3c, 0x64
+-      .byte   0x41, 0x19, 0x84
+-      .byte   0x42, 0x2c, 0x84
+-      .byte   0x45, 0x1c, 0x84
+-      .byte   0
+-      .ascii  "Video 7"
+-      .byte   0
+-
+-# Realtek VGA
+-realtek_test:
+-      leaw    idrtvga, %si
+-      movw    $0x45, %di
+-      movw    $0x0b, %cx
+-      repe
+-      cmpsb
+-      je      isrt
+-      
+-      xorw    %bp, %bp
+-isrt: ret
+-
+-idrtvga:      .ascii  "REALTEK VGA"
+-
+-realtek_md:
+-      .byte   0x1a, 0x3c, 0x50
+-      .byte   0x1b, 0x19, 0x84
+-      .byte   0x1c, 0x1e, 0x84
+-      .byte   0x1d, 0x2b, 0x84
+-      .byte   0x1e, 0x3c, 0x84
+-      .byte   0
+-      .ascii  "REALTEK"
+-      .byte   0
+-
+-#endif        /* CONFIG_VIDEO_SVGA */
+-
+-# User-defined local mode table (VGA only)
+-#ifdef CONFIG_VIDEO_LOCAL
+-local_modes:
+-      leaw    local_mode_table, %si
+-locm1:        lodsw
+-      orw     %ax, %ax
+-      jz      locm2
+-      
+-      stosw
+-      movsw
+-      jmp     locm1
+-
+-locm2:        ret
+-
+-# This is the table of local video modes which can be supplied manually
+-# by the user. Each entry consists of mode ID (word) and dimensions
+-# (byte for column count and another byte for row count). These modes
+-# are placed before all SVGA and VESA modes and override them if table
+-# compacting is enabled. The table must end with a zero word followed
+-# by NUL-terminated video adapter name.
+-local_mode_table:
+-      .word   0x0100                          # Example: 40x25
+-      .byte   25,40
+-      .word   0
+-      .ascii  "Local"
+-      .byte   0
+-#endif        /* CONFIG_VIDEO_LOCAL */
+-
+-# Read a key and return the ASCII code in al, scan code in ah
+-getkey:       xorb    %ah, %ah
+-      int     $0x16
+-      ret
+-
+-# Read a key with a timeout of 30 seconds.
+-# The hardware clock is used to get the time.
+-getkt:        call    gettime
+-      addb    $30, %al                        # Wait 30 seconds
+-      cmpb    $60, %al
+-      jl      lminute
+-
+-      subb    $60, %al
+-lminute:
+-      movb    %al, %cl
+-again:        movb    $0x01, %ah
+-      int     $0x16
+-      jnz     getkey                          # key pressed, so get it
+-
+-      call    gettime
+-      cmpb    %cl, %al
+-      jne     again
+-
+-      movb    $0x20, %al                      # timeout, return `space'
+-      ret
+-
+-# Flush the keyboard buffer
+-flush:        movb    $0x01, %ah
+-      int     $0x16
+-      jz      empty
+-      
+-      xorb    %ah, %ah
+-      int     $0x16
+-      jmp     flush
+-
+-empty:        ret
+-
+-# Print hexadecimal number.
+-prthw:        pushw   %ax
+-      movb    %ah, %al
+-      call    prthb
+-      popw    %ax
+-prthb:        pushw   %ax
+-      shrb    $4, %al
+-      call    prthn
+-      popw    %ax
+-      andb    $0x0f, %al
+-prthn:        cmpb    $0x0a, %al
+-      jc      prth1
+-
+-      addb    $0x07, %al
+-prth1:        addb    $0x30, %al
+-      jmp     prtchr
+-
+-# Print decimal number in al
+-prtdec:       pushw   %ax
+-      pushw   %cx
+-      xorb    %ah, %ah
+-      movb    $0x0a, %cl
+-      idivb   %cl
+-      cmpb    $0x09, %al
+-      jbe     lt100
+-
+-      call    prtdec
+-      jmp     skip10
+-
+-lt100:        addb    $0x30, %al
+-      call    prtchr
+-skip10:       movb    %ah, %al
+-      addb    $0x30, %al
+-      call    prtchr  
+-      popw    %cx
+-      popw    %ax
+-      ret
+-
+-store_edid:
+-#ifdef CONFIG_FIRMWARE_EDID
+-      pushw   %es                             # just save all registers
+-      pushw   %ax
+-      pushw   %bx
+-      pushw   %cx
+-      pushw   %dx
+-      pushw   %di
+-
+-      pushw   %fs
+-      popw    %es
+-
+-      movl    $0x13131313, %eax               # memset block with 0x13
+-      movw    $32, %cx
+-      movw    $0x140, %di
+-      cld
+-      rep
+-      stosl
+-
+-      cmpw    $0x0200, vbe_version            # only do EDID on >= VBE2.0
+-      jl      no_edid
+-
+-      pushw   %es                             # save ES
+-      xorw    %di, %di                        # Report Capability
+-      pushw   %di
+-      popw    %es                             # ES:DI must be 0:0
+-      movw    $0x4f15, %ax
+-      xorw    %bx, %bx
+-      xorw    %cx, %cx
+-      int     $0x10
+-      popw    %es                             # restore ES
+-
+-      cmpb    $0x00, %ah                      # call successful
+-      jne     no_edid
+-
+-      cmpb    $0x4f, %al                      # function supported
+-      jne     no_edid
+-
+-      movw    $0x4f15, %ax                    # do VBE/DDC
+-      movw    $0x01, %bx
+-      movw    $0x00, %cx
+-      movw    $0x00, %dx
+-      movw    $0x140, %di
+-      int     $0x10
+-
+-no_edid:
+-      popw    %di                             # restore all registers
+-      popw    %dx
+-      popw    %cx
+-      popw    %bx
+-      popw    %ax
+-      popw    %es
+-#endif
+-      ret
+-
+-# VIDEO_SELECT-only variables
+-mt_end:               .word   0       # End of video mode table if built
+-edit_buf:     .space  6       # Line editor buffer
+-card_name:    .word   0       # Pointer to adapter name
+-scanning:     .byte   0       # Performing mode scan
+-do_restore:   .byte   0       # Screen contents altered during mode change
+-svga_prefix:  .byte   VIDEO_FIRST_BIOS>>8     # Default prefix for BIOS modes
+-graphic_mode: .byte   0       # Graphic mode with a linear frame buffer
+-dac_size:     .byte   6       # DAC bit depth
+-vbe_version:  .word   0       # VBE bios version
+-
+-# Status messages
+-keymsg:               .ascii  "Press <RETURN> to see video modes available, "
+-              .ascii  "<SPACE> to continue or wait 30 secs"
+-              .byte   0x0d, 0x0a, 0
+-
+-listhdr:      .byte   0x0d, 0x0a
+-              .ascii  "Mode:    COLSxROWS:"
+-
+-crlft:                .byte   0x0d, 0x0a, 0
+-
+-prompt:               .byte   0x0d, 0x0a
+-              .asciz  "Enter mode number or `scan': "
+-
+-unknt:                .asciz  "Unknown mode ID. Try again."
+-
+-badmdt:               .ascii  "You passed an undefined mode number."
+-              .byte   0x0d, 0x0a, 0
+-
+-vesaer:               .ascii  "Error: Scanning of VESA modes failed. Please "
+-              .ascii  "report to <mj@ucw.cz>."
+-              .byte   0x0d, 0x0a, 0
+-
+-old_name:     .asciz  "CGA/MDA/HGA"
+-
+-ega_name:     .asciz  "EGA"
+-
+-svga_name:    .ascii  " "
+-
+-vga_name:     .asciz  "VGA"
+-
+-vesa_name:    .asciz  "VESA"
+-
+-name_bann:    .asciz  "Video adapter: "
+-#endif /* CONFIG_VIDEO_SELECT */
+-
+-# Other variables:
+-adapter:      .byte   0       # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
+-video_segment:        .word   0xb800  # Video memory segment
+-force_size:   .word   0       # Use this size instead of the one in BIOS vars
+diff -puN /dev/null arch/i386/boot/video.c
+--- /dev/null
++++ a/arch/i386/boot/video.c
+@@ -0,0 +1,456 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/video.c
++ *
++ * Select video mode
++ */
++
++#include "boot.h"
++#include "video.h"
++#include "vesa.h"
++
++/*
++ * Mode list variables
++ */
++static struct card_info cards[];    /* List of cards to probe for */
++
++/*
++ * Common variables
++ */
++int adapter;                  /* 0=CGA/MDA/HGC, 1=EGA, 2=VGA+ */
++u16 video_segment;
++int force_x, force_y; /* Don't query the BIOS for cols/rows */
++
++int do_restore = 0;   /* Screen contents changed during mode flip */
++int graphic_mode;     /* Graphic mode with linear frame buffer */
++
++static void store_cursor_position(void)
++{
++      u16 curpos;
++      u16 ax, bx;
++
++      ax = 0x0300;
++      bx = 0;
++      asm(INT10
++          : "=d" (curpos), "+a" (ax), "+b" (bx)
++          : : "ecx", "esi", "edi");
++
++      boot_params.screen_info.orig_x = curpos;
++      boot_params.screen_info.orig_y = curpos >> 8;
++}
++
++static void store_video_mode(void)
++{
++      u16 ax, page;
++
++      /* N.B.: the saving of the video page here is a bit silly,
++         since we pretty much assume page 0 everywhere. */
++      ax = 0x0f00;
++      asm(INT10
++          : "+a" (ax), "=b" (page)
++          : : "ecx", "edx", "esi", "edi");
++
++      /* Not all BIOSes are clean with respect to the top bit */
++      boot_params.screen_info.orig_video_mode = ax & 0x7f;
++      boot_params.screen_info.orig_video_page = page;
++}
++
++/*
++ * Store the video mode parameters for later usage by the kernel.
++ * This is done by asking the BIOS except for the rows/columns
++ * parameters in the default 80x25 mode -- these are set directly,
++ * because some very obscure BIOSes supply insane values.
++ */
++static void store_mode_params(void)
++{
++      u16 font_size;
++      int x, y;
++
++      /* For graphics mode, it is up to the mode-setting driver
++         (currently only video-vesa.c) to store the parameters */
++      if (graphic_mode)
++              return;
++
++      store_cursor_position();
++      store_video_mode();
++
++      if (boot_params.screen_info.orig_video_mode == 0x07) {
++              /* MDA, HGC, or VGA in monochrome mode */
++              video_segment = 0xb000;
++      } else {
++              /* CGA, EGA, VGA and so forth */
++              video_segment = 0xb800;
++      }
++
++      set_fs(0);
++      font_size = rdfs16(0x485); /* Font size, BIOS area */
++      boot_params.screen_info.orig_video_points = font_size;
++
++      x = rdfs16(0x44a);
++      y = (adapter == ADAPTER_CGA) ? 25 : rdfs8(0x484)+1;
++
++      if (force_x)
++              x = force_x;
++      if (force_y)
++              y = force_y;
++
++      boot_params.screen_info.orig_video_cols  = x;
++      boot_params.screen_info.orig_video_lines = y;
++}
++
++/* Probe the video drivers and have them generate their mode lists. */
++static void probe_cards(int unsafe)
++{
++      struct card_info *card;
++      static u8 probed[2];
++
++      if (probed[unsafe])
++              return;
++
++      probed[unsafe] = 1;
++
++      for (card = video_cards; card < video_cards_end; card++) {
++              if (card->unsafe == unsafe) {
++                      if (card->probe)
++                              card->nmodes = card->probe();
++                      else
++                              card->nmodes = 0;
++              }
++      }
++}
++
++/* Test if a mode is defined */
++int mode_defined(u16 mode)
++{
++      struct card_info *card;
++      struct mode_info *mi;
++      int i;
++
++      for (card = video_cards; card < video_cards_end; card++) {
++              mi = card->modes;
++              for (i = 0; i < card->nmodes; i++, mi++) {
++                      if (mi->mode == mode)
++                              return 1;
++              }
++      }
++
++      return 0;
++}
++
++/* Set mode (without recalc) */
++static int raw_set_mode(u16 mode)
++{
++      int nmode, i;
++      struct card_info *card;
++      struct mode_info *mi;
++
++      /* Drop the recalc bit if set */
++      mode &= ~VIDEO_RECALC;
++
++      /* Scan for mode based on fixed ID, position, or resolution */
++      nmode = 0;
++      for (card = video_cards; card < video_cards_end; card++) {
++              mi = card->modes;
++              for (i = 0; i < card->nmodes; i++, mi++) {
++                      int visible = mi->x || mi->y;
++
++                      if ((mode == nmode && visible) ||
++                          mode == mi->mode ||
++                          mode == (mi->y << 8)+mi->x)
++                              return card->set_mode(mi);
++
++                      if (visible)
++                              nmode++;
++              }
++      }
++
++      /* Nothing found?  Is it an "exceptional" (unprobed) mode? */
++      for (card = video_cards; card < video_cards_end; card++) {
++              if (mode >= card->xmode_first &&
++                  mode < card->xmode_first+card->xmode_n) {
++                      struct mode_info mix;
++                      mix.mode = mode;
++                      mix.x = mix.y = 0;
++                      return card->set_mode(&mix);
++              }
++      }
++
++      /* Otherwise, failure... */
++      return -1;
++}
++
++/*
++ * Recalculate the vertical video cutoff (hack!)
++ */
++static void vga_recalc_vertical(void)
++{
++      unsigned int font_size, rows;
++      u16 crtc;
++      u8 ov;
++
++      set_fs(0);
++      font_size = rdfs8(0x485); /* BIOS: font size (pixels) */
++      rows = force_y ? force_y : rdfs8(0x484)+1; /* Text rows */
++
++      rows *= font_size;      /* Visible scan lines */
++      rows--;                 /* ... minus one */
++
++      crtc = vga_crtc();
++
++      out_idx((u8)rows, crtc, 0x12); /* Lower height register */
++      ov = in_idx(crtc, 0x07); /* Overflow register */
++      ov &= 0xbd;
++      ov |= (rows >> (8-1)) & 0x02;
++      ov |= (rows >> (9-6)) & 0x40;
++      out_idx(ov, crtc, 0x07);
++}
++
++/* Set mode (with recalc if specified) */
++static int set_mode(u16 mode)
++{
++      int rv;
++
++      /* Very special mode numbers... */
++      if (mode == VIDEO_CURRENT_MODE)
++              return 0;       /* Nothing to do... */
++      else if (mode == NORMAL_VGA)
++              mode = VIDEO_80x25;
++      else if (mode == EXTENDED_VGA)
++              mode = VIDEO_8POINT;
++
++      rv = raw_set_mode(mode);
++      if (rv)
++              return rv;
++
++      if (mode & VIDEO_RECALC)
++              vga_recalc_vertical();
++
++      return 0;
++}
++
++static unsigned int get_entry(void)
++{
++      char entry_buf[4];
++      int i, len = 0;
++      int key;
++      unsigned int v;
++
++      do {
++              key = getchar();
++
++              if (key == '\b') {
++                      if (len > 0) {
++                              puts("\b \b");
++                              len--;
++                      }
++              } else if ((key >= '0' && key <= '9') ||
++                         (key >= 'A' && key <= 'Z') ||
++                         (key >= 'a' && key <= 'z')) {
++                      if (len < sizeof entry_buf) {
++                              entry_buf[len++] = key;
++                              putchar(key);
++                      }
++              }
++      } while (key != '\r');
++      putchar('\n');
++
++      if (len == 0)
++              return VIDEO_CURRENT_MODE; /* Default */
++
++      v = 0;
++      for (i = 0; i < len; i++) {
++              v <<= 4;
++              key = entry_buf[i] | 0x20;
++              v += (key > '9') ? key-'a'+10 : key-'0';
++      }
++
++      return v;
++}
++
++static void display_menu(void)
++{
++      struct card_info *card;
++      struct mode_info *mi;
++      char ch;
++      int i;
++
++      puts("Mode:    COLSxROWS:\n");
++
++      ch = '0';
++      for (card = video_cards; card < video_cards_end; card++) {
++              mi = card->modes;
++              for (i = 0; i < card->nmodes; i++, mi++) {
++                      int visible = mi->x && mi->y;
++                      u16 mode_id = mi->mode ? mi->mode :
++                              (mi->y << 8)+mi->x;
++
++                      if (!visible)
++                              continue; /* Hidden mode */
++
++                      printf("%c  %04X  %3dx%-3d  %s\n",
++                             ch, mode_id, mi->x, mi->y, card->card_name);
++
++                      if (ch == '9')
++                              ch = 'a';
++                      else if (ch == 'z' || ch == ' ')
++                              ch = ' '; /* Out of keys... */
++                      else
++                              ch++;
++              }
++      }
++}
++
++#define H(x)  ((x)-'a'+10)
++#define SCAN  ((H('s')<<12)+(H('c')<<8)+(H('a')<<4)+H('n'))
++
++static unsigned int mode_menu(void)
++{
++      int key;
++      unsigned int sel;
++
++      puts("Press <ENTER> to see video modes available, "
++           "<SPACE> to continue, or wait 30 sec\n");
++
++      kbd_flush();
++      while (1) {
++              key = getchar_timeout();
++              if (key == ' ' || key == 0)
++                      return VIDEO_CURRENT_MODE; /* Default */
++              if (key == '\r')
++                      break;
++              putchar('\a');  /* Beep! */
++      }
++
++
++      for (;;) {
++              display_menu();
++
++              puts("Enter a video mode or \"scan\" to scan for "
++                   "additional modes: ");
++              sel = get_entry();
++              if (sel != SCAN)
++                      return sel;
++
++              probe_cards(1);
++      }
++}
++
++#ifdef CONFIG_VIDEO_RETAIN
++/* Save screen content to the heap */
++struct saved_screen {
++      int x, y;
++      int curx, cury;
++      u16 *data;
++} saved;
++
++static void save_screen(void)
++{
++      /* Should be called after store_mode_params() */
++      saved.x = boot_params.screen_info.orig_video_cols;
++      saved.y = boot_params.screen_info.orig_video_lines;
++      saved.curx = boot_params.screen_info.orig_x;
++      saved.cury = boot_params.screen_info.orig_y;
++
++      if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
++              return;         /* Not enough heap to save the screen */
++
++      saved.data = GET_HEAP(u16, saved.x*saved.y);
++
++      set_fs(video_segment);
++      copy_from_fs(saved.data, 0, saved.x*saved.y*sizeof(u16));
++}
++
++static void restore_screen(void)
++{
++      /* Should be called after store_mode_params() */
++      int xs = boot_params.screen_info.orig_video_cols;
++      int ys = boot_params.screen_info.orig_video_lines;
++      int y;
++      addr_t dst = 0;
++      u16 *src = saved.data;
++      u16 ax, bx, dx;
++
++      if (graphic_mode)
++              return;         /* Can't restore onto a graphic mode */
++
++      if (!src)
++              return;         /* No saved screen contents */
++
++      /* Restore screen contents */
++
++      set_fs(video_segment);
++      for (y = 0; y < ys; y++) {
++              int npad;
++
++              if (y < saved.y) {
++                      int copy = (xs < saved.x) ? xs : saved.x;
++                      copy_to_fs(dst, src, copy*sizeof(u16));
++                      dst += copy*sizeof(u16);
++                      src += saved.x;
++                      npad = (xs < saved.x) ? 0 : xs-saved.x;
++              } else {
++                      npad = xs;
++              }
++
++              /* Writes "npad" blank characters to
++                 video_segment:dst and advances dst */
++              asm volatile("pushw %%es ; "
++                           "movw %2,%%es ; "
++                           "shrw %%cx ; "
++                           "jnc 1f ; "
++                           "stosw \n\t"
++                           "1: rep;stosl ; "
++                           "popw %%es"
++                           : "+D" (dst), "+c" (npad)
++                           : "bdSm" (video_segment),
++                             "a" (0x07200720));
++      }
++
++      /* Restore cursor position */
++      ax = 0x0200;            /* Set cursor position */
++      bx = 0;                 /* Page number (<< 8) */
++      dx = (saved.cury << 8)+saved.curx;
++      asm volatile(INT10
++                   : "+a" (ax), "+b" (bx), "+d" (dx)
++                   : : "ecx", "esi", "edi");
++}
++#else
++#define save_screen()         ((void)0)
++#define restore_screen()      ((void)0)
++#endif
++
++void set_video(void)
++{
++      u16 mode = boot_params.hdr.vid_mode;
++
++      RESET_HEAP();
++
++      store_mode_params();
++      save_screen();
++      probe_cards(0);
++
++      for (;;) {
++              if (mode == ASK_VGA)
++                      mode = mode_menu();
++
++              if (!set_mode(mode))
++                      break;
++
++              printf("Undefined video mode number: %x\n", mode);
++              mode = ASK_VGA;
++      }
++      vesa_store_edid();
++      store_mode_params();
++
++      if (do_restore)
++              restore_screen();
++}
+diff -puN /dev/null arch/i386/boot/video.h
+--- /dev/null
++++ a/arch/i386/boot/video.h
+@@ -0,0 +1,145 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/video.h
++ *
++ * Header file for the real-mode video probing code
++ */
++
++#ifndef BOOT_VIDEO_H
++#define BOOT_VIDEO_H
++
++#include <linux/types.h>
++
++/* Enable autodetection of SVGA adapters and modes. */
++#undef CONFIG_VIDEO_SVGA
++
++/* Enable autodetection of VESA modes */
++#define CONFIG_VIDEO_VESA
++
++/* Retain screen contents when switching modes */
++#define CONFIG_VIDEO_RETAIN
++
++/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */
++#undef CONFIG_VIDEO_400_HACK
++
++/* This code uses an extended set of video mode numbers. These include:
++ * Aliases for standard modes
++ *      NORMAL_VGA (-1)
++ *      EXTENDED_VGA (-2)
++ *      ASK_VGA (-3)
++ * Video modes numbered by menu position -- NOT RECOMMENDED because of lack
++ * of compatibility when extending the table. These are between 0x00 and 0xff.
++ */
++#define VIDEO_FIRST_MENU 0x0000
++
++/* Standard BIOS video modes (BIOS number + 0x0100) */
++#define VIDEO_FIRST_BIOS 0x0100
++
++/* VESA BIOS video modes (VESA number + 0x0200) */
++#define VIDEO_FIRST_VESA 0x0200
++
++/* Video7 special modes (BIOS number + 0x0900) */
++#define VIDEO_FIRST_V7 0x0900
++
++/* Special video modes */
++#define VIDEO_FIRST_SPECIAL 0x0f00
++#define VIDEO_80x25 0x0f00
++#define VIDEO_8POINT 0x0f01
++#define VIDEO_80x43 0x0f02
++#define VIDEO_80x28 0x0f03
++#define VIDEO_CURRENT_MODE 0x0f04
++#define VIDEO_80x30 0x0f05
++#define VIDEO_80x34 0x0f06
++#define VIDEO_80x60 0x0f07
++#define VIDEO_GFX_HACK 0x0f08
++#define VIDEO_LAST_SPECIAL 0x0f09
++
++/* Video modes given by resolution */
++#define VIDEO_FIRST_RESOLUTION 0x1000
++
++/* The "recalculate timings" flag */
++#define VIDEO_RECALC 0x8000
++
++/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
++#ifdef CONFIG_VIDEO_RETAIN
++void store_screen(void);
++#define DO_STORE() store_screen()
++#else
++#define DO_STORE() ((void)0)
++#endif /* CONFIG_VIDEO_RETAIN */
++
++/*
++ * Mode table structures
++ */
++
++struct mode_info {
++      u16 mode;               /* Mode number (vga= style) */
++      u8  x, y;               /* Width, height */
++};
++
++struct card_info {
++      const char *card_name;
++      int (*set_mode)(struct mode_info *mode);
++      int (*probe)(void);
++      struct mode_info *modes;
++      int nmodes;             /* Number of probed modes so far */
++      int unsafe;             /* Probing is unsafe, only do after "scan" */
++      u16 xmode_first;        /* Unprobed modes to try to call anyway */
++      u16 xmode_n;            /* Size of unprobed mode range */
++};
++
++#define __videocard struct card_info __attribute__((section(".videocards")))
++extern struct card_info video_cards[], video_cards_end[];
++
++int mode_defined(u16 mode);   /* video.c */
++
++/* Basic video information */
++#define ADAPTER_CGA   0       /* CGA/MDA/HGC */
++#define ADAPTER_EGA   1
++#define ADAPTER_VGA   2
++
++extern int adapter;
++extern u16 video_segment;
++extern int force_x, force_y;  /* Don't query the BIOS for cols/rows */
++extern int do_restore;                /* Restore screen contents */
++extern int graphic_mode;      /* Graphics mode with linear frame buffer */
++
++/*
++ * int $0x10 is notorious for touching registers it shouldn't.
++ * gcc doesn't like %ebp being clobbered, so define it as a push/pop
++ * sequence here.
++ */
++#define INT10 "pushl %%ebp; int $0x10; popl %%ebp"
++
++/* Accessing VGA indexed registers */
++static inline u8 in_idx(u16 port, u8 index)
++{
++      outb(index, port);
++      return inb(port+1);
++}
++
++static inline void out_idx(u8 v, u16 port, u8 index)
++{
++      outw(index+(v << 8), port);
++}
++
++/* Writes a value to an indexed port and then reads the port again */
++static inline u8 tst_idx(u8 v, u16 port, u8 index)
++{
++      out_idx(port, index, v);
++      return in_idx(port, index);
++}
++
++/* Get the I/O port of the VGA CRTC */
++u16 vga_crtc(void);           /* video-vga.c */
++
++#endif /* BOOT_VIDEO_H */
+diff -puN /dev/null arch/i386/boot/voyager.c
+--- /dev/null
++++ a/arch/i386/boot/voyager.c
+@@ -0,0 +1,46 @@
++/* -*- linux-c -*- ------------------------------------------------------- *
++ *
++ *   Copyright (C) 1991, 1992 Linus Torvalds
++ *   Copyright 2007 rPath, Inc. - All Rights Reserved
++ *
++ *   This file is part of the Linux kernel, and is made available under
++ *   the terms of the GNU General Public License version 2.
++ *
++ * ----------------------------------------------------------------------- */
++
++/*
++ * arch/i386/boot/voyager.c
++ *
++ * Get the Voyager config information
++ */
++
++#include "boot.h"
++
++#ifdef CONFIG_X86_VOYAGER
++
++int query_voyager(void)
++{
++      u8 err;
++      u16 es, di;
++      /* Abuse the apm_bios_info area for this */
++      u8 *data_ptr = (u8 *)&boot_params.apm_bios_info;
++
++      data_ptr[0] = 0xff;     /* Flag on config not found(?) */
++
++      asm("pushw %%es ; "
++          "int $0x15 ; "
++          "setc %0 ; "
++          "movw %%es, %1 ; "
++          "popw %%es"
++          : "=qm" (err), "=rm" (es), "=D" (di)
++          : "a" (0xffc0));
++
++      if (err)
++              return -1;      /* Not Voyager */
++
++      set_fs(es);
++      copy_from_fs(data_ptr, di, 7);  /* Table is 7 bytes apparently */
++      return 0;
++}
++
++#endif /* CONFIG_X86_VOYAGER */
+diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup arch/i386/kernel/cpu/Makefile
+diff -puN /dev/null arch/i386/kernel/cpu/addon_cpuid_features.c
+--- /dev/null
++++ a/arch/i386/kernel/cpu/addon_cpuid_features.c
+@@ -0,0 +1,50 @@
++
++/*
++ *    Routines to indentify additional cpu features that are scattered in
++ *    cpuid space.
++ */
++
++#include <linux/cpu.h>
++
++#include <asm/processor.h>
++
++struct cpuid_bit {
++      u16 feature;
++      u8 reg;
++      u8 bit;
++      u32 level;
++};
++
++enum cpuid_regs {
++      CR_EAX = 0,
++      CR_ECX,
++      CR_EDX,
++      CR_EBX
++};
++
++void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c)
++{
++      u32 max_level;
++      u32 regs[4];
++      const struct cpuid_bit *cb;
++
++      static const struct cpuid_bit cpuid_bits[] = {
++              { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006 },
++              { 0, 0, 0, 0 }
++      };
++
++      for (cb = cpuid_bits; cb->feature; cb++) {
++
++              /* Verify that the level is valid */
++              max_level = cpuid_eax(cb->level & 0xffff0000);
++              if (max_level < cb->level ||
++                  max_level > (cb->level | 0xffff))
++                      continue;
++
++              cpuid(cb->level, &regs[CR_EAX], &regs[CR_EBX],
++                      &regs[CR_ECX], &regs[CR_EDX]);
++
++              if (regs[cb->reg] & (1 << cb->bit))
++                      set_bit(cb->feature, c->x86_capability);
++      }
++}
+diff -puN arch/i386/kernel/cpu/common.c~git-newsetup arch/i386/kernel/cpu/common.c
+--- a/arch/i386/kernel/cpu/common.c~git-newsetup
++++ a/arch/i386/kernel/cpu/common.c
+@@ -353,6 +353,8 @@ static void __cpuinit generic_identify(s
+                       if ( xlvl >= 0x80000004 )
+                               get_model_name(c); /* Default name */
+               }
++
++              init_scattered_cpuid_features(c);
+       }
+       early_intel_workaround(c);
+diff -puN arch/i386/kernel/cpu/proc.c~git-newsetup arch/i386/kernel/cpu/proc.c
+--- a/arch/i386/kernel/cpu/proc.c~git-newsetup
++++ a/arch/i386/kernel/cpu/proc.c
+@@ -29,7 +29,8 @@ static int show_cpuinfo(struct seq_file 
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
+-              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext", "3dnow",
++              NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm",
++              "3dnowext", "3dnow",
+               /* Transmeta-defined */
+               "recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
+@@ -40,8 +41,9 @@ static int show_cpuinfo(struct seq_file 
+               /* Other (Linux-defined) */
+               "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
+               NULL, NULL, NULL, NULL,
+-              "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              "constant_tsc", "up", NULL, "arch_perfmon",
++              "pebs", "bts", NULL, "sync_rdtsc",
++              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               /* Intel-defined (#2) */
+@@ -57,9 +59,16 @@ static int show_cpuinfo(struct seq_file 
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               /* AMD-defined (#2) */
+-              "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8legacy", "abm",
+-              "sse4a", "misalignsse",
+-              "3dnowprefetch", "osvw", "ibs", NULL, NULL, NULL, NULL, NULL,
++              "lahf_lm", "cmp_legacy", "svm", "extapic", "cr8_legacy",
++              "altmovcr8", "abm", "sse4a",
++              "misalignsse", "3dnowprefetch",
++              "osvw", "ibs", NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++
++              /* Auxiliary (Linux-defined) */
++              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       };
+diff -puN arch/i386/kernel/e820.c~git-newsetup arch/i386/kernel/e820.c
+--- a/arch/i386/kernel/e820.c~git-newsetup
++++ a/arch/i386/kernel/e820.c
+@@ -766,7 +766,7 @@ void __init print_memory_map(char *who)
+               case E820_NVS:
+                               printk("(ACPI NVS)\n");
+                               break;
+-              default:        printk("type %lu\n", e820.map[i].type);
++              default:        printk("type %u\n", e820.map[i].type);
+                               break;
+               }
+       }
+diff -puN arch/i386/kernel/setup.c~git-newsetup arch/i386/kernel/setup.c
+--- a/arch/i386/kernel/setup.c~git-newsetup
++++ a/arch/i386/kernel/setup.c
+@@ -102,19 +102,10 @@ static unsigned int highmem_pages = -1;
+ /*
+  * Setup options
+  */
+-struct drive_info_struct { char dummy[32]; } drive_info;
+-#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \
+-    defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
+-EXPORT_SYMBOL(drive_info);
+-#endif
+ struct screen_info screen_info;
+ EXPORT_SYMBOL(screen_info);
+ struct apm_info apm_info;
+ EXPORT_SYMBOL(apm_info);
+-struct sys_desc_table_struct {
+-      unsigned short length;
+-      unsigned char table[0];
+-};
+ struct edid_info edid_info;
+ EXPORT_SYMBOL_GPL(edid_info);
+ struct ist_info ist_info;
+@@ -134,7 +125,7 @@ unsigned long saved_videomode;
+ static char __initdata command_line[COMMAND_LINE_SIZE];
+-unsigned char __initdata boot_params[PARAM_SIZE];
++struct boot_params __initdata boot_params;
+ #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+ struct edd edd;
+@@ -528,7 +519,6 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+       ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
+-      drive_info = DRIVE_INFO;
+       screen_info = SCREEN_INFO;
+       edid_info = EDID_INFO;
+       apm_info.bios = APM_BIOS_INFO;
+diff -puN arch/i386/kernel/verify_cpu.S~git-newsetup /dev/null
+--- a/arch/i386/kernel/verify_cpu.S
++++ /dev/null
+@@ -1,94 +0,0 @@
+-/* Check if CPU has some minimum CPUID bits
+-   This runs in 16bit mode so that the caller can still use the BIOS
+-   to output errors on the screen */
+-#include <asm/cpufeature.h>
+-#include <asm/msr.h>
+-
+-verify_cpu:
+-      pushfl                          # Save caller passed flags
+-      pushl   $0                      # Kill any dangerous flags
+-      popfl
+-
+-#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4
+-      pushfl
+-      pop     %eax
+-      orl     $(1<<18),%eax           # try setting AC
+-      push    %eax
+-      popfl
+-      pushfl
+-      popl    %eax
+-      testl   $(1<<18),%eax
+-      jz      bad
+-#endif
+-#if REQUIRED_MASK1 != 0
+-      pushfl                          # standard way to check for cpuid
+-      popl    %eax
+-      movl    %eax,%ebx
+-      xorl    $0x200000,%eax
+-      pushl   %eax
+-      popfl
+-      pushfl
+-      popl    %eax
+-      cmpl    %eax,%ebx
+-      pushfl                          # standard way to check for cpuid
+-      popl    %eax
+-      movl    %eax,%ebx
+-      xorl    $0x200000,%eax
+-      pushl   %eax
+-      popfl
+-      pushfl
+-      popl    %eax
+-      cmpl    %eax,%ebx
+-      jz      bad                     # REQUIRED_MASK1 != 0 requires CPUID
+-
+-      movl    $0x0,%eax               # See if cpuid 1 is implemented
+-      cpuid
+-      cmpl    $0x1,%eax
+-      jb      bad                     # no cpuid 1
+-
+-#if REQUIRED_MASK1 & NEED_CMPXCHG64
+-      /* Some VIA C3s need magic MSRs to enable CX64. Do this here */
+-      cmpl    $0x746e6543,%ebx        # Cent
+-      jne     1f
+-      cmpl    $0x48727561,%edx        # aurH
+-      jne     1f
+-      cmpl    $0x736c7561,%ecx        # auls
+-      jne     1f
+-      movl    $1,%eax                 # check model
+-      cpuid
+-      movl    %eax,%ebx
+-      shr     $8,%ebx
+-      andl    $0xf,%ebx
+-      cmp     $6,%ebx                 # check family == 6
+-      jne     1f
+-      shr     $4,%eax
+-      andl    $0xf,%eax
+-      cmpl    $6,%eax                 # check model >= 6
+-      jb      1f
+-      # assume models >= 6 all support this MSR
+-      movl    $MSR_VIA_FCR,%ecx
+-      rdmsr
+-      orl     $((1<<1)|(1<<7)),%eax   # enable CMPXCHG64 and PGE
+-      wrmsr
+-1:
+-#endif
+-      movl    $0x1,%eax               # Does the cpu have what it takes
+-      cpuid
+-
+-#if CONFIG_X86_MINIMUM_CPU_MODEL > 4
+-#error        add proper model checking here
+-#endif
+-
+-      andl    $REQUIRED_MASK1,%edx
+-      xorl    $REQUIRED_MASK1,%edx
+-      jnz     bad
+-#endif /* REQUIRED_MASK1 */
+-
+-      popfl
+-      xor     %eax,%eax
+-      ret
+-
+-bad:
+-      popfl
+-      movl    $1,%eax
+-      ret
+diff -puN arch/x86_64/Kconfig~git-newsetup arch/x86_64/Kconfig
+--- a/arch/x86_64/Kconfig~git-newsetup
++++ a/arch/x86_64/Kconfig
+@@ -453,6 +453,10 @@ config NR_CPUS
+         This is purely to save memory - each supported CPU requires
+         memory in the static kernel configuration.
++config PHYSICAL_ALIGN
++      hex
++      default "0x200000"
++
+ config HOTPLUG_CPU
+       bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)"
+       depends on SMP && HOTPLUG && EXPERIMENTAL
+diff -puN arch/x86_64/boot/Makefile~git-newsetup arch/x86_64/boot/Makefile
+--- a/arch/x86_64/boot/Makefile~git-newsetup
++++ a/arch/x86_64/boot/Makefile
+@@ -1,135 +1,9 @@
+ #
+ # arch/x86_64/boot/Makefile
+ #
+-# This file is subject to the terms and conditions of the GNU General Public
+-# License.  See the file "COPYING" in the main directory of this archive
+-# for more details.
+-#
+-# Copyright (C) 1994 by Linus Torvalds
+-#
+-
+-# ROOT_DEV specifies the default root-device when making the image.
+-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
+-# the default of FLOPPY is used by 'build'.
+-
+-ROOT_DEV := CURRENT
+-
+-# If you want to preset the SVGA mode, uncomment the next line and
+-# set SVGA_MODE to whatever number you want.
+-# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
+-# The number is the same as you would ordinarily press at bootup.
+-
+-SVGA_MODE := -DSVGA_MODE=NORMAL_VGA
+-
+-# If you want the RAM disk device, define this to be the size in blocks.
+-
+-#RAMDISK := -DRAMDISK=512
+-
+-targets               := vmlinux.bin bootsect bootsect.o \
+-                 setup setup.o bzImage mtools.conf
+-
+-EXTRA_CFLAGS := -m32
+-
+-hostprogs-y   := tools/build
+-HOST_EXTRACFLAGS += $(LINUXINCLUDE)
+-subdir-               := compressed/  #Let make clean descend in compressed/
+-# ---------------------------------------------------------------------------
+-
+-$(obj)/bzImage: IMAGE_OFFSET := 0x100000
+-$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__
+-$(obj)/bzImage: BUILDFLAGS   := -b
+-
+-quiet_cmd_image = BUILD   $@
+-cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \
+-          $(obj)/vmlinux.bin $(ROOT_DEV) > $@
+-
+-$(obj)/bzImage: $(obj)/bootsect $(obj)/setup \
+-                            $(obj)/vmlinux.bin $(obj)/tools/build FORCE
+-      $(call if_changed,image)
+-      @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+-
+-$(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE
+-      $(call if_changed,objcopy)
+-
+-LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary
+-LDFLAGS_setup  := -Ttext 0x0 -s --oformat binary -e begtext
+-
+-$(obj)/setup $(obj)/bootsect: %: %.o FORCE
+-      $(call if_changed,ld)
+-
+-$(obj)/compressed/vmlinux: FORCE
+-      $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@
+-
+-# Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel
+-FDARGS = 
+-# Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel
+-FDINITRD =
+-
+-image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,)
+-
+-$(obj)/mtools.conf: $(src)/mtools.conf.in
+-      sed -e 's|@OBJ@|$(obj)|g' < $< > $@
+-
+-# This requires write access to /dev/fd0
+-zdisk: $(BOOTIMAGE) $(obj)/mtools.conf
+-      MTOOLSRC=$(obj)/mtools.conf mformat a:                  ; sync
+-      syslinux /dev/fd0                                       ; sync
+-      echo '$(image_cmdline)' | \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg
+-      if [ -f '$(FDINITRD)' ] ; then \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \
+-      fi
+-      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux  ; sync
+-
+-# These require being root or having syslinux 2.02 or higher installed
+-fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf
+-      dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440
+-      MTOOLSRC=$(obj)/mtools.conf mformat v:                  ; sync
+-      syslinux $(obj)/fdimage                                 ; sync
+-      echo '$(image_cmdline)' | \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg
+-      if [ -f '$(FDINITRD)' ] ; then \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \
+-      fi
+-      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux  ; sync
+-
+-fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf
+-      dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880
+-      MTOOLSRC=$(obj)/mtools.conf mformat w:                  ; sync
+-      syslinux $(obj)/fdimage                                 ; sync
+-      echo '$(image_cmdline)' | \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg
+-      if [ -f '$(FDINITRD)' ] ; then \
+-              MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \
+-      fi
+-      MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux  ; sync
+-
+-isoimage: $(BOOTIMAGE)
+-      -rm -rf $(obj)/isoimage
+-      mkdir $(obj)/isoimage
+-      for i in lib lib64 share end ; do \
+-              if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
+-                      cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
+-                      break ; \
+-              fi ; \
+-              if [ $$i = end ] ; then exit 1 ; fi ; \
+-      done
+-      cp $(BOOTIMAGE) $(obj)/isoimage/linux
+-      echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg
+-      if [ -f '$(FDINITRD)' ] ; then \
+-              cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \
+-      fi
+-      mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \
+-              -no-emul-boot -boot-load-size 4 -boot-info-table \
+-              $(obj)/isoimage
+-      rm -rf $(obj)/isoimage
+-
+-zlilo: $(BOOTIMAGE)
+-      if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi
+-      if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi
+-      cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz
+-      cp System.map $(INSTALL_PATH)/
+-      if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi
++# The actual boot code is shared with i386 including the Makefile.
++# So tell kbuild that we fetch the code from i386 and include the
++# Makefile from i386 too.
+-install:
+-      sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
++src := arch/i386/boot
++include $(src)/Makefile
+diff -puN arch/x86_64/boot/bootsect.S~git-newsetup /dev/null
+--- a/arch/x86_64/boot/bootsect.S
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/*
+- *    bootsect.S              Copyright (C) 1991, 1992 Linus Torvalds
+- *
+- *    modified by Drew Eckhardt
+- *    modified by Bruce Evans (bde)
+- *    modified by Chris Noe (May 1999) (as86 -> gas)
+- *    gutted by H. Peter Anvin (Jan 2003)
+- *
+- * BIG FAT NOTE: We're in real mode using 64k segments.  Therefore segment
+- * addresses must be multiplied by 16 to obtain their respective linear
+- * addresses. To avoid confusion, linear addresses are written using leading
+- * hex while segment addresses are written as segment:offset.
+- *
+- */
+-
+-#include <asm/boot.h>
+-
+-SETUPSECTS    = 4                     /* default nr of setup-sectors */
+-BOOTSEG               = 0x07C0                /* original address of boot-sector */
+-INITSEG               = DEF_INITSEG           /* we move boot here - out of the way */
+-SETUPSEG      = DEF_SETUPSEG          /* setup starts here */
+-SYSSEG                = DEF_SYSSEG            /* system loaded at 0x10000 (65536) */
+-SYSSIZE               = DEF_SYSSIZE           /* system size: # of 16-byte clicks */
+-                                      /* to be loaded */
+-ROOT_DEV      = 0                     /* ROOT_DEV is now written by "build" */
+-SWAP_DEV      = 0                     /* SWAP_DEV is now written by "build" */
+-
+-#ifndef SVGA_MODE
+-#define SVGA_MODE ASK_VGA
+-#endif
+-
+-#ifndef RAMDISK
+-#define RAMDISK 0
+-#endif
+-
+-#ifndef ROOT_RDONLY
+-#define ROOT_RDONLY 1
+-#endif
+-
+-.code16
+-.text
+-
+-.global _start
+-_start:
+-
+-      # Normalize the start address
+-      jmpl    $BOOTSEG, $start2
+-
+-start2:
+-      movw    %cs, %ax
+-      movw    %ax, %ds
+-      movw    %ax, %es
+-      movw    %ax, %ss
+-      movw    $0x7c00, %sp
+-      sti
+-      cld
+-
+-      movw    $bugger_off_msg, %si
+-
+-msg_loop:
+-      lodsb
+-      andb    %al, %al
+-      jz      die
+-      movb    $0xe, %ah
+-      movw    $7, %bx
+-      int     $0x10
+-      jmp     msg_loop
+-
+-die:
+-      # Allow the user to press a key, then reboot
+-      xorw    %ax, %ax
+-      int     $0x16
+-      int     $0x19
+-
+-      # int 0x19 should never return.  In case it does anyway,
+-      # invoke the BIOS reset code...
+-      ljmp    $0xf000,$0xfff0
+-
+-
+-bugger_off_msg:
+-      .ascii  "Direct booting from floppy is no longer supported.\r\n"
+-      .ascii  "Please use a boot loader program instead.\r\n"
+-      .ascii  "\n"
+-      .ascii  "Remove disk and press any key to reboot . . .\r\n"
+-      .byte   0
+-
+-
+-      # Kernel attributes; used by setup
+-
+-      .org 497
+-setup_sects:  .byte SETUPSECTS
+-root_flags:   .word ROOT_RDONLY
+-syssize:      .word SYSSIZE
+-swap_dev:     .word SWAP_DEV
+-ram_size:     .word RAMDISK
+-vid_mode:     .word SVGA_MODE
+-root_dev:     .word ROOT_DEV
+-boot_flag:    .word 0xAA55
+diff -puN arch/x86_64/boot/compressed/Makefile~git-newsetup arch/x86_64/boot/compressed/Makefile
+--- a/arch/x86_64/boot/compressed/Makefile~git-newsetup
++++ a/arch/x86_64/boot/compressed/Makefile
+@@ -7,11 +7,12 @@
+ #
+ targets               := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
+-EXTRA_AFLAGS  := -traditional
+-# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
+-# -m32
+-CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2  -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin
++CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2  \
++        -fno-strict-aliasing -fPIC -mcmodel=small \
++         $(call cc-option, -ffreestanding) \
++         $(call cc-option, -fno-stack-protector)
++AFLAGS  := $(CFLAGS) -D__ASSEMBLY__
+ LDFLAGS := -m elf_x86_64
+ LDFLAGS_vmlinux := -T
+diff -puN arch/x86_64/boot/compressed/head.S~git-newsetup arch/x86_64/boot/compressed/head.S
+--- a/arch/x86_64/boot/compressed/head.S~git-newsetup
++++ a/arch/x86_64/boot/compressed/head.S
+@@ -46,10 +46,10 @@ startup_32:
+  * at and where we were actually loaded at.  This can only be done
+  * with a short local call on x86.  Nothing  else will tell us what
+  * address we are running at.  The reserved chunk of the real-mode
+- * data at 0x34-0x3f are used as the stack for this calculation.
+- * Only 4 bytes are needed.
++ * data at 0x1e4 (defined as a scratch field) are used as the stack
++ * for this calculation. Only 4 bytes are needed.
+  */
+-      leal    0x40(%esi), %esp
++      leal    (0x1e4+4)(%esi), %esp
+       call    1f
+ 1:    popl    %ebp
+       subl    $1b, %ebp
+diff -puN arch/x86_64/boot/install.sh~git-newsetup /dev/null
+--- a/arch/x86_64/boot/install.sh
++++ /dev/null
+@@ -1,2 +0,0 @@
+-#!/bin/sh
+-. $srctree/arch/i386/boot/install.sh
+diff -puN arch/x86_64/boot/mtools.conf.in~git-newsetup /dev/null
+--- a/arch/x86_64/boot/mtools.conf.in
++++ /dev/null
+@@ -1,17 +0,0 @@
+-#
+-# mtools configuration file for "make (b)zdisk"
+-#
+-
+-# Actual floppy drive
+-drive a:
+-  file="/dev/fd0"
+-
+-# 1.44 MB floppy disk image
+-drive v:
+-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter
+-
+-# 2.88 MB floppy disk image (mostly for virtual uses)
+-drive w:
+-  file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter
+-
+-
+diff -puN arch/x86_64/boot/setup.S~git-newsetup /dev/null
+--- a/arch/x86_64/boot/setup.S
++++ /dev/null
+@@ -1,826 +0,0 @@
+-/*
+- *    setup.S         Copyright (C) 1991, 1992 Linus Torvalds
+- *
+- * setup.s is responsible for getting the system data from the BIOS,
+- * and putting them into the appropriate places in system memory.
+- * both setup.s and system has been loaded by the bootblock.
+- *
+- * This code asks the bios for memory/disk/other parameters, and
+- * puts them in a "safe" place: 0x90000-0x901FF, ie where the
+- * boot-block used to be. It is then up to the protected mode
+- * system to read them from there before the area is overwritten
+- * for buffer-blocks.
+- *
+- * Move PS/2 aux init code to psaux.c
+- * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92
+- *
+- * some changes and additional features by Christoph Niemann,
+- * March 1993/June 1994 (Christoph.Niemann@linux.org)
+- *
+- * add APM BIOS checking by Stephen Rothwell, May 1994
+- * (sfr@canb.auug.org.au)
+- *
+- * High load stuff, initrd support and position independency
+- * by Hans Lermen & Werner Almesberger, February 1996
+- * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch>
+- *
+- * Video handling moved to video.S by Martin Mares, March 1996
+- * <mj@k332.feld.cvut.cz>
+- *
+- * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
+- * parsons) to avoid loadlin confusion, July 1997
+- *
+- * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
+- * <stiker@northlink.com>
+- *
+- * Fix to work around buggy BIOSes which don't use carry bit correctly
+- * and/or report extended memory in CX/DX for e801h memory size detection 
+- * call.  As a result the kernel got wrong figures.  The int15/e801h docs
+- * from Ralf Brown interrupt list seem to indicate AX/BX should be used
+- * anyway.  So to avoid breaking many machines (presumably there was a reason
+- * to orginally use CX/DX instead of AX/BX), we do a kludge to see
+- * if CX/DX have been changed in the e801 call and if so use AX/BX .
+- * Michael Miller, April 2001 <michaelm@mjmm.org>
+- *
+- * Added long mode checking and SSE force. March 2003, Andi Kleen.            
+- */
+-
+-#include <asm/segment.h>
+-#include <linux/utsrelease.h>
+-#include <linux/compile.h>
+-#include <asm/boot.h>
+-#include <asm/e820.h>
+-#include <asm/page.h>
+-#include <asm/setup.h>
+-
+-/* Signature words to ensure LILO loaded us right */
+-#define SIG1  0xAA55
+-#define SIG2  0x5A5A
+-
+-INITSEG  = DEF_INITSEG                # 0x9000, we move boot here, out of the way
+-SYSSEG   = DEF_SYSSEG         # 0x1000, system loaded at 0x10000 (65536).
+-SETUPSEG = DEF_SETUPSEG               # 0x9020, this is the current segment
+-                              # ... and the former contents of CS
+-
+-DELTA_INITSEG = SETUPSEG - INITSEG    # 0x0020
+-
+-.code16
+-.globl begtext, begdata, begbss, endtext, enddata, endbss
+-
+-.text
+-begtext:
+-.data
+-begdata:
+-.bss
+-begbss:
+-.text
+-
+-start:
+-      jmp     trampoline
+-
+-# This is the setup header, and it must start at %cs:2 (old 0x9020:2)
+-
+-              .ascii  "HdrS"          # header signature
+-              .word   0x0206          # header version number (>= 0x0105)
+-                                      # or else old loadlin-1.5 will fail)
+-realmode_swtch:       .word   0, 0            # default_switch, SETUPSEG
+-start_sys_seg:        .word   SYSSEG
+-              .word   kernel_version  # pointing to kernel version string
+-                                      # above section of header is compatible
+-                                      # with loadlin-1.5 (header v1.5). Don't
+-                                      # change it.
+-
+-type_of_loader:       .byte   0               # = 0, old one (LILO, Loadlin,
+-                                      #      Bootlin, SYSLX, bootsect...)
+-                                      # See Documentation/i386/boot.txt for
+-                                      # assigned ids
+-      
+-# flags, unused bits must be zero (RFU) bit within loadflags
+-loadflags:
+-LOADED_HIGH   = 1                     # If set, the kernel is loaded high
+-CAN_USE_HEAP  = 0x80                  # If set, the loader also has set
+-                                      # heap_end_ptr to tell how much
+-                                      # space behind setup.S can be used for
+-                                      # heap purposes.
+-                                      # Only the loader knows what is free
+-#ifndef __BIG_KERNEL__
+-              .byte   0
+-#else
+-              .byte   LOADED_HIGH
+-#endif
+-
+-setup_move_size: .word  0x8000                # size to move, when setup is not
+-                                      # loaded at 0x90000. We will move setup 
+-                                      # to 0x90000 then just before jumping
+-                                      # into the kernel. However, only the
+-                                      # loader knows how much data behind
+-                                      # us also needs to be loaded.
+-
+-code32_start:                         # here loaders can put a different
+-                                      # start address for 32-bit code.
+-#ifndef __BIG_KERNEL__
+-              .long   0x1000          #   0x1000 = default for zImage
+-#else
+-              .long   0x100000        # 0x100000 = default for big kernel
+-#endif
+-
+-ramdisk_image:        .long   0               # address of loaded ramdisk image
+-                                      # Here the loader puts the 32-bit
+-                                      # address where it loaded the image.
+-                                      # This only will be read by the kernel.
+-
+-ramdisk_size: .long   0               # its size in bytes
+-
+-bootsect_kludge:
+-              .long   0               # obsolete
+-
+-heap_end_ptr: .word   modelist+1024   # (Header version 0x0201 or later)
+-                                      # space from here (exclusive) down to
+-                                      # end of setup code can be used by setup
+-                                      # for local heap purposes.
+-
+-pad1:         .word   0
+-cmd_line_ptr: .long 0                 # (Header version 0x0202 or later)
+-                                      # If nonzero, a 32-bit pointer
+-                                      # to the kernel command line.
+-                                      # The command line should be
+-                                      # located between the start of
+-                                      # setup and the end of low
+-                                      # memory (0xa0000), or it may
+-                                      # get overwritten before it
+-                                      # gets read.  If this field is
+-                                      # used, there is no longer
+-                                      # anything magical about the
+-                                      # 0x90000 segment; the setup
+-                                      # can be located anywhere in
+-                                      # low memory 0x10000 or higher.
+-
+-ramdisk_max:  .long 0xffffffff
+-kernel_alignment:  .long 0x200000       # physical addr alignment required for
+-                                      # protected mode relocatable kernel
+-#ifdef CONFIG_RELOCATABLE
+-relocatable_kernel:    .byte 1
+-#else
+-relocatable_kernel:    .byte 0
+-#endif
+-pad2:                  .byte 0
+-pad3:                  .word 0
+-
+-cmdline_size:   .long   COMMAND_LINE_SIZE-1     #length of the command line,
+-                                                #added with boot protocol
+-                                                #version 2.06
+-
+-trampoline:   call    start_of_setup
+-              .align 16
+-                                      # The offset at this point is 0x240
+-              .space  (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff)
+-# End of setup header #####################################################
+-
+-start_of_setup:
+-# Bootlin depends on this being done early
+-      movw    $0x01500, %ax
+-      movb    $0x81, %dl
+-      int     $0x13
+-
+-#ifdef SAFE_RESET_DISK_CONTROLLER
+-# Reset the disk controller.
+-      movw    $0x0000, %ax
+-      movb    $0x80, %dl
+-      int     $0x13
+-#endif
+-
+-# Set %ds = %cs, we know that SETUPSEG = %cs at this point
+-      movw    %cs, %ax                # aka SETUPSEG
+-      movw    %ax, %ds
+-# Check signature at end of setup
+-      cmpw    $SIG1, setup_sig1
+-      jne     bad_sig
+-
+-      cmpw    $SIG2, setup_sig2
+-      jne     bad_sig
+-
+-      jmp     good_sig1
+-
+-# Routine to print asciiz string at ds:si
+-prtstr:
+-      lodsb
+-      andb    %al, %al
+-      jz      fin
+-
+-      call    prtchr
+-      jmp     prtstr
+-
+-fin:  ret
+-
+-# Space printing
+-prtsp2:       call    prtspc          # Print double space
+-prtspc:       movb    $0x20, %al      # Print single space (note: fall-thru)
+-
+-prtchr:       
+-      pushw   %ax
+-      pushw   %cx
+-      movw    $0007,%bx
+-      movw    $0x01, %cx
+-      movb    $0x0e, %ah
+-      int     $0x10
+-      popw    %cx
+-      popw    %ax
+-      ret
+-
+-beep: movb    $0x07, %al
+-      jmp     prtchr
+-      
+-no_sig_mess: .string  "No setup signature found ..."
+-
+-good_sig1:
+-      jmp     good_sig
+-
+-# We now have to find the rest of the setup code/data
+-bad_sig:
+-      movw    %cs, %ax                        # SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # INITSEG
+-      movw    %ax, %ds
+-      xorb    %bh, %bh
+-      movb    (497), %bl                      # get setup sect from bootsect
+-      subw    $4, %bx                         # LILO loads 4 sectors of setup
+-      shlw    $8, %bx                         # convert to words (1sect=2^8 words)
+-      movw    %bx, %cx
+-      shrw    $3, %bx                         # convert to segment
+-      addw    $SYSSEG, %bx
+-      movw    %bx, %cs:start_sys_seg
+-# Move rest of setup code/data to here
+-      movw    $2048, %di                      # four sectors loaded by LILO
+-      subw    %si, %si
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      movw    %ax, %es
+-      movw    $SYSSEG, %ax
+-      movw    %ax, %ds
+-      rep
+-      movsw
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      movw    %ax, %ds
+-      cmpw    $SIG1, setup_sig1
+-      jne     no_sig
+-
+-      cmpw    $SIG2, setup_sig2
+-      jne     no_sig
+-
+-      jmp     good_sig
+-
+-no_sig:
+-      lea     no_sig_mess, %si
+-      call    prtstr
+-
+-no_sig_loop:
+-      jmp     no_sig_loop
+-
+-good_sig:
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %ds
+-# Check if an old loader tries to load a big-kernel
+-      testb   $LOADED_HIGH, %cs:loadflags     # Do we have a big kernel?
+-      jz      loader_ok                       # No, no danger for old loaders.
+-
+-      cmpb    $0, %cs:type_of_loader          # Do we have a loader that
+-                                              # can deal with us?
+-      jnz     loader_ok                       # Yes, continue.
+-
+-      pushw   %cs                             # No, we have an old loader,
+-      popw    %ds                             # die. 
+-      lea     loader_panic_mess, %si
+-      call    prtstr
+-
+-      jmp     no_sig_loop
+-
+-loader_panic_mess: .string "Wrong loader, giving up..."
+-
+-loader_ok:
+-      /* check for long mode. */
+-      /* we have to do this before the VESA setup, otherwise the user
+-         can't see the error message. */
+-      
+-      pushw   %ds
+-      movw    %cs,%ax
+-      movw    %ax,%ds
+-      
+-      call verify_cpu
+-      testl %eax,%eax
+-      jz sse_ok
+-
+-no_longmode:
+-      call    beep
+-      lea     long_mode_panic,%si
+-      call    prtstr
+-no_longmode_loop:             
+-      jmp     no_longmode_loop
+-long_mode_panic:
+-      .string "Your CPU does not support long mode. Use a 32bit distribution."
+-      .byte 0
+-
+-#include "../kernel/verify_cpu.S"
+-sse_ok:
+-      popw    %ds
+-      
+-# tell BIOS we want to go to long mode
+-      movl  $0xec00,%eax      # declare target operating mode
+-      movl  $2,%ebx           # long mode
+-      int $0x15                       
+-      
+-# Get memory size (extended mem, kB)
+-
+-      xorl    %eax, %eax
+-      movl    %eax, (0x1e0)
+-#ifndef STANDARD_MEMORY_BIOS_CALL
+-      movb    %al, (E820NR)
+-# Try three different memory detection schemes.  First, try
+-# e820h, which lets us assemble a memory map, then try e801h,
+-# which returns a 32-bit memory size, and finally 88h, which
+-# returns 0-64m
+-
+-# method E820H:
+-# the memory map from hell.  e820h returns memory classified into
+-# a whole bunch of different types, and allows memory holes and
+-# everything.  We scan through this memory map and build a list
+-# of the first 32 memory areas, which we return at [E820MAP].
+-# This is documented at http://www.acpi.info/, in the ACPI 2.0 specification.
+-
+-#define SMAP  0x534d4150
+-
+-meme820:
+-      xorl    %ebx, %ebx                      # continuation counter
+-      movw    $E820MAP, %di                   # point into the whitelist
+-                                              # so we can have the bios
+-                                              # directly write into it.
+-
+-jmpe820:
+-      movl    $0x0000e820, %eax               # e820, upper word zeroed
+-      movl    $SMAP, %edx                     # ascii 'SMAP'
+-      movl    $20, %ecx                       # size of the e820rec
+-      pushw   %ds                             # data record.
+-      popw    %es
+-      int     $0x15                           # make the call
+-      jc      bail820                         # fall to e801 if it fails
+-
+-      cmpl    $SMAP, %eax                     # check the return is `SMAP'
+-      jne     bail820                         # fall to e801 if it fails
+-
+-#     cmpl    $1, 16(%di)                     # is this usable memory?
+-#     jne     again820
+-
+-      # If this is usable memory, we save it by simply advancing %di by
+-      # sizeof(e820rec).
+-      #
+-good820:
+-      movb    (E820NR), %al                   # up to 128 entries
+-      cmpb    $E820MAX, %al
+-      jae     bail820
+-
+-      incb    (E820NR)
+-      movw    %di, %ax
+-      addw    $20, %ax
+-      movw    %ax, %di
+-again820:
+-      cmpl    $0, %ebx                        # check to see if
+-      jne     jmpe820                         # %ebx is set to EOF
+-bail820:
+-
+-
+-# method E801H:
+-# memory size is in 1k chunksizes, to avoid confusing loadlin.
+-# we store the 0xe801 memory size in a completely different place,
+-# because it will most likely be longer than 16 bits.
+-# (use 1e0 because that's what Larry Augustine uses in his
+-# alternative new memory detection scheme, and it's sensible
+-# to write everything into the same place.)
+-
+-meme801:
+-      stc                                     # fix to work around buggy
+-      xorw    %cx,%cx                         # BIOSes which don't clear/set
+-      xorw    %dx,%dx                         # carry on pass/error of
+-                                              # e801h memory size call
+-                                              # or merely pass cx,dx though
+-                                              # without changing them.
+-      movw    $0xe801, %ax
+-      int     $0x15
+-      jc      mem88
+-
+-      cmpw    $0x0, %cx                       # Kludge to handle BIOSes
+-      jne     e801usecxdx                     # which report their extended
+-      cmpw    $0x0, %dx                       # memory in AX/BX rather than
+-      jne     e801usecxdx                     # CX/DX.  The spec I have read
+-      movw    %ax, %cx                        # seems to indicate AX/BX 
+-      movw    %bx, %dx                        # are more reasonable anyway...
+-
+-e801usecxdx:
+-      andl    $0xffff, %edx                   # clear sign extend
+-      shll    $6, %edx                        # and go from 64k to 1k chunks
+-      movl    %edx, (0x1e0)                   # store extended memory size
+-      andl    $0xffff, %ecx                   # clear sign extend
+-      addl    %ecx, (0x1e0)                   # and add lower memory into
+-                                              # total size.
+-
+-# Ye Olde Traditional Methode.  Returns the memory size (up to 16mb or
+-# 64mb, depending on the bios) in ax.
+-mem88:
+-
+-#endif
+-      movb    $0x88, %ah
+-      int     $0x15
+-      movw    %ax, (2)
+-
+-# Set the keyboard repeat rate to the max
+-      movw    $0x0305, %ax
+-      xorw    %bx, %bx
+-      int     $0x16
+-
+-# Check for video adapter and its parameters and allow the
+-# user to browse video modes.
+-      call    video                           # NOTE: we need %ds pointing
+-                                              # to bootsector
+-
+-# Get hd0 data...
+-      xorw    %ax, %ax
+-      movw    %ax, %ds
+-      ldsw    (4 * 0x41), %si
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      pushw   %ax
+-      movw    %ax, %es
+-      movw    $0x0080, %di
+-      movw    $0x10, %cx
+-      pushw   %cx
+-      cld
+-      rep
+-      movsb
+-# Get hd1 data...
+-      xorw    %ax, %ax
+-      movw    %ax, %ds
+-      ldsw    (4 * 0x46), %si
+-      popw    %cx
+-      popw    %es
+-      movw    $0x0090, %di
+-      rep
+-      movsb
+-# Check that there IS a hd1 :-)
+-      movw    $0x01500, %ax
+-      movb    $0x81, %dl
+-      int     $0x13
+-      jc      no_disk1
+-      
+-      cmpb    $3, %ah
+-      je      is_disk1
+-
+-no_disk1:
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %es
+-      movw    $0x0090, %di
+-      movw    $0x10, %cx
+-      xorw    %ax, %ax
+-      cld
+-      rep
+-      stosb
+-is_disk1:
+-
+-# Check for PS/2 pointing device
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ax, %ds
+-      movb    $0, (0x1ff)                     # default is no pointing device
+-      int     $0x11                           # int 0x11: equipment list
+-      testb   $0x04, %al                      # check if mouse installed
+-      jz      no_psmouse
+-
+-      movb    $0xAA, (0x1ff)                  # device present
+-no_psmouse:
+-
+-#include "../../i386/boot/edd.S"
+-
+-# Now we want to move to protected mode ...
+-      cmpw    $0, %cs:realmode_swtch
+-      jz      rmodeswtch_normal
+-
+-      lcall   *%cs:realmode_swtch
+-
+-      jmp     rmodeswtch_end
+-
+-rmodeswtch_normal:
+-        pushw %cs
+-      call    default_switch
+-
+-rmodeswtch_end:
+-# we get the code32 start address and modify the below 'jmpi'
+-# (loader may have changed it)
+-      movl    %cs:code32_start, %eax
+-      movl    %eax, %cs:code32
+-
+-# Now we move the system to its rightful place ... but we check if we have a
+-# big-kernel. In that case we *must* not move it ...
+-      testb   $LOADED_HIGH, %cs:loadflags
+-      jz      do_move0                        # .. then we have a normal low
+-                                              # loaded zImage
+-                                              # .. or else we have a high
+-                                              # loaded bzImage
+-      jmp     end_move                        # ... and we skip moving
+-
+-do_move0:
+-      movw    $0x100, %ax                     # start of destination segment
+-      movw    %cs, %bp                        # aka SETUPSEG
+-      subw    $DELTA_INITSEG, %bp             # aka INITSEG
+-      movw    %cs:start_sys_seg, %bx          # start of source segment
+-      cld
+-do_move:
+-      movw    %ax, %es                        # destination segment
+-      incb    %ah                             # instead of add ax,#0x100
+-      movw    %bx, %ds                        # source segment
+-      addw    $0x100, %bx
+-      subw    %di, %di
+-      subw    %si, %si
+-      movw    $0x800, %cx
+-      rep
+-      movsw
+-      cmpw    %bp, %bx                        # assume start_sys_seg > 0x200,
+-                                              # so we will perhaps read one
+-                                              # page more than needed, but
+-                                              # never overwrite INITSEG
+-                                              # because destination is a
+-                                              # minimum one page below source
+-      jb      do_move
+-
+-end_move:
+-# then we load the segment descriptors
+-      movw    %cs, %ax                        # aka SETUPSEG
+-      movw    %ax, %ds
+-              
+-# Check whether we need to be downward compatible with version <=201
+-      cmpl    $0, cmd_line_ptr
+-      jne     end_move_self           # loader uses version >=202 features
+-      cmpb    $0x20, type_of_loader
+-      je      end_move_self           # bootsect loader, we know of it
+-
+-# Boot loader doesnt support boot protocol version 2.02.
+-# If we have our code not at 0x90000, we need to move it there now.
+-# We also then need to move the params behind it (commandline)
+-# Because we would overwrite the code on the current IP, we move
+-# it in two steps, jumping high after the first one.
+-      movw    %cs, %ax
+-      cmpw    $SETUPSEG, %ax
+-      je      end_move_self
+-
+-      cli                                     # make sure we really have
+-                                              # interrupts disabled !
+-                                              # because after this the stack
+-                                              # should not be used
+-      subw    $DELTA_INITSEG, %ax             # aka INITSEG
+-      movw    %ss, %dx
+-      cmpw    %ax, %dx
+-      jb      move_self_1
+-
+-      addw    $INITSEG, %dx
+-      subw    %ax, %dx                        # this will go into %ss after
+-                                              # the move
+-move_self_1:
+-      movw    %ax, %ds
+-      movw    $INITSEG, %ax                   # real INITSEG
+-      movw    %ax, %es
+-      movw    %cs:setup_move_size, %cx
+-      std                                     # we have to move up, so we use
+-                                              # direction down because the
+-                                              # areas may overlap
+-      movw    %cx, %di
+-      decw    %di
+-      movw    %di, %si
+-      subw    $move_self_here+0x200, %cx
+-      rep
+-      movsb
+-      ljmp    $SETUPSEG, $move_self_here
+-
+-move_self_here:
+-      movw    $move_self_here+0x200, %cx
+-      rep
+-      movsb
+-      movw    $SETUPSEG, %ax
+-      movw    %ax, %ds
+-      movw    %dx, %ss
+-end_move_self:                                        # now we are at the right place
+-      lidt    idt_48                          # load idt with 0,0
+-      xorl    %eax, %eax                      # Compute gdt_base
+-      movw    %ds, %ax                        # (Convert %ds:gdt to a linear ptr)
+-      shll    $4, %eax
+-      addl    $gdt, %eax
+-      movl    %eax, (gdt_48+2)
+-      lgdt    gdt_48                          # load gdt with whatever is
+-                                              # appropriate
+-
+-# that was painless, now we enable a20
+-      call    empty_8042
+-
+-      movb    $0xD1, %al                      # command write
+-      outb    %al, $0x64
+-      call    empty_8042
+-
+-      movb    $0xDF, %al                      # A20 on
+-      outb    %al, $0x60
+-      call    empty_8042
+-
+-#
+-#     You must preserve the other bits here. Otherwise embarrasing things
+-#     like laptops powering off on boot happen. Corrected version by Kira
+-#     Brown from Linux 2.2
+-#
+-      inb     $0x92, %al                      # 
+-      orb     $02, %al                        # "fast A20" version
+-      outb    %al, $0x92                      # some chips have only this
+-
+-# wait until a20 really *is* enabled; it can take a fair amount of
+-# time on certain systems; Toshiba Tecras are known to have this
+-# problem.  The memory location used here (0x200) is the int 0x80
+-# vector, which should be safe to use.
+-
+-      xorw    %ax, %ax                        # segment 0x0000
+-      movw    %ax, %fs
+-      decw    %ax                             # segment 0xffff (HMA)
+-      movw    %ax, %gs
+-a20_wait:
+-      incw    %ax                             # unused memory location <0xfff0
+-      movw    %ax, %fs:(0x200)                # we use the "int 0x80" vector
+-      cmpw    %gs:(0x210), %ax                # and its corresponding HMA addr
+-      je      a20_wait                        # loop until no longer aliased
+-
+-# make sure any possible coprocessor is properly reset..
+-      xorw    %ax, %ax
+-      outb    %al, $0xf0
+-      call    delay
+-
+-      outb    %al, $0xf1
+-      call    delay
+-
+-# well, that went ok, I hope. Now we mask all interrupts - the rest
+-# is done in init_IRQ().
+-      movb    $0xFF, %al                      # mask all interrupts for now
+-      outb    %al, $0xA1
+-      call    delay
+-      
+-      movb    $0xFB, %al                      # mask all irq's but irq2 which
+-      outb    %al, $0x21                      # is cascaded
+-
+-# Well, that certainly wasn't fun :-(. Hopefully it works, and we don't
+-# need no steenking BIOS anyway (except for the initial loading :-).
+-# The BIOS-routine wants lots of unnecessary data, and it's less
+-# "interesting" anyway. This is how REAL programmers do it.
+-#
+-# Well, now's the time to actually move into protected mode. To make
+-# things as simple as possible, we do no register set-up or anything,
+-# we let the gnu-compiled 32-bit programs do that. We just jump to
+-# absolute address 0x1000 (or the loader supplied one),
+-# in 32-bit protected mode.
+-#
+-# Note that the short jump isn't strictly needed, although there are
+-# reasons why it might be a good idea. It won't hurt in any case.
+-      movw    $1, %ax                         # protected mode (PE) bit
+-      lmsw    %ax                             # This is it!
+-      jmp     flush_instr
+-
+-flush_instr:
+-      xorw    %bx, %bx                        # Flag to indicate a boot
+-      xorl    %esi, %esi                      # Pointer to real-mode code
+-      movw    %cs, %si
+-      subw    $DELTA_INITSEG, %si
+-      shll    $4, %esi                        # Convert to 32-bit pointer
+-# NOTE: For high loaded big kernels we need a
+-#     jmpi    0x100000,__KERNEL_CS
+-#
+-#     but we yet haven't reloaded the CS register, so the default size 
+-#     of the target offset still is 16 bit.
+-#     However, using an operand prefix (0x66), the CPU will properly
+-#     take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
+-#     Manual, Mixing 16-bit and 32-bit code, page 16-6)
+-
+-      .byte 0x66, 0xea                        # prefix + jmpi-opcode
+-code32:       .long   0x1000                          # will be set to 0x100000
+-                                              # for big kernels
+-      .word   __KERNEL_CS
+-
+-# Here's a bunch of information about your current kernel..
+-kernel_version:       .ascii  UTS_RELEASE
+-              .ascii  " ("
+-              .ascii  LINUX_COMPILE_BY
+-              .ascii  "@"
+-              .ascii  LINUX_COMPILE_HOST
+-              .ascii  ") "
+-              .ascii  UTS_VERSION
+-              .byte   0
+-
+-# This is the default real mode switch routine.
+-# to be called just before protected mode transition
+-default_switch:
+-      cli                                     # no interrupts allowed !
+-      movb    $0x80, %al                      # disable NMI for bootup
+-                                              # sequence
+-      outb    %al, $0x70
+-      lret
+-
+-
+-# This routine checks that the keyboard command queue is empty
+-# (after emptying the output buffers)
+-#
+-# Some machines have delusions that the keyboard buffer is always full
+-# with no keyboard attached...
+-#
+-# If there is no keyboard controller, we will usually get 0xff
+-# to all the reads.  With each IO taking a microsecond and
+-# a timeout of 100,000 iterations, this can take about half a
+-# second ("delay" == outb to port 0x80). That should be ok,
+-# and should also be plenty of time for a real keyboard controller
+-# to empty.
+-#
+-
+-empty_8042:
+-      pushl   %ecx
+-      movl    $100000, %ecx
+-
+-empty_8042_loop:
+-      decl    %ecx
+-      jz      empty_8042_end_loop
+-
+-      call    delay
+-
+-      inb     $0x64, %al                      # 8042 status port
+-      testb   $1, %al                         # output buffer?
+-      jz      no_output
+-
+-      call    delay
+-      inb     $0x60, %al                      # read it
+-      jmp     empty_8042_loop
+-
+-no_output:
+-      testb   $2, %al                         # is input buffer full?
+-      jnz     empty_8042_loop                 # yes - loop
+-empty_8042_end_loop:
+-      popl    %ecx
+-      ret
+-
+-# Read the cmos clock. Return the seconds in al
+-gettime:
+-      pushw   %cx
+-      movb    $0x02, %ah
+-      int     $0x1a
+-      movb    %dh, %al                        # %dh contains the seconds
+-      andb    $0x0f, %al
+-      movb    %dh, %ah
+-      movb    $0x04, %cl
+-      shrb    %cl, %ah
+-      aad
+-      popw    %cx
+-      ret
+-
+-# Delay is needed after doing I/O
+-delay:
+-      outb    %al,$0x80
+-      ret
+-
+-# Descriptor tables
+-gdt:
+-      .word   0, 0, 0, 0                      # dummy
+-
+-      .word   0, 0, 0, 0                      # unused
+-
+-      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
+-      .word   0                               # base address = 0
+-      .word   0x9A00                          # code read/exec
+-      .word   0x00CF                          # granularity = 4096, 386
+-                                              #  (+5th nibble of limit)
+-
+-      .word   0xFFFF                          # 4Gb - (0x100000*0x1000 = 4Gb)
+-      .word   0                               # base address = 0
+-      .word   0x9200                          # data read/write
+-      .word   0x00CF                          # granularity = 4096, 386
+-                                              #  (+5th nibble of limit)
+-gdt_end:
+-idt_48:
+-      .word   0                               # idt limit = 0
+-      .word   0, 0                            # idt base = 0L
+-gdt_48:
+-      .word   gdt_end-gdt-1                   # gdt limit
+-      .word   0, 0                            # gdt base (filled in later)
+-
+-# Include video setup & detection code
+-
+-#include "../../i386/boot/video.S"
+-
+-# Setup signature -- must be last
+-setup_sig1:   .word   SIG1
+-setup_sig2:   .word   SIG2
+-
+-# After this point, there is some free space which is used by the video mode
+-# handling code to store the temporary mode table (not used by the kernel).
+-
+-modelist:
+-
+-.text
+-endtext:
+-.data
+-enddata:
+-.bss
+-endbss:
+diff -puN arch/x86_64/boot/tools/build.c~git-newsetup /dev/null
+--- a/arch/x86_64/boot/tools/build.c
++++ /dev/null
+@@ -1,185 +0,0 @@
+-/*
+- *  Copyright (C) 1991, 1992  Linus Torvalds
+- *  Copyright (C) 1997 Martin Mares
+- */
+-
+-/*
+- * This file builds a disk-image from three different files:
+- *
+- * - bootsect: compatibility mbr which prints an error message if
+- *             someone tries to boot the kernel directly.
+- * - setup: 8086 machine code, sets up system parm
+- * - system: 80386 code for actual system
+- *
+- * It does some checking that all files are of the correct type, and
+- * just writes the result to stdout, removing headers and padding to
+- * the right amount. It also writes some system data to stderr.
+- */
+-
+-/*
+- * Changes by tytso to allow root device specification
+- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+- * Cross compiling fixes by Gertjan van Wingerde, July 1996
+- * Rewritten by Martin Mares, April 1997
+- */
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <stdlib.h>
+-#include <stdarg.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <sys/sysmacros.h>
+-#include <unistd.h>
+-#include <fcntl.h>
+-#include <asm/boot.h>
+-
+-typedef unsigned char byte;
+-typedef unsigned short word;
+-typedef unsigned long u32;
+-
+-#define DEFAULT_MAJOR_ROOT 0
+-#define DEFAULT_MINOR_ROOT 0
+-
+-/* Minimal number of setup sectors (see also bootsect.S) */
+-#define SETUP_SECTS 4
+-
+-byte buf[1024];
+-int fd;
+-int is_big_kernel;
+-
+-void die(const char * str, ...)
+-{
+-      va_list args;
+-      va_start(args, str);
+-      vfprintf(stderr, str, args);
+-      fputc('\n', stderr);
+-      exit(1);
+-}
+-
+-void file_open(const char *name)
+-{
+-      if ((fd = open(name, O_RDONLY, 0)) < 0)
+-              die("Unable to open `%s': %m", name);
+-}
+-
+-void usage(void)
+-{
+-      die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
+-}
+-
+-int main(int argc, char ** argv)
+-{
+-      unsigned int i, c, sz, setup_sectors;
+-      u32 sys_size;
+-      byte major_root, minor_root;
+-      struct stat sb;
+-
+-      if (argc > 2 && !strcmp(argv[1], "-b"))
+-        {
+-          is_big_kernel = 1;
+-          argc--, argv++;
+-        }
+-      if ((argc < 4) || (argc > 5))
+-              usage();
+-      if (argc > 4) {
+-              if (!strcmp(argv[4], "CURRENT")) {
+-                      if (stat("/", &sb)) {
+-                              perror("/");
+-                              die("Couldn't stat /");
+-                      }
+-                      major_root = major(sb.st_dev);
+-                      minor_root = minor(sb.st_dev);
+-              } else if (strcmp(argv[4], "FLOPPY")) {
+-                      if (stat(argv[4], &sb)) {
+-                              perror(argv[4]);
+-                              die("Couldn't stat root device.");
+-                      }
+-                      major_root = major(sb.st_rdev);
+-                      minor_root = minor(sb.st_rdev);
+-              } else {
+-                      major_root = 0;
+-                      minor_root = 0;
+-              }
+-      } else {
+-              major_root = DEFAULT_MAJOR_ROOT;
+-              minor_root = DEFAULT_MINOR_ROOT;
+-      }
+-      fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
+-
+-      file_open(argv[1]);
+-      i = read(fd, buf, sizeof(buf));
+-      fprintf(stderr,"Boot sector %d bytes.\n",i);
+-      if (i != 512)
+-              die("Boot block must be exactly 512 bytes");
+-      if (buf[510] != 0x55 || buf[511] != 0xaa)
+-              die("Boot block hasn't got boot flag (0xAA55)");
+-      buf[508] = minor_root;
+-      buf[509] = major_root;
+-      if (write(1, buf, 512) != 512)
+-              die("Write call failed");
+-      close (fd);
+-
+-      file_open(argv[2]);                                 /* Copy the setup code */
+-      for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
+-              if (write(1, buf, c) != c)
+-                      die("Write call failed");
+-      if (c != 0)
+-              die("read-error on `setup'");
+-      close (fd);
+-
+-      setup_sectors = (i + 511) / 512;        /* Pad unused space with zeros */
+-      /* for compatibility with ancient versions of LILO. */
+-      if (setup_sectors < SETUP_SECTS)
+-              setup_sectors = SETUP_SECTS;
+-      fprintf(stderr, "Setup is %d bytes.\n", i);
+-      memset(buf, 0, sizeof(buf));
+-      while (i < setup_sectors * 512) {
+-              c = setup_sectors * 512 - i;
+-              if (c > sizeof(buf))
+-                      c = sizeof(buf);
+-              if (write(1, buf, c) != c)
+-                      die("Write call failed");
+-              i += c;
+-      }
+-
+-      file_open(argv[3]);
+-      if (fstat (fd, &sb))
+-              die("Unable to stat `%s': %m", argv[3]);
+-      sz = sb.st_size;
+-      fprintf (stderr, "System is %d kB\n", sz/1024);
+-      sys_size = (sz + 15) / 16;
+-      if (!is_big_kernel && sys_size > DEF_SYSSIZE)
+-              die("System is too big. Try using bzImage or modules.");
+-      while (sz > 0) {
+-              int l, n;
+-
+-              l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
+-              if ((n=read(fd, buf, l)) != l) {
+-                      if (n < 0)
+-                              die("Error reading %s: %m", argv[3]);
+-                      else
+-                              die("%s: Unexpected EOF", argv[3]);
+-              }
+-              if (write(1, buf, l) != l)
+-                      die("Write failed");
+-              sz -= l;
+-      }
+-      close(fd);
+-
+-      if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
+-              die("Output: seek failed");
+-      buf[0] = setup_sectors;
+-      if (write(1, buf, 1) != 1)
+-              die("Write of setup sector count failed");
+-      if (lseek(1, 500, SEEK_SET) != 500)
+-              die("Output: seek failed");
+-      buf[0] = (sys_size & 0xff);
+-      buf[1] = ((sys_size >> 8) & 0xff);
+-      buf[2] = ((sys_size >> 16) & 0xff);
+-      buf[3] = ((sys_size >> 24) & 0xff);
+-      if (write(1, buf, 4) != 4)
+-              die("Write of image length failed");
+-
+-      return 0;                                           /* Everything is OK */
+-}
+diff -puN arch/x86_64/kernel/Makefile~git-newsetup arch/x86_64/kernel/Makefile
+--- a/arch/x86_64/kernel/Makefile~git-newsetup
++++ a/arch/x86_64/kernel/Makefile
+@@ -45,6 +45,7 @@ obj-$(CONFIG_PCI)            += early-quirks.o
+ obj-y                         += topology.o
+ obj-y                         += intel_cacheinfo.o
++obj-y                         += addon_cpuid_features.o
+ obj-y                         += pcspeaker.o
+ CFLAGS_vsyscall.o             := $(PROFILING) -g0
+@@ -58,6 +59,7 @@ cpuid-$(subst m,y,$(CONFIG_X86_CPUID))  
+ topology-y                     += ../../i386/kernel/topology.o
+ microcode-$(subst m,y,$(CONFIG_MICROCODE))  += ../../i386/kernel/microcode.o
+ intel_cacheinfo-y             += ../../i386/kernel/cpu/intel_cacheinfo.o
++addon_cpuid_features-y                += ../../i386/kernel/cpu/addon_cpuid_features.o
+ quirks-y                      += ../../i386/kernel/quirks.o
+ i8237-y                               += ../../i386/kernel/i8237.o
+ msr-$(subst m,y,$(CONFIG_X86_MSR))  += ../../i386/kernel/msr.o
+diff -puN arch/x86_64/kernel/setup.c~git-newsetup arch/x86_64/kernel/setup.c
+--- a/arch/x86_64/kernel/setup.c~git-newsetup
++++ a/arch/x86_64/kernel/setup.c
+@@ -855,6 +855,8 @@ void __cpuinit identify_cpu(struct cpuin
+                       c->x86_capability[2] = cpuid_edx(0x80860001);
+       }
++      init_scattered_cpuid_features(c);
++
+       c->apicid = phys_pkg_id(0);
+       /*
+@@ -940,7 +942,7 @@ static int show_cpuinfo(struct seq_file 
+               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+               "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
+-              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
++              "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe",
+               /* AMD-defined */
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+@@ -956,10 +958,11 @@ static int show_cpuinfo(struct seq_file 
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               /* Other (Linux-defined) */
+-              "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
+-              "constant_tsc", NULL, NULL,
+-              "up", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              "cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
++              NULL, NULL, NULL, NULL,
++              "constant_tsc", "up", NULL, "arch_perfmon",
++              "pebs", "bts", NULL, "sync_rdtsc",
++              "rep_good", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               /* Intel-defined (#2) */
+@@ -970,7 +973,7 @@ static int show_cpuinfo(struct seq_file 
+               /* VIA/Cyrix/Centaur-defined */
+               NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
+-              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              "ace2", "ace2_en", "phe", "phe_en", "pmm", "pmm_en", NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+@@ -981,6 +984,12 @@ static int show_cpuinfo(struct seq_file 
+               "osvw", "ibs", NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++
++              /* Auxiliary (Linux-defined) */
++              "ida", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+       };
+       static char *x86_power_flags[] = { 
+               "ts",   /* temperature sensor */
+diff -puN arch/x86_64/kernel/verify_cpu.S~git-newsetup arch/x86_64/kernel/verify_cpu.S
+--- a/arch/x86_64/kernel/verify_cpu.S~git-newsetup
++++ a/arch/x86_64/kernel/verify_cpu.S
+@@ -37,20 +37,6 @@ verify_cpu:
+       pushl   $0                      # Kill any dangerous flags
+       popfl
+-      /* minimum CPUID flags for x86-64 as defined by AMD */
+-#define M(x) (1<<(x))
+-#define M2(a,b) M(a)|M(b)
+-#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d)
+-
+-#define SSE_MASK \
+-      (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2))
+-#define REQUIRED_MASK1 \
+-      (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\
+-       M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\
+-       M(X86_FEATURE_FXSR))
+-#define REQUIRED_MASK2 \
+-      (M(X86_FEATURE_LM - 32))
+-
+       pushfl                          # standard way to check for cpuid
+       popl    %eax
+       movl    %eax,%ebx
+@@ -79,8 +65,8 @@ verify_cpu:
+ verify_cpu_noamd:
+       movl    $0x1,%eax               # Does the cpu have what it takes
+       cpuid
+-      andl    $REQUIRED_MASK1,%edx
+-      xorl    $REQUIRED_MASK1,%edx
++      andl    $REQUIRED_MASK0,%edx
++      xorl    $REQUIRED_MASK0,%edx
+       jnz     verify_cpu_no_longmode
+       movl    $0x80000000,%eax        # See if extended cpuid is implemented
+@@ -90,8 +76,8 @@ verify_cpu_noamd:
+       movl    $0x80000001,%eax        # Does the cpu have what it takes
+       cpuid
+-      andl    $REQUIRED_MASK2,%edx
+-      xorl    $REQUIRED_MASK2,%edx
++      andl    $REQUIRED_MASK1,%edx
++      xorl    $REQUIRED_MASK1,%edx
+       jnz     verify_cpu_no_longmode
+ verify_cpu_sse_test:
+diff -puN drivers/ide/legacy/hd.c~git-newsetup drivers/ide/legacy/hd.c
+--- a/drivers/ide/legacy/hd.c~git-newsetup
++++ a/drivers/ide/legacy/hd.c
+@@ -718,74 +718,25 @@ static int __init hd_init(void)
+       device_timer.function = hd_times_out;
+       blk_queue_hardsect_size(hd_queue, 512);
+-#ifdef __i386__
+       if (!NR_HD) {
+-              extern struct drive_info drive_info;
+-              unsigned char *BIOS = (unsigned char *) &drive_info;
+-              unsigned long flags;
+-              int cmos_disks;
+-
+-              for (drive=0 ; drive<2 ; drive++) {
+-                      hd_info[drive].cyl = *(unsigned short *) BIOS;
+-                      hd_info[drive].head = *(2+BIOS);
+-                      hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
+-                      hd_info[drive].ctl = *(8+BIOS);
+-                      hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
+-                      hd_info[drive].sect = *(14+BIOS);
+-#ifdef does_not_work_for_everybody_with_scsi_but_helps_ibm_vp
+-                      if (hd_info[drive].cyl && NR_HD == drive)
+-                              NR_HD++;
+-#endif
+-                      BIOS += 16;
+-              }
+-
+-      /*
+-              We query CMOS about hard disks : it could be that 
+-              we have a SCSI/ESDI/etc controller that is BIOS
+-              compatible with ST-506, and thus showing up in our
+-              BIOS table, but not register compatible, and therefore
+-              not present in CMOS.
+-
+-              Furthermore, we will assume that our ST-506 drives
+-              <if any> are the primary drives in the system, and 
+-              the ones reflected as drive 1 or 2.
+-
+-              The first drive is stored in the high nibble of CMOS
+-              byte 0x12, the second in the low nibble.  This will be
+-              either a 4 bit drive type or 0xf indicating use byte 0x19 
+-              for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
+-
+-              Needless to say, a non-zero value means we have 
+-              an AT controller hard disk for that drive.
+-
+-              Currently the rtc_lock is a bit academic since this
+-              driver is non-modular, but someday... ?         Paul G.
+-      */
+-
+-              spin_lock_irqsave(&rtc_lock, flags);
+-              cmos_disks = CMOS_READ(0x12);
+-              spin_unlock_irqrestore(&rtc_lock, flags);
+-
+-              if (cmos_disks & 0xf0) {
+-                      if (cmos_disks & 0x0f)
+-                              NR_HD = 2;
+-                      else
+-                              NR_HD = 1;
+-              }
+-      }
+-#endif /* __i386__ */
+-#ifdef __arm__
+-      if (!NR_HD) {
+-              /* We don't know anything about the drive.  This means
++              /*
++               * We don't know anything about the drive.  This means
+                * that you *MUST* specify the drive parameters to the
+                * kernel yourself.
++               *
++               * If we were on an i386, we used to read this info from
++               * the BIOS or CMOS.  This doesn't work all that well,
++               * since this assumes that this is a primary or secondary
++               * drive, and if we're using this legacy driver, it's
++               * probably an auxilliary controller added to recover
++               * legacy data off an ST-506 drive.  Either way, it's
++               * definitely safest to have the user explicitly specify
++               * the information.
+                */
+               printk("hd: no drives specified - use hd=cyl,head,sectors"
+                       " on kernel command line\n");
+-      }
+-#endif
+-      if (!NR_HD)
+               goto out;
++      }
+       for (drive=0 ; drive < NR_HD ; drive++) {
+               struct gendisk *disk = alloc_disk(64);
+diff -puN include/asm-i386/boot.h~git-newsetup include/asm-i386/boot.h
+--- a/include/asm-i386/boot.h~git-newsetup
++++ a/include/asm-i386/boot.h
+@@ -1,5 +1,5 @@
+-#ifndef _LINUX_BOOT_H
+-#define _LINUX_BOOT_H
++#ifndef _ASM_BOOT_H
++#define _ASM_BOOT_H
+ /* Don't touch these, unless you really know what you're doing. */
+ #define DEF_INITSEG   0x9000
+@@ -17,4 +17,4 @@
+                               + (CONFIG_PHYSICAL_ALIGN - 1)) \
+                               & ~(CONFIG_PHYSICAL_ALIGN - 1))
+-#endif /* _LINUX_BOOT_H */
++#endif /* _ASM_BOOT_H */
+diff -puN /dev/null include/asm-i386/bootparam.h
+--- /dev/null
++++ a/include/asm-i386/bootparam.h
+@@ -0,0 +1,85 @@
++#ifndef _ASM_BOOTPARAM_H
++#define _ASM_BOOTPARAM_H
++
++#include <linux/types.h>
++#include <linux/screen_info.h>
++#include <linux/apm_bios.h>
++#include <asm/e820.h>
++#include <linux/edd.h>
++#include <video/edid.h>
++
++struct setup_header {
++      u8      setup_sects;
++      u16     root_flags;
++      u32     syssize;
++      u16     ram_size;
++      u16     vid_mode;
++      u16     root_dev;
++      u16     boot_flag;
++      u16     jump;
++      u32     header;
++      u16     version;
++      u32     realmode_swtch;
++      u16     start_sys;
++      u16     kernel_version;
++      u8      type_of_loader;
++      u8      loadflags;
++#define LOADED_HIGH   0x01
++#define CAN_USE_HEAP  0x80
++      u16     setup_move_size;
++      u32     code32_start;
++      u32     ramdisk_image;
++      u32     ramdisk_size;
++      u32     bootsect_kludge;
++      u16     heap_end_ptr;
++      u16     _pad1;
++      u32     cmd_line_ptr;
++      u32     initrd_addr_max;
++      u32     kernel_alignment;
++      u8      relocatable_kernel;
++} __attribute__((packed));
++
++struct sys_desc_table {
++      u16 length;
++      u8  table[14];
++};
++
++struct efi_info {
++      u32 _pad1;
++      u32 efi_systab;
++      u32 efi_memdesc_size;
++      u32 efi_memdec_version;
++      u32 efi_memmap;
++      u32 fi_memmap_size;
++      u32 _pad2[2];
++};
++
++/* The so-called "zeropage" */
++struct boot_params {
++      struct screen_info screen_info;                 /* 0x000 */
++      struct apm_bios_info apm_bios_info;             /* 0x040 */
++      u8  _pad2[12];                                  /* 0x054 */
++      u32 speedstep_info[4];                          /* 0x060 */
++      u8  _pad3[16];                                  /* 0x070 */
++      u8  hd0_info[16];       /* obsolete! */         /* 0x080 */
++      u8  hd1_info[16];       /* obsolete! */         /* 0x090 */
++      struct sys_desc_table sys_desc_table;           /* 0x0a0 */
++      u8  _pad4[144];                                 /* 0x0b0 */
++      struct edid_info edid_info;                     /* 0x140 */
++      struct efi_info efi_info;                       /* 0x1c0 */
++      u32 alt_mem_k;                                  /* 0x1e0 */
++      u32 scratch;            /* Scratch field! */    /* 0x1e4 */
++      u8  e820_entries;                               /* 0x1e8 */
++      u8  eddbuf_entries;                             /* 0x1e9 */
++      u8  edd_mbr_sig_buf_entries;                    /* 0x1ea */
++      u8  _pad6[6];                                   /* 0x1eb */
++      struct setup_header hdr;    /* setup header */  /* 0x1f1 */
++      u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
++      u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];        /* 0x290 */
++      struct e820entry e820_map[E820MAX];             /* 0x2d0 */
++      u8  _pad8[48];                                  /* 0xcd0 */
++      struct edd_info eddbuf[EDDMAXNR];               /* 0xd00 */
++      u8  _pad9[276];                                 /* 0xeec */
++} __attribute__((packed));
++
++#endif /* _ASM_BOOTPARAM_H */
+diff -puN include/asm-i386/cpufeature.h~git-newsetup include/asm-i386/cpufeature.h
+--- a/include/asm-i386/cpufeature.h~git-newsetup
++++ a/include/asm-i386/cpufeature.h
+@@ -12,7 +12,7 @@
+ #endif
+ #include <asm/required-features.h>
+-#define NCAPINTS      7       /* N 32-bit words worth of info */
++#define NCAPINTS      8       /* N 32-bit words worth of info */
+ /* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
+ #define X86_FEATURE_FPU               (0*32+ 0) /* Onboard FPU */
+@@ -81,6 +81,7 @@
+ #define X86_FEATURE_BTS               (3*32+13)  /* Branch Trace Store */
+ #define X86_FEATURE_LAPIC_TIMER_BROKEN (3*32+ 14) /* lapic timer broken in C1 */
+ #define X86_FEATURE_SYNC_RDTSC        (3*32+15)  /* RDTSC synchronizes the CPU */
++#define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
+ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+ #define X86_FEATURE_XMM3      (4*32+ 0) /* Streaming SIMD Extensions-3 */
+@@ -108,11 +109,24 @@
+ #define X86_FEATURE_LAHF_LM   (6*32+ 0) /* LAHF/SAHF in long mode */
+ #define X86_FEATURE_CMP_LEGACY        (6*32+ 1) /* If yes HyperThreading not valid */
+-#define cpu_has(c, bit)                                       \
+-      ((__builtin_constant_p(bit) && (bit) < 32 &&    \
+-              (1UL << (bit)) & REQUIRED_MASK1) ?      \
+-              1 :                                     \
+-      test_bit(bit, (c)->x86_capability))
++/*
++ * Auxiliary flags: Linux defined - For features scattered in various
++ * CPUID levels like 0x6, 0xA etc
++ */
++#define X86_FEATURE_IDA               (7*32+ 0) /* Intel Dynamic Acceleration */
++
++#define cpu_has(c, bit)                                                       \
++      (__builtin_constant_p(bit) &&                                   \
++       ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||     \
++         (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||     \
++         (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||     \
++         (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) ||     \
++         (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) ||     \
++         (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) ||     \
++         (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||     \
++         (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) )      \
++        ? 1 :                                                         \
++        test_bit(bit, (c)->x86_capability))
+ #define boot_cpu_has(bit)     cpu_has(&boot_cpu_data, bit)
+ #define cpu_has_fpu           boot_cpu_has(X86_FEATURE_FPU)
+diff -puN include/asm-i386/e820.h~git-newsetup include/asm-i386/e820.h
+--- a/include/asm-i386/e820.h~git-newsetup
++++ a/include/asm-i386/e820.h
+@@ -25,13 +25,15 @@
+ #ifndef __ASSEMBLY__
++struct e820entry {
++      u64 addr;       /* start of memory segment */
++      u64 size;       /* size of memory segment */
++      u32 type;       /* type of memory segment */
++} __attribute__((packed));
++
+ struct e820map {
+-    int nr_map;
+-    struct e820entry {
+-      unsigned long long addr;        /* start of memory segment */
+-      unsigned long long size;        /* size of memory segment */
+-      unsigned long type;             /* type of memory segment */
+-    } map[E820MAX];
++      u32 nr_map;
++      struct e820entry map[E820MAX];
+ };
+ extern struct e820map e820;
+diff -puN include/asm-i386/processor.h~git-newsetup include/asm-i386/processor.h
+--- a/include/asm-i386/processor.h~git-newsetup
++++ a/include/asm-i386/processor.h
+@@ -118,6 +118,7 @@ void __init cpu_detect(struct cpuinfo_x8
+ extern void identify_boot_cpu(void);
+ extern void identify_secondary_cpu(struct cpuinfo_x86 *);
+ extern void print_cpu_info(struct cpuinfo_x86 *);
++extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
+ extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+ extern unsigned short num_cache_leaves;
+diff -puN include/asm-i386/required-features.h~git-newsetup include/asm-i386/required-features.h
+--- a/include/asm-i386/required-features.h~git-newsetup
++++ a/include/asm-i386/required-features.h
+@@ -3,7 +3,7 @@
+ /* Define minimum CPUID feature set for kernel These bits are checked
+    really early to actually display a visible error message before the
+-   kernel dies.  Only add word 0 bits here
++   kernel dies.  Make sure to assign features to the proper mask!
+    Some requirements that are not in CPUID yet are also in the
+    CONFIG_X86_MINIMUM_CPU mode which is checked too.
+@@ -11,24 +11,45 @@
+    The real information is in arch/i386/Kconfig.cpu, this just converts
+    the CONFIGs into a bitmask */
++#ifndef CONFIG_MATH_EMULATION
++# define NEED_FPU     (1<<(X86_FEATURE_FPU & 31))
++#else
++# define NEED_FPU     0
++#endif
++
+ #ifdef CONFIG_X86_PAE
+-#define NEED_PAE      (1<<X86_FEATURE_PAE)
++# define NEED_PAE     (1<<(X86_FEATURE_PAE & 31))
+ #else
+-#define NEED_PAE      0
++# define NEED_PAE     0
+ #endif
+ #ifdef CONFIG_X86_CMOV
+-#define NEED_CMOV     (1<<X86_FEATURE_CMOV)
++# define NEED_CMOV    (1<<(X86_FEATURE_CMOV & 31))
+ #else
+-#define NEED_CMOV     0
++# define NEED_CMOV    0
+ #endif
+ #ifdef CONFIG_X86_CMPXCHG64
+-#define NEED_CMPXCHG64  (1<<X86_FEATURE_CX8)
++# define NEED_CX8     (1<<(X86_FEATURE_CX8 & 31))
++#else
++# define NEED_CX8     0
++#endif
++
++#define REQUIRED_MASK0        (NEED_FPU|NEED_PAE|NEED_CMOV|NEED_CX8)
++
++#ifdef CONFIG_X86_USE_3DNOW
++# define NEED_3DNOW   (1<<(X86_FEATURE_3DNOW & 31))
+ #else
+-#define NEED_CMPXCHG64  0
++# define NEED_3DNOW   0
+ #endif
+-#define REQUIRED_MASK1        (NEED_PAE|NEED_CMOV|NEED_CMPXCHG64)
++#define REQUIRED_MASK1        (NEED_3DNOW)
++
++#define REQUIRED_MASK2        0
++#define REQUIRED_MASK3        0
++#define REQUIRED_MASK4        0
++#define REQUIRED_MASK5        0
++#define REQUIRED_MASK6        0
++#define REQUIRED_MASK7        0
+ #endif
+diff -puN include/asm-i386/setup.h~git-newsetup include/asm-i386/setup.h
+--- a/include/asm-i386/setup.h~git-newsetup
++++ a/include/asm-i386/setup.h
+@@ -26,12 +26,15 @@
+ #define NEW_CL_POINTER                0x228   /* Relative to real mode data */
+ #ifndef __ASSEMBLY__
++
++#include <asm/bootparam.h>
++
+ /*
+  * This is set up by the setup-routine at boot-time
+  */
+-extern unsigned char boot_params[PARAM_SIZE];
++extern struct boot_params boot_params;
+-#define PARAM (boot_params)
++#define PARAM ((char *)&boot_params)
+ #define SCREEN_INFO (*(struct screen_info *) (PARAM+0))
+ #define EXT_MEM_K (*(unsigned short *) (PARAM+2))
+ #define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+@@ -39,8 +42,7 @@ extern unsigned char boot_params[PARAM_S
+ #define E820_MAP    ((struct e820entry *) (PARAM+E820MAP))
+ #define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+0x40))
+ #define IST_INFO   (*(struct ist_info *) (PARAM+0x60))
+-#define DRIVE_INFO (*(struct drive_info_struct *) (PARAM+0x80))
+-#define SYS_DESC_TABLE (*(struct sys_desc_table_struct*)(PARAM+0xa0))
++#define SYS_DESC_TABLE (*(struct sys_desc_table *)(PARAM+0xa0))
+ #define EFI_SYSTAB ((efi_system_table_t *) *((unsigned long *)(PARAM+0x1c4)))
+ #define EFI_MEMDESC_SIZE (*((unsigned long *) (PARAM+0x1c8)))
+ #define EFI_MEMDESC_VERSION (*((unsigned long *) (PARAM+0x1cc)))
+diff -puN include/asm-x86_64/alternative.h~git-newsetup include/asm-x86_64/alternative.h
+--- a/include/asm-x86_64/alternative.h~git-newsetup
++++ a/include/asm-x86_64/alternative.h
+@@ -5,6 +5,41 @@
+ #include <linux/types.h>
+ #include <linux/stddef.h>
++
++/*
++ * Alternative inline assembly for SMP.
++ *
++ * The LOCK_PREFIX macro defined here replaces the LOCK and
++ * LOCK_PREFIX macros used everywhere in the source tree.
++ *
++ * SMP alternatives use the same data structures as the other
++ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
++ * UP system running a SMP kernel.  The existing apply_alternatives()
++ * works fine for patching a SMP kernel for UP.
++ *
++ * The SMP alternative tables can be kept after boot and contain both
++ * UP and SMP versions of the instructions to allow switching back to
++ * SMP at runtime, when hotplugging in a new CPU, which is especially
++ * useful in virtualized environments.
++ *
++ * The very common lock prefix is handled as special case in a
++ * separate table which is a pure address list without replacement ptr
++ * and size information.  That keeps the table sizes small.
++ */
++
++#ifdef CONFIG_SMP
++#define LOCK_PREFIX \
++              ".section .smp_locks,\"a\"\n"   \
++              "  .align 8\n"                  \
++              "  .quad 661f\n" /* address */  \
++              ".previous\n"                   \
++              "661:\n\tlock; "
++
++#else /* ! CONFIG_SMP */
++#define LOCK_PREFIX ""
++#endif
++
++/* This must be included *after* the definition of LOCK_PREFIX */
+ #include <asm/cpufeature.h>
+ struct alt_instr {
+@@ -108,39 +143,6 @@ static inline void alternatives_smp_swit
+  */
+ #define ASM_OUTPUT2(a, b) a, b
+-/*
+- * Alternative inline assembly for SMP.
+- *
+- * The LOCK_PREFIX macro defined here replaces the LOCK and
+- * LOCK_PREFIX macros used everywhere in the source tree.
+- *
+- * SMP alternatives use the same data structures as the other
+- * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+- * UP system running a SMP kernel.  The existing apply_alternatives()
+- * works fine for patching a SMP kernel for UP.
+- *
+- * The SMP alternative tables can be kept after boot and contain both
+- * UP and SMP versions of the instructions to allow switching back to
+- * SMP at runtime, when hotplugging in a new CPU, which is especially
+- * useful in virtualized environments.
+- *
+- * The very common lock prefix is handled as special case in a
+- * separate table which is a pure address list without replacement ptr
+- * and size information.  That keeps the table sizes small.
+- */
+-
+-#ifdef CONFIG_SMP
+-#define LOCK_PREFIX \
+-              ".section .smp_locks,\"a\"\n"   \
+-              "  .align 8\n"                  \
+-              "  .quad 661f\n" /* address */  \
+-              ".previous\n"                   \
+-              "661:\n\tlock; "
+-
+-#else /* ! CONFIG_SMP */
+-#define LOCK_PREFIX ""
+-#endif
+-
+ struct paravirt_patch;
+ #ifdef CONFIG_PARAVIRT
+ void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end);
+diff -puN include/asm-x86_64/boot.h~git-newsetup include/asm-x86_64/boot.h
+--- a/include/asm-x86_64/boot.h~git-newsetup
++++ a/include/asm-x86_64/boot.h
+@@ -1,15 +1 @@
+-#ifndef _LINUX_BOOT_H
+-#define _LINUX_BOOT_H
+-
+-/* Don't touch these, unless you really know what you're doing. */
+-#define DEF_INITSEG   0x9000
+-#define DEF_SYSSEG    0x1000
+-#define DEF_SETUPSEG  0x9020
+-#define DEF_SYSSIZE   0x7F00
+-
+-/* Internal svga startup constants */
+-#define NORMAL_VGA    0xffff          /* 80x25 mode */
+-#define EXTENDED_VGA  0xfffe          /* 80x50 mode */
+-#define ASK_VGA               0xfffd          /* ask for it at bootup */
+-
+-#endif
++#include <asm-i386/boot.h>
+diff -puN /dev/null include/asm-x86_64/bootparam.h
+--- /dev/null
++++ a/include/asm-x86_64/bootparam.h
+@@ -0,0 +1 @@
++#include <asm-i386/bootparam.h>
+diff -puN include/asm-x86_64/cpufeature.h~git-newsetup include/asm-x86_64/cpufeature.h
+--- a/include/asm-x86_64/cpufeature.h~git-newsetup
++++ a/include/asm-x86_64/cpufeature.h
+@@ -7,115 +7,24 @@
+ #ifndef __ASM_X8664_CPUFEATURE_H
+ #define __ASM_X8664_CPUFEATURE_H
+-#define NCAPINTS      7       /* N 32-bit words worth of info */
++#include <asm-i386/cpufeature.h>
+-/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
+-#define X86_FEATURE_FPU               (0*32+ 0) /* Onboard FPU */
+-#define X86_FEATURE_VME               (0*32+ 1) /* Virtual Mode Extensions */
+-#define X86_FEATURE_DE                (0*32+ 2) /* Debugging Extensions */
+-#define X86_FEATURE_PSE       (0*32+ 3) /* Page Size Extensions */
+-#define X86_FEATURE_TSC               (0*32+ 4) /* Time Stamp Counter */
+-#define X86_FEATURE_MSR               (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
+-#define X86_FEATURE_PAE               (0*32+ 6) /* Physical Address Extensions */
+-#define X86_FEATURE_MCE               (0*32+ 7) /* Machine Check Architecture */
+-#define X86_FEATURE_CX8               (0*32+ 8) /* CMPXCHG8 instruction */
+-#define X86_FEATURE_APIC      (0*32+ 9) /* Onboard APIC */
+-#define X86_FEATURE_SEP               (0*32+11) /* SYSENTER/SYSEXIT */
+-#define X86_FEATURE_MTRR      (0*32+12) /* Memory Type Range Registers */
+-#define X86_FEATURE_PGE               (0*32+13) /* Page Global Enable */
+-#define X86_FEATURE_MCA               (0*32+14) /* Machine Check Architecture */
+-#define X86_FEATURE_CMOV      (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
+-#define X86_FEATURE_PAT               (0*32+16) /* Page Attribute Table */
+-#define X86_FEATURE_PSE36     (0*32+17) /* 36-bit PSEs */
+-#define X86_FEATURE_PN                (0*32+18) /* Processor serial number */
+-#define X86_FEATURE_CLFLSH    (0*32+19) /* Supports the CLFLUSH instruction */
+-#define X86_FEATURE_DS                (0*32+21) /* Debug Store */
+-#define X86_FEATURE_ACPI      (0*32+22) /* ACPI via MSR */
+-#define X86_FEATURE_MMX               (0*32+23) /* Multimedia Extensions */
+-#define X86_FEATURE_FXSR      (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
+-                                        /* of FPU context), and CR4.OSFXSR available */
+-#define X86_FEATURE_XMM               (0*32+25) /* Streaming SIMD Extensions */
+-#define X86_FEATURE_XMM2      (0*32+26) /* Streaming SIMD Extensions-2 */
+-#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
+-#define X86_FEATURE_HT                (0*32+28) /* Hyper-Threading */
+-#define X86_FEATURE_ACC               (0*32+29) /* Automatic clock control */
+-#define X86_FEATURE_IA64      (0*32+30) /* IA-64 processor */
+-
+-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+-/* Don't duplicate feature flags which are redundant with Intel! */
+-#define X86_FEATURE_SYSCALL   (1*32+11) /* SYSCALL/SYSRET */
+-#define X86_FEATURE_MMXEXT    (1*32+22) /* AMD MMX extensions */
+-#define X86_FEATURE_FXSR_OPT  (1*32+25) /* FXSR optimizations */
+-#define X86_FEATURE_RDTSCP    (1*32+27) /* RDTSCP */
+-#define X86_FEATURE_LM                (1*32+29) /* Long Mode (x86-64) */
+-#define X86_FEATURE_3DNOWEXT  (1*32+30) /* AMD 3DNow! extensions */
+-#define X86_FEATURE_3DNOW     (1*32+31) /* 3DNow! */
+-
+-/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+-#define X86_FEATURE_RECOVERY  (2*32+ 0) /* CPU in recovery mode */
+-#define X86_FEATURE_LONGRUN   (2*32+ 1) /* Longrun power control */
+-#define X86_FEATURE_LRTI      (2*32+ 3) /* LongRun table interface */
+-
+-/* Other features, Linux-defined mapping, word 3 */
+-/* This range is used for feature bits which conflict or are synthesized */
+-#define X86_FEATURE_CXMMX     (3*32+ 0) /* Cyrix MMX extensions */
+-#define X86_FEATURE_K6_MTRR   (3*32+ 1) /* AMD K6 nonstandard MTRRs */
+-#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
+-#define X86_FEATURE_CENTAUR_MCR       (3*32+ 3) /* Centaur MCRs (= MTRRs) */
+-#define X86_FEATURE_REP_GOOD  (3*32+ 4) /* rep microcode works well on this CPU */
+-#define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
+-#define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
+-#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
+-#define X86_FEATURE_UP                (3*32+8) /* SMP kernel running on UP */
+-#define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */
+-#define X86_FEATURE_PEBS      (3*32+10) /* Precise-Event Based Sampling */
+-#define X86_FEATURE_BTS               (3*32+11) /* Branch Trace Store */
+-
+-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+-#define X86_FEATURE_XMM3      (4*32+ 0) /* Streaming SIMD Extensions-3 */
+-#define X86_FEATURE_MWAIT     (4*32+ 3) /* Monitor/Mwait support */
+-#define X86_FEATURE_DSCPL     (4*32+ 4) /* CPL Qualified Debug Store */
+-#define X86_FEATURE_EST               (4*32+ 7) /* Enhanced SpeedStep */
+-#define X86_FEATURE_TM2               (4*32+ 8) /* Thermal Monitor 2 */
+-#define X86_FEATURE_CID               (4*32+10) /* Context ID */
+-#define X86_FEATURE_CX16      (4*32+13) /* CMPXCHG16B */
+-#define X86_FEATURE_XTPR      (4*32+14) /* Send Task Priority Messages */
+-
+-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+-#define X86_FEATURE_XSTORE    (5*32+ 2) /* on-CPU RNG present (xstore insn) */
+-#define X86_FEATURE_XSTORE_EN (5*32+ 3) /* on-CPU RNG enabled */
+-#define X86_FEATURE_XCRYPT    (5*32+ 6) /* on-CPU crypto (xcrypt insn) */
+-#define X86_FEATURE_XCRYPT_EN (5*32+ 7) /* on-CPU crypto enabled */
+-
+-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+-#define X86_FEATURE_LAHF_LM   (6*32+ 0) /* LAHF/SAHF in long mode */
+-#define X86_FEATURE_CMP_LEGACY        (6*32+ 1) /* If yes HyperThreading not valid */
+-
+-#define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
+-#define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
+-
+-#define cpu_has_fpu            1
++#undef  cpu_has_vme
+ #define cpu_has_vme            0
+-#define cpu_has_de             1
+-#define cpu_has_pse            1
+-#define cpu_has_tsc            1
++
++#undef  cpu_has_pae
+ #define cpu_has_pae            ___BUG___
+-#define cpu_has_pge            1
+-#define cpu_has_apic           boot_cpu_has(X86_FEATURE_APIC)
+-#define cpu_has_mtrr           1
+-#define cpu_has_mmx            1
+-#define cpu_has_fxsr           1
+-#define cpu_has_xmm            1
+-#define cpu_has_xmm2           1
+-#define cpu_has_xmm3           boot_cpu_has(X86_FEATURE_XMM3)
+-#define cpu_has_ht             boot_cpu_has(X86_FEATURE_HT)
++
++#undef  cpu_has_mp
+ #define cpu_has_mp             1 /* XXX */
++
++#undef  cpu_has_k6_mtrr
+ #define cpu_has_k6_mtrr        0
++
++#undef  cpu_has_cyrix_arr
+ #define cpu_has_cyrix_arr      0
++
++#undef  cpu_has_centaur_mcr
+ #define cpu_has_centaur_mcr    0
+-#define cpu_has_clflush              boot_cpu_has(X86_FEATURE_CLFLSH)
+-#define cpu_has_ds           boot_cpu_has(X86_FEATURE_DS)
+-#define cpu_has_pebs         boot_cpu_has(X86_FEATURE_PEBS)
+-#define cpu_has_bts          boot_cpu_has(X86_FEATURE_BTS)
+ #endif /* __ASM_X8664_CPUFEATURE_H */
+diff -puN include/asm-x86_64/e820.h~git-newsetup include/asm-x86_64/e820.h
+--- a/include/asm-x86_64/e820.h~git-newsetup
++++ a/include/asm-x86_64/e820.h
+@@ -11,7 +11,9 @@
+ #ifndef __E820_HEADER
+ #define __E820_HEADER
+-#include <linux/mmzone.h>
++#ifndef _SETUP
++# include <linux/mmzone.h>
++#endif
+ #define E820MAP       0x2d0           /* our map */
+ #define E820MAX       128             /* number of entries in E820MAP */
+@@ -30,7 +32,7 @@ struct e820entry {
+ } __attribute__((packed));
+ struct e820map {
+-    int nr_map;
++      u32 nr_map;
+       struct e820entry map[E820MAX];
+ };
+diff -puN include/asm-x86_64/processor.h~git-newsetup include/asm-x86_64/processor.h
+--- a/include/asm-x86_64/processor.h~git-newsetup
++++ a/include/asm-x86_64/processor.h
+@@ -99,6 +99,7 @@ extern char ignore_irq13;
+ extern void identify_cpu(struct cpuinfo_x86 *);
+ extern void print_cpu_info(struct cpuinfo_x86 *);
++extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
+ extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+ extern unsigned short num_cache_leaves;
+@@ -367,8 +368,6 @@ static inline void sync_core(void)
+       asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
+ } 
+-#define cpu_has_fpu 1
+-
+ #define ARCH_HAS_PREFETCH
+ static inline void prefetch(void *x) 
+ { 
+diff -puN /dev/null include/asm-x86_64/required-features.h
+--- /dev/null
++++ a/include/asm-x86_64/required-features.h
+@@ -0,0 +1,46 @@
++#ifndef _ASM_REQUIRED_FEATURES_H
++#define _ASM_REQUIRED_FEATURES_H 1
++
++/* Define minimum CPUID feature set for kernel These bits are checked
++   really early to actually display a visible error message before the
++   kernel dies.  Make sure to assign features to the proper mask!
++
++   The real information is in arch/x86_64/Kconfig.cpu, this just converts
++   the CONFIGs into a bitmask */
++
++/* x86-64 baseline features */
++#define NEED_FPU      (1<<(X86_FEATURE_FPU & 31))
++#define NEED_PSE      (1<<(X86_FEATURE_PSE & 31))
++#define NEED_MSR      (1<<(X86_FEATURE_MSR & 31))
++#define NEED_PAE      (1<<(X86_FEATURE_PAE & 31))
++#define NEED_CX8      (1<<(X86_FEATURE_CX8 & 31))
++#define NEED_PGE      (1<<(X86_FEATURE_PGE & 31))
++#define NEED_FXSR     (1<<(X86_FEATURE_FXSR & 31))
++#define NEED_CMOV     (1<<(X86_FEATURE_CMOV & 31))
++#define NEED_XMM      (1<<(X86_FEATURE_XMM & 31))
++#define NEED_XMM2     (1<<(X86_FEATURE_XMM2 & 31))
++
++#define REQUIRED_MASK0        (NEED_FPU|NEED_PSE|NEED_MSR|NEED_PAE|\
++                       NEED_CX8|NEED_PGE|NEED_FXSR|NEED_CMOV|\
++                       NEED_XMM|NEED_XMM2)
++#define SSE_MASK      (NEED_XMM|NEED_XMM2)
++
++/* x86-64 baseline features */
++#define NEED_LM               (1<<(X86_FEATURE_LM & 31))
++
++#ifdef CONFIG_X86_USE_3DNOW
++# define NEED_3DNOW   (1<<(X86_FEATURE_3DNOW & 31))
++#else
++# define NEED_3DNOW   0
++#endif
++
++#define REQUIRED_MASK1        (NEED_LM|NEED_3DNOW)
++
++#define REQUIRED_MASK2        0
++#define REQUIRED_MASK3        0
++#define REQUIRED_MASK4        0
++#define REQUIRED_MASK5        0
++#define REQUIRED_MASK6        0
++#define REQUIRED_MASK7        0
++
++#endif
+diff -puN include/asm-x86_64/segment.h~git-newsetup include/asm-x86_64/segment.h
+--- a/include/asm-x86_64/segment.h~git-newsetup
++++ a/include/asm-x86_64/segment.h
+@@ -3,6 +3,14 @@
+ #include <asm/cache.h>
++/* Simple and small GDT entries for booting only */
++
++#define GDT_ENTRY_BOOT_CS             2
++#define __BOOT_CS     (GDT_ENTRY_BOOT_CS * 8)
++
++#define GDT_ENTRY_BOOT_DS             (GDT_ENTRY_BOOT_CS + 1)
++#define __BOOT_DS     (GDT_ENTRY_BOOT_DS * 8)
++
+ #define __KERNEL_CS   0x10
+ #define __KERNEL_DS   0x18
+diff -puN include/linux/edd.h~git-newsetup include/linux/edd.h
+--- a/include/linux/edd.h~git-newsetup
++++ a/include/linux/edd.h
+@@ -49,10 +49,6 @@
+ #define EDD_MBR_SIG_MAX 16        /* max number of signatures to store */
+ #define EDD_MBR_SIG_NR_BUF 0x1ea  /* addr of number of MBR signtaures at EDD_MBR_SIG_BUF
+                                    in boot_params - treat this as 1 byte  */
+-#define EDD_CL_EQUALS   0x3d646465     /* "edd=" */
+-#define EDD_CL_OFF      0x666f         /* "of" for off  */
+-#define EDD_CL_SKIP     0x6b73         /* "sk" for skipmbr */
+-#define EDD_CL_ON       0x6e6f               /* "on" for on */
+ #ifndef __ASSEMBLY__
+diff -puN include/linux/screen_info.h~git-newsetup include/linux/screen_info.h
+--- a/include/linux/screen_info.h~git-newsetup
++++ a/include/linux/screen_info.h
+@@ -10,7 +10,7 @@
+ struct screen_info {
+       u8  orig_x;             /* 0x00 */
+       u8  orig_y;             /* 0x01 */
+-      u16 dontuse1;           /* 0x02 -- EXT_MEM_K sits here */
++      u16 ext_mem_k;          /* 0x02 */
+       u16 orig_video_page;    /* 0x04 */
+       u8  orig_video_mode;    /* 0x06 */
+       u8  orig_video_cols;    /* 0x07 */
+@@ -27,7 +27,7 @@ struct screen_info {
+       u16 lfb_depth;          /* 0x16 */
+       u32 lfb_base;           /* 0x18 */
+       u32 lfb_size;           /* 0x1c */
+-      u16 dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */
++      u16 cl_magic, cl_offset; /* 0x20 */
+       u16 lfb_linelength;     /* 0x24 */
+       u8  red_size;           /* 0x26 */
+       u8  red_pos;            /* 0x27 */
+@@ -42,9 +42,8 @@ struct screen_info {
+       u16 pages;              /* 0x32 */
+       u16 vesa_attributes;    /* 0x34 */
+       u32 capabilities;       /* 0x36 */
+-                              /* 0x3a -- 0x3b reserved for future expansion */
+-                              /* 0x3c -- 0x3f micro stack for relocatable kernels */
+-};
++      u8  _reserved[6];       /* 0x3a */
++} __attribute__((packed));
+ extern struct screen_info screen_info;
+_
diff --git a/target/linux/generic-2.6/patches-2.6.22/015-x86_newsetup_fixup.patch b/target/linux/generic-2.6/patches-2.6.22/015-x86_newsetup_fixup.patch
new file mode 100644 (file)
index 0000000..fad5435
--- /dev/null
@@ -0,0 +1,22 @@
+From: Andrew Morton <akpm@linux-foundation.org>
+
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+
+ arch/i386/kernel/cpu/Makefile |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff -puN arch/i386/kernel/cpu/Makefile~git-newsetup-fixup arch/i386/kernel/cpu/Makefile
+--- a/arch/i386/kernel/cpu/Makefile~git-newsetup-fixup
++++ a/arch/i386/kernel/cpu/Makefile
+@@ -8,7 +8,7 @@ obj-y  +=      amd.o
+ obj-y +=      cyrix.o
+ obj-y +=      centaur.o
+ obj-y +=      transmeta.o
+-obj-y +=      intel.o intel_cacheinfo.o
++obj-y +=      intel.o intel_cacheinfo.o addon_cpuid_features.o
+ obj-y +=      rise.o
+ obj-y +=      nexgen.o
+ obj-y +=      umc.o
+_
diff --git a/target/linux/generic-2.6/patches-2.6.22/600-eeprom_93cx6.patch b/target/linux/generic-2.6/patches-2.6.22/600-eeprom_93cx6.patch
new file mode 100644 (file)
index 0000000..e8bcd5a
--- /dev/null
@@ -0,0 +1,474 @@
+From: Ivo van Doorn <ivdoorn@gmail.com>
+Date: Fri, 11 May 2007 19:59:40 +0000 (-0400)
+Subject: [PATCH] Add 93cx6 eeprom library
+X-Git-Tag: v2.6.23-rc1~1201^2~74
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9467d64b0e88763914c01f71ddf591b166c4f526
+
+[PATCH] Add 93cx6 eeprom library
+
+This patch adds a library for reading from 93cx6 eeproms.
+
+Signed-off-by: Michael Wu <flamingice@sourmilk.net>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+---
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index 616eee9..bd601ef 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -34,6 +34,11 @@ config PHANTOM
+         If you choose to build module, its name will be phantom. If unsure,
+         say N here.
++config EEPROM_93CX6
++      tristate "EEPROM 93CX6 support"
++      ---help---
++        This is a driver for the EEPROM chipsets 93c46 and 93c66.
++        The driver supports both read as well as write commands.
+         If unsure, say N.
+@@ -187,5 +192,4 @@ config THINKPAD_ACPI_BAY
+         If you are not sure, say Y here.
+-
+ endmenu
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index 8abbf2f..b5ce0e3 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -14,3 +14,4 @@ obj-$(CONFIG_PHANTOM)                += phantom.o
+ obj-$(CONFIG_SGI_IOC4)                += ioc4.o
+ obj-$(CONFIG_SONY_LAPTOP)     += sony-laptop.o
+ obj-$(CONFIG_THINKPAD_ACPI)   += thinkpad_acpi.o
++obj-$(CONFIG_EEPROM_93CX6)    += eeprom_93cx6.o
+diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
+new file mode 100644
+index 0000000..bfcb434
+--- /dev/null
++++ b/drivers/misc/eeprom_93cx6.c
+@@ -0,0 +1,229 @@
++/*
++      Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
++      <http://rt2x00.serialmonkey.com>
++
++      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; either version 2 of the License, or
++      (at your option) any later version.
++
++      This program is distributed in the hope that it will be useful,
++      but WITHOUT ANY WARRANTY; without even the implied warranty of
++      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++      GNU General Public License for more details.
++
++      You should have received a copy of the GNU General Public License
++      along with this program; if not, write to the
++      Free Software Foundation, Inc.,
++      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++/*
++      Module: eeprom_93cx6
++      Abstract: EEPROM reader routines for 93cx6 chipsets.
++      Supported chipsets: 93c46 & 93c66.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/version.h>
++#include <linux/delay.h>
++#include <linux/eeprom_93cx6.h>
++
++MODULE_AUTHOR("http://rt2x00.serialmonkey.com");
++MODULE_VERSION("1.0");
++MODULE_DESCRIPTION("EEPROM 93cx6 chip driver");
++MODULE_LICENSE("GPL");
++
++static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
++{
++      eeprom->reg_data_clock = 1;
++      eeprom->register_write(eeprom);
++      udelay(1);
++}
++
++static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
++{
++      eeprom->reg_data_clock = 0;
++      eeprom->register_write(eeprom);
++      udelay(1);
++}
++
++static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
++{
++      /*
++       * Clear all flags, and enable chip select.
++       */
++      eeprom->register_read(eeprom);
++      eeprom->reg_data_in = 0;
++      eeprom->reg_data_out = 0;
++      eeprom->reg_data_clock = 0;
++      eeprom->reg_chip_select = 1;
++      eeprom->register_write(eeprom);
++
++      /*
++       * kick a pulse.
++       */
++      eeprom_93cx6_pulse_high(eeprom);
++      eeprom_93cx6_pulse_low(eeprom);
++}
++
++static void eeprom_93cx6_cleanup(struct eeprom_93cx6 *eeprom)
++{
++      /*
++       * Clear chip_select and data_in flags.
++       */
++      eeprom->register_read(eeprom);
++      eeprom->reg_data_in = 0;
++      eeprom->reg_chip_select = 0;
++      eeprom->register_write(eeprom);
++
++      /*
++       * kick a pulse.
++       */
++      eeprom_93cx6_pulse_high(eeprom);
++      eeprom_93cx6_pulse_low(eeprom);
++}
++
++static void eeprom_93cx6_write_bits(struct eeprom_93cx6 *eeprom,
++      const u16 data, const u16 count)
++{
++      unsigned int i;
++
++      eeprom->register_read(eeprom);
++
++      /*
++       * Clear data flags.
++       */
++      eeprom->reg_data_in = 0;
++      eeprom->reg_data_out = 0;
++
++      /*
++       * Start writing all bits.
++       */
++      for (i = count; i > 0; i--) {
++              /*
++               * Check if this bit needs to be set.
++               */
++              eeprom->reg_data_in = !!(data & (1 << (i - 1)));
++
++              /*
++               * Write the bit to the eeprom register.
++               */
++              eeprom->register_write(eeprom);
++
++              /*
++               * Kick a pulse.
++               */
++              eeprom_93cx6_pulse_high(eeprom);
++              eeprom_93cx6_pulse_low(eeprom);
++      }
++
++      eeprom->reg_data_in = 0;
++      eeprom->register_write(eeprom);
++}
++
++static void eeprom_93cx6_read_bits(struct eeprom_93cx6 *eeprom,
++      u16 *data, const u16 count)
++{
++      unsigned int i;
++      u16 buf = 0;
++
++      eeprom->register_read(eeprom);
++
++      /*
++       * Clear data flags.
++       */
++      eeprom->reg_data_in = 0;
++      eeprom->reg_data_out = 0;
++
++      /*
++       * Start reading all bits.
++       */
++      for (i = count; i > 0; i--) {
++              eeprom_93cx6_pulse_high(eeprom);
++
++              eeprom->register_read(eeprom);
++
++              /*
++               * Clear data_in flag.
++               */
++              eeprom->reg_data_in = 0;
++
++              /*
++               * Read if the bit has been set.
++               */
++              if (eeprom->reg_data_out)
++                      buf |= (1 << (i - 1));
++
++              eeprom_93cx6_pulse_low(eeprom);
++      }
++
++      *data = buf;
++}
++
++/**
++ * eeprom_93cx6_read - Read multiple words from eeprom
++ * @eeprom: Pointer to eeprom structure
++ * @word: Word index from where we should start reading
++ * @data: target pointer where the information will have to be stored
++ *
++ * This function will read the eeprom data as host-endian word
++ * into the given data pointer.
++ */
++void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom, const u8 word,
++      u16 *data)
++{
++      u16 command;
++
++      /*
++       * Initialize the eeprom register
++       */
++      eeprom_93cx6_startup(eeprom);
++
++      /*
++       * Select the read opcode and the word to be read.
++       */
++      command = (PCI_EEPROM_READ_OPCODE << eeprom->width) | word;
++      eeprom_93cx6_write_bits(eeprom, command,
++              PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
++
++      /*
++       * Read the requested 16 bits.
++       */
++      eeprom_93cx6_read_bits(eeprom, data, 16);
++
++      /*
++       * Cleanup eeprom register.
++       */
++      eeprom_93cx6_cleanup(eeprom);
++}
++EXPORT_SYMBOL_GPL(eeprom_93cx6_read);
++
++/**
++ * eeprom_93cx6_multiread - Read multiple words from eeprom
++ * @eeprom: Pointer to eeprom structure
++ * @word: Word index from where we should start reading
++ * @data: target pointer where the information will have to be stored
++ * @words: Number of words that should be read.
++ *
++ * This function will read all requested words from the eeprom,
++ * this is done by calling eeprom_93cx6_read() multiple times.
++ * But with the additional change that while the eeprom_93cx6_read
++ * will return host ordered bytes, this method will return little
++ * endian words.
++ */
++void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom, const u8 word,
++      __le16 *data, const u16 words)
++{
++      unsigned int i;
++      u16 tmp;
++
++      for (i = 0; i < words; i++) {
++              tmp = 0;
++              eeprom_93cx6_read(eeprom, word + i, &tmp);
++              data[i] = cpu_to_le16(tmp);
++      }
++}
++EXPORT_SYMBOL_GPL(eeprom_93cx6_multiread);
++
+diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
+new file mode 100644
+index 0000000..d774b77
+--- /dev/null
++++ b/include/linux/eeprom_93cx6.h
+@@ -0,0 +1,72 @@
++/*
++      Copyright (C) 2004 - 2006 rt2x00 SourceForge Project
++      <http://rt2x00.serialmonkey.com>
++
++      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; either version 2 of the License, or
++      (at your option) any later version.
++
++      This program is distributed in the hope that it will be useful,
++      but WITHOUT ANY WARRANTY; without even the implied warranty of
++      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++      GNU General Public License for more details.
++
++      You should have received a copy of the GNU General Public License
++      along with this program; if not, write to the
++      Free Software Foundation, Inc.,
++      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++ */
++
++/*
++      Module: eeprom_93cx6
++      Abstract: EEPROM reader datastructures for 93cx6 chipsets.
++      Supported chipsets: 93c46 & 93c66.
++ */
++
++/*
++ * EEPROM operation defines.
++ */
++#define PCI_EEPROM_WIDTH_93C46        6
++#define PCI_EEPROM_WIDTH_93C66        8
++#define PCI_EEPROM_WIDTH_OPCODE       3
++#define PCI_EEPROM_WRITE_OPCODE       0x05
++#define PCI_EEPROM_READ_OPCODE        0x06
++#define PCI_EEPROM_EWDS_OPCODE        0x10
++#define PCI_EEPROM_EWEN_OPCODE        0x13
++
++/**
++ * struct eeprom_93cx6 - control structure for setting the commands
++ * for reading the eeprom data.
++ * @data: private pointer for the driver.
++ * @register_read(struct eeprom_93cx6 *eeprom): handler to
++ * read the eeprom register, this function should set all reg_* fields.
++ * @register_write(struct eeprom_93cx6 *eeprom): handler to
++ * write to the eeprom register by using all reg_* fields.
++ * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines
++ * @reg_data_in: register field to indicate data input
++ * @reg_data_out: register field to indicate data output
++ * @reg_data_clock: register field to set the data clock
++ * @reg_chip_select: register field to set the chip select
++ *
++ * This structure is used for the communication between the driver
++ * and the eeprom_93cx6 handlers for reading the eeprom.
++ */
++struct eeprom_93cx6 {
++      void *data;
++
++      void (*register_read)(struct eeprom_93cx6 *eeprom);
++      void (*register_write)(struct eeprom_93cx6 *eeprom);
++
++      int width;
++
++      char reg_data_in;
++      char reg_data_out;
++      char reg_data_clock;
++      char reg_chip_select;
++};
++
++extern void eeprom_93cx6_read(struct eeprom_93cx6 *eeprom,
++      const u8 word, u16 *data);
++extern void eeprom_93cx6_multiread(struct eeprom_93cx6 *eeprom,
++      const u8 word, __le16 *data, const u16 words);
+From: Ivo van Doorn <ivdoorn@gmail.com>
+Date: Mon, 14 May 2007 21:06:01 +0000 (+0200)
+Subject: [PATCH] eeprom_93cx6: Add comment for 1us delay after pulse
+X-Git-Tag: v2.6.23-rc1~1201^2~73
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=4b914dc0493edff19ff698a18198a173a14ba9d2
+
+[PATCH] eeprom_93cx6: Add comment for 1us delay after pulse
+
+This will add a comment for the 1us delay which is taken
+after the pulse has been switched. The 1us delay is based
+on the specifications so that should be made clear.
+
+Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+---
+
+diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
+index bfcb434..0d6d742 100644
+--- a/drivers/misc/eeprom_93cx6.c
++++ b/drivers/misc/eeprom_93cx6.c
+@@ -39,6 +39,12 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
+ {
+       eeprom->reg_data_clock = 1;
+       eeprom->register_write(eeprom);
++
++      /*
++       * Add a short delay for the pulse to work.
++       * According to the specifications the minimal time
++       * should be 450ns so a 1us delay is sufficient.
++       */
+       udelay(1);
+ }
+@@ -46,6 +52,12 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
+ {
+       eeprom->reg_data_clock = 0;
+       eeprom->register_write(eeprom);
++
++      /*
++       * Add a short delay for the pulse to work.
++       * According to the specifications the minimal time
++       * should be 450ns so a 1us delay is sufficient.
++       */
+       udelay(1);
+ }
+From: John W. Linville <linville@tuxdriver.com>
+Date: Tue, 12 Jun 2007 01:37:46 +0000 (-0400)
+Subject: [PATCH] eeprom_93cx6: shorten pulse timing to match spec
+X-Git-Tag: v2.6.23-rc1~1201^2~71
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=7e9400f178d291b2208c4ed9aac0f425c1364000
+
+[PATCH] eeprom_93cx6: shorten pulse timing to match spec
+
+93cx6 datasheet available here:
+
+        http://ww1.microchip.com/downloads/en/DeviceDoc/21749F.pdf
+
+Figure 1-1 and Table 1-2 on pages 4-5 indicate that both Clock High
+Time and Clock Low Time have largest minimum times of 450ns.
+
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+---
+
+diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
+index 0d6d742..ac515b0 100644
+--- a/drivers/misc/eeprom_93cx6.c
++++ b/drivers/misc/eeprom_93cx6.c
+@@ -42,10 +42,10 @@ static inline void eeprom_93cx6_pulse_high(struct eeprom_93cx6 *eeprom)
+       /*
+        * Add a short delay for the pulse to work.
+-       * According to the specifications the minimal time
+-       * should be 450ns so a 1us delay is sufficient.
++       * According to the specifications the "maximum minimum"
++       * time should be 450ns.
+        */
+-      udelay(1);
++      ndelay(450);
+ }
+ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
+From: Francois Romieu <romieu@fr.zoreil.com>
+Date: Tue, 3 Jul 2007 22:31:44 +0000 (+0200)
+Subject: eeprom_93cx6: shorten pulse timing to match spec (bis)
+X-Git-Tag: v2.6.23-rc1~1151^2~11
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8abd531e3f77188de2fc41e677d075cc66e61631
+
+eeprom_93cx6: shorten pulse timing to match spec (bis)
+
+Based on an original idea by John W. Linville.
+
+It is the missing part of 42d45ccd60636c28e35c2016f091783bc14ad99c
+
+Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
+Signed-off-by: Jeff Garzik <jeff@garzik.org>
+---
+
+diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
+index ac515b0..ea55654 100644
+--- a/drivers/misc/eeprom_93cx6.c
++++ b/drivers/misc/eeprom_93cx6.c
+@@ -55,10 +55,10 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
+       /*
+        * Add a short delay for the pulse to work.
+-       * According to the specifications the minimal time
+-       * should be 450ns so a 1us delay is sufficient.
++       * According to the specifications the "maximum minimum"
++       * time should be 450ns.
+        */
+-      udelay(1);
++      ndelay(450);
+ }
+ static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)