filled out more of mm_bootstrap() including initializing the free page linked list

git-svn-id: svn://anubis/hos/trunk@34 5b3e749e-e535-0410-8002-a9bb6afbdfca
This commit is contained in:
josh 2009-07-02 01:09:09 +00:00
parent bfb4f3bdd0
commit 2bddc1d428
4 changed files with 69 additions and 10 deletions

View File

@ -29,7 +29,7 @@ u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
k_early_panic("No memory map provided by bootloader!");
}
mb_mmap_t * mmap = (mb_mmap_t *) (mb_info->mmap_addr + HOS_KERNEL_OFFSET - 4);
mb_mmap_t * mmap = (mb_mmap_t *) (mb_info->mmap_addr + KERNEL_OFFSET - 4);
for (unsigned int sz = 0; sz < mb_info->mmap_length; sz += mmap->size + 4)
{
mm_record_mmap_entry(mmap);

View File

@ -6,23 +6,28 @@
extern "C" {
#endif
#define HOS_KERNEL_OFFSET 0xE0000000
#define KERNEL_OFFSET 0xE0000000
#define PAGE_LOG_SIZE 12
#define PAGE_SIZE (1 << PAGE_LOG_SIZE)
#define PAGE_HIGH_MASK (0xFFFFFFFFu << PAGE_LOG_SIZE)
#define PAGE_LOW_MASK (0xFFFFFFFFu >> (32 - PAGE_LOG_SIZE))
#define CONSOLE_MEMORY (HOS_KERNEL_OFFSET + 0xB8000)
#define CONSOLE_MEMORY (KERNEL_OFFSET + 0xB8000)
extern u8_t _code;
extern u8_t _data;
extern u8_t _bss;
extern u8_t _end;
#define KERNEL_PHYSICAL_ADDRESS ((&_code) - HOS_KERNEL_OFFSET)
#define KERNEL_VIRTUAL_ADDRESS (&_code)
#define KERNEL_SIZE ((&_end) - (&_code))
#define KERNEL_CODE (&_code)
#define KERNEL_DATA (&_data)
#define KERNEL_BSS (&_bss)
#define KERNEL_END (&_end)
#define KERNEL_PHYSICAL_ADDRESS ((u32_t)(KERNEL_CODE - KERNEL_OFFSET))
#define KERNEL_VIRTUAL_ADDRESS ((u32_t)KERNEL_CODE)
#define KERNEL_SIZE ((u32_t)(KERNEL_END - KERNEL_CODE))
#ifdef __cplusplus
}

View File

@ -1,4 +1,6 @@
#include <stddef.h>
#include "mm.h"
#include "boot/k_early_panic.h"
@ -10,6 +12,8 @@ pagedirectory_t page_directory __attribute__ ((aligned (4096)));
static mm_mem_range_t mm_mmap_entries[MM_MAX_MMAP_ENTRIES];
static int mm_mmap_num_entries = 0;
static int mm_num_free_pages = 0;
u32_t * mm_free_page_ptr = NULL;
/**************************************************************************
* This function is run in segmented memory before paging is in effect. *
@ -38,6 +42,8 @@ void mm_record_mmap_entry(mb_mmap_t * mmap)
*************************************************************************/
void mm_bootstrap()
{
u32_t max_ram_address = KERNEL_PHYSICAL_ADDRESS + KERNEL_SIZE - 1;
if (mm_mmap_num_entries < 1)
{
k_early_panic("No mmap entries read from bootloader!");
@ -45,12 +51,58 @@ void mm_bootstrap()
for (int mmap_idx = 0; mmap_idx < mm_mmap_num_entries; mmap_idx++)
{
u32_t base_address = mm_mmap_entries[mmap_idx].base;
if (base_address & PAGE_LOW_MASK)
{
/* start of this mmap range is not page-aligned */
base_address = (base_address & PAGE_HIGH_MASK) + PAGE_SIZE;
}
u32_t address_limit = mm_mmap_entries[mmap_idx].base +
mm_mmap_entries[mmap_idx].length;
if (address_limit & PAGE_LOW_MASK)
{
/* end of this mmap range is not page-aligned */
address_limit &= PAGE_HIGH_MASK;
}
/* record the highest RAM address found */
if ((address_limit - 1) > max_ram_address)
{
max_ram_address = (address_limit - 1);
}
/*
* loop through every page in the mmap range and add
* pages into the free page linked list
*/
u32_t * last_page = NULL;
while (base_address < address_limit)
{
/* check to make sure the RAM page isn't overlapping the kernel */
if ( base_address + PAGE_SIZE <= KERNEL_PHYSICAL_ADDRESS
&& base_address >= KERNEL_PHYSICAL_ADDRESS + KERNEL_SIZE )
{
/* we found a page to add to the free list */
u32_t * page_virtual_address =
(u32_t *)(base_address + KERNEL_OFFSET);
*page_virtual_address = 0;
if (last_page == NULL)
{
mm_free_page_ptr = (u32_t *) base_address;
}
else
{
*last_page = base_address;
}
last_page = page_virtual_address;
mm_num_free_pages++;
}
base_address += PAGE_SIZE;
}
}
/* Clear the page directory */
for (unsigned int i = 0;
i < sizeof(page_directory) / sizeof(page_directory[0]);
i++)
for (unsigned int i = 0; i < NUM_PAGETABLE_ENTRIES; i++)
{
page_directory[i] = 0;
}

View File

@ -12,8 +12,10 @@ extern "C" {
typedef u32_t pagedirectory_entry_t;
#define NUM_PAGETABLE_ENTRIES (PAGE_SIZE / sizeof(pagedirectory_entry_t))
typedef pagedirectory_entry_t
pagedirectory_t[PAGE_SIZE / sizeof(pagedirectory_entry_t)];
pagedirectory_t[NUM_PAGETABLE_ENTRIES];
extern pagedirectory_t page_directory;