#define __ELILO_SYSDEPS_IA32_H__
#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))
* A new bit, LDRFLAG_BOOT_PARAM_RELOC, in the loader_flags
* field is also defined in this file.
*/
-typedef struct efi_ia32_boot_params {
- UINT32 size;
- UINT32 command_line;
- UINT32 efi_sys_tbl;
- UINT32 efi_mem_map;
- UINT32 efi_mem_map_size;
- UINT32 efi_mem_desc_size;
- UINT32 efi_mem_desc_version;
- UINT32 initrd_start;
- UINT32 initrd_size;
- UINT32 loader_start;
- UINT32 loader_size;
- UINT32 kernel_start;
- UINT32 kernel_size;
- UINT16 num_cols;
- UINT16 num_rows;
- UINT16 orig_x;
- UINT16 orig_y;
-} efi_ia32_boot_params_t;
-
-extern efi_ia32_boot_params_t efi_ia32_bp;
-
+
#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 {
UINT8 raw[0x2000];
struct {
/* EFI boot loader signature. */
/* 0x1C0 */ UINT8 efi_loader_sig[4]; /* LDR */
-#define EFI_LOADER_SIG "EFIL"
+#define EFI_LOADER_SIG_IA32 "EL32"
/* Address of the EFI system table. */
/* 0x1C4 */ UINT32 efi_sys_tbl; /* LDR */
/* Available contiguous extended memory in KB. */
/* 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). */
/* 0x1F1 */ UINT8 setup_sectors; /* BLD */
/* 0x224 */ UINT16 heap_end_ptr; /* LDR */
/* %%TBD */
-/* 0x226 */ UINT32 base_mem_size; /* LDR */
+/* 0x226 */ UINT16 unused_7; /* LDR */
+
+/* 0x228 */ UINT32 cmdline_addr; /* LDR */
+/* 0x22C */ UINT32 unused_8[41];
+/* 0x2D0 */ UINT8 e820_map[2560];
} s;
} boot_params_t;
#pragma pack()
UINT8 *t = (UINT8 *)(to); \
UINT8 *f = (UINT8 *)(from); \
UINTN n = cnt; \
- if (t && f && n) { \
- while (n--) { \
- *t++ = *f++; \
- } \
- } \
+ 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--; \
+ } \
+ } \
}
#define MEMSET(ptr, size, val) { \
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;
static inline void
start_kernel(VOID *kentry, boot_params_t *bp)
{
+ UINT32 temp;
+
/*
* Disable interrupts.
*/
-
asm volatile ( "cli" : : );
- /*
- * Relocate initrd, if present.
- */
-
- if (bp->s.initrd_start) {
- /* %%TBD */
- MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size);
- bp->s.initrd_start = 15 * 1024 * 1024;
- }
+ /*
+ * Relocate kernel (if needed), and initrd (if present).
+ * Copy kernel first, in case kernel was loaded overlapping where we're
+ * planning to copy the initrd. This assumes that the initrd didn't
+ * get loaded overlapping where we're planning to copy the kernel, but
+ * that's pretty unlikely since we couldn't alloc that space for the
+ * kernel (or the kernel would already be there).
+ */
+ if (kernel_start != kernel_load_address) {
+ MEMCPY(kernel_start, kernel_load_address, kernel_size);
+ }
+
+ if (bp->s.initrd_start) {
+ temp = bp->s.initrd_start;
+ MEMCPY(INITRD_START, temp , bp->s.initrd_size);
+ bp->s.initrd_start = INITRD_START;
+ }
/*
* Copy boot sector, setup data and command line
MEMCPY(high_base_mem, bp, 0x4000);
- /*
- * initialize efi ia32 boot params and place them at 1kb up from
- * the start of the boot command line param. This results in the
- * efi ia32 boot params to be copied to 0x00104c00. See bootparams.c
- * for details on how this is arranged. EFI enabled
- * kernels will look for the efi boot params here to know if the
- * kernel is booting on an EFI platform or legacy BIOS based platfrom
- */
+ bp = (boot_params_t *)high_base_mem;
+ bp->s.cmdline_addr = high_base_mem + bp->s.cmdline_offset;
- efi_ia32_bp.initrd_start = bp->s.initrd_start;
- efi_ia32_bp.initrd_size = bp->s.initrd_size;
-
- MEMCPY(high_base_mem + 0x4000 - 0x0400, &efi_ia32_bp, sizeof(efi_ia32_bp));
-
/*
* Initialize Linux GDT.
*/
* Jump to kernel entry point.
*/
-
asm volatile ( "jmp *%%ecx" : : );
}