aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2025-01-28 00:54:11 -0500
committerRaghuram Subramani <raghus2247@gmail.com>2025-01-28 00:54:11 -0500
commit690d5f698a14554901d6f661f23695a4dca09a7c (patch)
tree333abfbfb4da7ecd4c45cdb463c823a20ba3d0d6
parenta672e4b99cf43aa800ce9f9f5b8e9c374d2eb98d (diff)
virtual_mm: Implement free_pages()
-rw-r--r--kernel/include/mm/virtual_mm.h14
-rw-r--r--kernel/kernel/kernel.c6
-rw-r--r--kernel/mm/virtual_mm/virtual_mm.c48
3 files changed, 59 insertions, 9 deletions
diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h
index bb63f97..849b370 100644
--- a/kernel/include/mm/virtual_mm.h
+++ b/kernel/include/mm/virtual_mm.h
@@ -88,8 +88,18 @@ void virtual_mm_initialize(void);
void virtual_mm_map_page(void *physical_address, void *virtual_address);
/*
- * Find a virtual address with n consecutive free addresses. AWIUFHAILWFHIALW
+ * Find a virtual address with n consecutive free addresses.
*/
-uint32_t virtual_mm_find_free_virtual_addresses(uint32_t n);
+uint32_t virtual_mm_find_free_virtual_addresses(uint32_t n_pages);
+
+/*
+ * Allocate and map n pages.
+ */
+void *virtual_mm_alloc_pages(uint32_t n_pages);
+
+/*
+ * Free n pages from the starting address.
+ */
+void virtual_mm_free_pages(void *starting_address, uint32_t n_pages);
#endif
diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c
index e988857..8754aa2 100644
--- a/kernel/kernel/kernel.c
+++ b/kernel/kernel/kernel.c
@@ -46,10 +46,10 @@ kernel_main(uint32_t magic, multiboot_info_t *multiboot_info)
physical_mm_init();
virtual_mm_initialize();
- printk("\nKernel", "Started.");
+ void *starting_address = virtual_mm_alloc_pages(1);
+ virtual_mm_free_pages(starting_address, 2);
- // virtual_mm_map_page((void *) 0x0C00000, (void *) 0x3000);
- virtual_mm_find_free_virtual_addresses(3);
+ printk("\nKernel", "Started.");
exit();
halt(); /* If exit() fails (on real hardware) */
diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c
index 573767e..4039597 100644
--- a/kernel/mm/virtual_mm/virtual_mm.c
+++ b/kernel/mm/virtual_mm/virtual_mm.c
@@ -116,6 +116,22 @@ virtual_mm_map_page(void *physical_address, void *virtual_address)
| PTE_WRITABLE(1);
}
+void
+virtual_mm_unmap_page(void *virtual_address)
+{
+ uint32_t *pd_entry = &current_page_directory[GET_PD_INDEX(virtual_address)];
+
+ uint32_t *table = 0;
+ /* If the pd_entry isn't present, return */
+ if (!PDE_IS_PRESENT(pd_entry))
+ return;
+
+ table = (uint32_t *) PDE_GET_TABLE(pd_entry);
+
+ uint32_t *pt_entry = &table[GET_PT_INDEX(virtual_address)];
+ *pt_entry = 0;
+}
+
ALWAYS_INLINE uint32_t *
get_or_make_table(uint32_t *pd_entry)
{
@@ -142,6 +158,7 @@ virtual_mm_find_free_virtual_addresses(uint32_t n)
for (uint32_t pd_index = 1; pd_index < PAGE_DIRECTORY_SIZE; pd_index++) {
uint32_t starting_pd_index = pd_index;
uint32_t *pd_entry = &current_page_directory[pd_index];
+ /* Ideally, we shouldn't be allocating tables here */
uint32_t *table = get_or_make_table(pd_entry);
for (uint32_t starting_pt_index = 0; starting_pt_index < PAGE_TABLE_SIZE;
@@ -164,12 +181,13 @@ virtual_mm_find_free_virtual_addresses(uint32_t n)
pt_index = 0;
}
- /* If page table entry is already used, break from the current loop */
+ /* If page table entry is already used, break from the current loop
+ */
uint32_t *pt_entry = &table[pt_index];
if (PTE_IS_PRESENT(pt_entry)) {
- /* Since we have some used address at some point between j and count,
- * we can't find n consecutive free addresses in between j and the
- * used block (j + count + 1) */
+ /* Since we have some used address at some point between j and
+ * count, we can't find n consecutive free addresses in between j
+ * and the used block (j + count + 1) */
starting_pt_index += count;
break;
}
@@ -183,3 +201,25 @@ virtual_mm_find_free_virtual_addresses(uint32_t n)
ASSERT_NOT_REACHED();
return 0;
}
+
+void *
+virtual_mm_alloc_pages(uint32_t n_pages)
+{
+ uint32_t starting_address = virtual_mm_find_free_virtual_addresses(n_pages);
+ if (starting_address == 0)
+ return 0;
+
+ for (uint32_t i = 0; i < n_pages; i++)
+ virtual_mm_map_page(physical_mm_allocate_block(),
+ (void *) (starting_address + (i * 4096)));
+
+ return (void *) starting_address;
+}
+
+void
+virtual_mm_free_pages(void *starting_address, uint32_t n_pages)
+{
+ for (uint32_t i = 0; i < n_pages; i++)
+ virtual_mm_unmap_page(
+ (void *) (((uint32_t) starting_address) + (i * 4096)));
+}