release 3.5-pre2
https://sourceforge.net/projects/elilo/files/elilo/elilo-3.5pre2/
This commit is contained in:
parent
cb533a5de5
commit
6a4d7e49dc
29 changed files with 523 additions and 1389 deletions
35
ChangeLog
35
ChangeLog
|
@ -1,11 +1,34 @@
|
|||
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>
|
||||
* 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.
|
||||
* 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 <brett@hp.com>
|
||||
* integrated ia32 compressed kernel support from Matt Tolentino
|
||||
<matthew.e.tolentino@intel.com>
|
||||
<matthew.e.tolentino@intel.com>
|
||||
2003-08-20 Stephane Eranian <eranian@hpl.hp.com>
|
||||
* released 3.4
|
||||
2003-08-19 Stephane Eranian <eranian@hpl.hp.com>
|
||||
|
@ -93,7 +116,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 <eranian@hpl.hp.com>
|
||||
* added a Linux utility program (elilovar in tools) to set/read/delete
|
||||
the EliloAlt EFI variable used to specify an alternate kernel to boot.
|
||||
|
|
|
@ -95,38 +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'.')
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
# EFI specs allows only lower floating point partition to be used
|
||||
CFLAGS += -mfixed-range=f32-f127
|
||||
endif
|
||||
|
|
2
Makefile
2
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 \
|
||||
|
|
4
alloc.c
4
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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
@ -379,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 */
|
||||
|
||||
|
@ -389,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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
@ -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) {
|
||||
|
@ -494,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 */
|
||||
|
||||
|
@ -505,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);
|
||||
|
||||
|
|
18
config.c
18
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)},
|
||||
|
@ -882,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -933,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;
|
||||
|
||||
|
@ -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.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;
|
||||
|
@ -1003,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;
|
||||
}
|
||||
|
|
BIN
elilo-ia32.efi
BIN
elilo-ia32.efi
Binary file not shown.
BIN
elilo-ia64.efi
BIN
elilo-ia64.efi
Binary file not shown.
103
elilo.c
103
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,22 +123,22 @@ 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;
|
||||
|
@ -134,10 +146,52 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem)
|
|||
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");
|
||||
|
@ -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);
|
||||
|
@ -607,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
|
||||
|
@ -627,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 */
|
||||
|
|
10
elilo.h
10
elilo.h
|
@ -81,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 */
|
||||
|
@ -112,6 +113,7 @@ extern EFI_SYSTEM_TABLE *systab;
|
|||
typedef struct {
|
||||
VOID *start_addr;
|
||||
UINTN pgcnt;
|
||||
UINTN size;
|
||||
} memdesc_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -169,7 +171,7 @@ extern VOID U2ascii(CHAR16 *, CHAR8 *, UINTN);
|
|||
/* from config.c (more in config.h) */
|
||||
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);
|
||||
|
@ -178,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);
|
||||
|
||||
/*
|
||||
|
@ -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 INTN sysdeps_init(EFI_HANDLE dev);
|
||||
extern INTN sysdeps_initrd_get_addr(kdesc_t *, memdesc_t *);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
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) {
|
||||
Print(L"ERROR: i = %d, MAX_DEFAULT_CONFIGS is not large enough\n", i);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
//#endif
|
||||
#endif
|
||||
StrnCpy(defconf[i].fname, FILEOPS_ARCH_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"));
|
||||
for (i=0; i<MAX_DEFAULT_CONFIGS; i++) {
|
||||
if (defconf[i].fname[0] == CHAR_NULL) { break; }
|
||||
VERB_PRT(3,Print(L"\t%s\n", defconf[i].fname));
|
||||
}
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
224
gunzip.c
Normal file
224
gunzip.c
Normal 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;
|
||||
}
|
|
@ -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__ */
|
|
@ -34,6 +34,8 @@
|
|||
#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))
|
||||
|
||||
|
|
35
ia32/gzip.h
35
ia32/gzip.h
|
@ -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__ */
|
|
@ -30,6 +30,8 @@
|
|||
#include "loader.h"
|
||||
#include "gzip.h"
|
||||
|
||||
#define LD_NAME L"gzip_ia32"
|
||||
|
||||
static INTN
|
||||
gzip_probe_format(CHAR16 *kname)
|
||||
{
|
||||
|
|
1205
ia32/inflate.c
1205
ia32/inflate.c
File diff suppressed because it is too large
Load diff
|
@ -164,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;
|
||||
|
@ -270,7 +271,7 @@ 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
|
||||
|
|
12
ia64/gzip.c
12
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;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "loader.h"
|
||||
#include "gzip.h"
|
||||
|
||||
#define LD_NAME L"gzip_ia64"
|
||||
|
||||
static INTN
|
||||
gzip_probe_format(CHAR16 *kname)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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!
|
||||
*/
|
41
initrd.c
41
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 <notting@redhat.com> 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;
|
||||
}
|
||||
|
||||
image->size = size;
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue