1 #pragma once 2 #include <common/glib.h> 3 #include <common/semaphore.h> 4 #include <common/spinlock.h> 5 #include <common/atomic.h> 6 7 struct mm_struct; 8 struct anon_vma_t; 9 typedef uint64_t vm_flags_t; 10 11 /** 12 * @brief 内存页表结构体 13 * 14 */ 15 typedef struct 16 { 17 unsigned long pml4t; 18 } pml4t_t; 19 20 typedef struct 21 { 22 unsigned long pdpt; 23 } pdpt_t; 24 25 typedef struct 26 { 27 unsigned long pdt; 28 } pdt_t; 29 30 typedef struct 31 { 32 unsigned long pt; 33 } pt_t; 34 35 // Address Range Descriptor Structure 地址范围描述符 36 struct ARDS 37 { 38 ul BaseAddr; // 基地址 39 ul Length; // 内存长度 以字节为单位 40 unsigned int type; // 本段内存的类型 41 // type=1 表示可以被操作系统使用 42 // type=2 ARR - 内存使用中或被保留,操作系统不能使用 43 // 其他 未定义,操作系统需要将其视为ARR 44 } __attribute__((packed)); // 修饰该结构体不会生成对齐空间,改用紧凑格式 45 46 struct memory_desc 47 { 48 49 struct ARDS e820[32]; // 物理内存段结构数组 50 ul len_e820; // 物理内存段长度 51 52 ul *bmp; // 物理空间页映射位图 53 ul bmp_len; // bmp的长度 54 ul bits_size; // 物理地址空间页数量 55 56 struct Page *pages_struct; 57 ul count_pages; // struct page结构体的总数 58 ul pages_struct_len; // pages_struct链表的长度 59 60 struct Zone *zones_struct; 61 ul count_zones; // zone结构体的数量 62 ul zones_struct_len; // zones_struct列表的长度 63 64 ul kernel_code_start, kernel_code_end; // 内核程序代码段起始地址、结束地址 65 ul kernel_data_end, rodata_end; // 内核程序数据段结束地址、 内核程序只读段结束地址 66 uint64_t start_brk; // 堆地址的起始位置 67 68 ul end_of_struct; // 内存页管理结构的结束地址 69 }; 70 71 struct Zone 72 { 73 // 指向内存页的指针 74 struct Page *pages_group; 75 ul count_pages; // 本区域的struct page结构体总数 76 77 // 本内存区域的起始、结束的页对齐地址 78 ul zone_addr_start; 79 ul zone_addr_end; 80 ul zone_length; // 区域长度 81 82 // 本区域空间的属性 83 ul attr; 84 85 struct memory_desc *gmd_struct; 86 87 // 本区域正在使用中和空闲中的物理页面数量 88 ul count_pages_using; 89 ul count_pages_free; 90 91 // 物理页被引用次数 92 ul total_pages_link; 93 }; 94 95 struct Page 96 { 97 // 本页所属的内存域结构体 98 struct Zone *zone; 99 // 本页对应的物理地址 100 ul addr_phys; 101 // 页面属性 102 ul attr; 103 // 页面被引用的次数 104 ul ref_counts; 105 // 本页的创建时间 106 ul age; 107 108 struct anon_vma_t *anon_vma; // 本页对应的anon_vma 109 110 spinlock_t op_lock; // 页面操作锁 111 112 }; 113 114 /** 115 * @brief 虚拟内存区域(VMA)结构体 116 * 117 */ 118 struct vm_area_struct 119 { 120 struct vm_area_struct *vm_prev, *vm_next; 121 122 // 虚拟内存区域的范围是一个左闭右开的区间:[vm_start, vm_end) 123 uint64_t vm_start; // 区域的起始地址 124 uint64_t vm_end; // 区域的结束地址 125 struct mm_struct *vm_mm; // 虚拟内存区域对应的mm结构体 126 vm_flags_t vm_flags; // 虚拟内存区域的标志位, 具体可选值请见mm.h 127 128 129 struct List anon_vma_list; // anon_vma的链表结点 130 struct anon_vma_t * anon_vma; // 属于的anon_vma 131 132 struct vm_operations_t *vm_ops; // 操作方法 133 atomic_t ref_count; // 引用计数 134 pgoff_t page_offset; // 起始地址在当前VMA所占的2M物理页中的偏移量 135 void *private_data; 136 }; 137 138 /** 139 * @brief 内存空间分布结构体 140 * 包含了进程内存空间分布的信息 141 */ 142 struct mm_struct 143 { 144 pml4t_t *pgd; // 内存页表指针 145 struct vm_area_struct *vmas; // VMA列表 146 // 代码段空间 147 uint64_t code_addr_start, code_addr_end; 148 // 数据段空间 149 uint64_t data_addr_start, data_addr_end; 150 // 只读数据段空间 151 uint64_t rodata_addr_start, rodata_addr_end; 152 // BSS段的空间 153 uint64_t bss_start, bss_end; 154 // 动态内存分配区(堆区域) 155 uint64_t brk_start, brk_end; 156 // 应用层栈基地址 157 uint64_t stack_start; 158 }; 159 160 /** 161 * @brief 匿名vma对象的结构体 162 * 163 * anon_vma与每个内存页结构体进行一对一绑定 164 * anon_vma也连接着一切使用到该内存页的vma,当发生页面换出时,应当更新与该page相关的所有vma在页表中的映射信息。 165 */ 166 struct anon_vma_t 167 { 168 // anon vma的操作信号量 169 semaphore_t sem; 170 171 /** 172 * 记录当前有多少个vma与该anon_vma关联,当vma被释放时, 173 * 应当检查这个值。当该值为0时,应当释放anon_vma结构体 174 */ 175 atomic_t ref_count; 176 177 // todo: 把下面的循环链表更换成红黑树 178 // 与当前anon_vma相关的vma的列表 179 struct List vma_list; 180 // 当前anon vma对应的page 181 struct Page* page; 182 };