diff --git a/kernel/mm/mm-types.h b/kernel/mm/mm-types.h new file mode 100644 index 00000000..0d4f2c74 --- /dev/null +++ b/kernel/mm/mm-types.h @@ -0,0 +1,69 @@ +#pragma once +#include + +struct mm_struct; + +/** + * @brief 内存页表结构体 + * + */ +typedef struct +{ + unsigned long pml4t; +} pml4t_t; + +typedef struct +{ + unsigned long pdpt; +} pdpt_t; + +typedef struct +{ + unsigned long pdt; +} pdt_t; + +typedef struct +{ + unsigned long pt; +} pt_t; + +/** + * @brief 虚拟内存区域(VMA)结构体 + * + */ +struct vm_area_struct +{ + struct List list; // 循环链表结构体 + + // 虚拟内存区域的范围是一个左闭右开的区间:[vm_start, vm_end) + uint64_t vm_start; // 区域的起始地址 + uint64_t vm_end; // 区域的结束地址 + struct mm_struct *vm_mm; // 虚拟内存区域对应的mm结构体 + uint64_t vm_flags; // 虚拟内存区域的标志位 + + struct vm_operations_t *vm_ops; // 操作方法 + uint64_t ref_count; // 引用计数 + void *private_data; +}; + +/** + * @brief 内存空间分布结构体 + * 包含了进程内存空间分布的信息 + */ +struct mm_struct +{ + pml4t_t *pgd; // 内存页表指针 + struct vm_area_struct *vmas; // VMA列表 + // 代码段空间 + uint64_t code_addr_start, code_addr_end; + // 数据段空间 + uint64_t data_addr_start, data_addr_end; + // 只读数据段空间 + uint64_t rodata_addr_start, rodata_addr_end; + // BSS段的空间 + uint64_t bss_start, bss_end; + // 动态内存分配区(堆区域) + uint64_t brk_start, brk_end; + // 应用层栈基地址 + uint64_t stack_start; +}; \ No newline at end of file diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index a3c0c493..9e1a8507 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -1,4 +1,5 @@ #include "mm.h" +#include "mm-types.h" #include "slab.h" #include #include diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h index 38614630..754c41a7 100644 --- a/kernel/mm/mm.h +++ b/kernel/mm/mm.h @@ -1,6 +1,7 @@ #pragma once #include +#include // 每个页表的项数 // 64位下,每个页表4k,每条页表项8B,故一个页表有512条 @@ -233,13 +234,31 @@ struct Page */ struct mm_stat_t { - uint64_t total; // 计算机的总内存数量大小 - uint64_t used; // 已使用的内存大小 - uint64_t free; // 空闲物理页所占的内存大小 - uint64_t shared; // 共享的内存大小 - uint64_t cache_used; // 位于slab缓冲区中的已使用的内存大小 - uint64_t cache_free; // 位于slab缓冲区中的空闲的内存大小 - uint64_t available; // 系统总空闲内存大小(包括kmalloc缓冲区) + uint64_t total; // 计算机的总内存数量大小 + uint64_t used; // 已使用的内存大小 + uint64_t free; // 空闲物理页所占的内存大小 + uint64_t shared; // 共享的内存大小 + uint64_t cache_used; // 位于slab缓冲区中的已使用的内存大小 + uint64_t cache_free; // 位于slab缓冲区中的空闲的内存大小 + uint64_t available; // 系统总空闲内存大小(包括kmalloc缓冲区) +}; + +/** + * @brief 虚拟内存区域的操作方法的结构体 + * + */ +struct vm_operations_t +{ + /** + * @brief vm area 被打开时的回调函数 + * + */ + void (*open)(struct vm_area_struct *area); + /** + * @brief vm area将要被移除的时候,将会调用该回调函数 + * + */ + void (*close)(struct vm_area_struct *area); }; extern struct memory_desc memory_management_struct; @@ -258,8 +277,8 @@ extern char _end; // 每个区域的索引 int ZONE_DMA_INDEX = 0; -int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable -int ZONE_UNMAPPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable +int ZONE_NORMAL_INDEX = 0; +int ZONE_UNMAPPED_INDEX = 0; // 初始化内存管理单元 void mm_init(); @@ -332,14 +351,6 @@ ul get_page_attr(struct Page *page); */ ul set_page_attr(struct Page *page, ul flags); -/** - * @brief 内存页表结构体 - * - */ -typedef struct -{ - unsigned long pml4t; -} pml4t_t; #define mk_pml4t(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) /** * @brief 设置pml4页表的页表项 @@ -348,24 +359,12 @@ typedef struct */ #define set_pml4t(pml4tptr, pml4tval) (*(pml4tptr) = (pml4tval)) -typedef struct -{ - unsigned long pdpt; -} pdpt_t; #define mk_pdpt(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pdpt(pdptptr, pdptval) (*(pdptptr) = (pdptval)) -typedef struct -{ - unsigned long pdt; -} pdt_t; #define mk_pdt(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pdt(pdtptr, pdtval) (*(pdtptr) = (pdtval)) -typedef struct -{ - unsigned long pt; -} pt_t; #define mk_pt(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) #define set_pt(ptptr, ptval) (*(ptptr) = (ptval)) @@ -462,7 +461,7 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset); /** * @brief 获取系统当前的内存信息(未上锁,不一定精准) - * + * * @return struct mm_stat_t 内存信息结构体 */ struct mm_stat_t mm_stat(); \ No newline at end of file diff --git a/kernel/process/process.c b/kernel/process/process.c index 638da4a5..2fbab92f 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -583,6 +583,7 @@ void process_init() initial_mm.brk_end = current_pcb->addr_limit; initial_mm.stack_start = _stack_start; + initial_mm.vmas = NULL; initial_tss[proc_current_cpu_id].rsp0 = initial_thread.rbp; diff --git a/kernel/process/process.h b/kernel/process/process.h index f1e2acb9..fe70e143 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -17,8 +17,7 @@ #include #include #include - - +#include // 进程最大可拥有的文件描述符数量 #define PROC_MAX_FD_NUM 16 @@ -52,27 +51,6 @@ #define CLONE_SIGNAL (1 << 1) #define CLONE_VM (1 << 2) // 在进程间共享虚拟内存空间 -/** - * @brief 内存空间分布结构体 - * 包含了进程内存空间分布的信息 - */ -struct mm_struct -{ - pml4t_t *pgd; // 内存页表指针 - // 代码段空间 - ul code_addr_start, code_addr_end; - // 数据段空间 - ul data_addr_start, data_addr_end; - // 只读数据段空间 - ul rodata_addr_start, rodata_addr_end; - // BSS段的空间 - uint64_t bss_start, bss_end; - // 动态内存分配区(堆区域) - ul brk_start, brk_end; - // 应用层栈基地址 - ul stack_start; -}; - struct thread_struct { // 内核层栈基指针 @@ -355,7 +333,7 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne asm volatile("movq %0, %%cr3 \n\t" ::"r"(next_pcb->mm->pgd) \ : "memory"); \ } while (0) -// flush_tlb(); +// flush_tlb(); // 获取当前cpu id #define proc_current_cpu_id (current_pcb->cpu_id)