bootloader: pass memory map to kernel
Previously, the bootloader would only provide a single memory range. At least on VirtualBox, this memory range includes the ACPI tables, which the kernel then happily overwrites when executing VM. Much of the infrastructure to use a fullblown memory map is already in place; this patch adds the last (and strangely missing) bit of generating the memory map in a multiboot-compatible way. It should be noted that both the bootloader and the kernel actually violate the multiboot specification by not packing the structure for the memory ranges. This is a NetBSD bug, but it is also a nonissue for (our) practical purposes. It can be fixed without changing the code added in this patch. Change-Id: I7c0a307a8a8133239531e1d2b80f376849f90247
This commit is contained in:
parent
29492bb71c
commit
3b0299dd65
1 changed files with 51 additions and 0 deletions
|
@ -666,6 +666,49 @@ userconf_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(PASS_MEMMAP) && defined(__minix)
|
||||
/*
|
||||
* Construct a memory map for the multiboot info structure, with memory ranges
|
||||
* as reported by the BIOS. If successful, set the HAS_MMAP flag. Code copied
|
||||
* largely from bootinfo_memmap.c.
|
||||
*/
|
||||
static void
|
||||
memmap_init(struct multiboot_info * mbi)
|
||||
{
|
||||
multiboot_memory_map_t *mmap;
|
||||
int buf[5], i, nranges;
|
||||
|
||||
nranges = 0;
|
||||
i = 0;
|
||||
do {
|
||||
if (getmementry(&i, buf))
|
||||
break;
|
||||
nranges++;
|
||||
} while (i);
|
||||
|
||||
if (nranges == 0)
|
||||
return;
|
||||
|
||||
mbi->mmap_length = sizeof(multiboot_memory_map_t) * nranges;
|
||||
|
||||
mmap = alloc(mbi->mmap_length);
|
||||
|
||||
mbi->mmap_addr = vtophys(mmap);
|
||||
|
||||
i = 0;
|
||||
while (nranges-- > 0) {
|
||||
getmementry(&i, buf);
|
||||
|
||||
/* Stupid tricks to deal with alignment issues. */
|
||||
memcpy(&mmap->mm_base_addr, buf, sizeof(buf));
|
||||
mmap->mm_size = sizeof(*mmap) - sizeof(mmap->mm_size);
|
||||
mmap++;
|
||||
}
|
||||
|
||||
mbi->mi_flags |= MULTIBOOT_INFO_HAS_MMAP;
|
||||
}
|
||||
#endif /* PASS_MEMMAP && __minix */
|
||||
|
||||
int
|
||||
exec_multiboot(const char *file, char *args)
|
||||
{
|
||||
|
@ -718,6 +761,14 @@ exec_multiboot(const char *file, char *args)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(PASS_MEMMAP) && defined(__minix)
|
||||
/*
|
||||
* The MINIX3 kernel needs a full memory map. Without it, it will do
|
||||
* silly things such as overwriting the ACPI tables.
|
||||
*/
|
||||
memmap_init(mbi);
|
||||
#endif /* PASS_MEMMAP && __minix */
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n", marks[MARK_ENTRY],
|
||||
marks[MARK_NSYM], marks[MARK_SYM], marks[MARK_END]);
|
||||
|
|
Loading…
Reference in a new issue