gpt4 book ai didi

c - 如何实现分页,并在知道虚拟地址的情况下找到物理内存地址

转载 作者:行者123 更新时间:2023-12-01 00:09:43 25 4
gpt4 key购买 nike

我想实现 paging 的初始化。
引用 osdev wiki 的一些链接:https://wiki.osdev.org/Paging , https://wiki.osdev.org/Setting_Up_Paging ,我自己的版本很不一样。
因为,当我们查看页目录时,他们说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 位)。

关于c - 如何实现分页,并在知道虚拟地址的情况下找到物理内存地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59719743/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com