diff options
-rw-r--r-- | kernel/include/mm/physical_mm.h | 4 | ||||
-rw-r--r-- | kernel/include/mm/virtual_mm.h | 2 | ||||
-rw-r--r-- | kernel/kernel/kernel.c | 3 | ||||
-rw-r--r-- | kernel/mm/physical_mm/physical_mm.c | 4 | ||||
-rw-r--r-- | kernel/mm/virtual_mm/virtual_mm.c | 64 |
5 files changed, 73 insertions, 4 deletions
diff --git a/kernel/include/mm/physical_mm.h b/kernel/include/mm/physical_mm.h index 6befcb0..7ad97d9 100644 --- a/kernel/include/mm/physical_mm.h +++ b/kernel/include/mm/physical_mm.h @@ -29,12 +29,12 @@ #define BITMAP_ENTRY_SIZE 32 -/* TODO: This is the maximum number of blocks for a 4GiB system. */ +/* This is the maximum number of blocks for a 4GiB system. */ #define MAX_BLOCKS 1048576 void physical_mm_init(void); -uint32_t physical_mm_find_first_free_block(void); +uint32_t physical_mm_find_free_block(void); void *physical_mm_allocate_block(void); void physical_mm_free_block(void *physical_address); diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h index 980e809..6bd5178 100644 --- a/kernel/include/mm/virtual_mm.h +++ b/kernel/include/mm/virtual_mm.h @@ -83,4 +83,6 @@ void virtual_mm_initialize(void); */ void virtual_mm_map_page(void *physical_address, void *virtual_address); +void virtual_mm_find_free_virtual_addresses(uint32_t n); + #endif diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index 0ebaf64..f41f48e 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -48,6 +48,9 @@ kernel_main(uint32_t magic, multiboot_info_t *multiboot_info) printk("\nKernel", "Started."); + virtual_mm_map_page((void *) 0x0C00000, (void *) 0x3000); + virtual_mm_find_free_virtual_addresses(2); + exit(); halt(); /* If exit() fails (on real hardware) */ } diff --git a/kernel/mm/physical_mm/physical_mm.c b/kernel/mm/physical_mm/physical_mm.c index 5b405e6..ed89316 100644 --- a/kernel/mm/physical_mm/physical_mm.c +++ b/kernel/mm/physical_mm/physical_mm.c @@ -140,7 +140,7 @@ physical_mm_init(void) } uint32_t -physical_mm_find_first_free_block(void) +physical_mm_find_free_block(void) { /* TODO: Why doesn't using block_count instead of MAX_BLOCKS work? */ for (uint32_t i = 0; i < MAX_BLOCKS / BITMAP_ENTRY_SIZE; i++) @@ -167,7 +167,7 @@ physical_mm_allocate_block(void) spinlock_acquire(&memory_map_lock); - uint32_t block = physical_mm_find_first_free_block(); + uint32_t block = physical_mm_find_free_block(); physical_mm_set_used(block, &total_free_blocks, memory_map); spinlock_release(&memory_map_lock); diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c index 9c239a1..929b37d 100644 --- a/kernel/mm/virtual_mm/virtual_mm.c +++ b/kernel/mm/virtual_mm/virtual_mm.c @@ -113,3 +113,67 @@ virtual_mm_map_page(void *physical_address, void *virtual_address) *pt_entry = PTE_FRAME((uint32_t) physical_address) | PTE_PRESENT(1) | PTE_WRITABLE(1); } + +ALWAYS_INLINE uint32_t * +get_table(uint32_t *pd_entry) +{ + uint32_t *table; + if (!PDE_IS_PRESENT(pd_entry)) { + table = physical_mm_allocate_block(); + if (!table) + ASSERT_NOT_REACHED(); + + for (uint32_t _ = 0; _ < 1024; _++) + table[_] = 0; + + *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1); + } else + table = (uint32_t *) PDE_GET_TABLE(pd_entry); + + return table; +} + +ALWAYS_INLINE void +virtual_mm_find_free_virtual_addresses(uint32_t n) +{ + for (uint32_t i = 0; i < PAGE_DIRECTORY_SIZE; i++) { + uint32_t current_pd_index = i; + uint32_t *pd_entry = ¤t_page_directory[current_pd_index]; + uint32_t *table = get_table(pd_entry); + + for (uint32_t j = 0; j < PAGE_TABLE_SIZE; j++) { + uint32_t *pt_entry = &table[j]; + if (PTE_IS_PRESENT(pt_entry)) + continue; + /* We found our starting pt_entry */ + + printk("debug", "Starting: 0x%x", pt_entry); + uint32_t count = 0; + for (uint32_t k = j; k <= PAGE_TABLE_SIZE; k++) { + /* If we overflow, switch to the consecutive page directory entry */ + if (k == PAGE_TABLE_SIZE) { + pd_entry = ¤t_page_directory[++current_pd_index]; + table = get_table(pd_entry); + printk("debug", "Switching pd_entry: 0x%x", pd_entry); + k = 0; + } + + uint32_t *pt_entry = &table[k]; + if (PTE_IS_PRESENT(pt_entry)) { + count = 0; + current_pd_index = i; + pd_entry = ¤t_page_directory[current_pd_index]; + j += count; + break; + } + + // printk("debug", "Found page: 0x%x", &table[k]); + count++; + if (count == n) { + printk("debug", "Found starting page at: 0x%x", &table[j]); + return; + } + } + } + } +} |