Explorar o código

merge master and fix conflicts

fslongjin %!s(int64=2) %!d(string=hai) anos
pai
achega
f3cd2b7777
Modificáronse 4 ficheiros con 38 adicións e 6 borrados
  1. 2 1
      .vscode/settings.json
  2. 30 2
      kernel/mm/mm-types.h
  3. 3 2
      kernel/mm/mm.c
  4. 3 1
      kernel/mm/mmap.c

+ 2 - 1
.vscode/settings.json

@@ -121,7 +121,8 @@
         "textui.h": "c",
         "atomic.h": "c",
         "uart.h": "c",
-        "fat_ent.h": "c"
+        "fat_ent.h": "c",
+        "semaphore.h": "c"
     },
     "C_Cpp.errorSquiggles": "Enabled",
     "esbonio.sphinx.confDir": ""

+ 30 - 2
kernel/mm/mm-types.h

@@ -1,7 +1,10 @@
 #pragma once
 #include <common/glib.h>
+#include <common/semaphore.h>
+#include <common/atomic.h>
 
 struct mm_struct;
+struct anon_vma_t;
 typedef uint64_t vm_flags_t;
 
 /**
@@ -100,6 +103,11 @@ struct Page
     ul ref_counts;
     // 本页的创建时间
     ul age;
+    
+    struct anon_vma_t *anon_vma;    // 本页对应的anon_vma
+
+    spinlock_t op_lock; // 页面操作锁
+
 };
 
 /**
@@ -114,10 +122,14 @@ struct vm_area_struct
     uint64_t vm_start;       // 区域的起始地址
     uint64_t vm_end;         // 区域的结束地址
     struct mm_struct *vm_mm; // 虚拟内存区域对应的mm结构体
-    vm_flags_t vm_flags;       // 虚拟内存区域的标志位, 具体可选值请见mm.h
+    vm_flags_t vm_flags;     // 虚拟内存区域的标志位, 具体可选值请见mm.h
+    
+    
+    struct List anon_vma_list;  // anon_vma的链表结点
+    struct anon_vma_t * anon_vma;   // 属于的anon_vma
 
     struct vm_operations_t *vm_ops; // 操作方法
-    uint64_t ref_count;             // 引用计数
+    atomic_t ref_count;             // 引用计数
     void *private_data;
 };
 
@@ -141,4 +153,20 @@ struct mm_struct
     uint64_t brk_start, brk_end;
     // 应用层栈基地址
     uint64_t stack_start;
+};
+
+/**
+ * @brief 匿名vma对象的结构体
+ *
+ * anon_vma与每个内存页结构体进行一对一绑定
+ * anon_vma也连接着一切使用到该内存页的vma,当发生页面换出时,应当更新与该page相关的所有vma在页表中的映射信息。
+ */
+struct anon_vma_t
+{
+    semaphore_t sem;
+    atomic_t ref_count;
+
+    // todo: 把下面的循环链表更换成红黑树
+    // 与当前anon_vma相关的vma的列表
+    struct List vma_list;
 };

+ 3 - 2
kernel/mm/mm.c

@@ -247,6 +247,8 @@ unsigned long page_init(struct Page *page, ul flags)
         barrier();
         ++page->zone->total_pages_link;
     }
+    page->anon_vma = NULL;
+    spin_init(&page->op_lock);
     return 0;
 }
 
@@ -586,7 +588,7 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset)
     {
         for (uint64_t i = old_brk_end_addr; i < end_addr; i += PAGE_2M_SIZE)
         {
-            mm_map_vma(current_pcb->mm,i, PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, VM_USER|VM_ACCESS_FLAGS, NULL);
+            mm_map_vma(current_pcb->mm, i, PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, VM_USER | VM_ACCESS_FLAGS, NULL);
         }
         current_pcb->mm->brk_end = end_addr;
     }
@@ -614,4 +616,3 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset)
     }
     return end_addr;
 }
-

+ 3 - 1
kernel/mm/mmap.c

@@ -327,6 +327,8 @@ int mm_map_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, uint64_t p
     vma->vm_start = vaddr;
     vma->vm_end = vaddr + length;
 
+    // 将vma与对应的anon_vma进行绑定
+    struct Page * pg = Phy_to_2M_Page(paddr);
     // 将VMA加入链表
     retval = vma_insert(mm, vma);
     if (retval == -EEXIST) // 之前已经存在了相同的vma,直接返回
@@ -336,7 +338,7 @@ int mm_map_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, uint64_t p
     }
     uint64_t len_4k = length % PAGE_2M_SIZE;
     uint64_t len_2m = length - len_4k;
-    // kdebug("len_2m=%ld", len_2m);
+
     // ==== 将地址映射到页表
     /*
         todo: 限制页面的读写权限