Stephane Eranian 2011-01-13 08:46:45 -05:00 committed by Vincent Batts
parent e351d8fbea
commit 82f7288853
29 changed files with 659 additions and 235 deletions

View File

@ -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> 2009-10-22 signed off by Jason Fleischli <jason.fleischli@hp.com>
* elilo 3.12 release commit * elilo 3.12 release commit
* Added additional #defines for debug levels to reduce the output * Added additional #defines for debug levels to reduce the output
@ -39,8 +53,10 @@
subtree subtree
* bugfix loader_probe now correctly errors out if no loaders * bugfix loader_probe now correctly errors out if no loaders
registered. registered.
2008-01-11 signed off by Jason Fleischli <jason.fleischli@hp.com> 2008-01-11 signed off by Jason Fleischli <jason.fleischli@hp.com>
* Various compile warning cleanups. * Various compile warning cleanups.
2008-01-03 signed off by Jason Fleischli <jason.fleischli@hp.com> 2008-01-03 signed off by Jason Fleischli <jason.fleischli@hp.com>
* Patch contribution from Scott Davilla <davilla@4pi.com> * Patch contribution from Scott Davilla <davilla@4pi.com>
when x is zero for the first call to add_memory_region, e820_map[-1] 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 above the e820_map[0] location that should have been zeroed by the
bootloader, the code should not access outside the bounds of bootloader, the code should not access outside the bounds of
structures. structures.
2008-01-03 Jason Fleischli <jason.fleischli@hp.com> 2008-01-03 Jason Fleischli <jason.fleischli@hp.com>
* initrd.c -- Let the allocator decide where to grab the memory from * 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 efi memory map. Current start_addr=image->start_addr forces the
@ -57,8 +74,10 @@
the image->start_addr resulting in an elilo hang. Leaving start_addr the image->start_addr resulting in an elilo hang. Leaving start_addr
NULL at initialization forces alloc_pages to get a memory region NULL at initialization forces alloc_pages to get a memory region
sufficient for the size of the initrd image. sufficient for the size of the initrd image.
2007-12-19 Jason Fleischli <jason.fleischli@hp.com> 2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
* bumping version string to 3.8 * bumping version string to 3.8
2007-12-19 Jason Fleischli <jason.fleischli@hp.com> 2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
* MORE PATCHES FROM INTEL FOR IA32 X86_64. * MORE PATCHES FROM INTEL FOR IA32 X86_64.
* Fix compile warning for cmdline_addr assignment. * Fix compile warning for cmdline_addr assignment.
@ -83,11 +102,13 @@
EFI framebuffer type ID setting code in ELILO is changed accordingly. EFI framebuffer type ID setting code in ELILO is changed accordingly.
* E820 memory map is added to IA32 to make it possible for * E820 memory map is added to IA32 to make it possible for
Linux kernel not to depend on EFI memory map on EFI 32. Linux kernel not to depend on EFI memory map on EFI 32.
2007-09-27 Jason Fleischli <jason.fleischli@hp.com> 2007-09-27 Jason Fleischli <jason.fleischli@hp.com>
* updating changelog for last commit that was omitted * updating changelog for last commit that was omitted
* incorporating AGriffis patches to enhance parsing * incorporating AGriffis patches to enhance parsing
passes root= option to kernel options and accounts for -- option passes root= option to kernel options and accounts for -- option
designation. designation.
2007-07-19 Jason Fleischli <jason.fleischli@hp.com> 2007-07-19 Jason Fleischli <jason.fleischli@hp.com>
* Integrated x86_64 support patches from Chandramouli Narayanan * Integrated x86_64 support patches from Chandramouli Narayanan
<mouli@linux.intel.com> changes summarized in following bullets. <mouli@linux.intel.com> changes summarized in following bullets.
@ -159,13 +180,17 @@
* x86_64/sysdeps.c -- new file, system stuff for x86_64 * x86_64/sysdeps.c -- new file, system stuff for x86_64
* elilo.txt -- documentation update, add Intel to copyright * elilo.txt -- documentation update, add Intel to copyright
* README.gnu-efi -- documentation update for x86_64 * README.gnu-efi -- documentation update for x86_64
2006-01-27 Alex Williamson <alex.williamson@hp.com> 2006-01-27 Alex Williamson <alex.williamson@hp.com>
* Found a couple more places where vmcode isn't zeroed, causing the * Found a couple more places where vmcode isn't zeroed, causing the
option to get carried over to labels it shouldn't. option to get carried over to labels it shouldn't.
2006-01-09 Brett Johnson <brett@hp.com> 2006-01-09 Brett Johnson <brett@hp.com>
* Released 3.6 * Released 3.6
2005-12-22 Alex Williamson <alex.williamson@hp.com> 2005-12-22 Alex Williamson <alex.williamson@hp.com>
* Fixed vmcode_name initialization in textmenu chooser * Fixed vmcode_name initialization in textmenu chooser
2005-12-01 Alex Williamson <alex.williamson@hp.com> 2005-12-01 Alex Williamson <alex.williamson@hp.com>
* Applied patch from Fred Yang <fred.yang@intel.com> to support the * Applied patch from Fred Yang <fred.yang@intel.com> to support the
vmm= boot option. This option specifies the kernel image for a vmm= boot option. This option specifies the kernel image for a
@ -179,29 +204,37 @@
image will be uncompressed into memory before it is provided to the image will be uncompressed into memory before it is provided to the
hypervisor. Any combination of compressed and uncompressed images hypervisor. Any combination of compressed and uncompressed images
can be used for the image and vmm options. can be used for the image and vmm options.
2005-09-15 Brett Johnson <brett@hp.com> 2005-09-15 Brett Johnson <brett@hp.com>
* Applied patch from Tristan Gingold to add dcache flush and sync with * Applied patch from Tristan Gingold to add dcache flush and sync with
icache to gzip and plain loaders. This ommision was just noticed now 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 due to the much larger caches in Montecito, and the smaller size of
Xen (as compared to the linux kernel). Xen (as compared to the linux kernel).
2004-09-27 Brett Johnson <brett@hp.com> 2004-09-27 Brett Johnson <brett@hp.com>
* Increase the hardcoded size of the texmenu chooser menu from 16 to 64 * Increase the hardcoded size of the texmenu chooser menu from 16 to 64
2004-09-23 Brett Johnson <brett@hp.com> 2004-09-23 Brett Johnson <brett@hp.com>
* Fix for 924147. Thanks to Stephanie Schaaf <sas@sgi.com> for a patch * Fix for 924147. Thanks to Stephanie Schaaf <sas@sgi.com> for a patch
that the fix is based on. that the fix is based on.
2004-02-19 Brett Johnson <brett@hp.com> 2004-02-19 Brett Johnson <brett@hp.com>
* Fixed bug where default image initrd would carry over to another * Fixed bug where default image initrd would carry over to another
image that was selected interactively (iff the newly selected image image that was selected interactively (iff the newly selected image
did not have an initrd). did not have an initrd).
* Added support for subnet-specific config files in netfs. * Added support for subnet-specific config files in netfs.
2004-02-17 Brett Johnson <brett@hp.com> 2004-02-17 Brett Johnson <brett@hp.com>
* integrated ia32 compressed kernel support from Matt Tolentino * integrated ia32 compressed kernel support from Matt Tolentino
<matthew.e.tolentino@intel.com> <matthew.e.tolentino@intel.com>
2003-08-20 Stephane Eranian <eranian@hpl.hp.com> 2003-08-20 Stephane Eranian <eranian@hpl.hp.com>
* released 3.4 * released 3.4
2003-08-19 Stephane Eranian <eranian@hpl.hp.com> 2003-08-19 Stephane Eranian <eranian@hpl.hp.com>
* integrated ia32 updates from Matt * integrated ia32 updates from Matt
Tolentino <matthew.e.tolentino@intel.com> Tolentino <matthew.e.tolentino@intel.com>
2003-08-13 Stephane Eranian <eranian@hpl.hp.com> 2003-08-13 Stephane Eranian <eranian@hpl.hp.com>
* updated elilo.txt and netbooting.txt * updated elilo.txt and netbooting.txt
* fix a bug in choosers/simple.c:print_infos(). * fix a bug in choosers/simple.c:print_infos().
@ -214,37 +247,47 @@
* updated simple chooser set of builtin command keys * updated simple chooser set of builtin command keys
* command keys are only valid if first on the line * command keys are only valid if first on the line
* increase default buffer size and increment when netbooting * increase default buffer size and increment when netbooting
2003-06-04 Stephane Eranian <eranian@hpl.hp.com> 2003-06-04 Stephane Eranian <eranian@hpl.hp.com>
* fix fs/netfs.c to work with recent version * fix fs/netfs.c to work with recent version
of EFI (14.61 or higher) which do not have the of EFI (14.61 or higher) which do not have the
TFTP problem anymore. fix submitted by Guy Laborde TFTP problem anymore. fix submitted by Guy Laborde
2003-04-21 Stephane Eranian <eranian@hpl.hp.com> 2003-04-21 Stephane Eranian <eranian@hpl.hp.com>
* ext2fs support is turned off by default to avoid * ext2fs support is turned off by default to avoid
problems with ext3-formatted partitions. problems with ext3-formatted partitions.
* added gcc version check. MUST use 3.0 or higher * added gcc version check. MUST use 3.0 or higher
2003-03-03 Stephane Eranian <eranian@hpl.hp.com> 2003-03-03 Stephane Eranian <eranian@hpl.hp.com>
* added check on dev_tab in fs/*fs.c:*_uninstall() * added check on dev_tab in fs/*fs.c:*_uninstall()
2003-02-07 Stephane Eranian <eranian@hpl.hp.com> 2003-02-07 Stephane Eranian <eranian@hpl.hp.com>
* clean up in glue_localfs.c w.r.t. CHAR16 in set_default_path() * clean up in glue_localfs.c w.r.t. CHAR16 in set_default_path()
* added support for extracting basename of bootloader path * added support for extracting basename of bootloader path
when using BOOTP (DHCP) only. The prefix is then used for all files 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. open via netfs. Suggestion and initial patch by Guy Laborde from HP.
2003-01-28 Stephane Eranian <eranian@hpl.hp.com> 2003-01-28 Stephane Eranian <eranian@hpl.hp.com>
* fix the set_default_path() routine in glue_localfs.c. It would not * fix the set_default_path() routine in glue_localfs.c. It would not
correctly get the basename of the devpath. This caused the correctly get the basename of the devpath. This caused the
elilo.conf not to be found sometimes. elilo.conf not to be found sometimes.
2003-01-21 Stephane Eranian <eranian@hpl.hp.com> 2003-01-21 Stephane Eranian <eranian@hpl.hp.com>
* fix bug in glue_netfs.c convert_ip2decstr() which caused some IP * fix bug in glue_netfs.c convert_ip2decstr() which caused some IP
addresses to be incorrectly converted to strings. addresses to be incorrectly converted to strings.
2002-11-01 Stephane Eranian <eranian@hpl.hp.com> 2002-11-01 Stephane Eranian <eranian@hpl.hp.com>
* fix bug in -r option for IA64. There is no argument to this option. * fix bug in -r option for IA64. There is no argument to this option.
2002-10-15 Stephane Eranian <eranian@hpl.hp.com> 2002-10-15 Stephane Eranian <eranian@hpl.hp.com>
* fixed a double free bug for the kernel memory in case of abort. * fixed a double free bug for the kernel memory in case of abort.
(bug spotted by Levent Akyl from Intel) (bug spotted by Levent Akyl from Intel)
* released 3.3a * released 3.3a
2002-09-14 Stephane Eranian <eranian@hpl.hp.com> 2002-09-14 Stephane Eranian <eranian@hpl.hp.com>
* applied patch from Andreas Schwab <schwab@suse.de> to eliloalt.c. * applied patch from Andreas Schwab <schwab@suse.de> to eliloalt.c.
eliloalt dynamically selects a variable in /proc/efi/vars. eliloalt dynamically selects a variable in /proc/efi/vars.
2002-09-12 Stephane Eranian <eranian@hpl.hp.com> 2002-09-12 Stephane Eranian <eranian@hpl.hp.com>
* removed extra free() from fs/ext2fs.c:ext2fs_init_state(). * removed extra free() from fs/ext2fs.c:ext2fs_init_state().
Bug report and fix by NOMURA Jun'ichi <j-nomura@ce.jp.nec.com> Bug report and fix by NOMURA Jun'ichi <j-nomura@ce.jp.nec.com>
@ -252,25 +295,31 @@
was bigger than the 128KB limit of EFI causing some weird fimrware 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> 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) * on IA-64 forbid the use of f32-f127 by the compiler (EFI spec)
2002-09-10 Stephane Eranian <eranian@hpl.hp.com> 2002-09-10 Stephane Eranian <eranian@hpl.hp.com>
* fix a bug in argify() that was causing an EFI assertion * fix a bug in argify() that was causing an EFI assertion
when aborting at the elilo prompt when netbooted. when aborting at the elilo prompt when netbooted.
2002-08-26 Stephane Eranian <eranian@hpl.hp.com> 2002-08-26 Stephane Eranian <eranian@hpl.hp.com>
* fixed devschemes/simple.c to use SPrint() instead of its own buggy * fixed devschemes/simple.c to use SPrint() instead of its own buggy
conversion code (spotted by Richard Hirst). conversion code (spotted by Richard Hirst).
* fix bug in argify() when there was no NULL character in the string. * fix bug in argify() when there was no NULL character in the string.
* released 3.3 * released 3.3
2002-08-19 Stephane Eranian <eranian@hpl.hp.com> 2002-08-19 Stephane Eranian <eranian@hpl.hp.com>
* added fpswa.txt in the docs directory * added fpswa.txt in the docs directory
* updated elilo.txt * updated elilo.txt
2002-08-15 Stephane Eranian <eranian@hpl.hp.com> 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 * 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 * 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. * 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 * fixed problem in fs/netfs.c causing large (>4MB) binaries to fail the Mftp() call
2002-06-13 Stephane Eranian <eranian@hpl.hp.com> 2002-06-13 Stephane Eranian <eranian@hpl.hp.com>
* Changed the despecialization character for the variables from \\ to & * Changed the despecialization character for the variables from \\ to &
to avoid conflicts with \\ as a path separator to avoid conflicts with \\ as a path separator
2002-06-11 Stephane Eranian <eranian@hpl.hp.com> 2002-06-11 Stephane Eranian <eranian@hpl.hp.com>
* fixed the return value in efi_main(). elilo was always returning * 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> success even in case of failure. Bug reported by Egan Ford <egan@sense.net>
@ -280,11 +329,13 @@
compliant with EFI spec with regards to where it looks for files. compliant with EFI spec with regards to where it looks for files.
With this patch, elilo will look in the directory it was loaded With this patch, elilo will look in the directory it was loaded
from, not on the root of the partition anymore. from, not on the root of the partition anymore.
2002-03-04 Stephane Eranian <eranian@hpl.hp.com> 2002-03-04 Stephane Eranian <eranian@hpl.hp.com>
* released version 3.2 * released version 3.2
* cleanup some GNU extension in fs/ext2fs.c (variable size array) * cleanup some GNU extension in fs/ext2fs.c (variable size array)
* updated all documentation. Added netbooting.txt, simple_chooser.txt, * updated all documentation. Added netbooting.txt, simple_chooser.txt,
eliloalt.txt, elilovar.txt eliloalt.txt, elilovar.txt
2002-02-21 Stephane Eranian <eranian@hpl.hp.com> 2002-02-21 Stephane Eranian <eranian@hpl.hp.com>
* added a Linux utility program (elilovar in tools) to set/read/delete * added a Linux utility program (elilovar in tools) to set/read/delete
the EliloAlt EFI variable used to specify an alternate kernel to boot. the EliloAlt EFI variable used to specify an alternate kernel to boot.
@ -292,19 +343,24 @@
* added support for hostname,domain name extraction in fs/netfs.c * added support for hostname,domain name extraction in fs/netfs.c
* fixed all known bugs in alternate.c * fixed all known bugs in alternate.c
* integrated patch from SGI to fix load offset for relocatable kernels (Jack Steiner, Brent Casavant) * 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> 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 * 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> 2002-02-20 Stephane Eranian <eranian@hpl.hp.com>
* fixed missing netfs_fd_free() in case of file not found in netfs.c * fixed missing netfs_fd_free() in case of file not found in netfs.c
2002-02-19 Stephane Eranian <eranian@hpl.hp.com> 2002-02-19 Stephane Eranian <eranian@hpl.hp.com>
* added support for substitution variables (vars.c) * added support for substitution variables (vars.c)
* changed the bootparam structure size back to 4kB * changed the bootparam structure size back to 4kB
* added support to simple to print final command line option with tab key * 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) * 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 * added EFICRT0 variable in Makefile to indicate location of loader script+crt0
2002-02-14 Stephane Eranian <eranian@hpl.hp.com> 2002-02-14 Stephane Eranian <eranian@hpl.hp.com>
* added support for message= option to simple chooser * added support for message= option to simple chooser
* added support for description= option to simple chooser * added support for description= option to simple chooser
2002-02-13 Stephane Eranian <eranian@hpl.hp.com> 2002-02-13 Stephane Eranian <eranian@hpl.hp.com>
* choosers/textmenu.c: new textmenu chooser (by rhirst@linuxcare.com) used by Debian * choosers/textmenu.c: new textmenu chooser (by rhirst@linuxcare.com) used by Debian
* config.c: added support for dynamic global/per-image option management * config.c: added support for dynamic global/per-image option management
@ -333,6 +389,7 @@
mode was specified in config file. In this case, we now autoboot mode was specified in config file. In this case, we now autoboot
and ignore the prompt directive. and ignore the prompt directive.
* updated elilo.txt * updated elilo.txt
2001-08-15 Brent Casavant <bcasavan@sgi.com> 2001-08-15 Brent Casavant <bcasavan@sgi.com>
* fix a bug in config.c:find_option() where it would do * fix a bug in config.c:find_option() where it would do
a strXcmp() on a NULL string. a strXcmp() on a NULL string.

View File

@ -68,7 +68,7 @@ CPPFLAGS = -DCONFIG_$(ARCH)
OPTIMFLAGS = -O2 OPTIMFLAGS = -O2
DEBUGFLAGS = -Wall 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 LDFLAGS = -nostdlib -znocombreloc
INSTALL = install INSTALL = install

View File

@ -81,7 +81,7 @@ elilo.efi: elilo.so
elilo.so: $(FILES) elilo.so: $(FILES)
elilo.o : elilo.c elilo.o : elilo.c $(ARCH)/sysdeps.h
fileops.o : Make.defaults fileops.o : Make.defaults
chooser.o : Make.defaults chooser.o : Make.defaults

22
alloc.c
View File

@ -110,7 +110,7 @@ alloc(UINTN size, EFI_MEMORY_TYPE type)
} }
alloc_add(tmp, size, ALLOC_POOL); alloc_add(tmp, size, ALLOC_POOL);
#ifdef DEBUG_MEM #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 #endif
return tmp; 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); 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; return addr;
} }
@ -162,7 +162,7 @@ free(VOID *addr)
return; return;
found: found:
#ifdef DEBUG_MEM #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", p->type == ALLOC_POOL ? L"Pool": L"Page",
addr, p->size)); addr, p->size));
#endif #endif
@ -196,7 +196,7 @@ free_all(VOID)
while(used_allocs) { while(used_allocs) {
#ifdef DEBUG_MEM #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 #endif
if (used_allocs->type == ALLOC_POOL) if (used_allocs->type == ALLOC_POOL)
uefi_call_wrapper(BS->FreePool, 1, used_allocs->addr); uefi_call_wrapper(BS->FreePool, 1, used_allocs->addr);
@ -217,7 +217,15 @@ INTN
alloc_kmem_anywhere(VOID **start_addr, UINTN pgcnt) alloc_kmem_anywhere(VOID **start_addr, UINTN pgcnt)
{ {
void * tmp; 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_addr = tmp;
kmem_pgcnt = pgcnt; kmem_pgcnt = pgcnt;
@ -241,7 +249,7 @@ VOID
free_kmem(VOID) free_kmem(VOID)
{ {
#ifdef DEBUG_MEM #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 #endif
if (kmem_addr && kmem_pgcnt != 0) { if (kmem_addr && kmem_pgcnt != 0) {
free(kmem_addr); free(kmem_addr);
@ -249,7 +257,7 @@ free_kmem(VOID)
kmem_pgcnt = 0; kmem_pgcnt = 0;
} }
#ifdef DEBUG_MEM #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 #endif
} }

View File

@ -96,6 +96,8 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, memdesc_t *vmcode, UINTN *co
*/ */
Memset(bp, 0, BOOT_PARAM_MEMSIZE); Memset(bp, 0, BOOT_PARAM_MEMSIZE);
U2ascii(args, cp, cmdline_size);
if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0; if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0;
/* /*

View File

@ -42,17 +42,13 @@ TARGET=choosers.o
all: $(TARGET) 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) $(LD) -o $@ -r $(FILES)
clean: clean:
$(RM) -f $(TARGET) $(FILES) $(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

View File

@ -41,8 +41,8 @@ static VOID
display_label_info(CHAR16 *name) display_label_info(CHAR16 *name)
{ {
CHAR16 *desc; CHAR16 *desc;
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[PATHNAME_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 vmcode_name[PATHNAME_MAXLEN];
CHAR16 options_tmp[CMDLINE_MAXLEN]; CHAR16 options_tmp[CMDLINE_MAXLEN];
CHAR16 options[CMDLINE_MAXLEN]; CHAR16 options[CMDLINE_MAXLEN];
CHAR16 kname[FILENAME_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=" # define BOOT_IMG_STR L"BOOT_IMAGE="
CHAR16 buffer[CMDLINE_MAXLEN]; CHAR16 buffer[CMDLINE_MAXLEN];
CHAR16 alt_buffer[CMDLINE_MAXLEN]; CHAR16 alt_buffer[CMDLINE_MAXLEN];
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[PATHNAME_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 vmcode_name[PATHNAME_MAXLEN];
CHAR16 args[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN];
CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 devname[PATHNAME_MAXLEN];
CHAR16 dpath[FILENAME_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN];
CHAR16 *slash_pos, *colon_pos, *backslash_pos; CHAR16 *slash_pos, *colon_pos, *backslash_pos;
UINTN len; UINTN len;
@ -290,8 +290,9 @@ restart:
if (elilo_opt.prompt) { if (elilo_opt.prompt) {
console_textmode(); console_textmode();
ret = select_kernel(buffer, sizeof(buffer)); ret = select_kernel(buffer, CMDLINE_MAXLEN);
if (ret == -1) return -1; if (ret == -1) return -1;
/* this function takes really the number of bytes ... */
argc = argify(buffer,sizeof(buffer), argv); argc = argify(buffer,sizeof(buffer), argv);
index = 0; index = 0;
} }

View File

@ -363,10 +363,10 @@ textmenu_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmd
{ {
# define BOOT_IMG_STR L"BOOT_IMAGE=" # define BOOT_IMG_STR L"BOOT_IMAGE="
CHAR16 label[CMDLINE_MAXLEN]; CHAR16 label[CMDLINE_MAXLEN];
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[PATHNAME_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 vmcode_name[PATHNAME_MAXLEN];
CHAR16 args[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN];
CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 devname[PATHNAME_MAXLEN];
CHAR16 dpath[FILENAME_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN];
CHAR16 *slash_pos, *colon_pos, *backslash_pos; CHAR16 *slash_pos, *colon_pos, *backslash_pos;
UINTN len; UINTN len;

View File

@ -56,7 +56,7 @@
*/ */
#define ELILO_DEFAULT_CONFIG L"elilo.conf" #define ELILO_DEFAULT_CONFIG L"elilo.conf"
#define MAX_STRING CMDLINE_MAXLEN #define MAX_STRING 512
#define CONFIG_BUFSIZE 512 /* input buffer size */ #define CONFIG_BUFSIZE 512 /* input buffer size */
/* /*
@ -71,7 +71,7 @@ typedef struct boot_image {
struct boot_image *next; struct boot_image *next;
CHAR16 label[MAX_STRING]; CHAR16 label[MAX_STRING];
CHAR16 kname[FILENAME_MAXLEN]; CHAR16 kname[FILENAME_MAXLEN];
CHAR16 options[MAX_STRING]; CHAR16 options[CMDLINE_MAXLEN];
CHAR16 initrd[FILENAME_MAXLEN]; CHAR16 initrd[FILENAME_MAXLEN];
CHAR16 vmcode[FILENAME_MAXLEN]; CHAR16 vmcode[FILENAME_MAXLEN];
CHAR16 root[FILENAME_MAXLEN]; CHAR16 root[FILENAME_MAXLEN];
@ -100,7 +100,7 @@ typedef struct {
CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */ CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */
CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */ CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */
CHAR16 vmcode[FILENAME_MAXLEN];/* globally defined boot-time module */ CHAR16 vmcode[FILENAME_MAXLEN];/* globally defined boot-time module */
CHAR16 options[MAX_STRING]; CHAR16 options[CMDLINE_MAXLEN];
CHAR16 default_image_name[MAX_STRING]; CHAR16 default_image_name[MAX_STRING];
CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN]; CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN];
CHAR16 chooser[FILENAME_MAXLEN];/* which image chooser to use */ 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; 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) { 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);
} }
} }

BIN
elilo-ia32.efi Normal file → Executable file

Binary file not shown.

BIN
elilo-ia64.efi Normal file → Executable file

Binary file not shown.

BIN
elilo-x86_64.efi Normal file → Executable file

Binary file not shown.

View File

@ -93,7 +93,7 @@ do_kernel_load(CHAR16 *kname, kdesc_t *kd)
INTN INTN
kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memdesc_t *mmem) 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 * Do the vm image switch here

10
elilo.h
View File

@ -29,7 +29,7 @@
#ifndef __ELILO_H__ #ifndef __ELILO_H__
#define __ELILO_H__ #define __ELILO_H__
#define ELILO_VERSION L"3.12" #define ELILO_VERSION L"3.14"
#include <efi.h> #include <efi.h>
@ -54,6 +54,10 @@
#define ROUNDUP(x,a) (((x) + (a) - 1) & ~((a) - 1)) #define ROUNDUP(x,a) (((x) + (a) - 1) & ~((a) - 1))
#define ROUNDDOWN(x,a) ((x) & ~((a) - 1)) #define ROUNDDOWN(x,a) ((x) & ~((a) - 1))
#ifndef UINT32_MAX
#define UINT32_MAX ((UINT32)-1)
#endif
/* /*
* Elilo Boot modes * Elilo Boot modes
*/ */
@ -65,7 +69,8 @@
#define ELILO_DEFAULT_TIMEOUT ELILO_TIMEOUT_INFINITY #define ELILO_DEFAULT_TIMEOUT ELILO_TIMEOUT_INFINITY
#define ELILO_TIMEOUT_INFINITY (~0UL) #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 FILENAME_MAXLEN 256
#define MAX_ARGS 256 #define MAX_ARGS 256
/* Just pick an arbitrary number that's high enough for now :o) */ /* 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 INTN sysdeps_getopt(INTN, INTN, CHAR16 *);
extern VOID sysdeps_print_cmdline_opts(VOID); extern VOID sysdeps_print_cmdline_opts(VOID);
extern INTN sysdeps_register_options(VOID); extern INTN sysdeps_register_options(VOID);
extern VOID *sysdeps_checkfix_initrd(VOID *, memdesc_t *);
#define CHAR_SLASH L'/' #define CHAR_SLASH L'/'
#define CHAR_BACKSLASH L'\\' #define CHAR_BACKSLASH L'\\'

View File

@ -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; 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)); (dev_tab[idx].fops ? dev_tab[idx].fops->name: L"N/A"), str2));
if (str) FreePool(str); if (str) FreePool(str);

View File

@ -54,17 +54,13 @@ all: $(TARGET)
# XXX: does not trigger recompile when changing filesystem selection # XXX: does not trigger recompile when changing filesystem selection
# without doing make clean. # 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) $(LD) -r -o $@ $(FILES)
clean: clean:
$(RM) -f $(TARGET) $(FILES) $(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

View File

@ -98,7 +98,7 @@ localfs_open(localfs_interface_t *this, CHAR16 *name, UINTN *fd)
DBG_PRT((L"localfs_open on %s\n", name)); 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) { if (status == EFI_SUCCESS) {
*fd = LOCALFS_F2FD(fh); *fd = LOCALFS_F2FD(fh);
} }

View File

@ -64,6 +64,19 @@ static CHAR16 netfs_default_path[FILENAME_MAXLEN];
static CHAR16 *hexa=L"0123456789ABCDEF"; 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 static VOID
convert_ip2hex(UINT8 *ip, INTN l, CHAR16 *str) 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); set_var(VAR_NETFS_DOMAINAME, info.domainame);
if (info.using_pxe) { 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); status = netfs->netfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config[0].fname);
if (EFI_ERROR(status)) { if (EFI_ERROR(status)) {
StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1); 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 # endif
# define CONFIG_EXTENSION L".conf\0" # define CONFIG_EXTENSION L".conf\0"
DBG_PRT((L"netfs_setdefaults: machine specific (!using_pxe)"));
/* /*
* will try machine/subnet specific files first. * will try machine/subnet specific files first.
* the filenames are constructed based on the IP(v4) address * 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, str, maxlen-1);
StrnCpy(config[6].fname+2, CONFIG_EXTENSION, 6); 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 #else
StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1); StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);
config[0].fname[maxlen-1] = CHAR_NULL; config[0].fname[maxlen-1] = CHAR_NULL;

View File

@ -169,7 +169,7 @@ bzImage_probe(CHAR16 *kname)
kernel_start)); 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) { if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
/* /*

View File

@ -149,6 +149,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
return 0; return 0;
} }
VOID *
sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
{
return start_addr;
}
VOID VOID
sysdeps_free_boot_params(boot_params_t *bp) sysdeps_free_boot_params(boot_params_t *bp)
{ {
@ -201,7 +207,19 @@ static INTN get_video_info(boot_params_t * bp) {
(VOID **)Gop_handle); (VOID **)Gop_handle);
if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) { 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; return -1;
} }
Gop_handle = alloc(size, 0); Gop_handle = alloc(size, 0);

View File

@ -140,6 +140,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
return 0; 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. */ /* Flush data cache [addr; addr + len], and sync with icache. */
void void
flush_dcache (CHAR8 *addr, UINT64 len) flush_dcache (CHAR8 *addr, UINT64 len)

View File

@ -41,7 +41,11 @@ INTN
load_file(CHAR16 *filename, memdesc_t *image) load_file(CHAR16 *filename, memdesc_t *image)
{ {
EFI_STATUS status; 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; UINTN pgcnt;
UINT64 size = 0; UINT64 size = 0;
fops_fd_t fd; fops_fd_t fd;
@ -71,7 +75,11 @@ load_file(CHAR16 *filename, memdesc_t *image)
/* round up to get required number of pages (4KB) */ /* round up to get required number of pages (4KB) */
image->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(image->size); 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) { if (start_addr == NULL) {
ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt, ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt,
filename)); filename));

View File

@ -1,53 +1,69 @@
3 . 1 2 R E L E A S E N O T E S 3 . 1 4 R E L E A S E N O T E S
=================================== ===================================
QUICK SUMMARY QUICK CHANGE SUMMARY
==================== ====================
* FIXES MAC CONSOLE ISSUE * Fixes for newly emerging x86_64 UEFI-2 boxes where long standing old
* FIXES NETBOOT BROKEN assumptions are borked.
* FIXES EXITBOOTSERVICES FAILURE * Uptake of SUSE and community patches
* TEMP FIX INCREASE BZIMAGE LIMITS - 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 text-mode command line option, force text-mode (bypass graphics probes).
* replace error output on GOP handle failed, downgraded to normal
print status with more informative output.
* Fix ia32 build issue with new gcc due to stack protector enforcement.
BUILD NOTES BUILD NOTES
==================== ====================
You will need the following toolchain to build elilo-3.12 from source You will need the following toolchain to build elilo-3.14 from source
the elilo build environment is optimized for Debian and Debian based distros. the elilo build environment is optimized for Debian and Debian based distros.
1. gnu-efi3.0d or greater, (you will want gnu-efi3.0i or > for cross build env elilo-3.14 was built in the Debian Lenny (Ubuntu 10.04) build environment.
setups) elilo-3.12 binaries were built with gnu-efi3.0e-2 Toolchain versions for this release were:
2. gcc-4.1.1 or greater, elilo-3.12 binaries were built with: x86x(32 &64)
x86 -> 4.2.3-1ubuntu6 * gnu-efi --> 3.0i-2ubuntu1
x86_64 -> 4.2.3-1ubuntu6 * gcc ------> 4.4.3-1ubuntu1
ia64 -> 4.3.2-1.1 * binutils -> 2.20.1-3ubuntu7
3. binutils-2.17.50.0.14 or greater, elilo-3.12 binaries were built with: ia64
x86 -> 2.18.1-cvs20080103-0ubuntu1 * gnu-efi --> 3.0e-2
x86_64 -> 2.18.1~cvs20080103-0ubuntu1 * gcc ------> 4.3.2-2
ia64 -> 2.18.1~cvs20080103-7 * binutils -> 2.18.1~cvs20080103-7
* if you use a debian based (lenny)build environment you will have no problems * if you use a debian based (lenny)build environment you will have no problems
and setting it up is simple. you will be able to build elilo in 3 steps: and setting it up is simple. you will be able to build elilo in 3 steps:
1. apt-get install gnu-efi, gcc, binutils 1. apt-get install gnu-efi, gcc, binutils
2. apt-get source elilo (or download elilo-3.12.tar.gz from SourceForge.) 2. apt-get source elilo (or download elilo-3.14.tar.gz from SourceForge.)
3. cd ./elilo-3.12 and type make 3. extract source tarball and cd ./elilo-3.14 and type $> make
** If you use the upstream tarballs for the toolchain you will need to move
some files around. ** If you use the upstream toolchain tarballs(i.e. pre distro) you will need
to move some files around for elilo build to work.
GNU-EFI (provides the efi 1.10 and uefi 2.x libraries & api) GNU-EFI (provides the efi 1.10 and uefi 2.x libraries & api)
------- -------
gnu-efi libraries are installed to /usr/local/lib by the gnu-efi libraries are installed to /usr/local/lib by the
upstream gnu-efi source package. elilo expects them to be in system location upstream gnu-efi source package. elilo expects them to be in system location
/usr/lib. efi includes may be located in /usr/local/include/efi. elilo /usr/lib. efi includes may be located in /usr/local/include/efi. elilo
expects them to be in system location /usr/include/efi. expects them to be in system location /usr/include/efi.
[ The reason is LSB compliance ].
BINUTILS (provides the elf conversion utility to produce efi bins) BINUTILS (provides the elf conversion utility to produce efi bins)
-------- --------
likewise objcopy may be installed to /usr/local/bin by binutils, binutils provides objcopy which is installed to /usr/local/bin by binutils,
elilo source expects it to be in /usr/bin. elilo source expects it to be in /usr/bin.
again this LSB compliance is taken care of by the distro's that fix
the toolchains to install to the correct compliant system locations
instead of the "user optional" location.
ELILO ON EFI X86_64 ELILO ON EFI X86_64
===================== =====================
HARD REQUIREMENTS HARD REQUIREMENTS
EFI + x86_64 requires efi64 enabled linux kernel i.e. 2.6.21 or newer EFI + x86_64 REQUIRES an efi64 enabled linux kernel i.e. 2.6.21 or newer
nothing earlier will work, 2.6.21 was the earliest kernel that efi64 nothing earlier will work, 2.6.21 was the earliest kernel that efi64
support went into. You need to compile the kernel with CONFIG_EFI support went into. You need to compile the kernel with CONFIG_EFI
kernel option ON. kernel option ON.
@ -57,12 +73,34 @@ HARD REQUIREMENTS
will enable early boot messages on the console. Elilo for x86_64 will enable early boot messages on the console. Elilo for x86_64
attempts to query EFI for GOP support and if it fails it defaults to attempts to query EFI for GOP support and if it fails it defaults to
text mode which may or may not show you early console ouput depends on text mode which may or may not show you early console ouput depends on
your efi and physical setup. your efi console settings and physical setup. Elilo has no way to know
if your console settings are messed up.
WORKING ELILO.CONF FOR EFI X86_64 EXAMPLE WORKING ELILO.CONF FOR EFI X86_64 EXAMPLE
Here is my elilo.conf from my UEFI2.0/x86_64 (with nvidia pcie add on Here is my elilo.conf from my UEFI2.0/x86_64 (with nvidia pcie add on
card, i.e. your vga= kernel param may be different) workstation which uses GOP. card, i.e. your vga= kernel param may be different) workstation which uses GOP.
...shows me console output, what elilo is doing, and kernel boot. Here is a partial kernel vga table I was able to find and add here.
Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
-------+--------------------------------------------------------------
4 bits | ? ? 0x302 ? ? ? ?
8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
decimal | d785 d788 d791
24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
Additionally from ...kernel-source/Documentation/Boot.txt...
vga=<mode>
<mode> here is either an integer (in C notation, either
decimal, octal, or hexadecimal) or one of the strings
"normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask"
(meaning 0xFFFD). This value should be entered into the
vid_mode field, as it is used by the kernel before the command
line is parsed.
example below shows me console output, what elilo is doing, and kernel boot.
vga=normal with efi console input output directed to graphics card should
work as well.
default=UBUNTU default=UBUNTU
chooser=simple chooser=simple
@ -70,35 +108,8 @@ WORKING ELILO.CONF FOR EFI X86_64 EXAMPLE
delay=30 delay=30
append="root=/dev/sda3 vga=0x31e splash showopts" append="root=/dev/sda3 vga=0x31e splash showopts"
image=/vmlinuz-2.6.24-23-generic image=/vmlinuz-2.6.32-27-generic
label="UBUNTU" label="UBUNTU"
description="Ubuntu 2.6.24-23-generic kernel" description="Ubuntu 2.6.32-27-generic kernel"
initrd=/initrd.img-2.6.24-23-generic initrd=/initrd.img-2.6.32-27-generic
CHANGES FROM 3.10 TO 3.12
========================
Patch contributions from Julen Blache @ Debian
thank you. ** ADDS MAC IA32 NATIVE BOOT SUPPORT (i.e. consplitter fix)
* Added additional #defines for debug levels to reduce the output noise
* Added Mac console patch rework from Julien Blache @ debian
this fixes the invisible console output from elilo on Macs
* Moved static ELILO_VERSION variable from elilo.c to elilo.h
so that elilo will print its version string and arch on startup.
* Fixed bug 2825044 ExitBootServices error handling, correctly deal
with changed memory map key if memory map changes from under elilo.
* Added memory map key to map debug output.
* Fixed bug 2874380 netbooting just flat broken. fixed ia64, x86_64
ia32, fixed handling of server side support of tfpt options (get file size)
elilo now attempts to get file size before attempting read of file
to set the buffers up correctly and deal with tftp servers that dont
support options extensions a little better.
* netboot, fixed bad blocksize handling
* netboot, fixed filename length for elilo-x86_64.conf type on tftp
server.
* increased bzimage kernel max length sizes to 4mb on i386 and 8mb on
x86_64... this is a legacy design hold over from original design and
needs to be re-written to do dynamic size memory management based on
the size of the actual vmlinuz image, as ia64/gzip does.

View File

@ -41,11 +41,11 @@ StrnCpy(OUT CHAR16 *dst, IN const CHAR16 *src, IN UINTN size)
{ {
CHAR16 *res = dst; CHAR16 *res = dst;
while (size-- && (*dst++ = *src++) != CHAR_NULL); while (size && size-- && (*dst++ = *src++) != CHAR_NULL);
/* /*
* does the null padding * does the null padding
*/ */
while (size-- > 0) *dst++ = CHAR_NULL; while (size && size-- > 0) *dst++ = CHAR_NULL;
return res; return res;
} }
@ -55,11 +55,11 @@ StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, IN UINTN size)
{ {
CHAR8 *res = dst; CHAR8 *res = dst;
while (size-- && (*dst++ = (CHAR8)*src++) != '\0'); while (size && size-- && (*dst++ = (CHAR8)*src++) != '\0');
/* /*
* does the null padding * does the null padding
*/ */
while (size-- > 0) *dst++ = '\0'; while (size && size-- > 0) *dst++ = '\0';
return res; return res;
} }
@ -76,11 +76,11 @@ strncpya(OUT CHAR8 *dst, IN const CHAR8 *src, IN UINTN size)
{ {
CHAR8 *res = dst; CHAR8 *res = dst;
while (size-- && (*dst++ = *src++) != '\0'); while (size && size-- && (*dst++ = *src++) != '\0');
/* /*
* does the null padding * does the null padding
*/ */
while (size-- > 0) *dst++ = '\0'; while (size && size-- > 0) *dst++ = '\0';
return res; return res;
} }

View File

@ -47,8 +47,10 @@
#define ELILOALT_VERSION "0.02" #define ELILOALT_VERSION "0.02"
#define ELILO_ALT_NAME "EliloAlt" #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 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_NON_VOLATILE 0x0000000000000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
@ -80,7 +82,9 @@ typedef struct _efi_variable_t {
uint32_t attributes; uint32_t attributes;
} __attribute__((packed)) efi_variable_t; } __attribute__((packed)) efi_variable_t;
static char *efivar_dir = EFIVAR_DIR;
static char *elilo_alt_name = ELILO_ALT_NAME; static char *elilo_alt_name = ELILO_ALT_NAME;
static char *elilo_altvar = ELILO_ALTVAR;
static struct option cmd_options[]={ static struct option cmd_options[]={
{ "version", 0, 0, 1}, { "version", 0, 0, 1},
@ -129,9 +133,15 @@ check_proc_efi(int find_entry)
if (getuid() != 0) { if (getuid() != 0) {
fatal_error("This program must be run as root\n"); fatal_error("This program must be run as root\n");
} }
efi_vars = opendir(EFIVAR_DIR); efi_vars = opendir(efivar_dir);
if (efi_vars == NULL) { 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) { if (!find_entry) {
closedir(efi_vars); closedir(efi_vars);
@ -143,9 +153,10 @@ check_proc_efi(int find_entry)
break; break;
} }
if (entry == NULL) { 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); closedir(efi_vars);
return name; return name;
} }
@ -158,7 +169,7 @@ delete_var(void)
check_proc_efi(0); check_proc_efi(0);
fd = open(ELILO_ALTVAR, O_WRONLY); fd = open(elilo_altvar, O_WRONLY);
if (fd == -1) { if (fd == -1) {
fatal_error("variable not defined\n"); fatal_error("variable not defined\n");
} }
@ -176,7 +187,7 @@ delete_var(void)
r = write(fd, &var, sizeof(var)); r = write(fd, &var, sizeof(var));
if (r != 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); close(fd);
} }
@ -191,7 +202,7 @@ print_var(void)
check_proc_efi(0); check_proc_efi(0);
fd = open(ELILO_ALTVAR, O_RDONLY); fd = open(elilo_altvar, O_RDONLY);
if (fd == -1) { if (fd == -1) {
fatal_error("variable not defined\n"); fatal_error("variable not defined\n");
} }
@ -200,7 +211,7 @@ print_var(void)
r = read(fd, &var, sizeof(var)); r = read(fd, &var, sizeof(var));
if (r != 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=\""); printf("EliloAlt=\"");
for(i=0; i < var.datasize; i+=1){ for(i=0; i < var.datasize; i+=1){
@ -231,7 +242,7 @@ set_var(char *cmdline)
fd = open(name, O_WRONLY); fd = open(name, O_WRONLY);
if (fd == -1) { 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)); memset(&var, 0, sizeof(var));
@ -256,7 +267,7 @@ set_var(char *cmdline)
r = write(fd, &var, sizeof(var)); r = write(fd, &var, sizeof(var));
if (r != 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); close(fd);

View File

@ -36,6 +36,129 @@ UINTN param_size = 0;
UINTN kernel_size = 0x800000; /* 8M (default x86_64 bzImage size limit) */ 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 static INTN
bzImage_probe(CHAR16 *kname) bzImage_probe(CHAR16 *kname)
{ {
@ -158,53 +281,34 @@ bzImage_probe(CHAR16 *kname)
* Allocate memory for kernel. * Allocate memory for kernel.
*/ */
/* kernel_load_address = bzImage_alloc();
* Get correct address for kernel from header, if applicable & available. if ( ! kernel_load_address ) {
*/ ERR_PRT((L"Could not allocate memory for kernel."));
if ((param_start->s.hdr_major == 2) && free(param_start);
(param_start->s.hdr_minor >= 6) && param_start = NULL;
(param_start->s.kernel_start >= DEFAULT_KERNEL_START)) { param_size = 0;
kernel_start = (void *)param_start->s.kernel_start; fops_close(fd);
VERB_PRT(3, Print(L"kernel header suggests kernel start at address "PTR_FMT"\n", return -1;
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;
}
}
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. * 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; size = kernel_size;
efi_status = fops_read(fd, kernel_load_address, &size); efi_status = fops_read(fd, kernel_load_address, &size);
if (EFI_ERROR(efi_status) || size < 0x10000) { 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); free(param_start);
param_start = NULL; param_start = NULL;
param_size = 0; param_size = 0;
fops_close(fd); fops_close(fd);
free_kmem(); free_kmem();
return -1; return -1;
} else {
Print(L" done\n");
} }
DBG_PRT((L"kernel image read: %d bytes, %d Kbytes\n", size, size / 1024)); DBG_PRT((L"kernel image read: %d bytes, %d Kbytes\n", size, size / 1024));

View File

@ -33,15 +33,23 @@
typedef struct { typedef struct {
UINTN legacy_free_boot; UINTN legacy_free_boot;
UINTN text_mode;
} x86_64_global_config_t; } 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 x86_64_global_config_t x86_64_gconf;
static config_option_t sysdeps_global_options[]={ static config_option_t sysdeps_global_options[]={
{OPT_BOOL, OPT_GLOBAL, L"legacy-free", NULL, NULL, &x86_64_gconf.legacy_free_boot} {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 * X86_64 operations that need to be done only once and just before
* entering the main loop of the loader * 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; 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 INTN
sysdeps_register_options(VOID) sysdeps_register_options(VOID)
{ {
@ -89,14 +105,11 @@ sysdeps_register_options(VOID)
ret = register_config_options(sysdeps_global_options, ret = register_config_options(sysdeps_global_options,
sizeof(sysdeps_global_options)/sizeof(config_option_t), sizeof(sysdeps_global_options)/sizeof(config_option_t),
OPTIONS_GROUP_GLOBAL); OPTIONS_GROUP_GLOBAL);
#if 0
/* no per image options yet */
if (ret == -1 ) return ret; if (ret == -1 ) return ret;
ret = register_config_options(sysdeps_image_options, ret = register_config_options(sysdeps_image_options,
sizeof(sysdeps_image_options)/sizeof(config_option_t), sizeof(sysdeps_image_options)/sizeof(config_option_t),
OPTIONS_GROUP_IMAGE); OPTIONS_GROUP_IMAGE);
#endif
return ret; return ret;
} }

View File

@ -107,12 +107,12 @@ typedef union x86_64_boot_params {
/* 0x06 */ UINT8 orig_video_mode; /* LDR */ /* 0x06 */ UINT8 orig_video_mode; /* LDR */
/* 0x07 */ UINT8 orig_video_cols; /* LDR */ /* 0x07 */ UINT8 orig_video_cols; /* LDR */
/* 0x08 */ UINT16 unused_1; /* unused */ /* 0x08 */ UINT16 pad_1; /* unused */
/* %%TBD */ /* %%TBD */
/* 0x0A */ UINT16 orig_ega_bx; /* LDR */ /* 0x0A */ UINT16 orig_ega_bx; /* LDR */
/* 0x0C */ UINT16 unused_2; /* unused */ /* 0x0C */ UINT16 pad_2; /* unused */
/* Screen height before passing control to kernel. */ /* Screen height before passing control to kernel. */
/* 0x0E */ UINT8 orig_video_rows; /* LDR */ /* 0x0E */ UINT8 orig_video_rows; /* LDR */
@ -174,7 +174,7 @@ typedef union x86_64_boot_params {
/* 0x4E */ UINT32 bios_code_len; /* LDR */ /* 0x4E */ UINT32 bios_code_len; /* LDR */
/* 0x52 */ UINT16 bios_data_len; /* LDR */ /* 0x52 */ UINT16 bios_data_len; /* LDR */
/* 0x54 */ UINT8 unused_3[0x2C]; /* unused */ /* 0x54 */ UINT8 pad_3[0x2C]; /* unused */
/* %%TBD */ /* %%TBD */
/* 0x80 */ UINT8 hd0_info[0x10]; /* LDR */ /* 0x80 */ UINT8 hd0_info[0x10]; /* LDR */
@ -184,7 +184,7 @@ typedef union x86_64_boot_params {
/* 0xA0 */ UINT16 mca_info_len; /* LDR */ /* 0xA0 */ UINT16 mca_info_len; /* LDR */
/* 0xA2 */ UINT8 mca_info_buf[0x10]; /* LDR */ /* 0xA2 */ UINT8 mca_info_buf[0x10]; /* LDR */
/* 0xB2 */ UINT8 unused_4[0x10E]; /* unused */ /* 0xB2 */ UINT8 pad_4[0x10E]; /* unused */
/* EFI boot loader signature. */ /* EFI boot loader signature. */
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */ /* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
@ -209,9 +209,9 @@ typedef union x86_64_boot_params {
/* Available contiguous extended memory in KB. */ /* Available contiguous extended memory in KB. */
/* 0x1E0 */ UINT32 alt_mem_k; /* LDR */ /* 0x1E0 */ UINT32 alt_mem_k; /* LDR */
/* 0x1E4 */ UINT32 unused_51; /* unused */ /* 0x1E4 */ UINT32 pad_51; /* unused */
/* 0x1E8 */ UINT8 e820_nrmap; /* 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). */ /* Size of setup code in sectors (1 sector == 512 bytes). */
/* 0x1F1 */ UINT8 setup_sectors; /* BLD */ /* 0x1F1 */ UINT8 setup_sectors; /* BLD */
@ -220,15 +220,10 @@ typedef union x86_64_boot_params {
/* 0x1F2 */ UINT16 mount_root_rdonly; /* BLD */ /* 0x1F2 */ UINT16 mount_root_rdonly; /* BLD */
/* %%TBD */ /* %%TBD */
/* 0x1F4 */ UINT16 sys_size; /* BLD */ /* 0x1F4 */ UINT32 sys_size; /* BLD */
/* %%TBD */ /* %%TBD */
/* 0x1F6 */ UINT16 swap_dev; /* BLD */ /* 0x1F8 */ UINT16 ram_size_DNU; /* BLD */
/* %%TBD */
/* 0x1F8 */ UINT16 ramdisk_flags; /* BLD */
#define RAMDISK_PROMPT 0x8000
#define RAMDISK_LOAD 0x4000
/* %%TBD */ /* %%TBD */
/* 0x1FA */ UINT16 video_mode_flag; /* BLD */ /* 0x1FA */ UINT16 video_mode_flag; /* BLD */
@ -236,12 +231,8 @@ typedef union x86_64_boot_params {
/* %%TBD */ /* %%TBD */
/* 0x1FC */ UINT16 orig_root_dev; /* BLD */ /* 0x1FC */ UINT16 orig_root_dev; /* BLD */
/* 0x1FE */ UINT8 unused_6; /* unused */
/* %%TBD */ /* %%TBD */
/* 0x1FF */ UINT8 aux_dev_info; /* LDR */ /* 0x1FE */ UINT16 boot_flag; /* ? */
#define NO_MOUSE 0x00
#define FOUND_MOUSE 0xAA
/* Jump past setup data (not used in EFI). */ /* Jump past setup data (not used in EFI). */
/* 0x200 */ UINT16 jump; /* BLD */ /* 0x200 */ UINT16 jump; /* BLD */
@ -283,16 +274,21 @@ typedef union x86_64_boot_params {
/* 0x21C */ UINT32 initrd_size; /* LDR */ /* 0x21C */ UINT32 initrd_size; /* LDR */
/* %%TBD */ /* %%TBD */
/* 0x220 */ UINT32 bootsect_helper; /* BLD */ /* 0x220 */ UINT32 bootsect_helper_DNU; /* BLD */
/* %%TBD */ /* %%TBD */
/* 0x224 */ UINT16 heap_end_ptr; /* LDR */ /* 0x224 */ UINT16 heap_end_ptr; /* LDR */
/* %%TBD */ /* %%TBD */
/* 0x226 */ UINT16 unused_7; /* LDR */ /* 0x226 */ UINT8 ext_loader_ver; /* LDR */
/* 0x227 */ UINT8 ext_loader_type; /* LDR */
/* 0x228 */ UINT32 cmdline_addr; /* 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]; /* 0x2D0 */ UINT8 e820_map[2560];
} s; } s;
} boot_params_t; } boot_params_t;
@ -368,6 +364,7 @@ extern UINT8 rmswitch_image[];
extern UINTN rmswitch_size; extern UINTN rmswitch_size;
extern INTN x86_64_use_legacy_free_boot(); extern INTN x86_64_use_legacy_free_boot();
extern INTN x86_64_text_mode();
/* /*
* How to jump to kernel code * How to jump to kernel code
@ -382,7 +379,6 @@ start_kernel(VOID *kentry, boot_params_t *bp)
UINT16 kernel_cs; UINT16 kernel_cs;
} jumpvector; } jumpvector;
VOID *jump_start; VOID *jump_start;
uint64_t temp;
/* /*
* Disable interrupts. * Disable interrupts.
@ -390,22 +386,16 @@ start_kernel(VOID *kentry, boot_params_t *bp)
asm volatile ( "cli" : : ); asm volatile ( "cli" : : );
/* /*
* Relocate kernel (if needed), and initrd (if present). * Relocate kernel (if needed).
* Copy kernel first, in case kernel was loaded overlapping where we're * This assumes that the initrd didn't get loaded overlapping where
* planning to copy the initrd. This assumes that the initrd didn't * we're planning to copy the kernel, but that's pretty unlikely
* get loaded overlapping where we're planning to copy the kernel, but * since we couldn't alloc that space for the kernel (or the kernel
* that's pretty unlikely since we couldn't alloc that space for the * would already be there).
* kernel (or the kernel would already be there).
*/ */
if (kernel_start != kernel_load_address) { if (kernel_start != kernel_load_address) {
MEMCPY(kernel_start, kernel_load_address, kernel_size); 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 * Copy boot sector, setup data and command line
* to final resting place. We need to copy * 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 { 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; } sys_img_options_t;
#endif /* __ELILO_SYSDEPS_X86_64_H__ */ #endif /* __ELILO_SYSDEPS_X86_64_H__ */

View File

@ -38,11 +38,19 @@
*/ */
#include <efi.h> #include <efi.h>
#include <efilib.h> #include <efilib.h>
#include <string.h>
#include "elilo.h" #include "elilo.h"
#include "loader.h" #include "loader.h"
#include "rmswitch.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; 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; UINTN high_ext_mem = 32 * 1024 * 1024;
/* This starting address will hold true for all of the loader types for now */ /* 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 */ /* 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; VOID *initrd_start = NULL;
UINTN initrd_size = 0; UINTN initrd_size = 0;
INTN e820_map_overflow = 0;
INTN INTN
sysdeps_init(EFI_HANDLE dev) sysdeps_init(EFI_HANDLE dev)
{ {
@ -131,10 +141,8 @@ sysdeps_init(EFI_HANDLE dev)
/* /*
* initrd_get_addr() * initrd_get_addr()
* Compute a starting address for the initial RAMdisk image. * Compute a starting address for the initial RAMdisk image.
* For now, this image is placed immediately after the end of * For now we suggest 'initrd_addr_max' with room for 32MB,
* the kernel memory. Inside the start_kernel() code, the * as image->pgcnt is not initialized yet.
* RAMdisk image will be relocated to the top of available
* extended memory.
*/ */
INTN INTN
sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem) 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; return -1;
} }
VERB_PRT(3, Print(L"kstart="PTR_FMT" kentry="PTR_FMT" kend="PTR_FMT"\n", VERB_PRT(3, Print(L"initrd_addr_max="PTR_FMT" reserve=%d\n",
kd->kstart, kd->kentry, kd->kend)); 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", VERB_PRT(3, Print(L"initrd start_addr="PTR_FMT" pgcnt=%d\n",
imem->start_addr, imem->pgcnt)); imem->start_addr, imem->pgcnt));
@ -157,6 +167,48 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
return 0; 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 VOID
sysdeps_free_boot_params(boot_params_t *bp) sysdeps_free_boot_params(boot_params_t *bp)
{ {
@ -199,6 +251,10 @@ static INTN get_video_info(boot_params_t * bp) {
UINTN size1; UINTN size1;
UINT8 i; UINT8 i;
if (x86_64_text_mode() == 1) {
Print((L"Skip GOP init, force text-mode.\n"));
return -1;
}
efi_status = uefi_call_wrapper( efi_status = uefi_call_wrapper(
BS->LocateHandle, BS->LocateHandle,
5, 5,
@ -209,7 +265,19 @@ static INTN get_video_info(boot_params_t * bp) {
(VOID **)Gop_handle); (VOID **)Gop_handle);
if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) { 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; return -1;
} }
Gop_handle = alloc(size, 0); Gop_handle = alloc(size, 0);
@ -326,10 +394,56 @@ static INTN get_video_info(boot_params_t * bp) {
return 0; 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 /* Convert EFI memory map to E820 map for the operating system
* This code is based on a Linux kernel patch submitted by Edgar Hucek * 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 */ /* Add a memory region to the e820 map */
static void add_memory_region (struct e820entry *e820_map, static void add_memory_region (struct e820entry *e820_map,
int *e820_nr_map, int *e820_nr_map,
@ -338,21 +452,56 @@ static void add_memory_region (struct e820entry *e820_map,
unsigned int type) unsigned int type)
{ {
int x = *e820_nr_map; 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) { if (x == 0)
Print(L"Too many entries in the memory map!\n"); 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].size += size;
estart = e820_map[x-1].addr;
esize = e820_map[x-1].size;
etype = e820_map[x-1].type;
merge++;
return; return;
} }
/* fill up to E820_MAX */
if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start if ( x < e820_max ) {
&& e820_map[x-1].type == type)
e820_map[x-1].size += size;
else {
e820_map[x].addr = start; e820_map[x].addr = start;
e820_map[x].size = size; e820_map[x].size = size;
e820_map[x].type = type; e820_map[x].type = type;
(*e820_nr_map)++; (*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) 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; break;
default: default:
/* We should not hit this case */ /* We should not hit this case */
DBG_PRT((L"hit default!?"));
add_memory_region(e820_map, &e820_nr_map, add_memory_region(e820_map, &e820_nr_map,
md->PhysicalStart, md->PhysicalStart,
md->NumberOfPages << EFI_PAGE_SHIFT, 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 * x86_64 specific boot parameters initialization routine
*
* Note: debug and verbose messages have already been turned off!
*/ */
INTN INTN
sysdeps_create_boot_params( sysdeps_create_boot_params(
@ -459,6 +611,12 @@ sysdeps_create_boot_params(
UINT8 row, col; UINT8 row, col;
UINT8 mode; UINT8 mode;
UINT16 hdr_version; 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")); 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; 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. * 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", DBG_PRT((L"initrd->start_addr="PTR_FMT" initrd->pgcnt=%d\n",
initrd->start_addr, initrd->pgcnt)); initrd->start_addr, initrd->pgcnt));
/* These RAMdisk flags are not needed, just zero them. */ /* These RAMdisk flags are not needed, just zero them. NOT!*/
bp->s.ramdisk_flags = 0; /* 'ramdisk_flags' (@0x1F8) is called 'ram_size' in the meantime, */
/* see Documentation/x86/boot.txt. */
if (initrd->start_addr && initrd->pgcnt) { 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. */ /* %%TBD - This will probably have to be changed. */
bp->s.initrd_start = (UINT32)(UINT64)initrd->start_addr; bp->s.initrd_start = (UINT32)(UINT64)initrd->start_addr;
bp->s.initrd_size = (UINT32)(initrd->size); 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 { } else {
bp->s.initrd_start = 0; bp->s.initrd_start = 0;
bp->s.initrd_size = 0; bp->s.initrd_size = 0;
@ -589,11 +739,6 @@ sysdeps_create_boot_params(
bp->s.mca_info_len = 0; bp->s.mca_info_len = 0;
ZeroMem(bp->s.mca_info_buf, sizeof bp->s.mca_info_buf); 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 * EFI loader signature
*/ */
@ -602,6 +747,11 @@ sysdeps_create_boot_params(
/* /*
* Kernel entry point. * 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; 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(setup_sectors, 0x1F1, L"%xh");
CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh"); CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
CHECK_OFFSET(sys_size, 0x1F4, 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(video_mode_flag, 0x1FA, L"%xh");
CHECK_OFFSET(orig_root_dev, 0x1FC, 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(jump, 0x200, L"%xh");
CHECK_OFFSET(setup_sig, 0x202, L"'%-4.4a'"); CHECK_OFFSET(setup_sig, 0x202, L"'%-4.4a'");
CHECK_OFFSET(hdr_minor, 0x206, L"%xh"); CHECK_OFFSET(hdr_minor, 0x206, L"%xh");
@ -710,9 +858,9 @@ sysdeps_create_boot_params(
CHECK_OFFSET(kernel_start, 0x214, L"%xh"); CHECK_OFFSET(kernel_start, 0x214, L"%xh");
CHECK_OFFSET(initrd_start, 0x218, L"%xh"); CHECK_OFFSET(initrd_start, 0x218, L"%xh");
CHECK_OFFSET(initrd_size, 0x21C, 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(heap_end_ptr, 0x224, L"%xh");
CHECK_OFFSET(cmdline_addr, 0x228, L"%xh"); CHECK_OFFSET(cmdline_addr, 0x228, L"%xh");
CHECK_OFFSET(e820_map, 0x2D0, L"%xh");
if (test) { if (test) {
ERR_PRT((L"Boot sector and/or setup parameter alignment error.")); ERR_PRT((L"Boot sector and/or setup parameter alignment error."));
@ -802,6 +950,31 @@ do_memmap:
* and update the bootparam accordingly * and update the bootparam accordingly
*/ */
fill_e820map(bp, &mdesc); 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; return 0;
} }