From 0af4f5eb1d17c86914689fe7b439db82db74f53f Mon Sep 17 00:00:00 2001 From: zhaoyanbai Date: Sun, 4 Oct 2026 23:01:25 +0800 Subject: [PATCH] =?utf8?q?vm=5Farea=E6=94=B9=E5=90=8D=E4=B8=BAvma,vm=5Fstr?= =?utf8?q?uct=E6=94=B9=E5=90=8D=E4=B8=BAvmap=5Fregion=E7=9B=B8=E5=85=B3?= =?utf8?q?=E7=9A=84=E4=BB=A3=E7=A0=81=E4=B8=8D=E5=86=8D=E4=BD=BF=E7=94=A8v?= =?utf8?q?m=5Farea=E5=85=B3=E9=94=AE=E5=AD=97,=E4=BB=A5=E6=98=BE=E7=A4=BA?= =?utf8?q?=E5=9C=B0=E5=8C=BA=E5=88=86=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BB=A3?= =?utf8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/mm.h | 6 +-- include/task.h | 2 +- include/vmalloc.h | 17 ++++---- kernel/ioremap.c | 26 +++++------ kernel/vmalloc.c | 108 +++++++++++++++++++++++----------------------- mm/mm.c | 18 ++++---- 6 files changed, 90 insertions(+), 87 deletions(-) diff --git a/include/mm.h b/include/mm.h index 35aa6fa..6cbc032 100644 --- a/include/mm.h +++ b/include/mm.h @@ -32,11 +32,11 @@ void kfree(void* addr); #define VM_GROW_UP 0x10000000 #define VM_GROW_DOWN 0x20000000 -typedef struct vm_area { +typedef struct vma { uint32_t vm_bgn; uint32_t vm_end; uint32_t vm_flags; - struct vm_area* vm_next; -} vm_area_t; + struct vma* vm_next; +} vma_t; diff --git a/include/task.h b/include/task.h index 574a686..0b73f79 100644 --- a/include/task.h +++ b/include/task.h @@ -79,7 +79,7 @@ typedef union task_union { path_t root; path_t pwd; - vm_area_t* vma_list; + vma_t* vma_list; list_head_t list; // 所有进程串成一个链表 list_head_t ready_list; // 就绪队列 diff --git a/include/vmalloc.h b/include/vmalloc.h index 898ba03..5aac6d4 100644 --- a/include/vmalloc.h +++ b/include/vmalloc.h @@ -12,18 +12,19 @@ #include #include -#define VM_ALLOC 0x01 -#define VM_IOREMAP 0x02 +#define VMAP_ALLOC 0x01 +#define VMAP_IOREMAP 0x02 -typedef struct vm_struct { +// virtual map region +typedef struct vmap_region { vaddr_t vm_vaddr; size_t vm_size; paddr_t vm_paddr; uint32_t vm_flags; - struct vm_struct* vm_next; -} vm_struct_t; + struct vmap_region* vm_next; +} vmap_region_t; -vm_struct_t* alloc_vm_area(size_t size, uint32_t flags); -vm_struct_t* find_vm_area(vaddr_t vaddr); +vmap_region_t* alloc_vmap_region(size_t size, uint32_t flags); +vmap_region_t* find_vmap_region(vaddr_t vaddr); -void free_vm_area(vm_struct_t* vm); +void free_vmap_region(vmap_region_t* region); diff --git a/kernel/ioremap.c b/kernel/ioremap.c index 783298c..4517d10 100644 --- a/kernel/ioremap.c +++ b/kernel/ioremap.c @@ -31,30 +31,30 @@ void ioremap_page_range_clear(vaddr_t vaddr, size_t size) { void* ioremap(paddr_t phys_addr, size_t size) { size = PAGE_UP(size); - vm_struct_t* vm_area = alloc_vm_area(size, VM_IOREMAP); - if (!vm_area) { + vmap_region_t* vmap_region = alloc_vmap_region(size, VMAP_IOREMAP); + if (!vmap_region) { return NULL; } // 映射物理地址到虚拟地址 - vm_area->vm_paddr = phys_addr; - vm_area->vm_flags |= VM_IOREMAP; + vmap_region->vm_paddr = phys_addr; + vmap_region->vm_flags |= VMAP_IOREMAP; - printk("ioremap: 0x%08x -> 0x%08x size %u\n", phys_addr, vm_area->vm_vaddr, vm_area->vm_size); + printk("ioremap: 0x%08x -> 0x%08x size %u\n", phys_addr, vmap_region->vm_vaddr, vmap_region->vm_size); - ioremap_page_range(vm_area->vm_vaddr, vm_area->vm_paddr, vm_area->vm_size); + ioremap_page_range(vmap_region->vm_vaddr, vmap_region->vm_paddr, vmap_region->vm_size); - return (void*)vm_area->vm_vaddr; + return (void*)vmap_region->vm_vaddr; } void iounmap(vaddr_t vaddr) { - vm_struct_t* vm_area = find_vm_area(vaddr); - assert(vm_area != NULL); - assert(vm_area->vm_flags & VM_IOREMAP); + vmap_region_t* vmap_region = find_vmap_region(vaddr); + assert(vmap_region != NULL); + assert(vmap_region->vm_flags & VMAP_IOREMAP); - printk("iounmap: 0x%08x size %u\n", vm_area->vm_vaddr, vm_area->vm_size); + printk("iounmap: 0x%08x size %u\n", vmap_region->vm_vaddr, vmap_region->vm_size); - free_vm_area(vm_area); + free_vmap_region(vmap_region); - ioremap_page_range_clear(vm_area->vm_vaddr, vm_area->vm_size); + ioremap_page_range_clear(vmap_region->vm_vaddr, vmap_region->vm_size); } diff --git a/kernel/vmalloc.c b/kernel/vmalloc.c index 7c2a0bb..a8ef8a0 100644 --- a/kernel/vmalloc.c +++ b/kernel/vmalloc.c @@ -15,39 +15,41 @@ #include #include -static vm_struct_t* vm_area_list = NULL; +static vmap_region_t* vmap_region_list = NULL; -vaddr_t vm_vaddr_base = VMALLOC_VADDR_BASE + (8 * 1024 * 1024); -vaddr_t vm_vaddr_end = VMALLOC_VADDR_END; +static const int vmap_guard_size = 4 * 1024 * 1024; // 4MB -vm_struct_t* alloc_vm_area(size_t size, uint32_t flags) { +static const vaddr_t vmap_vaddr_base = VMALLOC_VADDR_BASE + vmap_guard_size; +static const vaddr_t vmap_vaddr_end = VMALLOC_VADDR_END - vmap_guard_size; + +vmap_region_t* alloc_vmap_region(size_t size, uint32_t flags) { // assert size是页对齐 assert(PAGE_DOWN(size) == size); - assert(vm_vaddr_base < vm_vaddr_end); + assert(vmap_vaddr_base < vmap_vaddr_end); size += PAGE_SIZE; // 尾部添加一个空页 - vaddr_t vm_area_gap_bgn = 0; - vaddr_t vm_area_gap_end = 0; + vaddr_t vmap_region_gap_bgn = 0; + vaddr_t vmap_region_gap_end = 0; uint32_t eflags; irq_save(eflags); - vm_struct_t* prev = NULL; - vm_struct_t* curt = vm_area_list; + vmap_region_t* prev = NULL; + vmap_region_t* curt = vmap_region_list; while (curt != NULL) { - assert(curt->vm_vaddr >= vm_vaddr_base); - assert(curt->vm_vaddr + curt->vm_size <= vm_vaddr_end); + assert(curt->vm_vaddr >= vmap_vaddr_base); + assert(curt->vm_vaddr + curt->vm_size <= vmap_vaddr_end); // - vm_area_gap_bgn = prev == NULL ? vm_vaddr_base : prev->vm_vaddr + prev->vm_size; - vm_area_gap_end = curt->vm_vaddr; + vmap_region_gap_bgn = prev == NULL ? vmap_vaddr_base : prev->vm_vaddr + prev->vm_size; + vmap_region_gap_end = curt->vm_vaddr; - assert(vm_area_gap_bgn <= vm_area_gap_end); + assert(vmap_region_gap_bgn <= vmap_region_gap_end); // 找到了 - if (vm_area_gap_end - vm_area_gap_bgn >= size) { + if (vmap_region_gap_end - vmap_region_gap_bgn >= size) { break; } @@ -57,56 +59,56 @@ vm_struct_t* alloc_vm_area(size_t size, uint32_t flags) { // 如果找到最后了也还没找到 if (curt == NULL) { - vm_area_gap_bgn = prev == NULL ? vm_vaddr_base : prev->vm_vaddr + prev->vm_size; - vm_area_gap_end = vm_vaddr_end; + vmap_region_gap_bgn = prev == NULL ? vmap_vaddr_base : prev->vm_vaddr + prev->vm_size; + vmap_region_gap_end = vmap_vaddr_end; - assert(vm_area_gap_bgn <= vm_area_gap_end); + assert(vmap_region_gap_bgn <= vmap_region_gap_end); - if (vm_area_gap_end - vm_area_gap_bgn < size) { + if (vmap_region_gap_end - vmap_region_gap_bgn < size) { irq_restore(eflags); return NULL; } } - // 创建一人vm_struct - vm_struct_t* vm_area = kmalloc(sizeof(vm_struct_t), 0); - if (vm_area == NULL) { + // 创建一个vmap_region + vmap_region_t* vmap_region = kmalloc(sizeof(vmap_region_t), 0); + if (vmap_region == NULL) { irq_restore(eflags); return NULL; } - vm_area->vm_vaddr = vm_area_gap_bgn; - vm_area->vm_size = size; - vm_area->vm_flags = flags; + vmap_region->vm_vaddr = vmap_region_gap_bgn; + vmap_region->vm_size = size; + vmap_region->vm_flags = flags; // add to list - vm_area->vm_next = curt; + vmap_region->vm_next = curt; if (prev == NULL) { - vm_area_list = vm_area; + vmap_region_list = vmap_region; } else { - prev->vm_next = vm_area; + prev->vm_next = vmap_region; } irq_restore(eflags); - return vm_area; + return vmap_region; } -vm_struct_t* find_vm_area(vaddr_t vaddr) { +vmap_region_t* find_vmap_region(vaddr_t vaddr) { assert(PAGE_DOWN(vaddr) == vaddr); - assert(vaddr >= vm_vaddr_base); - assert(vaddr < vm_vaddr_end); - assert(vm_area_list != NULL); + assert(vaddr >= vmap_vaddr_base); + assert(vaddr < vmap_vaddr_end); + assert(vmap_region_list != NULL); uint32_t eflags; irq_save(eflags); - vm_struct_t* curt = vm_area_list; + vmap_region_t* curt = vmap_region_list; while (curt != NULL) { assert(curt->vm_size != 0); - assert(curt->vm_vaddr >= vm_vaddr_base); - assert(curt->vm_vaddr + curt->vm_size <= vm_vaddr_end); + assert(curt->vm_vaddr >= vmap_vaddr_base); + assert(curt->vm_vaddr + curt->vm_size <= vmap_vaddr_end); if (vaddr == curt->vm_vaddr) { irq_restore(eflags); @@ -123,37 +125,37 @@ vm_struct_t* find_vm_area(vaddr_t vaddr) { return NULL; } -void free_vm_area(vm_struct_t* vm_area) { - assert(vm_area != NULL); - assert(vm_area->vm_size != 0); - assert(vm_area->vm_size % PAGE_SIZE == 0); - assert(vm_area->vm_size >= (2 * PAGE_SIZE)); - assert(vm_area->vm_vaddr >= vm_vaddr_base); - assert(vm_area->vm_vaddr + vm_area->vm_size <= vm_vaddr_end); - assert(vm_area_list != NULL); +void free_vmap_region(vmap_region_t* region) { + assert(region != NULL); + assert(region->vm_size != 0); + assert(region->vm_size % PAGE_SIZE == 0); + assert(region->vm_size >= (2 * PAGE_SIZE)); + assert(region->vm_vaddr >= vmap_vaddr_base); + assert(region->vm_vaddr + region->vm_size <= vmap_vaddr_end); + assert(vmap_region_list != NULL); // TODO uint32_t eflags; irq_save(eflags); - vm_struct_t* prev = NULL; - vm_struct_t* curt = vm_area_list; + vmap_region_t* prev = NULL; + vmap_region_t* curt = vmap_region_list; while (curt != NULL) { - if (curt == vm_area) { + if (curt == region) { if (prev == NULL) { // 只有链表上仅有一个节点,且这个节点就是要删除的节点的情况下prev才可能为NULL - assert(vm_area_list == vm_area); - assert(vm_area->vm_next == NULL); + assert(vmap_region_list == region); + assert(region->vm_next == NULL); // - vm_area_list = curt->vm_next; + vmap_region_list = curt->vm_next; } else { prev->vm_next = curt->vm_next; } - // 释放前先清空vm_struct避免连续二次释放 - memset(curt, 0, sizeof(vm_struct_t)); + // 释放前先清空vmap_region避免连续二次释放 + memset(curt, 0, sizeof(vmap_region_t)); kfree(curt); @@ -166,7 +168,7 @@ void free_vm_area(vm_struct_t* vm_area) { } // 不应该出现这种情况 - assert(0 && "vm_area not found"); + assert(0 && "vmap_region not found"); irq_restore(eflags); } diff --git a/mm/mm.c b/mm/mm.c index 8e9d74b..e8bbee3 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -198,12 +198,12 @@ void init_mm() { printk("memory init finished...\n"); boot_delay(DEFAULT_BOOT_DELAY_TICKS); - g_vma_kmem_cache = kmem_cache_create("vma", sizeof(vm_area_t), 4); + g_vma_kmem_cache = kmem_cache_create("vma", sizeof(vma_t), 4); assert(g_vma_kmem_cache != NULL); } -vm_area_t* vma_alloc() { - vm_area_t* vma = kmem_cache_alloc(g_vma_kmem_cache, 0); +vma_t* vma_alloc() { + vma_t* vma = kmem_cache_alloc(g_vma_kmem_cache, 0); vma->vm_bgn = 0; vma->vm_end = 0; vma->vm_flags = 0; @@ -211,12 +211,12 @@ vm_area_t* vma_alloc() { return vma; } -void vma_insert(task_t* tsk, vm_area_t* vma_new) { +void vma_insert(task_t* tsk, vma_t* vma_new) { // - vm_area_t** p = &tsk->vma_list; + vma_t** p = &tsk->vma_list; while (*p != NULL) { - vm_area_t* v = *p; + vma_t* v = *p; assert(v->vm_bgn < v->vm_end); assert(vma_new->vm_bgn < vma_new->vm_end); @@ -234,10 +234,10 @@ void vma_insert(task_t* tsk, vm_area_t* vma_new) { *p = vma_new; } -vm_area_t* vma_find(task_t* tsk, vm_area_t* vma, uint32_t addr) { - vm_area_t** p = &tsk->vma_list; +vma_t* vma_find(task_t* tsk, vma_t* vma, uint32_t addr) { + vma_t** p = &tsk->vma_list; while (*p != NULL) { - vm_area_t* v = *p; + vma_t* v = *p; if (addr <= v->vm_end) { break; -- 2.55.0