Imported Upstream version 3.14 upstream upstream/3.14
authorBdale Garbee <bdale@gag.com>
Fri, 29 Jun 2012 17:02:56 +0000 (11:02 -0600)
committerBdale Garbee <bdale@gag.com>
Fri, 29 Jun 2012 17:02:56 +0000 (11:02 -0600)
26 files changed:
.ChangeLog.swp [deleted file]
ChangeLog
Make.defaults
Makefile
alloc.c
bootparams.c
choosers/Makefile
choosers/simple.c
choosers/textmenu.c
config.c
elilo.c
elilo.h
fileops.c
fs/Makefile
fs/localfs.c
glue_netfs.c
ia32/bzimage.c
ia32/system.c
ia64/system.c
initrd.c
strops.c
tools/eliloalt.c
x86_64/bzimage.c
x86_64/config.c
x86_64/sysdeps.h
x86_64/system.c

diff --git a/.ChangeLog.swp b/.ChangeLog.swp
deleted file mode 100644 (file)
index 7c1e3be..0000000
Binary files a/.ChangeLog.swp and /dev/null differ
index 12d2ddf015751a18f93d29097b4d4ce0b88fdb9b..a1dc18246ebd7a59a85a09ac482c1cc5543e46d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2011-1-10 signed off by Jason Fleischli <jason.fleischli@hp.com>
+       * Uptake of SUSE patches
+       - add sysfs support for efi vars (formerly /proc/efi/vars)
+       - fix strncpy overflow
+       - fix bzimage alloc
+       - cleanups
+       - support longer command line
+       - yet some more mac fixes
+       - align elilo with latest kernel boot protocol format.
+       - new memory management strategy for initrd and kernel image loading.
+       * add force text mode command line option.
+       * replace error output on GOP handle failed, downgraded to normal
+         print status with more informative output.
+
 2009-10-22 signed off by Jason Fleischli <jason.fleischli@hp.com>
        * elilo 3.12 release commit
        * Added additional #defines for debug levels to reduce the output
          subtree
        * bugfix loader_probe now correctly errors out if no loaders
          registered.
+
 2008-01-11 signed off by Jason Fleischli <jason.fleischli@hp.com>
        * Various compile warning cleanups.
+
 2008-01-03 signed off by Jason Fleischli <jason.fleischli@hp.com>
        * Patch contribution from Scott Davilla <davilla@4pi.com>
          when x is zero for the first call to add_memory_region, e820_map[-1] 
@@ -49,6 +65,7 @@
          above the e820_map[0] location that should have been zeroed by the 
          bootloader, the code should not access outside the bounds of 
          structures. 
+
 2008-01-03 Jason Fleischli <jason.fleischli@hp.com>
        * initrd.c -- Let the allocator decide where to grab the memory from 
          the efi memory map. Current start_addr=image->start_addr forces the 
          the image->start_addr resulting in an elilo hang. Leaving start_addr 
          NULL at initialization forces alloc_pages to get a memory region 
          sufficient for the size of the initrd image.
+
 2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
        * bumping version string to 3.8
+
 2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
        * MORE PATCHES FROM INTEL FOR IA32 X86_64.
        * Fix compile warning for cmdline_addr assignment.
          EFI framebuffer type ID setting code in ELILO is changed accordingly.
        * E820 memory map is added to IA32 to make it possible for
          Linux kernel not to depend on EFI memory map on EFI 32.
+
 2007-09-27 Jason Fleischli <jason.fleischli@hp.com>
        * updating changelog for last commit that was omitted
        * incorporating AGriffis patches to enhance parsing
          passes root= option to kernel options and accounts for -- option
          designation.
+
 2007-07-19 Jason Fleischli <jason.fleischli@hp.com>
        * Integrated x86_64 support patches from Chandramouli Narayanan
          <mouli@linux.intel.com> changes summarized in following bullets.
        * x86_64/sysdeps.c -- new file, system stuff for x86_64
        * elilo.txt -- documentation update, add Intel to copyright
        * README.gnu-efi -- documentation update for x86_64
+
 2006-01-27 Alex Williamson <alex.williamson@hp.com>
        * Found a couple more places where vmcode isn't zeroed, causing the
          option to get carried over to labels it shouldn't.
+
 2006-01-09 Brett Johnson <brett@hp.com>
        * Released 3.6
+
 2005-12-22 Alex Williamson <alex.williamson@hp.com>
        * Fixed vmcode_name initialization in textmenu chooser
+
 2005-12-01 Alex Williamson <alex.williamson@hp.com>
        * Applied patch from Fred Yang <fred.yang@intel.com> to support the
          vmm= boot option.  This option specifies the kernel image for a
          image will be uncompressed into memory before it is provided to the
          hypervisor.  Any combination of compressed and uncompressed images
          can be used for the image and vmm options.
+
 2005-09-15 Brett Johnson <brett@hp.com>
        * Applied patch from Tristan Gingold to add dcache flush and sync with
          icache to gzip and plain loaders.  This ommision was just noticed now
          due to the much larger caches in Montecito, and the smaller size of
          Xen (as compared to the linux kernel).
+
 2004-09-27 Brett Johnson <brett@hp.com>
        * Increase the hardcoded size of the texmenu chooser menu from 16 to 64
+
 2004-09-23 Brett Johnson <brett@hp.com>
        * Fix for 924147.  Thanks to Stephanie Schaaf <sas@sgi.com> for a patch
          that the fix is based on.
+
 2004-02-19 Brett Johnson <brett@hp.com>
        * Fixed bug where default image initrd would carry over to another
          image that was selected interactively (iff the newly selected image
          did not have an initrd).
        * Added support for subnet-specific config files in netfs.
+
 2004-02-17 Brett Johnson <brett@hp.com>
        * integrated ia32 compressed kernel support from Matt Tolentino
          <matthew.e.tolentino@intel.com>
+
 2003-08-20 Stephane Eranian <eranian@hpl.hp.com>
        * released 3.4
+
 2003-08-19 Stephane Eranian <eranian@hpl.hp.com>
        * integrated ia32 updates from Matt
          Tolentino <matthew.e.tolentino@intel.com>
+
 2003-08-13 Stephane Eranian <eranian@hpl.hp.com>
        * updated elilo.txt and netbooting.txt
        * fix a bug in choosers/simple.c:print_infos().
        * updated simple chooser set of builtin command keys
        * command keys are only valid if first on the line
        * increase default buffer size and increment when netbooting
+
 2003-06-04 Stephane Eranian <eranian@hpl.hp.com>
        * fix fs/netfs.c to work with recent version
          of EFI (14.61 or higher) which do not have the 
          TFTP problem anymore. fix submitted by Guy Laborde
+
 2003-04-21 Stephane Eranian <eranian@hpl.hp.com>
        * ext2fs support is turned off by default to avoid
          problems with ext3-formatted partitions.
        * added gcc version check. MUST use 3.0 or higher
+
 2003-03-03 Stephane Eranian <eranian@hpl.hp.com>
        * added check on dev_tab in fs/*fs.c:*_uninstall()
+
 2003-02-07 Stephane Eranian <eranian@hpl.hp.com>
        * clean up in glue_localfs.c w.r.t. CHAR16 in set_default_path()
        * added support for extracting basename of bootloader path
          when using BOOTP (DHCP) only. The prefix is then used for all files
          open via netfs. Suggestion and initial patch by Guy Laborde from HP.
+
 2003-01-28 Stephane Eranian <eranian@hpl.hp.com>
        * fix the set_default_path() routine in glue_localfs.c. It would not
          correctly get the basename of the devpath. This caused the
          elilo.conf not to be found sometimes.
+
 2003-01-21 Stephane Eranian <eranian@hpl.hp.com>
        * fix bug in glue_netfs.c convert_ip2decstr() which caused some IP
          addresses to be incorrectly converted to strings.
+
 2002-11-01 Stephane Eranian <eranian@hpl.hp.com>
        * fix bug in -r option for IA64. There is no argument to this option.
+
 2002-10-15 Stephane Eranian <eranian@hpl.hp.com>
        * fixed a double free bug for the kernel memory in case of abort.
          (bug spotted by Levent Akyl from Intel)
        * released 3.3a
+
 2002-09-14 Stephane Eranian <eranian@hpl.hp.com>
        * applied patch from Andreas Schwab <schwab@suse.de> to eliloalt.c.
          eliloalt dynamically selects a variable in /proc/efi/vars.
+
 2002-09-12 Stephane Eranian <eranian@hpl.hp.com>
        * removed extra free() from fs/ext2fs.c:ext2fs_init_state().
          Bug report and fix by NOMURA Jun'ichi <j-nomura@ce.jp.nec.com>
          was bigger than the 128KB limit of EFI causing some weird fimrware
          errors. bug reported by OMURA Jun'ichi <j-nomura@ce.jp.nec.com>
        * on IA-64 forbid the use of f32-f127 by the compiler (EFI spec)
+
 2002-09-10 Stephane Eranian <eranian@hpl.hp.com>
        * fix a bug in argify() that was causing an EFI assertion 
          when aborting at the elilo prompt when netbooted.
+
 2002-08-26 Stephane Eranian <eranian@hpl.hp.com>
        * fixed devschemes/simple.c to use SPrint() instead of its own buggy
          conversion code (spotted by Richard Hirst).
        * fix bug in argify() when there was no NULL character in the string.
        * released 3.3
+
 2002-08-19 Stephane Eranian <eranian@hpl.hp.com>
        * added fpswa.txt in the docs directory
        * updated elilo.txt
+
 2002-08-15 Stephane Eranian <eranian@hpl.hp.com>
        * added -F file option for IA-64 to allow a specific fpswa driver to be loaded
        * fixed fpswa.c to try and load the driver from all accessible partitions
        * added support to load (plain or gzipped) big-endian ELF/ia64 binaries using p_paddr.
        * fixed problem in fs/netfs.c causing large (>4MB) binaries to fail the Mftp() call
+
 2002-06-13 Stephane Eranian <eranian@hpl.hp.com>
        * Changed the despecialization character for the variables from \\ to &
          to avoid conflicts with \\ as a path separator
+
 2002-06-11 Stephane Eranian <eranian@hpl.hp.com>
        * fixed the return value in efi_main(). elilo was always returning
          success even in case of failure. Bug reported by Egan Ford <egan@sense.net>
          compliant with EFI spec with regards to where it looks for files.
          With this patch, elilo will look in the directory it was loaded
          from, not on the root of the partition anymore.
+
 2002-03-04 Stephane Eranian <eranian@hpl.hp.com>
        * released version 3.2
        * cleanup some GNU extension in fs/ext2fs.c (variable size array)
        * updated all documentation. Added netbooting.txt, simple_chooser.txt,
          eliloalt.txt, elilovar.txt
+
 2002-02-21 Stephane Eranian <eranian@hpl.hp.com>
        * added a Linux utility program (elilovar in tools) to set/read/delete 
          the EliloAlt EFI variable used to specify an alternate kernel to boot.
        * added support for hostname,domain name extraction in fs/netfs.c
        * fixed all known bugs in alternate.c
        * integrated patch from SGI to fix load offset for relocatable kernels (Jack Steiner, Brent Casavant)
+
 2002-02-21 Michael Johnston <michael.johnston@intel.com> and Chris Ahna <christopher.j.ahna@intel.com>
        * major update to ia32 support: can now boot 2.4.x,  and 2.2.x kernels
+
 2002-02-20 Stephane Eranian <eranian@hpl.hp.com>
        * fixed missing netfs_fd_free() in case of file not found in netfs.c
+
 2002-02-19 Stephane Eranian <eranian@hpl.hp.com>
        * added support for substitution variables (vars.c)
        * changed the bootparam structure size back to 4kB
        * added support to simple to print final command line option with tab key
        * got rid of all the \r characters in strings use only \n (adjust emulator)
        * added EFICRT0 variable in Makefile to indicate location of loader script+crt0
+
 2002-02-14 Stephane Eranian <eranian@hpl.hp.com>
        * added support for message= option to simple chooser
        * added support for description= option to simple chooser
+
 2002-02-13 Stephane Eranian <eranian@hpl.hp.com>
        * choosers/textmenu.c: new textmenu chooser (by rhirst@linuxcare.com) used by Debian
        * config.c: added support for dynamic global/per-image option management
          mode was specified in config file. In this case, we now autoboot
          and ignore the prompt directive.
        * updated elilo.txt
+
 2001-08-15  Brent Casavant <bcasavan@sgi.com>
        * fix a bug in config.c:find_option() where it would do
          a strXcmp() on a NULL string.
index f5dca13b103f023f405dad5c9a7783117630c6fe..e541ea86d77055f0ed561e52ffec9b17f59d9128 100644 (file)
@@ -68,7 +68,7 @@ CPPFLAGS   = -DCONFIG_$(ARCH)
 
 OPTIMFLAGS = -O2 
 DEBUGFLAGS = -Wall
-CFLAGS     = $(OPTIMFLAGS) -fno-strict-aliasing -fpic -fshort-wchar $(DEBUGFLAGS)
+CFLAGS     = $(OPTIMFLAGS) -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar $(DEBUGFLAGS)
 LDFLAGS           = -nostdlib -znocombreloc
 INSTALL           = install
 
index 613b597ee890ac7d8c4b0034702cb74be251ac57..f0efebd9735cfa47978f883aad77ae9c24fd3b5d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -81,7 +81,7 @@ elilo.efi: elilo.so
 
 elilo.so: $(FILES)
 
-elilo.o : elilo.c
+elilo.o : elilo.c $(ARCH)/sysdeps.h
 
 fileops.o : Make.defaults
 chooser.o : Make.defaults
diff --git a/alloc.c b/alloc.c
index 6f463e4324e4e03199672ecaa6d321ef39f0ec25..cd67c38e239f005091946fcd2aab72b3cad4895c 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -110,7 +110,7 @@ alloc(UINTN size, EFI_MEMORY_TYPE type)
        }
        alloc_add(tmp, size, ALLOC_POOL);
 #ifdef DEBUG_MEM
-        DBG_PRT((L"alloc: allocated %d bytes @[" PTR_FMT "-" PTR_FMT "]\n", size, tmp, tmp+size));
+        DBG_PRT((L"alloc: allocated %d bytes @[" PTR_FMT "-" PTR_FMT "]", size, tmp, tmp+size));
 #endif
        return tmp;
 }
@@ -140,7 +140,7 @@ alloc_pages(UINTN pgcnt, EFI_MEMORY_TYPE type, EFI_ALLOCATE_TYPE where, VOID *ad
 
        alloc_add(addr, pgcnt, ALLOC_PAGES);
 
-        DBG_PRT((L"allocator: allocated %d pages @0x%lx\n", pgcnt, tmp));
+        DBG_PRT((L"allocator: allocated %d pages @" PTR_FMT, pgcnt, tmp));
 
        return addr;
 }
@@ -162,7 +162,7 @@ free(VOID *addr)
        return; 
 found:
 #ifdef DEBUG_MEM
-        DBG_PRT((L"free: %s @" PTR_FMT " size=%d\n", 
+        DBG_PRT((L"free: %s @" PTR_FMT " size=%d",
                p->type == ALLOC_POOL ? L"Pool": L"Page", 
                addr, p->size));
 #endif
@@ -196,7 +196,7 @@ free_all(VOID)
 
        while(used_allocs) {
 #ifdef DEBUG_MEM
-               DBG_PRT((L"free_all %a @ " PTR_FMT "\n", used_allocs->type == ALLOC_POOL ? "pool" : "pages", used_allocs->addr));
+               DBG_PRT((L"free_all %a @ " PTR_FMT, used_allocs->type == ALLOC_POOL ? "pool" : "pages", used_allocs->addr));
 #endif 
                if (used_allocs->type == ALLOC_POOL)
                        uefi_call_wrapper(BS->FreePool, 1, used_allocs->addr);
@@ -217,7 +217,15 @@ INTN
 alloc_kmem_anywhere(VOID **start_addr, UINTN pgcnt)
 {
        void * tmp;
-       if ((tmp = alloc_pages(pgcnt, EfiLoaderData, AllocateAnyPages, *start_addr)) == 0) return -1;
+       /*
+        * During "AllocateAnyPages" *start_addr will be ignored.
+        * Therefore we can safely subvert it to reuse this function with
+        * an alloc_kmem_anyhwere_below() semantic...
+        */
+       tmp = alloc_pages(pgcnt, EfiLoaderData,
+                       (*start_addr) ? AllocateMaxAddress : AllocateAnyPages,
+                       *start_addr);
+       if (tmp == NULL) return -1;
 
        kmem_addr  = tmp;
        kmem_pgcnt = pgcnt;
@@ -241,7 +249,7 @@ VOID
 free_kmem(VOID)
 {
 #ifdef DEBUG_MEM
-       DBG_PRT((L"free_kmem before (" PTR_FMT ", %d)\n", kmem_addr, kmem_pgcnt));
+       DBG_PRT((L"free_kmem before (" PTR_FMT ", %d)", kmem_addr, kmem_pgcnt));
 #endif
        if (kmem_addr && kmem_pgcnt != 0) {
                free(kmem_addr);
@@ -249,7 +257,7 @@ free_kmem(VOID)
                kmem_pgcnt = 0;
        }
 #ifdef DEBUG_MEM
-       DBG_PRT((L"free_kmem after (" PTR_FMT ", %d)\n", kmem_addr, kmem_pgcnt));
+       DBG_PRT((L"free_kmem after (" PTR_FMT ", %d)", kmem_addr, kmem_pgcnt));
 #endif
 }
 
index da3d6642ae5e5603fa325dcc70cbba7a51704ee6..576a57942973f7c93b1e79b7ecf4e18cb8e72931 100644 (file)
@@ -96,6 +96,8 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, memdesc_t *vmcode, UINTN *co
         */
        Memset(bp, 0, BOOT_PARAM_MEMSIZE);
 
+       U2ascii(args, cp, cmdline_size);
+
        if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0;
 
        /*
index 31b10d09a48af693ffc21a26dd0820aa460c0768..9915f486d2ffe1bc490de8d80f3e0857beaf5eb1 100644 (file)
@@ -42,17 +42,13 @@ TARGET=choosers.o
 
 all: $(TARGET)
 
-$(TARGET): check-choosers $(TOPDIR)/Make.defaults $(FILES)
+$(TARGET): $(TOPDIR)/Make.defaults $(FILES)
+       @if [ -z "$(FILES)" ]; then \
+               echo "You need to define at least one chooser in Make.defaults"; \
+               exit 1; \
+       fi
        $(LD) -o $@ -r $(FILES)
 
 clean:
        $(RM) -f $(TARGET) $(FILES)
-       
-check-choosers:
-       @if [ -n "$(FILES)" ]; then \
-               exit 0; \
-       else \
-               echo "You need to define at least one chooser in Make.defaults"; \
-               exit 1; \
-       fi
 
index f064e12b973ccf26b3b27b0050f37bd49400101d..d0c38f7bee6dd89098c25db1f48a4ed13ee75db0 100644 (file)
@@ -41,8 +41,8 @@ static VOID
 display_label_info(CHAR16 *name)
 {
        CHAR16 *desc;
-       CHAR16 initrd_name[CMDLINE_MAXLEN];
-       CHAR16 vmcode_name[CMDLINE_MAXLEN];
+       CHAR16 initrd_name[PATHNAME_MAXLEN];
+       CHAR16 vmcode_name[PATHNAME_MAXLEN];
        CHAR16 options_tmp[CMDLINE_MAXLEN];
        CHAR16 options[CMDLINE_MAXLEN];
        CHAR16 kname[FILENAME_MAXLEN];
@@ -254,10 +254,10 @@ simple_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmdli
 #      define BOOT_IMG_STR     L"BOOT_IMAGE="
        CHAR16 buffer[CMDLINE_MAXLEN];
        CHAR16 alt_buffer[CMDLINE_MAXLEN];
-       CHAR16 initrd_name[CMDLINE_MAXLEN];
-       CHAR16 vmcode_name[CMDLINE_MAXLEN];
+       CHAR16 initrd_name[PATHNAME_MAXLEN];
+       CHAR16 vmcode_name[PATHNAME_MAXLEN];
        CHAR16 args[CMDLINE_MAXLEN];
-       CHAR16 devname[CMDLINE_MAXLEN];
+       CHAR16 devname[PATHNAME_MAXLEN];
        CHAR16 dpath[FILENAME_MAXLEN];
        CHAR16 *slash_pos, *colon_pos, *backslash_pos;
        UINTN len;
@@ -290,8 +290,9 @@ restart:
 
        if (elilo_opt.prompt) {
                console_textmode();
-               ret = select_kernel(buffer, sizeof(buffer));
+               ret = select_kernel(buffer, CMDLINE_MAXLEN);
                if (ret == -1) return -1;
+               /* this function takes really the number of bytes ... */
                argc    = argify(buffer,sizeof(buffer), argv); 
                index   = 0;
        }
index ac282c0cc6f933427dc6f751d6b1bca60852c39f..52021a91bb7296b9614f978b202dfcad4d562142 100644 (file)
@@ -363,10 +363,10 @@ textmenu_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmd
 {      
 #      define BOOT_IMG_STR     L"BOOT_IMAGE="
        CHAR16 label[CMDLINE_MAXLEN];
-       CHAR16 initrd_name[CMDLINE_MAXLEN];
-       CHAR16 vmcode_name[CMDLINE_MAXLEN];
+       CHAR16 initrd_name[PATHNAME_MAXLEN];
+       CHAR16 vmcode_name[PATHNAME_MAXLEN];
        CHAR16 args[CMDLINE_MAXLEN];
-       CHAR16 devname[CMDLINE_MAXLEN];
+       CHAR16 devname[PATHNAME_MAXLEN];
        CHAR16 dpath[FILENAME_MAXLEN];
        CHAR16 *slash_pos, *colon_pos, *backslash_pos;
        UINTN len;
index 5ad8de624ea420f2b0d67060c0d3ad7f2d5ec035..d144c9f0a9b1620a0f10b2ac98edce55f790ceb7 100644 (file)
--- a/config.c
+++ b/config.c
@@ -56,7 +56,7 @@
  */
 #define ELILO_DEFAULT_CONFIG   L"elilo.conf"
 
-#define MAX_STRING     CMDLINE_MAXLEN
+#define MAX_STRING     512
 #define CONFIG_BUFSIZE 512     /* input buffer size */
 
 /*
@@ -71,7 +71,7 @@ typedef struct boot_image {
        struct boot_image *next;
        CHAR16  label[MAX_STRING];
        CHAR16  kname[FILENAME_MAXLEN];
-       CHAR16  options[MAX_STRING];
+       CHAR16  options[CMDLINE_MAXLEN];
        CHAR16  initrd[FILENAME_MAXLEN];
        CHAR16  vmcode[FILENAME_MAXLEN];
        CHAR16  root[FILENAME_MAXLEN];
@@ -100,7 +100,7 @@ typedef struct {
        CHAR16          root[FILENAME_MAXLEN];  /* globally defined root fs */
        CHAR16          initrd[FILENAME_MAXLEN];/* globally defined initrd  */
        CHAR16          vmcode[FILENAME_MAXLEN];/* globally defined boot-time module  */
-       CHAR16          options[MAX_STRING];
+       CHAR16          options[CMDLINE_MAXLEN];
        CHAR16          default_image_name[MAX_STRING];
        CHAR16          message_file[MAX_MESSAGES][FILENAME_MAXLEN]; 
        CHAR16          chooser[FILENAME_MAXLEN];/* which image chooser to use */
@@ -909,10 +909,10 @@ print_label_list(VOID)
 {
        boot_image_t *img, *dfl = global_config.default_image;
 
-       if (dfl) Print(L"\t%s\n", dfl->label);
+       if (dfl) Print(L"    %s\n", dfl->label);
 
        for (img = image_list; img; img = img->next) {
-               if (img != dfl) Print(L"\t%s\n", img->label);
+               if (img != dfl) Print(L"    %s\n", img->label);
        }
 }
 
diff --git a/elilo.c b/elilo.c
index 31c7294076b804d8cd55fbb7d91ba7e8d625a0d7..ade977d401c1b654a411bc7eaec5b95b14f2b95f 100644 (file)
--- a/elilo.c
+++ b/elilo.c
@@ -93,7 +93,7 @@ do_kernel_load(CHAR16 *kname, kdesc_t *kd)
 INTN
 kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memdesc_t *mmem)
 {
-       CHAR16 kernel[CMDLINE_MAXLEN];
+       CHAR16 kernel[FILENAME_MAXLEN];
 
        /*
         * Do the vm image switch here
diff --git a/elilo.h b/elilo.h
index 4809fbe4ab880d9b8920a605977ed041cde4b717..bd0cd0b69bbdda709f77eea887a1f28d3c157960 100644 (file)
--- a/elilo.h
+++ b/elilo.h
@@ -29,7 +29,7 @@
 #ifndef __ELILO_H__
 #define __ELILO_H__
 
-#define ELILO_VERSION L"3.12"
+#define ELILO_VERSION L"3.14"
 
 #include <efi.h>
 
 #define ROUNDUP(x,a)   (((x) + (a) - 1) & ~((a) - 1))
 #define ROUNDDOWN(x,a)  ((x) & ~((a) - 1))
 
+#ifndef UINT32_MAX
+#define UINT32_MAX     ((UINT32)-1)
+#endif
+
 /*
  * Elilo Boot modes
  */
@@ -65,7 +69,8 @@
 #define ELILO_DEFAULT_TIMEOUT  ELILO_TIMEOUT_INFINITY
 #define ELILO_TIMEOUT_INFINITY (~0UL)
 
-#define CMDLINE_MAXLEN         512 /* needed by ia32 */
+#define CMDLINE_MAXLEN         2048
+#define PATHNAME_MAXLEN                512
 #define FILENAME_MAXLEN                256
 #define MAX_ARGS               256
 /* Just pick an arbitrary number that's high enough for now :o) */
@@ -212,6 +217,7 @@ extern CHAR16 *sysdeps_get_cmdline_opts(VOID);
 extern INTN sysdeps_getopt(INTN, INTN, CHAR16 *);
 extern VOID sysdeps_print_cmdline_opts(VOID);
 extern INTN sysdeps_register_options(VOID);
+extern VOID *sysdeps_checkfix_initrd(VOID *, memdesc_t *);
 
 #define        CHAR_SLASH      L'/'
 #define CHAR_BACKSLASH L'\\'
index 1a43479f97fcdbbff8a7584c34804d3b62982574..9cf66ebb2d80a1e6c172647d1645a71c36a68161 100644 (file)
--- a/fileops.c
+++ b/fileops.c
@@ -497,7 +497,7 @@ add_dev_tab(EFI_GUID *proto, EFI_HANDLE boot_handle, UINTN size, fops_fs_glue_t
 
                        str2 = str == NULL ? L"Unknown" : str;
 
-                       DBG_PRT((L"%s : %-8s : %s\n", dev_tab[idx].name,
+                       DBG_PRT((L"%s : %-8s : %s", dev_tab[idx].name,
                                (dev_tab[idx].fops ? dev_tab[idx].fops->name: L"N/A"), str2));
 
                        if (str) FreePool(str);
index 1829d967cee4edfd9b50389c58b82e14b4fd4b13..8e422b21258f46a209ed25e60fa7c9700e85abda 100644 (file)
@@ -54,17 +54,13 @@ all: $(TARGET)
 # XXX: does not trigger recompile when changing filesystem selection
 #      without doing make clean.
 #
-$(TARGET): check-filesystems $(TOPDIR)/Make.defaults $(FILES)
+$(TARGET): $(TOPDIR)/Make.defaults $(FILES)
+       @if [ -z "$(FILES)" ]; then \
+               echo "You need to define at least one filesystem in Make.defaults"; \
+               exit 1; \
+       fi
        $(LD) -r -o $@ $(FILES)
 
 clean:
        $(RM) -f $(TARGET) $(FILES)
 
-check-filesystems:
-       @if [ -n "$(FILES)" ]; then \
-               exit 0; \
-       else \
-               echo "You need to define at least one filesystem in Make.defaults"; \
-               exit 1; \
-       fi
-
index fe1333fee764160bdb28f61b43aaef29087325b0..7f09ab16a316ad592c74e80cfceaac13a0047e5c 100644 (file)
@@ -98,7 +98,7 @@ localfs_open(localfs_interface_t *this, CHAR16 *name, UINTN *fd)
 
        DBG_PRT((L"localfs_open on %s\n", name));
 
-       status = uefi_call_wrapper(lfs->volume->Open, 5, lfs->volume, &fh, name, EFI_FILE_MODE_READ, 0);
+       status = uefi_call_wrapper(lfs->volume->Open, 5, lfs->volume, &fh, name, EFI_FILE_MODE_READ, (UINT64)0);
        if (status == EFI_SUCCESS) {
                *fd = LOCALFS_F2FD(fh);
        } 
index e47bcc8414747566fac0f3ed87a35d7012b07f03..eebfecc103ee692954ea8b48f77ca015f8c2346c 100644 (file)
@@ -64,6 +64,19 @@ static CHAR16 netfs_default_path[FILENAME_MAXLEN];
 
 static CHAR16 *hexa=L"0123456789ABCDEF";
 
+static VOID
+convert_mac2hex(UINT8 *hw_addr,INTN l, CHAR16 *str)
+{
+       UINTN i;
+
+       for (i=0 ; i < l; i++) {
+               str[3*i] = hexa[(hw_addr[i] & 0xf0)>>4];
+               str[3*i+1] = hexa[hw_addr[i] & 0x0f];
+               str[3*i+2] = ':';
+       }
+       str[3*l-1]='\0';
+}
+
 static VOID
 convert_ip2hex(UINT8 *ip, INTN l, CHAR16 *str)
 {
@@ -153,6 +166,8 @@ netfs_setdefaults(VOID *intf, config_file_t *config, CHAR16 *kname, UINTN maxlen
        set_var(VAR_NETFS_DOMAINAME, info.domainame);
 
        if (info.using_pxe) {
+               DBG_PRT((L"netfs_setdefaults: using_pxe"));
+
                status = netfs->netfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config[0].fname);
                if (EFI_ERROR(status)) {
                        StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);
@@ -181,6 +196,8 @@ netfs_setdefaults(VOID *intf, config_file_t *config, CHAR16 *kname, UINTN maxlen
 #  endif            
 
 #  define CONFIG_EXTENSION L".conf\0"
+
+               DBG_PRT((L"netfs_setdefaults: machine specific (!using_pxe)"));
                /*
                 * will try machine/subnet specific files first.
                 * the filenames are constructed based on the IP(v4) address
@@ -206,6 +223,12 @@ netfs_setdefaults(VOID *intf, config_file_t *config, CHAR16 *kname, UINTN maxlen
 
                StrnCpy(config[6].fname, str, maxlen-1);
                StrnCpy(config[6].fname+2, CONFIG_EXTENSION, 6);
+
+               /* use the MAC address as a possible file name as well */
+               convert_mac2hex(info.hw_addr,6,str);
+               StrnCpy(config[7].fname, str, maxlen-1);
+               StrnCpy(config[7].fname+17, CONFIG_EXTENSION, 6);
+
 #else
                StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);
                config[0].fname[maxlen-1] = CHAR_NULL;
index 6e4e05685a3720bc34108a84229a25031b5ccc94..bb00632f1c260d359f48eac4794c3b6b4e1ee6e0 100644 (file)
@@ -169,7 +169,7 @@ bzImage_probe(CHAR16 *kname)
                         kernel_start));
         }
 
-        kernel_load_address = kernel_start;
+        kernel_load_address = NULL; /* allocate anywhere! */
 
         if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
                 /*
index 078d40650a2aca096be6704653f0549a65b7e544..520946a44f1aaf9fe870b573da2ef9594bb2b9fb 100644 (file)
@@ -149,6 +149,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
        return 0;
 }
 
+VOID *
+sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
+{
+       return start_addr;
+}
+
 VOID
 sysdeps_free_boot_params(boot_params_t *bp)
 {
@@ -201,7 +207,19 @@ static INTN get_video_info(boot_params_t * bp) {
                        (VOID **)Gop_handle);
 
        if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
-               ERR_PRT((L"LocateHandle GopProtocol failed."));
+                Print(L"LocateHandle GopProtocol failed.\n");
+                Print(L"--Either no graphics head is installed,\n" \ 
+                       "--efi console is set to serial, or,\n" \
+                       "--the EFI firmware version of this machine is\n" \
+                       "--older than UEFI 2.0. and does not support GOP");
+                Print(L"you can SAFELY IGNORE this error. elilo will\n" \
+                       "default to text-mode.\n Alternatively you can " \
+                       "now force text mode by setting config variable\n" \
+                       "text_mode=1 for x86 in elilo.conf or via cmdline.\n\n");
+                Print(L"However if this is the last text output you see\n" \
+                       "ensure that your kernel console command line\n " \
+                       "variable matches up with the actual efi boot menu\n" \
+                       "console output settings. for example efi console\n\n");
                return -1;
        }
        Gop_handle = alloc(size, 0);
index 2530a3b513544af00cf436ff21f177327a07ddd7..2f4223db56c52a7bb783a3637510dfe10216f384 100644 (file)
@@ -140,6 +140,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
        return 0;
 }
 
+VOID *
+sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
+{
+       return start_addr;
+}
+
 /* Flush data cache [addr; addr + len], and sync with icache.  */
 void
 flush_dcache (CHAR8 *addr, UINT64 len)
index 581abda225eeb66b2fb382892e26dfe402f84127..7a68bb37e9852d67cccb2ab4749590a0ed8ae334 100644 (file)
--- a/initrd.c
+++ b/initrd.c
@@ -41,7 +41,11 @@ INTN
 load_file(CHAR16 *filename, memdesc_t *image)
 {
        EFI_STATUS status;
-       VOID *start_addr = NULL;
+       /*
+        * Actually using the value from sysdeps_initrd_get_addr()
+        * instead of NULL is no change for ia64!
+        */
+       VOID *start_addr = image->start_addr;
        UINTN pgcnt;
        UINT64 size = 0;
        fops_fd_t fd;
@@ -71,7 +75,11 @@ load_file(CHAR16 *filename, memdesc_t *image)
        /* round up to get required number of pages (4KB) */
        image->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(image->size);
 
-       start_addr = alloc_pages(pgcnt, EfiLoaderData, start_addr ? AllocateAddress : AllocateAnyPages, 0 );
+       start_addr = alloc_pages(pgcnt, EfiLoaderData,
+               start_addr ? AllocateAddress : AllocateAnyPages, start_addr);
+
+       start_addr = sysdeps_checkfix_initrd(start_addr, image);
+
        if (start_addr == NULL) {
                ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt,
                         filename));
index b47a58e860e7914e103e90908ff6364aa47bd688..98a66a45e360f1cd568c520b72ea6dd14d076460 100644 (file)
--- a/strops.c
+++ b/strops.c
@@ -41,11 +41,11 @@ StrnCpy(OUT CHAR16 *dst, IN const CHAR16 *src, IN UINTN size)
 {
        CHAR16 *res = dst;
 
-       while (size-- && (*dst++ = *src++) != CHAR_NULL);
+       while (size && size-- && (*dst++ = *src++) != CHAR_NULL);
        /*
         * does the null padding
         */
-       while (size-- > 0) *dst++ = CHAR_NULL;
+       while (size && size-- > 0) *dst++ = CHAR_NULL;
 
        return res;
 }
@@ -55,11 +55,11 @@ StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, IN UINTN size)
 {
        CHAR8 *res = dst;
 
-       while (size-- && (*dst++ = (CHAR8)*src++) != '\0');
+       while (size && size-- && (*dst++ = (CHAR8)*src++) != '\0');
        /*
         * does the null padding
         */
-       while (size-- > 0) *dst++ = '\0';
+       while (size && size-- > 0) *dst++ = '\0';
 
        return res;
 }
@@ -76,11 +76,11 @@ strncpya(OUT CHAR8 *dst, IN const CHAR8 *src, IN UINTN size)
 {
        CHAR8 *res = dst;
 
-       while (size-- && (*dst++ = *src++) != '\0');
+       while (size && size-- && (*dst++ = *src++) != '\0');
        /*
         * does the null padding
         */
-       while (size-- > 0) *dst++ = '\0';
+       while (size && size-- > 0) *dst++ = '\0';
 
        return res;
 }
index 1c9709a11f950f55b491778723bbbb3ba0158e3c..8af2bf241eb855459c916ef02d55a9d166a6d946 100644 (file)
 #define ELILOALT_VERSION       "0.02"
 
 #define ELILO_ALT_NAME "EliloAlt"
-#define EFIVAR_DIR     "/proc/efi/vars"
+#define EFIVAR_DIR     "/sys/firmware/efi/vars"
+#define OFIVAR_DIR     "/proc/efi/vars"
 #define ELILO_ALTVAR   EFIVAR_DIR"/"ELILO_ALT_NAME"-00000000-0000-0000-0000-000000000000"
+#define OLILO_ALTVAR   OFIVAR_DIR"/"ELILO_ALT_NAME"-00000000-0000-0000-0000-000000000000"
 
 #define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
@@ -80,7 +82,9 @@ typedef struct _efi_variable_t {
         uint32_t        attributes;
 } __attribute__((packed)) efi_variable_t;
 
+static char *efivar_dir = EFIVAR_DIR;
 static char *elilo_alt_name = ELILO_ALT_NAME;
+static char *elilo_altvar = ELILO_ALTVAR;
 
 static struct option cmd_options[]={
        { "version", 0, 0, 1},
@@ -129,9 +133,15 @@ check_proc_efi(int find_entry)
        if (getuid() != 0) {
                fatal_error("This program must be run as root\n");
        }
-       efi_vars = opendir(EFIVAR_DIR);
+       efi_vars = opendir(efivar_dir);
        if (efi_vars == NULL) {
-               fatal_error("Cannot access %s\n", EFIVAR_DIR);
+               efivar_dir = OFIVAR_DIR;
+               elilo_altvar = OLILO_ALTVAR;
+               efi_vars = opendir(efivar_dir);
+       }
+       if (efi_vars == NULL) {
+               fatal_error("Can access neither %s nor %s\n",
+                           EFIVAR_DIR, efivar_dir);
        }
        if (!find_entry) {
                closedir(efi_vars);
@@ -143,9 +153,10 @@ check_proc_efi(int find_entry)
                        break;
        }
        if (entry == NULL) {
-               fatal_error("Cannot find entry in %s\n", EFIVAR_DIR);
+               fatal_error("Cannot find entry in %s\n", efivar_dir);
        }
-       sprintf(name, "%s/%s", EFIVAR_DIR, entry->d_name);
+       snprintf(name, 1023, "%s/%s", efivar_dir, entry->d_name);
+       name[1023] = 0;
        closedir(efi_vars);
        return name;
 }
@@ -158,7 +169,7 @@ delete_var(void)
 
        check_proc_efi(0);
 
-       fd = open(ELILO_ALTVAR, O_WRONLY);
+       fd = open(elilo_altvar, O_WRONLY);
        if (fd == -1) {
                fatal_error("variable not defined\n");
        }
@@ -176,7 +187,7 @@ delete_var(void)
        
        r = write(fd, &var, sizeof(var));
        if (r != sizeof(var)) {
-               fatal_error("Variable %s defined but invalid content\n", ELILO_ALTVAR);
+               fatal_error("Variable %s defined but invalid content\n", elilo_altvar);
        }
        close(fd);
 }
@@ -191,7 +202,7 @@ print_var(void)
 
        check_proc_efi(0);
 
-       fd = open(ELILO_ALTVAR, O_RDONLY);
+       fd = open(elilo_altvar, O_RDONLY);
        if (fd == -1) {
                fatal_error("variable not defined\n");
        }
@@ -200,7 +211,7 @@ print_var(void)
 
        r = read(fd, &var, sizeof(var));
        if (r != sizeof(var)) {
-               fatal_error("Variable %s defined but invalid content\n", ELILO_ALTVAR);
+               fatal_error("Variable %s defined but invalid content\n", elilo_altvar);
        }
        printf("EliloAlt=\"");
        for(i=0; i < var.datasize; i+=1){
@@ -231,7 +242,7 @@ set_var(char *cmdline)
 
        fd = open(name, O_WRONLY);
        if (fd == -1) {
-               fatal_error("can't open %s: %s\n", ELILO_ALTVAR, strerror(errno));
+               fatal_error("can't open %s: %s\n", elilo_altvar, strerror(errno));
        }
 
        memset(&var, 0, sizeof(var));
@@ -256,7 +267,7 @@ set_var(char *cmdline)
        
        r = write(fd, &var, sizeof(var));
        if (r != sizeof(var)) {
-               fatal_error("Variable %s defined but invalid content %d\n", ELILO_ALTVAR, r);
+               fatal_error("Variable %s defined but invalid content %d\n", elilo_altvar, r);
        }
        close(fd);
 
index e3c7c6bb31a00e12066454538bd1b83b3730e3d4..9be4bd662f1c7c321cbb3b761c496676783055d2 100644 (file)
@@ -36,6 +36,129 @@ UINTN param_size = 0;
 
 UINTN kernel_size = 0x800000;  /* 8M (default x86_64 bzImage size limit) */
 
+static VOID *
+bzImage_alloc()
+{
+       UINTN pages = EFI_SIZE_TO_PAGES(kernel_size);
+       int reloc_kernel = 0;
+       VOID *kla, *kend = kernel_start + kernel_size;
+       UINT32 kalign, kmask;
+       boot_params_t *ps = param_start;
+
+       /*
+        * Get address for kernel from header, if applicable & available.
+        */
+       if ((ps->s.hdr_major < 2) ||
+           (ps->s.hdr_major == 2 && ps->s.hdr_minor < 5)) {
+               reloc_kernel = 0;
+       } else {
+               if (ps->s.kernel_start >= DEFAULT_KERNEL_START)
+                       kernel_start = (void *)(UINT64)ps->s.kernel_start;
+               reloc_kernel = ps->s.relocatable_kernel;
+               kalign = ps->s.kernel_alignment;
+               kmask = kalign - 1;
+               VERB_PRT(3, Print(L"kernel header (%d.%d) suggests kernel "
+                       "start at address "PTR_FMT" (%srelocatable!)\n",
+                       ps->s.hdr_major, ps->s.hdr_minor, ps->s.kernel_start,
+                       (reloc_kernel ? L"": L"not ")));
+       }
+
+       /*
+        * Best effort for old (< 2.6.20) and non-relocatable kernels
+        */
+       if (alloc_kmem(kernel_start, pages) == 0) {
+               VERB_PRT(3, Print(L"kernel_start: "PTR_FMT" kernel_size: %d\n",
+                       kernel_start, kernel_size));
+               return kernel_start;
+       } else if ( ! reloc_kernel ) {
+               /*
+                * Couldn't get desired address--just load it anywhere and
+                * (try to) move it later.  It's the only chance for non-
+                * relocatable kernels, but it breaks occassionally...
+                */
+               ERR_PRT((L"Kernel header (%d.%d) suggests kernel "
+                       "start at address "PTR_FMT" (non relocatable!)\n"
+                       "This address is not available, so an attempt"
+                       "is made to copy the kernel there later on\n"
+                       "BEWARE: this is unsupported and may not work.  "
+                       "Please update your kernel.\n",
+                       ps->s.hdr_major, ps->s.hdr_minor, ps->s.kernel_start));
+               kla = (VOID *)(UINT32_MAX - kernel_size);
+               /* NULL would preserve the "anywhere" semantic, */
+               /* but it would not prevent allocation above 4GB! */
+
+               if (alloc_kmem_anywhere(&kla, pages) != 0) {
+                       /* out of luck */
+                       return NULL;
+               }
+               VERB_PRT(3, Print(L"kernel_start: "PTR_FMT
+                       "  kernel_size: %d  loading at: "PTR_FMT"\n",
+                       kernel_start, kernel_size, kla));
+               return kla;
+       }
+
+
+       /* Is 'ps->s.kernel_alignment' guaranteed to be sane? */
+       if (kalign < EFI_PAGE_SIZE) {
+               kalign = EFI_PAGE_SIZE;
+               kmask = EFI_PAGE_MASK;
+       }
+       DBG_PRT((L"alignment: kernel=0x%x efi_page=0x%x : 0x%x\n",
+               ps->s.kernel_alignment, EFI_PAGE_SIZE, kalign));
+
+       /*
+        * Couldn't get the preferred address, but luckily it's
+        * a relocatable kernel, so ...
+        *
+        * 1. use 'find_kernel_memory()' (like Itanium)
+        * 2. try out the 16 lowest possible aligned addresses (> 0)
+        * 3. get enough memory to align "creatively"
+        * 4. forget alignment (and start praying)...
+        */
+
+       /* 1. */
+       if ((find_kernel_memory(kernel_start, kend, kalign, &kla) != 0) ||
+           (alloc_kmem(kla, pages) != 0)) {
+               kla = NULL;
+       }
+
+       /* 2. */
+       if ( ! kla && (UINT64)kernel_start < kalign ) {
+               int i;
+               for ( i = 1; i < 16 && !kla; i++ ) {
+                       VOID *tmp = (VOID *)((UINT64)kalign * i);
+                       if (alloc_kmem(tmp, pages) == 0) {
+                               kla =  tmp;
+                       }
+               }
+       }
+
+       /* 3. */
+       if ( ! kla ) {
+               UINTN apages = EFI_SIZE_TO_PAGES(kernel_size + kmask);
+               kla = (VOID *)(UINT32_MAX - kernel_size - kmask);
+
+               if (alloc_kmem_anywhere(&kla, apages) == 0) {
+                       kla = (VOID *)(((UINT64)kla + kmask) & ~kmask);
+               } else {
+                       kla = NULL;
+               }
+       }
+
+       /* 4. last resort */
+       if ( ! kla ) {
+               kla = (VOID *)(UINT32_MAX - kernel_size);
+               if (alloc_kmem_anywhere(&kla, pages) != 0) {
+                       return NULL;
+               }
+       }
+
+       kernel_start = kla;
+       VERB_PRT(1, Print(L"relocating kernel_start: "PTR_FMT
+               "  kernel_size: %d\n", kernel_start, kernel_size));
+       return kla;
+}
+
 static INTN
 bzImage_probe(CHAR16 *kname)
 {
@@ -158,53 +281,34 @@ bzImage_probe(CHAR16 *kname)
         * Allocate memory for kernel.
         */
 
-       /*
-        * Get correct address for kernel from header, if applicable & available. 
-        */
-       if ((param_start->s.hdr_major == 2) &&
-           (param_start->s.hdr_minor >= 6) &&
-           (param_start->s.kernel_start >= DEFAULT_KERNEL_START)) {
-               kernel_start = (void *)param_start->s.kernel_start;
-               VERB_PRT(3, Print(L"kernel header suggests kernel start at address "PTR_FMT"\n", 
-                       kernel_start));
-       }
-
-       kernel_load_address = kernel_start;
-
-       if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
-               /*
-                * Couldn't get desired address--just load it anywhere and move it later.
-                * (Easier than relocating kernel, and also works with non-relocatable kernels.)
-                */
-               if (alloc_kmem_anywhere(&kernel_load_address, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
-                       ERR_PRT((L"Could not allocate memory for kernel."));
-                       free(param_start);
-                       param_start = NULL;
-                       param_size = 0;
-                       fops_close(fd);
-                       return -1;
-               }
+       kernel_load_address = bzImage_alloc();
+       if ( ! kernel_load_address ) {
+               ERR_PRT((L"Could not allocate memory for kernel."));
+               free(param_start);
+               param_start = NULL;
+               param_size = 0;
+               fops_close(fd);
+               return -1;
        }
 
-       VERB_PRT(3, Print(L"kernel_start: "PTR_FMT"  kernel_size: %d  loading at: "PTR_FMT"\n", 
-               kernel_start, kernel_size, kernel_load_address));
-
        /*
         * Now read the rest of the kernel image into memory.
         */
 
-       DBG_PRT((L"reading kernel image...\n"));
+       Print(L"Loading kernel %s... ", kname);
 
        size = kernel_size;
        efi_status = fops_read(fd, kernel_load_address, &size);
        if (EFI_ERROR(efi_status) || size < 0x10000) {
-               ERR_PRT((L"Error reading kernel image %s.", kname));
+               ERR_PRT((L"Error reading kernel image (0x%x).", efi_status));
                free(param_start);
                param_start = NULL;
                param_size = 0;
                fops_close(fd);
                free_kmem();
                return -1;
+       } else {
+               Print(L" done\n");
        }
 
        DBG_PRT((L"kernel image read:  %d bytes, %d Kbytes\n", size, size / 1024));
index e8d46206b6fc43608cc32ad04bf3aa5d386ea774..59e7b10c5f9e62f9d92e525f7de249757da6312a 100644 (file)
 
 typedef struct {
        UINTN legacy_free_boot;
+       UINTN text_mode;
 } x86_64_global_config_t;
 
 
+#define x86_64_opt_offsetof(option)    (&((sys_img_options_t *)(0x0))->option)
+
 static x86_64_global_config_t x86_64_gconf;
 
 static config_option_t sysdeps_global_options[]={
        {OPT_BOOL,      OPT_GLOBAL, L"legacy-free",     NULL,   NULL,   &x86_64_gconf.legacy_free_boot}
 };
 
+static config_option_t sysdeps_image_options[]={
+       {OPT_BOOL,      OPT_IMAGE_SYS, L"text-mode",    NULL,   NULL,   x86_64_opt_offsetof(text_mode)}
+};
+
+
 /*
  * X86_64 operations that need to be done only once and just before 
  * entering the main loop of the loader
@@ -81,6 +89,14 @@ x86_64_use_legacy_free_boot(VOID)
        return x86_64_gconf.legacy_free_boot ? 1 : 0;
 }
 
+
+INTN
+x86_64_text_mode(VOID)
+{
+       return (elilo_opt.sys_img_opts &&
+               elilo_opt.sys_img_opts->text_mode == TRUE) ? 1 : 0;
+}
+
 INTN
 sysdeps_register_options(VOID)
 {
@@ -89,14 +105,11 @@ sysdeps_register_options(VOID)
        ret = register_config_options(sysdeps_global_options, 
                                      sizeof(sysdeps_global_options)/sizeof(config_option_t),
                                      OPTIONS_GROUP_GLOBAL);
-#if 0
-       /* no per image options yet */
        if (ret == -1 ) return ret;
 
        ret = register_config_options(sysdeps_image_options, 
                                      sizeof(sysdeps_image_options)/sizeof(config_option_t),
                                      OPTIONS_GROUP_IMAGE);
-#endif
 
        return ret;
 }
index 338aa40bfbb6aa4ed28f2e543fe6ad0dfc52b559..ff99eef220cd8709da84fdd9de5e9410f67e4f12 100644 (file)
@@ -107,12 +107,12 @@ typedef union x86_64_boot_params {
 /* 0x06 */     UINT8 orig_video_mode;          /* LDR */
 /* 0x07 */     UINT8 orig_video_cols;          /* LDR */
 
-/* 0x08 */     UINT16 unused_1;                /* unused */
+/* 0x08 */     UINT16 pad_1;                   /* unused */
 
 /* %%TBD */
 /* 0x0A */     UINT16 orig_ega_bx;             /* LDR */
 
-/* 0x0C */     UINT16 unused_2;                /* unused */
+/* 0x0C */     UINT16 pad_2;                   /* unused */
 
 /* Screen height before passing control to kernel. */
 /* 0x0E */     UINT8 orig_video_rows;          /* LDR */
@@ -174,7 +174,7 @@ typedef union x86_64_boot_params {
 /* 0x4E */     UINT32 bios_code_len;           /* LDR */
 /* 0x52 */     UINT16 bios_data_len;           /* LDR */
 
-/* 0x54 */     UINT8 unused_3[0x2C];           /* unused */
+/* 0x54 */     UINT8 pad_3[0x2C];              /* unused */
 
 /* %%TBD */
 /* 0x80 */     UINT8 hd0_info[0x10];           /* LDR */
@@ -184,7 +184,7 @@ typedef union x86_64_boot_params {
 /* 0xA0 */     UINT16 mca_info_len;            /* LDR */
 /* 0xA2 */     UINT8 mca_info_buf[0x10];       /* LDR */
 
-/* 0xB2 */     UINT8 unused_4[0x10E];          /* unused */
+/* 0xB2 */     UINT8 pad_4[0x10E];             /* unused */
 
 /* EFI boot loader signature. */
 /* 0x1C0 */    UINT8 efi_loader_sig[4];        /* LDR */
@@ -209,9 +209,9 @@ typedef union x86_64_boot_params {
 /* Available contiguous extended memory in KB. */
 /* 0x1E0 */    UINT32 alt_mem_k;               /* LDR */
 
-/* 0x1E4 */    UINT32 unused_51;               /* unused */
+/* 0x1E4 */    UINT32 pad_51;                  /* unused */
 /* 0x1E8 */    UINT8 e820_nrmap;
-/* 0x1E9 */    UINT32 unused_52[2];            /* unused */
+/* 0x1E9 */    UINT32 pad_52[2];               /* unused */
 
 /* Size of setup code in sectors (1 sector == 512 bytes). */
 /* 0x1F1 */    UINT8 setup_sectors;            /* BLD */
@@ -220,15 +220,10 @@ typedef union x86_64_boot_params {
 /* 0x1F2 */    UINT16 mount_root_rdonly;       /* BLD */
 
 /* %%TBD */
-/* 0x1F4 */    UINT16 sys_size;                /* BLD */
+/* 0x1F4 */    UINT32 sys_size;                /* BLD */
 
 /* %%TBD */
-/* 0x1F6 */    UINT16 swap_dev;                /* BLD */
-
-/* %%TBD */
-/* 0x1F8 */    UINT16 ramdisk_flags;           /* BLD */
-#define RAMDISK_PROMPT         0x8000
-#define RAMDISK_LOAD           0x4000
+/* 0x1F8 */    UINT16 ram_size_DNU;            /* BLD */
 
 /* %%TBD */
 /* 0x1FA */    UINT16 video_mode_flag;         /* BLD */
@@ -236,12 +231,8 @@ typedef union x86_64_boot_params {
 /* %%TBD */
 /* 0x1FC */    UINT16 orig_root_dev;           /* BLD */
 
-/* 0x1FE */    UINT8 unused_6;                 /* unused */
-
 /* %%TBD */
-/* 0x1FF */    UINT8 aux_dev_info;             /* LDR */
-#define NO_MOUSE               0x00
-#define FOUND_MOUSE            0xAA
+/* 0x1FE */    UINT16 boot_flag;               /* ? */
 
 /* Jump past setup data (not used in EFI). */
 /* 0x200 */    UINT16 jump;                    /* BLD */
@@ -283,16 +274,21 @@ typedef union x86_64_boot_params {
 /* 0x21C */    UINT32 initrd_size;             /* LDR */
 
 /* %%TBD */
-/* 0x220 */    UINT32 bootsect_helper;         /* BLD */
+/* 0x220 */    UINT32 bootsect_helper_DNU;     /* BLD */
 
 /* %%TBD */
 /* 0x224 */    UINT16 heap_end_ptr;            /* LDR */
 
 /* %%TBD */
-/* 0x226 */    UINT16 unused_7;                /* LDR */
+/* 0x226 */    UINT8 ext_loader_ver;           /* LDR */
+/* 0x227 */    UINT8 ext_loader_type;          /* LDR */
 
 /* 0x228 */    UINT32 cmdline_addr;            /* LDR */
-/* 0x22C */    UINT32 unused_8[41];
+/* 0x22C */    UINT32 initrd_addr_max;         /* BLD */
+/* 0x230 */    UINT32 kernel_alignment;        /* BLD */
+/* 0x234 */    UINT8 relocatable_kernel;       /* BLD */
+/* 0x235 */    UINT8 pad_8[3];
+/* 0x238 */    UINT32 pad_9[38];
 /* 0x2D0 */    UINT8  e820_map[2560];
        } s;
 } boot_params_t;
@@ -368,6 +364,7 @@ extern UINT8 rmswitch_image[];
 extern UINTN rmswitch_size;
 
 extern INTN x86_64_use_legacy_free_boot();
+extern INTN x86_64_text_mode();
 
 /*
  * How to jump to kernel code
@@ -382,7 +379,6 @@ start_kernel(VOID *kentry, boot_params_t *bp)
                UINT16  kernel_cs;
        } jumpvector;
        VOID    *jump_start;
-       uint64_t temp;
 
        /*
         * Disable interrupts.
@@ -390,22 +386,16 @@ start_kernel(VOID *kentry, boot_params_t *bp)
        asm volatile ( "cli" : : );
 
        /*
-        * Relocate kernel (if needed), and initrd (if present).
-        * Copy kernel first, in case kernel was loaded overlapping where we're
-        * planning to copy the initrd.  This assumes that the initrd didn't
-        * get loaded overlapping where we're planning to copy the kernel, but
-        * that's pretty unlikely since we couldn't alloc that space for the
-        * kernel (or the kernel would already be there).
+        * Relocate kernel (if needed).
+        * This assumes that the initrd didn't get loaded overlapping where
+        * we're planning to copy the kernel, but that's pretty unlikely
+        * since we couldn't alloc that space for the kernel (or the kernel
+        * would already be there).
         */
        if (kernel_start != kernel_load_address) {
                MEMCPY(kernel_start, kernel_load_address, kernel_size);
        }
 
-       if (bp->s.initrd_start) {
-               temp =  bp->s.initrd_start;
-               MEMCPY(INITRD_START, temp , bp->s.initrd_size);
-               bp->s.initrd_start = INITRD_START;
-       }
        /*
         * Copy boot sector, setup data and command line
         * to final resting place.  We need to copy
@@ -468,7 +458,8 @@ start_kernel(VOID *kentry, boot_params_t *bp)
 }
 
 typedef struct sys_img_options {
-       UINT8 nothing_yet;
+       UINT8 dummy;     /* forces non-zero offset for first field */
+       UINT8 text_mode; /* do not try to initialize Graphics Output Protocol */
 } sys_img_options_t;
 
 #endif /* __ELILO_SYSDEPS_X86_64_H__ */
index 6874acc51aa32e2eea7b9d07231a06e916211624..44c2e467a6f3f05d2f33028c11d0c9d1405cc99f 100644 (file)
  */
 #include <efi.h>
 #include <efilib.h>
+#include <string.h>
 
 #include "elilo.h"
 #include "loader.h"
 #include "rmswitch.h"
 
+#define DEBUG_CREATE_BOOT_PARAMS 0
+#if DEBUG_CREATE_BOOT_PARAMS
+#define DPR(a) do { if (elilo_opt.debug) { Print a; } } while ( 0 )
+#else
+#define DPR(a)
+#endif
+
 extern loader_ops_t bzimage_loader, plain_loader, gzip_loader; 
 
 /*
@@ -105,14 +113,16 @@ UINTN high_base_mem = 0x90000;
 UINTN high_ext_mem = 32 * 1024 * 1024;
 
 /* This starting address will hold true for all of the loader types for now */
-VOID *kernel_start = (void *)DEFAULT_KERNEL_START;
+VOID *kernel_start = (VOID *)DEFAULT_KERNEL_START;
 
 /* The kernel may load elsewhere if EFI firmware reserves kernel_start */
-VOID *kernel_load_address = DEFAULT_KERNEL_START; 
+VOID *kernel_load_address = (VOID *)DEFAULT_KERNEL_START;
 
 VOID *initrd_start = NULL;
 UINTN initrd_size = 0;
 
+INTN e820_map_overflow = 0;
+
 INTN
 sysdeps_init(EFI_HANDLE dev)
 {
@@ -131,10 +141,8 @@ sysdeps_init(EFI_HANDLE dev)
 /*
  * initrd_get_addr()
  *     Compute a starting address for the initial RAMdisk image.
- *     For now, this image is placed immediately after the end of
- *     the kernel memory.  Inside the start_kernel() code, the
- *     RAMdisk image will be relocated to the top of available
- *     extended memory.
+ *     For now we suggest 'initrd_addr_max' with room for 32MB,
+ *     as image->pgcnt is not initialized yet.
  */
 INTN
 sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
@@ -146,10 +154,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
                return -1;
        }
 
-       VERB_PRT(3, Print(L"kstart="PTR_FMT"  kentry="PTR_FMT"  kend="PTR_FMT"\n", 
-               kd->kstart, kd->kentry, kd->kend));
+       VERB_PRT(3, Print(L"initrd_addr_max="PTR_FMT" reserve=%d\n",
+               param_start->s.initrd_addr_max, 32*MB));
 
-       imem->start_addr = kd->kend;
+       imem->start_addr = (VOID *)
+               (((UINT64)param_start->s.initrd_addr_max - 32*MB + 1)
+               & ~EFI_PAGE_MASK);
 
        VERB_PRT(3, Print(L"initrd start_addr="PTR_FMT" pgcnt=%d\n", 
                imem->start_addr, imem->pgcnt));
@@ -157,6 +167,48 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
        return 0;
 }
 
+
+/*
+ * checkfix_initrd()
+ *     Check and possibly fix allocation of initrd memory.
+ */
+VOID *
+sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
+{
+       UINTN pgcnt =  EFI_SIZE_TO_PAGES(imem->size);
+       UINT64 initrd_addr_max = (UINT64)param_start->s.initrd_addr_max;
+       UINT64 ki_max = initrd_addr_max - imem->size + 1;
+       VOID *ki_max_addr;
+
+       VERB_PRT( 3, Print(L"loadfile: start_addr="PTR_FMT
+               " ki_max_addr="PTR_FMT"\n", start_addr, (VOID *)ki_max));
+       if (ki_max > UINT32_MAX) {
+               ERR_PRT((L"Force kernel specified initrd_addr_max="PTR_FMT
+                       " below 4GB\n", (VOID *)initrd_addr_max));
+               ki_max = UINT32_MAX - imem->size + 1;
+       }
+       ki_max_addr = (VOID *)ki_max;
+
+       if ((UINT64)start_addr > ki_max) {
+               VERB_PRT(1, Print(L"initrd start_addr="PTR_FMT" above "
+                       "limit="PTR_FMT"\n", start_addr, ki_max_addr));
+               free(start_addr);
+               start_addr = NULL;
+       }
+       /* so either the initial allocation failed or it's been to high! */
+       if (start_addr == NULL) {
+               start_addr = alloc_pages(pgcnt, EfiLoaderData,
+                       AllocateMaxAddress, ki_max_addr);
+       }
+       if ((UINT64)start_addr > ki_max) {
+               ERR_PRT((L"Failed to allocate %d pages below %dMB",
+                       pgcnt, (param_start->s.initrd_addr_max+1)>>20));
+               free(start_addr);
+               start_addr = NULL;
+       }
+       return start_addr;
+}
+
 VOID
 sysdeps_free_boot_params(boot_params_t *bp)
 {
@@ -199,6 +251,10 @@ static INTN get_video_info(boot_params_t * bp) {
         UINTN size1;
         UINT8 i;
 
+       if (x86_64_text_mode() == 1) {
+               Print((L"Skip GOP init, force text-mode.\n"));
+               return -1;
+       }
        efi_status = uefi_call_wrapper(
                        BS->LocateHandle,
                        5,
@@ -209,7 +265,19 @@ static INTN get_video_info(boot_params_t * bp) {
                        (VOID **)Gop_handle);
        
        if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
-               ERR_PRT((L"LocateHandle GopProtocol failed."));
+               Print(L"LocateHandle GopProtocol failed.\n");
+               Print(L"--Either no graphics head is installed,\n" \
+                      "--efi console is set to serial, or,\n" \
+                      "--the EFI firmware version of this machine is\n" \
+                      "--older than UEFI 2.0. and does not support GOP");
+               Print(L"you can SAFELY IGNORE this error. elilo will\n" \
+                      "default to text-mode.\n Alternatively you can " \
+                      "now force text mode by setting config variable\n" \
+                      "text_mode=1 for x86 in elilo.conf or via cmdline.\n\n");
+               Print(L"However if this is the last text output you see\n" \
+                      "ensure that your kernel console command line\n " \
+                      "variable matches up with the actual efi boot menu\n" \
+                      "console output settings.\n\n");
                return -1;
        }
        Gop_handle = alloc(size, 0);
@@ -326,10 +394,56 @@ static INTN get_video_info(boot_params_t * bp) {
        return 0;
 }
 
+CHAR16 *
+StrStr(IN const CHAR16 *h, IN const CHAR16 *n)
+{
+       const CHAR16 *t = h;
+       CHAR16 *res;
+       int len = 0, i;
+
+       len = StrLen((CHAR16 *)n);
+       while(*t != CHAR_NULL) {
+         res = StrChr( t, n[0]);
+         if (!res) return res;
+         for( i = 1; i < len && res[i] != CHAR_NULL && res[i] == n[i]; i++);
+         if ( i == len ) return res;
+         t = res + 1;
+         if (t > h + CMDLINE_MAXLEN) return (CHAR16 *)0;
+       }
+
+       return (CHAR16 *)0;
+}
+
+CHAR8 *
+StrStr8(IN const CHAR8 *h, IN const CHAR8 *n)
+{
+       const CHAR8 *t = h;
+       CHAR8 *res;
+       int len = 0, i;
+
+       len = strlena((CHAR8 *)n);
+       while(*t != 0) {
+         res = strchra( t, n[0]);
+         if (!res) return res;
+         for( i = 1; i < len && res[i] != 0 && res[i] == n[i]; i++);
+         if ( i == len ) return res;
+         t = res + 1;
+         if (t > (h + CMDLINE_MAXLEN)) return (CHAR8 *)0;
+       }
+
+       return (CHAR8 *)0;
+}
+
 /* Convert EFI memory map to E820 map for the operating system 
  * This code is based on a Linux kernel patch submitted by Edgar Hucek
  */
 
+#if DEBUG_CREATE_BOOT_PARAMS
+static int e820_max = 6;
+#else
+static int e820_max = E820_MAX;
+#endif
+
 /* Add a memory region to the e820 map */
 static void add_memory_region (struct e820entry *e820_map,
                               int *e820_nr_map,
@@ -338,21 +452,56 @@ static void add_memory_region (struct e820entry *e820_map,
                               unsigned int type)
 {
        int x = *e820_nr_map;
+       static unsigned long long estart = 0ULL;
+       static unsigned long esize = 0L;
+       static unsigned int etype = -1;
+       static int merge = 0;
 
-       if (x == E820_MAX) {
-               Print(L"Too many entries in the memory map!\n");
-               return;
-       }
+       if (x == 0)
+               DPR((L"AMR: %3s %4s %16s/%12s/%s\n",
+                       L"idx", L" ", L"start", L"size", L"type"));
 
+       /* merge adjacent regions of same type */
        if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start
-           && e820_map[x-1].type == type)
+           && e820_map[x-1].type == type) {
                e820_map[x-1].size += size;
-       else {
+               estart = e820_map[x-1].addr;
+               esize  = e820_map[x-1].size;
+               etype  = e820_map[x-1].type;
+               merge++;
+               return;
+       }
+       /* fill up to E820_MAX */
+       if ( x < e820_max ) {
                e820_map[x].addr = start;
                e820_map[x].size = size;
                e820_map[x].type = type;
                (*e820_nr_map)++;
+               if (merge) DPR((L"AMR: %3d ==>  %016llx/%012lx/%d (%d)\n",
+                               x-1, estart, esize, etype, merge));
+               merge=0;
+               DPR((L"AMR: %3d add  %016llx/%012lx/%d\n",
+                       x, start, size, type));
+               return;
        }
+       /* different type means another region didn't fit */
+       /* or same type, but there's a hole */
+       if (etype != type || (estart + esize) != start) {
+               if (merge) DPR((L"AMR: %3d ===> %016llx/%012lx/%d (%d)\n",
+                       e820_map_overflow, estart, esize, etype, merge));
+               merge = 0;
+               estart = start;
+               esize = size;
+               etype = type;
+               e820_map_overflow++;
+               DPR((L"AMR: %3d OVER %016llx/%012lx/%d\n",
+                        e820_map_overflow, start, size, type));
+               return;
+       }
+       /* same type and no hole, merge it */
+       estart += esize;
+       esize += size;
+       merge++;
 }
 
 void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
@@ -431,6 +580,7 @@ void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
                        break;
                default:
                        /* We should not hit this case */
+                       DBG_PRT((L"hit default!?"));
                        add_memory_region(e820_map, &e820_nr_map,
                                          md->PhysicalStart,
                                          md->NumberOfPages << EFI_PAGE_SHIFT,
@@ -444,6 +594,8 @@ void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
 
 /*
  * x86_64 specific boot parameters initialization routine
+ *
+ * Note: debug and verbose messages have already been turned off!
  */
 INTN
 sysdeps_create_boot_params(
@@ -459,6 +611,12 @@ sysdeps_create_boot_params(
        UINT8 row, col;
        UINT8 mode;
        UINT16 hdr_version;
+       UINT8 e820_map_overflow_warned = 0;
+
+#if DEBUG_CREATE_BOOT_PARAMS
+       elilo_opt.debug=1;
+       elilo_opt.verbose=5;
+#endif
 
        DBG_PRT((L"fill_boot_params()\n"));
 
@@ -493,17 +651,9 @@ sysdeps_create_boot_params(
        hdr_version = (bp->s.hdr_major << 8) | bp->s.hdr_minor;
 
        /*
-        * Clear out unused memory in boot sector image.
+        * Do NOT clear out unknown memory in boot sector image.
+        * This breaks boot protocol >= 2.10 (2.6.31).
         */
-       bp->s.unused_1 = 0;
-       bp->s.unused_2 = 0;
-       ZeroMem(&bp->s.unused_3, sizeof bp->s.unused_3);
-       ZeroMem(&bp->s.unused_4, sizeof bp->s.unused_4);
-       ZeroMem(&bp->s.unused_51, sizeof bp->s.unused_51);
-       ZeroMem(&bp->s.unused_52, sizeof bp->s.unused_52);
-       bp->s.unused_6 = 0;
-       bp->s.unused_7 = 0;
-       ZeroMem(bp->s.unused_8, sizeof bp->s.unused_8);
 
        /*
         * Tell kernel this was loaded by an advanced loader type.
@@ -553,19 +703,19 @@ sysdeps_create_boot_params(
        DBG_PRT((L"initrd->start_addr="PTR_FMT"  initrd->pgcnt=%d\n",
                initrd->start_addr, initrd->pgcnt));
 
-       /* These RAMdisk flags are not needed, just zero them. */
-       bp->s.ramdisk_flags = 0;
+       /* These RAMdisk flags are not needed, just zero them. NOT!*/
+       /* 'ramdisk_flags' (@0x1F8) is called 'ram_size' in the meantime, */
+       /* see Documentation/x86/boot.txt. */
 
        if (initrd->start_addr && initrd->pgcnt) {
+               if ( (UINT64)initrd->start_addr > UINT32_MAX ) {
+                       ERR_PRT((L"Start of initrd out of reach (>4GB)."));
+                       free_kmem();
+                       return -1;
+               }
                /* %%TBD - This will probably have to be changed. */
                bp->s.initrd_start = (UINT32)(UINT64)initrd->start_addr;
                bp->s.initrd_size = (UINT32)(initrd->size);
-               /*
-                * This is the RAMdisk root device for RedHat 2.2.x
-                * kernels (major 0x01, minor 0x00).
-                */
-
-               bp->s.orig_root_dev = 0x0100;
        } else {
                bp->s.initrd_start = 0;
                bp->s.initrd_size = 0;
@@ -589,11 +739,6 @@ sysdeps_create_boot_params(
        bp->s.mca_info_len = 0;
        ZeroMem(bp->s.mca_info_buf, sizeof bp->s.mca_info_buf);
 
-       /*
-        * Pointing device presence.  The kernel will detect this.
-        */
-       bp->s.aux_dev_info = NO_MOUSE;
-
        /*
         * EFI loader signature 
         */
@@ -602,6 +747,11 @@ sysdeps_create_boot_params(
        /*
         * Kernel entry point.
         */
+       if ( (UINT64)kernel_start != (UINT32)(UINT64)kernel_start ) {
+               ERR_PRT((L"Start of kernel (will be) out of reach (>4GB)."));
+               free_kmem();
+               return -1;
+       }
        bp->s.kernel_start = (UINT32)(UINT64)kernel_start;
 
        /*
@@ -692,11 +842,9 @@ sysdeps_create_boot_params(
                CHECK_OFFSET(setup_sectors, 0x1F1, L"%xh");
                CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
                CHECK_OFFSET(sys_size, 0x1F4, L"%xh");
-               CHECK_OFFSET(swap_dev, 0x1F6, L"%xh");
-               CHECK_OFFSET(ramdisk_flags, 0x1F8, L"%xh");
                CHECK_OFFSET(video_mode_flag, 0x1FA, L"%xh");
                CHECK_OFFSET(orig_root_dev, 0x1FC, L"%xh");
-               CHECK_OFFSET(aux_dev_info, 0x1FF, L"%xh");
+               CHECK_OFFSET(boot_flag, 0x1FE, L"%xh");
                CHECK_OFFSET(jump, 0x200, L"%xh");
                CHECK_OFFSET(setup_sig, 0x202, L"'%-4.4a'");
                CHECK_OFFSET(hdr_minor, 0x206, L"%xh");
@@ -710,9 +858,9 @@ sysdeps_create_boot_params(
                CHECK_OFFSET(kernel_start, 0x214, L"%xh");
                CHECK_OFFSET(initrd_start, 0x218, L"%xh");
                CHECK_OFFSET(initrd_size, 0x21C, L"%xh");
-               CHECK_OFFSET(bootsect_helper, 0x220, L"%xh");
                CHECK_OFFSET(heap_end_ptr, 0x224, L"%xh");
                CHECK_OFFSET(cmdline_addr, 0x228, L"%xh");
+               CHECK_OFFSET(e820_map, 0x2D0, L"%xh");
 
                if (test) {
                        ERR_PRT((L"Boot sector and/or setup parameter alignment error."));
@@ -802,6 +950,31 @@ do_memmap:
         * and update the bootparam accordingly
         */
        fill_e820map(bp, &mdesc);
+
+#if DEBUG_CREATE_BOOT_PARAMS
+       if ( e820_map_overflow == 0 )
+               e820_map_overflow = -1; /* force second get_memmap()! */
+#endif
+       if (e820_map_overflow && !e820_map_overflow_warned) {
+               CHAR8 *aem = (CHAR8 *)"add_efi_memmap";
+               e820_map_overflow_warned++;
+
+#if DEBUG_CREATE_BOOT_PARAMS
+               elilo_opt.debug=0;
+               elilo_opt.verbose=0;
+#endif
+               if (e820_map_overflow == -1 || StrStr8(cmdline, aem)) {
+                       /* Print(L"...mapping again, silently!\n"); */
+                       goto do_memmap;
+               }
+
+               Print(L"\nCAUTION: EFI memory map has %d more entr%a"
+                       " than E820 map supports.\n"
+                       "To access all memory, '%a' may be necessary.\n\n",
+                       e820_map_overflow, (e820_map_overflow==1)?"y":"ies",
+                       aem);
+               goto do_memmap;
+       }
        
        return 0;
 }