1(_core_mm_api)= 2 3# 内存管理API 4 5## SLAB内存池 6 7SLAB内存池提供小内存对象的分配功能。 8 9### `void *kmalloc(unsigned long size, gfp_t gfp)` 10 11  获取小块的内存。 12 13#### 描述 14 15  kmalloc用于获取那些小于2M内存页大小的内存对象。可分配的内存对象大小为32bytes~1MBytes. 且分配的内存块大小、起始地址按照2的n次幂进行对齐。(比如,申请的是80bytes的内存空间,那么获得的内存对象大小为128bytes且内存地址按照128bytes对齐) 16 17##### 参数 18 19**size** 20 21  内存对象的大小 22 23**gfp** 24 25  标志位 26 27### `void *kzalloc(unsigned long size, gfp_t gfp)` 28 29#### 描述 30 31  获取小块的内存,并将其清零。其余功能与kmalloc相同。 32 33 34##### 参数 35 36**size** 37 38  内存对象的大小 39 40**gfp** 41 42  标志位 43 44### `unsigned long kfree(void *address)` 45 46  释放从slab分配的内存。 47 48#### 描述 49 50  该函数用于释放通过kmalloc申请的内存。如果`address`为NULL,则函数被调用后,无事发生。 51 52  请不要通过这个函数释放那些不是从`kmalloc()`或`kzalloc()`申请的内存,否则将会导致系统崩溃。 53 54##### 参数 55 56**address** 57 58  指向内存对象的起始地址的指针 59 60## 物理页管理 61 62DragonOS支持对物理页的直接操作 63 64### `struct Page *alloc_pages(unsigned int zone_select, int num, ul flags)` 65 66#### 描述 67 68  从物理页管理单元中申请一段连续的物理页 69 70#### 参数 71 72**zone_select** 73 74  要申请的物理页所位于的内存区域 75 76可选值: 77 78- `ZONE_DMA` DMA映射专用区域 79- `ZONE_NORMAL` 正常的物理内存区域,已在页表高地址处映射 80- `ZONE_UNMAPPED_IN_PGT` 尚未在页表中映射的区域 81 82**num** 83 84  要申请的连续物理页的数目,该值应当小于64 85 86**flags** 87 88  分配的页面要被设置成的属性 89 90可选值: 91 92- `PAGE_PGT_MAPPED` 页面在页表中已被映射 93- `PAGE_KERNEL_INIT` 内核初始化所占用的页 94- `PAGE_DEVICE` 设备MMIO映射的内存 95- `PAGE_KERNEL` 内核层页 96- `PAGE_SHARED` 共享页 97 98#### 返回值 99 100##### 成功 101 102  成功申请则返回指向起始页面的Page结构体的指针 103 104##### 失败 105 106  当ZONE错误或内存不足时,返回`NULL` 107 108### `void free_pages(struct Page *page, int number)` 109 110#### 描述 111 112  从物理页管理单元中释放一段连续的物理页。 113 114#### 参数 115 116**page** 117 118  要释放的第一个物理页的Page结构体 119 120**number** 121 122  要释放的连续内存页的数量。该值应小于64 123 124## 页表管理 125 126### `int mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool use4k)` 127 128#### 描述 129 130  将一段物理地址映射到当前页表的指定虚拟地址处 131 132#### 参数 133 134**virt_addr_start** 135 136  虚拟地址的起始地址 137 138**phys_addr_start** 139 140  物理地址的起始地址 141 142**length** 143 144  要映射的地址空间的长度 145 146**flags** 147 148  页表项的属性 149 150**use4k** 151 152  使用4级页表,将地址区域映射为若干4K页 153 154### `int mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user, bool flush, bool use4k)` 155 156#### 描述 157 158  将一段物理地址映射到指定页表的指定虚拟地址处 159 160#### 参数 161 162**proc_page_table_addr** 163 164  指定的顶层页表的起始地址 165 166**is_phys** 167 168  该顶层页表地址是否为物理地址 169 170**virt_addr_start** 171 172  虚拟地址的起始地址 173 174**phys_addr_start** 175 176  物理地址的起始地址 177 178**length** 179 180  要映射的地址空间的长度 181 182**flags** 183 184  页表项的属性 185 186**user** 187 188  页面是否为用户态可访问 189 190**flush** 191 192  完成映射后,是否刷新TLB 193 194**use4k** 195 196  使用4级页表,将地址区域映射为若干4K页 197 198#### 返回值 199 200- 映射成功:0 201- 映射失败:-EFAULT 202 203### `void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul length)` 204 205#### 描述 206 207  取消给定页表中的指定地址空间的页表项映射。 208 209#### 参数 210 211**proc_page_table_addr** 212 213  指定的顶层页表的基地址 214 215**is_phys** 216 217  该顶层页表地址是否为物理地址 218 219**virt_addr_start** 220 221  虚拟地址的起始地址 222 223**length** 224 225  要取消映射的地址空间的长度 226 227### `mm_unmap_addr(virt_addr, length)` 228 229#### 描述 230 231  该宏定义用于取消当前进程的页表中的指定地址空间的页表项映射。 232 233#### 参数 234 235**virt_addr** 236 237  虚拟地址的起始地址 238 239**length** 240 241  要取消映射的地址空间的长度 242 243## 内存信息获取 244 245### `struct mm_stat_t mm_stat()` 246 247#### 描述 248 249  获取计算机目前的内存空间使用情况 250 251#### 参数 252 253无 254 255#### 返回值 256 257  返回值是一个`mm_mstat_t`结构体,该结构体定义于`mm/mm.h`中。其中包含了以下信息(单位均为字节): 258 259| 参数名 | 解释 | 260| ---------- | ----------------------- | 261| total | 计算机的总内存数量大小 | 262| used | 已使用的内存大小 | 263| free | 空闲物理页所占的内存大小 | 264| shared | 共享的内存大小 | 265| cache_used | 位于slab缓冲区中的已使用的内存大小 | 266| cache_free | 位于slab缓冲区中的空闲的内存大小 | 267| available | 系统总空闲内存大小(包括kmalloc缓冲区) |