From d2abc5e3936ee9629f407e400d5d9c9bc2487ed360f55cb896f31cbc2112fde9 Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Mon, 15 Dec 2008 11:28:48 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/elilo?expand=0&rev=11 --- eliloalt.debian.man8 => debian.eliloalt.man8 | 0 elilo-bzimage-alloc.diff | 225 +++++++++++++++++++ elilo-uEFI-no-alloc_kmem.diff | 108 --------- elilo.changes | 8 + elilo.conf.man5 | 11 + elilo.spec | 27 +-- 6 files changed, 258 insertions(+), 121 deletions(-) rename eliloalt.debian.man8 => debian.eliloalt.man8 (100%) create mode 100644 elilo-bzimage-alloc.diff delete mode 100644 elilo-uEFI-no-alloc_kmem.diff create mode 100644 elilo.conf.man5 diff --git a/eliloalt.debian.man8 b/debian.eliloalt.man8 similarity index 100% rename from eliloalt.debian.man8 rename to debian.eliloalt.man8 diff --git a/elilo-bzimage-alloc.diff b/elilo-bzimage-alloc.diff new file mode 100644 index 0000000..f2af53d --- /dev/null +++ b/elilo-bzimage-alloc.diff @@ -0,0 +1,225 @@ +From: Stuart_Hayes@Dell.com +Subject: Re: [elilo-discuss] Follow-Up to 1MB Allocation Problem +Message-ID: + +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! + +diff -purN '--exclude=*o' '--exclude=tags' elilo-3.8-3.35-orig1/alloc.c elilo-3.8-3.35-orig_c/alloc.c +--- elilo-3.8-3.35-orig1/alloc.c 2008-12-08 06:03:05.000000000 -0600 ++++ elilo-3.8-3.35-orig_c/alloc.c 2008-12-08 04:51:28.000000000 -0600 +@@ -213,6 +213,19 @@ free_all(VOID) + } + + INTN ++alloc_kmem_anywhere(VOID **start_addr, UINTN pgcnt) ++{ ++ void * tmp; ++ if ((tmp = alloc_pages(pgcnt, EfiLoaderData, AllocateAnyPages, *start_addr)) == 0) return -1; ++ ++ kmem_addr = tmp; ++ kmem_pgcnt = pgcnt; ++ *start_addr = tmp; ++ ++ return 0; ++} ++ ++INTN + alloc_kmem(VOID *start_addr, UINTN pgcnt) + { + if (alloc_pages(pgcnt, EfiLoaderData, AllocateAddress, start_addr) == 0) return -1; +diff -purN '--exclude=*o' '--exclude=tags' elilo-3.8-3.35-orig1/elilo.c elilo-3.8-3.35-orig_c/elilo.c +--- elilo-3.8-3.35-orig1/elilo.c 2008-12-08 06:03:05.000000000 -0600 ++++ elilo-3.8-3.35-orig_c/elilo.c 2008-12-08 05:01:33.000000000 -0600 +@@ -132,6 +132,9 @@ kernel_load(EFI_HANDLE image, CHAR16 *kn + + if (elilo_opt.initrd[0]) { + ++ /* ++ * fix me? -- load_file() ignores address from sysdeps_initrd_get_addr() ++ */ + if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error; + + switch(load_file(elilo_opt.initrd, imem)) { +Files elilo-3.8-3.35-orig1/elilo.efi and elilo-3.8-3.35-orig_c/elilo.efi differ +Files elilo-3.8-3.35-orig1/tools/eliloalt and elilo-3.8-3.35-orig_c/tools/eliloalt differ +diff -purN '--exclude=*o' '--exclude=tags' elilo-3.8-3.35-orig1/x86_64/bzimage.c elilo-3.8-3.35-orig_c/x86_64/bzimage.c +--- elilo-3.8-3.35-orig1/x86_64/bzimage.c 2008-12-08 06:03:05.000000000 -0600 ++++ elilo-3.8-3.35-orig_c/x86_64/bzimage.c 2008-12-08 05:04:52.000000000 -0600 +@@ -158,13 +158,37 @@ 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 >= 0) && ++ (param_start->s.kernel_start >= DEFAULT_KERNEL_START)) { ++ kernel_start = kernel_load_address = (VOID *)((UINTN)param_start->s.kernel_start); ++ VERB_PRT(3, Print(L"kernel header suggests kernel start at address 0x%x\n", ++ kernel_start)); ++ } ++ ++ kernel_load_address = kernel_start; ++ + if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) { +- ERR_PRT((L"Could not allocate kernel memory.")); +- return -1; +- } else { +- VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n", +- kernel_start, kernel_size)); ++ /* ++ * 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))) { ++ 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: 0x%x kernel_size: %d loading at: 0x%x\n", ++ kernel_start, kernel_size, kernel_load_address)); ++ + /* + * Now read the rest of the kernel image into memory. + */ +@@ -172,7 +196,7 @@ bzImage_probe(CHAR16 *kname) + DBG_PRT((L"reading kernel image...\n")); + + size = kernel_size; +- efi_status = fops_read(fd, kernel_start, &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)); + free(param_start); +diff -purN '--exclude=*o' '--exclude=tags' elilo-3.8-3.35-orig1/x86_64/sysdeps.h elilo-3.8-3.35-orig_c/x86_64/sysdeps.h +--- elilo-3.8-3.35-orig1/x86_64/sysdeps.h 2008-12-08 06:03:05.000000000 -0600 ++++ elilo-3.8-3.35-orig_c/x86_64/sysdeps.h 2008-12-08 06:01:52.000000000 -0600 +@@ -48,6 +48,11 @@ + #define INITRD_START (50*1024*1024) + + /* ++ * Default start address for kernel. ++ */ ++#define DEFAULT_KERNEL_START 0x100000 ++ ++/* + * This version must match the one in the kernel. + * + * This table was put together using information from the +@@ -307,10 +312,16 @@ typedef union x86_64_boot_params { + UINT8 *t = (UINT8 *)(to); \ + UINT8 *f = (UINT8 *)(from); \ + UINTN n = cnt; \ +- if (t && f && n) { \ ++ if (t && f && n && (tf)) { \ ++ t += n; \ ++ f += n; \ ++ while (n--) { \ ++ *t-- = *f--; \ ++ } \ + } \ + } + +@@ -343,6 +354,7 @@ extern UINTN param_size; + + extern VOID *kernel_start; + extern UINTN kernel_size; ++extern VOID *kernel_load_address; + + extern VOID *initrd_start; + extern UINTN initrd_size; +@@ -379,14 +391,24 @@ start_kernel(VOID *kentry, boot_params_t + asm volatile ( "cli" : : ); + + /* +- * Relocate initrd, if present. ++ * 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). + */ + ++ 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 +diff -purN '--exclude=*o' '--exclude=tags' elilo-3.8-3.35-orig1/x86_64/system.c elilo-3.8-3.35-orig_c/x86_64/system.c +--- elilo-3.8-3.35-orig1/x86_64/system.c 2008-12-08 06:03:25.000000000 -0600 ++++ elilo-3.8-3.35-orig_c/x86_64/system.c 2008-12-08 04:51:28.000000000 -0600 +@@ -105,7 +105,9 @@ 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 *)0x100000; /* 1M */ ++VOID *kernel_start = (VOID *)DEFAULT_KERNEL_START; ++/* The kernel may load elsewhere if EFI firmware reserves kernel_start */ ++VOID *kernel_load_address = (VOID *)DEFAULT_KERNEL_START; + + VOID *initrd_start = NULL; + UINTN initrd_size = 0; +--- elilo/fs/localfs.c ++++ elilo/fs/localfs.c +@@ -98,7 +98,7 @@ + + 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); + } +--- elilo/elilo.h ++++ elilo/elilo.h +@@ -151,6 +151,7 @@ + extern VOID free_pages(VOID *); + extern VOID free_all(VOID); + extern INTN alloc_kmem(VOID *, UINTN); ++extern INTN alloc_kmem_anywhere(VOID **, UINTN); + extern VOID free_kmem(VOID); + extern VOID free_all_memory(VOID); + diff --git a/elilo-uEFI-no-alloc_kmem.diff b/elilo-uEFI-no-alloc_kmem.diff deleted file mode 100644 index 0805ba5..0000000 --- a/elilo-uEFI-no-alloc_kmem.diff +++ /dev/null @@ -1,108 +0,0 @@ ---- elilo/x86_64/bzimage.c -+++ elilo/x86_64/bzimage.c -@@ -160,7 +160,9 @@ - - if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) { - ERR_PRT((L"Could not allocate kernel memory.")); -- return -1; -+ if (x86_64_allow_alloc_fail() != 1) { -+ return -1; -+ } - } else { - VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n", - kernel_start, kernel_size)); -@@ -169,7 +171,7 @@ - * 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_start, &size); -@@ -181,6 +183,8 @@ - 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)); ---- elilo/x86_64/config.c -+++ elilo/x86_64/config.c -@@ -33,15 +33,24 @@ - - typedef struct { - UINTN legacy_free_boot; -+ UINTN allow_alloc_fail; - } 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} -+ {OPT_BOOL, OPT_GLOBAL, L"legacy-free", NULL, NULL, &x86_64_gconf.legacy_free_boot}, -+ {OPT_BOOL, OPT_GLOBAL, L"skid-alloc", NULL, NULL, &x86_64_gconf.allow_alloc_fail}, -+}; -+ -+static config_option_t sysdeps_image_options[]={ -+ {OPT_BOOL, OPT_IMAGE_SYS, L"skid-alloc", NULL, NULL, x86_64_opt_offsetof(allow_alloc_fail)}, - }; - -+ - /* - * X86_64 operations that need to be done only once and just before - * entering the main loop of the loader -@@ -82,6 +91,13 @@ - } - - INTN -+x86_64_allow_alloc_fail(VOID) -+{ -+ return x86_64_gconf.allow_alloc_fail == TRUE -+ || (elilo_opt.sys_img_opts && elilo_opt.sys_img_opts->allow_alloc_fail ==TRUE) ? 1 : 0; -+} -+ -+INTN - sysdeps_register_options(VOID) - { - INTN ret; -@@ -89,14 +105,11 @@ - 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; - } ---- elilo/x86_64/sysdeps.h -+++ elilo/x86_64/sysdeps.h -@@ -357,6 +357,7 @@ - extern UINTN rmswitch_size; - - extern INTN x86_64_use_legacy_free_boot(); -+extern INTN x86_64_allow_alloc_fail(); - - /* - * How to jump to kernel code -@@ -449,7 +450,8 @@ - } - - typedef struct sys_img_options { -- UINT8 nothing_yet; -+ UINT8 dummy; /* forces non-zero offset for first field */ -+ UINT8 allow_alloc_fail; /* ignore failure of alloc_kmem */ - } sys_img_options_t; - - #endif /* __ELILO_SYSDEPS_X86_64_H__ */ diff --git a/elilo.changes b/elilo.changes index c0895a7..37dc574 100644 --- a/elilo.changes +++ b/elilo.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Dec 9 16:34:53 CET 2008 - rw@suse.de + +- elilo.efi + * Second attempt to work around firmware problem. (bnc#437486) +- elilo.conf + * Provide stub man page. (bnc#435648) + ------------------------------------------------------------------- Fri Nov 21 15:56:50 CET 2008 - rw@suse.de diff --git a/elilo.conf.man5 b/elilo.conf.man5 new file mode 100644 index 0000000..5819dd2 --- /dev/null +++ b/elilo.conf.man5 @@ -0,0 +1,11 @@ +.TH ELILO.CONF 5 "2008-12-06" +.SH NAME +elilo.conf \- elilo configuration file +.SH SYNOPSIS +/etc/elilo.conf +.SH FILES +.IR /etc/elilo.conf , +.I /boot/efi/efi/SuSE/elilo.conf +.SH SEE ALSO +.IR /usr/share/doc/packages/elilo/elilo.txt +(Section III) diff --git a/elilo.spec b/elilo.spec index c6bb396..29158c4 100644 --- a/elilo.spec +++ b/elilo.spec @@ -21,7 +21,7 @@ Name: elilo Summary: EFI Linux Loader Version: 3.8 -Release: 24 +Release: 25 ExclusiveArch: ia64 %ix86 x86_64 Group: System/Boot AutoReqProv: on @@ -30,16 +30,17 @@ License: GPL v2 or later Url: http://elilo.sourceforge.net/ Source: http://dl.sourceforge.net/elilo/elilo-3.8.tar.gz Source1: elilo.pl -Source2: eliloalt.debian.man8 -Source3: rpmlintrc +Source2: debian.eliloalt.man8 +Source3: elilo.conf.man5 +Source9: rpmlintrc Patch0: elilo-3.8-cvs20080127.diff Patch1: elilo-MAC.diff Patch2: elilo-spelling.diff Patch3: elilo-longer-commandline.diff Patch4: elilo-fix-possible-overflow.diff Patch5: elilo-avoid-tab.diff -Patch6: eliloalt-sysfs.diff -Patch7: elilo-uEFI-no-alloc_kmem.diff +Patch6: elilo-bzimage-alloc.diff +Patch9: eliloalt-sysfs.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: gnu-efi >= 3.0e @@ -64,7 +65,7 @@ Authors: %patch4 -p1 %patch5 -p1 %patch6 -p1 -%patch7 -p1 +%patch9 -p1 perl -pe 's{\@EDITION\@}{%{version}-%{release}}; s{\@LIBEXECDIR\@}{%{_libexecdir}}; s{\@ARCH\@}{%{_target_cpu}}; @@ -72,7 +73,6 @@ perl -pe 's{\@EDITION\@}{%{version}-%{release}}; perl -pi -e 's{/usr/lib}{%{_libexecdir}}' Make.defaults chmod 555 elilo.pl && touch -r %{SOURCE1} elilo.pl ! fgrep '%%{version}-%%{release}' elilo.pl -cp --preserve=time %{SOURCE2} eliloalt.8 %build make OPTIMFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -fno-stack-protector" @@ -85,11 +85,9 @@ install -d $RPM_BUILD_ROOT%{_libexecdir}/efi $RPM_BUILD_ROOT/sbin install -m 444 elilo.efi $RPM_BUILD_ROOT%{_libexecdir}/efi install tools/eliloalt $RPM_BUILD_ROOT/sbin install -p -m 555 elilo.pl $RPM_BUILD_ROOT/sbin/elilo -%if 0 -install -D -p -m 644 elilo.5 $RPM_BUILD_ROOT/usr/share/man/man5/elilo.conf.5 -%endif install -D -p -m 644 elilo.8 $RPM_BUILD_ROOT/usr/share/man/man8/elilo.8 -install -D -p -m 644 eliloalt.8 $RPM_BUILD_ROOT/usr/share/man/man8/eliloalt.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 %clean rm -fr $RPM_BUILD_ROOT @@ -104,12 +102,15 @@ echo "Please run /sbin/elilo!" %{_libexecdir}/efi /sbin/elilo /sbin/eliloalt -%if 0 /usr/share/man/man5/* -%endif /usr/share/man/man8/* %changelog +* Tue Dec 09 2008 rw@suse.de +- elilo.efi + * Second attempt to work around firmware problem. (bnc#437486) +- elilo.conf + * Provide stub man page. (bnc#435648) * Fri Nov 21 2008 rw@suse.de - elilo.efi * Significant code cleanup from CVS. (bnc#443565)