diff --git a/kernel/boot/k_bootstrap.cc b/kernel/boot/k_bootstrap.cc index 75c2a1d..2820ecc 100644 --- a/kernel/boot/k_bootstrap.cc +++ b/kernel/boot/k_bootstrap.cc @@ -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); diff --git a/kernel/include/hos_defines.h b/kernel/include/hos_defines.h index 5783776..7f5460f 100644 --- a/kernel/include/hos_defines.h +++ b/kernel/include/hos_defines.h @@ -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 } diff --git a/kernel/mm/mm.cc b/kernel/mm/mm.cc index a61ab59..eefb3da 100644 --- a/kernel/mm/mm.cc +++ b/kernel/mm/mm.cc @@ -1,4 +1,6 @@ +#include + #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; } diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h index 068ebec..b545892 100644 --- a/kernel/mm/mm.h +++ b/kernel/mm/mm.h @@ -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;