forked from pool/elilo
231 lines
5.6 KiB
Diff
231 lines
5.6 KiB
Diff
|
---
|
||
|
bootparams.c | 2
|
||
|
x86_64/system.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||
|
2 files changed, 134 insertions(+), 7 deletions(-)
|
||
|
|
||
|
--- a/bootparams.c
|
||
|
+++ b/bootparams.c
|
||
|
@@ -96,6 +96,8 @@ create_boot_params(CHAR16 *args, memdesc
|
||
|
*/
|
||
|
Memset(bp, 0, BOOT_PARAM_MEMSIZE);
|
||
|
|
||
|
+ U2ascii(args, cp, cmdline_size);
|
||
|
+
|
||
|
if (sysdeps_create_boot_params(bp, cp, initrd, vmcode, cookie) == -1) return 0;
|
||
|
|
||
|
/*
|
||
|
--- a/x86_64/system.c
|
||
|
+++ b/x86_64/system.c
|
||
|
@@ -38,11 +38,19 @@
|
||
|
*/
|
||
|
#include <efi.h>
|
||
|
#include <efilib.h>
|
||
|
+#include <string.h>
|
||
|
|
||
|
#include "elilo.h"
|
||
|
#include "loader.h"
|
||
|
#include "rmswitch.h"
|
||
|
|
||
|
+#define DEBUG_CREATE_BOOT_PARAMS 0
|
||
|
+#if DEBUG_CREATE_BOOT_PARAMS
|
||
|
+#define DPR(a) do { if (elilo_opt.debug) { Print a; } } while ( 0 )
|
||
|
+#else
|
||
|
+#define DPR(a)
|
||
|
+#endif
|
||
|
+
|
||
|
extern loader_ops_t bzimage_loader, plain_loader, gzip_loader;
|
||
|
|
||
|
/*
|
||
|
@@ -113,6 +121,8 @@ VOID *kernel_load_address = (VOID *)DEFA
|
||
|
VOID *initrd_start = NULL;
|
||
|
UINTN initrd_size = 0;
|
||
|
|
||
|
+INTN e820_map_overflow = 0;
|
||
|
+
|
||
|
INTN
|
||
|
sysdeps_init(EFI_HANDLE dev)
|
||
|
{
|
||
|
@@ -368,10 +378,56 @@ static INTN get_video_info(boot_params_t
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+CHAR16 *
|
||
|
+StrStr(IN const CHAR16 *h, IN const CHAR16 *n)
|
||
|
+{
|
||
|
+ const CHAR16 *t = h;
|
||
|
+ CHAR16 *res;
|
||
|
+ int len = 0, i;
|
||
|
+
|
||
|
+ len = StrLen((CHAR16 *)n);
|
||
|
+ while(*t != CHAR_NULL) {
|
||
|
+ res = StrChr( t, n[0]);
|
||
|
+ if (!res) return res;
|
||
|
+ for( i = 1; i < len && res[i] != CHAR_NULL && res[i] == n[i]; i++);
|
||
|
+ if ( i == len ) return res;
|
||
|
+ t = res + 1;
|
||
|
+ if (t > h + CMDLINE_MAXLEN) return (CHAR16 *)0;
|
||
|
+ }
|
||
|
+
|
||
|
+ return (CHAR16 *)0;
|
||
|
+}
|
||
|
+
|
||
|
+CHAR8 *
|
||
|
+StrStr8(IN const CHAR8 *h, IN const CHAR8 *n)
|
||
|
+{
|
||
|
+ const CHAR8 *t = h;
|
||
|
+ CHAR8 *res;
|
||
|
+ int len = 0, i;
|
||
|
+
|
||
|
+ len = strlena((CHAR8 *)n);
|
||
|
+ while(*t != 0) {
|
||
|
+ res = strchra( t, n[0]);
|
||
|
+ if (!res) return res;
|
||
|
+ for( i = 1; i < len && res[i] != 0 && res[i] == n[i]; i++);
|
||
|
+ if ( i == len ) return res;
|
||
|
+ t = res + 1;
|
||
|
+ if (t > (h + CMDLINE_MAXLEN)) return (CHAR8 *)0;
|
||
|
+ }
|
||
|
+
|
||
|
+ return (CHAR8 *)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
|
||
|
*/
|
||
|
|
||
|
+#if DEBUG_CREATE_BOOT_PARAMS
|
||
|
+static int e820_max = 6;
|
||
|
+#else
|
||
|
+static int e820_max = E820_MAX;
|
||
|
+#endif
|
||
|
+
|
||
|
/* Add a memory region to the e820 map */
|
||
|
static void add_memory_region (struct e820entry *e820_map,
|
||
|
int *e820_nr_map,
|
||
|
@@ -380,21 +436,56 @@ static void add_memory_region (struct e8
|
||
|
unsigned int type)
|
||
|
{
|
||
|
int x = *e820_nr_map;
|
||
|
+ static unsigned long long estart = 0ULL;
|
||
|
+ static unsigned long esize = 0L;
|
||
|
+ static unsigned int etype = -1;
|
||
|
+ static int merge = 0;
|
||
|
+
|
||
|
+ if (x == 0)
|
||
|
+ DPR((L"AMR: %3s %4s %16s/%12s/%s\n",
|
||
|
+ L"idx", L" ", L"start", L"size", L"type"));
|
||
|
|
||
|
- if (x == E820_MAX) {
|
||
|
- Print(L"Too many entries in the memory map!\n");
|
||
|
- return;
|
||
|
- }
|
||
|
-
|
||
|
+ /* merge adjacent regions of same type */
|
||
|
if ((x > 0) && e820_map[x-1].addr + e820_map[x-1].size == start
|
||
|
- && e820_map[x-1].type == type)
|
||
|
+ && e820_map[x-1].type == type) {
|
||
|
e820_map[x-1].size += size;
|
||
|
- else {
|
||
|
+ estart = e820_map[x-1].addr;
|
||
|
+ esize = e820_map[x-1].size;
|
||
|
+ etype = e820_map[x-1].type;
|
||
|
+ merge++;
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ /* fill up to E820_MAX */
|
||
|
+ if ( x < e820_max ) {
|
||
|
e820_map[x].addr = start;
|
||
|
e820_map[x].size = size;
|
||
|
e820_map[x].type = type;
|
||
|
(*e820_nr_map)++;
|
||
|
+ if (merge) DPR((L"AMR: %3d ==> %016llx/%012lx/%d (%d)\n",
|
||
|
+ x-1, estart, esize, etype, merge));
|
||
|
+ merge=0;
|
||
|
+ DPR((L"AMR: %3d add %016llx/%012lx/%d\n",
|
||
|
+ x, start, size, type));
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ /* different type means another region didn't fit */
|
||
|
+ /* or same type, but there's a hole */
|
||
|
+ if (etype != type || (estart + esize) != start) {
|
||
|
+ if (merge) DPR((L"AMR: %3d ===> %016llx/%012lx/%d (%d)\n",
|
||
|
+ e820_map_overflow, estart, esize, etype, merge));
|
||
|
+ merge = 0;
|
||
|
+ estart = start;
|
||
|
+ esize = size;
|
||
|
+ etype = type;
|
||
|
+ e820_map_overflow++;
|
||
|
+ DPR((L"AMR: %3d OVER %016llx/%012lx/%d\n",
|
||
|
+ e820_map_overflow, start, size, type));
|
||
|
+ return;
|
||
|
}
|
||
|
+ /* same type and no hole, merge it */
|
||
|
+ estart += esize;
|
||
|
+ esize += size;
|
||
|
+ merge++;
|
||
|
}
|
||
|
|
||
|
void fill_e820map(boot_params_t *bp, mmap_desc_t *mdesc)
|
||
|
@@ -473,6 +564,7 @@ void fill_e820map(boot_params_t *bp, mma
|
||
|
break;
|
||
|
default:
|
||
|
/* We should not hit this case */
|
||
|
+ DBG_PRT((L"hit default!?"));
|
||
|
add_memory_region(e820_map, &e820_nr_map,
|
||
|
md->PhysicalStart,
|
||
|
md->NumberOfPages << EFI_PAGE_SHIFT,
|
||
|
@@ -486,6 +578,8 @@ void fill_e820map(boot_params_t *bp, mma
|
||
|
|
||
|
/*
|
||
|
* x86_64 specific boot parameters initialization routine
|
||
|
+ *
|
||
|
+ * Note: debug and verbose messages have already been turned off!
|
||
|
*/
|
||
|
INTN
|
||
|
sysdeps_create_boot_params(
|
||
|
@@ -501,6 +595,12 @@ sysdeps_create_boot_params(
|
||
|
UINT8 row, col;
|
||
|
UINT8 mode;
|
||
|
UINT16 hdr_version;
|
||
|
+ UINT8 e820_map_overflow_warned = 0;
|
||
|
+
|
||
|
+#if DEBUG_CREATE_BOOT_PARAMS
|
||
|
+ elilo_opt.debug=1;
|
||
|
+ elilo_opt.verbose=5;
|
||
|
+#endif
|
||
|
|
||
|
DBG_PRT((L"fill_boot_params()\n"));
|
||
|
|
||
|
@@ -834,6 +934,31 @@ do_memmap:
|
||
|
* and update the bootparam accordingly
|
||
|
*/
|
||
|
fill_e820map(bp, &mdesc);
|
||
|
+
|
||
|
+#if DEBUG_CREATE_BOOT_PARAMS
|
||
|
+ if ( e820_map_overflow == 0 )
|
||
|
+ e820_map_overflow = -1; /* force second get_memmap()! */
|
||
|
+#endif
|
||
|
+ if (e820_map_overflow && !e820_map_overflow_warned) {
|
||
|
+ CHAR8 *aem = (CHAR8 *)"add_efi_memmap";
|
||
|
+ e820_map_overflow_warned++;
|
||
|
+
|
||
|
+#if DEBUG_CREATE_BOOT_PARAMS
|
||
|
+ elilo_opt.debug=0;
|
||
|
+ elilo_opt.verbose=0;
|
||
|
+#endif
|
||
|
+ if (e820_map_overflow == -1 || StrStr8(cmdline, aem)) {
|
||
|
+ /* Print(L"...mapping again, silently!\n"); */
|
||
|
+ goto do_memmap;
|
||
|
+ }
|
||
|
+
|
||
|
+ Print(L"\nCAUTION: EFI memory map has %d more entr%a"
|
||
|
+ " than E820 map supports.\n"
|
||
|
+ "To access all memory, '%a' may be necessary.\n\n",
|
||
|
+ e820_map_overflow, (e820_map_overflow==1)?"y":"ies",
|
||
|
+ aem);
|
||
|
+ goto do_memmap;
|
||
|
+ }
|
||
|
|
||
|
return 0;
|
||
|
}
|