pte.h

本文详细介绍了页表管理中的关键概念和技术实现细节,包括页表索引、页表条目、物理地址与虚拟地址的转换过程以及相关宏定义的作用。通过具体的内联函数示例,展示了如何创建和获取页表条目。

#definePTSHIFT PGBITS /*page table index的开始位:12*/
#define PTBITS 10 /*page table index的位长度*/
#define PTSPAN (1 << PTBITS << PGBITS) /*一个page table index指向一个page table,而一个page table大小是1KB*/
#define PTMASK BITMASK(PTSHIFT, PTBITS) /*掩码,即过滤其他位*/
static inline unsigned pt_no (const void *va) {
return ((uintptr_t) va & PTMASK) >> PTSHIFT;
}
va表示虚拟地址,即32位,先把page table index通过掩码过滤,然后把他移到低位。

一个page table index指向一个page table,而一个page table entry是一个虚拟地址。
一个PDE把物理地址抽取出来指向一个page table。如果PDE的present位是false,则忽略其他位。

31 12 11 0
+------------------------------------+------------------------+
| Physical Address | Flags |
+------------------------------------+------------------------+
12-31位是物理地址,我们指向一个page table之前必须要把他转化为虚拟地址。

#define PTE_FLAGS 0x00000fff /* Flag bits. */
#define PTE_ADDR 0xfffff000 /* Address bits. */
#define PTE_AVL 0x00000e00 /* Bits available for OS use. */
#define PTE_P 0x1 /* 1=present, 0=not present. */
#define PTE_W 0x2 /* 1=read/write, 0=read-only. */
#define PTE_U 0x4 /* 1=user/kernel, 0=kernel only. */
#define PTE_A 0x20 /* 1=accessed, 0=not acccessed. */
#define PTE_D 0x40 /* 1=dirty, 0=not dirty (PTEs only). */
以上是一群宏定义,他们的目的很像掩码,就是过滤其他位,把自己需要的位给抽取出来。
static inline uint32_t pde_create (uint32_t *pt) {
ASSERT (pg_ofs (pt) == 0);
return vtop (pt) | PTE_U | PTE_P | PTE_W;
}
pt为page table 的虚拟地址,我们前面讲到pde含有的是page table的物理地址,因此我们需要把va转换为pa,并且还要把标识位设置好。即用户进程能访问,并且present,并且能够可以写的。
static inline uint32_t *pde_get_pt (uint32_t pde) {
ASSERT (pde & PTE_P);
return ptov (pde & PTE_ADDR);
}
这个就和我上面讲的一样,已知pde地址,要求他指向的page table的地址,需要先用掩码把物理地址提取出来,再变成虚拟地址即可。
static inline uint32_t pte_create_kernel (void *page, bool writable) {
ASSERT (pg_ofs (page) == 0);
return vtop (page) | PTE_P | (writable ? PTE_W : 0);
}
这个是创建一个pte指向指定的page,就类似于pde指向pt。需要注意是这个只能被kernel所使用。

home/kiki/Desktop/rwProcMem_module/linux_kernel_api.h:39:29: error: too many arguments to function call, expected single argument 'pte', have 2 arguments 39 | return pte_mkwrite(pte, &vma); | ~~~~~~~~~~~ ^~~~ ../arch/arm64/include/asm/pgtable.h:174:21: note: 'pte_mkwrite' declared here 174 | static inline pte_t pte_mkwrite(pte_t pte) | ^ ~~~~~~~~~ In file included from /home/kiki/Desktop/rwProcMem_module/sys.c:1: In file included from /home/kiki/Desktop/rwProcMem_module/sys.h:19: In file included from /home/kiki/Desktop/rwProcMem_module/api_proxy.h:4: /home/kiki/Desktop/rwProcMem_module/linux_kernel_api.h:91:29: error: too few arguments provided to function-like macro invocation 91 | return class_create(name); | ^ ../include/linux/device/class.h:265:9: note: macro 'class_create' defined here 265 | #define class_create(owner, name) \ | ^ In file included from /home/kiki/Desktop/rwProcMem_module/sys.c:1: In file included from /home/kiki/Desktop/rwProcMem_module/sys.h:19: In file included from /home/kiki/Desktop/rwProcMem_module/api_proxy.h:4: /home/kiki/Desktop/rwProcMem_module/linux_kernel_api.h:91:12: error: use of undeclared identifier 'class_create' 91 | return class_create(name); | ^ In file included from /home/kiki/Desktop/rwProcMem_module/sys.c:1: In file included from /home/kiki/Desktop/rwProcMem_module/sys.h:22: In file included from /home/kiki/Desktop/rwProcMem_module/proc_maps.h:30: /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:197:3: error: implicit declaration of function 'VMA_ITERATOR' [-Werror,-Wimplicit-function-declaration] 197 | VMA_ITERATOR(iter, mm, 0); | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:197:16: error: use of undeclared identifier 'iter' 197 | VMA_ITERATOR(iter, mm, 0); | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:198:3: error: implicit declaration of function 'for_each_vma' [-Werror,-Wimplicit-function-declaration] 198 | for_each_vma(iter, vma) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:198:26: error: expected ';' after expression 198 | for_each_vma(iter, vma) { | ^ | ; /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:198:16: error: use of undeclared identifier 'iter' 198 | for_each_vma(iter, vma) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps_auto_offset.h:200:5: error: 'break' statement not in loop or switch statement 200 | break; | ^ In file included from /home/kiki/Desktop/rwProcMem_module/sys.c:1: In file included from /home/kiki/Desktop/rwProcMem_module/sys.h:22: /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3369:3: error: implicit declaration of function 'VMA_ITERATOR' [-Werror,-Wimplicit-function-declaration] 3369 | VMA_ITERATOR(iter, mm, 0); | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3369:16: error: use of undeclared identifier 'iter' 3369 | VMA_ITERATOR(iter, mm, 0); | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3370:3: error: implicit declaration of function 'for_each_vma' [-Werror,-Wimplicit-function-declaration] 3370 | for_each_vma(iter, vma) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3370:26: error: expected ';' after expression 3370 | for_each_vma(iter, vma) { | ^ | ; /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3370:16: error: use of undeclared identifier 'iter' 3370 | for_each_vma(iter, vma) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3379:5: error: 'break' statement not in loop or switch statement 3379 | break; | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3403:15: error: implicit declaration of function 'vma_is_initial_heap' [-Werror,-Wimplicit-function-declaration] 3403 | } else if (vma_is_initial_heap(vma)) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3405:15: error: implicit declaration of function 'vma_is_initial_stack' [-Werror,-Wimplicit-function-declaration] 3405 | } else if (vma_is_initial_stack(vma)) { | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3408:17: error: implicit declaration of function 'anon_vma_name' [-Werror,-Wimplicit-function-declaration] 3408 | anon_name = anon_vma_name(vma); | ^ /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3408:17: note: did you mean 'arch_vma_name'? ../include/linux/mm.h:3216:14: note: 'arch_vma_name' declared here 3216 | const char * arch_vma_name(struct vm_area_struct *vma); | ^ In file included from /home/kiki/Desktop/rwProcMem_module/sys.c:1: In file included from /home/kiki/Desktop/rwProcMem_module/sys.h:22: /home/kiki/Desktop/rwProcMem_module/proc_maps.h:3408:15: error: incompatible integer to pointer conversion assigning to 'struct anon_vma_name *' from 'int' [-Wint-conversion] 3408 | anon_name = anon_vma_name(vma); | ^ ~~~~~~~~~~~~~~~~~~ fatal error: too many errors emitted, stopping now [-ferror-limit=] 20 errors generated. make[3]: *** [../scripts/Makefile.build:273:/home/kiki/Desktop/rwProcMem_module/sys.o] 错误 1 make[2]: *** [/home/kiki/Desktop/5.1-common/Makefile:1931:/home/kiki/Desktop/rwProcMem_module] 错误 2 make[1]: *** [../Makefile:192:__sub-make] 错误 2 make[1]: 离开目录“/home/kiki/Desktop/5.1-common/out” make: *** [Makefile:10:all] 错误 2
06-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值