* Enlarged maximum kernel size to 2 MB - this is the code the boot loader's
MMU code reserves for the kernel, and we hit that limit recently with the addition of the boot splash code. * This fixes the boot crash as triggered by Stippi's recent changes to the splash image. * Cleanup (doxygen comments, line length). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24805 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2007, Axel Dörfler, [email protected].
|
* Copyright 2004-2008, Axel Dörfler, [email protected].
|
||||||
* Based on code written by Travis Geiselbrecht for NewOS.
|
* Based on code written by Travis Geiselbrecht for NewOS.
|
||||||
*
|
*
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
@@ -22,25 +22,27 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
/** The (physical) memory layout of the boot loader is currently as follows:
|
/*! The (physical) memory layout of the boot loader is currently as follows:
|
||||||
* 0x0500 - 0x10000 protected mode stack
|
0x0500 - 0x10000 protected mode stack
|
||||||
* 0x0500 - 0x09000 real mode stack
|
0x0500 - 0x09000 real mode stack
|
||||||
* 0x10000 - ? code (up to ~500 kB)
|
0x10000 - ? code (up to ~500 kB)
|
||||||
* 0x90000 1st temporary page table (identity maps 0-4 MB)
|
0x90000 1st temporary page table (identity maps 0-4 MB)
|
||||||
* 0x91000 2nd (4-8 MB)
|
0x91000 2nd (4-8 MB)
|
||||||
* 0x92000 - 0x92000 further page tables
|
0x92000 - 0x92000 further page tables
|
||||||
* 0x9e000 - 0xa0000 SMP trampoline code
|
0x9e000 - 0xa0000 SMP trampoline code
|
||||||
* [0xa0000 - 0x100000 BIOS/ROM/reserved area]
|
[0xa0000 - 0x100000 BIOS/ROM/reserved area]
|
||||||
* 0x100000 page directory
|
0x100000 page directory
|
||||||
* ... boot loader heap (32 kB)
|
... boot loader heap (32 kB)
|
||||||
* ... free physical memory
|
... free physical memory
|
||||||
*
|
|
||||||
* The first 8 MB are identity mapped (0x0 - 0x0800000); paging is turned
|
The first 8 MB are identity mapped (0x0 - 0x0800000); paging is turned
|
||||||
* on. The kernel is mapped at 0x80000000, all other stuff mapped by the
|
on. The kernel is mapped at 0x80000000, all other stuff mapped by the
|
||||||
* loader (kernel args, modules, driver settings, ...) comes after
|
loader (kernel args, modules, driver settings, ...) comes after
|
||||||
* 0x81000000 which means that there is currently only 1 MB reserved for
|
0x80020000 which means that there is currently only 2 MB reserved for
|
||||||
* the kernel itself (see kMaxKernelSize).
|
the kernel itself (see kMaxKernelSize).
|
||||||
*/
|
|
||||||
|
The layout in PXE mode differs a bit from this, see definitions below.
|
||||||
|
*/
|
||||||
|
|
||||||
//#define TRACE_MMU
|
//#define TRACE_MMU
|
||||||
#ifdef TRACE_MMU
|
#ifdef TRACE_MMU
|
||||||
@@ -61,14 +63,15 @@ struct extended_memory {
|
|||||||
uint32 type;
|
uint32 type;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _PXE_ENV
|
|
||||||
|
|
||||||
static const uint32 kDefaultPageTableFlags = 0x07; // present, user, R/W
|
static const uint32 kDefaultPageTableFlags = 0x07; // present, user, R/W
|
||||||
static const size_t kMaxKernelSize = 0x100000; // 1 MB for the kernel
|
static const size_t kMaxKernelSize = 0x200000; // 2 MB for the kernel
|
||||||
|
|
||||||
// working page directory and page table
|
// working page directory and page table
|
||||||
static uint32 *sPageDirectory = 0;
|
static uint32 *sPageDirectory = 0;
|
||||||
|
|
||||||
|
#ifdef _PXE_ENV
|
||||||
|
|
||||||
static addr_t sNextPhysicalAddress = 0x112000;
|
static addr_t sNextPhysicalAddress = 0x112000;
|
||||||
static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize;
|
static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize;
|
||||||
static addr_t sMaxVirtualAddress = KERNEL_BASE + 0x400000;
|
static addr_t sMaxVirtualAddress = KERNEL_BASE + 0x400000;
|
||||||
@@ -79,12 +82,6 @@ static const uint32 kPageTableRegionEnd = 0x8b000;
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static const uint32 kDefaultPageTableFlags = 0x07; // present, user, R/W
|
|
||||||
static const size_t kMaxKernelSize = 0x100000; // 1 MB for the kernel
|
|
||||||
|
|
||||||
// working page directory and page table
|
|
||||||
static uint32 *sPageDirectory = 0;
|
|
||||||
|
|
||||||
static addr_t sNextPhysicalAddress = 0x100000;
|
static addr_t sNextPhysicalAddress = 0x100000;
|
||||||
static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize;
|
static addr_t sNextVirtualAddress = KERNEL_BASE + kMaxKernelSize;
|
||||||
static addr_t sMaxVirtualAddress = KERNEL_BASE + 0x400000;
|
static addr_t sMaxVirtualAddress = KERNEL_BASE + 0x400000;
|
||||||
@@ -133,9 +130,9 @@ get_next_physical_page()
|
|||||||
static uint32 *
|
static uint32 *
|
||||||
get_next_page_table()
|
get_next_page_table()
|
||||||
{
|
{
|
||||||
TRACE(("get_next_page_table, sNextPageTableAddress %p, kPageTableRegionEnd %p\n",
|
TRACE(("get_next_page_table, sNextPageTableAddress %p, kPageTableRegionEnd "
|
||||||
sNextPageTableAddress, kPageTableRegionEnd));
|
"%p\n", sNextPageTableAddress, kPageTableRegionEnd));
|
||||||
|
|
||||||
addr_t address = sNextPageTableAddress;
|
addr_t address = sNextPageTableAddress;
|
||||||
if (address >= kPageTableRegionEnd)
|
if (address >= kPageTableRegionEnd)
|
||||||
return (uint32 *)get_next_physical_page();
|
return (uint32 *)get_next_physical_page();
|
||||||
@@ -145,8 +142,7 @@ get_next_page_table()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Adds a new page table for the specified base address */
|
/*! Adds a new page table for the specified base address */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_page_table(addr_t base)
|
add_page_table(addr_t base)
|
||||||
{
|
{
|
||||||
@@ -154,16 +150,20 @@ add_page_table(addr_t base)
|
|||||||
|
|
||||||
// Get new page table and clear it out
|
// Get new page table and clear it out
|
||||||
uint32 *pageTable = get_next_page_table();
|
uint32 *pageTable = get_next_page_table();
|
||||||
if (pageTable > (uint32 *)(8 * 1024 * 1024))
|
if (pageTable > (uint32 *)(8 * 1024 * 1024)) {
|
||||||
panic("tried to add page table beyond the indentity mapped 8 MB region\n");
|
panic("tried to add page table beyond the indentity mapped 8 MB "
|
||||||
|
"region\n");
|
||||||
|
}
|
||||||
|
|
||||||
gKernelArgs.arch_args.pgtables[gKernelArgs.arch_args.num_pgtables++] = (uint32)pageTable;
|
gKernelArgs.arch_args.pgtables[gKernelArgs.arch_args.num_pgtables++]
|
||||||
|
= (uint32)pageTable;
|
||||||
|
|
||||||
for (int32 i = 0; i < 1024; i++)
|
for (int32 i = 0; i < 1024; i++)
|
||||||
pageTable[i] = 0;
|
pageTable[i] = 0;
|
||||||
|
|
||||||
// put the new page table into the page directory
|
// put the new page table into the page directory
|
||||||
sPageDirectory[base/(4*1024*1024)] = (uint32)pageTable | kDefaultPageTableFlags;
|
sPageDirectory[base / (4 * 1024 * 1024)]
|
||||||
|
= (uint32)pageTable | kDefaultPageTableFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,8 +172,10 @@ unmap_page(addr_t virtualAddress)
|
|||||||
{
|
{
|
||||||
TRACE(("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress));
|
TRACE(("unmap_page(virtualAddress = %p)\n", (void *)virtualAddress));
|
||||||
|
|
||||||
if (virtualAddress < KERNEL_BASE)
|
if (virtualAddress < KERNEL_BASE) {
|
||||||
panic("unmap_page: asked to unmap invalid page %p!\n", (void *)virtualAddress);
|
panic("unmap_page: asked to unmap invalid page %p!\n",
|
||||||
|
(void *)virtualAddress);
|
||||||
|
}
|
||||||
|
|
||||||
// unmap the page from the correct page table
|
// unmap the page from the correct page table
|
||||||
uint32 *pageTable = (uint32 *)(sPageDirectory[virtualAddress
|
uint32 *pageTable = (uint32 *)(sPageDirectory[virtualAddress
|
||||||
@@ -184,19 +186,20 @@ unmap_page(addr_t virtualAddress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Creates an entry to map the specified virtualAddress to the given
|
/*! Creates an entry to map the specified virtualAddress to the given
|
||||||
* physicalAddress.
|
physicalAddress.
|
||||||
* If the mapping goes beyond the current page table, it will allocate
|
If the mapping goes beyond the current page table, it will allocate
|
||||||
* a new one. If it cannot map the requested page, it panics.
|
a new one. If it cannot map the requested page, it panics.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
|
map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
|
||||||
{
|
{
|
||||||
TRACE(("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, physicalAddress));
|
TRACE(("map_page: vaddr 0x%lx, paddr 0x%lx\n", virtualAddress, physicalAddress));
|
||||||
|
|
||||||
if (virtualAddress < KERNEL_BASE)
|
if (virtualAddress < KERNEL_BASE) {
|
||||||
panic("map_page: asked to map invalid page %p!\n", (void *)virtualAddress);
|
panic("map_page: asked to map invalid page %p!\n",
|
||||||
|
(void *)virtualAddress);
|
||||||
|
}
|
||||||
|
|
||||||
if (virtualAddress >= sMaxVirtualAddress) {
|
if (virtualAddress >= sMaxVirtualAddress) {
|
||||||
// we need to add a new page table
|
// we need to add a new page table
|
||||||
@@ -204,8 +207,10 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
|
|||||||
add_page_table(sMaxVirtualAddress);
|
add_page_table(sMaxVirtualAddress);
|
||||||
sMaxVirtualAddress += B_PAGE_SIZE * 1024;
|
sMaxVirtualAddress += B_PAGE_SIZE * 1024;
|
||||||
|
|
||||||
if (virtualAddress >= sMaxVirtualAddress)
|
if (virtualAddress >= sMaxVirtualAddress) {
|
||||||
panic("map_page: asked to map a page to %p\n", (void *)virtualAddress);
|
panic("map_page: asked to map a page to %p\n",
|
||||||
|
(void *)virtualAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
physicalAddress &= ~(B_PAGE_SIZE - 1);
|
physicalAddress &= ~(B_PAGE_SIZE - 1);
|
||||||
@@ -214,9 +219,9 @@ map_page(addr_t virtualAddress, addr_t physicalAddress, uint32 flags)
|
|||||||
uint32 *pageTable = (uint32 *)(sPageDirectory[virtualAddress
|
uint32 *pageTable = (uint32 *)(sPageDirectory[virtualAddress
|
||||||
/ (B_PAGE_SIZE * 1024)] & 0xfffff000);
|
/ (B_PAGE_SIZE * 1024)] & 0xfffff000);
|
||||||
uint32 tableEntry = (virtualAddress % (B_PAGE_SIZE * 1024)) / B_PAGE_SIZE;
|
uint32 tableEntry = (virtualAddress % (B_PAGE_SIZE * 1024)) / B_PAGE_SIZE;
|
||||||
|
|
||||||
TRACE(("map_page: inserting pageTable %p, tableEntry %ld, physicalAddress %p\n",
|
TRACE(("map_page: inserting pageTable %p, tableEntry %ld, physicalAddress "
|
||||||
pageTable, tableEntry, physicalAddress));
|
"%p\n", pageTable, tableEntry, physicalAddress));
|
||||||
|
|
||||||
pageTable[tableEntry] = physicalAddress | flags;
|
pageTable[tableEntry] = physicalAddress | flags;
|
||||||
|
|
||||||
@@ -251,7 +256,7 @@ static uint32
|
|||||||
get_memory_map(extended_memory **_extendedMemory)
|
get_memory_map(extended_memory **_extendedMemory)
|
||||||
{
|
{
|
||||||
extended_memory *block = (extended_memory *)kExtraSegmentScratch;
|
extended_memory *block = (extended_memory *)kExtraSegmentScratch;
|
||||||
bios_regs regs = { 0, 0, sizeof(extended_memory), 0, 0, (uint32)block, 0, 0};
|
bios_regs regs = {0, 0, sizeof(extended_memory), 0, 0, (uint32)block, 0, 0};
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
|
|
||||||
TRACE(("get_memory_map()\n"));
|
TRACE(("get_memory_map()\n"));
|
||||||
@@ -273,7 +278,7 @@ get_memory_map(extended_memory **_extendedMemory)
|
|||||||
#ifdef TRACE_MMU
|
#ifdef TRACE_MMU
|
||||||
dprintf("extended memory info (from 0xe820):\n");
|
dprintf("extended memory info (from 0xe820):\n");
|
||||||
for (uint32 i = 0; i < count; i++) {
|
for (uint32 i = 0; i < count; i++) {
|
||||||
dprintf(" base 0x%Lx, len 0x%Lx, type %lu\n",
|
dprintf(" base 0x%Lx, len 0x%Lx, type %lu\n",
|
||||||
block[i].base_addr, block[i].length, block[i].type);
|
block[i].base_addr, block[i].length, block[i].type);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -351,8 +356,8 @@ mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 flags)
|
|||||||
extern "C" void *
|
extern "C" void *
|
||||||
mmu_allocate(void *virtualAddress, size_t size)
|
mmu_allocate(void *virtualAddress, size_t size)
|
||||||
{
|
{
|
||||||
TRACE(("mmu_allocate: requested vaddr: %p, next free vaddr: 0x%lx, size: %ld\n",
|
TRACE(("mmu_allocate: requested vaddr: %p, next free vaddr: 0x%lx, size: "
|
||||||
virtualAddress, sNextVirtualAddress, size));
|
"%ld\n", virtualAddress, sNextVirtualAddress, size));
|
||||||
|
|
||||||
size = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE;
|
size = (size + B_PAGE_SIZE - 1) / B_PAGE_SIZE;
|
||||||
// get number of pages to map
|
// get number of pages to map
|
||||||
@@ -360,13 +365,14 @@ mmu_allocate(void *virtualAddress, size_t size)
|
|||||||
if (virtualAddress != NULL) {
|
if (virtualAddress != NULL) {
|
||||||
// This special path is almost only useful for loading the
|
// This special path is almost only useful for loading the
|
||||||
// kernel into memory; it will only allow you to map the
|
// kernel into memory; it will only allow you to map the
|
||||||
// 1 MB following the kernel base address.
|
// 'kMaxKernelSize' bytes following the kernel base address.
|
||||||
// Also, it won't check for already mapped addresses, so
|
// Also, it won't check for already mapped addresses, so
|
||||||
// you better know why you are here :)
|
// you better know why you are here :)
|
||||||
addr_t address = (addr_t)virtualAddress;
|
addr_t address = (addr_t)virtualAddress;
|
||||||
|
|
||||||
// is the address within the valid range?
|
// is the address within the valid range?
|
||||||
if (address < KERNEL_BASE || address + size >= KERNEL_BASE + kMaxKernelSize)
|
if (address < KERNEL_BASE
|
||||||
|
|| address + size >= KERNEL_BASE + kMaxKernelSize)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (uint32 i = 0; i < size; i++) {
|
for (uint32 i = 0; i < size; i++) {
|
||||||
@@ -380,18 +386,18 @@ mmu_allocate(void *virtualAddress, size_t size)
|
|||||||
void *address = (void *)sNextVirtualAddress;
|
void *address = (void *)sNextVirtualAddress;
|
||||||
|
|
||||||
for (uint32 i = 0; i < size; i++) {
|
for (uint32 i = 0; i < size; i++) {
|
||||||
map_page(get_next_virtual_page(), get_next_physical_page(), kDefaultPageFlags);
|
map_page(get_next_virtual_page(), get_next_physical_page(),
|
||||||
|
kDefaultPageFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** This will unmap the allocated chunk of memory from the virtual
|
/*! This will unmap the allocated chunk of memory from the virtual
|
||||||
* address space. It might not actually free memory (as its implementation
|
address space. It might not actually free memory (as its implementation
|
||||||
* is very simple), but it might.
|
is very simple), but it might.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
mmu_free(void *virtualAddress, size_t size)
|
mmu_free(void *virtualAddress, size_t size)
|
||||||
{
|
{
|
||||||
@@ -421,11 +427,10 @@ mmu_free(void *virtualAddress, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sets up the final and kernel accessible GDT and IDT tables.
|
/*! Sets up the final and kernel accessible GDT and IDT tables.
|
||||||
* BIOS calls won't work any longer after this function has
|
BIOS calls won't work any longer after this function has
|
||||||
* been called.
|
been called.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
mmu_init_for_kernel(void)
|
mmu_init_for_kernel(void)
|
||||||
{
|
{
|
||||||
@@ -488,7 +493,7 @@ mmu_init_for_kernel(void)
|
|||||||
// seg 0x10 - kernel 4GB data
|
// seg 0x10 - kernel 4GB data
|
||||||
set_segment_descriptor(&virtualGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE,
|
set_segment_descriptor(&virtualGDT[2], 0, 0xffffffff, DT_DATA_WRITEABLE,
|
||||||
DPL_KERNEL);
|
DPL_KERNEL);
|
||||||
|
|
||||||
// seg 0x1b - ring 3 user 4GB code
|
// seg 0x1b - ring 3 user 4GB code
|
||||||
set_segment_descriptor(&virtualGDT[3], 0, 0xffffffff, DT_CODE_READABLE,
|
set_segment_descriptor(&virtualGDT[3], 0, 0xffffffff, DT_CODE_READABLE,
|
||||||
DPL_USER);
|
DPL_USER);
|
||||||
@@ -511,17 +516,23 @@ mmu_init_for_kernel(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// save the memory we've physically allocated
|
// save the memory we've physically allocated
|
||||||
gKernelArgs.physical_allocated_range[0].size = sNextPhysicalAddress - gKernelArgs.physical_allocated_range[0].start;
|
gKernelArgs.physical_allocated_range[0].size
|
||||||
|
= sNextPhysicalAddress - gKernelArgs.physical_allocated_range[0].start;
|
||||||
|
|
||||||
// save the memory we've virtually allocated (for the kernel and other stuff)
|
// Save the memory we've virtually allocated (for the kernel and other
|
||||||
|
// stuff)
|
||||||
gKernelArgs.virtual_allocated_range[0].start = KERNEL_BASE;
|
gKernelArgs.virtual_allocated_range[0].start = KERNEL_BASE;
|
||||||
gKernelArgs.virtual_allocated_range[0].size = sNextVirtualAddress - KERNEL_BASE;
|
gKernelArgs.virtual_allocated_range[0].size
|
||||||
|
= sNextVirtualAddress - KERNEL_BASE;
|
||||||
gKernelArgs.num_virtual_allocated_ranges = 1;
|
gKernelArgs.num_virtual_allocated_ranges = 1;
|
||||||
|
|
||||||
// sort the address ranges
|
// sort the address ranges
|
||||||
sort_addr_range(gKernelArgs.physical_memory_range, gKernelArgs.num_physical_memory_ranges);
|
sort_addr_range(gKernelArgs.physical_memory_range,
|
||||||
sort_addr_range(gKernelArgs.physical_allocated_range, gKernelArgs.num_physical_allocated_ranges);
|
gKernelArgs.num_physical_memory_ranges);
|
||||||
sort_addr_range(gKernelArgs.virtual_allocated_range, gKernelArgs.num_virtual_allocated_ranges);
|
sort_addr_range(gKernelArgs.physical_allocated_range,
|
||||||
|
gKernelArgs.num_physical_allocated_ranges);
|
||||||
|
sort_addr_range(gKernelArgs.virtual_allocated_range,
|
||||||
|
gKernelArgs.num_virtual_allocated_ranges);
|
||||||
|
|
||||||
#ifdef TRACE_MMU
|
#ifdef TRACE_MMU
|
||||||
{
|
{
|
||||||
@@ -566,10 +577,12 @@ mmu_init(void)
|
|||||||
|
|
||||||
// also map it on the next vpage
|
// also map it on the next vpage
|
||||||
gKernelArgs.arch_args.vir_pgdir = get_next_virtual_page();
|
gKernelArgs.arch_args.vir_pgdir = get_next_virtual_page();
|
||||||
map_page(gKernelArgs.arch_args.vir_pgdir, (uint32)sPageDirectory, kDefaultPageFlags);
|
map_page(gKernelArgs.arch_args.vir_pgdir, (uint32)sPageDirectory,
|
||||||
|
kDefaultPageFlags);
|
||||||
|
|
||||||
// map in a kernel stack
|
// map in a kernel stack
|
||||||
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL, KERNEL_STACK_SIZE);
|
gKernelArgs.cpu_kstack[0].start = (addr_t)mmu_allocate(NULL,
|
||||||
|
KERNEL_STACK_SIZE);
|
||||||
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE;
|
gKernelArgs.cpu_kstack[0].size = KERNEL_STACK_SIZE;
|
||||||
|
|
||||||
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
TRACE(("kernel stack at 0x%lx to 0x%lx\n", gKernelArgs.cpu_kstack[0].start,
|
||||||
@@ -587,16 +600,24 @@ mmu_init(void)
|
|||||||
if (extMemoryBlock[i].type == 1) {
|
if (extMemoryBlock[i].type == 1) {
|
||||||
// round everything up to page boundaries, exclusive of pages
|
// round everything up to page boundaries, exclusive of pages
|
||||||
// it partially occupies
|
// it partially occupies
|
||||||
extMemoryBlock[i].length -= (extMemoryBlock[i].base_addr % B_PAGE_SIZE)
|
if ((extMemoryBlock[i].base_addr % B_PAGE_SIZE) != 0) {
|
||||||
? (B_PAGE_SIZE - (extMemoryBlock[i].base_addr % B_PAGE_SIZE)) : 0;
|
extMemoryBlock[i].length -= B_PAGE_SIZE
|
||||||
extMemoryBlock[i].base_addr = ROUNDUP(extMemoryBlock[i].base_addr, B_PAGE_SIZE);
|
- extMemoryBlock[i].base_addr % B_PAGE_SIZE;
|
||||||
extMemoryBlock[i].length = ROUNDOWN(extMemoryBlock[i].length, B_PAGE_SIZE);
|
}
|
||||||
|
extMemoryBlock[i].base_addr
|
||||||
|
= ROUNDUP(extMemoryBlock[i].base_addr, B_PAGE_SIZE);
|
||||||
|
extMemoryBlock[i].length
|
||||||
|
= ROUNDOWN(extMemoryBlock[i].length, B_PAGE_SIZE);
|
||||||
|
|
||||||
// we ignore all memory beyond 4 GB
|
// we ignore all memory beyond 4 GB
|
||||||
if (extMemoryBlock[i].base_addr > 0xffffffffULL)
|
if (extMemoryBlock[i].base_addr > 0xffffffffULL)
|
||||||
continue;
|
continue;
|
||||||
if (extMemoryBlock[i].base_addr + extMemoryBlock[i].length > 0xffffffffULL)
|
|
||||||
extMemoryBlock[i].length = 0x100000000ULL - extMemoryBlock[i].base_addr;
|
if (extMemoryBlock[i].base_addr + extMemoryBlock[i].length
|
||||||
|
> 0xffffffffULL) {
|
||||||
|
extMemoryBlock[i].length
|
||||||
|
= 0x100000000ULL - extMemoryBlock[i].base_addr;
|
||||||
|
}
|
||||||
|
|
||||||
if (gKernelArgs.num_physical_memory_ranges > 0) {
|
if (gKernelArgs.num_physical_memory_ranges > 0) {
|
||||||
// we might want to extend a previous hole
|
// we might want to extend a previous hole
|
||||||
@@ -606,14 +627,16 @@ mmu_init(void)
|
|||||||
gKernelArgs.num_physical_memory_ranges - 1].size;
|
gKernelArgs.num_physical_memory_ranges - 1].size;
|
||||||
addr_t holeSize = extMemoryBlock[i].base_addr - previousEnd;
|
addr_t holeSize = extMemoryBlock[i].base_addr - previousEnd;
|
||||||
|
|
||||||
// if the hole is smaller than 1 MB, we try to mark the memory
|
// If the hole is smaller than 1 MB, we try to mark the
|
||||||
// as allocated and extend the previous memory range
|
// memory as allocated and extend the previous memory range
|
||||||
if (previousEnd <= extMemoryBlock[i].base_addr
|
if (previousEnd <= extMemoryBlock[i].base_addr
|
||||||
&& holeSize < 0x100000
|
&& holeSize < 0x100000
|
||||||
&& insert_physical_allocated_range(previousEnd,
|
&& insert_physical_allocated_range(previousEnd,
|
||||||
extMemoryBlock[i].base_addr - previousEnd) == B_OK) {
|
extMemoryBlock[i].base_addr - previousEnd)
|
||||||
|
== B_OK) {
|
||||||
gKernelArgs.physical_memory_range[
|
gKernelArgs.physical_memory_range[
|
||||||
gKernelArgs.num_physical_memory_ranges - 1].size += holeSize;
|
gKernelArgs.num_physical_memory_ranges - 1].size
|
||||||
|
+= holeSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,19 +645,22 @@ mmu_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ToDo: for now!
|
// TODO: for now!
|
||||||
dprintf("No extended memory block - using 32 MB (fix me!)\n");
|
dprintf("No extended memory block - using 32 MB (fix me!)\n");
|
||||||
uint32 memSize = 32 * 1024 * 1024;
|
uint32 memSize = 32 * 1024 * 1024;
|
||||||
|
|
||||||
// we dont have an extended map, assume memory is contiguously mapped at 0x0
|
// We dont have an extended map, assume memory is contiguously mapped
|
||||||
|
// at 0x0
|
||||||
gKernelArgs.physical_memory_range[0].start = 0;
|
gKernelArgs.physical_memory_range[0].start = 0;
|
||||||
gKernelArgs.physical_memory_range[0].size = memSize;
|
gKernelArgs.physical_memory_range[0].size = memSize;
|
||||||
gKernelArgs.num_physical_memory_ranges = 1;
|
gKernelArgs.num_physical_memory_ranges = 1;
|
||||||
|
|
||||||
// mark the bios area allocated
|
// mark the bios area allocated
|
||||||
gKernelArgs.physical_allocated_range[gKernelArgs.num_physical_allocated_ranges].start = 0x9f000; // 640k - 1 page
|
uint32 biosRange = gKernelArgs.num_physical_allocated_ranges++;
|
||||||
gKernelArgs.physical_allocated_range[gKernelArgs.num_physical_allocated_ranges].size = 0x61000;
|
|
||||||
gKernelArgs.num_physical_allocated_ranges++;
|
gKernelArgs.physical_allocated_range[biosRange].start = 0x9f000;
|
||||||
|
// 640k - 1 page
|
||||||
|
gKernelArgs.physical_allocated_range[biosRange].size = 0x61000;
|
||||||
}
|
}
|
||||||
|
|
||||||
gKernelArgs.arch_args.page_hole = 0xffc00000;
|
gKernelArgs.arch_args.page_hole = 0xffc00000;
|
||||||
|
|||||||
Reference in New Issue
Block a user