release 3.10
https://sourceforge.net/projects/elilo/files/elilo/elilo-3.10/ (sans a few CVS directories)
This commit is contained in:
parent
34d8003a54
commit
4e87874a03
35 changed files with 412 additions and 235 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2008-04-02 signed off by Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* elilo 3.10 release commit
|
||||||
|
* Bumped version string to 3.10
|
||||||
|
* added PTR_FMT 32bit & 64bit pointer translation for correct output
|
||||||
|
* elilo hang bugfix x86_64 non-standard kernels with non-traditional start address
|
||||||
|
elilo will pull the start address from the kernel elf header for 2.6
|
||||||
|
or newer kernels, map memory and use that start address, else use standard
|
||||||
|
1MB default start address. And handle case of overlapping kernels
|
||||||
|
and initrds in memory. Patch contributor Stuart Hayes @ Dell,
|
||||||
|
thanks Stuart!
|
||||||
|
* ported kernel start adress fix to ia32
|
||||||
|
* eliminated all possible compiler warnings except those actually
|
||||||
|
caused by gnu-efi that cant be fixed here.
|
||||||
|
* Debug output improvement, added pauses with visual feedback when
|
||||||
|
user sets debug & verbose options.
|
||||||
|
* bugfix added missing find_bits function definition back into ia32
|
||||||
|
subtree
|
||||||
|
* bugfix loader_probe now correctly errors out if no loaders
|
||||||
|
registered.
|
||||||
|
2008-01-11 signed off by Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* Various compile warning cleanups.
|
||||||
2008-01-03 signed off by Jason Fleischli <jason.fleischli@hp.com>
|
2008-01-03 signed off by Jason Fleischli <jason.fleischli@hp.com>
|
||||||
* Patch contribution from Scott Davilla <davilla@4pi.com>
|
* Patch contribution from Scott Davilla <davilla@4pi.com>
|
||||||
when x is zero for the first call to add_memory_region, e820_map[-1]
|
when x is zero for the first call to add_memory_region, e820_map[-1]
|
||||||
|
|
|
@ -68,7 +68,7 @@ CPPFLAGS = -DCONFIG_$(ARCH)
|
||||||
|
|
||||||
OPTIMFLAGS = -O2
|
OPTIMFLAGS = -O2
|
||||||
DEBUGFLAGS = -Wall
|
DEBUGFLAGS = -Wall
|
||||||
CFLAGS = $(OPTIMFLAGS) -fpic -fshort-wchar $(DEBUGFLAGS)
|
CFLAGS = $(OPTIMFLAGS) -fno-strict-aliasing -fpic -fshort-wchar $(DEBUGFLAGS)
|
||||||
LDFLAGS = -nostdlib -znocombreloc
|
LDFLAGS = -nostdlib -znocombreloc
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
|
|
||||||
|
|
27
alloc.c
27
alloc.c
|
@ -105,12 +105,12 @@ alloc(UINTN size, EFI_MEMORY_TYPE type)
|
||||||
|
|
||||||
status = uefi_call_wrapper(BS->AllocatePool, 3, type, size, &tmp);
|
status = uefi_call_wrapper(BS->AllocatePool, 3, type, size, &tmp);
|
||||||
if (EFI_ERROR(status)) {
|
if (EFI_ERROR(status)) {
|
||||||
ERR_PRT((L"allocator: AllocatePool(%d, %d, 0x%x) failed (%r)\n", type, size, status));
|
ERR_PRT((L"allocator: AllocatePool(%d, %d) failed (%r)\n", type, size, status));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
alloc_add(tmp, size, ALLOC_POOL);
|
alloc_add(tmp, size, ALLOC_POOL);
|
||||||
|
|
||||||
DBG_PRT((L"alloc: allocated %d bytes @[0x%lx-0x%lx]\n", size, tmp, tmp+size));
|
DBG_PRT((L"alloc: allocated %d bytes @[" PTR_FMT "-" PTR_FMT "]\n", size, tmp, tmp+size));
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -158,10 +158,10 @@ free(VOID *addr)
|
||||||
if (p->addr == addr) goto found;
|
if (p->addr == addr) goto found;
|
||||||
}
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
VERB_PRT(1, Print(L"allocator: invalid free @ 0x%lx\n", addr));
|
VERB_PRT(1, Print(L"allocator: invalid free @ " PTR_FMT "\n", addr));
|
||||||
return;
|
return;
|
||||||
found:
|
found:
|
||||||
DBG_PRT((L"free: %s @0x%lx size=%ld\n",
|
DBG_PRT((L"free: %s @" PTR_FMT " size=%d\n",
|
||||||
p->type == ALLOC_POOL ? L"Pool": L"Page",
|
p->type == ALLOC_POOL ? L"Pool": L"Page",
|
||||||
addr, p->size));
|
addr, p->size));
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ free_all(VOID)
|
||||||
|
|
||||||
while(used_allocs) {
|
while(used_allocs) {
|
||||||
|
|
||||||
DBG_PRT((L"free_all %a @ 0x%lx\n", used_allocs->type == ALLOC_POOL ? "pool" : "pages", used_allocs->addr));
|
DBG_PRT((L"free_all %a @ " PTR_FMT "\n", used_allocs->type == ALLOC_POOL ? "pool" : "pages", used_allocs->addr));
|
||||||
|
|
||||||
if (used_allocs->type == ALLOC_POOL)
|
if (used_allocs->type == ALLOC_POOL)
|
||||||
uefi_call_wrapper(BS->FreePool, 1, used_allocs->addr);
|
uefi_call_wrapper(BS->FreePool, 1, used_allocs->addr);
|
||||||
|
@ -212,6 +212,19 @@ free_all(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTN
|
||||||
|
alloc_kmem_anywhere(VOID **start_addr, UINTN pgcnt)
|
||||||
|
{
|
||||||
|
void * tmp;
|
||||||
|
if ((tmp = alloc_pages(pgcnt, EfiLoaderData, AllocateAnyPages, *start_addr)) == 0) return -1;
|
||||||
|
|
||||||
|
kmem_addr = tmp;
|
||||||
|
kmem_pgcnt = pgcnt;
|
||||||
|
*start_addr = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
INTN
|
INTN
|
||||||
alloc_kmem(VOID *start_addr, UINTN pgcnt)
|
alloc_kmem(VOID *start_addr, UINTN pgcnt)
|
||||||
{
|
{
|
||||||
|
@ -226,13 +239,13 @@ alloc_kmem(VOID *start_addr, UINTN pgcnt)
|
||||||
VOID
|
VOID
|
||||||
free_kmem(VOID)
|
free_kmem(VOID)
|
||||||
{
|
{
|
||||||
DBG_PRT((L"free_kmem before (%lx, %ld)\n", kmem_addr, kmem_pgcnt));
|
DBG_PRT((L"free_kmem before (" PTR_FMT ", %d)\n", kmem_addr, kmem_pgcnt));
|
||||||
if (kmem_addr && kmem_pgcnt != 0) {
|
if (kmem_addr && kmem_pgcnt != 0) {
|
||||||
free(kmem_addr);
|
free(kmem_addr);
|
||||||
kmem_addr = NULL;
|
kmem_addr = NULL;
|
||||||
kmem_pgcnt = 0;
|
kmem_pgcnt = 0;
|
||||||
}
|
}
|
||||||
DBG_PRT((L"free_kmem after (%lx, %ld)\n", kmem_addr, kmem_pgcnt));
|
DBG_PRT((L"free_kmem after (" PTR_FMT ", %d)\n", kmem_addr, kmem_pgcnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -56,7 +56,7 @@ static EFI_GUID altk_guid={0,};
|
||||||
* Please note that no fatal error is reported by this function
|
* Please note that no fatal error is reported by this function
|
||||||
*/
|
*/
|
||||||
INTN
|
INTN
|
||||||
alternate_kernel(CHAR16 *buffer, INTN size)
|
alternate_kernel(CHAR16 *buffer, UINTN size)
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
INTN ret = -1;
|
INTN ret = -1;
|
||||||
|
|
|
@ -78,7 +78,7 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, memdesc_t *vmcode, UINTN *co
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"boot params @ 0x%lx\n", bp));
|
VERB_PRT(3, Print(L"boot params @ " PTR_FMT "\n", bp));
|
||||||
|
|
||||||
/* XXX: need to fix this for 3.5 */
|
/* XXX: need to fix this for 3.5 */
|
||||||
#ifdef CONFIG_ia64
|
#ifdef CONFIG_ia64
|
||||||
|
|
|
@ -220,7 +220,7 @@ display_message(VOID)
|
||||||
{
|
{
|
||||||
fops_fd_t fd;
|
fops_fd_t fd;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
INTN len, i;
|
UINTN len, i;
|
||||||
CHAR16 *filename;
|
CHAR16 *filename;
|
||||||
CHAR8 buf[256];
|
CHAR8 buf[256];
|
||||||
|
|
||||||
|
|
|
@ -186,12 +186,12 @@ paint_menu(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
static INTN
|
static INTN
|
||||||
read_message_file(INTN msg, INT8 *buf, INTN max)
|
read_message_file(INTN msg, UINT8 *buf, UINTN max)
|
||||||
{
|
{
|
||||||
CHAR16 *filename;
|
CHAR16 *filename;
|
||||||
fops_fd_t message_fd;
|
fops_fd_t message_fd;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
INTN len = max;
|
UINTN len = max;
|
||||||
|
|
||||||
if (msg > 10) return 0;
|
if (msg > 10) 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.
BIN
elilo-x86_64.efi
BIN
elilo-x86_64.efi
Binary file not shown.
16
elilo.c
16
elilo.c
|
@ -46,13 +46,15 @@
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "config.h" /* for config_init() */
|
#include "config.h" /* for config_init() */
|
||||||
|
|
||||||
#define ELILO_VERSION L"3.8"
|
#define ELILO_VERSION L"3.10"
|
||||||
#define ELILO_SHARED_CMDLINE_OPTS L"pPMC:aDhd:i:vVc:E"
|
#define ELILO_SHARED_CMDLINE_OPTS L"pPMC:aDhd:i:vVc:E"
|
||||||
|
|
||||||
elilo_config_t elilo_opt;
|
elilo_config_t elilo_opt;
|
||||||
|
|
||||||
EFI_SYSTEM_TABLE *systab; /* pointer to EFI system table */
|
EFI_SYSTEM_TABLE *systab; /* pointer to EFI system table */
|
||||||
|
|
||||||
|
extern INTN wait_timeout (UINTN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Load the Linux kernel in memory from the boot media
|
* Load the Linux kernel in memory from the boot media
|
||||||
* Output:
|
* Output:
|
||||||
|
@ -127,11 +129,12 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memde
|
||||||
return ELILO_LOAD_RETRY;
|
return ELILO_LOAD_RETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n",
|
VERB_PRT(3, Print(L"kernel loaded in [" PTR_FMT "-" PTR_FMT "] entry=" PTR_FMT "\n",
|
||||||
(unsigned long)kd->kstart, (unsigned long)kd->kend, (unsigned long)kd->kentry));
|
kd->kstart, kd->kend, kd->kentry));
|
||||||
|
|
||||||
if (elilo_opt.initrd[0]) {
|
if (elilo_opt.initrd[0]) {
|
||||||
|
|
||||||
|
/* ramdisk image is moved to the top of available extended memory later by start_kernel() */
|
||||||
if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error;
|
if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error;
|
||||||
|
|
||||||
switch(load_file(elilo_opt.initrd, imem)) {
|
switch(load_file(elilo_opt.initrd, imem)) {
|
||||||
|
@ -242,6 +245,9 @@ do_launch:
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline));
|
VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline));
|
||||||
|
|
||||||
|
/* Give user time to see the output before launch */
|
||||||
|
if (elilo_opt.debug || elilo_opt.verbose) r = wait_timeout(300);
|
||||||
|
|
||||||
/* free resources associated with file accesses (before ExitBootServices) */
|
/* free resources associated with file accesses (before ExitBootServices) */
|
||||||
close_devices();
|
close_devices();
|
||||||
|
|
||||||
|
@ -455,7 +461,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
|
||||||
return EFI_LOAD_ERROR;
|
return EFI_LOAD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERB_PRT(5,Print(L"Loaded at 0x%lx size=%d bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
|
VERB_PRT(5,Print(L"Loaded at " PTR_FMT " size=%ld bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
|
||||||
/*
|
/*
|
||||||
* verify EDD3.0 status. Users may have to reboot
|
* verify EDD3.0 status. Users may have to reboot
|
||||||
*/
|
*/
|
||||||
|
@ -599,7 +605,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
|
||||||
goto do_exit;
|
goto do_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBG_PRT((L"Optind=%d optarg=%x argc=%d", Optind, Optarg, argc));
|
DBG_PRT((L"Optind=%d optarg=" PTR_FMT " argc=%d", Optind, Optarg, argc));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we can't defer this phase any longer...
|
* we can't defer this phase any longer...
|
||||||
|
|
9
elilo.h
9
elilo.h
|
@ -31,6 +31,12 @@
|
||||||
|
|
||||||
#include <efi.h>
|
#include <efi.h>
|
||||||
|
|
||||||
|
#ifdef CONFIG_ia32
|
||||||
|
#define PTR_FMT L"0x%x"
|
||||||
|
#else
|
||||||
|
#define PTR_FMT L"0x%lx"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "elilo_debug.h"
|
#include "elilo_debug.h"
|
||||||
|
|
||||||
#include "fileops.h"
|
#include "fileops.h"
|
||||||
|
@ -150,6 +156,7 @@ extern VOID *alloc_pages(UINTN, EFI_MEMORY_TYPE, EFI_ALLOCATE_TYPE, VOID *);
|
||||||
extern VOID free_pages(VOID *);
|
extern VOID free_pages(VOID *);
|
||||||
extern VOID free_all(VOID);
|
extern VOID free_all(VOID);
|
||||||
extern INTN alloc_kmem(VOID *, UINTN);
|
extern INTN alloc_kmem(VOID *, UINTN);
|
||||||
|
extern INTN alloc_kmem_anywhere(VOID **, UINTN);
|
||||||
extern VOID free_kmem(VOID);
|
extern VOID free_kmem(VOID);
|
||||||
extern VOID free_all_memory(VOID);
|
extern VOID free_all_memory(VOID);
|
||||||
|
|
||||||
|
@ -183,7 +190,7 @@ extern CHAR16 *get_config_file(VOID);
|
||||||
extern INTN load_file(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 *, UINTN);
|
||||||
|
|
||||||
/* from bootparams.c */
|
/* from bootparams.c */
|
||||||
extern VOID *create_boot_params (CHAR16 *, memdesc_t *, memdesc_t *, UINTN *);
|
extern VOID *create_boot_params (CHAR16 *, memdesc_t *, memdesc_t *, UINTN *);
|
||||||
|
|
|
@ -142,7 +142,7 @@ read_bytes(EFI_BLOCK_IO *blkio, UINT32 mediaid, UINTN offset, VOID *addr, UINTN
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG_PRT((L"readblock(%x, %d, %d, %d, %x)", blkio, mediaid, base, buffer_size, buffer));
|
DBG_PRT((L"readblock(PTR_FMT ", %d, %ld, %d, " PTR_FMT ")", blkio, mediaid, base, buffer_size, buffer));
|
||||||
|
|
||||||
status = uefi_call_wrapper(blkio->ReadBlocks, 5, blkio, mediaid, base, buffer_size, buffer);
|
status = uefi_call_wrapper(blkio->ReadBlocks, 5, blkio, mediaid, base, buffer_size, buffer);
|
||||||
if (EFI_ERROR(status)) {
|
if (EFI_ERROR(status)) {
|
||||||
|
@ -903,7 +903,7 @@ ext2fs_install_one(EFI_HANDLE dev, VOID **intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb.s_magic != EXT2_SUPER_MAGIC) {
|
if (sb.s_magic != EXT2_SUPER_MAGIC) {
|
||||||
DBG_PRT((L"bad magic 0x%x\n", sb.s_magic));
|
DBG_PRT((L"bad magic "PTR_FMT"\n", sb.s_magic));
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -323,7 +323,7 @@ netfs_open(netfs_interface_t *this, CHAR16 *name, UINTN *fd)
|
||||||
retry:
|
retry:
|
||||||
f->netbuf_size = f->netbuf_maxsize;
|
f->netbuf_size = f->netbuf_maxsize;
|
||||||
|
|
||||||
DBG_PRT((L"\nbefore netbuf:0x%lx netbuf_size=%ld\n", f->netbuf, f->netbuf_size));
|
DBG_PRT((L"\nbefore netbuf:" PTR_FMT " netbuf_size=%d\n", f->netbuf, f->netbuf_size));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For EFI versions older than 14.61:
|
* For EFI versions older than 14.61:
|
||||||
|
@ -349,7 +349,7 @@ retry:
|
||||||
NULL,
|
NULL,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
||||||
DBG_PRT((L"after Mftp=%r netbuf:0x%lx netbuf_size=%ld blocksize=%ld\n",
|
DBG_PRT((L"after Mftp=%r netbuf:" PTR_FMT " netbuf_size=%d blocksize=%d\n",
|
||||||
status,
|
status,
|
||||||
f->netbuf,
|
f->netbuf,
|
||||||
f->netbuf_size,
|
f->netbuf_size,
|
||||||
|
|
|
@ -47,7 +47,7 @@ bzImage_probe(CHAR16 *kname)
|
||||||
DBG_PRT((L"probe_bzImage_boot()\n"));
|
DBG_PRT((L"probe_bzImage_boot()\n"));
|
||||||
|
|
||||||
if (!kname) {
|
if (!kname) {
|
||||||
ERR_PRT((L"kname == %xh", kname));
|
ERR_PRT((L"kname == " PTR_FMT, kname));
|
||||||
free_kmem();
|
free_kmem();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ bzImage_probe(CHAR16 *kname)
|
||||||
param_size = (bootsect[0x1F1] + 1) * 512;
|
param_size = (bootsect[0x1F1] + 1) * 512;
|
||||||
param_start = alloc(param_size, EfiLoaderData);
|
param_start = alloc(param_size, EfiLoaderData);
|
||||||
|
|
||||||
DBG_PRT((L"param_size=%d param_start=%x", param_size, param_start));
|
DBG_PRT((L"param_size=%d param_start=" PTR_FMT, param_size, param_start));
|
||||||
|
|
||||||
if (!param_start) {
|
if (!param_start) {
|
||||||
ERR_PRT((L"Could not allocate %d bytes of setup data.",
|
ERR_PRT((L"Could not allocate %d bytes of setup data.",
|
||||||
|
@ -141,7 +141,7 @@ bzImage_probe(CHAR16 *kname)
|
||||||
|
|
||||||
{
|
{
|
||||||
UINT8 *c = ((UINT8 *)param_start)+514;
|
UINT8 *c = ((UINT8 *)param_start)+514;
|
||||||
DBG_PRT((L"param_start(c=%x): %c-%c-%c-%c",
|
DBG_PRT((L"param_start(c=" PTR_FMT "): %c-%c-%c-%c",
|
||||||
c, (CHAR16)c[0],(CHAR16) c[1], (CHAR16)c[2], (CHAR16)c[3]));
|
c, (CHAR16)c[0],(CHAR16) c[1], (CHAR16)c[2], (CHAR16)c[3]));
|
||||||
}
|
}
|
||||||
if (CompareMem(((UINT8 *)param_start) + 514, "HdrS", 4)) {
|
if (CompareMem(((UINT8 *)param_start) + 514, "HdrS", 4)) {
|
||||||
|
@ -158,13 +158,38 @@ bzImage_probe(CHAR16 *kname)
|
||||||
* Allocate memory for kernel.
|
* Allocate memory for kernel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) {
|
/*
|
||||||
ERR_PRT((L"Could not allocate kernel memory."));
|
* Get correct address for kernel from header, if applicable & available.
|
||||||
return -1;
|
*/
|
||||||
} else {
|
if ((param_start->s.hdr_major == 2) &&
|
||||||
VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n",
|
(param_start->s.hdr_minor >= 6) &&
|
||||||
kernel_start, kernel_size));
|
(param_start->s.kernel_start >= DEFAULT_KERNEL_START)) {
|
||||||
}
|
kernel_start = (void *)param_start->s.kernel_start;
|
||||||
|
VERB_PRT(3, Print(L"kernel header suggests kernel start at address "PTR_FMT"\n",
|
||||||
|
kernel_start));
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel_load_address = kernel_start;
|
||||||
|
|
||||||
|
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
|
||||||
|
/*
|
||||||
|
* Couldn't get desired address--just load it anywhere and move it later.
|
||||||
|
* (Easier than relocating kernel, and also works with non-relocatable kernels.)
|
||||||
|
*/
|
||||||
|
if (alloc_kmem_anywhere(&kernel_load_address, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
|
||||||
|
ERR_PRT((L"Could not allocate memory for kernel."));
|
||||||
|
free(param_start);
|
||||||
|
param_start = NULL;
|
||||||
|
param_size = 0;
|
||||||
|
fops_close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VERB_PRT(3, Print(L"kernel_start: "PTR_FMT" kernel_size: %d loading at: "PTR_FMT"\n",
|
||||||
|
kernel_start, kernel_size, kernel_load_address));
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now read the rest of the kernel image into memory.
|
* Now read the rest of the kernel image into memory.
|
||||||
*/
|
*/
|
||||||
|
@ -172,7 +197,7 @@ bzImage_probe(CHAR16 *kname)
|
||||||
DBG_PRT((L"reading kernel image...\n"));
|
DBG_PRT((L"reading kernel image...\n"));
|
||||||
|
|
||||||
size = kernel_size;
|
size = kernel_size;
|
||||||
efi_status = fops_read(fd, kernel_start, &size);
|
efi_status = fops_read(fd, kernel_load_address, &size);
|
||||||
if (EFI_ERROR(efi_status) || size < 0x10000) {
|
if (EFI_ERROR(efi_status) || size < 0x10000) {
|
||||||
ERR_PRT((L"Error reading kernel image %s.", kname));
|
ERR_PRT((L"Error reading kernel image %s.", kname));
|
||||||
free(param_start);
|
free(param_start);
|
||||||
|
@ -200,7 +225,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
|
||||||
DBG_PRT((L"load_bzImage_boot()\n"));
|
DBG_PRT((L"load_bzImage_boot()\n"));
|
||||||
|
|
||||||
if (!kname || !kd) {
|
if (!kname || !kd) {
|
||||||
ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd));
|
ERR_PRT((L"kname=" PTR_FMT " kd=" PTR_FMT, kname, kd));
|
||||||
free(param_start);
|
free(param_start);
|
||||||
param_start = NULL;
|
param_start = NULL;
|
||||||
param_size = 0;
|
param_size = 0;
|
||||||
|
@ -210,7 +235,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
|
||||||
kd->kstart = kd->kentry = kernel_start;
|
kd->kstart = kd->kentry = kernel_start;
|
||||||
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
|
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
|
||||||
|
|
||||||
DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend));
|
DBG_PRT((L"kstart=" PTR_FMT " kentry=" PTR_FMT " kend=" PTR_FMT "\n", kd->kstart, kd->kentry, kd->kend));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
30
ia32/gzip.c
30
ia32/gzip.c
|
@ -153,7 +153,7 @@ gzip_free(void *where)
|
||||||
int
|
int
|
||||||
fill_inbuf(void)
|
fill_inbuf(void)
|
||||||
{
|
{
|
||||||
INTN expected, nread;
|
UINTN expected, nread;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
|
|
||||||
expected = nread = INBUFSIZE;
|
expected = nread = INBUFSIZE;
|
||||||
|
@ -277,7 +277,7 @@ analyze_chunks(void)
|
||||||
* the relevant header information.
|
* the relevant header information.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
first_block (const char *buf, long blocksize)
|
first_block (const unsigned char *buf, long blocksize)
|
||||||
{
|
{
|
||||||
Elf32_Ehdr *elf;
|
Elf32_Ehdr *elf;
|
||||||
Elf32_Phdr *phdrs;
|
Elf32_Phdr *phdrs;
|
||||||
|
@ -297,13 +297,13 @@ first_block (const char *buf, long blocksize)
|
||||||
phnum = elf->e_phnum;
|
phnum = elf->e_phnum;
|
||||||
|
|
||||||
VERB_PRT(3, {
|
VERB_PRT(3, {
|
||||||
Print(L"Entry point 0x%lx\n", elf->e_entry);
|
Print(L"Entry point "PTR_FMT"\n", elf->e_entry);
|
||||||
Print(L"%d program headers\n", phnum);
|
Print(L"%d program headers\n", phnum);
|
||||||
Print(L"%d segment headers\n", elf->e_shnum);
|
Print(L"%d segment headers\n", elf->e_shnum);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (offs + phnum * sizeof(*phdrs) > (unsigned) blocksize) {
|
if (offs + phnum * sizeof(*phdrs) > (unsigned) blocksize) {
|
||||||
ERR_PRT((L"%s : ELF program headers not in first block (%ld)\n", LD_NAME, offs));
|
ERR_PRT((L"%s : ELF program headers not in first block (%d)\n", LD_NAME, offs));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,15 +345,15 @@ first_block (const char *buf, long blocksize)
|
||||||
|
|
||||||
if (phdrs[i].p_type != PT_LOAD) {
|
if (phdrs[i].p_type != PT_LOAD) {
|
||||||
CHUNK_NO_LOAD(i); /* mark no load chunk */
|
CHUNK_NO_LOAD(i); /* mark no load chunk */
|
||||||
DBG_PRT((L"%s : skipping segment %ld\n", LD_NAME, i));
|
DBG_PRT((L"%s : skipping segment %d\n", LD_NAME, i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHUNK_CAN_LOAD(i); /* mark no load chunk */
|
CHUNK_CAN_LOAD(i); /* mark no load chunk */
|
||||||
|
|
||||||
VERB_PRT(3,
|
VERB_PRT(3,
|
||||||
Print(L"\n%s : segment %ld vaddr [0x%lx-0x%lx] offset %ld filesz %ld "
|
Print(L"\n%s : segment %d vaddr ["PTR_FMT"-"PTR_FMT"] offset %d filesz %d "
|
||||||
"memsz=%ld bss_sz=%ld\n",
|
"memsz=%d bss_sz=%d\n",
|
||||||
LD_NAME, 1+i, chunks[i].addr, chunks[i].addr+phdrs[i].p_filesz,
|
LD_NAME, 1+i, chunks[i].addr, chunks[i].addr+phdrs[i].p_filesz,
|
||||||
chunks[i].offset, chunks[i].size, memsz, chunks[i].bss_sz));
|
chunks[i].offset, chunks[i].size, memsz, chunks[i].bss_sz));
|
||||||
|
|
||||||
|
@ -364,12 +364,12 @@ first_block (const char *buf, long blocksize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (low_addr & (EFI_PAGE_SIZE - 1)) {
|
if (low_addr & (EFI_PAGE_SIZE - 1)) {
|
||||||
ERR_PRT((L"%s : low_addr not page aligned 0x%lx\n", LD_NAME, low_addr));
|
ERR_PRT((L"%s : low_addr not page aligned "PTR_FMT"\n", LD_NAME, low_addr));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
analyze_chunks();
|
analyze_chunks();
|
||||||
|
|
||||||
DBG_PRT((L"%s : %d program headers entry=0x%lx\nlowest_addr=0x%lx highest_addr=0x%lx\n",
|
DBG_PRT((L"%s : %d program headers entry=" PTR_FMT "\nlowest_addr="PTR_FMT" highest_addr="PTR_FMT"\n",
|
||||||
LD_NAME,
|
LD_NAME,
|
||||||
phnum, kernel_entry, low_addr, max_addr));
|
phnum, kernel_entry, low_addr, max_addr));
|
||||||
|
|
||||||
|
@ -384,9 +384,9 @@ first_block (const char *buf, long blocksize)
|
||||||
|
|
||||||
/* allocate memory for the kernel */
|
/* allocate memory for the kernel */
|
||||||
if (alloc_kmem((void *)low_addr, pages) == -1) {
|
if (alloc_kmem((void *)low_addr, pages) == -1) {
|
||||||
ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n",
|
ERR_PRT((L"%s : AllocatePages(%d, "PTR_FMT") for kernel failed\n",
|
||||||
LD_NAME, pages, low_addr));
|
LD_NAME, pages, low_addr));
|
||||||
ERR_PRT((L"%s : Could not load kernel at 0x%lx\n", LD_NAME, low_addr));
|
ERR_PRT((L"%s : Could not load kernel at "PTR_FMT"\n", LD_NAME, low_addr));
|
||||||
ERR_PRT((L"%s : Bailing\n", LD_NAME));
|
ERR_PRT((L"%s : Bailing\n", LD_NAME));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -430,12 +430,12 @@ flush_window(void)
|
||||||
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
||||||
static UINTN heli_count;
|
static UINTN heli_count;
|
||||||
struct segment *cp;
|
struct segment *cp;
|
||||||
char *src, *dst;
|
unsigned char *src, *dst;
|
||||||
long cnt;
|
long cnt;
|
||||||
|
|
||||||
if (!outcnt) return;
|
if (!outcnt) return;
|
||||||
|
|
||||||
DBG_PRT((L"%s : flush_window outnct=%d file_offset=%ld\n", LD_NAME, outcnt, file_offset));
|
DBG_PRT((L"%s : flush_window outnct=%d file_offset=%d\n", LD_NAME, outcnt, file_offset));
|
||||||
|
|
||||||
Print(L"%c\b",helicopter[heli_count++%4]);
|
Print(L"%c\b",helicopter[heli_count++%4]);
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ tail:
|
||||||
file_offset += skip;
|
file_offset += skip;
|
||||||
outcnt -= skip;
|
outcnt -= skip;
|
||||||
}
|
}
|
||||||
dst = (char *)cp->addr + (file_offset - cp->offset);
|
dst = (unsigned char *)cp->addr + (file_offset - cp->offset);
|
||||||
cnt = cp->offset + cp->size - file_offset;
|
cnt = cp->offset + cp->size - file_offset;
|
||||||
if (cnt > outcnt)
|
if (cnt > outcnt)
|
||||||
cnt = outcnt;
|
cnt = outcnt;
|
||||||
|
@ -482,7 +482,7 @@ tail:
|
||||||
/* See if we are at the end of this chunk */
|
/* See if we are at the end of this chunk */
|
||||||
if (file_offset == cp->offset + cp->size) {
|
if (file_offset == cp->offset + cp->size) {
|
||||||
if (cp->bss_sz) {
|
if (cp->bss_sz) {
|
||||||
dst = (char *)cp->addr + cp->size;
|
dst = (unsigned char *)cp->addr + cp->size;
|
||||||
Memset(dst, 0, cp->bss_sz);
|
Memset(dst, 0, cp->bss_sz);
|
||||||
}
|
}
|
||||||
nextchunk();
|
nextchunk();
|
||||||
|
|
|
@ -111,7 +111,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
}
|
}
|
||||||
VERB_PRT(3, {
|
VERB_PRT(3, {
|
||||||
Print(L"ELF Header information: \n");
|
Print(L"ELF Header information: \n");
|
||||||
Print(L"\tEntry point 0x%x\n", (ehdr.e_entry & PADDR_MASK));
|
Print(L"\tEntry point "PTR_FMT"\n", (ehdr.e_entry & PADDR_MASK));
|
||||||
Print(L"\t%d program headers\n", ehdr.e_phnum);
|
Print(L"\t%d program headers\n", ehdr.e_phnum);
|
||||||
Print(L"\t%d segment headers\n", ehdr.e_shnum);
|
Print(L"\t%d segment headers\n", ehdr.e_shnum);
|
||||||
});
|
});
|
||||||
|
@ -145,8 +145,8 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
paddr = (phdrs[i].p_paddr & PADDR_MASK);
|
paddr = (phdrs[i].p_paddr & PADDR_MASK);
|
||||||
memsz = phdrs[i].p_memsz;
|
memsz = phdrs[i].p_memsz;
|
||||||
|
|
||||||
DBG_PRT((L"Phdr %d paddr [0x%x-0x%x] offset 0x%x"
|
DBG_PRT((L"Phdr %d paddr ["PTR_FMT"-"PTR_FMT"] offset "PTR_FMT""
|
||||||
" filesz 0x%x memsz=0x%x bss_sz=0x%x p_type=0x%x\n",
|
" filesz "PTR_FMT" memsz="PTR_FMT" bss_sz="PTR_FMT" p_type="PTR_FMT"\n",
|
||||||
1+i, paddr, paddr+phdrs[i].p_filesz, phdrs[i].p_offset,
|
1+i, paddr, paddr+phdrs[i].p_filesz, phdrs[i].p_offset,
|
||||||
phdrs[i].p_filesz, memsz,
|
phdrs[i].p_filesz, memsz,
|
||||||
(memsz - phdrs[i].p_filesz), phdrs[i].p_type));
|
(memsz - phdrs[i].p_filesz), phdrs[i].p_type));
|
||||||
|
@ -160,7 +160,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((UINTN)low_addr & (EFI_PAGE_SIZE - 1)) {
|
if ((UINTN)low_addr & (EFI_PAGE_SIZE - 1)) {
|
||||||
ERR_PRT((L"%s : kernel low address 0x%x not page aligned\n",
|
ERR_PRT((L"%s : kernel low address "PTR_FMT" not page aligned\n",
|
||||||
LD_NAME, low_addr));
|
LD_NAME, low_addr));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -176,16 +176,16 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
|
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
|
||||||
|
|
||||||
VERB_PRT(3, {
|
VERB_PRT(3, {
|
||||||
Print(L"Lowest PhysAddr: 0x%x\nTotalMemSize:%d bytes (%d pages)\n",
|
Print(L"Lowest PhysAddr: "PTR_FMT"\nTotalMemSize:%d bytes (%d pages)\n",
|
||||||
low_addr, total_size, pages);
|
low_addr, total_size, pages);
|
||||||
Print(L"Kernel entry @ 0x%x\n", kd->kentry);
|
Print(L"Kernel entry @ "PTR_FMT"\n", kd->kentry);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* now allocate memory for the kernel at the exact requested spot */
|
/* now allocate memory for the kernel at the exact requested spot */
|
||||||
if (alloc_kmem(low_addr, pages) == -1) {
|
if (alloc_kmem(low_addr, pages) == -1) {
|
||||||
ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n",
|
ERR_PRT((L"%s : AllocatePages(%d, "PTR_FMT") for kernel failed\n",
|
||||||
LD_NAME, pages, low_addr));
|
LD_NAME, pages, low_addr));
|
||||||
ERR_PRT((L"%s : Could not alloc %d pages for the kernel at 0x%lx "
|
ERR_PRT((L"%s : Could not alloc %d pages for the kernel at "PTR_FMT""
|
||||||
" and relocation is not not been implemented!\n",
|
" and relocation is not not been implemented!\n",
|
||||||
LD_NAME, pages, low_addr));
|
LD_NAME, pages, low_addr));
|
||||||
goto load_abort;
|
goto load_abort;
|
||||||
|
@ -206,7 +206,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
if (phdrs[i].p_type != PT_LOAD)
|
if (phdrs[i].p_type != PT_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"poffs: 0x%x (phdrs[%d].p_offset)\n",
|
VERB_PRT(3, Print(L"poffs: "PTR_FMT" (phdrs[%d].p_offset)\n",
|
||||||
phdrs[i].p_offset, i));
|
phdrs[i].p_offset, i));
|
||||||
|
|
||||||
filesz = phdrs[i].p_filesz;
|
filesz = phdrs[i].p_filesz;
|
||||||
|
@ -221,9 +221,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
|
|
||||||
VERB_PRT(4, {
|
VERB_PRT(4, {
|
||||||
Print(L"\nHeader #%d\n", i);
|
Print(L"\nHeader #%d\n", i);
|
||||||
Print(L"Offset in file 0x%x\n", phdrs[i].p_offset);
|
Print(L"Offset in file "PTR_FMT"\n", phdrs[i].p_offset);
|
||||||
Print(L"Physical addr 0x%x\n", low_addr);
|
Print(L"Physical addr "PTR_FMT"\n", low_addr);
|
||||||
Print(L"BSS size 0x%x bytes\n", bss_sz);
|
Print(L"BSS size %d bytes\n", bss_sz);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#define ELILO_ARCH "IA-32" /* ASCII string */
|
#define ELILO_ARCH "IA-32" /* ASCII string */
|
||||||
#define PADDR_MASK 0xfffffff
|
#define PADDR_MASK 0xfffffff
|
||||||
|
|
||||||
|
#define INITRD_START (15*1024*1024)
|
||||||
|
#define DEFAULT_KERNEL_START 0x100000
|
||||||
|
|
||||||
/* for now use library versions */
|
/* for now use library versions */
|
||||||
#define Memset(a,v,n) SetMem((a),(n),(v))
|
#define Memset(a,v,n) SetMem((a),(n),(v))
|
||||||
#define Memcpy(a,b,n) CopyMem((a),(b),(n))
|
#define Memcpy(a,b,n) CopyMem((a),(b),(n))
|
||||||
|
@ -299,11 +302,17 @@ typedef union ia32_boot_params {
|
||||||
UINT8 *t = (UINT8 *)(to); \
|
UINT8 *t = (UINT8 *)(to); \
|
||||||
UINT8 *f = (UINT8 *)(from); \
|
UINT8 *f = (UINT8 *)(from); \
|
||||||
UINTN n = cnt; \
|
UINTN n = cnt; \
|
||||||
if (t && f && n) { \
|
if (t && f && n && (t<f)) { \
|
||||||
while (n--) { \
|
while (n--) { \
|
||||||
*t++ = *f++; \
|
*t++ = *f++; \
|
||||||
} \
|
} \
|
||||||
} \
|
} else if (t && f && n && (t>f)) { \
|
||||||
|
t += n; \
|
||||||
|
f += n; \
|
||||||
|
while (n--) { \
|
||||||
|
*t-- = *f--; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MEMSET(ptr, size, val) { \
|
#define MEMSET(ptr, size, val) { \
|
||||||
|
@ -338,6 +347,7 @@ extern UINTN kernel_size;
|
||||||
|
|
||||||
extern VOID *initrd_start;
|
extern VOID *initrd_start;
|
||||||
extern UINTN initrd_size;
|
extern UINTN initrd_size;
|
||||||
|
extern VOID *kernel_load_address;
|
||||||
|
|
||||||
extern dt_addr_t gdt_addr;
|
extern dt_addr_t gdt_addr;
|
||||||
extern dt_addr_t idt_addr;
|
extern dt_addr_t idt_addr;
|
||||||
|
@ -357,19 +367,31 @@ extern INTN ia32_use_legacy_free_boot();
|
||||||
static inline void
|
static inline void
|
||||||
start_kernel(VOID *kentry, boot_params_t *bp)
|
start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
{
|
{
|
||||||
|
UINT32 temp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable interrupts.
|
* Disable interrupts.
|
||||||
*/
|
*/
|
||||||
asm volatile ( "cli" : : );
|
asm volatile ( "cli" : : );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Relocate initrd, if present.
|
* Relocate kernel (if needed), and initrd (if present).
|
||||||
*/
|
* Copy kernel first, in case kernel was loaded overlapping where we're
|
||||||
|
* planning to copy the initrd. This assumes that the initrd didn't
|
||||||
|
* get loaded overlapping where we're planning to copy the kernel, but
|
||||||
|
* that's pretty unlikely since we couldn't alloc that space for the
|
||||||
|
* kernel (or the kernel would already be there).
|
||||||
|
*/
|
||||||
|
if (kernel_start != kernel_load_address) {
|
||||||
|
MEMCPY(kernel_start, kernel_load_address, kernel_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp->s.initrd_start) {
|
||||||
|
temp = bp->s.initrd_start;
|
||||||
|
MEMCPY(INITRD_START, temp , bp->s.initrd_size);
|
||||||
|
bp->s.initrd_start = INITRD_START;
|
||||||
|
}
|
||||||
|
|
||||||
if (bp->s.initrd_start) {
|
|
||||||
MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size);
|
|
||||||
bp->s.initrd_start = 15 * 1024 * 1024;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Copy boot sector, setup data and command line
|
* Copy boot sector, setup data and command line
|
||||||
* to final resting place. We need to copy
|
* to final resting place. We need to copy
|
||||||
|
|
|
@ -97,7 +97,10 @@ UINTN high_base_mem = 0x90000;
|
||||||
UINTN high_ext_mem = 32 * 1024 * 1024;
|
UINTN high_ext_mem = 32 * 1024 * 1024;
|
||||||
|
|
||||||
/* This starting address will hold true for all of the loader types for now */
|
/* This starting address will hold true for all of the loader types for now */
|
||||||
VOID *kernel_start = (VOID *)0x100000; /* 1M */
|
VOID *kernel_start = (VOID *)DEFAULT_KERNEL_START;
|
||||||
|
|
||||||
|
/* The kernel may load elsewhere if EFI firmware reserves kernel_start */
|
||||||
|
VOID *kernel_load_address = (VOID *)DEFAULT_KERNEL_START;
|
||||||
|
|
||||||
VOID *initrd_start = NULL;
|
VOID *initrd_start = NULL;
|
||||||
UINTN initrd_size = 0;
|
UINTN initrd_size = 0;
|
||||||
|
@ -131,16 +134,16 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
|
||||||
DBG_PRT((L"initrd_get_addr()\n"));
|
DBG_PRT((L"initrd_get_addr()\n"));
|
||||||
|
|
||||||
if (!kd || !imem) {
|
if (!kd || !imem) {
|
||||||
ERR_PRT((L"kd=0x%x imem=0x%x", kd, imem));
|
ERR_PRT((L"kd=" PTR_FMT " imem=" PTR_FMT, kd, imem));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"kstart=0x%x kentry=0x%x kend=0x%x\n",
|
VERB_PRT(3, Print(L"kstart=" PTR_FMT " kentry=" PTR_FMT " kend=" PTR_FMT "\n",
|
||||||
kd->kstart, kd->kentry, kd->kend));
|
kd->kstart, kd->kentry, kd->kend));
|
||||||
|
|
||||||
imem->start_addr = kd->kend;
|
imem->start_addr = kd->kend;
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"initrd start_addr=0x%x pgcnt=%d\n",
|
VERB_PRT(3, Print(L"initrd start_addr=" PTR_FMT " pgcnt=%d\n",
|
||||||
imem->start_addr, imem->pgcnt));
|
imem->start_addr, imem->pgcnt));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -156,6 +159,24 @@ sysdeps_free_boot_params(boot_params_t *bp)
|
||||||
free_memmap(&md);
|
free_memmap(&md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID find_bits(unsigned long mask, UINT8 *first, UINT8* len) {
|
||||||
|
unsigned char bit_pos = 0, bit_len = 0;
|
||||||
|
*first =0;
|
||||||
|
*len = 0;
|
||||||
|
if (mask == 0)
|
||||||
|
return;
|
||||||
|
while (!(mask & 0x1)) {
|
||||||
|
mask = mask >> 1;
|
||||||
|
bit_pos++;
|
||||||
|
}
|
||||||
|
while (mask & 0x1) {
|
||||||
|
mask = mask >> 1;
|
||||||
|
bit_len++;
|
||||||
|
}
|
||||||
|
*first = bit_pos;
|
||||||
|
*len = bit_len;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get video information.
|
* Get video information.
|
||||||
*/
|
*/
|
||||||
|
@ -163,10 +184,11 @@ static INTN get_video_info(boot_params_t * bp) {
|
||||||
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
|
||||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode = NULL;
|
||||||
EFI_HANDLE *Gop_handle;
|
EFI_HANDLE *Gop_handle = NULL;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINTN size, size1;
|
UINTN size = 0;
|
||||||
|
UINTN size1;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
efi_status = uefi_call_wrapper(
|
efi_status = uefi_call_wrapper(
|
||||||
|
@ -204,7 +226,7 @@ static INTN get_video_info(boot_params_t * bp) {
|
||||||
3,
|
3,
|
||||||
*Gop_handle,
|
*Gop_handle,
|
||||||
&GopProtocol,
|
&GopProtocol,
|
||||||
&Gop_interface);
|
(VOID **) &Gop_interface);
|
||||||
|
|
||||||
if (EFI_ERROR(efi_status)) {
|
if (EFI_ERROR(efi_status)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -428,7 +450,7 @@ sysdeps_create_boot_params(
|
||||||
DBG_PRT((L"fill_boot_params()\n"));
|
DBG_PRT((L"fill_boot_params()\n"));
|
||||||
|
|
||||||
if (!bp || !cmdline || !initrd || !cookie) {
|
if (!bp || !cmdline || !initrd || !cookie) {
|
||||||
ERR_PRT((L"bp=0x%x cmdline=0x%x initrd=0x%x cookie=0x%x",
|
ERR_PRT((L"bp=" PTR_FMT " cmdline=" PTR_FMT " initrd=" PTR_FMT " cookie=" PTR_FMT,
|
||||||
bp, cmdline, initrd, cookie));
|
bp, cmdline, initrd, cookie));
|
||||||
|
|
||||||
if (param_start != NULL) {
|
if (param_start != NULL) {
|
||||||
|
@ -515,7 +537,7 @@ sysdeps_create_boot_params(
|
||||||
* Initial RAMdisk and root device stuff.
|
* Initial RAMdisk and root device stuff.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DBG_PRT((L"initrd->start_addr=0x%x initrd->pgcnt=%d\n",
|
DBG_PRT((L"initrd->start_addr=" PTR_FMT " initrd->pgcnt=%d\n",
|
||||||
initrd->start_addr, initrd->pgcnt));
|
initrd->start_addr, initrd->pgcnt));
|
||||||
|
|
||||||
/* These RAMdisk flags are not needed, just zero them. */
|
/* These RAMdisk flags are not needed, just zero them. */
|
||||||
|
@ -597,7 +619,7 @@ sysdeps_create_boot_params(
|
||||||
#define WAIT_FOR_KEY() \
|
#define WAIT_FOR_KEY() \
|
||||||
{ \
|
{ \
|
||||||
EFI_INPUT_KEY key; \
|
EFI_INPUT_KEY key; \
|
||||||
while (ST->ConIn->ReadKeyStroke(ST->ConIn, &key) != EFI_SUCCESS) { \
|
while (uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key) != EFI_SUCCESS) { \
|
||||||
; \
|
; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
@ -697,7 +719,9 @@ sysdeps_create_boot_params(
|
||||||
|
|
||||||
if (!get_video_info(bp)) goto do_memmap;
|
if (!get_video_info(bp)) goto do_memmap;
|
||||||
|
|
||||||
efi_status = ST->ConOut->QueryMode(
|
efi_status = uefi_call_wrapper(
|
||||||
|
ST->ConOut->QueryMode,
|
||||||
|
4,
|
||||||
ST->ConOut,
|
ST->ConOut,
|
||||||
ST->ConOut->Mode->Mode,
|
ST->ConOut->Mode->Mode,
|
||||||
&cols,
|
&cols,
|
||||||
|
|
|
@ -132,7 +132,7 @@ check_fpswa(EFI_HANDLE image, EFI_HANDLE dev, CHAR16 *fpswa_file)
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
UINTN j, count = sizeof(fpswa_filenames)/sizeof(CHAR16 *);
|
UINTN j, count = sizeof(fpswa_filenames)/sizeof(CHAR16 *);
|
||||||
INTN cookie;
|
UINTN cookie;
|
||||||
CHAR16 devname[FILENAME_MAXLEN];
|
CHAR16 devname[FILENAME_MAXLEN];
|
||||||
|
|
||||||
if (fpswa_file) {
|
if (fpswa_file) {
|
||||||
|
|
14
ia64/gzip.c
14
ia64/gzip.c
|
@ -161,7 +161,7 @@ gzip_free(void *where)
|
||||||
int
|
int
|
||||||
fill_inbuf(void)
|
fill_inbuf(void)
|
||||||
{
|
{
|
||||||
INTN expected, nread;
|
UINTN expected, nread;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
|
|
||||||
expected = nread = INBUFSIZE;
|
expected = nread = INBUFSIZE;
|
||||||
|
@ -309,7 +309,7 @@ analyze_chunks(void)
|
||||||
* the relevant header information.
|
* the relevant header information.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
first_block (const char *buf, long blocksize)
|
first_block (const unsigned char *buf, long blocksize)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr *elf;
|
Elf64_Ehdr *elf;
|
||||||
Elf64_Phdr *phdrs;
|
Elf64_Phdr *phdrs;
|
||||||
|
@ -439,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;
|
||||||
|
|
||||||
VERB_PRT(1, (L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr));
|
VERB_PRT(1, Print(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"));
|
||||||
|
@ -464,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));
|
||||||
|
|
||||||
VERB_PRT(1, (L"low_addr=0x%lx new_addr=0x%lx offset=0x%lx", low_addr, new_addr, load_offset));
|
VERB_PRT(1, Print(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
|
||||||
|
@ -526,7 +526,7 @@ flush_window(void)
|
||||||
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
||||||
static UINTN heli_count;
|
static UINTN heli_count;
|
||||||
struct segment *cp;
|
struct segment *cp;
|
||||||
char *src, *dst;
|
unsigned char *src, *dst;
|
||||||
long cnt;
|
long cnt;
|
||||||
|
|
||||||
if (!outcnt) return;
|
if (!outcnt) return;
|
||||||
|
@ -565,7 +565,7 @@ tail:
|
||||||
file_offset += skip;
|
file_offset += skip;
|
||||||
outcnt -= skip;
|
outcnt -= skip;
|
||||||
}
|
}
|
||||||
dst = (char *)cp->addr + (file_offset - cp->offset);
|
dst = (unsigned char *)cp->addr + (file_offset - cp->offset);
|
||||||
|
|
||||||
cnt = cp->offset + cp->size - file_offset;
|
cnt = cp->offset + cp->size - file_offset;
|
||||||
|
|
||||||
|
@ -582,7 +582,7 @@ tail:
|
||||||
/* See if we are at the end of this chunk */
|
/* See if we are at the end of this chunk */
|
||||||
if (file_offset == cp->offset + cp->size) {
|
if (file_offset == cp->offset + cp->size) {
|
||||||
if (cp->bss_sz) {
|
if (cp->bss_sz) {
|
||||||
dst = (char *)cp->addr + cp->size;
|
dst = (unsigned char *)cp->addr + cp->size;
|
||||||
Memset(dst, 0, cp->bss_sz);
|
Memset(dst, 0, cp->bss_sz);
|
||||||
}
|
}
|
||||||
nextchunk();
|
nextchunk();
|
||||||
|
|
|
@ -159,4 +159,4 @@ longjmp:
|
||||||
invala // virt. -> phys. regnum mapping may change
|
invala // virt. -> phys. regnum mapping may change
|
||||||
mov pr=r24,-1
|
mov pr=r24,-1
|
||||||
br.ret.dptk.few rp
|
br.ret.dptk.few rp
|
||||||
.endp __longjmp
|
.endp longjmp
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
VERB_PRT(1, (L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n", LD_NAME, pages, low_addr));
|
VERB_PRT(1, Print(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"));
|
||||||
|
|
|
@ -81,6 +81,7 @@ setjmp:
|
||||||
.proc __sigsetjmp
|
.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)
|
||||||
|
.body
|
||||||
alloc loc1=ar.pfs,2,2,2,0
|
alloc loc1=ar.pfs,2,2,2,0
|
||||||
mov r16=ar.unat
|
mov r16=ar.unat
|
||||||
;;
|
;;
|
||||||
|
@ -89,6 +90,7 @@ __sigsetjmp:
|
||||||
add r3=8,in0
|
add r3=8,in0
|
||||||
;;
|
;;
|
||||||
st8.spill.nta [r2]=sp,16 // r12 (sp)
|
st8.spill.nta [r2]=sp,16 // r12 (sp)
|
||||||
|
;;
|
||||||
st8.spill.nta [r3]=gp,16 // r1 (gp)
|
st8.spill.nta [r3]=gp,16 // r1 (gp)
|
||||||
;;
|
;;
|
||||||
st8.nta [r2]=r16,16 // save caller's unat
|
st8.nta [r2]=r16,16 // save caller's unat
|
||||||
|
@ -96,13 +98,13 @@ __sigsetjmp:
|
||||||
add r8=0xa0,in0
|
add r8=0xa0,in0
|
||||||
;;
|
;;
|
||||||
st8.spill.nta [r2]=r4,16 // r4
|
st8.spill.nta [r2]=r4,16 // r4
|
||||||
|
;;
|
||||||
st8.spill.nta [r3]=r5,16 // r5
|
st8.spill.nta [r3]=r5,16 // r5
|
||||||
add r9=0xb0,in0
|
add r9=0xb0,in0
|
||||||
;;
|
;;
|
||||||
stf.spill.nta [r8]=f2,32
|
stf.spill.nta [r8]=f2,32
|
||||||
stf.spill.nta [r9]=f3,32
|
stf.spill.nta [r9]=f3,32
|
||||||
mov loc0=rp
|
mov loc0=rp
|
||||||
.body
|
|
||||||
;;
|
;;
|
||||||
stf.spill.nta [r8]=f4,32
|
stf.spill.nta [r8]=f4,32
|
||||||
stf.spill.nta [r9]=f5,32
|
stf.spill.nta [r9]=f5,32
|
||||||
|
@ -139,6 +141,7 @@ __sigsetjmp:
|
||||||
stf.spill.nta [r9]=f31
|
stf.spill.nta [r9]=f31
|
||||||
|
|
||||||
st8.spill.nta [r2]=r6,16 // r6
|
st8.spill.nta [r2]=r6,16 // r6
|
||||||
|
;;
|
||||||
st8.spill.nta [r3]=r7,16 // r7
|
st8.spill.nta [r3]=r7,16 // r7
|
||||||
;;
|
;;
|
||||||
mov r23=ar.bsp
|
mov r23=ar.bsp
|
||||||
|
|
|
@ -86,7 +86,7 @@ start_kernel(VOID *kentry, VOID *bp)
|
||||||
asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(kentry),"r"(bp));
|
asm volatile ("mov r28=%1; br.sptk.few %0" :: "b"(kentry),"r"(bp));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const UINT64
|
static inline UINT64
|
||||||
__ia64_swab64 (UINT64 x)
|
__ia64_swab64 (UINT64 x)
|
||||||
{
|
{
|
||||||
UINT64 result;
|
UINT64 result;
|
||||||
|
@ -95,13 +95,13 @@ __ia64_swab64 (UINT64 x)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const UINT32
|
static inline UINT32
|
||||||
__ia64_swab32 (UINT32 x)
|
__ia64_swab32 (UINT32 x)
|
||||||
{
|
{
|
||||||
return __ia64_swab64(x) >> 32;
|
return __ia64_swab64(x) >> 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const UINT16
|
static inline UINT16
|
||||||
__ia64_swab16(UINT16 x)
|
__ia64_swab16(UINT16 x)
|
||||||
{
|
{
|
||||||
return __ia64_swab64(x) >> 48;
|
return __ia64_swab64(x) >> 48;
|
||||||
|
|
|
@ -1094,10 +1094,10 @@ static int gunzip(void)
|
||||||
error("Input has invalid flags\n");
|
error("Input has invalid flags\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
(ulg)get_byte(); /* Get timestamp */
|
(void)get_byte(); /* Get timestamp - 4 bytes */
|
||||||
((ulg)get_byte()) << 8;
|
(void)get_byte();
|
||||||
((ulg)get_byte()) << 16;
|
(void)get_byte();
|
||||||
((ulg)get_byte()) << 24;
|
(void)get_byte();
|
||||||
|
|
||||||
(void)get_byte(); /* Ignore extra flags for the moment */
|
(void)get_byte(); /* Ignore extra flags for the moment */
|
||||||
(void)get_byte(); /* Ignore OS type for the moment */
|
(void)get_byte(); /* Ignore OS type for the moment */
|
||||||
|
|
4
initrd.c
4
initrd.c
|
@ -77,9 +77,9 @@ load_file(CHAR16 *filename, memdesc_t *image)
|
||||||
filename));
|
filename));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
VERB_PRT(2, Print(L"%s image: total_size: %ld bytes base: 0x%lx "
|
VERB_PRT(2, Print(L"%s image: total_size: %d bytes base: " PTR_FMT " "
|
||||||
"pages %d\n", filename, image->size,
|
"pages %d\n", filename, image->size,
|
||||||
(UINTN)start_addr, pgcnt));
|
start_addr, pgcnt));
|
||||||
|
|
||||||
Print(L"Loading file %s...", filename);
|
Print(L"Loading file %s...", filename);
|
||||||
|
|
||||||
|
|
6
loader.c
6
loader.c
|
@ -38,12 +38,18 @@ loader_ops_t *
|
||||||
loader_probe(CHAR16 *kname)
|
loader_probe(CHAR16 *kname)
|
||||||
{
|
{
|
||||||
loader_ops_t *ops;
|
loader_ops_t *ops;
|
||||||
|
UINTN n = 0;
|
||||||
|
|
||||||
for (ops= ldops_list; ops; ops = ops->next) {
|
for (ops= ldops_list; ops; ops = ops->next) {
|
||||||
|
n++;
|
||||||
|
VERB_PRT(3, Print(L"Probing loader: %s\n", ops->ld_name));
|
||||||
if (ops->ld_probe(kname) == 0) {
|
if (ops->ld_probe(kname) == 0) {
|
||||||
return ops;
|
return ops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!n) {
|
||||||
|
ERR_PRT((L"No loaders registered"));
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
163
release.notes
163
release.notes
|
@ -1,94 +1,93 @@
|
||||||
|
3 . 1 0 R E L E A S E N O T E S
|
||||||
|
===================================
|
||||||
|
|
||||||
SUBMIT BUG REPORTS HERE --> http://sourceforge.net/tracker/?group_id=91879&atid=598709
|
BUILD NOTES
|
||||||
|
====================
|
||||||
|
You will need the following toolchain to build elilo-3.10 from source
|
||||||
|
the elilo build environment is optimized for Debian and Debian based distros.
|
||||||
|
1. gnu-efi3.0d or greater, elilo-3.10 binaries were built with gnu-efi3.0e-2
|
||||||
|
shipping in Lenny
|
||||||
|
2. gcc-4.1.1 or greater, elilo-3.10 binaries were built with:
|
||||||
|
x86 -> 4.2.3-1ubuntu6
|
||||||
|
x86_64 -> 4.2.3-1ubuntu6
|
||||||
|
ia64 -> 4.3.2-1.1
|
||||||
|
3. binutils-2.17.50.0.14 or greater, elilo-3.10 binaries were built with:
|
||||||
|
x86 -> 2.18.1-cvs20080103-0ubuntu1
|
||||||
|
x86_64 -> 2.18.1~cvs20080103-0ubuntu1
|
||||||
|
ia64 -> 2.18.1~cvs20080103-7
|
||||||
|
|
||||||
IMPORTANT NOTE FOR BUILDS ON ALL ARCHS:
|
* if you use a debian based (lenny)build environment you will have no problems
|
||||||
-------------------------
|
and setting it up is simple. you will be able to build elilo in 3 steps:
|
||||||
|
1. apt-get install gnu-efi, gcc, binutils
|
||||||
|
2. apt-get source elilo (or download elilo-3.10.tar.gz from SourceForge.)
|
||||||
|
3. cd ./elilo-3.10 and type make
|
||||||
|
|
||||||
You will need the following toolchain to build elilo with the 3.7 source tarball
|
** If you use the upstream tarballs for the toolchain you will need to move
|
||||||
(for all archs due to the new uefi call wrappers).
|
some files around.
|
||||||
|
GNU-EFI (provides the efi 1.10 and uefi 2.x libraries & api)
|
||||||
|
-------
|
||||||
|
gnu-efi libraries are installed to /usr/local/lib by the
|
||||||
|
upstream gnu-efi source package. elilo expects them to be in system location
|
||||||
|
/usr/lib. efi includes may be located in /usr/local/include/efi. elilo
|
||||||
|
expects them to be in system location /usr/include/efi.
|
||||||
|
|
||||||
1. gnu-efi-3.0d or > .... http://sourceforge.net/project/showfiles.php?group_id=163609&package_id=185019&release_id=508306
|
BINUTILS (provides the elf conversion utility to produce efi bins)
|
||||||
|
--------
|
||||||
2. gcc-4.1.1 or >
|
likewise objcopy may be installed to /usr/local/bin by binutils,
|
||||||
3. binutils-2.17.50.0.14 or > with Intel64 EFI support
|
elilo source expects it to be in /usr/bin.
|
||||||
|
|
||||||
*BuildNote: efi libraries are installed to /usr/local/lib
|
|
||||||
by the default gnu-efi source package. elilo expects them to
|
|
||||||
be in standard linux system location /usr/lib. efi includes
|
|
||||||
may be located in /usr/local/include/efi. elilo expects
|
|
||||||
them to be in standard linux system location /usr/include/efi.
|
|
||||||
likewise objcopy may be installed to /usr/local/bin by binutils,
|
|
||||||
elilo source expects it to be in /usr/bin. On distributions
|
|
||||||
using standard linux system conventions such
|
|
||||||
as Debian and Ubuntu this is corrected in the binutils and gnu-efi packages.
|
|
||||||
|
|
||||||
|
|
||||||
Implementation:
|
ELILO ON EFI X86_64
|
||||||
--------------
|
=====================
|
||||||
Calls to EFI services in x86_64 require a wrapper to pass the arguments
|
HARD REQUIREMENTS
|
||||||
in the appropriate manner. This is implemented with efi wrapper.
|
Elilo/x86_64 requires efi64 enabled linux kernel i.e. 2.6.21 or newer
|
||||||
For IA32 and IA64, the wrapper is a macro that merely calls the
|
nothing earlier will work, 2.6.21 was the earliest kernel that efi64
|
||||||
EFI services directly. The elilo source has been modified to use the
|
support went into. You need to compile the kernel with CONFIG_EFI
|
||||||
efi wrapper implemented in the gnu-efi-3.0d library.
|
kernel option ON.
|
||||||
elilo for x86_64 and its dependent libraries are built and the final
|
x86_64 platforms with UEFI 2.0 firmware deprecate UGA protocol
|
||||||
ELF image is converted into PE-COFF image using the objcopy supported
|
and therefore only the Graphics Output Protocol (GOP) is supported. For
|
||||||
by binutils-2.17.50.0.14 or above with Intel64 EFI support.
|
such platforms, the kernel must be compiled with EFI_FB option ON. This
|
||||||
|
will enable early boot messages on the console. Elilo for x86_64
|
||||||
|
attempts to query EFI for GOP support and if it fails it defaults to
|
||||||
|
text mode which may or may not show you early console ouput depends on
|
||||||
|
your efi and physical setup. If efi default console ouput is set to
|
||||||
|
serial and you dont have anything attached to the serial port then youre
|
||||||
|
not going to see messages from elilo, duh.
|
||||||
|
|
||||||
On UEFI 2.0 firmware, only Graphics Output Protocol (GOP) is supported.
|
WORKING ELILO.CONF FOR EFI X86_64 EXAMPLE
|
||||||
The x86_64 elilo first queries video information from GOP failing which
|
Here is my elilo.conf from my UEFI2.0/x86_64 workstation which uses GOP.
|
||||||
it queries for text mode support. The video information is passed to
|
shows me console output, what elilo is doing, and kernel boot.
|
||||||
Linux kernel via boot parameter. The GOP support requires
|
|
||||||
Linux kernel EFI framebuffer driver (kernel configuration option).
|
|
||||||
|
|
||||||
Booting on EFI/x86_64 platforms
|
default=UBUNTU
|
||||||
-----------------------------
|
chooser=simple
|
||||||
|
verbose=5
|
||||||
|
delay=30
|
||||||
|
append="root=/dev/sda3 vga=0x31e splash showopts"
|
||||||
|
|
||||||
To use elilo on x86_64, you can put it on a floppy and
|
image=/vmlinuz-2.6.24-23-generic
|
||||||
on a FAT32 partition (msdos partition). You can also
|
label="UBUNTU"
|
||||||
netboot if your network adapter has support for UNDI/PXE.
|
description="Ubuntu 2.6.24-23-generic kernel"
|
||||||
|
initrd=/initrd.img-2.6.24-23-generic
|
||||||
|
|
||||||
Elilo/x86_64 requires efi64 enabled linux kernel (> 2.6.21).
|
|
||||||
You need to compile the kernel with CONFIG_EFI option.
|
|
||||||
x86_64 platforms with UEFI 2.0 firmware deprecate UGA protocol
|
|
||||||
and therefore only the Graphics Output Protocol (GOP) is supported. For
|
|
||||||
such platforms, the kernel must be configured with EFI_FB option. This
|
|
||||||
will enable early boot messages on the console. The elilo for x86_64
|
|
||||||
attempts to query the firmware for GOP and if it fails it defaults to
|
|
||||||
text mode.
|
|
||||||
|
|
||||||
The x86_64 implementation converts the EFI memory map into E820 map and
|
CHANGES FROM 3.8 TO 3.10
|
||||||
passes it in the bootparameter supplied to the kernel. For details on
|
========================
|
||||||
bootparameter, see x86_64/sysdeps.h.
|
Patch contributions from David Lombard @ Intel and Stuart Hayes @ Dell
|
||||||
|
thank you.
|
||||||
|
|
||||||
|
* added PTR_FMT 32bit & 64bit pointer translation for correct output
|
||||||
|
* elilo hang bugfix x86_64 non-standard kernels with non-traditional start
|
||||||
|
address elilo will pull the start address from the kernel elf header for 2.6
|
||||||
|
or newer kernels, map memory and use that start address, else use standard
|
||||||
|
1MB default start address. And handle case of overlapping kernels
|
||||||
|
and initrds in memory.
|
||||||
|
* ported kernel start adress and memory overlap handling to ia32
|
||||||
|
* eliminated all possible compiler warnings except those actually
|
||||||
|
caused by gnu-efi that cant be fixed here.
|
||||||
|
* Debug output improvement, added pauses with visual feedback when
|
||||||
|
user sets debug or verbose options.
|
||||||
|
* bugfix added missing find_bits function definition back into ia32
|
||||||
|
subtree
|
||||||
|
* bugfix loader_probe now correctly errors out if no loaders
|
||||||
|
registered.
|
||||||
|
|
||||||
CHANGES BETWEEN 3.6 & 3.8
|
|
||||||
-------------------------
|
|
||||||
- options parsing changed to append root= after append="-- options" to
|
|
||||||
accomodate xen ia64 support. without this change the option is
|
|
||||||
passed to the hypervisor instead of the kernel resulting in the
|
|
||||||
standard kernel panic.
|
|
||||||
INTEL PATCHES
|
|
||||||
- E820 memory map is added to IA32 to make it possible for
|
|
||||||
Linux kernel not to depend on EFI memory map on EFI 32.
|
|
||||||
- The EFI framebuffer type ID is changed in Linux kernel to
|
|
||||||
conform to Linux kernel framebuffer type ID grouping rules. So the
|
|
||||||
EFI framebuffer type ID setting code in ELILO is changed accordingly.
|
|
||||||
- The boot loader signature of IA32 and x86_64 is redefined to
|
|
||||||
make it possible for Linux kernel to distinguish whether the
|
|
||||||
underlying firmware is EFI 32 or EFI 64.
|
|
||||||
- updates for EFI-2.0 boot support going into linux kernel 2.6.24-rc4
|
|
||||||
- CL_MAGIC is not supported by 32-bit boot protocol. So, the kernel
|
|
||||||
command line passing code is changed accordingly.
|
|
||||||
- bugfix, on some machines efi memmap entries exceed the 128 maximum
|
|
||||||
for e820 map entries, so consecutive memmap entries with the same
|
|
||||||
type are merged to bring the count below 128.
|
|
||||||
- bugfix, uninitialized e820 _nr_map in fill_e820map.
|
|
||||||
- fixed compile warning for cmdline_addr assignment.
|
|
||||||
ADDITIONAL CHANGES
|
|
||||||
- version string updated to 3.8
|
|
||||||
- fixed x86_64 hang created by initrd images larger than 7mb due
|
|
||||||
to the code always using the same efi region which on some machines
|
|
||||||
is only 7mb. code changed to properly have the efi allocator decide
|
|
||||||
which regions to use based on the total pagecount required by the
|
|
||||||
size of the initrd to be loaded.
|
|
||||||
- bugfix, for ia32 and x86_64 code, e820_map[x-1] accesses memory
|
|
||||||
out of bounds when x=0.
|
|
||||||
|
|
6
util.c
6
util.c
|
@ -134,8 +134,10 @@ wait_timeout(UINTN timeout)
|
||||||
ERR_PRT((L"waitkey WaitForEvent failed %r", status));
|
ERR_PRT((L"waitkey WaitForEvent failed %r", status));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (timeout % 10 == 1) Print(L".");
|
||||||
|
|
||||||
} while (timeout-- && idx == 0);
|
} while (timeout-- && idx == 0);
|
||||||
|
Print(L"\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SetTimer(timer, TimerCancel, 0) is causing problems on IA-32 and gcc3
|
* SetTimer(timer, TimerCancel, 0) is causing problems on IA-32 and gcc3
|
||||||
|
@ -248,7 +250,7 @@ split_args(CHAR16 *buffer, CHAR16 *kname, CHAR16 *args)
|
||||||
INTN
|
INTN
|
||||||
read_file(UINTN fd, UINTN total_size, CHAR8 *buffer)
|
read_file(UINTN fd, UINTN total_size, CHAR8 *buffer)
|
||||||
{
|
{
|
||||||
INTN size, j=0;
|
UINTN size, j=0;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
CHAR16 helicopter[4] = { L'|' , L'/' , L'-' , L'\\' };
|
CHAR16 helicopter[4] = { L'|' , L'/' , L'-' , L'\\' };
|
||||||
INTN ret = ELILO_LOAD_SUCCESS;
|
INTN ret = ELILO_LOAD_SUCCESS;
|
||||||
|
@ -315,7 +317,7 @@ get_memmap(mmap_desc_t *desc)
|
||||||
}
|
}
|
||||||
desc->map_size += ELILO_MEMMAP_INC;
|
desc->map_size += ELILO_MEMMAP_INC;
|
||||||
}
|
}
|
||||||
DBG_PRT((L"final get_memmap map_size=%ld", desc->map_size));
|
DBG_PRT((L"final get_memmap map_size=%d", desc->map_size));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,13 +158,37 @@ bzImage_probe(CHAR16 *kname)
|
||||||
* Allocate memory for kernel.
|
* Allocate memory for kernel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) {
|
/*
|
||||||
ERR_PRT((L"Could not allocate kernel memory."));
|
* Get correct address for kernel from header, if applicable & available.
|
||||||
return -1;
|
*/
|
||||||
} else {
|
if ((param_start->s.hdr_major == 2) &&
|
||||||
VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n",
|
(param_start->s.hdr_minor >= 6) &&
|
||||||
kernel_start, kernel_size));
|
(param_start->s.kernel_start >= DEFAULT_KERNEL_START)) {
|
||||||
|
kernel_start = (void *)param_start->s.kernel_start;
|
||||||
|
VERB_PRT(3, Print(L"kernel header suggests kernel start at address "PTR_FMT"\n",
|
||||||
|
kernel_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kernel_load_address = kernel_start;
|
||||||
|
|
||||||
|
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
|
||||||
|
/*
|
||||||
|
* Couldn't get desired address--just load it anywhere and move it later.
|
||||||
|
* (Easier than relocating kernel, and also works with non-relocatable kernels.)
|
||||||
|
*/
|
||||||
|
if (alloc_kmem_anywhere(&kernel_load_address, EFI_SIZE_TO_PAGES(kernel_size)) != 0) {
|
||||||
|
ERR_PRT((L"Could not allocate memory for kernel."));
|
||||||
|
free(param_start);
|
||||||
|
param_start = NULL;
|
||||||
|
param_size = 0;
|
||||||
|
fops_close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VERB_PRT(3, Print(L"kernel_start: "PTR_FMT" kernel_size: %d loading at: "PTR_FMT"\n",
|
||||||
|
kernel_start, kernel_size, kernel_load_address));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now read the rest of the kernel image into memory.
|
* Now read the rest of the kernel image into memory.
|
||||||
*/
|
*/
|
||||||
|
@ -172,7 +196,7 @@ bzImage_probe(CHAR16 *kname)
|
||||||
DBG_PRT((L"reading kernel image...\n"));
|
DBG_PRT((L"reading kernel image...\n"));
|
||||||
|
|
||||||
size = kernel_size;
|
size = kernel_size;
|
||||||
efi_status = fops_read(fd, kernel_start, &size);
|
efi_status = fops_read(fd, kernel_load_address, &size);
|
||||||
if (EFI_ERROR(efi_status) || size < 0x10000) {
|
if (EFI_ERROR(efi_status) || size < 0x10000) {
|
||||||
ERR_PRT((L"Error reading kernel image %s.", kname));
|
ERR_PRT((L"Error reading kernel image %s.", kname));
|
||||||
free(param_start);
|
free(param_start);
|
||||||
|
@ -200,7 +224,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
|
||||||
DBG_PRT((L"load_bzImage_boot()\n"));
|
DBG_PRT((L"load_bzImage_boot()\n"));
|
||||||
|
|
||||||
if (!kname || !kd) {
|
if (!kname || !kd) {
|
||||||
ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd));
|
ERR_PRT((L"kname="PTR_FMT" kd="PTR_FMT"", kname, kd));
|
||||||
free(param_start);
|
free(param_start);
|
||||||
param_start = NULL;
|
param_start = NULL;
|
||||||
param_size = 0;
|
param_size = 0;
|
||||||
|
@ -210,7 +234,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
|
||||||
kd->kstart = kd->kentry = kernel_start;
|
kd->kstart = kd->kentry = kernel_start;
|
||||||
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
|
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
|
||||||
|
|
||||||
DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend));
|
DBG_PRT((L"kstart="PTR_FMT" kentry="PTR_FMT" kend="PTR_FMT"\n", kd->kstart, kd->kentry, kd->kend));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ gzip_free(void *where)
|
||||||
int
|
int
|
||||||
fill_inbuf(void)
|
fill_inbuf(void)
|
||||||
{
|
{
|
||||||
INTN expected, nread;
|
UINTN expected, nread;
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
|
|
||||||
expected = nread = INBUFSIZE;
|
expected = nread = INBUFSIZE;
|
||||||
|
@ -280,7 +280,7 @@ analyze_chunks(void)
|
||||||
* the relevant header information.
|
* the relevant header information.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
first_block (const char *buf, long blocksize)
|
first_block (const unsigned char *buf, long blocksize)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr *elf;
|
Elf64_Ehdr *elf;
|
||||||
Elf64_Phdr *phdrs;
|
Elf64_Phdr *phdrs;
|
||||||
|
@ -433,7 +433,7 @@ flush_window(void)
|
||||||
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
|
||||||
static UINTN heli_count;
|
static UINTN heli_count;
|
||||||
struct segment *cp;
|
struct segment *cp;
|
||||||
char *src, *dst;
|
unsigned char *src, *dst;
|
||||||
long cnt;
|
long cnt;
|
||||||
|
|
||||||
if (!outcnt) return;
|
if (!outcnt) return;
|
||||||
|
@ -471,7 +471,7 @@ tail:
|
||||||
file_offset += skip;
|
file_offset += skip;
|
||||||
outcnt -= skip;
|
outcnt -= skip;
|
||||||
}
|
}
|
||||||
dst = (char *)cp->addr + (file_offset - cp->offset);
|
dst = (unsigned char *)cp->addr + (file_offset - cp->offset);
|
||||||
cnt = cp->offset + cp->size - file_offset;
|
cnt = cp->offset + cp->size - file_offset;
|
||||||
if (cnt > outcnt)
|
if (cnt > outcnt)
|
||||||
cnt = outcnt;
|
cnt = outcnt;
|
||||||
|
@ -485,7 +485,7 @@ tail:
|
||||||
/* See if we are at the end of this chunk */
|
/* See if we are at the end of this chunk */
|
||||||
if (file_offset == cp->offset + cp->size) {
|
if (file_offset == cp->offset + cp->size) {
|
||||||
if (cp->bss_sz) {
|
if (cp->bss_sz) {
|
||||||
dst = (char *)cp->addr + cp->size;
|
dst = (unsigned char *)cp->addr + cp->size;
|
||||||
Memset(dst, 0, cp->bss_sz);
|
Memset(dst, 0, cp->bss_sz);
|
||||||
}
|
}
|
||||||
nextchunk();
|
nextchunk();
|
||||||
|
|
|
@ -119,7 +119,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
}
|
}
|
||||||
VERB_PRT(3, {
|
VERB_PRT(3, {
|
||||||
Print(L"ELF Header information: \n");
|
Print(L"ELF Header information: \n");
|
||||||
Print(L"\tEntry point 0x%x\n", (ehdr.e_entry & PADDR_MASK));
|
Print(L"\tEntry point "PTR_FMT"\n", (ehdr.e_entry & PADDR_MASK));
|
||||||
Print(L"\t%d program headers\n", ehdr.e_phnum);
|
Print(L"\t%d program headers\n", ehdr.e_phnum);
|
||||||
Print(L"\t%d segment headers\n", ehdr.e_shnum);
|
Print(L"\t%d segment headers\n", ehdr.e_shnum);
|
||||||
});
|
});
|
||||||
|
@ -153,8 +153,8 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
paddr = (phdrs[i].p_paddr & PADDR_MASK);
|
paddr = (phdrs[i].p_paddr & PADDR_MASK);
|
||||||
memsz = phdrs[i].p_memsz;
|
memsz = phdrs[i].p_memsz;
|
||||||
|
|
||||||
DBG_PRT((L"Phdr %d paddr [0x%x-0x%x] offset 0x%x"
|
DBG_PRT((L"Phdr %d paddr ["PTR_FMT"-"PTR_FMT"] offset "PTR_FMT""
|
||||||
" filesz 0x%x memsz=0x%x bss_sz=0x%x p_type=0x%x\n",
|
" filesz "PTR_FMT" memsz="PTR_FMT" bss_sz="PTR_FMT" p_type="PTR_FMT"\n",
|
||||||
1+i, paddr, paddr+phdrs[i].p_filesz, phdrs[i].p_offset,
|
1+i, paddr, paddr+phdrs[i].p_filesz, phdrs[i].p_offset,
|
||||||
phdrs[i].p_filesz, memsz,
|
phdrs[i].p_filesz, memsz,
|
||||||
(memsz - phdrs[i].p_filesz), phdrs[i].p_type));
|
(memsz - phdrs[i].p_filesz), phdrs[i].p_type));
|
||||||
|
@ -168,7 +168,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((UINTN)low_addr & (EFI_PAGE_SIZE - 1)) {
|
if ((UINTN)low_addr & (EFI_PAGE_SIZE - 1)) {
|
||||||
ERR_PRT((L"%s : kernel low address 0x%x not page aligned\n",
|
ERR_PRT((L"%s : kernel low address "PTR_FMT" not page aligned\n",
|
||||||
LD_NAME, low_addr));
|
LD_NAME, low_addr));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -184,9 +184,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
|
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
|
||||||
|
|
||||||
VERB_PRT(3, {
|
VERB_PRT(3, {
|
||||||
Print(L"Lowest PhysAddr: 0x%x\nTotalMemSize:%d bytes (%d pages)\n",
|
Print(L"Lowest PhysAddr: "PTR_FMT"\nTotalMemSize:%d bytes (%d pages)\n",
|
||||||
low_addr, total_size, pages);
|
low_addr, total_size, pages);
|
||||||
Print(L"Kernel entry @ 0x%x\n", kd->kentry);
|
Print(L"Kernel entry @ "PTR_FMT"\n", kd->kentry);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* now allocate memory for the kernel at the exact requested spot */
|
/* now allocate memory for the kernel at the exact requested spot */
|
||||||
|
@ -213,7 +213,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
if (phdrs[i].p_type != PT_LOAD)
|
if (phdrs[i].p_type != PT_LOAD)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"poffs: 0x%x (phdrs[%d].p_offset)\n",
|
VERB_PRT(3, Print(L"poffs: "PTR_FMT" (phdrs[%d].p_offset)\n",
|
||||||
phdrs[i].p_offset, i));
|
phdrs[i].p_offset, i));
|
||||||
|
|
||||||
filesz = phdrs[i].p_filesz;
|
filesz = phdrs[i].p_filesz;
|
||||||
|
@ -228,9 +228,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
|
||||||
|
|
||||||
VERB_PRT(4, {
|
VERB_PRT(4, {
|
||||||
Print(L"\nHeader #%d\n", i);
|
Print(L"\nHeader #%d\n", i);
|
||||||
Print(L"Offset in file 0x%x\n", phdrs[i].p_offset);
|
Print(L"Offset in file "PTR_FMT"\n", phdrs[i].p_offset);
|
||||||
Print(L"Physical addr 0x%x\n", low_addr);
|
Print(L"Physical addr "PTR_FMT"\n", low_addr);
|
||||||
Print(L"BSS size 0x%x bytes\n", bss_sz);
|
Print(L"BSS size %d bytes\n", bss_sz);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -47,6 +47,10 @@
|
||||||
*/
|
*/
|
||||||
#define INITRD_START (50*1024*1024)
|
#define INITRD_START (50*1024*1024)
|
||||||
|
|
||||||
|
/* Default start address for kernel. */
|
||||||
|
#define DEFAULT_KERNEL_START 0x100000
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This version must match the one in the kernel.
|
* This version must match the one in the kernel.
|
||||||
*
|
*
|
||||||
|
@ -307,10 +311,16 @@ typedef union x86_64_boot_params {
|
||||||
UINT8 *t = (UINT8 *)(to); \
|
UINT8 *t = (UINT8 *)(to); \
|
||||||
UINT8 *f = (UINT8 *)(from); \
|
UINT8 *f = (UINT8 *)(from); \
|
||||||
UINTN n = cnt; \
|
UINTN n = cnt; \
|
||||||
if (t && f && n) { \
|
if (t && f && n && (t<f)) { \
|
||||||
while (n--) { \
|
while (n--) { \
|
||||||
*t++ = *f++; \
|
*t++ = *f++; \
|
||||||
} \
|
} \
|
||||||
|
} else if (t && f && n && (t>f)) { \
|
||||||
|
t += n; \
|
||||||
|
f += n; \
|
||||||
|
while (n--) { \
|
||||||
|
*t-- = *f--; \
|
||||||
|
} \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +353,7 @@ extern UINTN param_size;
|
||||||
|
|
||||||
extern VOID *kernel_start;
|
extern VOID *kernel_start;
|
||||||
extern UINTN kernel_size;
|
extern UINTN kernel_size;
|
||||||
|
extern VOID *kernel_load_address;
|
||||||
|
|
||||||
extern VOID *initrd_start;
|
extern VOID *initrd_start;
|
||||||
extern UINTN initrd_size;
|
extern UINTN initrd_size;
|
||||||
|
@ -370,8 +381,8 @@ start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
UINT32 kernel_entry;
|
UINT32 kernel_entry;
|
||||||
UINT16 kernel_cs;
|
UINT16 kernel_cs;
|
||||||
} jumpvector;
|
} jumpvector;
|
||||||
UINTN njump;
|
|
||||||
VOID *jump_start;
|
VOID *jump_start;
|
||||||
|
uint64_t temp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable interrupts.
|
* Disable interrupts.
|
||||||
|
@ -379,11 +390,20 @@ start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
asm volatile ( "cli" : : );
|
asm volatile ( "cli" : : );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Relocate initrd, if present.
|
* Relocate kernel (if needed), and initrd (if present).
|
||||||
|
* Copy kernel first, in case kernel was loaded overlapping where we're
|
||||||
|
* planning to copy the initrd. This assumes that the initrd didn't
|
||||||
|
* get loaded overlapping where we're planning to copy the kernel, but
|
||||||
|
* that's pretty unlikely since we couldn't alloc that space for the
|
||||||
|
* kernel (or the kernel would already be there).
|
||||||
*/
|
*/
|
||||||
|
if (kernel_start != kernel_load_address) {
|
||||||
|
MEMCPY(kernel_start, kernel_load_address, kernel_size);
|
||||||
|
}
|
||||||
|
|
||||||
if (bp->s.initrd_start) {
|
if (bp->s.initrd_start) {
|
||||||
MEMCPY(INITRD_START, bp->s.initrd_start, bp->s.initrd_size);
|
temp = bp->s.initrd_start;
|
||||||
|
MEMCPY(INITRD_START, temp , bp->s.initrd_size);
|
||||||
bp->s.initrd_start = INITRD_START;
|
bp->s.initrd_start = INITRD_START;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -434,14 +454,15 @@ start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Jump to kernel entry point.
|
* Jump to kernel entry point.
|
||||||
|
*
|
||||||
|
* Cast is to tell gcc that we know we're going from
|
||||||
|
* 64-bit ptr to 32-bit integer.
|
||||||
*/
|
*/
|
||||||
jumpvector.kernel_entry=kentry;
|
jumpvector.kernel_entry=(UINT32)((UINT64)kentry);
|
||||||
jumpvector.kernel_cs=0x10;
|
jumpvector.kernel_cs=0x10;
|
||||||
njump = &jumpvector;
|
|
||||||
jump_start = (VOID *)&jumpvector;
|
jump_start = (VOID *)&jumpvector;
|
||||||
//asm volatile ( "mov %0, %%rcx" : : "m" (&jumpvector) );
|
//asm volatile ( "mov %0, %%rcx" : : "m" (&jumpvector) );
|
||||||
asm volatile ( "mov %0, %%rcx" : : "m" (jump_start) );
|
asm volatile ( "mov %0, %%rcx" : : "m" (jump_start) );
|
||||||
//asm volatile ( "mov %0, %%rcx" : : "m" (njump) );
|
|
||||||
asm volatile ( "ljmp *(%%rcx)" : :);
|
asm volatile ( "ljmp *(%%rcx)" : :);
|
||||||
/* Never come back to here. */
|
/* Never come back to here. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,10 @@ UINTN high_base_mem = 0x90000;
|
||||||
UINTN high_ext_mem = 32 * 1024 * 1024;
|
UINTN high_ext_mem = 32 * 1024 * 1024;
|
||||||
|
|
||||||
/* This starting address will hold true for all of the loader types for now */
|
/* This starting address will hold true for all of the loader types for now */
|
||||||
VOID *kernel_start = (VOID *)0x100000; /* 1M */
|
VOID *kernel_start = (void *)DEFAULT_KERNEL_START;
|
||||||
|
|
||||||
|
/* The kernel may load elsewhere if EFI firmware reserves kernel_start */
|
||||||
|
VOID *kernel_load_address = DEFAULT_KERNEL_START;
|
||||||
|
|
||||||
VOID *initrd_start = NULL;
|
VOID *initrd_start = NULL;
|
||||||
UINTN initrd_size = 0;
|
UINTN initrd_size = 0;
|
||||||
|
@ -139,16 +142,16 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
|
||||||
DBG_PRT((L"initrd_get_addr()\n"));
|
DBG_PRT((L"initrd_get_addr()\n"));
|
||||||
|
|
||||||
if (!kd || !imem) {
|
if (!kd || !imem) {
|
||||||
ERR_PRT((L"kd=0x%x imem=0x%x", kd, imem));
|
ERR_PRT((L"kd="PTR_FMT" imem="PTR_FMT"", kd, imem));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"kstart=0x%x kentry=0x%x kend=0x%x\n",
|
VERB_PRT(3, Print(L"kstart="PTR_FMT" kentry="PTR_FMT" kend="PTR_FMT"\n",
|
||||||
kd->kstart, kd->kentry, kd->kend));
|
kd->kstart, kd->kentry, kd->kend));
|
||||||
|
|
||||||
imem->start_addr = kd->kend;
|
imem->start_addr = kd->kend;
|
||||||
|
|
||||||
VERB_PRT(3, Print(L"initrd start_addr=0x%x pgcnt=%d\n",
|
VERB_PRT(3, Print(L"initrd start_addr="PTR_FMT" pgcnt=%d\n",
|
||||||
imem->start_addr, imem->pgcnt));
|
imem->start_addr, imem->pgcnt));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -160,7 +163,7 @@ sysdeps_free_boot_params(boot_params_t *bp)
|
||||||
mmap_desc_t md;
|
mmap_desc_t md;
|
||||||
|
|
||||||
ZeroMem(&md, sizeof md);
|
ZeroMem(&md, sizeof md);
|
||||||
md.md = (VOID *)bp->s.efi_mem_map;
|
md.md = (VOID *)(UINT64)bp->s.efi_mem_map;
|
||||||
free_memmap(&md);
|
free_memmap(&md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +192,11 @@ static INTN get_video_info(boot_params_t * bp) {
|
||||||
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
|
||||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
|
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode;
|
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode = NULL;
|
||||||
EFI_HANDLE *Gop_handle;
|
EFI_HANDLE *Gop_handle = NULL;
|
||||||
EFI_STATUS efi_status;
|
EFI_STATUS efi_status;
|
||||||
UINTN size, size1;
|
UINTN size = 0;
|
||||||
|
UINTN size1;
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
efi_status = uefi_call_wrapper(
|
efi_status = uefi_call_wrapper(
|
||||||
|
@ -459,7 +463,7 @@ sysdeps_create_boot_params(
|
||||||
DBG_PRT((L"fill_boot_params()\n"));
|
DBG_PRT((L"fill_boot_params()\n"));
|
||||||
|
|
||||||
if (!bp || !cmdline || !initrd || !cookie) {
|
if (!bp || !cmdline || !initrd || !cookie) {
|
||||||
ERR_PRT((L"bp=0x%x cmdline=0x%x initrd=0x%x cookie=0x%x",
|
ERR_PRT((L"bp="PTR_FMT" cmdline="PTR_FMT" initrd="PTR_FMT" cookie="PTR_FMT"",
|
||||||
bp, cmdline, initrd, cookie));
|
bp, cmdline, initrd, cookie));
|
||||||
|
|
||||||
if (param_start != NULL) {
|
if (param_start != NULL) {
|
||||||
|
@ -546,7 +550,7 @@ sysdeps_create_boot_params(
|
||||||
* Initial RAMdisk and root device stuff.
|
* Initial RAMdisk and root device stuff.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DBG_PRT((L"initrd->start_addr=0x%x initrd->pgcnt=%d\n",
|
DBG_PRT((L"initrd->start_addr="PTR_FMT" initrd->pgcnt=%d\n",
|
||||||
initrd->start_addr, initrd->pgcnt));
|
initrd->start_addr, initrd->pgcnt));
|
||||||
|
|
||||||
/* These RAMdisk flags are not needed, just zero them. */
|
/* These RAMdisk flags are not needed, just zero them. */
|
||||||
|
@ -554,7 +558,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)(UINT64)initrd->start_addr;
|
||||||
bp->s.initrd_size = (UINT32)(initrd->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
|
||||||
|
@ -598,7 +602,7 @@ sysdeps_create_boot_params(
|
||||||
/*
|
/*
|
||||||
* Kernel entry point.
|
* Kernel entry point.
|
||||||
*/
|
*/
|
||||||
bp->s.kernel_start = (UINT32)kernel_start;
|
bp->s.kernel_start = (UINT32)(UINT64)kernel_start;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When changing stuff in the parameter structure compare
|
* When changing stuff in the parameter structure compare
|
||||||
|
|
Loading…
Reference in a new issue