mm-types.h 4.9 KB

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