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 };