我如何实现分页,并通过虚拟地址找到物理内存地址
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我如何实现分页,并通过虚拟地址找到物理内存地址相关的知识,希望对你有一定的参考价值。
我想实现分页的初始化。关于osdev Wiki的一些链接:https://wiki.osdev.org/Paging,https://wiki.osdev.org/Setting_Up_Paging,我自己的版本非常不同。因为,当我们查看page directory时,他们说12位用于标志,其余部分用于页表的地址,因此我尝试了类似的操作:
void init_paging()
unsigned int i = 0;
unsigned int __FIRST_PAGE_TABLE__[0x400] __attribute__((aligned(0x1000)));
for (i = 0; i < 0x400; i++) __PAGE_DIRECTORY__[i] = PAGE_PRESENT(0) | PAGE_READ_WRITE;
for (i = 0; i < 0x400; i++) __FIRST_PAGE_TABLE__[i] = ((i * 0x1000) << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
__PAGE_DIRECTORY__[0] = ((unsigned int)__FIRST_PAGE_TABLE__ << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
_EnablingPaging_();
此功能帮助我知道物理地址,也知道虚拟地址:
void *get_phyaddr(void *virtualaddr)
unsigned long pdindex = (unsigned long)virtualaddr >> 22;
unsigned long ptindex = (unsigned long)virtualaddr >> 12 & 0x03FF;
unsigned long *pd = (unsigned long *)__PAGE_DIRECTORY__[pdindex];
unsigned long *pt = (unsigned long *)pd[ptindex];
return (void *)(pt + ((unsigned int)virtualaddr & 0xFFF));
我的方向错误?
还是还是一样?
假设您正在尝试标识物理地址空间的前4个MiB:
a]对于unsigned int __FIRST_PAGE_TABLE__[0x400] __attribute__((aligned(0x1000)));
,它是一个局部变量(例如,可能放在堆栈上);并且该函数返回后将无法生存(例如,其使用的堆栈空间稍后将被其他函数覆盖),从而导致页表损坏。这样的结局不太可能。
b]对于__FIRST_PAGE_TABLE__[i] = ((i * 0x1000) << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
,您要移动i
两次,一次是使用* 0x1000
(与<< 12
相同),另一次是<< 12
。这太多了,它需要更像__FIRST_PAGE_TABLE__[i] = (i << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
。
c)对于__PAGE_DIRECTORY__[0] = ((unsigned int)__FIRST_PAGE_TABLE__ << 12) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
,该地址已经是地址(而不是需要移位的“页码”),因此它需要更像__PAGE_DIRECTORY__[0] = ((unsigned int)__FIRST_PAGE_TABLE__) | PAGE_PRESENT(1) | PAGE_READ_WRITE;
。
除此之外;我非常希望更好地使用类型。特别;您可能应该养成使用uint32_t
(或uint64_t
或您自己的typedef
)作为物理地址的习惯,以确保您不会将虚拟地址与物理地址相混淆(并确保当您犯错时,编译器会抱怨错误的类型);因为(即使现在由于身份映射它现在还不是很重要),它很快就会变得很重要。我还建议对页表条目和页目录条目使用uint32_t
,因为它们必须为32位,而不是“编译器感觉为int
应该是什么大小”(请注意,这与您的想法有所不同有关代码的信息,这比编译器实际执行的操作或int
是否恰好是32位更重要)。
以上是关于我如何实现分页,并通过虚拟地址找到物理内存地址的主要内容,如果未能解决你的问题,请参考以下文章