123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #pragma once
- #include <common/glib.h>
- #include <common/semaphore.h>
- #include <common/spinlock.h>
- #include <common/atomic.h>
- struct mm_struct;
- struct anon_vma_t;
- typedef uint64_t vm_flags_t;
- /**
- * @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;
- // Address Range Descriptor Structure 地址范围描述符
- struct ARDS
- {
- ul BaseAddr; // 基地址
- ul Length; // 内存长度 以字节为单位
- unsigned int type; // 本段内存的类型
- // type=1 表示可以被操作系统使用
- // type=2 ARR - 内存使用中或被保留,操作系统不能使用
- // 其他 未定义,操作系统需要将其视为ARR
- } __attribute__((packed)); // 修饰该结构体不会生成对齐空间,改用紧凑格式
- struct memory_desc
- {
- struct ARDS e820[32]; // 物理内存段结构数组
- ul len_e820; // 物理内存段长度
- ul *bmp; // 物理空间页映射位图
- ul bmp_len; // bmp的长度
- ul bits_size; // 物理地址空间页数量
- struct Page *pages_struct;
- ul count_pages; // struct page结构体的总数
- ul pages_struct_len; // pages_struct链表的长度
- struct Zone *zones_struct;
- ul count_zones; // zone结构体的数量
- ul zones_struct_len; // zones_struct列表的长度
- ul kernel_code_start, kernel_code_end; // 内核程序代码段起始地址、结束地址
- ul kernel_data_end, rodata_end; // 内核程序数据段结束地址、 内核程序只读段结束地址
- uint64_t start_brk; // 堆地址的起始位置
- ul end_of_struct; // 内存页管理结构的结束地址
- };
- struct Zone
- {
- // 指向内存页的指针
- struct Page *pages_group;
- ul count_pages; // 本区域的struct page结构体总数
- // 本内存区域的起始、结束的页对齐地址
- ul zone_addr_start;
- ul zone_addr_end;
- ul zone_length; // 区域长度
- // 本区域空间的属性
- ul attr;
- struct memory_desc *gmd_struct;
- // 本区域正在使用中和空闲中的物理页面数量
- ul count_pages_using;
- ul count_pages_free;
- // 物理页被引用次数
- ul total_pages_link;
- };
- struct Page
- {
- // 本页所属的内存域结构体
- struct Zone *zone;
- // 本页对应的物理地址
- ul addr_phys;
- // 页面属性
- ul attr;
- // 页面被引用的次数
- ul ref_counts;
- // 本页的创建时间
- ul age;
-
- struct anon_vma_t *anon_vma; // 本页对应的anon_vma
- spinlock_t op_lock; // 页面操作锁
- };
- /**
- * @brief 虚拟内存区域(VMA)结构体
- *
- */
- struct vm_area_struct
- {
- struct vm_area_struct *vm_prev, *vm_next;
- // 虚拟内存区域的范围是一个左闭右开的区间:[vm_start, vm_end)
- uint64_t vm_start; // 区域的起始地址
- uint64_t vm_end; // 区域的结束地址
- struct mm_struct *vm_mm; // 虚拟内存区域对应的mm结构体
- 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; // 操作方法
- atomic_t ref_count; // 引用计数
- pgoff_t page_offset; // 起始地址在当前VMA所占的2M物理页中的偏移量
- 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;
- };
- /**
- * @brief 匿名vma对象的结构体
- *
- * anon_vma与每个内存页结构体进行一对一绑定
- * anon_vma也连接着一切使用到该内存页的vma,当发生页面换出时,应当更新与该page相关的所有vma在页表中的映射信息。
- */
- struct anon_vma_t
- {
- // anon vma的操作信号量
- semaphore_t sem;
-
- /**
- * 记录当前有多少个vma与该anon_vma关联,当vma被释放时,
- * 应当检查这个值。当该值为0时,应当释放anon_vma结构体
- */
- atomic_t ref_count;
- // todo: 把下面的循环链表更换成红黑树
- // 与当前anon_vma相关的vma的列表
- struct List vma_list;
- // 当前anon vma对应的page
- struct Page* page;
- };
|