SHA256
1
0
forked from pool/elilo

Accepting request 204823 from Base:System

- Add perl modules to 'PreReq'.  (bnc#842183)
- Update to elilo-3.16 from SLE11/elilo-3.14.

OBS-URL: https://build.opensuse.org/request/show/204823
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/elilo?expand=0&rev=27
This commit is contained in:
Stephan Kulow 2013-10-29 08:23:27 +00:00 committed by Git OBS Bridge
commit b967048e97
26 changed files with 2277 additions and 1814 deletions

119
3.16-release-notes.txt Normal file
View File

@ -0,0 +1,119 @@
3 . 1 6 R E L E A S E N O T E S
===================================
QUICK CHANGE SUMMARY
====================
* Adds native x86x crossbuild functionality
build 32bit or 64bit versions from either environment via
make ARCH=ia32|x86_64 (the ARCH IS case sensitive).
make by itself will default to the native host arch.
* Add console reset call during initialization. thanks A. Steinmetz
* simplify output of no GOP warning text so it no longer looks like an error.
* MAJOR: Fixed Fault crash when EFI memory map changes from under elilo.
(from an outside interrupt in this case). When the EFI Memory map
changes after elilo has already built boot params to pass to the
kernel the EFI call to ExitBootSvcs just prior to boot will fail
because elilo has the old map key. This is valid EFI behavior, elilo
retries to pick up the new memory map and key but had already freed
the start params portion of boot params resulting in a NULL DEREF
crash reset once it hands the now bogus boot params to the kernel on
the 2nd successful call to exit efi and boot.
Thanks to Jerry Hoemann @ HP for reporting this bug.
* minor bugfix, fixed -m option broken. thanks Allan-lsk.
BUILD NOTES
====================
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.
elilo-3.16 was built in the squeeze+(ubuntu 11.x) build environments except
for itanium which is unchanged to best support legacy enterprise configs.
Toolchain versions for this release were:
x86x(32 & 64bit versions)
* gnu-efi --> 3.0i-3
* gcc ------> 4:4.4.4-1ubuntu2
* binutils -> 2.20.51.20100908-0ubuntu2
ia64
* gnu-efi --> 3.0e-2
* gcc ------> 4.3.2-2
* binutils -> 2.18.1~cvs20080103-7
* if you use a debian based build environment you will have no problems
and setting it up is simple. you will be able to build elilo in 3 steps:
1. apt-get install gnu-efi, gcc, binutils
2. apt-get source elilo (or download elilo-3.16 source from SourceForge.)
3. extract source tarball and cd to ./$your-elilo-source and type $> make
** 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 libraries are installed to /usr/local/lib by the
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
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 objcopy which is installed to /usr/local/bin by binutils,
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
=====================
HARD REQUIREMENTS
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
support went into. You need to compile the kernel with CONFIG_EFI
kernel option ON.
x86_64 platforms with UEFI 2.0 firmware deprecate UGA protocol
and therefore only the Graphics Output Protocol (GOP) is supported. For
such platforms, the kernel must be compiled with EFI_FB option ON. This
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
text mode which may or may not show you early console ouput depends on
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
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.
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
chooser=simple
verbose=5
delay=30
append="root=/dev/sda3 vga=0x31e splash showopts"
image=/vmlinuz-2.6.32-27-generic
label="UBUNTU"
description="Ubuntu 2.6.32-27-generic kernel"
initrd=/initrd.img-2.6.32-27-generic

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5005534ae972603c65caa8debb2bf3c4a22b895588323bc1b0a7a9f114e030ee
size 215125

3
elilo-3.16-source.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4c0b247d96cfa9067e6728ebc95d511ffda9f47af4831c2ec7c19dfa2ea5f9a0
size 147468

View File

@ -1,39 +0,0 @@
---
glue_netfs.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/glue_netfs.c
+++ b/glue_netfs.c
@@ -65,6 +65,19 @@ static CHAR16 netfs_default_path[FILENAM
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)
{
UINTN i;
@@ -210,6 +223,12 @@ netfs_setdefaults(VOID *intf, config_fil
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;

View File

@ -0,0 +1,149 @@
---
bootparams.c | 15 ++++-----------
x86_64/config.c | 18 ++++++++++++++++++
x86_64/sysdeps.h | 5 ++++-
x86_64/system.c | 30 +++++++++++++++++++++++++-----
4 files changed, 51 insertions(+), 17 deletions(-)
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -953,6 +953,11 @@ do_memmap:
#endif
if (e820_map_overflow && !e820_map_overflow_warned) {
CHAR8 *aem = (CHAR8 *)"add_efi_memmap";
+ UINTN al = strlena( aem) + 1;
+ UINTN cl = strlena( (CHAR8 *)cmdline);
+ INT8 autoadd = (x86_64_auto_add_efi_memmap() &&
+ (cl + al) < CMDLINE_MAXLEN);
+ CHAR16 *severity = (autoadd) ? L"Notice" : L"CAUTION";
e820_map_overflow_warned++;
#if DEBUG_CREATE_BOOT_PARAMS
@@ -964,11 +969,26 @@ do_memmap:
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);
+ Print(L"\n%s: EFI memory map has %d more entr%a than E820 map"
+ " supports.\n", severity, e820_map_overflow,
+ (e820_map_overflow==1)?"y":"ies");
+
+ if (autoadd) {
+ strcpya( cmdline + cl, (CHAR8 *)" ");
+ strcpya( cmdline + cl + 1, aem);
+ Print(L"To allow access to all memory, '%a' has been"
+ " auto-added!\n\n", aem);
+ wait_timeout(30);
+ goto do_memmap;
+ }
+ if ((cl + al) >= CMDLINE_MAXLEN)
+ Print(L"But adding '%a' would exceed the maximum"
+ " command-line length", aem);
+ else
+ Print(L"But auto-adding of '%a' is disabled in"
+ " 'elilo.conf'", aem);
+ wait_timeout(60);
+ Print(L"\n\n");
goto do_memmap;
}
--- a/x86_64/config.c
+++ b/x86_64/config.c
@@ -34,6 +34,7 @@
typedef struct {
UINTN legacy_free_boot;
UINTN text_mode;
+ CHAR16 add_efi_memmap[MAX_STRING];
} x86_64_global_config_t;
@@ -42,10 +43,14 @@ typedef struct {
static x86_64_global_config_t x86_64_gconf;
static config_option_t sysdeps_global_options[]={
+ {OPT_STR, OPT_GLOBAL, L"add-efi-memmap",
+ NULL, NULL, &x86_64_gconf.add_efi_memmap},
{OPT_BOOL, OPT_GLOBAL, L"legacy-free", NULL, NULL, &x86_64_gconf.legacy_free_boot}
};
static config_option_t sysdeps_image_options[]={
+ {OPT_STR, OPT_IMAGE_SYS, L"add-efi-memmap",
+ NULL, NULL, x86_64_opt_offsetof(add_efi_memmap)},
{OPT_BOOL, OPT_IMAGE_SYS, L"text-mode", NULL, NULL, x86_64_opt_offsetof(text_mode)}
};
@@ -89,6 +94,19 @@ x86_64_use_legacy_free_boot(VOID)
return x86_64_gconf.legacy_free_boot ? 1 : 0;
}
+INT8
+x86_64_auto_add_efi_memmap(VOID)
+{
+ if (elilo_opt.sys_img_opts) {
+ if (!StrCmp(elilo_opt.sys_img_opts->add_efi_memmap, L"false"))
+ return 0;
+ if (!StrCmp(elilo_opt.sys_img_opts->add_efi_memmap, L"auto"))
+ return 1;
+ }
+ if (!StrCmp(x86_64_gconf.add_efi_memmap, L"false"))
+ return 0;
+ return 1;
+}
INTN
x86_64_text_mode(VOID)
--- a/x86_64/sysdeps.h
+++ b/x86_64/sysdeps.h
@@ -365,6 +365,7 @@ extern UINTN rmswitch_size;
extern INTN x86_64_use_legacy_free_boot();
extern INTN x86_64_text_mode();
+extern INT8 x86_64_auto_add_efi_memmap();
/*
* How to jump to kernel code
@@ -457,9 +458,11 @@ start_kernel(VOID *kentry, boot_params_t
/* Never come back to here. */
}
+#define MAX_STRING 512 /* ToDo: move to 'config.h' */
typedef struct sys_img_options {
UINT8 dummy; /* forces non-zero offset for first field */
- UINT8 text_mode; /* do not try to initialize Graphics Output Protocol */
+ UINT8 text_mode; /* don't try to initialize GraphicsOutputProtocol */
+ CHAR16 add_efi_memmap[MAX_STRING]; /* "false" | "auto" */
} sys_img_options_t;
#endif /* __ELILO_SYSDEPS_X86_64_H__ */
--- a/bootparams.c
+++ b/bootparams.c
@@ -93,21 +93,14 @@ create_boot_params(CHAR16 *args, memdesc
*/
Memset(bp, 0, BOOT_PARAM_MEMSIZE);
+ /*
+ * Convert kernel command line args from UNICODE to ASCII
+ * and put them where the kernel expects them:
+ */
U2ascii(args, cp, cmdline_size);
if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0;
- /*
- * Convert kernel command line args from UNICODE to ASCII and put them where
- * the kernel expects them:
- */
- while (1) {
- ch = *args++;
- if (!ch) break;
- *cp++ = ch;
- }
- *cp++ = '\0';
-
return bp;
}

View File

@ -1,19 +0,0 @@
---
config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/config.c
+++ b/config.c
@@ -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);
}
}

56
elilo-blocksize.diff Normal file
View File

@ -0,0 +1,56 @@
---
config.c | 4 ++++
elilo.h | 2 ++
fs/netfs.c | 3 ++-
3 files changed, 8 insertions(+), 1 deletion(-)
--- a/config.c
+++ b/config.c
@@ -119,6 +119,7 @@ typedef struct {
UINTN timeout;
UINTN verbose;
UINTN edd30_no_force; /* don't force EDD30 if not set */
+ UINTN blocksize;
} global_config_t;
/*
@@ -143,6 +144,7 @@ static config_option_t global_common_opt
{OPT_STR, OPT_GLOBAL, L"default", NULL, NULL, global_config.default_image_name},
{OPT_NUM, OPT_GLOBAL, L"timeout", NULL, NULL, &global_config.timeout},
{OPT_NUM, OPT_GLOBAL, L"delay", NULL, NULL, &global_config.delay},
+{OPT_NUM, OPT_GLOBAL, L"block-size", NULL, NULL, &global_config.blocksize},
{OPT_BOOL, OPT_GLOBAL, L"debug", NULL, NULL, &global_config.debug},
{OPT_BOOL, OPT_GLOBAL, L"prompt", NULL, NULL, &global_config.prompt},
{OPT_NUM, OPT_GLOBAL, L"verbose", NULL, check_verbosity, &global_config.verbose},
@@ -827,6 +829,8 @@ update_elilo_opt(VOID)
if (global_config.debug) elilo_opt.debug = 1;
if (global_config.prompt) elilo_opt.prompt = 1;
+ if (global_config.blocksize)
+ elilo_opt.blocksize = global_config.blocksize;
/*
* update only if not set on command line
--- a/elilo.h
+++ b/elilo.h
@@ -105,6 +105,8 @@ typedef struct {
UINTN prompt; /* enter interactive mode */
UINTN parse_only; /* only parses the config file */
UINTN timeout; /* timeout before leaving interactive mode*/
+ UINTN blocksize; /* user-specified block-size for I/O */
+ /* (currently only used for TFTP!) */
image_opt_t img_opt; /* architecture independent per image options*/
--- a/fs/netfs.c
+++ b/fs/netfs.c
@@ -517,7 +517,8 @@ netfs_open(netfs_interface_t *this, CHAR
netfs_fd_t *f;
EFI_STATUS status;
CHAR8 ascii_name[FILENAME_MAXLEN];
- UINTN blocksize = NETFS_DEFAULT_BLOCKSIZE;
+ UINTN blocksize = (elilo_opt.blocksize > 0) ?
+ elilo_opt.blocksize : NETFS_DEFAULT_BLOCKSIZE;
UINTN prev_netbufsize, retries = 0;
BOOLEAN server_provided_filesize = FALSE;

View File

@ -1,47 +0,0 @@
From: Stuart_Hayes@Dell.com
Subject: Re: [elilo-discuss] Follow-Up to 1MB Allocation Problem
Message-ID: <DFEF91B22ED07447AB6AA4B237F913F90218586E@ausx3mpc125.aus.amer.dell.com>
Here's one solution to the problem, for bzImages in x86_64 (which could
easily be ported to the other image types and architecture). I tried to
make this minimally invasive. If bzImage_probe() can't load the kernel
where it should be, it will just load the kernel anywhere, and it will
be moved to the right address after elilo exits EFI boot services. (I
also made it read where the kernel should be from the kernel header.)
It looks like it was already loading the initrd just anywhere and then
moving it after exiting boot services.
(I also enhanced the "MEMCPY" macro in x86_64/sysdeps.h so it will copy
to an overlapping area correctly regardless of whether the "from"
address is higher or lower than the "to" address.)
I originally wrote code that would actually check if the kernel was
relocatable and then relocate it, like the ia64 code does. That worked
fine, except that the address that was found overlapped the area where
elilo copies the initrd in start_kernel() after EFI boot services are
exited! Instead of modifying the initrd addresses, too, I decided it
would be easier and less likely to break anyting else (and would work
with non-relocatable kernels, too) to just do it the other way.
Any chance we could get this patch into elilo? I can modify and
resubmit if there are any issues with this approach.
Thanks!
[ only one change of this patch is still missing... -- rw@suse.de ]
---
fs/localfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/localfs.c
+++ b/fs/localfs.c
@@ -98,7 +98,7 @@ localfs_open(localfs_interface_t *this,
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);
}

View File

@ -1,183 +0,0 @@
---
Makefile | 2 +-
alloc.c | 12 ++++++------
choosers/Makefile | 14 +++++---------
fileops.c | 2 +-
fs/Makefile | 14 +++++---------
glue_netfs.c | 4 ++++
x86_64/bzimage.c | 6 ++++--
7 files changed, 26 insertions(+), 28 deletions(-)
--- 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
--- 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
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);
@@ -249,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);
@@ -257,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
}
--- a/choosers/Makefile
+++ b/choosers/Makefile
@@ -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
--- a/fileops.c
+++ b/fileops.c
@@ -497,7 +497,7 @@ add_dev_tab(EFI_GUID *proto, EFI_HANDLE
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);
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -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
-
--- a/glue_netfs.c
+++ b/glue_netfs.c
@@ -153,6 +153,8 @@ netfs_setdefaults(VOID *intf, config_fil
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 +183,8 @@ netfs_setdefaults(VOID *intf, config_fil
# 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
--- a/x86_64/bzimage.c
+++ b/x86_64/bzimage.c
@@ -295,18 +295,20 @@ bzImage_probe(CHAR16 *kname)
* 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));

42
elilo-de-debianify.diff Normal file
View File

@ -0,0 +1,42 @@
---
Make.defaults | 5 +++--
ia32/Makefile | 2 +-
x86_64/Makefile | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
--- a/Make.defaults
+++ b/Make.defaults
@@ -63,8 +63,9 @@ CDIR := $(shell if [ "$$PWD" != "" ];
TOPDIR =
ALLSUBDIRS = ia32 ia64 x86_64 fs choosers devschemes tools
-HOSTARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH | sed s,i[3456789]86,ia32, | sed s,amd64,x86_64, )
-ARCH := $(shell dpkg-architecture -qDEB_BUILD_ARCH | sed s,i[3456789]86,ia32, | sed s,amd64,x86_64, )
+HOSTARCH := $(shell if ! dpkg-architecture -qDEB_BUILD_ARCH 2>/dev/null; then \
+ uname -m; fi | sed -e s,i[3456789]86,ia32, -e s,amd64,x86_64, )
+ARCH := $(HOSTARCH)
INCDIR = -I. -I$(TOPDIR) -I$(EFIINC) -I$(EFIINC)/$(ARCH) -I$(EFIINC)/protocol -I$(TOPDIR)/efi110
CPPFLAGS = -DCONFIG_$(ARCH)
--- a/x86_64/Makefile
+++ b/x86_64/Makefile
@@ -43,7 +43,7 @@ all: $(TARGET)
system.o: rmswitch.h
rmswitch.h: bin_to_h.c rmswitch.S
- $(CC) -o bin_to_h $(SRCDIR)/bin_to_h.c
+ $(CC) $(OPTIMFLAGS) -o bin_to_h $(SRCDIR)/bin_to_h.c
$(AS) -o rmswitch.o $(SRCDIR)/rmswitch.S
$(LD) -Ttext 0x0 -s --oformat binary -o rmswitch rmswitch.o
./bin_to_h <rmswitch >rmswitch.h
--- a/ia32/Makefile
+++ b/ia32/Makefile
@@ -42,7 +42,7 @@ all: $(TARGET)
system.o: rmswitch.h
rmswitch.h: bin_to_h.c rmswitch.S
- $(CC) -o bin_to_h $(SRCDIR)/bin_to_h.c
+ $(CC) $(OPTIMFLAGS) -o bin_to_h $(SRCDIR)/bin_to_h.c
$(AS) -o rmswitch.o $(SRCDIR)/rmswitch.S
$(LD) -Ttext 0x0 -s --oformat binary -o rmswitch rmswitch.o
./bin_to_h <rmswitch >rmswitch.h

View File

@ -1,26 +0,0 @@
From: Bernhard Walle <bwalle@suse.de>
Subject: [PATCH] Fix possible array length overflow
References: bnc#256676
Found by dan.yeisley@unisys.com.
Signed-off-by: Bernhard Walle <bwalle@suse.de>
---
choosers/simple.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/choosers/simple.c
+++ b/choosers/simple.c
@@ -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;
}

View File

@ -1,53 +0,0 @@
From: Jarrod Johnson <jbjohnso@us.ibm.com>
Fix StrnCpy bug that would overflow dst buffer if length of src met or
exceeded passed size value.
---
strops.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/strops.c
+++ b/strops.c
@@ -41,11 +41,11 @@ StrnCpy(OUT CHAR16 *dst, IN const CHAR16
{
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
{
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
{
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;
}

458
elilo-ipv6.diff Normal file
View File

@ -0,0 +1,458 @@
---
fs/netfs.c | 257 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
glue_netfs.c | 53 ++++++++++--
strops.c | 11 ++
strops.h | 1
4 files changed, 302 insertions(+), 20 deletions(-)
--- a/glue_netfs.c
+++ b/glue_netfs.c
@@ -133,6 +133,17 @@ netfs_set_default_path(netfs_interface_t
return EFI_SUCCESS;
}
+static INTN
+non_zero(UINT8 *c, UINTN len)
+{
+ int i;
+ for (i=0 ; i < len ; i++) {
+ if (c[i])
+ return 1;
+ }
+ return 0;
+}
+
static EFI_STATUS
netfs_setdefaults(VOID *intf, config_file_t *config, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath)
{
@@ -140,7 +151,7 @@ netfs_setdefaults(VOID *intf, config_fil
netfs_info_t info;
EFI_STATUS status;
UINT8 *ipaddr;
- UINTN m;
+ UINTN m, i;
CHAR16 ip_var[64], str[64];
UINT8 *ip;
@@ -165,6 +176,9 @@ netfs_setdefaults(VOID *intf, config_fil
set_var(VAR_NETFS_HOSTNAME, info.hostname);
set_var(VAR_NETFS_DOMAINAME, info.domainame);
+ DBG_PRT((L"netfs_setdefaults: hostname=%s (IPv%a)", info.hostname,
+ (info.using_ipv6 ? "6" : "4")));
+
if (info.using_pxe) {
DBG_PRT((L"netfs_setdefaults: using_pxe"));
@@ -184,13 +198,10 @@ netfs_setdefaults(VOID *intf, config_fil
# if defined(CONFIG_ia64)
# define CONFIG_ARCH_EXTENSION L"-ia64.conf\0"
-# define EXTENSION_LENGTH 11
# elif defined (CONFIG_ia32)
# define CONFIG_ARCH_EXTENSION L"-ia32.conf\0"
-# define EXTENSION_LENGTH 11
# elif defined (CONFIG_x86_64)
# define CONFIG_ARCH_EXTENSION L"-x86_64.conf\0"
-# define EXTENSION_LENGTH 13
# else
# error "You need to specfy your default arch config file"
# endif
@@ -203,31 +214,57 @@ netfs_setdefaults(VOID *intf, config_fil
* the filenames are constructed based on the IP(v4) address
*/
convert_ip2hex(ipaddr, m, str);
+#if 1
+ i = 0;
+ if (non_zero(ipaddr, m)) {
+ int nr = (m==16)? 10 : 6;
+ int st = (m==16)? 2 : 1;
+ m <<= 1;
+ StrnCpy(config[i].fname, str, m);
+ StrnCat(config[i++].fname,
+ CONFIG_EXTENSION, maxlen - m);
+ while (i <= nr) {
+ int stub = m - (i+1)*st;
+ StrnCpy(config[i].fname, str, stub);
+ StrnCat(config[i++].fname,
+ CONFIG_ARCH_EXTENSION, maxlen - m);
+ StrnCpy(config[i].fname, str, stub);
+ StrnCat(config[i++].fname,
+ CONFIG_EXTENSION, maxlen - m);
+ }
+ }
+ if (non_zero(info.hw_addr, 6)) {
+ convert_mac2hex(info.hw_addr,6,str);
+ StrnCpy(config[i].fname, str, maxlen-1);
+ StrnCpy(config[i++].fname+17, CONFIG_EXTENSION, 6);
+ }
+#else
StrnCpy(config[0].fname, str, maxlen-1);
StrnCpy(config[0].fname+8, CONFIG_EXTENSION, 6);
StrnCpy(config[1].fname, str, maxlen-1);
- StrnCpy(config[1].fname+6, CONFIG_ARCH_EXTENSION, EXTENSION_LENGTH);
+ StrnCpy(config[1].fname+6, CONFIG_ARCH_EXTENSION, maxlen-7);
StrnCpy(config[2].fname, str, maxlen-1);
StrnCpy(config[2].fname+6, CONFIG_EXTENSION, 6);
StrnCpy(config[3].fname, str, maxlen-1);
- StrnCpy(config[3].fname+4, CONFIG_ARCH_EXTENSION, EXTENSION_LENGTH);
+ StrnCpy(config[3].fname+4, CONFIG_ARCH_EXTENSION, maxlen-5);
StrnCpy(config[4].fname, str, maxlen-1);
StrnCpy(config[4].fname+4, CONFIG_EXTENSION, 6);
StrnCpy(config[5].fname, str, maxlen-1);
- StrnCpy(config[5].fname+2, CONFIG_ARCH_EXTENSION, EXTENSION_LENGTH);
+ StrnCpy(config[5].fname+2, CONFIG_ARCH_EXTENSION, maxlen-3);
StrnCpy(config[6].fname, str, maxlen-1);
- StrnCpy(config[6].fname+2, CONFIG_EXTENSION, 6);
+ StrnCpy(config[6].fname+2, CONFIG_EXTENSION, maxlen-3);
/* 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);
+#endif
#else
StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1);
--- a/strops.c
+++ b/strops.c
@@ -50,6 +50,17 @@ StrnCpy(OUT CHAR16 *dst, IN const CHAR16
return res;
}
+CHAR16 *
+StrnCat(OUT CHAR16 *dst, IN const CHAR16 *src, IN UINTN size)
+{
+ CHAR16 *res;
+
+ while (size && size-- && (*dst++) != CHAR_NULL);
+ res = StrnCpy(--dst, src, size);
+
+ return res;
+}
+
CHAR8 *
StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, IN UINTN size)
{
--- a/strops.h
+++ b/strops.h
@@ -28,6 +28,7 @@
extern CHAR16 *StrChr(IN const CHAR16 *s, const CHAR16 c);
extern CHAR16 *StrnCpy(OUT CHAR16 *dst, IN const CHAR16 *src, UINTN count);
+extern CHAR16 *StrnCat(OUT CHAR16 *dst, IN const CHAR16 *src, UINTN count);
extern CHAR8 *StrnXCpy(OUT CHAR8 *dst, IN const CHAR16 *src, UINTN count);
extern CHAR8 *strtok_simple(CHAR8 *in, CHAR8 c);
--- a/fs/netfs.c
+++ b/fs/netfs.c
@@ -75,6 +75,8 @@ typedef struct {
EFI_IP_ADDRESS netmask;
UINT8 hw_addr[16];
+ CHAR8 bootfile[NETFS_BOOTFILE_MAXLEN];
+
netfs_fd_t fd_tab[NETFS_FD_MAX];
netfs_fd_t *free_fd;
UINTN free_fd_count;
@@ -206,11 +208,239 @@ netfs_name(netfs_interface_t *this, CHAR
return EFI_SUCCESS;
}
+typedef struct {
+ UINT16 code;
+ UINT16 len;
+ UINT8 data[];
+} DHCPv6_OPTION;
+
+#define DHCPv6_REPLY 7
+#define OPT_BOOTFILE_URL 59
+#define PROTO "tftp://" /* only TFTP supported for now */
+
+static inline UINT16
+bswap16(UINT16 x)
+{
+ return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
+}
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohs(x) bswap16(x)
+# define htons(x) bswap16(x)
+#else
+# if __BYTE_ORDER == __BIG_ENDIAN
+# define ntohs(x) (x)
+# define htons(x) (x)
+# endif
+#endif
+/* string 2 net short */
+static UINT16
+stra2ns(CHAR8 *str)
+{
+ UINT16 ret = 0;
+ UINT8 v;
+ for(;*str;str++) {
+ if ('0' <= *str && *str <= '9')
+ v = *str - '0';
+ else if ('A' <= *str && *str <= 'F')
+ v = *str - 'A' + 10;
+ else if ('a' <= *str && *str <= 'f')
+ v = *str - 'a' + 10;
+ else
+ v = 0;
+ ret = (ret << 4) + v;
+ }
+ /* DBG_PRT((L"stra2ns: '%a'='%d'", str, ret)); */
+ return htons(ret);
+}
+
+/* IPv4/6 address to string */
+static CHAR8 *
+ip2stra(UINT8 octets, UINT8 *ip)
+{
+ int i, j;
+ static CHAR8 *hexa= (CHAR8 *)"0123456789ABCDEF";
+ static CHAR8 str[42];
+
+ if (octets == 16) {
+ for(i=j=0; i < 16; i++) {
+ str[j++] = hexa[(ip[i] & 0xf0)>>4];
+ str[j++] = hexa[ip[i] & 0x0f];
+ if (i && i%2 == 0)
+ str[j++] = ':';
+ }
+ } else if (octets == 4) {
+ int val, v;
+ for(i=j=0; i < 4; i++) {
+ val = ip[i];
+ v = val / 100;
+ if (v)
+ str[j++] = '0' + v;
+ v = (val % 100) / 10;
+ if (v || val > 99)
+ str[j++] = '0' + v;
+ val %= 10;
+ str[j++] = '0' + val;
+ str[j++] = '.';
+ }
+ } else
+ j = 1;
+ str[--j] = '\0';
+ /* DBG_PRT((L"ip2stra: '%a'", str)); */
+ return str;
+}
+
+/* string 2 IPv6 address */
+static UINT8 *
+stra2ip6(CHAR8 *str)
+{
+ UINTN i, j, p, len;
+ CHAR8 *a, *b, t;
+ static UINT16 ip[8];
+
+ for(i=0; i < 8; i++) {
+ ip[i] = 0;
+ }
+ len = strlena( str);
+ a = b = str;
+ for(i=p=0; i < len; i++, b++) {
+ if (*b != ':')
+ continue;
+ *b = '\0';
+ ip[p++] = stra2ns(a);
+ *b = ':';
+ a = b + 1;
+ if ( *(b+1) == ':' )
+ break;
+ }
+ a = b = str + len;
+ for(j=len, p=7; j > i; j--, a--) {
+ if (*a != ':')
+ continue;
+ t = *b;
+ *b = '\0';
+ ip[p--] = stra2ns(a+1);
+ *b = t;
+ b = a;
+ }
+ DBG_PRT((L"stra2ip6: '%a'='%a'", str, ip2stra(16, (UINT8 *)ip)));
+ return (UINT8 *)ip;
+}
+
+static VOID
+hexdump(UINT8 *dp, int size)
+{
+ int i = 0, j;
+ unsigned char *d = (unsigned char *)dp;
+ char hex[64], chr[17];
+ static CHAR8 *hexa= (CHAR8 *)"0123456789ABCDEF";
+
+ hex[58] = '\0';
+ chr[16] = '\0';
+ while ( i < size ) {
+ if ( i > 0 && i % 16 == 0 )
+ Print(L"%a >%a<\n", hex, chr);
+ if ( i % 16 == 0 ) {
+ Memset( hex, ' ', 58);
+ hex[56] = '\0';
+ if (i>0xFFFFFF) return;
+ for (j = 0; j < 6; j++)
+ hex[j] = hexa[(i>>(4*(5-j))) & 0xF];
+ }
+#define pos(i) ((((i%16)<8)?8:9)+(i%16)*3)
+ hex[pos(i)] = hexa[d[i]>>4&0xF];
+ hex[pos(i)+1] = hexa[d[i]&0xF];
+
+ chr[i%16] = ((d[i]>31&&d[i]<127)?d[i]:'.');
+ i++;
+ }
+ if ( i % 16 != 1 ) {
+ chr[(i%16)] = '\0';
+ Print(L"%a >%a<\n", hex, chr);
+ }
+}
+
+static INTN
+find_dhcp6_option(
+ EFI_PXE_BASE_CODE_PACKET *packet,
+ UINT8 option,
+ CHAR8 *str,
+ INTN *length)
+{
+ EFI_PXE_BASE_CODE_DHCPV6_PACKET *v6 =
+ (EFI_PXE_BASE_CODE_DHCPV6_PACKET *)packet->Raw;
+ int code, len;
+ DHCPv6_OPTION *p;
+
+ /* Consistency check */
+ if (v6->MessageType != DHCPv6_REPLY) {
+ VERB_PRT(2, Print(L"DHCPv6: MessageType: %d != %d\n",
+ v6->MessageType, DHCPv6_REPLY));
+ VERB_PRT(3, hexdump( (UINT8 *)v6, 1024));
+ return -1;
+ }
+ p = (DHCPv6_OPTION *)&v6->DhcpOptions;
+ while (0 != (code = ntohs(p->code))) {
+ len = ntohs(p->len);
+
+ VERB_PRT(4, { Print(L"DHCPv6: REPLY: Code=%d Len=%d\n",
+ code, len);
+ hexdump( p->data, (len<1020)?len:144);
+ });
+ if ( code == option ) {
+ len = (len > *length - 1) ? *length - 1 : len;
+ Memcpy(str, p->data, len);
+ str[len] = '\0';
+ *length = len;
+ }
+ p = (DHCPv6_OPTION *)((UINT8 *)p + len + 2*sizeof(UINT16));
+ }
+ return 0;
+}
+static INTN
+parse_bootfile_url(netfs_priv_state_t *nfs, CHAR8 *url) {
+ CHAR8 *end;
+ VERB_PRT(3, Print(L"DHCPv6: bootfile-url: '%a'\n", url));
+
+ /* check protocol */
+ if (strncmpa(url, (CHAR8 *)PROTO, sizeof(PROTO)-1)) {
+ ERR_PRT((L"Warning: bootfile-url must use TFTP for now! (%a)\n",
+ PROTO));
+ return -1;
+ }
+ /* fill in v6 address */
+ end = url+sizeof(PROTO);
+ while (*end != ']' && *end != '\0')
+ ++end;
+ if (url[sizeof(PROTO)-1] != '[' || *end != ']') {
+ ERR_PRT((L"Warning: bootfile-url must use '[IPv6::addr]'!\n"));
+ return -1;
+ }
+ *end = '\0';
+ Memcpy( nfs->srv_ip.v6.Addr, stra2ip6(url+sizeof(PROTO)), 16);
+ *end = ']';
+
+ /* remember bootfile path */
+ strncpya( nfs->bootfile, end + 1, NETFS_BOOTFILE_MAXLEN);
+ return 0;
+}
+
static VOID
netfs_extract_ip(netfs_priv_state_t *nfs)
{
EFI_PXE_BASE_CODE *pxe = nfs->pxe;
+ Memcpy(&nfs->cln_ip, &pxe->Mode->StationIp, sizeof(EFI_IP_ADDRESS));
+
+ if (pxe->Mode->UsingIpv6) {
+ CHAR8 str[NETFS_BOOTFILE_MAXLEN];
+ INTN len = NETFS_BOOTFILE_MAXLEN;
+ if (find_dhcp6_option(&nfs->pxe->Mode->DhcpAck,
+ OPT_BOOTFILE_URL, str, &len) != 0)
+ return;
+ parse_bootfile_url(nfs, str);
+ return;
+ }
+
if (pxe->Mode->PxeDiscoverValid) {
nfs->using_pxe = TRUE;
Memcpy(&nfs->srv_ip, pxe->Mode->PxeReply.Dhcpv4.BootpSiAddr, sizeof(EFI_IP_ADDRESS));
@@ -218,9 +453,9 @@ netfs_extract_ip(netfs_priv_state_t *nfs
} else {
Memcpy(&nfs->srv_ip, pxe->Mode->DhcpAck.Dhcpv4.BootpSiAddr, sizeof(EFI_IP_ADDRESS));
Memcpy(&nfs->hw_addr, pxe->Mode->DhcpAck.Dhcpv4.BootpHwAddr, sizeof(nfs->hw_addr));
+ strncpya(nfs->bootfile, pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, NETFS_BOOTFILE_MAXLEN);
}
- Memcpy(&nfs->cln_ip, &pxe->Mode->StationIp, sizeof(EFI_IP_ADDRESS));
Memcpy(&nfs->netmask, &pxe->Mode->SubnetMask, sizeof(EFI_IP_ADDRESS));
/*
@@ -326,11 +561,9 @@ netfs_open(netfs_interface_t *this, CHAR
U2ascii(name, ascii_name, FILENAME_MAXLEN);
- VERB_PRT(2, Print(L"downloading %a from %d.%d.%d.%d...\n", ascii_name,
- nfs->srv_ip.v4.Addr[0],
- nfs->srv_ip.v4.Addr[1],
- nfs->srv_ip.v4.Addr[2],
- nfs->srv_ip.v4.Addr[3]));
+ VERB_PRT(2, Print(L"downloading %a from %a...\n", ascii_name,
+ ip2stra((nfs->pxe->Mode->UsingIpv6 ? 16 : 4),
+ (UINT8 *)nfs->srv_ip.Addr)));
retry:
if (retries == 2) {
netfs_fd_free(nfs, f);
@@ -571,6 +804,9 @@ find_dhcp_option(EFI_PXE_BASE_CODE_PACKE
UINT8 tag, length;
UINT8 *opts = packet->Dhcpv4.DhcpOptions;
+ if (use_ipv6)
+ return find_dhcp6_option(packet, option, str, len);
+
*len = 0;
for(;;) {
@@ -637,15 +873,12 @@ netfs_getinfo(netfs_interface_t *this, n
VERB_PRT(3, Print(L"hostname(12): %a\n", str));
- /*
- * extract bootfile name from DHCP exchanges
- */
- if (nfs->using_pxe == 0) {
- ascii2U(nfs->pxe->Mode->DhcpAck.Dhcpv4.BootpBootFile, info->bootfile, NETFS_BOOTFILE_MAXLEN);
+skip_options:
+ if (!info->using_pxe && nfs->bootfile) {
+ ascii2U(nfs->bootfile, info->bootfile, NETFS_BOOTFILE_MAXLEN);
VERB_PRT(3, Print(L"bootfile: %s\n", info->bootfile));
}
-skip_options:
return EFI_SUCCESS;
}

View File

@ -1,109 +0,0 @@
From: Bernhard Walle <bwalle@suse.de>
Subject: Increase command line size to 2048 chars.
References: bnc#242702
Signed-off-by: Bernhard Walle <bwalle@suse.de>
---
choosers/simple.c | 10 +++++-----
choosers/textmenu.c | 6 +++---
config.c | 6 +++---
elilo.c | 2 +-
elilo.h | 3 ++-
5 files changed, 14 insertions(+), 13 deletions(-)
--- a/choosers/simple.c
+++ b/choosers/simple.c
@@ -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,
# 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;
--- a/choosers/textmenu.c
+++ b/choosers/textmenu.c
@@ -363,10 +363,10 @@ textmenu_choose(CHAR16 **argv, INTN argc
{
# 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;
--- 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 */
--- a/elilo.c
+++ b/elilo.c
@@ -93,7 +93,7 @@ do_kernel_load(CHAR16 *kname, kdesc_t *k
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
--- a/elilo.h
+++ b/elilo.h
@@ -69,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) */

67
elilo-mac-conf.diff Normal file
View File

@ -0,0 +1,67 @@
---
glue_netfs.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
--- a/glue_netfs.c
+++ b/glue_netfs.c
@@ -72,7 +72,7 @@ convert_mac2hex(UINT8 *hw_addr,INTN l, C
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*i+2] = '-';
}
str[3*l-1]='\0';
}
@@ -213,32 +213,35 @@ netfs_setdefaults(VOID *intf, config_fil
* will try machine/subnet specific files first.
* the filenames are constructed based on the IP(v4) address
*/
- convert_ip2hex(ipaddr, m, str);
#if 1
i = 0;
+ if (non_zero(info.hw_addr, 6)) {
+ convert_mac2hex(info.hw_addr,6,str);
+ /* Blindly prepend ARP type code for Ethernet (0x01)
+ * (at least for now...)
+ */
+ StrnCpy(config[i].fname, L"01-", 3);
+ StrnCat(config[i].fname, str, maxlen-10);
+ StrnCat(config[i++].fname, CONFIG_EXTENSION, maxlen-1);
+ }
if (non_zero(ipaddr, m)) {
- int nr = (m==16)? 10 : 6;
- int st = (m==16)? 2 : 1;
- m <<= 1;
- StrnCpy(config[i].fname, str, m);
- StrnCat(config[i++].fname,
- CONFIG_EXTENSION, maxlen - m);
- while (i <= nr) {
- int stub = m - (i+1)*st;
+ int step = (m==16)? 4 : 2;
+ int stub = m<<1;
+ convert_ip2hex(ipaddr, stub, str);
+ StrnCpy(config[i].fname, str, stub);
+ StrnCat(config[i++].fname, CONFIG_EXTENSION, maxlen-1);
+ while ( i+3 < MAX_DEFAULT_CONFIGS && stub > step) {
+ stub -= step;
StrnCpy(config[i].fname, str, stub);
StrnCat(config[i++].fname,
- CONFIG_ARCH_EXTENSION, maxlen - m);
+ CONFIG_ARCH_EXTENSION, maxlen-1);
StrnCpy(config[i].fname, str, stub);
StrnCat(config[i++].fname,
- CONFIG_EXTENSION, maxlen - m);
+ CONFIG_EXTENSION, maxlen-1);
}
}
- if (non_zero(info.hw_addr, 6)) {
- convert_mac2hex(info.hw_addr,6,str);
- StrnCpy(config[i].fname, str, maxlen-1);
- StrnCpy(config[i++].fname+17, CONFIG_EXTENSION, 6);
- }
#else
+ convert_ip2hex(ipaddr, m, str);
StrnCpy(config[0].fname, str, maxlen-1);
StrnCpy(config[0].fname+8, CONFIG_EXTENSION, 6);

33
elilo-max-conf.diff Normal file
View File

@ -0,0 +1,33 @@
---
fileops.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/fileops.c
+++ b/fileops.c
@@ -396,12 +396,13 @@ fops_setdefaults(struct config_file *def
boot_dev->fops->setdefaults(boot_dev->fops->intf, defconf, kname, maxlen, devpath);
}
i=0; while (i<MAX_DEFAULT_CONFIGS && defconf[i].fname[0] != CHAR_NULL) i += 1;
+ if ((i+1) >= MAX_DEFAULT_CONFIGS) {
#ifdef ELILO_DEBUG
- if ((i+3) >= MAX_DEFAULT_CONFIGS) {
- Print(L"ERROR: i = %d, MAX_DEFAULT_CONFIGS is not large enough\n", i);
- return EFI_INVALID_PARAMETER;
- }
+ Print(L"Warning: MAX_DEFAULT_CONFIGS(%d) is not large enough\n",
+ MAX_DEFAULT_CONFIGS);
#endif
+ i = MAX_DEFAULT_CONFIGS-2;
+ }
StrnCpy(defconf[i].fname, FILEOPS_ARCH_DEFAULT_CONFIG, maxlen-1);
StrnCpy(defconf[i+1].fname, FILEOPS_DEFAULT_CONFIG, maxlen-1);
@@ -409,7 +410,7 @@ fops_setdefaults(struct config_file *def
VERB_PRT(3,Print(L"Default config filename list:\n"));
for (i=0; i<MAX_DEFAULT_CONFIGS; i++) {
if (defconf[i].fname[0] == CHAR_NULL) { break; }
- VERB_PRT(3,Print(L"\t%s\n", defconf[i].fname));
+ VERB_PRT(3,Print(L"\t%2d. %s\n", i+1, defconf[i].fname));
}
#endif

View File

@ -1,95 +1,37 @@
---
x86_64/config.c | 19 ++++++++++++++++---
x86_64/sysdeps.h | 4 +++-
x86_64/system.c | 4 ++++
3 files changed, 23 insertions(+), 4 deletions(-)
x86_64/system.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
--- a/x86_64/config.c
+++ b/x86_64/config.c
@@ -33,15 +33,23 @@
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;
}
--- a/x86_64/sysdeps.h
+++ b/x86_64/sysdeps.h
@@ -364,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
@@ -457,7 +458,8 @@ start_kernel(VOID *kentry, boot_params_t
}
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__ */
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -251,6 +251,10 @@ static INTN get_video_info(boot_params_t
UINTN size1;
UINT8 i;
@@ -266,18 +266,18 @@ static INTN get_video_info(boot_params_t
+ 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,
if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
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");
+ 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.\n\n");
+ Print(L"You can SAFELY IGNORE this error. ELILO will "
+ "default to 'text-mode',\n"
+ "which may be enforced by setting that config variable\n"
+ "in elilo.conf or via cmdline.\n\n");
+ Print(L"However, if this is the last text output you see, "
+ "ensure that your\nkernel console command line"
+ "parameter matches up with the actual\n"
+ "EFI boot manager console output settings.\n\n");
return -1;
}
Gop_handle = alloc(size, 0);

View File

@ -1,186 +0,0 @@
---
x86_64/sysdeps.h | 34 +++++++++++++---------------------
x86_64/system.c | 34 +++++++---------------------------
2 files changed, 20 insertions(+), 48 deletions(-)
--- a/x86_64/sysdeps.h
+++ b/x86_64/sysdeps.h
@@ -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,17 @@ 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 pad_8[41];
/* 0x2D0 */ UINT8 e820_map[2560];
} s;
} boot_params_t;
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -493,17 +493,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 +545,14 @@ 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) {
/* %%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;
@@ -590,11 +577,6 @@ sysdeps_create_boot_params(
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
*/
CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG_X64, 4);
@@ -692,11 +674,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 +690,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."));

View File

@ -1,230 +0,0 @@
---
bootparams.c | 2
x86_64/system.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 134 insertions(+), 7 deletions(-)
--- a/bootparams.c
+++ b/bootparams.c
@@ -96,6 +96,8 @@ create_boot_params(CHAR16 *args, memdesc
*/
Memset(bp, 0, BOOT_PARAM_MEMSIZE);
+ U2ascii(args, cp, cmdline_size);
+
if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0;
/*
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -38,11 +38,19 @@
*/
#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;
/*
@@ -113,6 +121,8 @@ VOID *kernel_load_address = (VOID *)DEFA
VOID *initrd_start = NULL;
UINTN initrd_size = 0;
+INTN e820_map_overflow = 0;
+
INTN
sysdeps_init(EFI_HANDLE dev)
{
@@ -368,10 +378,56 @@ static INTN get_video_info(boot_params_t
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,
@@ -380,21 +436,56 @@ static void add_memory_region (struct e8
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 == 0)
+ DPR((L"AMR: %3s %4s %16s/%12s/%s\n",
+ L"idx", L" ", L"start", L"size", L"type"));
- if (x == E820_MAX) {
- Print(L"Too many entries in the memory map!\n");
- return;
- }
-
+ /* 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)
@@ -473,6 +564,7 @@ void fill_e820map(boot_params_t *bp, mma
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,
@@ -486,6 +578,8 @@ void fill_e820map(boot_params_t *bp, mma
/*
* x86_64 specific boot parameters initialization routine
+ *
+ * Note: debug and verbose messages have already been turned off!
*/
INTN
sysdeps_create_boot_params(
@@ -501,6 +595,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"));
@@ -834,6 +934,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;
}

View File

@ -1,228 +0,0 @@
---
elilo.h | 5 ++++
ia32/system.c | 6 +++++
ia64/system.c | 6 +++++
initrd.c | 12 +++++++++-
x86_64/sysdeps.h | 20 ++++++------------
x86_64/system.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++-------
6 files changed, 88 insertions(+), 22 deletions(-)
--- a/elilo.h
+++ b/elilo.h
@@ -54,6 +54,10 @@
#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
*/
@@ -212,6 +216,7 @@ extern CHAR16 *sysdeps_get_cmdline_opts(
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'\\'
--- a/ia32/system.c
+++ b/ia32/system.c
@@ -149,6 +149,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, mem
return 0;
}
+VOID *
+sysdeps_checkfix_initrd(VOID *start_addr, memdesc_t *imem)
+{
+ return start_addr;
+}
+
VOID
sysdeps_free_boot_params(boot_params_t *bp)
{
--- a/ia64/system.c
+++ b/ia64/system.c
@@ -140,6 +140,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, mem
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)
--- 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 *i
/* 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));
--- a/x86_64/sysdeps.h
+++ b/x86_64/sysdeps.h
@@ -284,7 +284,8 @@ typedef union x86_64_boot_params {
/* 0x227 */ UINT8 ext_loader_type; /* LDR */
/* 0x228 */ UINT32 cmdline_addr; /* LDR */
-/* 0x22C */ UINT32 pad_8[41];
+/* 0x22C */ UINT32 initrd_addr_max; /* BLD */
+/* 0x230 */ UINT32 pad_8[40];
/* 0x2D0 */ UINT8 e820_map[2560];
} s;
} boot_params_t;
@@ -374,7 +375,6 @@ start_kernel(VOID *kentry, boot_params_t
UINT16 kernel_cs;
} jumpvector;
VOID *jump_start;
- uint64_t temp;
/*
* Disable interrupts.
@@ -382,22 +382,16 @@ start_kernel(VOID *kentry, boot_params_t
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
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -131,10 +131,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 +144,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, mem
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 +157,48 @@ sysdeps_initrd_get_addr(kdesc_t *kd, mem
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)
{
@@ -550,6 +592,11 @@ sysdeps_create_boot_params(
/* 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);

View File

@ -1,257 +0,0 @@
---
alloc.c | 10 +++
ia32/bzimage.c | 2
x86_64/bzimage.c | 160 +++++++++++++++++++++++++++++++++++++++++++++----------
x86_64/sysdeps.h | 5 +
x86_64/system.c | 9 ++-
5 files changed, 152 insertions(+), 34 deletions(-)
--- a/alloc.c
+++ b/alloc.c
@@ -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;
--- a/ia32/bzimage.c
+++ b/ia32/bzimage.c
@@ -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) {
/*
--- a/x86_64/bzimage.c
+++ b/x86_64/bzimage.c
@@ -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,37 +281,16 @@ 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.
*/
--- a/x86_64/sysdeps.h
+++ b/x86_64/sysdeps.h
@@ -285,7 +285,10 @@ typedef union x86_64_boot_params {
/* 0x228 */ UINT32 cmdline_addr; /* LDR */
/* 0x22C */ UINT32 initrd_addr_max; /* BLD */
-/* 0x230 */ UINT32 pad_8[40];
+/* 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;
--- a/x86_64/system.c
+++ b/x86_64/system.c
@@ -105,10 +105,10 @@ 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;
@@ -631,6 +631,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;
/*

View File

@ -1,19 +1,231 @@
-------------------------------------------------------------------
Fri Oct 25 13:37:55 UTC 2013 - rw@suse.de
- elilo.efi
* update to elilo-3.16 to fix OBS download check.
Essentially "white-space" changes, plus bumping version number,
minus Debian idiosyncrasies.
- elilo.spec
* Remove date string from 'eliloalt'.
* Avoid duplication of 'elilo.txt'.
- elilo.pl
* Support for 'UUID=' and 'LABEL=' to specify root file-system.
-------------------------------------------------------------------
Thu Oct 24 17:18:48 UTC 2013 - rw@suse.de
- elilo.spec
* Add perl modules to 'PreReq'. (bnc#842183)
- Update openSUSE to elilo-3.14 from SLE11.
-------------------------------------------------------------------
Fri Aug 16 12:01:42 UTC 2013 - rw@suse.de
- elilo.pl
* SecureBoot: cope with separate '/boot' file-system. (bnc#825932)
* SecureBoot: improve detection of file-system UUIDs. (bnc#828835)
* Correctly handle installation to 'BOOT'.
-------------------------------------------------------------------
Wed May 29 15:10:40 UTC 2013 - rw@suse.com
- elilo.pl
* Always delete old EBM entries to fix ordering. (bnc#819900)
* Prevent XEN 'default' in 'elilo.conf'. (bnc#819900c5)
* Add man-page section about '--refresh-EBM' failure. (bnc#821109)
-------------------------------------------------------------------
Wed May 8 13:30:02 UTC 2013 - rw@suse.com
- elilo.pl
* SecureBoot: create only one Boot Manager entry. (bnc#818961)
-------------------------------------------------------------------
Fri Apr 19 13:28:08 UTC 2013 - rw@suse.com
- elilo.efi
* Clear console on startup. (bnc#812799)
* Avoid crash caused by EFI memory map changes. (bnc#800035)
- elilo.pl
* Work around chainloading issue with XEN. (bnc#812109)
-------------------------------------------------------------------
Wed Mar 27 21:40:29 UTC 2013 - rw@suse.com
- elilo.pl
* Fix handling of missing 'default' again.
-------------------------------------------------------------------
Wed Mar 27 20:42:50 UTC 2013 - rw@suse.com
- elilo.pl
* Implement chainloading of XEN for SecureBoot. (bnc#809702)
* Maintain 'default' in SecureBoot config. (bnc#811608c28)
* Handle failure of 'efibootmgr'. (bnc#809702c10)
* Improve verbose messages to be less alarming.
-------------------------------------------------------------------
Fri Mar 8 14:06:28 UTC 2013 - rw@suse.com
- elilo.efi
* Force default configs at the end of the network search list.
(bnc#789137)
- elilo.pl
* Disable use of 'shim'-loader options. (bnc#798043)
* Fix solitary 'secure-boot' for real.
-------------------------------------------------------------------
Tue Feb 12 17:00:32 UTC 2013 - rw@suse.com
- elilo.pl
* Revert work-around for 'shim'-loader option parsing. (bnc#798043)
* Treat 'secure-boot' identical to 'secure-boot = on'.
* Fix 'SecureBoot' sysfs variable reading.
-------------------------------------------------------------------
Fri Feb 8 18:42:49 UTC 2013 - rw@suse.com
- elilo.efi
* Now really introduce 'block-size'. (bnc#681242)
* Clarify warning message on GOP failure.
- elilo.pl
* Synchronize check for "Secure Boot" with YaST.
-------------------------------------------------------------------
Fri Jan 18 15:00:44 UTC 2013 - rw@suse.com
- elilo.efi
* Make automatic appending of 'add_efi_memmap' to kernel command
line default, and introduce config-file option (add-efi-memmap)
to control this (auto|false). (fate#314210, bnc#772245)
* Bring network search list more in line with 'PXELINUX'. (bnc#789137)
* Introduce 'block-size' as global option in 'elilo.conf'. (bnc#681242)
- elilo.pl
* Work around limitations in 'shim'-loader option parsing. (bnc#798043)
* Don't use temporary file to establish load options.
-------------------------------------------------------------------
Wed Dec 19 21:20:25 UTC 2012 - rw@suse.com
- elilo.pl
* Add support UEFI Secure Boot (via 'grub.efi'). (fate#314485)
* Don't try to write 'xen.cfg', if no valid XEN section is found
and treat "VMM" EFI-binaries as "mandatory". (bnc#792100)
* Support more than 10 EFI Boot Manager (EBM) entries.
* Stop using '--write-signature' for 'efibootmgr' (as non-GPT
disk-labels aren't supported anyway).
* Sort creation of EBM entries according to default boot section.
* Fix initial handling of obsolete files.
-------------------------------------------------------------------
Mon Jan 16 15:21:24 UTC 2012 - rw@suse.de
- elilo.pl
* Cope with misguided '/dev/mapper/' entries in 'fstab'. (bnc#717828)
-------------------------------------------------------------------
Fri Nov 25 17:12:38 UTC 2011 - rw@suse.de
- elilo.pl
* Allow empty 'vmmopts' for 'xen.efi'. (bnc#731288)
* Implement refreshing of EFI Boot Manager entries. (bnc#717828)
-------------------------------------------------------------------
Mon Sep 19 14:53:06 UTC 2011 - rw@suse.de
- elilo.pl
* Fix handling of 'xen.cfg'. (bnc#706110)
* Record installed files and remove only those in the future.
-------------------------------------------------------------------
Sun Sep 18 17:17:12 UTC 2011 - jengelh@medozas.de
- Remove redundant/obsolete tags/sections from specfile
- elilo.spec
* Remove redundant/obsolete tags/sections from specfile
(cf. packaging guidelines)
-------------------------------------------------------------------
Mon Aug 1 12:43:45 UTC 2011 - rw@suse.de
- elilo.efi
* Allow booting in an IPv6 network environment. (fate#311995)
- elilo.pl
* Add support for 'xen.efi'. (fate#311376)
-------------------------------------------------------------------
Fri Jun 17 12:54:53 UTC 2011 - rw@suse.de
- elilo.efi
* Update to elilo-3.14. (fate#311532)
- elilo.spec
* Follow openSUSE migration from libexecdir to libdir.
- elilo.pl
* Don't initialize '$[' to 0.
* Adapt to replacement of libexecdir with libdir.
-------------------------------------------------------------------
Fri Dec 17 10:51:23 UTC 2010 - coolo@novell.com
* Update to elilo-3.12 from SLE11 to fix EFI boot (bnc#659368)
- see ChangeLog for a detailed log
- Update openSUSE to elilo-3.12 from SLE11 to fix EFI boot (bnc#659368)
(see ChangeLog for a detailed log)
-------------------------------------------------------------------
Mon Apr 12 16:59:30 CEST 2010 - rw@suse.de
- elilo.efi
* Handle EFI memory maps larger than E820_MAX. (bnc#594516)
-------------------------------------------------------------------
Tue Mar 30 11:42:43 CEST 2010 - rw@suse.de
- elilo.efi
* Update boot protocol for 2.6.30. (bnc#560443)
* Allocate initrd below kernel specified limit. (bnc#577570)
* Load kernel relocated. (bnc#447843, 516215, 568848, 587858)
- elilo.pl
* Add handling of VMM for XEN. (bnc#578926)
-------------------------------------------------------------------
Tue Jan 26 12:14:57 CET 2010 - rw@suse.de
- elilo.efi
* PRELIMINARY debugging patch for x86_64. (bnc#560443)
-------------------------------------------------------------------
Fri Nov 20 13:10:51 CET 2009 - rw@suse.de
- elilo.efi
* Update to elilo-3.12.
-------------------------------------------------------------------
Tue Sep 22 18:30:29 CEST 2009 - rw@suse.de
- elilo.spec
* Submit to SLE11. (bnc#494042)
-------------------------------------------------------------------
Mon Jul 20 08:16:44 CEST 2009 - coolo@novell.com
- replace libexecdir with libdir
- elilo.spec
* replace libexecdir with libdir
-------------------------------------------------------------------
Thu May 28 13:05:25 CEST 2009 - ro@suse.de
- elilo.spec
* Use binutils219 on SLE10 SP3.
-------------------------------------------------------------------
Fri May 15 13:47:44 CEST 2009 - rw@suse.de
- elilo.efi
* Update to elilo-3.10. (fate#306032)
-------------------------------------------------------------------
Thu Apr 30 15:24:26 CEST 2009 - ro@suse.de
- elilo.spec
* Submit to SLE10 SP3. (fate#306032)
-------------------------------------------------------------------
Mon Feb 9 15:36:39 CET 2009 - rw@suse.de

1231
elilo.pl

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
#
# spec file for package elilo
#
# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -22,60 +22,61 @@ BuildRequires: binutils219
#!BuildIgnore: binutils
%endif
%endif
BuildRequires: gnu-efi >= 3.0e
BuildRequires: gnu-efi >= 3.0u
BuildRequires: perl(Pod::Man)
Name: elilo
Summary: EFI Linux Loader
Version: 3.12
Release: 1
ExclusiveArch: ia64 %ix86 x86_64
Group: System/Boot
PreReq: /usr/bin/perl
License: GPL-2.0+
Group: System/Boot
Version: 3.16
Release: 0
ExclusiveArch: ia64 %ix86 x86_64
PreReq: /usr/bin/perl perl(Pod::Usage) perl(Getopt::Long)
# "perl" must be in place *before* any package's 'pre' or 'post' section
# can (directly or indirectly) run '/sbin/elilo'! (bnc#842183)
%ifarch ia64
PreReq: perl(File::Compare)
%endif
Url: http://elilo.sourceforge.net/
Source: http://dl.sourceforge.net/elilo/elilo-3.12-source.tar.gz
#ource: http://downloads.sourceforge.net/elilo/elilo-3.16-all.tar.gz
Source: elilo-%{version}-source.tar.xz
Source1: elilo.pl
Source2: debian.eliloalt.man8
Source3: elilo.conf.man5
Source4: http://downloads.sourceforge.net/elilo/%{version}-release-notes.txt
Source9: rpmlintrc
Patch0: elilo-x86-64-bootproto-update.diff
Patch1: elilo-x86-64-initrd.diff
Patch2: elilo-x86-64-kernel.diff
Patch3: elilo-x86-64-e820-max.diff
Patch4: elilo-fix-possible-overflow.diff
Patch5: elilo-bzimage-alloc.diff
Patch6: elilo-fix-strncpy-overflow.diff
Patch7: elilo-longer-commandline.diff
Patch8: elilo-avoid-tab.diff
Patch9: elilo-cleanup.diff
Patch10: eliloalt-sysfs.diff
Patch11: elilo-MAC.diff
Patch12: elilo-text-mode.diff
Patch0: elilo-ipv6.diff
Patch1: elilo-max-conf.diff
Patch2: elilo-mac-conf.diff
Patch3: elilo-auto-add_efi_memmap.diff
Patch4: elilo-blocksize.diff
Patch5: elilo-text-mode.diff
Patch10: elilo-de-debianify.diff
Patch11: eliloalt-no-date.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
The EFI Linux boot loader.
%prep
%setup -q
%setup -q -n %{name}-%{version}-source
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%build
perl -pi -e 's{/usr/lib}{%{_libdir}}' Make.defaults
make OPTIMFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fno-stack-protector"
##################################################################
## DO NOT ADD RPM OPT FLAGS! THIS DOES NOT BUILD AGAINST GLIBC. ##
##################################################################
make OPTIMFLAGS="-fmessage-length=0"
perl -pe 's{\@EDITION\@}{%{version}-%{release}};
s{\@LIBDIR\@}{%{_libdir}};
s{\@ARCH\@}{%{_target_cpu}};
@ -94,14 +95,20 @@ install -p -m 555 elilo.pl $RPM_BUILD_ROOT/sbin/elilo
install -D -p -m 644 elilo.8 $RPM_BUILD_ROOT/usr/share/man/man8/elilo.8
install -D -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT/usr/share/man/man8/eliloalt.8
install -D -p -m 644 %{SOURCE3} $RPM_BUILD_ROOT/usr/share/man/man5/elilo.conf.5
install -p -m 644 %{SOURCE4} RELEASE-NOTES
diff -q docs/README.txt docs/elilo.txt && rm -f docs/README.txt
%post
#/sbin/elilo -v || :
echo "Please run /sbin/elilo!"
if [ -r /etc/sysconfig/bootloader ]; then
. /etc/sysconfig/bootloader
if [ "$LOADER_TYPE" = "elilo" -a -r /etc/elilo.conf ]; then
/sbin/elilo -v || :
fi
fi
%files
%defattr(-, root, root)
%doc README README.* TODO docs/*.txt ChangeLog
%doc README README.* TODO docs/*.txt RELEASE-NOTES
%{_libdir}/efi
/sbin/elilo
/sbin/eliloalt

21
eliloalt-no-date.diff Normal file
View File

@ -0,0 +1,21 @@
---
tools/eliloalt.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/tools/eliloalt.c
+++ b/tools/eliloalt.c
@@ -282,7 +282,13 @@ main(int argc, char **argv)
switch(c) {
case 0: continue; /* fast path for options */
case 1:
- printf("Version %s Date: %s\n", ELILOALT_VERSION, __DATE__);
+ printf("Version %s\n", ELILOALT_VERSION);
+ /* Don't use __DATE__ here, as it causes
+ * excessive rebuilds, which seems very
+ * wasteful for a tool that did not change
+ * in a very long time, and probably won't
+ * any more...
+ */
exit(0);
case 2:
case 'h':

View File

@ -1,113 +0,0 @@
---
tools/eliloalt.c | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
--- a/tools/eliloalt.c
+++ b/tools/eliloalt.c
@@ -47,8 +47,10 @@
#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);