Stephane Eranian 2005-12-06 08:21:36 -05:00 committed by Vincent Batts
parent cb533a5de5
commit 6a4d7e49dc
29 changed files with 523 additions and 1389 deletions

View file

@ -1,3 +1,26 @@
2005-12-01 Alex Williamson <alex.williamson@hp.com>
* Applied patch from Fred Yang <fred.yang@intel.com> to support the
vmm= boot option. This option specifies the kernel image for a
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 <brett@hp.com>
* Applied patch from Tristan Gingold to add dcache flush and sync with
icache to gzip and plain loaders. This ommision was just noticed now
due to the much larger caches in Montecito, and the smaller size of
Xen (as compared to the linux kernel).
2004-09-27 Brett Johnson <brett@hp.com>
* Increase the hardcoded size of the texmenu chooser menu from 16 to 64
2004-09-23 Brett Johnson <brett@hp.com>
* Fix for 924147. Thanks to Stephanie Schaaf <sas@sgi.com> for a patch
that the fix is based on.
2004-02-19 Brett Johnson <brett@hp.com> 2004-02-19 Brett Johnson <brett@hp.com>
* Fixed bug where default image initrd would carry over to another * Fixed bug where default image initrd would carry over to another
image that was selected interactively (iff the newly selected image image that was selected interactively (iff the newly selected image

View file

@ -95,38 +95,23 @@ ifeq ($(CONFIG_chooser_textmenu),y)
CFLAGS += -DCONFIG_CHOOSER_TEXTMENU CFLAGS += -DCONFIG_CHOOSER_TEXTMENU
endif 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) ifeq ($(ARCH),ia64)
prefix = GCC_VERSION=$(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
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)
ifneq ($(GCC_VERSION),2)
CFLAGS += -frename-registers 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
CC = $(prefix)gcc
AS = $(prefix)as
LD = $(prefix)ld
AR = $(prefix)ar
RANLIB = $(prefix)ranlib
OBJCOPY = $(prefix)objcopy
endif endif
# EFI specs allows only lower floating point partition to be used
CFLAGS += -mfixed-range=f32-f127
endif endif

View file

@ -61,7 +61,7 @@ endif
FILES = elilo.o getopt.o strops.o loader.o \ FILES = elilo.o getopt.o strops.o loader.o \
fileops.o util.o vars.o alloc.o chooser.o \ fileops.o util.o vars.o alloc.o chooser.o \
config.o initrd.o alternate.o bootparams.o \ config.o initrd.o alternate.o bootparams.o \
fs/fs.o \ gunzip.o fs/fs.o \
choosers/choosers.o \ choosers/choosers.o \
devschemes/devschemes.o \ devschemes/devschemes.o \
$(ARCH)/sysdeps.o \ $(ARCH)/sysdeps.o \

View file

@ -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); status = BS->AllocatePages(where, type , pgcnt, &tmp);
if (EFI_ERROR(status)) { 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; return NULL;
} }
/* XXX: will cause warning on IA-32 */ /* XXX: will cause warning on IA-32 */
@ -155,7 +155,7 @@ free(VOID *addr)
if (p->addr == addr) goto found; if (p->addr == addr) goto found;
} }
/* not 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; return;
found: found:
DBG_PRT((L"free: %s @0x%lx size=%ld\n", DBG_PRT((L"free: %s @0x%lx size=%ld\n",

View file

@ -38,7 +38,7 @@
* bp : the address of the bootparams otherwise (opaque type) * bp : the address of the bootparams otherwise (opaque type)
*/ */
VOID * 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 * XXX: need cleanup
@ -69,6 +69,7 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, UINTN *cookie)
* Allocate memory for boot parameters. * Allocate memory for boot parameters.
* This CANNOT be EfiLoaderData or EfiLoaderCode as the kernel * This CANNOT be EfiLoaderData or EfiLoaderCode as the kernel
* frees this region when initializing. * 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); 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); 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 * Convert kernel command line args from UNICODE to ASCII and put them where

View file

@ -37,6 +37,7 @@ display_label_info(CHAR16 *name)
{ {
CHAR16 *desc; CHAR16 *desc;
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[CMDLINE_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN];
CHAR16 options_tmp[CMDLINE_MAXLEN]; CHAR16 options_tmp[CMDLINE_MAXLEN];
CHAR16 options[CMDLINE_MAXLEN]; CHAR16 options[CMDLINE_MAXLEN];
CHAR16 kname[FILENAME_MAXLEN]; CHAR16 kname[FILENAME_MAXLEN];
@ -46,9 +47,9 @@ display_label_info(CHAR16 *name)
Print(L"desc : %s\n", desc); 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); StrCpy(kname, name);
Print(L"\n"); Print(L"\n");
} }
@ -56,6 +57,7 @@ display_label_info(CHAR16 *name)
Print(L"cmdline: %s %s\n", kname, options); Print(L"cmdline: %s %s\n", kname, options);
if (initrd_name[0]) Print(L"initrd : %s\n", initrd_name); if (initrd_name[0]) Print(L"initrd : %s\n", initrd_name);
if (vmcode_name[0]) Print(L"vmcode : %s\n", vmcode_name);
} }
static VOID static VOID
@ -247,6 +249,7 @@ simple_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmdli
CHAR16 buffer[CMDLINE_MAXLEN]; CHAR16 buffer[CMDLINE_MAXLEN];
CHAR16 alt_buffer[CMDLINE_MAXLEN]; CHAR16 alt_buffer[CMDLINE_MAXLEN];
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[CMDLINE_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN];
CHAR16 args[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN];
CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 devname[CMDLINE_MAXLEN];
CHAR16 dpath[FILENAME_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN];
@ -259,7 +262,7 @@ simple_choose(CHAR16 **argv, INTN argc, INTN index, CHAR16 *kname, CHAR16 *cmdli
display_message(); display_message();
restart: 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 */ /* reset per image loader options */
Memset(&elilo_opt.img_opt, 0, sizeof(elilo_opt.img_opt)); 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 * if no match is found, the args and initrd arguments may
* still be modified by global options in the config file. * 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 found, so assume first argument is kernel name and
* not label name * not label name
*/ */
if (ret == -1) { if (ret == -1) {
if (argv[index]) if ((index < argc) && argv[index])
StrCpy(kname, argv[index]); StrCpy(kname, argv[index]);
else else
StrCpy(kname, elilo_opt.default_kernel); StrCpy(kname, elilo_opt.default_kernel);
@ -335,9 +338,14 @@ restart:
StrCpy(elilo_opt.initrd, initrd_name); 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); VERB_PRT(1, { Print(L"kernel is '%s'\n", kname);
Print(L"arguments are '%s'\n", args); Print(L"arguments are '%s'\n", args);
if (elilo_opt.initrd[0]) Print(L"initrd is '%s'\n", elilo_opt.initrd); 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) { if (elilo_opt.prompt == 0) {
@ -379,7 +387,8 @@ restart:
*/ */
len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */ len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */
+StrLen(devname) /* device name */ +StrLen(devname) /* device name */
+StrLen(kname) /* kernel name */ /* kernel name */
+elilo_opt.vmcode[0] ? StrLen(elilo_opt.vmcode) : StrLen(kname)
+1 /* space */ +1 /* space */
+StrLen(args); /* args length */ +StrLen(args); /* args length */
@ -389,6 +398,9 @@ restart:
} }
StrCpy(cmdline, L"BOOT_IMAGE="); StrCpy(cmdline, L"BOOT_IMAGE=");
StrCat(cmdline, devname); StrCat(cmdline, devname);
if (elilo_opt.vmcode[0])
StrCat(cmdline, elilo_opt.vmcode);
else
StrCat(cmdline, kname); StrCat(cmdline, kname);
StrCat(cmdline, L" "); StrCat(cmdline, L" ");
StrCat(cmdline, args); StrCat(cmdline, args);

View file

@ -28,7 +28,7 @@
#include "elilo.h" #include "elilo.h"
#define MAX_LABELS 16 #define MAX_LABELS 64
#define MSGBUFLEN 4096 #define MSGBUFLEN 4096
static UINT8 msgbuf[MSGBUFLEN]; 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=" # define BOOT_IMG_STR L"BOOT_IMAGE="
CHAR16 label[CMDLINE_MAXLEN]; CHAR16 label[CMDLINE_MAXLEN];
CHAR16 initrd_name[CMDLINE_MAXLEN]; CHAR16 initrd_name[CMDLINE_MAXLEN];
CHAR16 vmcode_name[CMDLINE_MAXLEN];
CHAR16 args[CMDLINE_MAXLEN]; CHAR16 args[CMDLINE_MAXLEN];
CHAR16 devname[CMDLINE_MAXLEN]; CHAR16 devname[CMDLINE_MAXLEN];
CHAR16 dpath[FILENAME_MAXLEN]; CHAR16 dpath[FILENAME_MAXLEN];
@ -412,16 +413,16 @@ restart:
* still be modified by global options in the config file. * still be modified by global options in the config file.
*/ */
if (label[0]) if (label[0])
ret = find_label(label, kname, args, initrd_name); ret = find_label(label, kname, args, initrd_name, vmcode_name);
else 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 found, so assume first argument is kernel name and
* not label name * not label name
*/ */
if (ret == -1) { if (ret == -1) {
if (argv[index]) if ((index < argc) && argv[index])
StrCpy(kname, argv[index]); StrCpy(kname, argv[index]);
else else
StrCpy(kname, elilo_opt.default_kernel); StrCpy(kname, elilo_opt.default_kernel);
@ -448,9 +449,14 @@ restart:
StrCpy(elilo_opt.initrd, initrd_name); 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); VERB_PRT(1, { Print(L"kernel is '%s'\n", kname);
Print(L"arguments are '%s'\n", args); Print(L"arguments are '%s'\n", args);
if (elilo_opt.initrd[0]) Print(L"initrd is '%s'\n", elilo_opt.initrd); 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) { if (elilo_opt.prompt == 0) {
@ -494,6 +500,7 @@ restart:
len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */ len = StrLen(BOOT_IMG_STR) /* BOOT_IMAGE= */
+StrLen(devname) /* device name */ +StrLen(devname) /* device name */
+StrLen(kname) /* kernel name */ +StrLen(kname) /* kernel name */
+elilo_opt.vmcode[0] ? StrLen(elilo_opt.vmcode) : StrLen(kname)
+1 /* space */ +1 /* space */
+StrLen(args); /* args length */ +StrLen(args); /* args length */
@ -505,6 +512,9 @@ restart:
} }
StrCpy(cmdline, L"BOOT_IMAGE="); StrCpy(cmdline, L"BOOT_IMAGE=");
StrCat(cmdline, devname); StrCat(cmdline, devname);
if (elilo_opt.vmcode[0])
StrCat(cmdline, elilo_opt.vmcode);
else
StrCat(cmdline, kname); StrCat(cmdline, kname);
StrCat(cmdline, L" "); StrCat(cmdline, L" ");
StrCat(cmdline, args); StrCat(cmdline, args);

View file

@ -68,6 +68,7 @@ typedef struct boot_image {
CHAR16 kname[FILENAME_MAXLEN]; CHAR16 kname[FILENAME_MAXLEN];
CHAR16 options[MAX_STRING]; CHAR16 options[MAX_STRING];
CHAR16 initrd[FILENAME_MAXLEN]; CHAR16 initrd[FILENAME_MAXLEN];
CHAR16 vmcode[FILENAME_MAXLEN];
CHAR16 root[FILENAME_MAXLEN]; CHAR16 root[FILENAME_MAXLEN];
CHAR16 fallback[MAX_STRING]; CHAR16 fallback[MAX_STRING];
CHAR16 description[MAX_STRING]; CHAR16 description[MAX_STRING];
@ -93,6 +94,7 @@ typedef enum {
typedef struct { typedef struct {
CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */ CHAR16 root[FILENAME_MAXLEN]; /* globally defined root fs */
CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */ CHAR16 initrd[FILENAME_MAXLEN];/* globally defined initrd */
CHAR16 vmcode[FILENAME_MAXLEN];/* globally defined boot-time module */
CHAR16 options[MAX_STRING]; CHAR16 options[MAX_STRING];
CHAR16 default_image_name[MAX_STRING]; CHAR16 default_image_name[MAX_STRING];
CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN]; CHAR16 message_file[MAX_MESSAGES][FILENAME_MAXLEN];
@ -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_BOOL, OPT_GLOBAL, L"noedd30", NULL, NULL, &global_config.edd30_no_force},
{OPT_CMD, OPT_GLOBAL, L"append", NULL, NULL, global_config.options}, {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"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_FILE, OPT_GLOBAL, L"image", do_image, NULL, opt_offsetof(kname)},
{OPT_BOOL, OPT_GLOBAL, L"checkalt", NULL, NULL, &global_config.alt_check}, {OPT_BOOL, OPT_GLOBAL, L"checkalt", NULL, NULL, &global_config.alt_check},
{OPT_STR, OPT_GLOBAL, L"chooser", NULL, check_chooser, global_config.chooser}, {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"append", do_options, NULL, opt_offsetof(options)},
{OPT_CMD, OPT_IMAGE, L"literal", do_literal, NULL, NULL}, {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"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_STR, OPT_IMAGE, L"label", NULL, NULL, opt_offsetof(label)},
{OPT_FILE, OPT_IMAGE, L"image", do_image, NULL, opt_offsetof(kname)}, {OPT_FILE, OPT_IMAGE, L"image", do_image, NULL, opt_offsetof(kname)},
{OPT_STR, OPT_IMAGE, L"description", NULL, NULL, opt_offsetof(description)}, {OPT_STR, OPT_IMAGE, L"description", NULL, NULL, opt_offsetof(description)},
@ -882,10 +886,10 @@ print_label_list(VOID)
{ {
boot_image_t *img, *dfl = global_config.default_image; boot_image_t *img, *dfl = global_config.default_image;
if (dfl) Print(L"%s ", dfl->label); if (dfl) Print(L"\t%s\n", dfl->label);
for (img = image_list; img; img = img->next) { for (img = image_list; img; img = img->next) {
if (img != dfl) Print(L"%s ", img->label); if (img != dfl) Print(L"\t%s\n", img->label);
} }
} }
@ -933,7 +937,7 @@ find_description(CHAR16 *label)
} }
INTN 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; boot_image_t *img;
@ -966,6 +970,7 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd)
if (global_config.readonly) StrCat(options, L" ro"); if (global_config.readonly) StrCat(options, L" ro");
if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd); 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 */ /* make sure we don't get garbage here */
elilo_opt.sys_img_opts = NULL; elilo_opt.sys_img_opts = NULL;
@ -1003,12 +1008,17 @@ found:
else if (global_config.initrd[0]) else if (global_config.initrd[0])
StrCpy(initrd, global_config.initrd); 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 * point to architecture dependent options for this image
*/ */
elilo_opt.sys_img_opts = &img->sys_img_opts; 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; return 0;
} }

Binary file not shown.

Binary file not shown.

101
elilo.c
View file

@ -34,6 +34,7 @@
#include "elilo.h" #include "elilo.h"
#include "vars.h" #include "vars.h"
#include "gzip.h"
#include "getopt.h" #include "getopt.h"
#include "fileops.h" #include "fileops.h"
@ -84,13 +85,23 @@ do_kernel_load(CHAR16 *kname, kdesc_t *kd)
} }
INTN 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 ! * Now let's try to load the kernel !
*/ */
switch(do_kernel_load(kname, kd)) { switch(do_kernel_load(kernel, kd)) {
case ELILO_LOAD_SUCCESS: case ELILO_LOAD_SUCCESS:
break; break;
@ -101,6 +112,7 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem)
case ELILO_LOAD_ABORTED: case ELILO_LOAD_ABORTED:
/* we drop initrd in case we aborted the load */ /* we drop initrd in case we aborted the load */
elilo_opt.initrd[0] = CHAR_NULL; elilo_opt.initrd[0] = CHAR_NULL;
elilo_opt.vmcode[0] = CHAR_NULL;
/* will go back to interactive selection */ /* will go back to interactive selection */
elilo_opt.prompt = 1; elilo_opt.prompt = 1;
@ -111,22 +123,63 @@ 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", 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 (elilo_opt.initrd[0]) {
if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error; 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: case ELILO_LOAD_SUCCESS:
break; break;
case ELILO_LOAD_ERROR: case ELILO_LOAD_ERROR:
goto exit_error; goto exit_error;
case ELILO_LOAD_ABORTED: case ELILO_LOAD_ABORTED:
/* the free_kmem() is the responsibility of the loader */ free_kmem();
/* we drop initrd in case we aborted the load */ /* we drop initrd in case we aborted the load */
elilo_opt.initrd[0] = CHAR_NULL; 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.prompt = 1;
elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT; elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT;
elilo_opt.delay = 0; elilo_opt.delay = 0;
@ -138,6 +191,7 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem)
exit_error: exit_error:
free_kmem(); free_kmem();
if (imem->start_addr) free(imem->start_addr); if (imem->start_addr) free(imem->start_addr);
if (mmem->start_addr) free(mmem->start_addr);
return ELILO_LOAD_ERROR; return ELILO_LOAD_ERROR;
} }
@ -152,7 +206,7 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image
UINTN cookie; UINTN cookie;
EFI_STATUS status = EFI_SUCCESS; EFI_STATUS status = EFI_SUCCESS;
kdesc_t kd; kdesc_t kd;
memdesc_t imem; memdesc_t imem, mmem;
INTN r; INTN r;
/* /*
@ -164,12 +218,12 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image
for(;;) { for(;;) {
kname[0] = cmdline_tmp[0] = cmdline[0] = CHAR_NULL; 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; elilo_opt.sys_img_opts = NULL;
if (kernel_chooser(argv, argc, index, kname, cmdline_tmp) == -1) goto exit_error; 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: case ELILO_LOAD_SUCCESS:
goto do_launch; goto do_launch;
case ELILO_LOAD_ERROR: case ELILO_LOAD_ERROR:
@ -187,7 +241,7 @@ do_launch:
close_devices(); close_devices();
/* No console output permitted after create_boot_params()! */ /* 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 */ /* terminate bootservices */
status = BS->ExitBootServices(image, cookie); status = BS->ExitBootServices(image, cookie);
@ -221,6 +275,7 @@ elilo_help(VOID)
Print(L"-v verbose level(can appear multiple times)\n"); Print(L"-v verbose level(can appear multiple times)\n");
Print(L"-a always check for alternate kernel image\n"); Print(L"-a always check for alternate kernel image\n");
Print(L"-i file load file as the initial ramdisk\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"-C file indicate the config file to use\n");
Print(L"-P parse config file only (verify syntax)\n"); Print(L"-P parse config file only (verify syntax)\n");
Print(L"-D enable debug prints\n"); Print(L"-D enable debug prints\n");
@ -491,6 +546,13 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
} }
StrCpy(elilo_opt.initrd, Optarg); StrCpy(elilo_opt.initrd, Optarg);
break; 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': case 'C':
if (StrLen(Optarg) >= FILENAME_MAXLEN-1) { if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
Print(L"config filename is limited to %d characters\n", FILENAME_MAXLEN); Print(L"config filename is limited to %d characters\n", FILENAME_MAXLEN);
@ -608,10 +670,18 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
* we force interactive mode to give a chance to the user. * we force interactive mode to give a chance to the user.
* We also clear the error. * We also clear the error.
*/ */
if (ret && argc == 1) { if (ret != EFI_SUCCESS) {
Print(L"forcing interactive mode because of errors\n"); Print(L"forcing interactive mode due to config file error(s)\n");
elilo_opt.prompt = 1; 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 * If EDD30 EFI variable was not set to TRUE (or not defined), we
@ -627,13 +697,6 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
ret = EFI_LOAD_ERROR; 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 */ /* set default timeout if going interactive */

10
elilo.h
View file

@ -81,6 +81,7 @@ typedef struct {
UINTN delay; /* delay before booting the image */ UINTN delay; /* delay before booting the image */
UINTN verbose; /* verbosity level [1-5] */ UINTN verbose; /* verbosity level [1-5] */
CHAR16 initrd[FILENAME_MAXLEN]; /* name of file for initial ramdisk */ 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 delay_set; /* mark whether or not delay was specified on cmdline */
UINT8 edd30_on; /* true is EDD30 variable is TRUE */ UINT8 edd30_on; /* true is EDD30 variable is TRUE */
UINT8 edd30_no_force; /* don't force EDD30 variable to true */ UINT8 edd30_no_force; /* don't force EDD30 variable to true */
@ -112,6 +113,7 @@ extern EFI_SYSTEM_TABLE *systab;
typedef struct { typedef struct {
VOID *start_addr; VOID *start_addr;
UINTN pgcnt; UINTN pgcnt;
UINTN size;
} memdesc_t; } memdesc_t;
typedef struct { typedef struct {
@ -169,7 +171,7 @@ extern VOID U2ascii(CHAR16 *, CHAR8 *, UINTN);
/* from config.c (more in config.h) */ /* from config.c (more in config.h) */
extern EFI_STATUS read_config(CHAR16 *); extern EFI_STATUS read_config(CHAR16 *);
extern VOID print_config_options(VOID); 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 VOID print_label_list(VOID);
extern INTN config_init(VOID); extern INTN config_init(VOID);
extern CHAR16 *get_message_filename(INTN which); extern CHAR16 *get_message_filename(INTN which);
@ -178,13 +180,13 @@ extern VOID *get_next_description(VOID *prev, CHAR16 **label, CHAR16 **descripti
extern CHAR16 *get_config_file(VOID); extern CHAR16 *get_config_file(VOID);
/* from initrd.c */ /* from initrd.c */
extern INTN load_initrd(CHAR16 *, memdesc_t *); extern INTN load_file(CHAR16 *, memdesc_t *);
/* from alternate.c */ /* from alternate.c */
extern INTN alternate_kernel(CHAR16 *, INTN); extern INTN alternate_kernel(CHAR16 *, INTN);
/* from bootparams.c */ /* 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); extern VOID free_boot_params(VOID *bp);
/* /*
@ -192,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 VOID sysdeps_free_boot_params(boot_params_t *);
extern INTN sysdeps_init(EFI_HANDLE dev); extern INTN sysdeps_init(EFI_HANDLE dev);
extern INTN sysdeps_initrd_get_addr(kdesc_t *, memdesc_t *); extern INTN sysdeps_initrd_get_addr(kdesc_t *, memdesc_t *);

View file

@ -391,22 +391,22 @@ fops_setdefaults(struct config_file *defconf, CHAR16 *kname, UINTN maxlen, CHAR1
boot_dev->fops->setdefaults(boot_dev->fops->intf, defconf, kname, maxlen, devpath); boot_dev->fops->setdefaults(boot_dev->fops->intf, defconf, kname, maxlen, devpath);
} }
i=0; while (i<MAX_DEFAULT_CONFIGS && defconf[i].fname[0] != CHAR_NULL) i += 1; i=0; while (i<MAX_DEFAULT_CONFIGS && defconf[i].fname[0] != CHAR_NULL) i += 1;
//#ifdef ELILO_DEBUG #ifdef ELILO_DEBUG
if ((i+3) >= MAX_DEFAULT_CONFIGS) { if ((i+3) >= MAX_DEFAULT_CONFIGS) {
Print(L"ERROR: i = %d, MAX_DEFAULT_CONFIGS is not large enough\n", i); Print(L"ERROR: i = %d, MAX_DEFAULT_CONFIGS is not large enough\n", i);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
//#endif #endif
StrnCpy(defconf[i].fname, FILEOPS_ARCH_DEFAULT_CONFIG, maxlen-1); StrnCpy(defconf[i].fname, FILEOPS_ARCH_DEFAULT_CONFIG, maxlen-1);
StrnCpy(defconf[i+1].fname, FILEOPS_DEFAULT_CONFIG, maxlen-1); StrnCpy(defconf[i+1].fname, FILEOPS_DEFAULT_CONFIG, maxlen-1);
//#ifdef ELILO_DEBUG #ifdef ELILO_DEBUG
VERB_PRT(3,Print(L"Default config filename list:\n")); VERB_PRT(3,Print(L"Default config filename list:\n"));
for (i=0; i<MAX_DEFAULT_CONFIGS; i++) { for (i=0; i<MAX_DEFAULT_CONFIGS; i++) {
if (defconf[i].fname[0] == CHAR_NULL) { break; } if (defconf[i].fname[0] == CHAR_NULL) { break; }
VERB_PRT(3,Print(L"\t%s\n", defconf[i].fname)); VERB_PRT(3,Print(L"\t%s\n", defconf[i].fname));
} }
//#endif #endif
return EFI_SUCCESS; return EFI_SUCCESS;
} }

224
gunzip.c Normal file
View file

@ -0,0 +1,224 @@
/*
* Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
* Contributed by Alex Williamson <alex.williamson@hp.com>
*
* Copyright (C) 2001-2003 Hewlett-Packard Co.
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
*
* Copyright (C) 2001 Silicon Graphics, Inc.
* Contributed by Brent Casavant <bcasavan@sgi.com>
*
* 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 <efi.h>
#include <efilib.h>
#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;
}

View file

@ -26,10 +26,42 @@
#ifndef __GZIP_H__ #ifndef __GZIP_H__
#define __GZIP_H__ #define __GZIP_H__
int gunzip_image(memdesc_t *);
int gzip_probe(unsigned char *, unsigned long);
int gunzip_kernel(fops_fd_t, kdesc_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__ */ #endif /* __GZIP_H__ */

View file

@ -34,6 +34,8 @@
#include "gzip.h" #include "gzip.h"
#include "private.h" #include "private.h"
#define LD_NAME L"gzip_ia32"
#define memzero(s, n) Memset((VOID *)(s), 0, (n)) #define memzero(s, n) Memset((VOID *)(s), 0, (n))
#define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(n)) #define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(n))

View file

@ -1,35 +0,0 @@
/*
* Copyright (C) 2001-2002 Hewlett-Packard Co.
* Contributed by Stephane Eranian <eranian@hpl.hp.com>
*
* 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.
*/
#ifndef __GZIP_H__
#define __GZIP_H__
int gzip_probe(unsigned char *, unsigned long);
int gunzip_kernel(fops_fd_t, kdesc_t *);
#define LD_NAME L"gzip_ia32"
#endif /* __GZIP_H__ */

View file

@ -30,6 +30,8 @@
#include "loader.h" #include "loader.h"
#include "gzip.h" #include "gzip.h"
#define LD_NAME L"gzip_ia32"
static INTN static INTN
gzip_probe_format(CHAR16 *kname) gzip_probe_format(CHAR16 *kname)
{ {

File diff suppressed because it is too large Load diff

View file

@ -164,6 +164,7 @@ sysdeps_create_boot_params(
boot_params_t *bp, boot_params_t *bp,
CHAR8 *cmdline, CHAR8 *cmdline,
memdesc_t *initrd, memdesc_t *initrd,
memdesc_t *vmcode, /* no use for ia32 now*/
UINTN *cookie) UINTN *cookie)
{ {
mmap_desc_t mdesc; mmap_desc_t mdesc;
@ -270,7 +271,7 @@ sysdeps_create_boot_params(
if (initrd->start_addr && initrd->pgcnt) { if (initrd->start_addr && initrd->pgcnt) {
/* %%TBD - This will probably have to be changed. */ /* %%TBD - This will probably have to be changed. */
bp->s.initrd_start = (UINT32)initrd->start_addr; 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 * This is the RAMdisk root device for RedHat 2.2.x

View file

@ -37,6 +37,8 @@
#include "private.h" #include "private.h"
#include "setjmp.h" #include "setjmp.h"
#define LD_NAME L"gzip_ia64"
#define memzero(s, n) Memset((VOID *)(s), 0, (n)) #define memzero(s, n) Memset((VOID *)(s), 0, (n))
#define memcpy(a,b,n) Memcpy((VOID *)(a),(b),(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_VALID 0x1
#define CHUNK_FL_LOAD 0x2 #define CHUNK_FL_LOAD 0x2
#define CHUNK_FL_X 0x4
#define CHUNK_CAN_LOAD(n) chunks[(n)].flags |= CHUNK_FL_LOAD #define CHUNK_CAN_LOAD(n) chunks[(n)].flags |= CHUNK_FL_LOAD
#define CHUNK_NO_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; continue;
} }
if (bswap32(phdrs[i].p_flags) & PF_X)
chunks[i].flags |= CHUNK_FL_X;
CHUNK_CAN_LOAD(i); /* mark no load chunk */ CHUNK_CAN_LOAD(i); /* mark no load chunk */
VERB_PRT(3, VERB_PRT(3,
@ -433,7 +439,7 @@ first_block (const char *buf, long blocksize)
if (alloc_kmem((void *)low_addr, pages) == -1) { if (alloc_kmem((void *)low_addr, pages) == -1) {
VOID *new_addr; 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) { if (ia64_can_relocate() == 0) {
ERR_PRT((L"relocation is disabled, cannot load kernel")); ERR_PRT((L"relocation is disabled, cannot load kernel"));
@ -458,7 +464,7 @@ first_block (const char *buf, long blocksize)
/* unsigned arithmetic */ /* unsigned arithmetic */
load_offset = (UINTN) (new_addr - ROUNDDOWN((UINTN) low_addr,256*MB)); 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 * correct various addresses for non-zero load_offset
@ -566,6 +572,8 @@ tail:
if (cnt > outcnt) cnt = outcnt; if (cnt > outcnt) cnt = outcnt;
Memcpy(dst, src, cnt); Memcpy(dst, src, cnt);
if (cp->flags & CHUNK_FL_X)
flush_dcache (dst, cnt);
file_offset += cnt; file_offset += cnt;
outcnt -= cnt; outcnt -= cnt;

View file

@ -30,6 +30,8 @@
#include "loader.h" #include "loader.h"
#include "gzip.h" #include "gzip.h"
#define LD_NAME L"gzip_ia64"
static INTN static INTN
gzip_probe_format(CHAR16 *kname) gzip_probe_format(CHAR16 *kname)
{ {

View file

@ -288,7 +288,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
if (alloc_kmem(low_addr, pages) == -1) { if (alloc_kmem(low_addr, pages) == -1) {
VOID *new_addr; 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) { if (ia64_can_relocate() == 0) {
ERR_PRT((L"relocation is disabled, cannot load kernel")); 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); ret = read_file(fd, filesz, (CHAR8 *)phdrs[i].p_paddr);
if (ret == ELILO_LOAD_ABORTED) goto load_abort; if (ret == ELILO_LOAD_ABORTED) goto load_abort;
if (ret == ELILO_LOAD_ERROR) goto out; 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 * update file position

View file

@ -31,5 +31,7 @@ extern INTN query_fpswa(VOID **);
extern INTN ia64_can_relocate(); extern INTN ia64_can_relocate();
extern void flush_dcache (CHAR8 *addr, UINT64 len);
#endif /* __ELILO_PRIVATE_IA64_H__ */ #endif /* __ELILO_PRIVATE_IA64_H__ */

View file

@ -78,6 +78,7 @@ setjmp:
/* __sigsetjmp(__jmp_buf buf, int savemask) */ /* __sigsetjmp(__jmp_buf buf, int savemask) */
.proc __sigsetjmp
__sigsetjmp: __sigsetjmp:
//.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) //.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
alloc loc1=ar.pfs,2,2,2,0 alloc loc1=ar.pfs,2,2,2,0

View file

@ -65,8 +65,11 @@ typedef struct ia64_boot_params {
UINTN initrd_start; /* virtual address where the initial ramdisk begins */ UINTN initrd_start; /* virtual address where the initial ramdisk begins */
UINTN initrd_size; /* how big is the initial ramdisk */ 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_addr; /* start address of boot loader */
UINTN loader_size; /* size of loader code & data */ UINTN loader_size; /* size of loader code & data */
} boot_params_t; } boot_params_t;
typedef struct sys_img_options { typedef struct sys_img_options {

View file

@ -39,7 +39,7 @@ extern loader_ops_t plain_loader, gzip_loader;
* IA-64 specific boot paramters initialization routine * IA-64 specific boot paramters initialization routine
*/ */
INTN 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; UINTN cols, rows;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout; 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->efi_memdesc_version = mdesc.desc_version;
bp->command_line = (UINTN)cmdline; bp->command_line = (UINTN)cmdline;
bp->initrd_start = (UINTN) initrd->start_addr; 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: */ /* fetch console parameters: */
conout = systab->ConOut; conout = systab->ConOut;
@ -135,3 +140,20 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
return 0; 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));
}

View file

@ -1053,42 +1053,6 @@ makecrc(void)
crc = (ulg)0xffffffffUL; /* shift register contents */ 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! * Do the uncompression!
*/ */

View file

@ -29,7 +29,7 @@
#include "elilo.h" #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: * OUTPUTS:
* - ELILO_LOAD_SUCCESS: if everything works * - ELILO_LOAD_SUCCESS: if everything works
* - ELILO_LOAD_ABORTED: in case the user decided to abort loading * - ELILO_LOAD_ABORTED: in case the user decided to abort loading
@ -38,12 +38,12 @@
* Adapted from Bill Nottingham <notting@redhat.com> patch for ELI. * Adapted from Bill Nottingham <notting@redhat.com> patch for ELI.
*/ */
INTN INTN
load_initrd(CHAR16 *filename, memdesc_t *initrd) load_file(CHAR16 *filename, memdesc_t *image)
{ {
EFI_STATUS status; EFI_STATUS status;
VOID *start_addr = initrd->start_addr; VOID *start_addr = image->start_addr;
UINT64 size = 0;
UINTN pgcnt; UINTN pgcnt;
UINT64 size = 0;
fops_fd_t fd; fops_fd_t fd;
INTN ret = ELILO_LOAD_ERROR; INTN ret = ELILO_LOAD_ERROR;
@ -53,46 +53,48 @@ load_initrd(CHAR16 *filename, memdesc_t *initrd)
/* Open the file */ /* Open the file */
status = fops_open(filename, &fd); status = fops_open(filename, &fd);
if (EFI_ERROR(status)) { 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; return -1;
} }
DBG_PRT((L"initrd_open %s worked", filename)); DBG_PRT((L"open %s worked", filename));
/* warning: this function allocates memory */ /* warning: this function allocates memory */
status = fops_infosize(fd, &size); status = fops_infosize(fd, &size);
if (EFI_ERROR(status)) { 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; goto error;
} }
image->size = size;
/* round up to get required number of pages (4KB) */ /* round up to get required number of pages (4KB) */
initrd->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(size); image->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(image->size);
start_addr = alloc_pages(pgcnt, EfiLoaderData, start_addr ? AllocateAddress : AllocateAnyPages, start_addr); start_addr = alloc_pages(pgcnt, EfiLoaderData, start_addr ? AllocateAddress : AllocateAnyPages, start_addr);
if (start_addr == NULL) { 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; goto error;
} }
VERB_PRT(2, Print(L"initrd: total_size: %ld bytes base: 0x%lx pages %d\n", VERB_PRT(2, Print(L"%s image: total_size: %ld bytes base: 0x%lx "
size, (UINT64)start_addr, pgcnt)); "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); fops_close(fd);
if (ret != ELILO_LOAD_SUCCESS) { 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; goto error;
} }
Print(L"done\n"); Print(L"done\n");
initrd->start_addr = start_addr; image->start_addr = start_addr;
return ELILO_LOAD_SUCCESS; return ELILO_LOAD_SUCCESS;
@ -103,8 +105,9 @@ error:
* make sure nothing is passed to kernel * make sure nothing is passed to kernel
* in case of error. * in case of error.
*/ */
initrd->start_addr = 0; image->start_addr = 0;
initrd->pgcnt = 0; image->pgcnt = 0;
image->size = 0;
return ret; return ret;
} }