From f3cd2b7777cc63338cbf0234df502168456bbad1 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Sun, 14 Aug 2022 21:43:39 +0800 Subject: [PATCH] merge master and fix conflicts --- .vscode/settings.json | 3 ++- kernel/mm/mm-types.h | 32 ++++++++++++++++++++++++++++++-- kernel/mm/mm.c | 5 +++-- kernel/mm/mmap.c | 4 +++- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f2f2e7e1..5d7267b1 100644 --- a/.vscode/settings.json +++ b/.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": "" diff --git a/kernel/mm/mm-types.h b/kernel/mm/mm-types.h index 95c80cbf..156b35a5 100644 --- a/kernel/mm/mm-types.h +++ b/kernel/mm/mm-types.h @@ -1,7 +1,10 @@ #pragma once #include +#include +#include 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; }; \ No newline at end of file diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index c4466a87..6d682ab7 100644 --- a/kernel/mm/mm.c +++ b/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; } - diff --git a/kernel/mm/mmap.c b/kernel/mm/mmap.c index d8770c8b..4ebb7223 100644 --- a/kernel/mm/mmap.c +++ b/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: 限制页面的读写权限