release 3.8
https://sourceforge.net/projects/elilo/files/elilo/elilo-3.8/
This commit is contained in:
parent
97b2a7df25
commit
34d8003a54
13 changed files with 587 additions and 135504 deletions
47
ChangeLog
47
ChangeLog
|
@ -1,3 +1,50 @@
|
||||||
|
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]
|
||||||
|
will access memory outside the bounds of e820_map. While this does
|
||||||
|
not result in any problems as there is a UINT32 unused_8[41] block
|
||||||
|
above the e820_map[0] location that should have been zeroed by the
|
||||||
|
bootloader, the code should not access outside the bounds of
|
||||||
|
structures.
|
||||||
|
2008-01-03 Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* initrd.c -- Let the allocator decide where to grab the memory from
|
||||||
|
the efi memory map. Current start_addr=image->start_addr forces the
|
||||||
|
same efi region everytime, and has a 7mb limit. ramdisk (initrd.img)
|
||||||
|
files larger than 7MB wouldnt fit into the memory region assumed by
|
||||||
|
the image->start_addr resulting in an elilo hang. Leaving start_addr
|
||||||
|
NULL at initialization forces alloc_pages to get a memory region
|
||||||
|
sufficient for the size of the initrd image.
|
||||||
|
2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* bumping version string to 3.8
|
||||||
|
2007-12-19 Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* MORE PATCHES FROM INTEL FOR IA32 X86_64.
|
||||||
|
* Fix compile warning for cmdline_addr assignment.
|
||||||
|
* Fix an issue caused by uninitialized e820_nr_map in fill_e820map.
|
||||||
|
* On some machines, there are too many EFI memory map entries, so that,
|
||||||
|
the number of E820 map entries converted from EFI memory map exceeds
|
||||||
|
the limit (128). This patch fixes this bug by merging consecutive
|
||||||
|
memory map entries with the same type.
|
||||||
|
* CL_MAGIC is not supported by 32-bit boot protocol. So, the kernel
|
||||||
|
command line passing code is changed accordingly.
|
||||||
|
* EFI-2.0 boot support patches have been accepted into Linux kernel
|
||||||
|
2.6.24-rc4 and EFI runtime service patches have been accepted by
|
||||||
|
Linux kernel 2.6.24-rc4-mm1. There are some changes during the
|
||||||
|
merging, so there are some updates for elilo ia32/x86_64 too.
|
||||||
|
* The x86_64 boot parameters of Linux kernel is rearranged to line up
|
||||||
|
with ia32 boot parameters.
|
||||||
|
* 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.
|
||||||
|
* 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.
|
||||||
|
* E820 memory map is added to IA32 to make it possible for
|
||||||
|
Linux kernel not to depend on EFI memory map on EFI 32.
|
||||||
|
2007-09-27 Jason Fleischli <jason.fleischli@hp.com>
|
||||||
|
* updating changelog for last commit that was omitted
|
||||||
|
* incorporating AGriffis patches to enhance parsing
|
||||||
|
passes root= option to kernel options and accounts for -- option
|
||||||
|
designation.
|
||||||
2007-07-19 Jason Fleischli <jason.fleischli@hp.com>
|
2007-07-19 Jason Fleischli <jason.fleischli@hp.com>
|
||||||
* Integrated x86_64 support patches from Chandramouli Narayanan
|
* Integrated x86_64 support patches from Chandramouli Narayanan
|
||||||
<mouli@linux.intel.com> changes summarized in following bullets.
|
<mouli@linux.intel.com> changes summarized in following bullets.
|
||||||
|
|
89
config.c
89
config.c
|
@ -304,7 +304,7 @@ find_option(config_option_group_t *grp, CHAR16 *str)
|
||||||
* - TOK_ERR: in case of (parsing) error
|
* - TOK_ERR: in case of (parsing) error
|
||||||
*/
|
*/
|
||||||
static token_t
|
static token_t
|
||||||
get_token(CHAR16 *str, UINTN maxlen)
|
get_token_core(CHAR16 *str, UINTN maxlen, BOOLEAN rhs)
|
||||||
{
|
{
|
||||||
INTN ch, escaped;
|
INTN ch, escaped;
|
||||||
CHAR16 *here;
|
CHAR16 *here;
|
||||||
|
@ -320,7 +320,7 @@ get_token(CHAR16 *str, UINTN maxlen)
|
||||||
while ((ch = next()), ch != '\n') if (ch == CHAR_EOF) return TOK_EOF;
|
while ((ch = next()), ch != '\n') if (ch == CHAR_EOF) return TOK_EOF;
|
||||||
line_num++;
|
line_num++;
|
||||||
}
|
}
|
||||||
if (ch == '=') return TOK_EQUAL;
|
if (ch == '=' && !rhs) return TOK_EQUAL;
|
||||||
|
|
||||||
if (ch == '"') {
|
if (ch == '"') {
|
||||||
here = str;
|
here = str;
|
||||||
|
@ -373,7 +373,7 @@ get_token(CHAR16 *str, UINTN maxlen)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' ||
|
if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '#' ||
|
||||||
ch == '=' || ch == CHAR_EOF) {
|
ch == CHAR_EOF || (ch == '=' && !rhs)) {
|
||||||
again(ch);
|
again(ch);
|
||||||
*here = 0;
|
*here = 0;
|
||||||
return TOK_STR;
|
return TOK_STR;
|
||||||
|
@ -386,6 +386,18 @@ get_token(CHAR16 *str, UINTN maxlen)
|
||||||
return TOK_ERR;
|
return TOK_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static token_t
|
||||||
|
get_token(CHAR16 *str, UINTN maxlen)
|
||||||
|
{
|
||||||
|
return get_token_core(str, maxlen, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static token_t
|
||||||
|
get_token_rhs(CHAR16 *str, UINTN maxlen)
|
||||||
|
{
|
||||||
|
return get_token_core(str, maxlen, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static INTN
|
static INTN
|
||||||
image_check(boot_image_t *img)
|
image_check(boot_image_t *img)
|
||||||
{
|
{
|
||||||
|
@ -679,7 +691,7 @@ do_string_core(config_option_t *p, CHAR16 *str, UINTN maxlen, CHAR16 *msg)
|
||||||
/*
|
/*
|
||||||
* now get the value
|
* now get the value
|
||||||
*/
|
*/
|
||||||
tok = get_token(str, maxlen);
|
tok = get_token_rhs(str, maxlen);
|
||||||
if (tok != TOK_STR) {
|
if (tok != TOK_STR) {
|
||||||
config_error(L"Option %s expects %s", p->name, msg);
|
config_error(L"Option %s expects %s", p->name, msg);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -935,6 +947,37 @@ find_description(CHAR16 *label)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
add_root_to_options(CHAR16 *options, CHAR16 *root, CHAR16 *vmcode)
|
||||||
|
{
|
||||||
|
CHAR16 *o, ko[CMDLINE_MAXLEN];
|
||||||
|
|
||||||
|
if (vmcode[0]) {
|
||||||
|
for (o = options; *o; o++) {
|
||||||
|
if (*o == '-' && *(o+1) == '-')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (! *o) {
|
||||||
|
/* no separator found, add one */
|
||||||
|
StrCpy(o, L" -- ");
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance past separator and whitespace */
|
||||||
|
o += 2;
|
||||||
|
while (*o == ' ') o++;
|
||||||
|
} else {
|
||||||
|
o = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert root param at this point */
|
||||||
|
StrCpy(ko, o);
|
||||||
|
StrCpy(o, L"root=");
|
||||||
|
StrCat(o, root);
|
||||||
|
StrCat(o, L" ");
|
||||||
|
StrCat(o, ko);
|
||||||
|
}
|
||||||
|
|
||||||
INTN
|
INTN
|
||||||
find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 *vmcode)
|
find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16 *vmcode)
|
||||||
{
|
{
|
||||||
|
@ -957,15 +1000,12 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16
|
||||||
/*
|
/*
|
||||||
* when the label does not exist, we still propagate the global options
|
* when the label does not exist, we still propagate the global options
|
||||||
*/
|
*/
|
||||||
if (global_config.root[0]) {
|
|
||||||
StrCpy(options, L" root=");
|
|
||||||
StrCat(options, global_config.root);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global_config.options[0]) {
|
if (global_config.options[0]) {
|
||||||
StrCat(options, L" ");
|
StrCat(options, L" ");
|
||||||
StrCat(options, global_config.options);
|
StrCat(options, global_config.options);
|
||||||
}
|
}
|
||||||
|
if (global_config.root[0])
|
||||||
|
add_root_to_options(options, global_config.root, global_config.vmcode);
|
||||||
if (global_config.readonly) StrCat(options, L" ro");
|
if (global_config.readonly) StrCat(options, L" ro");
|
||||||
|
|
||||||
if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd);
|
if (global_config.initrd[0]) StrCpy(initrd, global_config.initrd);
|
||||||
|
@ -978,21 +1018,33 @@ find_label(CHAR16 *label, CHAR16 *kname, CHAR16 *options, CHAR16 *initrd, CHAR16
|
||||||
found:
|
found:
|
||||||
StrCpy(kname, img->kname);
|
StrCpy(kname, img->kname);
|
||||||
|
|
||||||
|
/* per image initrd has precedence over global initrd */
|
||||||
|
if (img->initrd[0])
|
||||||
|
StrCpy(initrd, img->initrd);
|
||||||
|
else
|
||||||
|
StrCpy(initrd, global_config.initrd);
|
||||||
|
|
||||||
|
/* per image vmcode has precedence over global vmcode */
|
||||||
|
if (img->vmcode[0])
|
||||||
|
StrCpy(vmcode, img->vmcode);
|
||||||
|
else
|
||||||
|
StrCpy(vmcode, global_config.vmcode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* literal option overrides any other image-based or global option
|
* literal option overrides any other image-based or global option
|
||||||
*
|
*
|
||||||
* In any case, the image option has priority over the global option
|
* In any case, the image option has priority over the global option
|
||||||
*/
|
*/
|
||||||
if (img->literal == 0) {
|
if (img->literal == 0) {
|
||||||
if (img->root[0] || global_config.root[0]) {
|
|
||||||
StrCat(options, L"root=");
|
|
||||||
StrCat(options, img->root[0] ? img->root : global_config.root);
|
|
||||||
}
|
|
||||||
/* XXX: check max length */
|
/* XXX: check max length */
|
||||||
if (img->options[0] || global_config.options[0]) {
|
if (img->options[0] || global_config.options[0]) {
|
||||||
StrCat(options, L" ");
|
StrCat(options, L" ");
|
||||||
StrCat(options, img->options[0] ? img->options: global_config.options);
|
StrCat(options, img->options[0] ? img->options: global_config.options);
|
||||||
}
|
}
|
||||||
|
if (img->root[0] || global_config.root[0]) {
|
||||||
|
add_root_to_options(options, img->root[0]
|
||||||
|
? img->root : global_config.root, vmcode);
|
||||||
|
}
|
||||||
if (img->readonly || global_config.readonly) {
|
if (img->readonly || global_config.readonly) {
|
||||||
StrCat(options, L" ro");
|
StrCat(options, L" ro");
|
||||||
}
|
}
|
||||||
|
@ -1001,17 +1053,6 @@ found:
|
||||||
StrCpy(options, img->options);
|
StrCpy(options, img->options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* per image initrd has precedence over global initrd */
|
|
||||||
if (img->initrd[0])
|
|
||||||
StrCpy(initrd, img->initrd);
|
|
||||||
else if (global_config.initrd[0])
|
|
||||||
StrCpy(initrd, global_config.initrd);
|
|
||||||
|
|
||||||
if (img->vmcode[0])
|
|
||||||
StrCpy(vmcode, img->vmcode);
|
|
||||||
else if (global_config.vmcode[0])
|
|
||||||
StrCpy(vmcode, global_config.vmcode);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* point to architecture dependent options for this image
|
* point to architecture dependent options for this image
|
||||||
*/
|
*/
|
||||||
|
|
135421
cscope.out
135421
cscope.out
File diff suppressed because it is too large
Load diff
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.
2
elilo.c
2
elilo.c
|
@ -46,7 +46,7 @@
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
#include "config.h" /* for config_init() */
|
#include "config.h" /* for config_init() */
|
||||||
|
|
||||||
#define ELILO_VERSION L"3.7"
|
#define ELILO_VERSION L"3.8"
|
||||||
#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;
|
||||||
|
|
|
@ -59,6 +59,26 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
|
/* Definitions for converting EFI memory map to E820 map for Linux
|
||||||
|
* These definitions are from include/linux/asm-x86/e820.h
|
||||||
|
* The structure ia32_boot_params below is updated to accommodate E820 map
|
||||||
|
* EFI memory map is converted to E820 map in this structure and passed
|
||||||
|
* to Linux. This way the OS does not need to do the conversion.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define E820_RAM 1
|
||||||
|
#define E820_RESERVED 2
|
||||||
|
#define E820_ACPI 3
|
||||||
|
#define E820_NVS 4
|
||||||
|
#define E820_MAX 128
|
||||||
|
|
||||||
|
struct e820entry {
|
||||||
|
UINT64 addr; /* start of memory segment */
|
||||||
|
UINT64 size; /* size of memory segment */
|
||||||
|
UINT32 type; /* type of memory segment */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef union ia32_boot_params {
|
typedef union ia32_boot_params {
|
||||||
UINT8 raw[0x2000];
|
UINT8 raw[0x2000];
|
||||||
struct {
|
struct {
|
||||||
|
@ -155,7 +175,7 @@ typedef union ia32_boot_params {
|
||||||
|
|
||||||
/* EFI boot loader signature. */
|
/* EFI boot loader signature. */
|
||||||
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
|
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
|
||||||
#define EFI_LOADER_SIG "EFIL"
|
#define EFI_LOADER_SIG_IA32 "EL32"
|
||||||
|
|
||||||
/* Address of the EFI system table. */
|
/* Address of the EFI system table. */
|
||||||
/* 0x1C4 */ UINT32 efi_sys_tbl; /* LDR */
|
/* 0x1C4 */ UINT32 efi_sys_tbl; /* LDR */
|
||||||
|
@ -177,7 +197,9 @@ typedef union ia32_boot_params {
|
||||||
/* Available contiguous extended memory in KB. */
|
/* Available contiguous extended memory in KB. */
|
||||||
/* 0x1E0 */ UINT32 alt_mem_k; /* LDR */
|
/* 0x1E0 */ UINT32 alt_mem_k; /* LDR */
|
||||||
|
|
||||||
/* 0x1E4 */ UINT8 unused_5[0x0D]; /* unused */
|
/* 0x1E4 */ UINT32 unused_51; /* unused */
|
||||||
|
/* 0x1E8 */ UINT8 e820_nrmap;
|
||||||
|
/* 0x1E9 */ UINT32 unused_52[2]; /* unused */
|
||||||
|
|
||||||
/* Size of setup code in sectors (1 sector == 512 bytes). */
|
/* Size of setup code in sectors (1 sector == 512 bytes). */
|
||||||
/* 0x1F1 */ UINT8 setup_sectors; /* BLD */
|
/* 0x1F1 */ UINT8 setup_sectors; /* BLD */
|
||||||
|
@ -258,6 +280,8 @@ typedef union ia32_boot_params {
|
||||||
/* 0x226 */ UINT16 unused_7; /* LDR */
|
/* 0x226 */ UINT16 unused_7; /* LDR */
|
||||||
|
|
||||||
/* 0x228 */ UINT32 cmdline_addr; /* LDR */
|
/* 0x228 */ UINT32 cmdline_addr; /* LDR */
|
||||||
|
/* 0x22C */ UINT32 unused_8[41];
|
||||||
|
/* 0x2D0 */ UINT8 e820_map[2560];
|
||||||
} s;
|
} s;
|
||||||
} boot_params_t;
|
} boot_params_t;
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
@ -354,6 +378,9 @@ start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
|
|
||||||
MEMCPY(high_base_mem, bp, 0x4000);
|
MEMCPY(high_base_mem, bp, 0x4000);
|
||||||
|
|
||||||
|
bp = (boot_params_t *)high_base_mem;
|
||||||
|
bp->s.cmdline_addr = high_base_mem + bp->s.cmdline_offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize Linux GDT.
|
* Initialize Linux GDT.
|
||||||
*/
|
*/
|
||||||
|
|
266
ia32/system.c
266
ia32/system.c
|
@ -156,6 +156,257 @@ sysdeps_free_boot_params(boot_params_t *bp)
|
||||||
free_memmap(&md);
|
free_memmap(&md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get video information.
|
||||||
|
*/
|
||||||
|
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_STATUS efi_status;
|
||||||
|
UINTN size, size1;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
efi_status = uefi_call_wrapper(
|
||||||
|
BS->LocateHandle,
|
||||||
|
5,
|
||||||
|
ByProtocol,
|
||||||
|
&GopProtocol,
|
||||||
|
NULL,
|
||||||
|
&size,
|
||||||
|
(VOID **)Gop_handle);
|
||||||
|
|
||||||
|
if (EFI_ERROR(efi_status) && efi_status != EFI_BUFFER_TOO_SMALL) {
|
||||||
|
ERR_PRT((L"LocateHandle GopProtocol failed."));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
Gop_handle = alloc(size, 0);
|
||||||
|
efi_status = uefi_call_wrapper(
|
||||||
|
BS->LocateHandle,
|
||||||
|
5,
|
||||||
|
ByProtocol,
|
||||||
|
&GopProtocol,
|
||||||
|
NULL,
|
||||||
|
&size,
|
||||||
|
(VOID **)Gop_handle);
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
ERR_PRT((L"LocateHandle GopProtocol failed."));
|
||||||
|
free(Gop_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i < size/sizeof(EFI_HANDLE); i++) {
|
||||||
|
Gop_handle += i;
|
||||||
|
efi_status = uefi_call_wrapper(
|
||||||
|
BS->HandleProtocol,
|
||||||
|
3,
|
||||||
|
*Gop_handle,
|
||||||
|
&GopProtocol,
|
||||||
|
&Gop_interface);
|
||||||
|
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Gop_mode = Gop_interface->Mode;
|
||||||
|
efi_status = uefi_call_wrapper(
|
||||||
|
Gop_interface->QueryMode,
|
||||||
|
4,
|
||||||
|
Gop_interface,
|
||||||
|
Gop_mode->Mode,
|
||||||
|
&size1,
|
||||||
|
&Gop_info);
|
||||||
|
if (!EFI_ERROR(efi_status))
|
||||||
|
break;
|
||||||
|
if (EFI_ERROR(efi_status)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (EFI_ERROR(efi_status) || i > (size/sizeof(EFI_HANDLE))) {
|
||||||
|
ERR_PRT((L"HandleProtocol GopProtocol failed."));
|
||||||
|
free(Gop_handle);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bp->s.is_vga = 0x70;
|
||||||
|
bp->s.orig_cursor_col = 0;
|
||||||
|
bp->s.orig_cursor_row = 0;
|
||||||
|
bp->s.orig_video_page = 0;
|
||||||
|
bp->s.orig_video_mode = 0;
|
||||||
|
bp->s.orig_video_cols = 0;
|
||||||
|
bp->s.orig_video_rows = 0;
|
||||||
|
bp->s.orig_ega_bx = 0;
|
||||||
|
bp->s.orig_video_points = 0;
|
||||||
|
|
||||||
|
bp->s.lfb_width = Gop_info->HorizontalResolution;
|
||||||
|
bp->s.lfb_height = Gop_info->VerticalResolution;
|
||||||
|
bp->s.lfb_base = Gop_mode->FrameBufferBase;
|
||||||
|
bp->s.lfb_size = Gop_mode->FrameBufferSize;
|
||||||
|
bp->s.lfb_pages = 1;
|
||||||
|
bp->s.vesa_seg = 0;
|
||||||
|
bp->s.vesa_off = 0;
|
||||||
|
if (Gop_info->PixelFormat == PixelRedGreenBlueReserved8BitPerColor) {
|
||||||
|
bp->s.lfb_depth = 32;
|
||||||
|
bp->s.lfb_red_size = 8;
|
||||||
|
bp->s.lfb_red_pos = 0;
|
||||||
|
bp->s.lfb_green_size = 8;
|
||||||
|
bp->s.lfb_green_pos = 8;
|
||||||
|
bp->s.lfb_blue_size = 8;
|
||||||
|
bp->s.lfb_blue_pos = 16;
|
||||||
|
bp->s.lfb_rsvd_size = 8;
|
||||||
|
bp->s.lfb_rsvd_pos = 24;
|
||||||
|
bp->s.lfb_line_len = Gop_info->PixelsPerScanLine * 4;
|
||||||
|
|
||||||
|
} else if (Gop_info->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
|
||||||
|
bp->s.lfb_depth = 32;
|
||||||
|
bp->s.lfb_red_size = 8;
|
||||||
|
bp->s.lfb_red_pos = 16;
|
||||||
|
bp->s.lfb_green_size = 8;
|
||||||
|
bp->s.lfb_green_pos = 8;
|
||||||
|
bp->s.lfb_blue_size = 8;
|
||||||
|
bp->s.lfb_blue_pos = 0;
|
||||||
|
bp->s.lfb_rsvd_size = 8;
|
||||||
|
bp->s.lfb_rsvd_pos = 24;
|
||||||
|
bp->s.lfb_line_len = Gop_info->PixelsPerScanLine * 4;
|
||||||
|
} else if (Gop_info->PixelFormat == PixelBitMask) {
|
||||||
|
find_bits(Gop_info->PixelInformation.RedMask,
|
||||||
|
&bp->s.lfb_red_pos, &bp->s.lfb_red_size);
|
||||||
|
find_bits(Gop_info->PixelInformation.GreenMask,
|
||||||
|
&bp->s.lfb_green_pos, &bp->s.lfb_green_size);
|
||||||
|
find_bits(Gop_info->PixelInformation.BlueMask,
|
||||||
|
&bp->s.lfb_blue_pos, &bp->s.lfb_blue_size);
|
||||||
|
find_bits(Gop_info->PixelInformation.ReservedMask,
|
||||||
|
&bp->s.lfb_rsvd_pos, &bp->s.lfb_rsvd_size);
|
||||||
|
bp->s.lfb_depth = bp->s.lfb_red_size + bp->s.lfb_green_size +
|
||||||
|
bp->s.lfb_blue_size + bp->s.lfb_rsvd_size;
|
||||||
|
bp->s.lfb_line_len = (Gop_info->PixelsPerScanLine * bp->s.lfb_depth) / 8;
|
||||||
|
} else {
|
||||||
|
bp->s.lfb_depth = 4;
|
||||||
|
bp->s.lfb_red_size = 0;
|
||||||
|
bp->s.lfb_red_pos = 0;
|
||||||
|
bp->s.lfb_green_size = 0;
|
||||||
|
bp->s.lfb_green_pos = 0;
|
||||||
|
bp->s.lfb_blue_size = 0;
|
||||||
|
bp->s.lfb_blue_pos = 0;
|
||||||
|
bp->s.lfb_rsvd_size = 0;
|
||||||
|
bp->s.lfb_rsvd_pos = 0;
|
||||||
|
bp->s.lfb_line_len = bp->s.lfb_width / 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert EFI memory map to E820 map for the operating system
|
||||||
|
* This code is based on a Linux kernel patch submitted by Edgar Hucek
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Add a memory region to the e820 map */
|
||||||
|
static void add_memory_region (struct e820entry *e820_map,
|
||||||
|
int *e820_nr_map,
|
||||||
|
UINT64 start,
|
||||||
|
UINT64 size,
|
||||||
|
UINT32 type)
|
||||||
|
{
|
||||||
|
int x = *e820_nr_map;
|
||||||
|
|
||||||
|
if (x == E820_MAX) {
|
||||||
|
Print(L"Too many entries in the memory map!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start
|
||||||
|
&& e820_map[x-1].type == type)
|
||||||
|
e820_map[x-1].size += size;
|
||||||
|
else {
|
||||||
|
e820_map[x].addr = start;
|
||||||
|
e820_map[x].size = size;
|
||||||
|
e820_map[x].type = type;
|
||||||
|
(*e820_nr_map)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||||||
|
{
|
||||||
|
int nr_map, e820_nr_map = 0, i;
|
||||||
|
UINT64 start, end, size;
|
||||||
|
EFI_MEMORY_DESCRIPTOR *md, *p;
|
||||||
|
struct e820entry *e820_map;
|
||||||
|
|
||||||
|
nr_map = mdesc->map_size/mdesc->desc_size;
|
||||||
|
e820_map = (struct e820entry *)bp->s.e820_map;
|
||||||
|
|
||||||
|
for (i = 0, p = mdesc->md; i < nr_map; i++)
|
||||||
|
{
|
||||||
|
md = p;
|
||||||
|
switch (md->Type) {
|
||||||
|
case EfiACPIReclaimMemory:
|
||||||
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
|
md->PhysicalStart,
|
||||||
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_ACPI);
|
||||||
|
break;
|
||||||
|
case EfiRuntimeServicesCode:
|
||||||
|
case EfiRuntimeServicesData:
|
||||||
|
case EfiReservedMemoryType:
|
||||||
|
case EfiMemoryMappedIO:
|
||||||
|
case EfiMemoryMappedIOPortSpace:
|
||||||
|
case EfiUnusableMemory:
|
||||||
|
case EfiPalCode:
|
||||||
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
|
md->PhysicalStart,
|
||||||
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_RESERVED);
|
||||||
|
break;
|
||||||
|
case EfiLoaderCode:
|
||||||
|
case EfiLoaderData:
|
||||||
|
case EfiBootServicesCode:
|
||||||
|
case EfiBootServicesData:
|
||||||
|
case EfiConventionalMemory:
|
||||||
|
start = md->PhysicalStart;
|
||||||
|
size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
||||||
|
end = start + size;
|
||||||
|
/* Fix up for BIOS that claims RAM in 640K-1MB region */
|
||||||
|
if (start < 0x100000ULL && end > 0xA0000ULL) {
|
||||||
|
if (start < 0xA0000ULL) {
|
||||||
|
/* start < 640K
|
||||||
|
* set memory map from start to 640K
|
||||||
|
*/
|
||||||
|
add_memory_region(e820_map,
|
||||||
|
&e820_nr_map,
|
||||||
|
start,
|
||||||
|
0xA0000ULL-start,
|
||||||
|
E820_RAM);
|
||||||
|
}
|
||||||
|
if (end <= 0x100000ULL)
|
||||||
|
continue;
|
||||||
|
/* end > 1MB
|
||||||
|
* set memory map avoiding 640K to 1MB hole
|
||||||
|
*/
|
||||||
|
start = 0x100000ULL;
|
||||||
|
size = end - start;
|
||||||
|
}
|
||||||
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
|
start, size, E820_RAM);
|
||||||
|
break;
|
||||||
|
case EfiACPIMemoryNVS:
|
||||||
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
|
md->PhysicalStart,
|
||||||
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_NVS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* We should not hit this case */
|
||||||
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
|
md->PhysicalStart,
|
||||||
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_RESERVED);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = NextMemoryDescriptor(p, mdesc->desc_size);
|
||||||
|
}
|
||||||
|
bp->s.e820_nrmap = e820_nr_map;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IA-32 specific boot parameters initialization routine
|
* IA-32 specific boot parameters initialization routine
|
||||||
*/
|
*/
|
||||||
|
@ -213,9 +464,11 @@ sysdeps_create_boot_params(
|
||||||
bp->s.unused_2 = 0;
|
bp->s.unused_2 = 0;
|
||||||
ZeroMem(bp->s.unused_3, sizeof bp->s.unused_3);
|
ZeroMem(bp->s.unused_3, sizeof bp->s.unused_3);
|
||||||
ZeroMem(bp->s.unused_4, sizeof bp->s.unused_4);
|
ZeroMem(bp->s.unused_4, sizeof bp->s.unused_4);
|
||||||
ZeroMem(bp->s.unused_5, sizeof bp->s.unused_5);
|
ZeroMem(&bp->s.unused_51, sizeof bp->s.unused_51);
|
||||||
|
ZeroMem(bp->s.unused_52, sizeof bp->s.unused_52);
|
||||||
bp->s.unused_6 = 0;
|
bp->s.unused_6 = 0;
|
||||||
bp->s.unused_7 = 0;
|
bp->s.unused_7 = 0;
|
||||||
|
ZeroMem(bp->s.unused_8, sizeof bp->s.unused_8);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tell kernel this was loaded by an advanced loader type.
|
* Tell kernel this was loaded by an advanced loader type.
|
||||||
|
@ -310,7 +563,7 @@ sysdeps_create_boot_params(
|
||||||
/*
|
/*
|
||||||
* EFI loader signature
|
* EFI loader signature
|
||||||
*/
|
*/
|
||||||
CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG, 4);
|
CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG_IA32, 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel entry point.
|
* Kernel entry point.
|
||||||
|
@ -402,6 +655,7 @@ sysdeps_create_boot_params(
|
||||||
CHECK_OFFSET(loader_start, 0x1D8, L"%xh");
|
CHECK_OFFSET(loader_start, 0x1D8, L"%xh");
|
||||||
CHECK_OFFSET(loader_size, 0x1DC, L"%xh");
|
CHECK_OFFSET(loader_size, 0x1DC, L"%xh");
|
||||||
CHECK_OFFSET(alt_mem_k, 0x1E0, L"%xh");
|
CHECK_OFFSET(alt_mem_k, 0x1E0, L"%xh");
|
||||||
|
CHECK_OFFSET(e820_nrmap, 0x1E8, L"%xh");
|
||||||
CHECK_OFFSET(setup_sectors, 0x1F1, L"%xh");
|
CHECK_OFFSET(setup_sectors, 0x1F1, L"%xh");
|
||||||
CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
|
CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
|
||||||
CHECK_OFFSET(sys_size, 0x1F4, L"%xh");
|
CHECK_OFFSET(sys_size, 0x1F4, L"%xh");
|
||||||
|
@ -426,6 +680,7 @@ sysdeps_create_boot_params(
|
||||||
CHECK_OFFSET(bootsect_helper, 0x220, L"%xh");
|
CHECK_OFFSET(bootsect_helper, 0x220, L"%xh");
|
||||||
CHECK_OFFSET(heap_end_ptr, 0x224, L"%xh");
|
CHECK_OFFSET(heap_end_ptr, 0x224, L"%xh");
|
||||||
CHECK_OFFSET(cmdline_addr, 0x228, L"%xh");
|
CHECK_OFFSET(cmdline_addr, 0x228, L"%xh");
|
||||||
|
CHECK_OFFSET(e820_map, 0x2D0, L"'%-2560.2560a'");
|
||||||
|
|
||||||
if (test) {
|
if (test) {
|
||||||
ERR_PRT((L"Boot sector and/or setup parameter alignment error."));
|
ERR_PRT((L"Boot sector and/or setup parameter alignment error."));
|
||||||
|
@ -440,6 +695,8 @@ sysdeps_create_boot_params(
|
||||||
* in the fill routine gets accounted for.
|
* in the fill routine gets accounted for.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (!get_video_info(bp)) goto do_memmap;
|
||||||
|
|
||||||
efi_status = ST->ConOut->QueryMode(
|
efi_status = ST->ConOut->QueryMode(
|
||||||
ST->ConOut,
|
ST->ConOut,
|
||||||
ST->ConOut->Mode->Mode,
|
ST->ConOut->Mode->Mode,
|
||||||
|
@ -488,6 +745,7 @@ sysdeps_create_boot_params(
|
||||||
bp->s.vesa_seg = 0;
|
bp->s.vesa_seg = 0;
|
||||||
bp->s.vesa_off = 0;
|
bp->s.vesa_off = 0;
|
||||||
|
|
||||||
|
do_memmap:
|
||||||
/*
|
/*
|
||||||
* Get memory map description and cookie for ExitBootServices()
|
* Get memory map description and cookie for ExitBootServices()
|
||||||
*/
|
*/
|
||||||
|
@ -503,6 +761,10 @@ sysdeps_create_boot_params(
|
||||||
bp->s.efi_mem_desc_size = mdesc.desc_size;
|
bp->s.efi_mem_desc_size = mdesc.desc_size;
|
||||||
bp->s.efi_mem_desc_ver = mdesc.desc_version;
|
bp->s.efi_mem_desc_ver = mdesc.desc_version;
|
||||||
bp->s.efi_sys_tbl = (UINTN)systab;
|
bp->s.efi_sys_tbl = (UINTN)systab;
|
||||||
|
/* Now that we have EFI memory map, convert it to E820 map
|
||||||
|
* and update the bootparam accordingly
|
||||||
|
*/
|
||||||
|
fill_e820map(bp, &mdesc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
4
initrd.c
4
initrd.c
|
@ -41,7 +41,7 @@ INTN
|
||||||
load_file(CHAR16 *filename, memdesc_t *image)
|
load_file(CHAR16 *filename, memdesc_t *image)
|
||||||
{
|
{
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
VOID *start_addr = image->start_addr;
|
VOID *start_addr = NULL;
|
||||||
UINTN pgcnt;
|
UINTN pgcnt;
|
||||||
UINT64 size = 0;
|
UINT64 size = 0;
|
||||||
fops_fd_t fd;
|
fops_fd_t fd;
|
||||||
|
@ -71,7 +71,7 @@ load_file(CHAR16 *filename, memdesc_t *image)
|
||||||
/* round up to get required number of pages (4KB) */
|
/* round up to get required number of pages (4KB) */
|
||||||
image->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(image->size);
|
image->pgcnt = pgcnt = EFI_SIZE_TO_PAGES(image->size);
|
||||||
|
|
||||||
start_addr = alloc_pages(pgcnt, EfiLoaderData, start_addr ? AllocateAddress : AllocateAnyPages, start_addr);
|
start_addr = alloc_pages(pgcnt, EfiLoaderData, start_addr ? AllocateAddress : AllocateAnyPages, 0 );
|
||||||
if (start_addr == NULL) {
|
if (start_addr == NULL) {
|
||||||
ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt,
|
ERR_PRT((L"Failed to allocate %d pages for %s image", pgcnt,
|
||||||
filename));
|
filename));
|
||||||
|
|
94
release.notes
Normal file
94
release.notes
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
SUBMIT BUG REPORTS HERE --> http://sourceforge.net/tracker/?group_id=91879&atid=598709
|
||||||
|
|
||||||
|
IMPORTANT NOTE FOR BUILDS ON ALL ARCHS:
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
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
|
||||||
|
passes it in the bootparameter supplied to the kernel. For details on
|
||||||
|
bootparameter, see x86_64/sysdeps.h.
|
||||||
|
|
||||||
|
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.
|
|
@ -180,28 +180,27 @@ typedef union x86_64_boot_params {
|
||||||
/* 0xA0 */ UINT16 mca_info_len; /* LDR */
|
/* 0xA0 */ UINT16 mca_info_len; /* LDR */
|
||||||
/* 0xA2 */ UINT8 mca_info_buf[0x10]; /* LDR */
|
/* 0xA2 */ UINT8 mca_info_buf[0x10]; /* LDR */
|
||||||
|
|
||||||
/* 0xB2 */ UINT8 unused_4[0x106]; /* unused */
|
/* 0xB2 */ UINT8 unused_4[0x10E]; /* unused */
|
||||||
|
|
||||||
/* Address of the EFI system table. */
|
|
||||||
/* 0x1B8 */ UINT64 efi_sys_tbl; /* LDR */
|
|
||||||
|
|
||||||
/* EFI boot loader signature. */
|
/* EFI boot loader signature. */
|
||||||
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
|
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
|
||||||
#define EFI_LOADER_SIG "EFIL"
|
#define EFI_LOADER_SIG_X64 "EL64"
|
||||||
|
|
||||||
|
/* Address of the EFI system table. */
|
||||||
|
/* 0x1C4 */ UINT32 efi_sys_tbl; /* LDR */
|
||||||
|
|
||||||
/* EFI memory descriptor size. */
|
/* EFI memory descriptor size. */
|
||||||
/* 0x1C4 */ UINT32 efi_mem_desc_size; /* LDR */
|
/* 0x1C8 */ UINT32 efi_mem_desc_size; /* LDR */
|
||||||
|
|
||||||
/* EFI memory descriptor version. */
|
/* EFI memory descriptor version. */
|
||||||
/* 0x1C8 */ UINT32 efi_mem_desc_ver; /* LDR */
|
/* 0x1CC */ UINT32 efi_mem_desc_ver; /* LDR */
|
||||||
|
|
||||||
/* Address & size of EFI memory map. */
|
/* Address & size of EFI memory map. */
|
||||||
/* 0x1CC */ UINT32 efi_mem_map_size; /* LDR */
|
/* 0x1D0 */ UINT32 efi_mem_map; /* LDR */
|
||||||
/* 0x1D0 */ UINT64 efi_mem_map; /* LDR */
|
/* 0x1D4 */ UINT32 efi_mem_map_size; /* LDR */
|
||||||
|
|
||||||
/* Address & size of loader. */
|
/* 0x1D8 */ UINT32 efi_sys_tbl_hi; /* LDR */
|
||||||
/* 0x1D8 */ UINT32 loader_start; /* LDR */
|
/* 0x1DC */ UINT32 efi_mem_map_hi; /* LDR */
|
||||||
/* 0x1DC */ UINT32 loader_size; /* LDR */
|
|
||||||
|
|
||||||
/* Available contiguous extended memory in KB. */
|
/* Available contiguous extended memory in KB. */
|
||||||
/* 0x1E0 */ UINT32 alt_mem_k; /* LDR */
|
/* 0x1E0 */ UINT32 alt_mem_k; /* LDR */
|
||||||
|
@ -395,6 +394,9 @@ start_kernel(VOID *kentry, boot_params_t *bp)
|
||||||
|
|
||||||
MEMCPY(high_base_mem, bp, 0x4000);
|
MEMCPY(high_base_mem, bp, 0x4000);
|
||||||
|
|
||||||
|
bp = (boot_params_t *)high_base_mem;
|
||||||
|
bp->s.cmdline_addr = high_base_mem + bp->s.cmdline_offset;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize Linux GDT.
|
* Initialize Linux GDT.
|
||||||
*/
|
*/
|
||||||
|
|
111
x86_64/system.c
111
x86_64/system.c
|
@ -255,7 +255,7 @@ static INTN get_video_info(boot_params_t * bp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bp->s.is_vga = 0x24;
|
bp->s.is_vga = 0x70;
|
||||||
bp->s.orig_cursor_col = 0;
|
bp->s.orig_cursor_col = 0;
|
||||||
bp->s.orig_cursor_row = 0;
|
bp->s.orig_cursor_row = 0;
|
||||||
bp->s.orig_video_page = 0;
|
bp->s.orig_video_page = 0;
|
||||||
|
@ -326,30 +326,56 @@ static INTN get_video_info(boot_params_t * bp) {
|
||||||
* This code is based on a Linux kernel patch submitted by Edgar Hucek
|
* This code is based on a Linux kernel patch submitted by Edgar Hucek
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Add a memory region to the e820 map */
|
||||||
|
static void add_memory_region (struct e820entry *e820_map,
|
||||||
|
int *e820_nr_map,
|
||||||
|
unsigned long long start,
|
||||||
|
unsigned long size,
|
||||||
|
unsigned int type)
|
||||||
|
{
|
||||||
|
int x = *e820_nr_map;
|
||||||
|
|
||||||
|
if (x == E820_MAX) {
|
||||||
|
Print(L"Too many entries in the memory map!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start
|
||||||
|
&& e820_map[x-1].type == type)
|
||||||
|
e820_map[x-1].size += size;
|
||||||
|
else {
|
||||||
|
e820_map[x].addr = start;
|
||||||
|
e820_map[x].size = size;
|
||||||
|
e820_map[x].type = type;
|
||||||
|
(*e820_nr_map)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||||||
{
|
{
|
||||||
int nr_map, i;
|
int nr_map, e820_nr_map = 0, i;
|
||||||
UINT64 start, end, size;
|
UINT64 start, end, size;
|
||||||
EFI_MEMORY_DESCRIPTOR *md, *p;
|
EFI_MEMORY_DESCRIPTOR *md, *p;
|
||||||
struct e820entry *e820_map;
|
struct e820entry *e820_map;
|
||||||
|
|
||||||
nr_map = mdesc->map_size/mdesc->desc_size;
|
nr_map = mdesc->map_size/mdesc->desc_size;
|
||||||
e820_map = (struct e820entry *)bp->s.e820_map;
|
e820_map = (struct e820entry *)bp->s.e820_map;
|
||||||
bp->s.e820_nrmap = nr_map;
|
|
||||||
|
|
||||||
for (i = 0, p = mdesc->md; i < nr_map; i++)
|
for (i = 0, p = mdesc->md; i < nr_map; i++)
|
||||||
{
|
{
|
||||||
md = p;
|
md = p;
|
||||||
switch (md->Type) {
|
switch (md->Type) {
|
||||||
case EfiACPIReclaimMemory:
|
case EfiACPIReclaimMemory:
|
||||||
e820_map->addr = md->PhysicalStart;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
e820_map->size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
md->PhysicalStart,
|
||||||
e820_map->type = E820_ACPI;
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_ACPI);
|
||||||
break;
|
break;
|
||||||
case EfiRuntimeServicesCode:
|
case EfiRuntimeServicesCode:
|
||||||
e820_map->addr = md->PhysicalStart;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
e820_map->size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
md->PhysicalStart,
|
||||||
e820_map->type = E820_EXEC_CODE;
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_EXEC_CODE);
|
||||||
break;
|
break;
|
||||||
case EfiRuntimeServicesData:
|
case EfiRuntimeServicesData:
|
||||||
case EfiReservedMemoryType:
|
case EfiReservedMemoryType:
|
||||||
|
@ -357,9 +383,10 @@ void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||||||
case EfiMemoryMappedIOPortSpace:
|
case EfiMemoryMappedIOPortSpace:
|
||||||
case EfiUnusableMemory:
|
case EfiUnusableMemory:
|
||||||
case EfiPalCode:
|
case EfiPalCode:
|
||||||
e820_map->addr = md->PhysicalStart;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
e820_map->size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
md->PhysicalStart,
|
||||||
e820_map->type = E820_RESERVED;
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_RESERVED);
|
||||||
break;
|
break;
|
||||||
case EfiLoaderCode:
|
case EfiLoaderCode:
|
||||||
case EfiLoaderData:
|
case EfiLoaderData:
|
||||||
|
@ -375,10 +402,11 @@ void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||||||
/* start < 640K
|
/* start < 640K
|
||||||
* set memory map from start to 640K
|
* set memory map from start to 640K
|
||||||
*/
|
*/
|
||||||
e820_map->addr = start;
|
add_memory_region(e820_map,
|
||||||
e820_map->size = 0xA0000ULL-start;
|
&e820_nr_map,
|
||||||
e820_map->type = E820_RAM;
|
start,
|
||||||
e820_map++;
|
0xA0000ULL-start,
|
||||||
|
E820_RAM);
|
||||||
}
|
}
|
||||||
if (end <= 0x100000ULL)
|
if (end <= 0x100000ULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -388,27 +416,28 @@ void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||||||
start = 0x100000ULL;
|
start = 0x100000ULL;
|
||||||
size = end - start;
|
size = end - start;
|
||||||
}
|
}
|
||||||
e820_map->addr = start;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
e820_map->size = size;
|
start, size, E820_RAM);
|
||||||
e820_map->type = E820_RAM;
|
|
||||||
break;
|
break;
|
||||||
case EfiACPIMemoryNVS:
|
case EfiACPIMemoryNVS:
|
||||||
e820_map->addr = md->PhysicalStart;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
e820_map->size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
md->PhysicalStart,
|
||||||
e820_map->type = E820_NVS;
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_NVS);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* We should not hit this case */
|
/* We should not hit this case */
|
||||||
e820_map->addr = md->PhysicalStart;
|
add_memory_region(e820_map, &e820_nr_map,
|
||||||
size = md->NumberOfPages << EFI_PAGE_SHIFT;
|
md->PhysicalStart,
|
||||||
e820_map->type = E820_RESERVED;
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||||||
|
E820_RESERVED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e820_map++;
|
|
||||||
p = NextMemoryDescriptor(p, mdesc->desc_size);
|
p = NextMemoryDescriptor(p, mdesc->desc_size);
|
||||||
}
|
}
|
||||||
|
bp->s.e820_nrmap = e820_nr_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* x86_64 specific boot parameters initialization routine
|
* x86_64 specific boot parameters initialization routine
|
||||||
*/
|
*/
|
||||||
|
@ -464,10 +493,10 @@ sysdeps_create_boot_params(
|
||||||
*/
|
*/
|
||||||
bp->s.unused_1 = 0;
|
bp->s.unused_1 = 0;
|
||||||
bp->s.unused_2 = 0;
|
bp->s.unused_2 = 0;
|
||||||
ZeroMem(bp->s.unused_3, sizeof bp->s.unused_3);
|
ZeroMem(&bp->s.unused_3, sizeof bp->s.unused_3);
|
||||||
ZeroMem(bp->s.unused_4, sizeof bp->s.unused_4);
|
ZeroMem(&bp->s.unused_4, sizeof bp->s.unused_4);
|
||||||
ZeroMem(bp->s.unused_51, sizeof bp->s.unused_51);
|
ZeroMem(&bp->s.unused_51, sizeof bp->s.unused_51);
|
||||||
ZeroMem(bp->s.unused_52, sizeof bp->s.unused_52);
|
ZeroMem(&bp->s.unused_52, sizeof bp->s.unused_52);
|
||||||
bp->s.unused_6 = 0;
|
bp->s.unused_6 = 0;
|
||||||
bp->s.unused_7 = 0;
|
bp->s.unused_7 = 0;
|
||||||
ZeroMem(bp->s.unused_8, sizeof bp->s.unused_8);
|
ZeroMem(bp->s.unused_8, sizeof bp->s.unused_8);
|
||||||
|
@ -564,7 +593,7 @@ sysdeps_create_boot_params(
|
||||||
/*
|
/*
|
||||||
* EFI loader signature
|
* EFI loader signature
|
||||||
*/
|
*/
|
||||||
CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG, 4);
|
CopyMem(bp->s.efi_loader_sig, EFI_LOADER_SIG_X64, 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Kernel entry point.
|
* Kernel entry point.
|
||||||
|
@ -647,14 +676,14 @@ sysdeps_create_boot_params(
|
||||||
CHECK_OFFSET(hd1_info, 0x90, L"");
|
CHECK_OFFSET(hd1_info, 0x90, L"");
|
||||||
CHECK_OFFSET(mca_info_len, 0xA0, L"%xh");
|
CHECK_OFFSET(mca_info_len, 0xA0, L"%xh");
|
||||||
CHECK_OFFSET(mca_info_buf, 0xA2, L"");
|
CHECK_OFFSET(mca_info_buf, 0xA2, L"");
|
||||||
CHECK_OFFSET(efi_sys_tbl, 0x1B8, L"%xh");
|
|
||||||
CHECK_OFFSET(efi_loader_sig, 0x1C0, L"'%-4.4a'");
|
CHECK_OFFSET(efi_loader_sig, 0x1C0, L"'%-4.4a'");
|
||||||
CHECK_OFFSET(efi_mem_desc_size, 0x1C4, L"%xh");
|
CHECK_OFFSET(efi_sys_tbl, 0x1C4, L"%xh");
|
||||||
CHECK_OFFSET(efi_mem_desc_ver, 0x1C8, L"%xh");
|
CHECK_OFFSET(efi_mem_desc_size, 0x1C8, L"%xh");
|
||||||
CHECK_OFFSET(efi_mem_map_size, 0x1CC, L"%xh");
|
CHECK_OFFSET(efi_mem_desc_ver, 0x1CC, L"%xh");
|
||||||
CHECK_OFFSET(efi_mem_map, 0x1D0, L"%xh");
|
CHECK_OFFSET(efi_mem_map, 0x1D0, L"%xh");
|
||||||
CHECK_OFFSET(loader_start, 0x1D8, L"%xh");
|
CHECK_OFFSET(efi_mem_map_size, 0x1D4, L"%xh");
|
||||||
CHECK_OFFSET(loader_size, 0x1DC, L"%xh");
|
CHECK_OFFSET(efi_sys_tbl_hi, 0x1D8, L"%xh");
|
||||||
|
CHECK_OFFSET(efi_mem_map_hi, 0x1DC, L"%xh");
|
||||||
CHECK_OFFSET(alt_mem_k, 0x1E0, L"%xh");
|
CHECK_OFFSET(alt_mem_k, 0x1E0, L"%xh");
|
||||||
CHECK_OFFSET(setup_sectors, 0x1F1, L"%xh");
|
CHECK_OFFSET(setup_sectors, 0x1F1, L"%xh");
|
||||||
CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
|
CHECK_OFFSET(mount_root_rdonly, 0x1F2, L"%xh");
|
||||||
|
@ -758,11 +787,13 @@ do_memmap:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*cookie = mdesc.cookie;
|
*cookie = mdesc.cookie;
|
||||||
bp->s.efi_mem_map = (UINTN)mdesc.md;
|
bp->s.efi_mem_map = (UINT32)(unsigned long)mdesc.md;
|
||||||
bp->s.efi_mem_map_size = mdesc.map_size;
|
bp->s.efi_mem_map_size = mdesc.map_size;
|
||||||
bp->s.efi_mem_desc_size = mdesc.desc_size;
|
bp->s.efi_mem_desc_size = mdesc.desc_size;
|
||||||
bp->s.efi_mem_desc_ver = mdesc.desc_version;
|
bp->s.efi_mem_desc_ver = mdesc.desc_version;
|
||||||
bp->s.efi_sys_tbl = (UINTN)systab;
|
bp->s.efi_sys_tbl = (UINT32)(unsigned long)systab;
|
||||||
|
bp->s.efi_mem_map_hi = (unsigned long)mdesc.md >> 32;
|
||||||
|
bp->s.efi_sys_tbl_hi = (unsigned long)systab >> 32;
|
||||||
/* Now that we have EFI memory map, convert it to E820 map
|
/* Now that we have EFI memory map, convert it to E820 map
|
||||||
* and update the bootparam accordingly
|
* and update the bootparam accordingly
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue