Переглянути джерело

feat(mm): add k_unmap and dealloc_{pd, pt}

greatbridf 2 роки тому
батько
коміт
943868c7f9
2 змінених файлів з 46 додано та 0 видалено
  1. 6 0
      include/kernel/mm.hpp
  2. 40 0
      src/kernel/mem.cpp

+ 6 - 0
include/kernel/mm.hpp

@@ -40,6 +40,9 @@ int k_map(
     int priv,
     int cow);
 
+// unmap a whole mem area, making sure that we will never use it again
+int k_unmap(mm* mm_area);
+
 // private memory mapping
 // changes won't be neither written back to file nor shared between processes
 // TODO: shared mapping
@@ -202,3 +205,6 @@ struct page allocate_page(void);
 
 pd_t alloc_pd(void);
 pt_t alloc_pt(void);
+
+void dealloc_pd(pd_t pd);
+void dealloc_pt(pt_t pt);

+ 40 - 0
src/kernel/mem.cpp

@@ -10,6 +10,7 @@
 #include <kernel/vga.h>
 #include <kernel_main.h>
 #include <types/bitmap.h>
+#include <types/size.h>
 #include <types/status.h>
 
 // global objects
@@ -334,6 +335,26 @@ pt_t alloc_pt(void)
     return pt;
 }
 
+void dealloc_pd(pd_t pd)
+{
+    for (pde_t* ent = (*pd) + 256; ent < (*pd) + 1024; ++ent) {
+        if (!ent->in.p)
+            continue;
+        dealloc_pt(to_pt(ent));
+    }
+    memset(pd, 0x00, sizeof(*pd));
+
+    page_t pg = to_page((pptr_t)pd);
+    free_page(pg);
+}
+void dealloc_pt(pt_t pt)
+{
+    memset(pt, 0x00, sizeof(*pt));
+
+    page_t pg = to_page((pptr_t)pt);
+    free_page(pg);
+}
+
 static inline void init_mem_layout(void)
 {
     mem_size = 1024 * mem_size_info.n_1k_blks;
@@ -428,6 +449,25 @@ int k_map(
     return GB_OK;
 }
 
+int k_unmap(mm* mm_area)
+{
+    for (auto iter = mm_area->pgs->begin(); iter != mm_area->pgs->end(); ++iter) {
+        if (*iter->ref_count == 1) {
+            ki_free(iter->ref_count);
+            free_page(iter->phys_page_id);
+        } else {
+            --*iter->ref_count;
+        }
+
+        iter->phys_page_id = 0;
+        iter->attr.v = 0;
+        iter->pte->v = 0;
+    }
+    mm_area->attr.v = 0;
+    mm_area->start = 0;
+    return GB_OK;
+}
+
 bool check_addr_range_avail(const mm* mm_area, void* start, void* end)
 {
     void* m_start = mm_area->start;