kernel: load at 16 MB, clear of what firmware keeps low
From 1 MB the 34 MB kernel ran across 8 MB, where OVMF keeps ACPI NVS memory that outlives the firmware -- so it was overwritten on every boot, after ExitBootServices. Firmware leaves its leftovers low; above 16 MB is where a machine is most reliably empty. KERNPHYS in memlayout.h, and kernel.ld agreeing with it. Nothing else named the old address. Under OVMF the range is now only boot-services memory: staged, copied home after the firmware exits, no warning. Boots as a CD and as a USB disk, 1 and 4 CPUs. The 15 MB below the kernel is not given to the page allocator yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
93d3b123c5
commit
5ed8f1b0d5
4 changed files with 14 additions and 5 deletions
|
|
@ -594,7 +594,7 @@ place_staged(void)
|
|||
}
|
||||
|
||||
// Load PT_LOAD segments to p_paddr. Physical addresses, not virtual: the
|
||||
// kernel is linked at 0xffff800000100000 but must be *placed* at 0x100000, and
|
||||
// kernel is linked at 0xffff800001000000 but must be *placed* at 0x1000000, and
|
||||
// p_paddr is where the linker script says each segment belongs.
|
||||
static UINT64
|
||||
load_elf(EFI_FILE_PROTOCOL *file)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,16 @@ extern uint64 lowtop;
|
|||
|
||||
// Key addresses for address space layout
|
||||
#define KERNBASE 0xFFFF800000000000 // First kernel virtual address
|
||||
#define KERNLINK (KERNBASE+EXTMEM) // Address where kernel is linked
|
||||
// Where the kernel is placed in physical memory, and linked above KERNBASE.
|
||||
//
|
||||
// 16 MB, not the 1 MB xv6 used. The kernel is 34 MB with the RAM disk in it,
|
||||
// and from 1 MB that ran across 8 MB, where OVMF keeps ACPI NVS memory --
|
||||
// which outlives the firmware, so the kernel was copied over it after
|
||||
// ExitBootServices on every boot. Firmware keeps its leftovers low; above
|
||||
// 16 MB is where a machine is most reliably empty. kernel/kernel.ld repeats
|
||||
// this number and has to agree.
|
||||
#define KERNPHYS 0x1000000
|
||||
#define KERNLINK (KERNBASE+KERNPHYS) // Address where kernel is linked
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
static inline addr_t v2p(void *a) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
//
|
||||
// 0x30000 is clear of stage2 (loaded at 0x7E00 and well under 0xA000), the
|
||||
// multiboot kernel-search buffer at 0x10000-0x14000, and the kernel's own load
|
||||
// address at 0x100000.
|
||||
// address at KERNPHYS, 16 MB.
|
||||
//
|
||||
// Both loaders write it, so a field's meaning must not depend on which one did.
|
||||
// Where they genuinely differ -- the BIOS path knows what medium it booted
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ OUTPUT_FORMAT("elf64-x86-64")
|
|||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
|
||||
mboot_load_addr = 0x00100000;
|
||||
mboot_load_addr = 0x01000000; /* KERNPHYS in include/arch/memlayout.h */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Link the kernel at this address: "." means the current address */
|
||||
/* Must be equal to KERNLINK */
|
||||
. = 0xFFFF800000100000;
|
||||
. = 0xFFFF800001000000;
|
||||
|
||||
PROVIDE(begin = .);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue