release 3.10

https://sourceforge.net/projects/elilo/files/elilo/elilo-3.10/

(sans a few CVS directories)
This commit is contained in:
Stephane Eranian 2009-04-03 09:38:32 -04:00 committed by Vincent Batts
parent 34d8003a54
commit 4e87874a03
35 changed files with 412 additions and 235 deletions

View file

@ -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>
* Patch contribution from Scott Davilla <davilla@4pi.com>
when x is zero for the first call to add_memory_region, e820_map[-1]

View file

@ -68,7 +68,7 @@ CPPFLAGS = -DCONFIG_$(ARCH)
OPTIMFLAGS = -O2
DEBUGFLAGS = -Wall
CFLAGS = $(OPTIMFLAGS) -fpic -fshort-wchar $(DEBUGFLAGS)
CFLAGS = $(OPTIMFLAGS) -fno-strict-aliasing -fpic -fshort-wchar $(DEBUGFLAGS)
LDFLAGS = -nostdlib -znocombreloc
INSTALL = install

27
alloc.c
View file

@ -105,12 +105,12 @@ alloc(UINTN size, EFI_MEMORY_TYPE type)
status = uefi_call_wrapper(BS->AllocatePool, 3, type, size, &tmp);
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;
}
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;
}
@ -158,10 +158,10 @@ free(VOID *addr)
if (p->addr == addr) goto 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;
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",
addr, p->size));
@ -195,7 +195,7 @@ free_all(VOID)
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)
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
alloc_kmem(VOID *start_addr, UINTN pgcnt)
{
@ -226,13 +239,13 @@ alloc_kmem(VOID *start_addr, UINTN pgcnt)
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) {
free(kmem_addr);
kmem_addr = NULL;
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

View file

@ -56,7 +56,7 @@ static EFI_GUID altk_guid={0,};
* Please note that no fatal error is reported by this function
*/
INTN
alternate_kernel(CHAR16 *buffer, INTN size)
alternate_kernel(CHAR16 *buffer, UINTN size)
{
EFI_STATUS status;
INTN ret = -1;

View file

@ -78,7 +78,7 @@ create_boot_params(CHAR16 *args, memdesc_t *initrd, memdesc_t *vmcode, UINTN *co
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 */
#ifdef CONFIG_ia64

View file

@ -220,7 +220,7 @@ display_message(VOID)
{
fops_fd_t fd;
EFI_STATUS status;
INTN len, i;
UINTN len, i;
CHAR16 *filename;
CHAR8 buf[256];

View file

@ -186,12 +186,12 @@ paint_menu(VOID)
}
static INTN
read_message_file(INTN msg, INT8 *buf, INTN max)
read_message_file(INTN msg, UINT8 *buf, UINTN max)
{
CHAR16 *filename;
fops_fd_t message_fd;
EFI_STATUS status;
INTN len = max;
UINTN len = max;
if (msg > 10) return 0;

Binary file not shown.

Binary file not shown.

Binary file not shown.

16
elilo.c
View file

@ -46,13 +46,15 @@
#include "loader.h"
#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"
elilo_config_t elilo_opt;
EFI_SYSTEM_TABLE *systab; /* pointer to EFI system table */
extern INTN wait_timeout (UINTN);
/*
* Load the Linux kernel in memory from the boot media
* Output:
@ -127,11 +129,12 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memde
return ELILO_LOAD_RETRY;
}
VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n",
(unsigned long)kd->kstart, (unsigned long)kd->kend, (unsigned long)kd->kentry));
VERB_PRT(3, Print(L"kernel loaded in [" PTR_FMT "-" PTR_FMT "] entry=" PTR_FMT "\n",
kd->kstart, kd->kend, kd->kentry));
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;
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));
/* 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) */
close_devices();
@ -455,7 +461,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
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
*/
@ -599,7 +605,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
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...

View file

@ -31,6 +31,12 @@
#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 "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_all(VOID);
extern INTN alloc_kmem(VOID *, UINTN);
extern INTN alloc_kmem_anywhere(VOID **, UINTN);
extern VOID free_kmem(VOID);
extern VOID free_all_memory(VOID);
@ -183,7 +190,7 @@ extern CHAR16 *get_config_file(VOID);
extern INTN load_file(CHAR16 *, memdesc_t *);
/* from alternate.c */
extern INTN alternate_kernel(CHAR16 *, INTN);
extern INTN alternate_kernel(CHAR16 *, UINTN);
/* from bootparams.c */
extern VOID *create_boot_params (CHAR16 *, memdesc_t *, memdesc_t *, UINTN *);

View file

@ -142,7 +142,7 @@ read_bytes(EFI_BLOCK_IO *blkio, UINT32 mediaid, UINTN offset, VOID *addr, UINTN
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);
if (EFI_ERROR(status)) {
@ -903,7 +903,7 @@ ext2fs_install_one(EFI_HANDLE dev, VOID **intf)
}
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;
}

View file

@ -323,7 +323,7 @@ netfs_open(netfs_interface_t *this, CHAR16 *name, UINTN *fd)
retry:
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:
@ -349,7 +349,7 @@ retry:
NULL,
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,
f->netbuf,
f->netbuf_size,

View file

@ -47,7 +47,7 @@ bzImage_probe(CHAR16 *kname)
DBG_PRT((L"probe_bzImage_boot()\n"));
if (!kname) {
ERR_PRT((L"kname == %xh", kname));
ERR_PRT((L"kname == " PTR_FMT, kname));
free_kmem();
return -1;
}
@ -110,7 +110,7 @@ bzImage_probe(CHAR16 *kname)
param_size = (bootsect[0x1F1] + 1) * 512;
param_start = alloc(param_size, EfiLoaderData);
DBG_PRT((L"param_size=%d param_start=%x", param_size, param_start));
DBG_PRT((L"param_size=%d param_start=" PTR_FMT, param_size, param_start));
if (!param_start) {
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;
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]));
}
if (CompareMem(((UINT8 *)param_start) + 514, "HdrS", 4)) {
@ -158,13 +158,38 @@ bzImage_probe(CHAR16 *kname)
* Allocate memory for kernel.
*/
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) {
ERR_PRT((L"Could not allocate kernel memory."));
return -1;
} else {
VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n",
kernel_start, kernel_size));
/*
* Get correct address for kernel from header, if applicable & available.
*/
if ((param_start->s.hdr_major == 2) &&
(param_start->s.hdr_minor >= 6) &&
(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.
*/
@ -172,7 +197,7 @@ bzImage_probe(CHAR16 *kname)
DBG_PRT((L"reading kernel image...\n"));
size = kernel_size;
efi_status = fops_read(fd, kernel_start, &size);
efi_status = fops_read(fd, kernel_load_address, &size);
if (EFI_ERROR(efi_status) || size < 0x10000) {
ERR_PRT((L"Error reading kernel image %s.", kname));
free(param_start);
@ -200,7 +225,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
DBG_PRT((L"load_bzImage_boot()\n"));
if (!kname || !kd) {
ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd));
ERR_PRT((L"kname=" PTR_FMT " kd=" PTR_FMT, kname, kd));
free(param_start);
param_start = NULL;
param_size = 0;
@ -210,7 +235,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
kd->kstart = kd->kentry = kernel_start;
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend));
DBG_PRT((L"kstart=" PTR_FMT " kentry=" PTR_FMT " kend=" PTR_FMT "\n", kd->kstart, kd->kentry, kd->kend));
return 0;
}

View file

@ -153,7 +153,7 @@ gzip_free(void *where)
int
fill_inbuf(void)
{
INTN expected, nread;
UINTN expected, nread;
EFI_STATUS status;
expected = nread = INBUFSIZE;
@ -277,7 +277,7 @@ analyze_chunks(void)
* the relevant header information.
*/
int
first_block (const char *buf, long blocksize)
first_block (const unsigned char *buf, long blocksize)
{
Elf32_Ehdr *elf;
Elf32_Phdr *phdrs;
@ -297,13 +297,13 @@ first_block (const char *buf, long blocksize)
phnum = elf->e_phnum;
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 segment headers\n", elf->e_shnum);
});
if (offs + phnum * sizeof(*phdrs) > (unsigned) blocksize) {
ERR_PRT((L"%s : ELF program headers not in first block (%ld)\n", LD_NAME, offs));
ERR_PRT((L"%s : ELF program headers not in first block (%d)\n", LD_NAME, offs));
return -1;
}
@ -345,15 +345,15 @@ first_block (const char *buf, long blocksize)
if (phdrs[i].p_type != PT_LOAD) {
CHUNK_NO_LOAD(i); /* mark no load chunk */
DBG_PRT((L"%s : skipping segment %ld\n", LD_NAME, i));
DBG_PRT((L"%s : skipping segment %d\n", LD_NAME, i));
continue;
}
CHUNK_CAN_LOAD(i); /* mark no load chunk */
VERB_PRT(3,
Print(L"\n%s : segment %ld vaddr [0x%lx-0x%lx] offset %ld filesz %ld "
"memsz=%ld bss_sz=%ld\n",
Print(L"\n%s : segment %d vaddr ["PTR_FMT"-"PTR_FMT"] offset %d filesz %d "
"memsz=%d bss_sz=%d\n",
LD_NAME, 1+i, chunks[i].addr, chunks[i].addr+phdrs[i].p_filesz,
chunks[i].offset, chunks[i].size, memsz, chunks[i].bss_sz));
@ -364,12 +364,12 @@ first_block (const char *buf, long blocksize)
}
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;
}
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,
phnum, kernel_entry, low_addr, max_addr));
@ -384,9 +384,9 @@ first_block (const char *buf, long blocksize)
/* allocate memory for the kernel */
if (alloc_kmem((void *)low_addr, pages) == -1) {
ERR_PRT((L"%s : AllocatePages(%d, 0x%lx) for kernel failed\n",
ERR_PRT((L"%s : AllocatePages(%d, "PTR_FMT") for kernel failed\n",
LD_NAME, pages, low_addr));
ERR_PRT((L"%s : Could not load kernel at 0x%lx\n", LD_NAME, low_addr));
ERR_PRT((L"%s : Could not load kernel at "PTR_FMT"\n", LD_NAME, low_addr));
ERR_PRT((L"%s : Bailing\n", LD_NAME));
goto error;
}
@ -430,12 +430,12 @@ flush_window(void)
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
static UINTN heli_count;
struct segment *cp;
char *src, *dst;
unsigned char *src, *dst;
long cnt;
if (!outcnt) return;
DBG_PRT((L"%s : flush_window outnct=%d file_offset=%ld\n", LD_NAME, outcnt, file_offset));
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]);
@ -468,7 +468,7 @@ tail:
file_offset += 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;
if (cnt > outcnt)
cnt = outcnt;
@ -482,7 +482,7 @@ tail:
/* See if we are at the end of this chunk */
if (file_offset == cp->offset + cp->size) {
if (cp->bss_sz) {
dst = (char *)cp->addr + cp->size;
dst = (unsigned char *)cp->addr + cp->size;
Memset(dst, 0, cp->bss_sz);
}
nextchunk();

View file

@ -111,7 +111,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
}
VERB_PRT(3, {
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 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);
memsz = phdrs[i].p_memsz;
DBG_PRT((L"Phdr %d paddr [0x%x-0x%x] offset 0x%x"
" filesz 0x%x memsz=0x%x bss_sz=0x%x p_type=0x%x\n",
DBG_PRT((L"Phdr %d paddr ["PTR_FMT"-"PTR_FMT"] offset "PTR_FMT""
" 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,
phdrs[i].p_filesz, memsz,
(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)) {
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));
goto out;
}
@ -176,16 +176,16 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
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);
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 */
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));
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",
LD_NAME, pages, low_addr));
goto load_abort;
@ -206,7 +206,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
if (phdrs[i].p_type != PT_LOAD)
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));
filesz = phdrs[i].p_filesz;
@ -221,9 +221,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
VERB_PRT(4, {
Print(L"\nHeader #%d\n", i);
Print(L"Offset in file 0x%x\n", phdrs[i].p_offset);
Print(L"Physical addr 0x%x\n", low_addr);
Print(L"BSS size 0x%x bytes\n", bss_sz);
Print(L"Offset in file "PTR_FMT"\n", phdrs[i].p_offset);
Print(L"Physical addr "PTR_FMT"\n", low_addr);
Print(L"BSS size %d bytes\n", bss_sz);
});
/*

View file

@ -35,6 +35,9 @@
#define ELILO_ARCH "IA-32" /* ASCII string */
#define PADDR_MASK 0xfffffff
#define INITRD_START (15*1024*1024)
#define DEFAULT_KERNEL_START 0x100000
/* for now use library versions */
#define Memset(a,v,n) SetMem((a),(n),(v))
#define Memcpy(a,b,n) CopyMem((a),(b),(n))
@ -299,10 +302,16 @@ typedef union ia32_boot_params {
UINT8 *t = (UINT8 *)(to); \
UINT8 *f = (UINT8 *)(from); \
UINTN n = cnt; \
if (t && f && n) { \
if (t && f && n && (t<f)) { \
while (n--) { \
*t++ = *f++; \
} \
} else if (t && f && n && (t>f)) { \
t += n; \
f += n; \
while (n--) { \
*t-- = *f--; \
} \
} \
}
@ -338,6 +347,7 @@ extern UINTN kernel_size;
extern VOID *initrd_start;
extern UINTN initrd_size;
extern VOID *kernel_load_address;
extern dt_addr_t gdt_addr;
extern dt_addr_t idt_addr;
@ -357,19 +367,31 @@ extern INTN ia32_use_legacy_free_boot();
static inline void
start_kernel(VOID *kentry, boot_params_t *bp)
{
UINT32 temp;
/*
* Disable interrupts.
*/
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) {
MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size);
bp->s.initrd_start = 15 * 1024 * 1024;
temp = bp->s.initrd_start;
MEMCPY(INITRD_START, temp , bp->s.initrd_size);
bp->s.initrd_start = INITRD_START;
}
/*
* Copy boot sector, setup data and command line
* to final resting place. We need to copy

View file

@ -97,7 +97,10 @@ UINTN high_base_mem = 0x90000;
UINTN high_ext_mem = 32 * 1024 * 1024;
/* This starting address will hold true for all of the loader types for now */
VOID *kernel_start = (VOID *)0x100000; /* 1M */
VOID *kernel_start = (VOID *)DEFAULT_KERNEL_START;
/* The kernel may load elsewhere if EFI firmware reserves kernel_start */
VOID *kernel_load_address = (VOID *)DEFAULT_KERNEL_START;
VOID *initrd_start = NULL;
UINTN initrd_size = 0;
@ -131,16 +134,16 @@ sysdeps_initrd_get_addr(kdesc_t *kd, memdesc_t *imem)
DBG_PRT((L"initrd_get_addr()\n"));
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;
}
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));
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));
return 0;
@ -156,6 +159,24 @@ sysdeps_free_boot_params(boot_params_t *bp)
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.
*/
@ -163,10 +184,11 @@ static INTN get_video_info(boot_params_t * bp) {
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode;
EFI_HANDLE *Gop_handle;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode = NULL;
EFI_HANDLE *Gop_handle = NULL;
EFI_STATUS efi_status;
UINTN size, size1;
UINTN size = 0;
UINTN size1;
UINT8 i;
efi_status = uefi_call_wrapper(
@ -204,7 +226,7 @@ static INTN get_video_info(boot_params_t * bp) {
3,
*Gop_handle,
&GopProtocol,
&Gop_interface);
(VOID **) &Gop_interface);
if (EFI_ERROR(efi_status)) {
continue;
@ -428,7 +450,7 @@ sysdeps_create_boot_params(
DBG_PRT((L"fill_boot_params()\n"));
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));
if (param_start != NULL) {
@ -515,7 +537,7 @@ sysdeps_create_boot_params(
* 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));
/* These RAMdisk flags are not needed, just zero them. */
@ -597,7 +619,7 @@ sysdeps_create_boot_params(
#define WAIT_FOR_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;
efi_status = ST->ConOut->QueryMode(
efi_status = uefi_call_wrapper(
ST->ConOut->QueryMode,
4,
ST->ConOut,
ST->ConOut->Mode->Mode,
&cols,

View file

@ -132,7 +132,7 @@ check_fpswa(EFI_HANDLE image, EFI_HANDLE dev, CHAR16 *fpswa_file)
#endif
};
UINTN j, count = sizeof(fpswa_filenames)/sizeof(CHAR16 *);
INTN cookie;
UINTN cookie;
CHAR16 devname[FILENAME_MAXLEN];
if (fpswa_file) {

View file

@ -161,7 +161,7 @@ gzip_free(void *where)
int
fill_inbuf(void)
{
INTN expected, nread;
UINTN expected, nread;
EFI_STATUS status;
expected = nread = INBUFSIZE;
@ -309,7 +309,7 @@ analyze_chunks(void)
* the relevant header information.
*/
int
first_block (const char *buf, long blocksize)
first_block (const unsigned char *buf, long blocksize)
{
Elf64_Ehdr *elf;
Elf64_Phdr *phdrs;
@ -439,7 +439,7 @@ first_block (const char *buf, long blocksize)
if (alloc_kmem((void *)low_addr, pages) == -1) {
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) {
ERR_PRT((L"relocation is disabled, cannot load kernel"));
@ -464,7 +464,7 @@ first_block (const char *buf, long blocksize)
/* unsigned arithmetic */
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
@ -526,7 +526,7 @@ flush_window(void)
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
static UINTN heli_count;
struct segment *cp;
char *src, *dst;
unsigned char *src, *dst;
long cnt;
if (!outcnt) return;
@ -565,7 +565,7 @@ tail:
file_offset += 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;
@ -582,7 +582,7 @@ tail:
/* See if we are at the end of this chunk */
if (file_offset == cp->offset + cp->size) {
if (cp->bss_sz) {
dst = (char *)cp->addr + cp->size;
dst = (unsigned char *)cp->addr + cp->size;
Memset(dst, 0, cp->bss_sz);
}
nextchunk();

View file

@ -159,4 +159,4 @@ longjmp:
invala // virt. -> phys. regnum mapping may change
mov pr=r24,-1
br.ret.dptk.few rp
.endp __longjmp
.endp longjmp

View file

@ -288,7 +288,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
if (alloc_kmem(low_addr, pages) == -1) {
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) {
ERR_PRT((L"relocation is disabled, cannot load kernel"));

View file

@ -81,6 +81,7 @@ setjmp:
.proc __sigsetjmp
__sigsetjmp:
//.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
.body
alloc loc1=ar.pfs,2,2,2,0
mov r16=ar.unat
;;
@ -89,6 +90,7 @@ __sigsetjmp:
add r3=8,in0
;;
st8.spill.nta [r2]=sp,16 // r12 (sp)
;;
st8.spill.nta [r3]=gp,16 // r1 (gp)
;;
st8.nta [r2]=r16,16 // save caller's unat
@ -96,13 +98,13 @@ __sigsetjmp:
add r8=0xa0,in0
;;
st8.spill.nta [r2]=r4,16 // r4
;;
st8.spill.nta [r3]=r5,16 // r5
add r9=0xb0,in0
;;
stf.spill.nta [r8]=f2,32
stf.spill.nta [r9]=f3,32
mov loc0=rp
.body
;;
stf.spill.nta [r8]=f4,32
stf.spill.nta [r9]=f5,32
@ -139,6 +141,7 @@ __sigsetjmp:
stf.spill.nta [r9]=f31
st8.spill.nta [r2]=r6,16 // r6
;;
st8.spill.nta [r3]=r7,16 // r7
;;
mov r23=ar.bsp

View file

@ -86,7 +86,7 @@ start_kernel(VOID *kentry, VOID *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)
{
UINT64 result;
@ -95,13 +95,13 @@ __ia64_swab64 (UINT64 x)
return result;
}
static inline const UINT32
static inline UINT32
__ia64_swab32 (UINT32 x)
{
return __ia64_swab64(x) >> 32;
}
static inline const UINT16
static inline UINT16
__ia64_swab16(UINT16 x)
{
return __ia64_swab64(x) >> 48;

View file

@ -1094,10 +1094,10 @@ static int gunzip(void)
error("Input has invalid flags\n");
return -1;
}
(ulg)get_byte(); /* Get timestamp */
((ulg)get_byte()) << 8;
((ulg)get_byte()) << 16;
((ulg)get_byte()) << 24;
(void)get_byte(); /* Get timestamp - 4 bytes */
(void)get_byte();
(void)get_byte();
(void)get_byte();
(void)get_byte(); /* Ignore extra flags for the moment */
(void)get_byte(); /* Ignore OS type for the moment */

View file

@ -77,9 +77,9 @@ load_file(CHAR16 *filename, memdesc_t *image)
filename));
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,
(UINTN)start_addr, pgcnt));
start_addr, pgcnt));
Print(L"Loading file %s...", filename);

View file

@ -38,12 +38,18 @@ loader_ops_t *
loader_probe(CHAR16 *kname)
{
loader_ops_t *ops;
UINTN n = 0;
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) {
return ops;
}
}
if (!n) {
ERR_PRT((L"No loaders registered"));
}
return NULL;
}

View file

@ -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
(for all archs due to the new uefi call wrappers).
** If you use the upstream tarballs for the toolchain you will need to move
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
2. gcc-4.1.1 or >
3. binutils-2.17.50.0.14 or > with Intel64 EFI support
*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.
BINUTILS (provides the elf conversion utility to produce efi bins)
--------
likewise objcopy may be installed to /usr/local/bin by binutils,
elilo source expects it to be in /usr/bin.
Implementation:
--------------
Calls to EFI services in x86_64 require a wrapper to pass the arguments
in the appropriate manner. This is implemented with efi wrapper.
For IA32 and IA64, the wrapper is a macro that merely calls the
EFI services directly. The elilo source has been modified to use the
efi wrapper implemented in the gnu-efi-3.0d library.
elilo for x86_64 and its dependent libraries are built and the final
ELF image is converted into PE-COFF image using the objcopy supported
by binutils-2.17.50.0.14 or above with Intel64 EFI support.
On UEFI 2.0 firmware, only Graphics Output Protocol (GOP) is supported.
The x86_64 elilo first queries video information from GOP failing which
it queries for text mode support. The video information is passed to
Linux kernel via boot parameter. The GOP support requires
Linux kernel EFI framebuffer driver (kernel configuration option).
Booting on EFI/x86_64 platforms
-----------------------------
To use elilo on x86_64, you can put it on a floppy and
on a FAT32 partition (msdos partition). You can also
netboot if your network adapter has support for UNDI/PXE.
Elilo/x86_64 requires efi64 enabled linux kernel (> 2.6.21).
You need to compile the kernel with CONFIG_EFI option.
ELILO ON EFI X86_64
=====================
HARD REQUIREMENTS
Elilo/x86_64 requires efi64 enabled linux kernel i.e. 2.6.21 or newer
nothing earlier will work, 2.6.21 was the earliest kernel that efi64
support went into. You need to compile the kernel with CONFIG_EFI
kernel option ON.
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.
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.
The x86_64 implementation converts the EFI memory map into E820 map and
passes it in the bootparameter supplied to the kernel. For details on
bootparameter, see x86_64/sysdeps.h.
WORKING ELILO.CONF FOR EFI X86_64 EXAMPLE
Here is my elilo.conf from my UEFI2.0/x86_64 workstation which uses GOP.
shows me console output, what elilo is doing, and kernel boot.
default=UBUNTU
chooser=simple
verbose=5
delay=30
append="root=/dev/sda3 vga=0x31e splash showopts"
image=/vmlinuz-2.6.24-23-generic
label="UBUNTU"
description="Ubuntu 2.6.24-23-generic kernel"
initrd=/initrd.img-2.6.24-23-generic
CHANGES FROM 3.8 TO 3.10
========================
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
View file

@ -134,8 +134,10 @@ wait_timeout(UINTN timeout)
ERR_PRT((L"waitkey WaitForEvent failed %r", status));
return -1;
}
if (timeout % 10 == 1) Print(L".");
} while (timeout-- && idx == 0);
Print(L"\n");
/*
* 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
read_file(UINTN fd, UINTN total_size, CHAR8 *buffer)
{
INTN size, j=0;
UINTN size, j=0;
EFI_STATUS status;
CHAR16 helicopter[4] = { L'|' , L'/' , L'-' , L'\\' };
INTN ret = ELILO_LOAD_SUCCESS;
@ -315,7 +317,7 @@ get_memmap(mmap_desc_t *desc)
}
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;
}

View file

@ -158,13 +158,37 @@ bzImage_probe(CHAR16 *kname)
* Allocate memory for kernel.
*/
if (alloc_kmem(kernel_start, EFI_SIZE_TO_PAGES(kernel_size))) {
ERR_PRT((L"Could not allocate kernel memory."));
return -1;
} else {
VERB_PRT(3, Print(L"kernel_start: 0x%x kernel_size: %d\n",
kernel_start, kernel_size));
/*
* Get correct address for kernel from header, if applicable & available.
*/
if ((param_start->s.hdr_major == 2) &&
(param_start->s.hdr_minor >= 6) &&
(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.
*/
@ -172,7 +196,7 @@ bzImage_probe(CHAR16 *kname)
DBG_PRT((L"reading kernel image...\n"));
size = kernel_size;
efi_status = fops_read(fd, kernel_start, &size);
efi_status = fops_read(fd, kernel_load_address, &size);
if (EFI_ERROR(efi_status) || size < 0x10000) {
ERR_PRT((L"Error reading kernel image %s.", kname));
free(param_start);
@ -200,7 +224,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
DBG_PRT((L"load_bzImage_boot()\n"));
if (!kname || !kd) {
ERR_PRT((L"kname=0x%x kd=0x%x", kname, kd));
ERR_PRT((L"kname="PTR_FMT" kd="PTR_FMT"", kname, kd));
free(param_start);
param_start = NULL;
param_size = 0;
@ -210,7 +234,7 @@ bzImage_load(CHAR16 *kname, kdesc_t *kd)
kd->kstart = kd->kentry = kernel_start;
kd->kend = ((UINT8 *)kd->kstart) + kernel_size;
DBG_PRT((L"kstart=0x%x kentry=0x%x kend=0x%x\n", kd->kstart, kd->kentry, kd->kend));
DBG_PRT((L"kstart="PTR_FMT" kentry="PTR_FMT" kend="PTR_FMT"\n", kd->kstart, kd->kentry, kd->kend));
return 0;
}

View file

@ -156,7 +156,7 @@ gzip_free(void *where)
int
fill_inbuf(void)
{
INTN expected, nread;
UINTN expected, nread;
EFI_STATUS status;
expected = nread = INBUFSIZE;
@ -280,7 +280,7 @@ analyze_chunks(void)
* the relevant header information.
*/
int
first_block (const char *buf, long blocksize)
first_block (const unsigned char *buf, long blocksize)
{
Elf64_Ehdr *elf;
Elf64_Phdr *phdrs;
@ -433,7 +433,7 @@ flush_window(void)
static const CHAR8 helicopter[4] = { '|' , '/' , '-' , '\\' };
static UINTN heli_count;
struct segment *cp;
char *src, *dst;
unsigned char *src, *dst;
long cnt;
if (!outcnt) return;
@ -471,7 +471,7 @@ tail:
file_offset += 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;
if (cnt > outcnt)
cnt = outcnt;
@ -485,7 +485,7 @@ tail:
/* See if we are at the end of this chunk */
if (file_offset == cp->offset + cp->size) {
if (cp->bss_sz) {
dst = (char *)cp->addr + cp->size;
dst = (unsigned char *)cp->addr + cp->size;
Memset(dst, 0, cp->bss_sz);
}
nextchunk();

View file

@ -119,7 +119,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
}
VERB_PRT(3, {
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 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);
memsz = phdrs[i].p_memsz;
DBG_PRT((L"Phdr %d paddr [0x%x-0x%x] offset 0x%x"
" filesz 0x%x memsz=0x%x bss_sz=0x%x p_type=0x%x\n",
DBG_PRT((L"Phdr %d paddr ["PTR_FMT"-"PTR_FMT"] offset "PTR_FMT""
" 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,
phdrs[i].p_filesz, memsz,
(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)) {
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));
goto out;
}
@ -184,9 +184,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
kd->kentry = (VOID *)(ehdr.e_entry & PADDR_MASK);
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);
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 */
@ -213,7 +213,7 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
if (phdrs[i].p_type != PT_LOAD)
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));
filesz = phdrs[i].p_filesz;
@ -228,9 +228,9 @@ load_elf(fops_fd_t fd, kdesc_t *kd)
VERB_PRT(4, {
Print(L"\nHeader #%d\n", i);
Print(L"Offset in file 0x%x\n", phdrs[i].p_offset);
Print(L"Physical addr 0x%x\n", low_addr);
Print(L"BSS size 0x%x bytes\n", bss_sz);
Print(L"Offset in file "PTR_FMT"\n", phdrs[i].p_offset);
Print(L"Physical addr "PTR_FMT"\n", low_addr);
Print(L"BSS size %d bytes\n", bss_sz);
});
/*

View file

@ -47,6 +47,10 @@
*/
#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.
*
@ -307,10 +311,16 @@ typedef union x86_64_boot_params {
UINT8 *t = (UINT8 *)(to); \
UINT8 *f = (UINT8 *)(from); \
UINTN n = cnt; \
if (t && f && n) { \
if (t && f && n && (t<f)) { \
while (n--) { \
*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 UINTN kernel_size;
extern VOID *kernel_load_address;
extern VOID *initrd_start;
extern UINTN initrd_size;
@ -370,8 +381,8 @@ start_kernel(VOID *kentry, boot_params_t *bp)
UINT32 kernel_entry;
UINT16 kernel_cs;
} jumpvector;
UINTN njump;
VOID *jump_start;
uint64_t temp;
/*
* Disable interrupts.
@ -379,11 +390,20 @@ start_kernel(VOID *kentry, boot_params_t *bp)
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) {
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;
}
/*
@ -434,14 +454,15 @@ start_kernel(VOID *kentry, boot_params_t *bp)
/*
* 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;
njump = &jumpvector;
jump_start = (VOID *)&jumpvector;
//asm volatile ( "mov %0, %%rcx" : : "m" (&jumpvector) );
asm volatile ( "mov %0, %%rcx" : : "m" (jump_start) );
//asm volatile ( "mov %0, %%rcx" : : "m" (njump) );
asm volatile ( "ljmp *(%%rcx)" : :);
/* Never come back to here. */
}

View file

@ -105,7 +105,10 @@ UINTN high_base_mem = 0x90000;
UINTN high_ext_mem = 32 * 1024 * 1024;
/* This starting address will hold true for all of the loader types for now */
VOID *kernel_start = (VOID *)0x100000; /* 1M */
VOID *kernel_start = (void *)DEFAULT_KERNEL_START;
/* The kernel may load elsewhere if EFI firmware reserves kernel_start */
VOID *kernel_load_address = DEFAULT_KERNEL_START;
VOID *initrd_start = NULL;
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"));
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;
}
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));
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));
return 0;
@ -160,7 +163,7 @@ sysdeps_free_boot_params(boot_params_t *bp)
mmap_desc_t 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);
}
@ -189,10 +192,11 @@ static INTN get_video_info(boot_params_t * bp) {
EFI_GUID GopProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop_interface;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Gop_info;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode;
EFI_HANDLE *Gop_handle;
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Gop_mode = NULL;
EFI_HANDLE *Gop_handle = NULL;
EFI_STATUS efi_status;
UINTN size, size1;
UINTN size = 0;
UINTN size1;
UINT8 i;
efi_status = uefi_call_wrapper(
@ -459,7 +463,7 @@ sysdeps_create_boot_params(
DBG_PRT((L"fill_boot_params()\n"));
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));
if (param_start != NULL) {
@ -546,7 +550,7 @@ sysdeps_create_boot_params(
* 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));
/* These RAMdisk flags are not needed, just zero them. */
@ -554,7 +558,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_start = (UINT32)(UINT64)initrd->start_addr;
bp->s.initrd_size = (UINT32)(initrd->size);
/*
* This is the RAMdisk root device for RedHat 2.2.x
@ -598,7 +602,7 @@ sysdeps_create_boot_params(
/*
* 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