From 8e0034665aa8483b27191c723608575536d01303 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Mon, 19 May 2008 23:09:33 -0600 Subject: [PATCH] Imported Upstream version 3.6 --- ChangeLog | 37 ++- Make.defaults | 48 ++-- Makefile | 2 +- TODO | 2 - alloc.c | 4 +- bootparams.c | 5 +- choosers/simple.c | 27 +- choosers/textmenu.c | 25 +- config.c | 65 ++--- docs/netbooting.txt | 18 +- elilo-ia32.efi | Bin 159859 -> 0 bytes elilo-ia64.efi | Bin 348238 -> 0 bytes elilo.c | 129 +++++++-- elilo.h | 21 +- fileops.c | 58 +++- fileops.h | 8 +- glue_localfs.c | 6 +- glue_netfs.c | 55 ++-- gnu-efi-3.0a-ia32.patch | 19 -- gunzip.c | 224 +++++++++++++++ ia64/gzip.h => gzip.h | 38 ++- ia32/Makefile | 2 +- ia32/bzimage.c | 224 +++++++++++++++ ia32/gzip.c | 554 ++++++++++++++++++++++++++++++++++++ ia32/gzip_loader.c | 81 ++++++ ia32/plain_loader.c | 285 +++++++++++++++++++ ia32/sysdeps.h | 46 +-- ia32/system.c | 366 +++--------------------- ia64/gzip.c | 12 +- ia64/gzip_loader.c | 2 + ia64/plain_loader.c | 4 +- ia64/private.h | 2 + ia64/setjmp.S | 1 + ia64/sysdeps.h | 3 + ia64/system.c | 26 +- ia64/inflate.c => inflate.c | 36 --- initrd.c | 41 +-- 37 files changed, 1860 insertions(+), 616 deletions(-) delete mode 100755 elilo-ia32.efi delete mode 100755 elilo-ia64.efi delete mode 100644 gnu-efi-3.0a-ia32.patch create mode 100644 gunzip.c rename ia64/gzip.h => gzip.h (50%) create mode 100644 ia32/bzimage.c create mode 100644 ia32/gzip.c create mode 100644 ia32/gzip_loader.c create mode 100644 ia32/plain_loader.c rename ia64/inflate.c => inflate.c (97%) diff --git a/ChangeLog b/ChangeLog index 07aba8e..d2cbe27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +2006-01-09 Brett Johnson + * Released 3.6 +2005-12-22 Alex Williamson + * Fixed vmcode_name initialization in textmenu chooser +2005-12-01 Alex Williamson + * Applied patch from Fred Yang to support the + vmm= boot option. This option specifies the kernel image for a + virtual machine monitor (aka hypervisor). The vmm= and image= + options are used together to load both the hypervisor kernel and + the guest domain kernel into memory. If a vmm= option is not + specified, elilo defaults to the old behavior of loading and booting + to the image= kernel. + * Added support for compressed image= files when used with the vmm= + option. If the image= file is detected to be gzip compressed, the + image will be uncompressed into memory before it is provided to the + hypervisor. Any combination of compressed and uncompressed images + can be used for the image and vmm options. +2005-09-15 Brett Johnson + * Applied patch from Tristan Gingold to add dcache flush and sync with + icache to gzip and plain loaders. This ommision was just noticed now + due to the much larger caches in Montecito, and the smaller size of + Xen (as compared to the linux kernel). +2004-09-27 Brett Johnson + * Increase the hardcoded size of the texmenu chooser menu from 16 to 64 +2004-09-23 Brett Johnson + * Fix for 924147. Thanks to Stephanie Schaaf for a patch + that the fix is based on. +2004-02-19 Brett Johnson + * Fixed bug where default image initrd would carry over to another + image that was selected interactively (iff the newly selected image + did not have an initrd). + * Added support for subnet-specific config files in netfs. +2004-02-17 Brett Johnson + * integrated ia32 compressed kernel support from Matt Tolentino + 2003-08-20 Stephane Eranian * released 3.4 2003-08-19 Stephane Eranian @@ -85,7 +120,7 @@ * released version 3.2 * cleanup some GNU extension in fs/ext2fs.c (variable size array) * updated all documentation. Added netbooting.txt, simple_chooser.txt, - eliloalt.txt, elilovar.txt + eliloalt.txt, elilovar.txt 2002-02-21 Stephane Eranian * added a Linux utility program (elilovar in tools) to set/read/delete the EliloAlt EFI variable used to specify an alternate kernel to boot. diff --git a/Make.defaults b/Make.defaults index 523f0fc..0a90776 100644 --- a/Make.defaults +++ b/Make.defaults @@ -68,7 +68,7 @@ CPPFLAGS = -DCONFIG_$(ARCH) OPTIMFLAGS = -O2 DEBUGFLAGS = -Wall CFLAGS = $(OPTIMFLAGS) -fpic -fshort-wchar $(DEBUGFLAGS) -LDFLAGS = -nostdlib +LDFLAGS = -nostdlib -znocombreloc INSTALL = install ifeq ($(CONFIG_machspec_netconfig),y) @@ -95,37 +95,23 @@ ifeq ($(CONFIG_chooser_textmenu),y) CFLAGS += -DCONFIG_CHOOSER_TEXTMENU endif +prefix = /usr/bin/ + # Redhat 8.0 ia32 gcc-3.x version is reported to produce working EFI binaries. + # Redhat 9.0 ia32 gcc-3.x version is reported to produce BAD binaries. +CC = $(prefix)gcc +AS = $(prefix)as +LD = $(prefix)ld +AR = $(prefix)ar +RANLIB = $(prefix)ranlib +OBJCOPY = $(prefix)objcopy + ifeq ($(ARCH),ia64) - prefix = - prefix = /opt/gcc3.1/bin/ - CC = $(prefix)gcc - AS = $(prefix)as - LD = $(prefix)ld - LD = ld - AR = $(prefix)ar - RANLIB = $(prefix)ranlib - OBJCOPY = $(prefix)objcopy - -GCC_VERSION=$(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') - -ifneq ($(GCC_VERSION),2) + GCC_VERSION=$(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') + + ifneq ($(GCC_VERSION),2) CFLAGS += -frename-registers -endif -# -# EFI specs allows only lower floating point partition to be used -# -# Redhat 8.0 gcc-3.x version is reported to produce working EFI binaries. -# Redhat 9.0 gcc-3.x version is reported to produce BAD binaries. -# -CFLAGS += -mfixed-range=f32-f127 -else - ifeq ($(ARCH),ia32) - prefix = - CC = $(prefix)gcc3 - AS = $(prefix)as - LD = $(prefix)ld - AR = $(prefix)ar - RANLIB = $(prefix)ranlib - OBJCOPY = $(prefix)objcopy endif + + # EFI specs allows only lower floating point partition to be used + CFLAGS += -mfixed-range=f32-f127 endif diff --git a/Makefile b/Makefile index d8ec67d..5015faf 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,7 @@ endif FILES = elilo.o getopt.o strops.o loader.o \ fileops.o util.o vars.o alloc.o chooser.o \ config.o initrd.o alternate.o bootparams.o \ - fs/fs.o \ + gunzip.o fs/fs.o \ choosers/choosers.o \ devschemes/devschemes.o \ $(ARCH)/sysdeps.o \ diff --git a/TODO b/TODO index d996a16..fb2696a 100644 --- a/TODO +++ b/TODO @@ -14,5 +14,3 @@ Some of the things TO DO: - Convert all filesystems (ext2fs, netfs) to use the FilesystemProtocol interface instead - cleanup x86 loader: use the same structure as IA-64 - - - support for subnetting in the config file when netbooting diff --git a/alloc.c b/alloc.c index 373fbdc..349da9f 100644 --- a/alloc.c +++ b/alloc.c @@ -129,7 +129,7 @@ alloc_pages(UINTN pgcnt, EFI_MEMORY_TYPE type, EFI_ALLOCATE_TYPE where, VOID *ad status = BS->AllocatePages(where, type , pgcnt, &tmp); if (EFI_ERROR(status)) { - ERR_PRT((L"allocator: AllocatePages(%d, %d, %d, 0x%lx) failed (%r)\n", where, type, pgcnt, tmp, status)); + VERB_PRT(1, (L"allocator: AllocatePages(%d, %d, %d, 0x%lx) failed (%r)\n", where, type, pgcnt, tmp, status)); return NULL; } /* XXX: will cause warning on IA-32 */ @@ -155,7 +155,7 @@ free(VOID *addr) if (p->addr == addr) goto found; } /* not found */ - ERR_PRT((L"allocator: invalid free @ 0x%lx\n", addr)); + VERB_PRT(1, (L"allocator: invalid free @ 0x%lx\n", addr)); return; found: DBG_PRT((L"free: %s @0x%lx size=%ld\n", diff --git a/bootparams.c b/bootparams.c index a6c9d7c..8859fcc 100644 --- a/bootparams.c +++ b/bootparams.c @@ -38,7 +38,7 @@ * bp : the address of the bootparams otherwise (opaque type) */ VOID * -create_boot_params(CHAR16 *args, memdesc_t *initrd, UINTN *cookie) +create_boot_params(CHAR16 *args, memdesc_t *initrd, memdesc_t *vmcode, UINTN *cookie) { /* * XXX: need cleanup @@ -69,6 +69,7 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, UINTN *cookie) * Allocate memory for boot parameters. * This CANNOT be EfiLoaderData or EfiLoaderCode as the kernel * frees this region when initializing. + * FIXME: Is this a bug? (since the memory type *is* EfiLoaderData) */ bp = (boot_params_t *)alloc(BOOT_PARAM_MEMSIZE, EfiLoaderData); @@ -95,7 +96,7 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, UINTN *cookie) */ Memset(bp, 0, BOOT_PARAM_MEMSIZE); - if (sysdeps_create_boot_params(bp, cp, initrd, cookie) == -1) return 0; + 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 diff --git a/choosers/simple.c b/choosers/simple.c index 9b0725e..b246a91 100644 --- a/choosers/simple.c +++ b/choosers/simple.c @@ -37,6 +37,7 @@ display_label_info(CHAR16 *name) { CHAR16 *desc; CHAR16 initrd_name[CMDLINE_MAXLEN]; + CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 options_tmp[CMDLINE_MAXLEN]; CHAR16 options[CMDLINE_MAXLEN]; CHAR16 kname[FILENAME_MAXLEN]; @@ -46,9 +47,9 @@ display_label_info(CHAR16 *name) Print(L"desc : %s\n", desc); } - initrd_name[0] = options_tmp[0] = kname[0] = CHAR_NULL; + initrd_name[0] = vmcode_name[0] = options_tmp[0] = kname[0] = CHAR_NULL; - if (find_label(name, kname, options_tmp, initrd_name) == -1) { + if (find_label(name, kname, options_tmp, initrd_name, vmcode_name) == -1) { StrCpy(kname, name); Print(L"\n"); } @@ -56,6 +57,7 @@ display_label_info(CHAR16 *name) Print(L"cmdline: %s %s\n", kname, options); if (initrd_name[0]) Print(L"initrd : %s\n", initrd_name); + if (vmcode_name[0]) Print(L"vmcode : %s\n", vmcode_name); } static VOID @@ -247,6 +249,7 @@ simple_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmdli CHAR16 buffer[CMDLINE_MAXLEN]; CHAR16 alt_buffer[CMDLINE_MAXLEN]; CHAR16 initrd_name[CMDLINE_MAXLEN]; + CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN]; CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN]; @@ -259,7 +262,7 @@ simple_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmdli display_message(); restart: - initrd_name[0] = kname[0] = cmdline[0] = args[0] = CHAR_NULL; + initrd_name[0] = vmcode_name[0] = kname[0] = cmdline[0] = args[0] = CHAR_NULL; /* reset per image loader options */ Memset(&elilo_opt.img_opt, 0, sizeof(elilo_opt.img_opt)); @@ -303,14 +306,14 @@ restart: * if no match is found, the args and initrd arguments may * still be modified by global options in the config file. */ - ret = find_label(argv[index], kname, args, initrd_name); + ret = find_label((index < argc) ? argv[index] : NULL, kname, args, initrd_name, vmcode_name); /* * not found, so assume first argument is kernel name and * not label name */ if (ret == -1) { - if (argv[index]) + if ((index < argc) && argv[index]) StrCpy(kname, argv[index]); else StrCpy(kname, elilo_opt.default_kernel); @@ -335,9 +338,14 @@ restart: StrCpy(elilo_opt.initrd, initrd_name); } + if (elilo_opt.vmcode[0] == CHAR_NULL && vmcode_name[0] != CHAR_NULL) { + StrCpy(elilo_opt.vmcode, vmcode_name); + } + VERB_PRT(1, { Print(L"kernel is '%s'\n", kname); Print(L"arguments are '%s'\n", args); if (elilo_opt.initrd[0]) Print(L"initrd is '%s'\n", elilo_opt.initrd); + if (elilo_opt.vmcode[0]) Print(L"vmm is '%s'\n", elilo_opt.vmcode); }); if (elilo_opt.prompt == 0) { @@ -346,6 +354,7 @@ restart: ret = wait_timeout(elilo_opt.delay); if (ret != 0) { elilo_opt.prompt = 1; + elilo_opt.initrd[0] = CHAR_NULL; elilo_opt.timeout = ELILO_TIMEOUT_INFINITY; goto restart; } @@ -378,7 +387,8 @@ restart: */ len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */ +StrLen(devname) /* device name */ - +StrLen(kname) /* kernel name */ + /* kernel name */ + +elilo_opt.vmcode[0] ? StrLen(elilo_opt.vmcode) : StrLen(kname) +1 /* space */ +StrLen(args); /* args length */ @@ -388,7 +398,10 @@ restart: } StrCpy(cmdline, L"BOOT_IMAGE="); StrCat(cmdline, devname); - StrCat(cmdline, kname); + if (elilo_opt.vmcode[0]) + StrCat(cmdline, elilo_opt.vmcode); + else + StrCat(cmdline, kname); StrCat(cmdline, L" "); StrCat(cmdline, args); diff --git a/choosers/textmenu.c b/choosers/textmenu.c index 9379b0e..3210dda 100644 --- a/choosers/textmenu.c +++ b/choosers/textmenu.c @@ -28,7 +28,7 @@ #include "elilo.h" -#define MAX_LABELS 16 +#define MAX_LABELS 64 #define MSGBUFLEN 4096 static UINT8 msgbuf[MSGBUFLEN]; @@ -358,6 +358,7 @@ textmenu_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmd # define BOOT_IMG_STR L"BOOT_IMAGE=" CHAR16 label[CMDLINE_MAXLEN]; CHAR16 initrd_name[CMDLINE_MAXLEN]; + CHAR16 vmcode_name[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN]; CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN]; @@ -382,7 +383,7 @@ textmenu_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmd nlabels++; } restart: - initrd_name[0] = kname[0] = cmdline[0] = args[0] = CHAR_NULL; + vmcode_name[0] = initrd_name[0] = kname[0] = cmdline[0] = args[0] = CHAR_NULL; /* reset per image loader options */ Memset(&elilo_opt.img_opt, 0, sizeof(elilo_opt.img_opt)); @@ -400,7 +401,7 @@ restart: if (elilo_opt.alt_check && alternate_kernel(PromptBuf, sizeof(PromptBuf)) == 0) { argc = argify(PromptBuf,sizeof(PromptBuf), argv); index = 0; - label[0] = args[0] = initrd_name[0] = 0; + label[0] = args[0] = initrd_name[0] = vmcode_name[0] = 0; } /* @@ -412,16 +413,16 @@ restart: * still be modified by global options in the config file. */ if (label[0]) - ret = find_label(label, kname, args, initrd_name); + ret = find_label(label, kname, args, initrd_name, vmcode_name); else - ret = find_label(argv[index], kname, args, initrd_name); + ret = find_label((index < argc) ? argv[index] : NULL, kname, args, initrd_name, vmcode_name); /* * not found, so assume first argument is kernel name and * not label name */ if (ret == -1) { - if (argv[index]) + if ((index < argc) && argv[index]) StrCpy(kname, argv[index]); else StrCpy(kname, elilo_opt.default_kernel); @@ -448,9 +449,14 @@ restart: StrCpy(elilo_opt.initrd, initrd_name); } + if (elilo_opt.vmcode[0] == CHAR_NULL && vmcode_name[0] != CHAR_NULL) { + StrCpy(elilo_opt.vmcode, vmcode_name); + } + VERB_PRT(1, { Print(L"kernel is '%s'\n", kname); Print(L"arguments are '%s'\n", args); if (elilo_opt.initrd[0]) Print(L"initrd is '%s'\n", elilo_opt.initrd); + if (elilo_opt.vmcode[0]) Print(L"vmm is '%s'\n", elilo_opt.vmcode); }); if (elilo_opt.prompt == 0) { @@ -459,6 +465,7 @@ restart: ret = wait_timeout(elilo_opt.delay); if (ret != 0) { elilo_opt.prompt = 1; + elilo_opt.initrd[0] = CHAR_NULL; elilo_opt.timeout = ELILO_TIMEOUT_INFINITY; goto restart; } @@ -493,6 +500,7 @@ restart: len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */ +StrLen(devname) /* device name */ +StrLen(kname) /* kernel name */ + +elilo_opt.vmcode[0] ? StrLen(elilo_opt.vmcode) : StrLen(kname) +1 /* space */ +StrLen(args); /* args length */ @@ -504,7 +512,10 @@ restart: } StrCpy(cmdline, L"BOOT_IMAGE="); StrCat(cmdline, devname); - StrCat(cmdline, kname); + if (elilo_opt.vmcode[0]) + StrCat(cmdline, elilo_opt.vmcode); + else + StrCat(cmdline, kname); StrCat(cmdline, L" "); StrCat(cmdline, args); diff --git a/config.c b/config.c index ac789b9..e24c0c0 100644 --- a/config.c +++ b/config.c @@ -68,6 +68,7 @@ typedef struct boot_image { CHAR16 kname[FILENAME_MAXLEN]; CHAR16 options[MAX_STRING]; CHAR16 initrd[FILENAME_MAXLEN]; + CHAR16 vmcode[FILENAME_MAXLEN]; CHAR16 root[FILENAME_MAXLEN]; CHAR16 fallback[MAX_STRING]; CHAR16 description[MAX_STRING]; @@ -93,6 +94,7 @@ typedef enum { 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 default_image_name[MAX_STRING]; CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN]; @@ -144,6 +146,7 @@ static config_option_t global_common_options[]={ {OPT_BOOL, OPT_GLOBAL, L"noedd30", NULL, NULL, &global_config.edd30_no_force}, {OPT_CMD, OPT_GLOBAL, L"append", NULL, NULL, global_config.options}, {OPT_FILE, OPT_GLOBAL, L"initrd", NULL, NULL, global_config.initrd}, +{OPT_FILE, OPT_GLOBAL, L"vmm", NULL, NULL, global_config.vmcode}, {OPT_FILE, OPT_GLOBAL, L"image", do_image, NULL, opt_offsetof(kname)}, {OPT_BOOL, OPT_GLOBAL, L"checkalt", NULL, NULL, &global_config.alt_check}, {OPT_STR, OPT_GLOBAL, L"chooser", NULL, check_chooser, global_config.chooser}, @@ -168,6 +171,7 @@ static config_option_t image_common_options[]={ {OPT_CMD, OPT_IMAGE, L"append", do_options, NULL, opt_offsetof(options)}, {OPT_CMD, OPT_IMAGE, L"literal", do_literal, NULL, NULL}, {OPT_FILE, OPT_IMAGE, L"initrd", NULL, NULL, opt_offsetof(initrd)}, + {OPT_FILE, OPT_IMAGE, L"vmm", NULL, NULL, opt_offsetof(vmcode)}, {OPT_STR, OPT_IMAGE, L"label", NULL, NULL, opt_offsetof(label)}, {OPT_FILE, OPT_IMAGE, L"image", do_image, NULL, opt_offsetof(kname)}, {OPT_STR, OPT_IMAGE, L"description", NULL, NULL, opt_offsetof(description)}, @@ -843,7 +847,7 @@ get_config_file(VOID) } EFI_STATUS -read_config(CHAR16 *filename, INTN retry) +read_config(CHAR16 *filename) { EFI_STATUS status; INTN ret; @@ -856,49 +860,8 @@ read_config(CHAR16 *filename, INTN retry) status = fops_open(filename, &config_fd); if (EFI_ERROR(status)) { - /* - * if the user explicitely specified a filename and we can't - * find it, then we must fail. - */ - if (elilo_opt.parse_only || retry == 0) { - VERB_PRT(3, Print(L"cannot open config file %s\n", filename)); - return status; - } - /* - * if not already submitted filename, - */ - if (StrCmp(filename, ELILO_ARCH_DEFAULT_CONFIG)) { - /* - * try the arch default file, now - */ - VERB_PRT(3,Print(L"config file %s not found, trying %s\n", - filename, ELILO_ARCH_DEFAULT_CONFIG)); - - StrCpy(global_config.config_file,ELILO_ARCH_DEFAULT_CONFIG); - - status = fops_open(ELILO_ARCH_DEFAULT_CONFIG, &config_fd); - } - /* - * if arch specific did not work, try generic - */ - if (EFI_ERROR(status) && StrCmp(filename, ELILO_DEFAULT_CONFIG)) { - /* - * try the default file as a last resort - */ - VERB_PRT(3,Print(L"config file %s not found, trying %s\n", - ELILO_ARCH_DEFAULT_CONFIG, ELILO_DEFAULT_CONFIG)); - - StrCpy(global_config.config_file, ELILO_DEFAULT_CONFIG); - status = fops_open(ELILO_DEFAULT_CONFIG, &config_fd); - } - /* - * if nothing worked, then bail out - */ - if (EFI_ERROR(status)) { - VERB_PRT(3, Print(L"no valid config file found\n")); - global_config.config_file[0] = CHAR_NULL; - return status; - } + VERB_PRT(3, Print(L"cannot open config file %s\n", filename)); + return status; } /* * start numbering at line 1 @@ -923,10 +886,10 @@ print_label_list(VOID) { boot_image_t *img, *dfl = global_config.default_image; - if (dfl) Print(L"%s ", dfl->label); + if (dfl) Print(L"\t%s\n", dfl->label); for (img = image_list; img; img = img->next) { - if (img != dfl) Print(L"%s ", img->label); + if (img != dfl) Print(L"\t%s\n", img->label); } } @@ -974,7 +937,7 @@ find_description(CHAR16 *label) } INTN -find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd) +find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 *vmcode) { boot_image_t *img; @@ -1007,6 +970,7 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd) if (global_config.readonly) StrCat(options, L" ro"); if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd); + if (global_config.vmcode[0]) StrCpy(vmcode, global_config.vmcode); /* make sure we don't get garbage here */ elilo_opt.sys_img_opts = NULL; @@ -1044,12 +1008,17 @@ found: else if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd); + if (img->vmcode[0]) + StrCpy(vmcode, img->vmcode); + else if (global_config.vmcode[0]) + StrCpy(vmcode, global_config.vmcode); + /* * point to architecture dependent options for this image */ elilo_opt.sys_img_opts = &img->sys_img_opts; - DBG_PRT((L"label %s: kname=%s options=%s initrd=%s", img->label, kname, options, initrd)); + DBG_PRT((L"label %s: kname=%s options=%s initrd=%s vmcode=%s", img->label, kname, options, initrd, vmcode)); return 0; } diff --git a/docs/netbooting.txt b/docs/netbooting.txt index 2f51740..130cc11 100644 --- a/docs/netbooting.txt +++ b/docs/netbooting.txt @@ -126,7 +126,21 @@ only on two very common cases: This filename is an opportunity to specify a machine specific configuration file. - 2) elilo-ia32.config or elilo-ia64.conf + 2) AA[BB[CC]][-ia32|ia64].conf + As of version 3.5, elilo will also look for IPv4 class A,B,C + subnet-specific versions of the config file. This is useful when you + want to have a common config file for all machines connected to a + particular subnet. + + For example, if your IP address is 10.0.0.1 (0A000001 in hex), elilo + will look first for 0A000001.conf, then 0A0000.conf, then 0A00.conf, + and finally 0A.conf. + + Elilo will also try architecture-specific versions of subnet-specific + config files first (So for example, on an Itanium system, + "0A0000-ia64.conf" will be tried before "0A0000.conf") + + 3) elilo-ia32.config or elilo-ia64.conf Depending on the machine (client side) architecture elilo will try the IA-32 or IA-64 file. @@ -135,7 +149,7 @@ only on two very common cases: This distinction between the architectures is useful when the same TFTP server services the two types of clients : IA32- and IA-64 machines. - 3) elilo.conf + 4) elilo.conf All files use the same format. Elilo will stop at the first match. In case no file is found, it will try to download a default kernel file name (vmlinux). diff --git a/elilo-ia32.efi b/elilo-ia32.efi deleted file mode 100755 index 3f8cd331af2ca272f7050217890bfe804ea00b9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 159859 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 bg9qZMnj3hMgl`C{;3DFosFS4m5rzK`0Rz9U diff --git a/elilo.c b/elilo.c index 0959c71..6bdd6bd 100644 --- a/elilo.c +++ b/elilo.c @@ -34,6 +34,7 @@ #include "elilo.h" #include "vars.h" +#include "gzip.h" #include "getopt.h" #include "fileops.h" @@ -84,13 +85,23 @@ do_kernel_load(CHAR16 *kname, kdesc_t *kd) } INTN -kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem) +kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memdesc_t *mmem) { + CHAR16 kernel[CMDLINE_MAXLEN]; + /* + * Do the vm image switch here + * if there is "vmm=" then elilo should load image specified + * in "vmm=" and then give the "image" to vmm as target kernel image + */ + if (elilo_opt.vmcode[0]) + StrCpy(kernel, elilo_opt.vmcode); + else + StrCpy(kernel, kname); /* * Now let's try to load the kernel ! */ - switch(do_kernel_load(kname, kd)) { + switch(do_kernel_load(kernel, kd)) { case ELILO_LOAD_SUCCESS: break; @@ -101,6 +112,7 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem) case ELILO_LOAD_ABORTED: /* we drop initrd in case we aborted the load */ elilo_opt.initrd[0] = CHAR_NULL; + elilo_opt.vmcode[0] = CHAR_NULL; /* will go back to interactive selection */ elilo_opt.prompt = 1; @@ -111,33 +123,75 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem) } VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n", - (UINT64)kd->kstart, (UINT64)kd->kend, (UINT64)kd->kentry)); + (unsigned long)kd->kstart, (unsigned long)kd->kend, (unsigned long)kd->kentry)); if (elilo_opt.initrd[0]) { if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error; - switch(load_initrd(elilo_opt.initrd, imem)) { + switch(load_file(elilo_opt.initrd, imem)) { case ELILO_LOAD_SUCCESS: break; case ELILO_LOAD_ERROR: goto exit_error; case ELILO_LOAD_ABORTED: - /* the free_kmem() is the responsibility of the loader */ + free_kmem(); + /* we drop initrd in case we aborted the load */ + elilo_opt.initrd[0] = CHAR_NULL; + elilo_opt.vmcode[0] = CHAR_NULL; + elilo_opt.prompt = 1; + elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT; + elilo_opt.delay = 0; + + return ELILO_LOAD_RETRY; + } + } + + if (elilo_opt.vmcode[0]) { + mmem->start_addr = 0; /* let the allocator decide */ + + switch(load_file(kname, mmem)) { + case ELILO_LOAD_SUCCESS: + break; + case ELILO_LOAD_ERROR: + goto exit_error; + case ELILO_LOAD_ABORTED: + if (imem->start_addr) + free(imem->start_addr); + free_kmem(); /* we drop initrd in case we aborted the load */ elilo_opt.initrd[0] = CHAR_NULL; + elilo_opt.vmcode[0] = CHAR_NULL; elilo_opt.prompt = 1; elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT; elilo_opt.delay = 0; return ELILO_LOAD_RETRY; } + + /* Test for a compressed image and unzip if found */ + if (gzip_probe(mmem->start_addr, mmem->size) == 0 && + gunzip_image(mmem) != ELILO_LOAD_SUCCESS) { + if (imem->start_addr) + free(imem->start_addr); + free(mmem->start_addr); + free_kmem(); + /* we drop initrd in case we aborted the load */ + elilo_opt.initrd[0] = CHAR_NULL; + elilo_opt.vmcode[0] = CHAR_NULL; + elilo_opt.prompt = 1; + elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT; + elilo_opt.delay = 0; + + return ELILO_LOAD_RETRY; + } } return ELILO_LOAD_SUCCESS; exit_error: free_kmem(); if (imem->start_addr) free(imem->start_addr); + if (mmem->start_addr) free(mmem->start_addr); return ELILO_LOAD_ERROR; } @@ -152,7 +206,7 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image UINTN cookie; EFI_STATUS status = EFI_SUCCESS; kdesc_t kd; - memdesc_t imem; + memdesc_t imem, mmem; INTN r; /* @@ -164,12 +218,12 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image for(;;) { kname[0] = cmdline_tmp[0] = cmdline[0] = CHAR_NULL; - imem.start_addr = 0; imem.pgcnt = 0; + imem.start_addr = 0; imem.pgcnt = 0; imem.size = 0; elilo_opt.sys_img_opts = NULL; if (kernel_chooser(argv, argc, index, kname, cmdline_tmp) == -1) goto exit_error; - switch (kernel_load(image, kname, &kd, &imem)) { + switch (kernel_load(image, kname, &kd, &imem, &mmem)) { case ELILO_LOAD_SUCCESS: goto do_launch; case ELILO_LOAD_ERROR: @@ -187,7 +241,7 @@ do_launch: close_devices(); /* No console output permitted after create_boot_params()! */ - if ((bp=create_boot_params(cmdline, &imem, &cookie)) == 0) goto error; + if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error; /* terminate bootservices */ status = BS->ExitBootServices(image, cookie); @@ -221,6 +275,7 @@ elilo_help(VOID) Print(L"-v verbose level(can appear multiple times)\n"); Print(L"-a always check for alternate kernel image\n"); Print(L"-i file load file as the initial ramdisk\n"); + Print(L"-m file load file as additional boot time vmm module\n"); Print(L"-C file indicate the config file to use\n"); Print(L"-P parse config file only (verify syntax)\n"); Print(L"-D enable debug prints\n"); @@ -368,8 +423,8 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) CHAR16 dpath[FILENAME_MAXLEN]; CHAR16 *devpath; - //elilo_opt.verbose=3; - //elilo_opt.debug=1; + elilo_opt.verbose=0; + elilo_opt.debug=0; /* initialize global variable */ systab = system_tab; @@ -491,6 +546,13 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) } StrCpy(elilo_opt.initrd, Optarg); break; + case 'm': + if (StrLen(Optarg) >= FILENAME_MAXLEN-1) { + Print(L"vmm module filename is limited to %d characters\n", FILENAME_MAXLEN); + goto do_exit; + } + StrCpy(elilo_opt.vmcode, Optarg); + break; case 'C': if (StrLen(Optarg) >= FILENAME_MAXLEN-1) { Print(L"config filename is limited to %d characters\n", FILENAME_MAXLEN); @@ -548,23 +610,37 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) /* * set per fileops defaults files for configuration and kernel */ - fops_setdefaults(elilo_opt.default_config, elilo_opt.default_kernel, FILENAME_MAXLEN, devpath); + fops_setdefaults(elilo_opt.default_configs, elilo_opt.default_kernel, FILENAME_MAXLEN, devpath); /* * XXX: won't be visible if verbose not required from command line */ VERB_PRT(2,Print(L"Default config: %s\nDefault_kernel: %s\n", - elilo_opt.default_config,elilo_opt.default_kernel)); + elilo_opt.default_configs[0].fname, elilo_opt.default_kernel)); /* * use default config file if not specified by user */ - ptr = elilo_opt.config[0] == CHAR_NULL ? (retry=1,elilo_opt.default_config) : (retry=0,elilo_opt.config); + ptr = elilo_opt.config[0] == CHAR_NULL ? (retry=1,elilo_opt.default_configs[0].fname) : (retry=0,elilo_opt.config); /* * parse config file (verbose becomes visible if set) */ - ret = read_config(ptr, retry); - Print(L"read_config=%r\n", ret); + ret = read_config(ptr); + VERB_PRT(1,Print(L"read_config=%r\n", ret)); + + /* Only try the default config filenames if user did not specify a + * config filename on the command line */ + if (elilo_opt.config[0] == CHAR_NULL) { + while ((ret != EFI_SUCCESS) && + (retry < MAX_DEFAULT_CONFIGS) && + (elilo_opt.default_configs[retry].fname[0] != CHAR_NULL)) { + + ptr = elilo_opt.default_configs[retry].fname; + ret = read_config(ptr); + VERB_PRT(1,Print(L"read_config=%r\n", ret)); + retry += 1; + } + } /* * when the config file is not found, we fail only if: * - the user did not specified interactive mode @@ -593,11 +669,19 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) * if there was an error when parsing the config file, then * we force interactive mode to give a chance to the user. * We also clear the error. - */ - if (ret && argc == 1) { - Print(L"forcing interactive mode because of errors\n"); + */ + if (ret != EFI_SUCCESS) { + Print(L"forcing interactive mode due to config file error(s)\n"); elilo_opt.prompt = 1; } + /* + * However, if the user specified a kernel on the command line + * then we don't go to interactive mode, even if there was an option in + * the config file telling us to do so. + */ + if (argc > Optind) { + elilo_opt.prompt = 0; + } /* * If EDD30 EFI variable was not set to TRUE (or not defined), we @@ -613,13 +697,6 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) ret = EFI_LOAD_ERROR; - /* - * if the user specified a kernel on the command line - * then we don't go to interactive mode even if it - * was set in the config file or set because of an - * error parsing the config file. - */ - if (argc > Optind) elilo_opt.prompt = 0; /* set default timeout if going interactive */ diff --git a/elilo.h b/elilo.h index 9d28617..74f740d 100644 --- a/elilo.h +++ b/elilo.h @@ -60,11 +60,17 @@ #define CMDLINE_MAXLEN 512 /* needed by ia32 */ #define FILENAME_MAXLEN 256 #define MAX_ARGS 256 +/* Just pick an arbitrary number that's high enough for now :o) */ +#define MAX_DEFAULT_CONFIGS 16 typedef struct { UINT8 nothing_yet; } image_opt_t; +typedef struct config_file { + CHAR16 fname[FILENAME_MAXLEN]; +} config_file_t; + typedef struct { /* * list of options controllable from both the command line @@ -75,6 +81,7 @@ typedef struct { UINTN delay; /* delay before booting the image */ UINTN verbose; /* verbosity level [1-5] */ CHAR16 initrd[FILENAME_MAXLEN]; /* name of file for initial ramdisk */ + CHAR16 vmcode[FILENAME_MAXLEN]; /* name of file for boot time module*/ UINT8 delay_set; /* mark whether or not delay was specified on cmdline */ UINT8 edd30_on; /* true is EDD30 variable is TRUE */ UINT8 edd30_no_force; /* don't force EDD30 variable to true */ @@ -91,7 +98,8 @@ typedef struct { sys_img_options_t *sys_img_opts; /* architecture depdendent per image options */ CHAR16 default_kernel[FILENAME_MAXLEN]; - CHAR16 default_config[FILENAME_MAXLEN]; + /* CHAR16 default_config[FILENAME_MAXLEN]; */ + config_file_t default_configs[MAX_DEFAULT_CONFIGS]; CHAR16 config[FILENAME_MAXLEN]; /* name of config file */ CHAR16 chooser[FILENAME_MAXLEN]; /* image chooser to use */ @@ -105,6 +113,7 @@ extern EFI_SYSTEM_TABLE *systab; typedef struct { VOID *start_addr; UINTN pgcnt; + UINTN size; } memdesc_t; typedef struct { @@ -160,9 +169,9 @@ extern VOID ascii2U(CHAR8 *, CHAR16 *, UINTN); extern VOID U2ascii(CHAR16 *, CHAR8 *, UINTN); /* from config.c (more in config.h) */ -extern EFI_STATUS read_config(CHAR16 *, INTN retry); +extern EFI_STATUS read_config(CHAR16 *); extern VOID print_config_options(VOID); -extern INTN find_label(CHAR16 *, CHAR16 *, CHAR16 *, CHAR16 *); +extern INTN find_label(CHAR16 *, CHAR16 *, CHAR16 *, CHAR16 *, CHAR16 *); extern VOID print_label_list(VOID); extern INTN config_init(VOID); extern CHAR16 *get_message_filename(INTN which); @@ -171,13 +180,13 @@ extern VOID *get_next_description(VOID *prev, CHAR16 **label, CHAR16 **descripti extern CHAR16 *get_config_file(VOID); /* from initrd.c */ -extern INTN load_initrd(CHAR16 *, memdesc_t *); +extern INTN load_file(CHAR16 *, memdesc_t *); /* from alternate.c */ extern INTN alternate_kernel(CHAR16 *, INTN); /* from bootparams.c */ -extern VOID *create_boot_params (CHAR16 *, memdesc_t *, UINTN *); +extern VOID *create_boot_params (CHAR16 *, memdesc_t *, memdesc_t *, UINTN *); extern VOID free_boot_params(VOID *bp); /* @@ -185,7 +194,7 @@ extern VOID free_boot_params(VOID *bp); */ -extern INTN sysdeps_create_boot_params(boot_params_t *, CHAR8 *, memdesc_t *, UINTN *); +extern INTN sysdeps_create_boot_params(boot_params_t *, CHAR8 *, memdesc_t *, memdesc_t *, UINTN *); extern VOID sysdeps_free_boot_params(boot_params_t *); extern INTN sysdeps_init(EFI_HANDLE dev); extern INTN sysdeps_initrd_get_addr(kdesc_t *, memdesc_t *); diff --git a/fileops.c b/fileops.c index 674fc5c..85f3485 100644 --- a/fileops.c +++ b/fileops.c @@ -345,12 +345,37 @@ fops_seek(fops_fd_t fd, UINT64 newpos) } EFI_STATUS -fops_setdefaults(CHAR16 *config, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath) +fops_setdefaults(struct config_file *defconf, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath) { + INTN i; + +/* + * The first default config file is architecture dependent. This is useful + * in case of network booting where the server is used for both types of + * architectures. + */ +#if defined(CONFIG_ia64) +#define FILEOPS_ARCH_DEFAULT_CONFIG L"elilo-ia64.conf" +#elif defined (CONFIG_ia32) +#define FILEOPS_ARCH_DEFAULT_CONFIG L"elilo-ia32.conf" +#else +#error "You need to specfy your default arch config file" +#endif + +/* + * last resort config file. Common to all architectures + */ +#define FILEOPS_DEFAULT_CONFIG L"elilo.conf" + #define FILEOPS_DEFAULT_KERNEL L"vmlinux" -#define FILEOPS_DEFAULT_CONFIG L"elilo.conf" - if (config == NULL || kname == NULL) return EFI_INVALID_PARAMETER; +#ifdef ELILO_DEBUG + if (defconf == NULL || kname == NULL) return EFI_INVALID_PARAMETER; +#endif + + for (i=0; ifops == NULL) { if (boot_dev == NULL) @@ -360,13 +385,30 @@ fops_setdefaults(CHAR16 *config, CHAR16 *kname, UINTN maxlen, CHAR16 *devpath) Print(L"Using builtin defaults for kernel and config file\n"); - StrnCpy(config, FILEOPS_DEFAULT_CONFIG, maxlen-1); StrnCpy(kname, FILEOPS_DEFAULT_KERNEL, maxlen-1); - - return EFI_UNSUPPORTED; } - - return boot_dev->fops->setdefaults(boot_dev->fops->intf, config, kname, maxlen, devpath); + else { + boot_dev->fops->setdefaults(boot_dev->fops->intf, defconf, kname, maxlen, devpath); + } + i=0; while (i= MAX_DEFAULT_CONFIGS) { + Print(L"ERROR: i = %d, MAX_DEFAULT_CONFIGS is not large enough\n", i); + return EFI_INVALID_PARAMETER; + } +#endif + StrnCpy(defconf[i].fname, FILEOPS_ARCH_DEFAULT_CONFIG, maxlen-1); + StrnCpy(defconf[i+1].fname, FILEOPS_DEFAULT_CONFIG, maxlen-1); + +#ifdef ELILO_DEBUG + VERB_PRT(3,Print(L"Default config filename list:\n")); + for (i=0; inetfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config); + status = netfs->netfs_query_layer(netfs, 0, NETFS_CONFIG_LAYER, maxlen, config[0].fname); if (EFI_ERROR(status)) { - StrnCpy(config, NETFS_DEFAULT_CONFIG, maxlen-1); - config[maxlen-1] = CHAR_NULL; + StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1); + config[0].fname[maxlen-1] = CHAR_NULL; } status = netfs->netfs_query_layer(netfs, 0, NETFS_KERNEL_LAYER, maxlen, kname); @@ -162,21 +162,44 @@ netfs_setdefaults(VOID *intf, CHAR16 *config, CHAR16 *kname, UINTN maxlen, CHAR1 } } else { #ifdef ENABLE_MACHINE_SPECIFIC_NETCONFIG + +# if defined(CONFIG_ia64) +# define CONFIG_ARCH_EXTENSION L"-ia64.conf\0" +# elif defined (CONFIG_ia32) +# define CONFIG_ARCH_EXTENSION L"-ia64.conf\0" +# else +# error "You need to specfy your default arch config file" +# endif + +# define CONFIG_EXTENSION L".conf\0" /* - * will try a machine specific file first. - * the file is constructed based on the IP(v4) address + * will try machine/subnet specific files first. + * the filenames are constructed based on the IP(v4) address */ - convert_ip2hex(ipaddr, m, config); - - config[8] = L'.'; - config[9] = L'c'; - config[10] = L'o'; - config[11] = L'n'; - config[12] = L'f'; - config[13] = CHAR_NULL; + convert_ip2hex(ipaddr, m, str); + 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, 11); + + 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, 11); + + 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, 11); + + StrnCpy(config[6].fname, str, maxlen-1); + StrnCpy(config[6].fname+2, CONFIG_EXTENSION, 6); #else - StrnCpy(config, NETFS_DEFAULT_CONFIG, maxlen-1); - config[maxlen-1] = CHAR_NULL; + StrnCpy(config[0].fname, NETFS_DEFAULT_CONFIG, maxlen-1); + config[0].fname[maxlen-1] = CHAR_NULL; #endif StrnCpy(kname, NETFS_DEFAULT_KERNEL, maxlen-1); kname[maxlen-1] = CHAR_NULL; diff --git a/gnu-efi-3.0a-ia32.patch b/gnu-efi-3.0a-ia32.patch deleted file mode 100644 index 6e3baf1..0000000 --- a/gnu-efi-3.0a-ia32.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff -urN gnu-efi-3.0a/gnuefi/elf_ia32_efi.lds gnu-efi-3.0a-ia32/gnuefi/elf_ia32_efi.lds ---- gnu-efi-3.0a/gnuefi/elf_ia32_efi.lds 2002-02-22 15:43:28.000000000 -0800 -+++ gnu-efi-3.0a-ia32/gnuefi/elf_ia32_efi.lds 2003-08-21 13:36:51.000000000 -0700 -@@ -17,6 +17,7 @@ - *(.rodata*) - *(.data) - *(.data1) -+ *(.data.*) - *(.sdata) - *(.got.plt) - *(.got) -@@ -34,6 +35,7 @@ - .rel : - { - *(.rel.data) -+ *(.rel.data.*) - *(.rel.got) - *(.rel.stab) - } diff --git a/gunzip.c b/gunzip.c new file mode 100644 index 0000000..18fb11f --- /dev/null +++ b/gunzip.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2005 Hewlett-Packard Development Company, L.P. + * Contributed by Alex Williamson + * + * Copyright (C) 2001-2003 Hewlett-Packard Co. + * Contributed by Stephane Eranian + * + * Copyright (C) 2001 Silicon Graphics, Inc. + * Contributed by Brent Casavant + * + * This file is part of the ELILO, the EFI Linux boot loader. + * + * ELILO is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ELILO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ELILO; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Please check out the elilo.txt for complete documentation on how + * to use this program. + */ + +#include +#include + +#include "elilo.h" + +#include "gzip.h" + +#define LD_NAME L"gunzip" + +#define memzero(s, n) Memset((VOID *)(s), 0, (n)) +#define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(n)) + +/* size of output buffer */ +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ +/* + * gzip declarations + */ +#define OF(args) args +#define FUNC_STATIC static + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +/* + * static parameters to gzip helper functions + * we cannot use paramters because API was not + * designed that way + */ +static uch *inbuf; /* input buffer (compressed data) */ +static uch *window; /* output buffer (uncompressed data) */ + +static VOID *outbuf; +unsigned char *outptr; +static unsigned long outsize; + +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +#define get_byte() inbuf[inptr++] + +/* Diagnostic functions */ +#ifdef INFLATE_DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +int stderr; +# define Trace(x) Print(L"line %d:\n", __LINE__); +# define Tracev(x) {if (verbose) Print(L"line %d:\n", __LINE__) ;} +# define Tracevv(x) {if (verbose>1) Print(L"line %d:\n", __LINE__) ;} +# define Tracec(c,x) {if (verbose && (c)) Print(L"line %d:\n", __LINE__) ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) Print(L"line %d:\n", __LINE__) ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static void flush_window(void); +static void error(char *m); +static long bytes_out; + +static void error(char *m); + +#define gzip_malloc(size) (void *)alloc(size, 0) +#define gzip_free(where) free(where) + +#include "inflate.c" + +/* + * Run a set of bytes through the crc shift register. If s is a NULL + * pointer, then initialize the crc shift register contents instead. + * Return the current crc in either case. + * + * Input: + * S pointer to bytes to pump through. + * N number of bytes in S[]. + */ +static void +updcrc(unsigned char *s, unsigned n) +{ + register unsigned long c; + /* crc is defined in inflate.c */ + + c = crc; + while (n--) { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } + crc = c; + return; +} + +/* + * Clear input and output buffers + */ +static void +clear_bufs(void) +{ + outcnt = 0; + inptr = 0; +} + +/* + * Write the output window window[0..outcnt-1] holding uncompressed + * data and update crc. + */ +void +flush_window(void) +{ + /* + * We'll end up relying on the CRC check and size check failing + * if there's actually more data than we expect. + */ + if (!outcnt || bytes_out + outcnt > outsize) + return; + + updcrc(window, outcnt); + + Memcpy(outptr, window, outcnt); + outptr += outcnt; + bytes_out += outcnt; + + outcnt = 0; +} + +static void +error(char *x) +{ + ERR_PRT((L"%s : %a", LD_NAME, x)); + /* will eventually exit with error from gunzip() */ +} + +static INT32 +decompress(VOID) +{ + INT32 ret; + + clear_bufs(); + makecrc(); + Print(L"Uncompressing... "); + ret = gunzip(); + if (ret == 0) Print(L"done\n"); + return ret == 0 ? 0 : -1; +} + +int +gunzip_image(memdesc_t *image) +{ + UINTN pgcnt; + + inbuf = image->start_addr; + + /* + * Last 4 bytes of gzip'd image indicates the uncompressed size + */ + outsize = inbuf[image->size - 1] << 24 | inbuf[image->size - 2] << 16 | + inbuf[image->size - 3] << 8 | inbuf[image->size - 4]; + + pgcnt = EFI_SIZE_TO_PAGES(outsize); + + outbuf = alloc_pages(pgcnt, EfiLoaderData, AllocateAnyPages, 0); + if (outbuf == NULL) { + ERR_PRT((L"%s : allocate output buffer failed\n", LD_NAME)); + return -1; + } + outptr = outbuf; + + window = (void *)alloc(WSIZE, 0); + if (window == NULL) { + ERR_PRT((L"%s : allocate output window failed\n", LD_NAME)); + free(outbuf); + return -1; + } + + bytes_out = 0; + + if (decompress() != 0) { + free(window); + free(outbuf); + return ELILO_LOAD_ERROR; + } + + free(window); + free(image->start_addr); + + image->start_addr = outbuf; + image->size = outsize; + image->pgcnt = pgcnt; + + return ELILO_LOAD_SUCCESS; +} diff --git a/ia64/gzip.h b/gzip.h similarity index 50% rename from ia64/gzip.h rename to gzip.h index 69749df..88b53f6 100644 --- a/ia64/gzip.h +++ b/gzip.h @@ -26,10 +26,42 @@ #ifndef __GZIP_H__ #define __GZIP_H__ - -int gzip_probe(unsigned char *, unsigned long); +int gunzip_image(memdesc_t *); int gunzip_kernel(fops_fd_t, kdesc_t *); -#define LD_NAME L"gzip_ia64" +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +/* + * check for valid gzip signature + * return: + * 0 : valid gzip archive + * -1: invalid gzip archive + */ +static inline int +gzip_probe(unsigned char *buf, unsigned long size) +{ + if (size < 4) return -1; + + if (buf[0] != 037 || + ((buf[1] != 0213) && (buf[1] != 0236))) return -1; + + /* We only support method #8, DEFLATED */ + if (buf[2] != 8) return -1; + + if ((buf[3] & ENCRYPTED) != 0) return -1; + + if ((buf[3] & CONTINUATION) != 0) return -1; + + if ((buf[3] & RESERVED) != 0) return -1; + + return 0; +} #endif /* __GZIP_H__ */ diff --git a/ia32/Makefile b/ia32/Makefile index 1b1c16c..353ae67 100644 --- a/ia32/Makefile +++ b/ia32/Makefile @@ -28,7 +28,7 @@ include ../Make.rules TOPDIR=$(CDIR)/.. -FILES=system.o config.o +FILES=system.o config.o bzimage.o plain_loader.o gzip_loader.o gzip.o TARGET=sysdeps.o diff --git a/ia32/bzimage.c b/ia32/bzimage.c new file mode 100644 index 0000000..aac1d37 --- /dev/null +++ b/ia32/bzimage.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2001-2003 Hewlett-Packard Co. + * Contributed by Stephane Eranian + * Contributed by Mike Johnston + * Contributed by Chris Ahna + * + * This file is part of the ELILO, the EFI Linux boot loader. + * + * ELILO is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ELILO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ELILO; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Please check out the elilo.txt for complete documentation on how + * to use this program. + */ + +#include +#include + +#include "elilo.h" +#include "loader.h" + +boot_params_t *param_start = NULL; +UINTN param_size = 0; + +UINTN kernel_size = 0x200000; /* 2M (largest x86 bzImage kernel image) */ + +static INTN +bzImage_probe(CHAR16 *kname) +{ + EFI_STATUS efi_status; + UINTN size; + fops_fd_t fd; + UINT8 bootsect[512]; + + DBG_PRT((L"probe_bzImage_boot()\n")); + + if (!kname) { + ERR_PRT((L"kname == %xh", kname)); + free_kmem(); + return -1; + } + + /* + * Open kernel image. + */ + DBG_PRT((L"opening %s...\n", kname)); + + efi_status = fops_open(kname, &fd); + if (EFI_ERROR(efi_status)) { + ERR_PRT((L"Could not open %s.", kname)); + free_kmem(); + return -1; + } + /* + * Read boot sector. + */ + + DBG_PRT((L"\nreading boot sector...\n")); + + size = sizeof bootsect; + efi_status = fops_read(fd, bootsect, &size); + if (EFI_ERROR(efi_status) || size != sizeof bootsect) { + ERR_PRT((L"Could not read boot sector from %s.", kname)); + fops_close(fd); + free_kmem(); + return -1; + } + /* + * Verify boot sector signature. + */ + + if (bootsect[0x1FE] != 0x55 || bootsect[0x1FF] != 0xAA) { + ERR_PRT((L"%s is not a bzImage kernel image.\n", kname)); + fops_close(fd); + free_kmem(); + return -1; + } + /* + * Check for out of range setup data size. + * Will almost always be 7, but we will accept 1 to 64. + */ + + DBG_PRT((L"bootsect[1F1h] == %d setup sectors\n", bootsect[0x1F1])); + + if (bootsect[0x1F1] < 1 || bootsect[0x1F1] > 64) { + ERR_PRT((L"%s is not a valid bzImage kernel image.", + kname)); + fops_close(fd); + free_kmem(); + return -1; + } + /* + * Allocate and read setup data. + */ + + DBG_PRT((L"reading setup data...\n")); + + param_size = (bootsect[0x1F1] + 1) * 512; + param_start = alloc(param_size, EfiLoaderData); + + DBG_PRT((L"param_size=%d param_start=%x", param_size, param_start)); + + if (!param_start) { + ERR_PRT((L"Could not allocate %d bytes of setup data.", + param_size)); + fops_close(fd); + free_kmem(); + return -1; + } + + CopyMem(param_start, bootsect, sizeof bootsect); + + size = param_size - 512; + efi_status = fops_read(fd, ((UINT8 *)param_start) + 512, &size); + + if (EFI_ERROR(efi_status) || size != param_size - 512) { + ERR_PRT((L"Could not read %d bytes of setup data.", + param_size - 512)); + free(param_start); + param_start = NULL; + param_size = 0; + fops_close(fd); + free_kmem(); + return -1; + } + /* + * Check for setup data signature. + */ + + { + UINT8 *c = ((UINT8 *)param_start)+514; + DBG_PRT((L"param_start(c=%x): %c-%c-%c-%c", + c, (CHAR16)c[0],(CHAR16) c[1], (CHAR16)c[2], (CHAR16)c[3])); + } + if (CompareMem(((UINT8 *)param_start) + 514, "HdrS", 4)) { + ERR_PRT((L"%s does not have a setup signature.", + kname)); + free(param_start); + param_start = NULL; + param_size = 0; + fops_close(fd); + free_kmem(); + return -1; + } + /* + * Allocate memory for kernel. + */ + + 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)); + } + /* + * Now read the rest of the kernel image into memory. + */ + + DBG_PRT((L"reading kernel image...\n")); + + size = kernel_size; + efi_status = fops_read(fd, kernel_start, &size); + if (EFI_ERROR(efi_status) || size < 0x10000) { + ERR_PRT((L"Error reading kernel image %s.", kname)); + free(param_start); + param_start = NULL; + param_size = 0; + fops_close(fd); + free_kmem(); + return -1; + } + + DBG_PRT((L"kernel image read: %d bytes, %d Kbytes\n", size, size / 1024)); + + /* + * Boot sector, setup data and kernel image loaded. + */ + + fops_close(fd); + return 0; +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +static INTN +bzImage_load(CHAR16 *kname, kdesc_t *kd) +{ + DBG_PRT((L"load_bzImage_boot()\n")); + + if (!kname || !kd) { + ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd)); + free(param_start); + param_start = NULL; + param_size = 0; + free_kmem(); + return -1; + } + kd->kstart = kd->kentry = kernel_start; + kd->kend = ((UINT8 *)kd->kstart) + kernel_size; + + DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend)); + + return 0; +} + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +loader_ops_t bzimage_loader = { + NULL, + L"bzImage_loader", + &bzImage_probe, + &bzImage_load +}; diff --git a/ia32/gzip.c b/ia32/gzip.c new file mode 100644 index 0000000..fff5f6d --- /dev/null +++ b/ia32/gzip.c @@ -0,0 +1,554 @@ +/* + * Copyright (C) 2001-2002 Hewlett-Packard Co. + * Contributed by Stephane Eranian + * + * Copyright (C) 2001 Silicon Graphics, Inc. + * Contributed by Brent Casavant + * + * This file is part of the ELILO, the EFI Linux boot loader. + * + * ELILO is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ELILO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ELILO; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Please check out the elilo.txt for complete documentation on how + * to use this program. + */ + +#include +#include + +#include "elf.h" +#include "elilo.h" +#include "gzip.h" +#include "private.h" + +#define LD_NAME L"gzip_ia32" + +#define memzero(s, n) Memset((VOID *)(s), 0, (n)) +#define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(n)) + +/* size of output buffer */ +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ +/* size of input buffer */ +#define INBUFSIZE 0x8000 + +/* + * gzip declarations + */ + +#define OF(args) args +#define FUNC_STATIC static + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + + +typedef struct segment { + unsigned long addr; /* start address */ + unsigned long offset; /* file offset */ + unsigned long size; /* file size */ + unsigned long bss_sz; /* BSS size */ + UINT8 flags; /* indicates whether to load or not */ +} segment_t; + +#define CHUNK_FL_VALID 0x1 +#define CHUNK_FL_LOAD 0x2 + +#define CHUNK_CAN_LOAD(n) chunks[(n)].flags |= CHUNK_FL_LOAD +#define CHUNK_NO_LOAD(n) chunks[(n)].flags &= ~CHUNK_FL_LOAD +#define CHUNK_IS_LOAD(n) (chunks[(n)].flags & CHUNK_FL_LOAD) + +#define CHUNK_VALIDATE(n) chunks[(n)].flags |= CHUNK_FL_VALID +#define CHUNK_INVALIDATE(n) chunks[(n)].flags = 0 +#define CHUNK_IS_VALID(n) (chunks[(n)].flags & CHUNK_FL_VALID) + +/* + * static parameters to gzip helper functions + * we cannot use paramters because API was not + * designed that way + */ +static segment_t *chunks; /* holds the list of segments */ +static segment_t *cur_chunk; +static UINTN nchunks; +static UINTN chunk; /* current segment */ +static UINTN input_fd; +static VOID *kernel_entry, *kernel_base, *kernel_end; + +static uch *inbuf; /* input buffer (compressed data) */ +static uch *window; /* output buffer (uncompressed data) */ +static unsigned long file_offset; /* position in the file */ + +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ +#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ +#define RESERVED 0xC0 /* bit 6,7: reserved */ + +#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) + +/* Diagnostic functions */ +#ifdef INFLATE_DEBUG +# define Assert(cond,msg) {if(!(cond)) error(msg);} +int stderr; +# define Trace(x) Print(L"line %d:\n", __LINE__); +# define Tracev(x) {if (verbose) Print(L"line %d:\n", __LINE__) ;} +# define Tracevv(x) {if (verbose>1) Print(L"line %d:\n", __LINE__) ;} +# define Tracec(c,x) {if (verbose && (c)) Print(L"line %d:\n", __LINE__) ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) Print(L"line %d:\n", __LINE__) ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + +static int fill_inbuf(void); +static void flush_window(void); +static void error(char *m); +static long bytes_out; +static void error(char *m); +static int error_return; + +static void * +gzip_malloc(int size) +{ + return (void *)alloc(size, 0); +} + +static void +gzip_free(void *where) +{ + return free(where); +} + +#include "inflate.c" + +/* + * Fill the input buffer and return the first byte in it. This is called + * only when the buffer is empty and at least one byte is really needed. + */ +int +fill_inbuf(void) +{ + INTN expected, nread; + EFI_STATUS status; + + expected = nread = INBUFSIZE; + + status = fops_read(input_fd, inbuf, &nread); + if (EFI_ERROR(status)) { + error("elilo: Read failed"); + } + DBG_PRT((L"%s : read %d bytes of %d bytes\n", LD_NAME, nread, expected)); + + insize = nread; + inptr = 1; + + return inbuf[0]; +} + +/* =========================================================================== + * Write the output window window[0..outcnt-1] and update crc and bytes_out. + * (Used for the decompressed data only.) + */ + +/* + * Run a set of bytes through the crc shift register. If s is a NULL + * pointer, then initialize the crc shift register contents instead. + * Return the current crc in either case. + * + * Input: + * S pointer to bytes to pump through. + * N number of bytes in S[]. + */ +unsigned long +updcrc(unsigned char *s, unsigned n) +{ + register unsigned long c; + /* crc is defined in inflate.c */ + + if (!s) { + c = 0xffffffffL; + } else { + c = crc; + while (n--) { + c = crc_32_tab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8); + } + } + crc = c; + return c ^ 0xffffffffUL; /* (instead of ~c for 64-bit machines) */ +} + + +/* + * Clear input and output buffers + */ +void +clear_bufs(void) +{ + outcnt = 0; + inptr = 0; + chunk = 0; + cur_chunk = NULL; + file_offset = 0; +} + + +static INTN +is_valid_header(Elf32_Ehdr *ehdr) +{ + UINT16 type, machine; + + type = ehdr->e_type; + machine = ehdr->e_machine; + + VERB_PRT(3, Print(L"class=%d type=%d data=%d machine=%d\n", + ehdr->e_ident[EI_CLASS], + type, + ehdr->e_ident[EI_DATA], + machine)); + + return ehdr->e_ident[EI_MAG0] == 0x7f + && ehdr->e_ident[EI_MAG1] == 'E' + && ehdr->e_ident[EI_MAG2] == 'L' + && ehdr->e_ident[EI_MAG3] == 'F' + && ehdr->e_ident[EI_CLASS] == ELFCLASS32 + && type == ET_EXEC /* must be executable */ + && machine == EM_386 ? 0 : -1; +} + +/* + * will invalidate loadble segments which overlap with others + */ +void +check_overlap(int i) +{ + int j; + unsigned long iend = chunks[i].addr + chunks[i].size; + + for(j=0; j < nchunks; j++) { + if (j ==i) continue; + if (chunks[i].addr >= chunks[j].addr && iend < (chunks[j].addr + chunks[j].size)) { + DBG_PRT((L"%s : segment %d fully included in segment %d\n", LD_NAME, i, j)); + CHUNK_INVALIDATE(i); /* nullyify segment */ + break; + } + } +} + +void +analyze_chunks(void) +{ + INTN i; + + for (i=0; i < nchunks; i++) { + if (CHUNK_IS_VALID(i) && !CHUNK_IS_LOAD(i)) + check_overlap(i); + } +} + + +/* + * The decompression code calls this function after decompressing the + * first block of the object file. The first block must contain all + * the relevant header information. + */ +int +first_block (const char *buf, long blocksize) +{ + Elf32_Ehdr *elf; + Elf32_Phdr *phdrs; + UINTN total_size, pages; + UINTN low_addr, max_addr; + UINTN offs = 0; + UINT16 phnum; + UINTN paddr, memsz; + INTN i; + + elf = (Elf32_Ehdr *)buf; + + if (is_valid_header(elf) == -1) + return -1; + + offs = elf->e_phoff; + phnum = elf->e_phnum; + + VERB_PRT(3, { + Print(L"Entry point 0x%lx\n", elf->e_entry); + Print(L"%d program headers\n", phnum); + Print(L"%d segment headers\n", elf->e_shnum); + }); + + if (offs + phnum * sizeof(*phdrs) > (unsigned) blocksize) { + ERR_PRT((L"%s : ELF program headers not in first block (%ld)\n", LD_NAME, offs)); + return -1; + } + + kernel_entry = (VOID *)(elf->e_entry & PADDR_MASK); + + phdrs = (Elf32_Phdr *) (buf + offs); + low_addr = ~0; + max_addr = 0; + + /* + * allocate chunk table + * Convention: a segment that does not need loading will + * have chunk[].addr = 0. + */ + chunks = (void *)alloc(sizeof(struct segment)*phnum, 0); + if (chunks == NULL) { + ERR_PRT((L"%s : failed alloc chunks %r\n", LD_NAME)); + return -1; + } + nchunks = phnum; + /* + * find lowest and higest virtual addresses + * don't assume FULLY sorted ! + */ + for (i = 0; i < phnum; ++i) { + /* + * record chunk no matter what because no load may happen + * anywhere in archive, not just as the last segment + */ + paddr = (phdrs[i].p_paddr & PADDR_MASK); + memsz = phdrs[i].p_memsz, + + chunks[i].addr = paddr; + chunks[i].offset = phdrs[i].p_offset; + chunks[i].size = phdrs[i].p_filesz; + chunks[i].bss_sz = phdrs[i].p_memsz - phdrs[i].p_filesz; + + CHUNK_VALIDATE(i); + + if (phdrs[i].p_type != PT_LOAD) { + CHUNK_NO_LOAD(i); /* mark no load chunk */ + DBG_PRT((L"%s : skipping segment %ld\n", LD_NAME, i)); + continue; + } + + CHUNK_CAN_LOAD(i); /* mark no load chunk */ + + VERB_PRT(3, + Print(L"\n%s : segment %ld vaddr [0x%lx-0x%lx] offset %ld filesz %ld " + "memsz=%ld bss_sz=%ld\n", + LD_NAME, 1+i, chunks[i].addr, chunks[i].addr+phdrs[i].p_filesz, + chunks[i].offset, chunks[i].size, memsz, chunks[i].bss_sz)); + + if (paddr < low_addr) + low_addr = paddr; + if (paddr + memsz > max_addr) + max_addr = paddr + memsz; + } + + if (low_addr & (EFI_PAGE_SIZE - 1)) { + ERR_PRT((L"%s : low_addr not page aligned 0x%lx\n", LD_NAME, low_addr)); + goto error; + } + analyze_chunks(); + + DBG_PRT((L"%s : %d program headers entry=0x%lx\nlowest_addr=0x%lx highest_addr=0x%lx\n", + LD_NAME, + phnum, kernel_entry, low_addr, max_addr)); + + total_size = (UINTN)max_addr - (UINTN)low_addr; + pages = EFI_SIZE_TO_PAGES(total_size); + + /* + * Record end of kernel for initrd + */ + kernel_base = (void *)low_addr; + kernel_end = (void *)(low_addr + (pages << EFI_PAGE_SHIFT)); + + /* allocate memory for the kernel */ + if (alloc_kmem((void *)low_addr, pages) == -1) { + ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", + LD_NAME, pages, low_addr)); + ERR_PRT((L"%s : Could not load kernel at 0x%lx\n", LD_NAME, low_addr)); + ERR_PRT((L"%s : Bailing\n", LD_NAME)); + goto error; + } + return 0; +error: + if (chunks) + free(chunks); + return -1; +} + +/* + * Determine which chunk in the Elf file will be coming out of the expand + * code next. + */ +static void +nextchunk(void) +{ + int i; + segment_t *cp; + + cp = NULL; + for(i=0; i < nchunks; i++) { + + if (!CHUNK_IS_VALID(i) || !CHUNK_IS_LOAD(i)) continue; + + if (file_offset > chunks[i].offset) continue; + + if (cp == NULL || chunks[i].offset < cp->offset) cp = &chunks[i]; + } + cur_chunk = cp; +} + + +/* + * Write the output window window[0..outcnt-1] holding uncompressed + * data and update crc. + */ +void +flush_window(void) +{ + static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' }; + static UINTN heli_count; + struct segment *cp; + char *src, *dst; + long cnt; + + if (!outcnt) return; + + DBG_PRT((L"%s : flush_window outnct=%d file_offset=%ld\n", LD_NAME, outcnt, file_offset)); + + Print(L"%c\b",helicopter[heli_count++%4]); + + updcrc(window, outcnt); + + /* first time, we extract the headers */ + if (!bytes_out) { + if (first_block(window, outcnt) < 0) + error("invalid exec header"); + nextchunk(); + } + + bytes_out += outcnt; + src = window; +tail: + /* check if user wants to abort */ + if (check_abort() == EFI_SUCCESS) goto load_abort; + + cp = cur_chunk; + if (cp == NULL || file_offset + outcnt <= cp->offset) { + file_offset += outcnt; + return; + } + + /* Does this window begin before the current chunk? */ + if (file_offset < cp->offset) { + unsigned long skip = cp->offset - file_offset; + + src += skip; + file_offset += skip; + outcnt -= skip; + } + dst = (char *)cp->addr + (file_offset - cp->offset); + cnt = cp->offset + cp->size - file_offset; + if (cnt > outcnt) + cnt = outcnt; + + Memcpy(dst, src, cnt); + + file_offset += cnt; + outcnt -= cnt; + src += cnt; + + /* See if we are at the end of this chunk */ + if (file_offset == cp->offset + cp->size) { + if (cp->bss_sz) { + dst = (char *)cp->addr + cp->size; + Memset(dst, 0, cp->bss_sz); + } + nextchunk(); + /* handle remaining bytes */ + if (outcnt) + goto tail; + } + return; +load_abort: + free_kmem(); + error_return = ELILO_LOAD_ABORTED; +} + +static void +error(char *x) +{ + ERR_PRT((L"%s : %a", LD_NAME, x)); + /* will eventually exit with error from gunzip() */ +} + +INT32 +decompress_kernel(VOID) +{ + INT32 ret; + + clear_bufs(); + makecrc(); + Print(L"Uncompressing Linux... "); + ret = gunzip(); + if (ret == 0) + Print(L"done\n"); + return ret == 0 ? 0 : -1; +} + +int +gunzip_kernel(fops_fd_t fd, kdesc_t *kd) +{ + int ret = -1; + + error_return = ELILO_LOAD_ERROR; + + window = (void *)alloc(WSIZE, 0); + if (window == NULL) { + ERR_PRT((L"%s : allocate output window failed\n", LD_NAME)); + return -1; + } + + inbuf = (void *)alloc(INBUFSIZE, 0); + if (inbuf == NULL) { + ERR_PRT((L"%s : allocate input window failedr\n", LD_NAME)); + goto error; + } + input_fd = fd; + insize = 0; + bytes_out = 0; + + ret = decompress_kernel(); +error: + if (window) free(window); + if (inbuf) free(inbuf); + + if (ret == 0) { + kd->kentry = kernel_entry; + kd->kend = kernel_end; + kd->kstart = kernel_base; + error_return = ELILO_LOAD_SUCCESS; + } + return error_return; +} diff --git a/ia32/gzip_loader.c b/ia32/gzip_loader.c new file mode 100644 index 0000000..2e11b84 --- /dev/null +++ b/ia32/gzip_loader.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2001-2002 Hewlett-Packard Co. + * Contributed by Stephane Eranian + * + * This file is part of the ELILO, the EFI Linux boot loader. + * + * ELILO is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ELILO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ELILO; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Please check out the elilo.txt for complete documentation on how + * to use this program. + */ + +#include +#include + +#include "elilo.h" +#include "loader.h" +#include "gzip.h" + +#define LD_NAME L"gzip_ia32" + +static INTN +gzip_probe_format(CHAR16 *kname) +{ + UINT8 buf[4]; + EFI_STATUS status; + INTN ret = -1; + UINTN size; + fops_fd_t fd; + + status = fops_open(kname, &fd); + if (EFI_ERROR(status)) return -1; + + size = sizeof(buf); + status = fops_read(fd, buf, &size); + + if (EFI_ERROR(status) || size != sizeof(buf)) goto error; + + ret = gzip_probe(buf, sizeof(buf)); +error: + fops_close(fd); + return ret; +} + + +static INTN +gzip_load_kernel(CHAR16 *kname, kdesc_t *kd) +{ + EFI_STATUS status; + INT32 ret; + fops_fd_t fd; + + status = fops_open(kname, &fd); + if (EFI_ERROR(status)) return ELILO_LOAD_ERROR; + + ret = gunzip_kernel(fd, kd); + + fops_close(fd); + + return ret; /* could be success, error, or abort */ +} + +loader_ops_t gzip_loader={ + NULL, + LD_NAME, + gzip_probe_format, + gzip_load_kernel +}; diff --git a/ia32/plain_loader.c b/ia32/plain_loader.c new file mode 100644 index 0000000..ac4c573 --- /dev/null +++ b/ia32/plain_loader.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2001-2002 Hewlett-Packard Co. + * Contributed by Stephane Eranian + * + * Copyright (C) 2001 Silicon Graphics, Inc. + * Contributed by Brent Casavant + * + * This file is part of the ELILO, the EFI Linux boot loader. + * + * ELILO is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ELILO is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ELILO; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Please check out the elilo.txt for complete documentation on how + * to use this program. + */ + +#include +#include + +#include "elilo.h" +#include "loader.h" +#include "elf.h" +#include "private.h" + +#define LD_NAME L"plain_elf32" + +static INTN +is_valid_header(Elf32_Ehdr *ehdr) +{ + UINT16 type, machine; + + type = ehdr->e_type; + machine = ehdr->e_machine; + + DBG_PRT((L"class=%d type=%d data=%d machine=%d\n", + ehdr->e_ident[EI_CLASS], + type, + ehdr->e_ident[EI_DATA], + machine)); + + return ehdr->e_ident[EI_MAG0] == 0x7f + && ehdr->e_ident[EI_MAG1] == 'E' + && ehdr->e_ident[EI_MAG2] == 'L' + && ehdr->e_ident[EI_MAG3] == 'F' + && ehdr->e_ident[EI_CLASS] == ELFCLASS32 + && type == ET_EXEC /* must be executable */ + && machine == EM_386 ? 0 : -1; +} + +static INTN +plain_probe(CHAR16 *kname) +{ + Elf32_Ehdr ehdr; + EFI_STATUS status; + INTN ret = -1; + fops_fd_t fd; + UINTN size = sizeof(ehdr); + + status = fops_open(kname, &fd); + if (EFI_ERROR(status)) + return -1; + + status = fops_read(fd, &ehdr, &size); + if (EFI_ERROR(status) || size != sizeof(ehdr)) + goto error; + + ret = is_valid_header(&ehdr); +error: + fops_close(fd); + return ret; +} + + +static INTN +load_elf(fops_fd_t fd, kdesc_t *kd) +{ + Elf32_Ehdr ehdr; + Elf32_Phdr *phdrs; + EFI_STATUS status; + INTN ret = ELILO_LOAD_ERROR; + UINTN i, total_size = 0; + UINTN pages, size, bss_sz, osize; + VOID *low_addr = (VOID *)~0; + VOID *max_addr = (VOID *)0; + UINTN paddr, memsz, filesz; + UINT16 phnum; + + Print(L"Loading Linux... "); + + size = sizeof(ehdr); + + status = fops_read(fd, &ehdr, &size); + if (EFI_ERROR(status) || size < sizeof(ehdr)) + return ELILO_LOAD_ERROR; + + if (is_valid_header(&ehdr) == -1) { + ERR_PRT((L"%s : not a 32-bit ELF image\n", LD_NAME)); + return ELILO_LOAD_ERROR; + } + VERB_PRT(3, { + Print(L"ELF Header information: \n"); + Print(L"\tEntry point 0x%x\n", (ehdr.e_entry & PADDR_MASK)); + Print(L"\t%d program headers\n", ehdr.e_phnum); + Print(L"\t%d segment headers\n", ehdr.e_shnum); + }); + + phnum = ehdr.e_phnum; + + if (fops_seek(fd, ehdr.e_phoff) < 0) { + ERR_PRT((L"%s : seek to %d for phdrs failed", LD_NAME, ehdr.e_phoff)); + return ELILO_LOAD_ERROR; + } + size = osize = (phnum * sizeof(Elf32_Phdr)); + + DBG_PRT((L"%s : allocate %d bytes for %d pheaders each of size:%d phentsize=%d\n", + LD_NAME, size, phnum, sizeof(Elf32_Phdr), ehdr.e_phentsize)); + + phdrs = (Elf32_Phdr *)alloc(size, 0); + if (phdrs == NULL) { + ERR_PRT((L"%s : allocate for phdrs failed", LD_NAME)); + return ELILO_LOAD_ERROR; + } + status = fops_read(fd, phdrs, &size); + if (EFI_ERROR(status) || size != osize) { + ERR_PRT((L"%s : phdr load failed", LD_NAME, status)); + goto out; + } + /* + * First pass to figure out total memory footprint + */ + for (i = 0; i < phnum; i++) { + + paddr = (phdrs[i].p_paddr & PADDR_MASK); + memsz = phdrs[i].p_memsz; + + DBG_PRT((L"Phdr %d paddr [0x%x-0x%x] offset 0x%x" + " filesz 0x%x memsz=0x%x bss_sz=0x%x p_type=0x%x\n", + 1+i, paddr, paddr+phdrs[i].p_filesz, phdrs[i].p_offset, + phdrs[i].p_filesz, memsz, + (memsz - phdrs[i].p_filesz), phdrs[i].p_type)); + + if (phdrs[i].p_type != PT_LOAD) + continue; + if (paddr < (UINTN)low_addr) + low_addr = (VOID *)paddr; + if (paddr + memsz > (UINTN)max_addr) + max_addr = (VOID *)paddr + memsz; + } + + if ((UINTN)low_addr & (EFI_PAGE_SIZE - 1)) { + ERR_PRT((L"%s : kernel low address 0x%x not page aligned\n", + LD_NAME, low_addr)); + goto out; + } + /* how many bytes are needed to hold the kernel? */ + total_size = (UINTN)max_addr - (UINTN)low_addr; + + /* round up to get required number of pages */ + pages = EFI_SIZE_TO_PAGES(total_size); + + /* keep track of location where kernel starts and ends */ + kd->kstart = low_addr; + kd->kend = (low_addr + (pages << EFI_PAGE_SHIFT)); + kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK); + + VERB_PRT(3, { + Print(L"Lowest PhysAddr: 0x%x\nTotalMemSize:%d bytes (%d pages)\n", + low_addr, total_size, pages); + Print(L"Kernel entry @ 0x%x\n", kd->kentry); + }); + + /* now allocate memory for the kernel at the exact requested spot */ + if (alloc_kmem(low_addr, pages) == -1) { + ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", + LD_NAME, pages, low_addr)); + ERR_PRT((L"%s : Could not alloc %d pages for the kernel at 0x%lx " + " and relocation is not not been implemented!\n", + LD_NAME, pages, low_addr)); + goto load_abort; + } + /* Pure paranoia. Clear the memory first. Just in case... */ + Memset(low_addr, 0, (pages << EFI_PAGE_SHIFT)); + + VERB_PRT(1, Print(L"Press any key to interrupt\n")); + + /* + * Walk through the program headers + * and actually load data into physical memory + */ + + for (i = 0; i < phnum; i++) { + + /* Check for pure loadable segment; ignore if not loadable */ + if (phdrs[i].p_type != PT_LOAD) + continue; + + VERB_PRT(3, Print(L"poffs: 0x%x (phdrs[%d].p_offset)\n", + phdrs[i].p_offset, i)); + + filesz = phdrs[i].p_filesz; + low_addr = (VOID *)((UINTN) phdrs[i].p_paddr & PADDR_MASK); + + /* Move to the right position */ + if (fops_seek(fd, phdrs[i].p_offset) < 0) + goto out_kernel; + + /* How many BSS bytes to clear */ + bss_sz = phdrs[i].p_memsz - filesz; + + VERB_PRT(4, { + Print(L"\nHeader #%d\n", i); + Print(L"Offset in file 0x%x\n", phdrs[i].p_offset); + Print(L"Physical addr 0x%x\n", low_addr); + Print(L"BSS size 0x%x bytes\n", bss_sz); + }); + + /* + * Read actual segment into memory + */ + ret = fops_read(fd, low_addr, &filesz); + if (ret == ELILO_LOAD_ABORTED) goto load_abort; + if (ret == ELILO_LOAD_ERROR) goto out; + + /* + * Clear bss section + */ + if (bss_sz) + Memset((VOID *)low_addr+filesz, 0, bss_sz); + } + + free(phdrs); + + Print(L"..Done\n"); + return ELILO_LOAD_SUCCESS; + +load_abort: + Print(L"..Aborted\n"); + ret = ELILO_LOAD_ABORTED; +out_kernel: + /* free kernel memory */ + free_kmem(); +out: + free(phdrs); + return ret; +} + +static INTN +plain_load_kernel(CHAR16 *kname, kdesc_t *kd) +{ + INTN ret; + fops_fd_t fd; + EFI_STATUS status; + + /* + * Moving the open here simplifies the load_elf() error handling + */ + status = fops_open(kname, &fd); + if (EFI_ERROR(status)) return ELILO_LOAD_ERROR; + + Print(L"Loading %s...", kname); + + ret = load_elf(fd, kd); + + fops_close(fd); + return ret; +} + +loader_ops_t plain_loader={ + NULL, + LD_NAME, + plain_probe, + plain_load_kernel +}; diff --git a/ia32/sysdeps.h b/ia32/sysdeps.h index d6f3324..0cec75a 100644 --- a/ia32/sysdeps.h +++ b/ia32/sysdeps.h @@ -33,6 +33,7 @@ #define __ELILO_SYSDEPS_IA32_H__ #define ELILO_ARCH "IA-32" /* ASCII string */ +#define PADDR_MASK 0xfffffff /* for now use library versions */ #define Memset(a,v,n) SetMem((a),(n),(v)) @@ -56,28 +57,7 @@ * A new bit, LDRFLAG_BOOT_PARAM_RELOC, in the loader_flags * field is also defined in this file. */ -typedef struct efi_ia32_boot_params { - UINT32 size; - UINT32 command_line; - UINT32 efi_sys_tbl; - UINT32 efi_mem_map; - UINT32 efi_mem_map_size; - UINT32 efi_mem_desc_size; - UINT32 efi_mem_desc_version; - UINT32 initrd_start; - UINT32 initrd_size; - UINT32 loader_start; - UINT32 loader_size; - UINT32 kernel_start; - UINT32 kernel_size; - UINT16 num_cols; - UINT16 num_rows; - UINT16 orig_x; - UINT16 orig_y; -} efi_ia32_boot_params_t; - -extern efi_ia32_boot_params_t efi_ia32_bp; - + #pragma pack(1) typedef union ia32_boot_params { UINT8 raw[0x2000]; @@ -275,7 +255,9 @@ typedef union ia32_boot_params { /* 0x224 */ UINT16 heap_end_ptr; /* LDR */ /* %%TBD */ -/* 0x226 */ UINT32 base_mem_size; /* LDR */ +/* 0x226 */ UINT16 unused_7; /* LDR */ + +/* 0x228 */ UINT32 cmdline_addr; /* LDR */ } s; } boot_params_t; #pragma pack() @@ -354,7 +336,6 @@ start_kernel(VOID *kentry, boot_params_t *bp) /* * Disable interrupts. */ - asm volatile ( "cli" : : ); /* @@ -362,11 +343,9 @@ start_kernel(VOID *kentry, boot_params_t *bp) */ if (bp->s.initrd_start) { - /* %%TBD */ MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size); bp->s.initrd_start = 15 * 1024 * 1024; } - /* * Copy boot sector, setup data and command line * to final resting place. We need to copy @@ -375,20 +354,6 @@ start_kernel(VOID *kentry, boot_params_t *bp) MEMCPY(high_base_mem, bp, 0x4000); - /* - * initialize efi ia32 boot params and place them at 1kb up from - * the start of the boot command line param. This results in the - * efi ia32 boot params to be copied to 0x00104c00. See bootparams.c - * for details on how this is arranged. EFI enabled - * kernels will look for the efi boot params here to know if the - * kernel is booting on an EFI platform or legacy BIOS based platfrom - */ - - efi_ia32_bp.initrd_start = bp->s.initrd_start; - efi_ia32_bp.initrd_size = bp->s.initrd_size; - - MEMCPY(high_base_mem + 0x4000 - 0x0400, &efi_ia32_bp, sizeof(efi_ia32_bp)); - /* * Initialize Linux GDT. */ @@ -429,7 +394,6 @@ start_kernel(VOID *kentry, boot_params_t *bp) * Jump to kernel entry point. */ - asm volatile ( "jmp *%%ecx" : : ); } diff --git a/ia32/system.c b/ia32/system.c index 2e8b8e4..1dbbc58 100644 --- a/ia32/system.c +++ b/ia32/system.c @@ -26,30 +26,23 @@ */ /* - * this file contains all the IA-32 specific code expected by generic loader + * This file contains all the IA-32 specific code expected by generic loader */ #include #include #include "elilo.h" #include "loader.h" - #include "rmswitch.h" -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/* extern loader_ops_t plain_loader, gzip_loader; */ - -efi_ia32_boot_params_t efi_ia32_bp; - +extern loader_ops_t bzimage_loader, plain_loader, gzip_loader; /* * Descriptor table base addresses & limits for Linux startup. */ dt_addr_t gdt_addr = { 0x800, 0x94000 }; -dt_addr_t idt_addr = { 0, 0 }; +dt_addr_t idt_addr = { 0, 0 }; /* * Initial GDT layout for Linux startup. @@ -77,7 +70,6 @@ UINT16 init_gdt[] = { UINTN sizeof_init_gdt = sizeof init_gdt; - /* * Highest available base memory address. * @@ -98,266 +90,33 @@ UINTN high_base_mem = 0x90000; * * This is computed by taking the highest available extended memory * address and rounding down to the nearest EFI_PAGE_SIZE (usually - * 4 kB) boundary. The ia32 Linux kernel can only support up to - * 2 GB (AFAIK). + * 4 kB) boundary. + * This is only used for backward compatibility. */ UINTN high_ext_mem = 32 * 1024 * 1024; -/* - * Starting location and size of runtime memory blocks. - */ - -boot_params_t *param_start = NULL; -UINTN param_size = 0; - +/* This starting address will hold true for all of the loader types for now */ VOID *kernel_start = (VOID *)0x100000; /* 1M */ -UINTN kernel_size = 0x200000; /* 2M (largest x86 kernel image) */ VOID *initrd_start = NULL; UINTN initrd_size = 0; -/* - * Boot parameters can be relocated if TRUE. - * Boot parameters must be placed at 0x90000 if FALSE. - * - * This will be set to TRUE if bit 6 (0x40) is set in the loader_flags - * field in a compressed x86 boot format kernel. This will also be set - * to TRUE if the kernel is an uncompressed ELF32 image. - * - * To remote boot w/ the universal network driver and a 16-bit UNDI - * this must be set to TRUE. - */ - -BOOLEAN can_reloc_boot_params = FALSE; - -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -static INTN -probe_bzImage_boot(CHAR16 *kname) -{ - EFI_STATUS efi_status; - UINTN size; - fops_fd_t fd; - UINT8 bootsect[512]; - - DBG_PRT((L"probe_bzImage_boot()\n")); - - if (!kname) { - ERR_PRT((L"kname == %xh", kname)); - free_kmem(); - return -1; - } - - /* - * Open kernel image. - */ - - DBG_PRT((L"opening %s...\n", kname)); - - efi_status = fops_open(kname, &fd); - - if (EFI_ERROR(efi_status)) { - ERR_PRT((L"Could not open %s.", kname)); - free_kmem(); - return -1; - } - - /* - * Read boot sector. - */ - - DBG_PRT((L"\nreading boot sector...\n")); - - size = sizeof bootsect; - efi_status = fops_read(fd, bootsect, &size); - - if (EFI_ERROR(efi_status) || size != sizeof bootsect) { - ERR_PRT((L"Could not read boot sector from %s.", kname)); - fops_close(fd); - free_kmem(); - return -1; - } - - /* - * Verify boot sector signature. - */ - - if (bootsect[0x1FE] != 0x55 || bootsect[0x1FF] != 0xAA) { - ERR_PRT((L"%s is not a bzImage kernel image.\n", kname)); - fops_close(fd); - free_kmem(); - return -1; - } - - /* - * Check for out of range setup data size. - * Will almost always be 7, but we will accept 1 to 64. - */ - - DBG_PRT((L"bootsect[1F1h] == %d setup sectors\n", bootsect[0x1F1])); - - if (bootsect[0x1F1] < 1 || bootsect[0x1F1] > 64) { - ERR_PRT((L"%s is not a valid bzImage kernel image.", - kname)); - - fops_close(fd); - free_kmem(); - return -1; - } - - /* - * Allocate and read setup data. - */ - - DBG_PRT((L"reading setup data...\n")); - - param_size = (bootsect[0x1F1] + 1) * 512; - //param_start = alloc(param_size, EfiBootServicesData); - param_start = alloc(param_size, EfiLoaderData); - - DBG_PRT((L"param_size=%d param_start=%x", param_size, param_start)); - - if (!param_start) { - ERR_PRT((L"Could not allocate %d bytes of setup data.", - param_size)); - - fops_close(fd); - free_kmem(); - return -1; - } - - CopyMem(param_start, bootsect, sizeof bootsect); - - size = param_size - 512; - efi_status = fops_read(fd, ((UINT8 *)param_start) + 512, &size); - - if (EFI_ERROR(efi_status) || size != param_size - 512) { - ERR_PRT((L"Could not read %d bytes of setup data.", - param_size - 512)); - - free(param_start); - param_start = NULL; - param_size = 0; - fops_close(fd); - free_kmem(); - return -1; - } - - /* - * Check for setup data signature. - */ - - { UINT8 *c = ((UINT8 *)param_start)+514; - DBG_PRT((L"param_start(c=%x): %c-%c-%c-%c", c, (CHAR16)c[0],(CHAR16) c[1], (CHAR16)c[2], (CHAR16)c[3])); - } - if (CompareMem(((UINT8 *)param_start) + 514, "HdrS", 4)) { - ERR_PRT((L"%s does not have a setup signature.", - kname)); - - free(param_start); - param_start = NULL; - param_size = 0; - fops_close(fd); - free_kmem(); - return -1; - } - - /* - * Allocate memory for kernel. - */ - - 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)); - } - - /* - * Now read the rest of the kernel image into memory. - */ - - DBG_PRT((L"reading kernel image...\n")); - - size = kernel_size; - - efi_status = fops_read(fd, kernel_start, &size); - - if (EFI_ERROR(efi_status) || size < 0x10000) { - ERR_PRT((L"Error reading kernel image %s.", kname)); - free(param_start); - param_start = NULL; - param_size = 0; - fops_close(fd); - free_kmem(); - return -1; - } - - DBG_PRT((L"kernel image read: %d bytes, %d Kbytes\n", size, size / 1024)); - - /* - * Boot sector, setup data and kernel image loaded. - */ - - fops_close(fd); - return 0; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -static INTN -load_bzImage_boot(CHAR16 *kname, kdesc_t *kd) -{ - DBG_PRT((L"load_bzImage_boot()\n")); - - if (!kname || !kd) { - ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd)); - - free(param_start); - param_start = NULL; - param_size = 0; - free_kmem(); - return -1; - } - - kd->kstart = kd->kentry = kernel_start; - kd->kend = ((UINT8 *)kd->kstart) + kernel_size; - - DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend)); - - return 0; -} - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -static loader_ops_t loader_bzImage_boot = { - NULL, - L"loader_bzImage_boot", - &probe_bzImage_boot, - &load_bzImage_boot -}; - -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ INTN sysdeps_init(EFI_HANDLE dev) { - DBG_PRT((L"sysdeps_init()\n")); /* * Register our loader(s)... */ - loader_register(&loader_bzImage_boot); - /* loader_register(&plain_loader); */ - /* loader_register(&gzip_loader); */ - - + loader_register(&bzimage_loader); + loader_register(&plain_loader); + loader_register(&gzip_loader); return 0; } -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* * initrd_get_addr() * Compute a starting address for the initial RAMdisk image. @@ -381,13 +140,12 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem) imem->start_addr = kd->kend; - VERB_PRT(3, Print(L"initrd start_addr=0x%x pgcnt=%d\n", imem->start_addr, imem->pgcnt)); + VERB_PRT(3, Print(L"initrd start_addr=0x%x pgcnt=%d\n", + imem->start_addr, imem->pgcnt)); return 0; } -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ VOID sysdeps_free_boot_params(boot_params_t *bp) { @@ -398,8 +156,6 @@ sysdeps_free_boot_params(boot_params_t *bp) free_memmap(&md); } -/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* * IA-32 specific boot parameters initialization routine */ @@ -408,6 +164,7 @@ sysdeps_create_boot_params( boot_params_t *bp, CHAR8 *cmdline, memdesc_t *initrd, + memdesc_t *vmcode, /* no use for ia32 now*/ UINTN *cookie) { mmap_desc_t mdesc; @@ -423,9 +180,11 @@ sysdeps_create_boot_params( ERR_PRT((L"bp=0x%x cmdline=0x%x initrd=0x%x cookie=0x%x", bp, cmdline, initrd, cookie)); - free(param_start); - param_start = NULL; - param_size = 0; + if (param_start != NULL) { + free(param_start); + param_start = NULL; + param_size = 0; + } free_kmem(); return -1; } @@ -436,29 +195,27 @@ sysdeps_create_boot_params( * the first two sectors (1K). The rest of the storage * can be used by the command line. */ - - CopyMem(bp, param_start, 0x2000); - - free(param_start); - param_start = NULL; - param_size = 0; - + if (param_start != NULL) { + CopyMem(bp, param_start, 0x2000); + free(param_start); + param_start = NULL; + param_size = 0; + } /* * Save off our header revision information. */ - hdr_version = (bp->s.hdr_major << 8) | bp->s.hdr_minor; /* * Clear out unused memory in boot sector image. */ - 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_5, sizeof bp->s.unused_5); bp->s.unused_6 = 0; + bp->s.unused_7 = 0; /* * Tell kernel this was loaded by an advanced loader type. @@ -475,6 +232,12 @@ sysdeps_create_boot_params( bp->s.cmdline_magik = CMDLINE_MAGIK; bp->s.cmdline_offset = (UINT8 *)cmdline - (UINT8 *)bp; + /* + * Clear out the cmdline_addr field so the kernel can find + * the cmdline. + */ + bp->s.cmdline_addr = 0x0; + /* * Setup hard drive parameters. * %%TBD - It should be okay to zero fill the hard drive @@ -484,28 +247,16 @@ sysdeps_create_boot_params( ZeroMem(bp->s.hd0_info, sizeof bp->s.hd0_info); ZeroMem(bp->s.hd1_info, sizeof bp->s.hd1_info); -#if 0 - CopyMem(bp->s.hd0_info, *((VOID **)(0x41 * 4)), - sizeof bp->s.hd0_info); - - CopyMem(bp->s.hd1_info, *((VOID **)(0x46 * 4)), - sizeof bp->s.hd1_info); -#endif - /* * Memory info. */ bp->s.alt_mem_k = high_ext_mem / 1024; - if (bp->s.alt_mem_k <= 65535) { + if (bp->s.alt_mem_k <= 65535) bp->s.ext_mem_k = (UINT16)bp->s.alt_mem_k; - } else { + else bp->s.ext_mem_k = 65535; - } - - if (hdr_version < 0x0202) - bp->s.base_mem_size = high_base_mem; /* * Initial RAMdisk and root device stuff. @@ -520,29 +271,22 @@ sysdeps_create_boot_params( if (initrd->start_addr && initrd->pgcnt) { /* %%TBD - This will probably have to be changed. */ bp->s.initrd_start = (UINT32)initrd->start_addr; - bp->s.initrd_size = (UINT32)(initrd->pgcnt * EFI_PAGE_SIZE); + bp->s.initrd_size = (UINT32)(initrd->size); /* * This is the RAMdisk root device for RedHat 2.2.x * kernels (major 0x01, minor 0x00). - * %%TBD - Will this work for other distributions and - * 2.3.x and 2.4.x kernels? I do not know, yet. */ bp->s.orig_root_dev = 0x0100; } else { bp->s.initrd_start = 0; bp->s.initrd_size = 0; - - /* Do not change the root device if there is no RAMdisk. */ - /* bp->s.orig_root_dev = 0; */ } /* * APM BIOS info. */ - -/* %%TBD - How to do Int 15h calls to get this info? */ bp->s.apm_bios_ver = NO_APM_BIOS; bp->s.bios_code_seg = 0; bp->s.bios_entry_point = 0; @@ -555,29 +299,22 @@ sysdeps_create_boot_params( /* * MCA BIOS info (misnomer). */ - -/* %%TBD - How to do Int 15h call to get this info? */ bp->s.mca_info_len = 0; ZeroMem(bp->s.mca_info_buf, sizeof bp->s.mca_info_buf); /* - * Pointing device presence. + * Pointing device presence. The kernel will detect this. */ - -/* %%TBD - How to do Int 11h call to get this info? */ bp->s.aux_dev_info = NO_MOUSE; /* - * EFI loader signature and address of EFI system table. + * EFI loader signature */ - CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG, 4); - bp->s.efi_sys_tbl = 0; /* %%TBD */ /* * Kernel entry point. */ - bp->s.kernel_start = (UINT32)kernel_start; /* @@ -587,6 +324,7 @@ sysdeps_create_boot_params( * arch/i386/boot/bootsect.S * arch/i386/boot/setup.S * arch/i386/kernel/setup.c + * include/asm-i386/setup.h (2.5/2.6) */ #define CHECK_OFFSET(n, o, f) \ @@ -610,7 +348,6 @@ sysdeps_create_boot_params( ; \ } \ } - { UINTN test = 0; @@ -688,7 +425,7 @@ sysdeps_create_boot_params( CHECK_OFFSET(initrd_size, 0x21C, L"%xh"); CHECK_OFFSET(bootsect_helper, 0x220, L"%xh"); CHECK_OFFSET(heap_end_ptr, 0x224, L"%xh"); - CHECK_OFFSET(base_mem_size, 0x226, L"%xh"); + CHECK_OFFSET(cmdline_addr, 0x228, L"%xh"); if (test) { ERR_PRT((L"Boot sector and/or setup parameter alignment error.")); @@ -711,7 +448,6 @@ sysdeps_create_boot_params( if (EFI_ERROR(efi_status)) { ERR_PRT((L"QueryMode failed. Fake it.")); - mode = 3; rows = 25; cols = 80; @@ -730,12 +466,10 @@ sysdeps_create_boot_params( bp->s.orig_video_cols = (UINT8)cols; bp->s.orig_video_rows = (UINT8)rows; -/* %%TBD - How to do Int 10h calls to get video info? */ bp->s.orig_ega_bx = 0; bp->s.is_vga = 0; - bp->s.orig_video_points = 0; + bp->s.orig_video_points = 16; -/* %%TBD - How to do Int 10h calls to get frame buffer info? */ bp->s.lfb_width = 0; bp->s.lfb_height = 0; bp->s.lfb_depth = 0; @@ -763,7 +497,6 @@ sysdeps_create_boot_params( free_kmem(); return -1; } - *cookie = mdesc.cookie; bp->s.efi_mem_map = (UINTN)mdesc.md; bp->s.efi_mem_map_size = mdesc.map_size; @@ -771,28 +504,5 @@ sysdeps_create_boot_params( bp->s.efi_mem_desc_ver = mdesc.desc_version; bp->s.efi_sys_tbl = (UINTN)systab; - /* - * my_ia32_boot_params and get ready to slap them into 0x00104c00 - */ - - efi_ia32_bp.size= sizeof(efi_ia32_bp); - efi_ia32_bp.command_line = (UINT32) cmdline; - efi_ia32_bp.efi_sys_tbl = bp->s.efi_sys_tbl; - efi_ia32_bp.efi_mem_map = bp->s.efi_mem_map; - efi_ia32_bp.efi_mem_map_size = bp->s.efi_mem_map_size; - efi_ia32_bp.efi_mem_desc_size = bp->s.efi_mem_desc_size; - efi_ia32_bp.efi_mem_desc_version = bp->s.efi_mem_desc_ver; - efi_ia32_bp.initrd_start = (UINTN)initrd->start_addr; - efi_ia32_bp.initrd_size = initrd->pgcnt * EFI_PAGE_SIZE; - efi_ia32_bp.loader_start = 0; - efi_ia32_bp.loader_size = 0; - efi_ia32_bp.kernel_start = bp->s.kernel_start; - efi_ia32_bp.kernel_size = kernel_size; - efi_ia32_bp.num_cols = cols; - efi_ia32_bp.num_rows = rows; - efi_ia32_bp.orig_x = col; - efi_ia32_bp.orig_y = row; - - return 0; } diff --git a/ia64/gzip.c b/ia64/gzip.c index bb5a065..01e28c8 100644 --- a/ia64/gzip.c +++ b/ia64/gzip.c @@ -37,6 +37,8 @@ #include "private.h" #include "setjmp.h" +#define LD_NAME L"gzip_ia64" + #define memzero(s, n) Memset((VOID *)(s), 0, (n)) #define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(n)) @@ -68,6 +70,7 @@ typedef struct segment { #define CHUNK_FL_VALID 0x1 #define CHUNK_FL_LOAD 0x2 +#define CHUNK_FL_X 0x4 #define CHUNK_CAN_LOAD(n) chunks[(n)].flags |= CHUNK_FL_LOAD #define CHUNK_NO_LOAD(n) chunks[(n)].flags &= ~CHUNK_FL_LOAD @@ -391,6 +394,9 @@ first_block (const char *buf, long blocksize) continue; } + if (bswap32(phdrs[i].p_flags) & PF_X) + chunks[i].flags |= CHUNK_FL_X; + CHUNK_CAN_LOAD(i); /* mark no load chunk */ VERB_PRT(3, @@ -433,7 +439,7 @@ first_block (const char *buf, long blocksize) if (alloc_kmem((void *)low_addr, pages) == -1) { VOID *new_addr; - ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr)); + VERB_PRT(1, (L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr)); if (ia64_can_relocate() == 0) { ERR_PRT((L"relocation is disabled, cannot load kernel")); @@ -458,7 +464,7 @@ first_block (const char *buf, long blocksize) /* unsigned arithmetic */ load_offset = (UINTN) (new_addr - ROUNDDOWN((UINTN) low_addr,256*MB)); - ERR_PRT((L"low_addr=0x%lx new_addr=0x%lx offset=0x%lx", low_addr, new_addr, load_offset)); + VERB_PRT(1, (L"low_addr=0x%lx new_addr=0x%lx offset=0x%lx", low_addr, new_addr, load_offset)); /* * correct various addresses for non-zero load_offset @@ -566,6 +572,8 @@ tail: if (cnt > outcnt) cnt = outcnt; Memcpy(dst, src, cnt); + if (cp->flags & CHUNK_FL_X) + flush_dcache (dst, cnt); file_offset += cnt; outcnt -= cnt; diff --git a/ia64/gzip_loader.c b/ia64/gzip_loader.c index 4e06db4..a84851f 100644 --- a/ia64/gzip_loader.c +++ b/ia64/gzip_loader.c @@ -30,6 +30,8 @@ #include "loader.h" #include "gzip.h" +#define LD_NAME L"gzip_ia64" + static INTN gzip_probe_format(CHAR16 *kname) { diff --git a/ia64/plain_loader.c b/ia64/plain_loader.c index 92d009e..150f7a0 100644 --- a/ia64/plain_loader.c +++ b/ia64/plain_loader.c @@ -288,7 +288,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd) if (alloc_kmem(low_addr, pages) == -1) { VOID *new_addr; - ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr)); + VERB_PRT(1, (L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr)); if (ia64_can_relocate() == 0) { ERR_PRT((L"relocation is disabled, cannot load kernel")); @@ -387,6 +387,8 @@ load_elf(fops_fd_t fd, kdesc_t *kd) ret = read_file(fd, filesz, (CHAR8 *)phdrs[i].p_paddr); if (ret == ELILO_LOAD_ABORTED) goto load_abort; if (ret == ELILO_LOAD_ERROR) goto out; + if (bswap32(phdrs[i].p_flags) & PF_X) + flush_dcache ((CHAR8 *)phdrs[i].p_paddr, filesz); /* * update file position diff --git a/ia64/private.h b/ia64/private.h index bb09faf..c8f34c7 100644 --- a/ia64/private.h +++ b/ia64/private.h @@ -31,5 +31,7 @@ extern INTN query_fpswa(VOID **); extern INTN ia64_can_relocate(); +extern void flush_dcache (CHAR8 *addr, UINT64 len); + #endif /* __ELILO_PRIVATE_IA64_H__ */ diff --git a/ia64/setjmp.S b/ia64/setjmp.S index ce7e67c..4bc2103 100644 --- a/ia64/setjmp.S +++ b/ia64/setjmp.S @@ -78,6 +78,7 @@ setjmp: /* __sigsetjmp(__jmp_buf buf, int savemask) */ + .proc __sigsetjmp __sigsetjmp: //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) alloc loc1=ar.pfs,2,2,2,0 diff --git a/ia64/sysdeps.h b/ia64/sysdeps.h index ab447fb..e11e6b7 100644 --- a/ia64/sysdeps.h +++ b/ia64/sysdeps.h @@ -65,8 +65,11 @@ typedef struct ia64_boot_params { UINTN initrd_start; /* virtual address where the initial ramdisk begins */ UINTN initrd_size; /* how big is the initial ramdisk */ + UINTN vmcode_start; /* virtual address where the boot time vmcode begins */ + UINTN vmcode_size; /* how big is the boot module */ UINTN loader_addr; /* start address of boot loader */ UINTN loader_size; /* size of loader code & data */ + } boot_params_t; typedef struct sys_img_options { diff --git a/ia64/system.c b/ia64/system.c index 388d435..bb826ef 100644 --- a/ia64/system.c +++ b/ia64/system.c @@ -39,7 +39,7 @@ extern loader_ops_t plain_loader, gzip_loader; * IA-64 specific boot paramters initialization routine */ INTN -sysdeps_create_boot_params(boot_params_t *bp, CHAR8 *cmdline, memdesc_t *initrd, UINTN *cookie) +sysdeps_create_boot_params(boot_params_t *bp, CHAR8 *cmdline, memdesc_t *initrd, memdesc_t *vmcode, UINTN *cookie) { UINTN cols, rows; SIMPLE_TEXT_OUTPUT_INTERFACE *conout; @@ -64,7 +64,12 @@ sysdeps_create_boot_params(boot_params_t *bp, CHAR8 *cmdline, memdesc_t *initrd, bp->efi_memdesc_version = mdesc.desc_version; bp->command_line = (UINTN)cmdline; bp->initrd_start = (UINTN) initrd->start_addr; - bp->initrd_size = initrd->pgcnt << EFI_PAGE_SHIFT; + bp->initrd_size = initrd->size; + DBG_PRT((L"Got initrd @ 0x%lx (%d bytes)", initrd->start_addr, initrd->size)); + + bp->vmcode_start = (UINTN) vmcode->start_addr; + bp->vmcode_size = vmcode->size; + DBG_PRT((L"Got vmcode @ 0x%lx (%d bytes)", vmcode->start_addr, vmcode->size)); /* fetch console parameters: */ conout = systab->ConOut; @@ -135,3 +140,20 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem) return 0; } +/* Flush data cache [addr; addr + len], and sync with icache. */ +void +flush_dcache (CHAR8 *addr, UINT64 len) +{ + /* Cache line length is at least 32. */ + UINT64 a = (UINT64)addr & ~0x1f; + + VERB_PRT(3, Print(L"Flush 0x%lx-", a)); + + /* Flush data. */ + for (len = (len + 31) & ~0x1f; len > 0; len -= 0x20, a += 0x20) + asm volatile ("fc %0" : : "r" (a)); + /* Sync and serialize. Maybe extra. */ + asm volatile (";; sync.i;; srlz.i;;"); + + VERB_PRT(3, Print(L"0x%lx\n", a)); +} diff --git a/ia64/inflate.c b/inflate.c similarity index 97% rename from ia64/inflate.c rename to inflate.c index 8273c98..843c93b 100644 --- a/ia64/inflate.c +++ b/inflate.c @@ -1053,42 +1053,6 @@ makecrc(void) crc = (ulg)0xffffffffUL; /* shift register contents */ } -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -/* - * check for valid gzip signature - * return: - * 0 : valid gzip archive - * -1: invalid gzip archive - */ -int -gzip_probe(uch *buf, unsigned long size) -{ - if (size < 4) return -1; - - if (buf[0] != 037 || - ((buf[1] != 0213) && (buf[1] != 0236))) return -1; - - /* We only support method #8, DEFLATED */ - if (buf[2] != 8) return -1; - - if ((buf[3] & ENCRYPTED) != 0) return -1; - - if ((buf[3] & CONTINUATION) != 0) return -1; - - if ((buf[3] & RESERVED) != 0) return -1; - - return 0; -} - - /* * Do the uncompression! */ diff --git a/initrd.c b/initrd.c index 92b6f44..09ed0f0 100644 --- a/initrd.c +++ b/initrd.c @@ -29,7 +29,7 @@ #include "elilo.h" /* - * This function allocates memory for the initial ramdisk (initrd) and loads it to memory + * This function allocates memory for file image and loads it to memory * OUTPUTS: * - ELILO_LOAD_SUCCESS: if everything works * - ELILO_LOAD_ABORTED: in case the user decided to abort loading @@ -38,12 +38,12 @@ * Adapted from Bill Nottingham patch for ELI. */ INTN -load_initrd(CHAR16 *filename, memdesc_t *initrd) +load_file(CHAR16 *filename, memdesc_t *image) { EFI_STATUS status; - VOID *start_addr = initrd->start_addr; - UINT64 size = 0; + VOID *start_addr = image->start_addr; UINTN pgcnt; + UINT64 size = 0; fops_fd_t fd; INTN ret = ELILO_LOAD_ERROR; @@ -53,46 +53,48 @@ load_initrd(CHAR16 *filename, memdesc_t *initrd) /* Open the file */ status = fops_open(filename, &fd); if (EFI_ERROR(status)) { - ERR_PRT((L"Open initrd file %s failed: %r", filename, status)); + ERR_PRT((L"Open file %s failed: %r", filename, status)); return -1; } - DBG_PRT((L"initrd_open %s worked", filename)); + DBG_PRT((L"open %s worked", filename)); /* warning: this function allocates memory */ status = fops_infosize(fd, &size); if (EFI_ERROR(status)) { - ERR_PRT((L"Couldn't read initrd file %s info %r",filename, status)); + ERR_PRT((L"Couldn't read file %s info %r", filename, status)); goto error; } - /* round up to get required number of pages (4KB) */ - initrd->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(size); - + image->size = size; + /* 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, start_addr); if (start_addr == NULL) { - ERR_PRT((L"Failed to allocate %d pages for initrd", pgcnt)); + ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt, + filename)); goto error; } - VERB_PRT(2, Print(L"initrd: total_size: %ld bytes base: 0x%lx pages %d\n", - size, (UINT64)start_addr, pgcnt)); + VERB_PRT(2, Print(L"%s image: total_size: %ld bytes base: 0x%lx " + "pages %d\n", filename, image->size, + (UINTN)start_addr, pgcnt)); - Print(L"Loading initrd %s...", filename); + Print(L"Loading file %s...", filename); - ret = read_file(fd, size, start_addr); + ret = read_file(fd, image->size, start_addr); fops_close(fd); if (ret != ELILO_LOAD_SUCCESS) { - ERR_PRT((L"read initrd(%s) failed: %d", filename, ret)); + ERR_PRT((L"read image(%s) failed: %d", filename, ret)); goto error; } Print(L"done\n"); - initrd->start_addr = start_addr; + image->start_addr = start_addr; return ELILO_LOAD_SUCCESS; @@ -103,8 +105,9 @@ error: * make sure nothing is passed to kernel * in case of error. */ - initrd->start_addr = 0; - initrd->pgcnt = 0; + image->start_addr = 0; + image->pgcnt = 0; + image->size = 0; return ret; } -- 2.30.2