gpt4 book ai didi

linux - nopage()方法实现

转载 作者:太空狗 更新时间:2023-10-29 12:19:23 25 4
gpt4 key购买 nike

任何人都知道如何在无页面方法中将虚拟地址转换为物理地址。引用设备驱动程序书,nopage 方法给出为,

struct page *simple_vma_nopage(struct vm_area_struct *vma,
unsigned long address, int *type)
{
struct page *pageptr;
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long physaddr = address - vma->vm_start + offset;
unsigned long pageframe = physaddr >> PAGE_SHIFT;

if (!pfn_valid(pageframe))
return NOPAGE_SIGBUS;
pageptr = pfn_to_page(pageframe);
get_page(pageptr);
if (type)
*type = VM_FAULT_MINOR;
return pageptr;
}

page_shift 是用于表示虚拟和物理内存地址偏移量的位数。但是偏移变量是什么?如何通过对地址和 vm_start 等虚拟地址变量的算术运算计算出物理地址?

最佳答案

感觉vm_pgoff的文档不是很清楚。这是内存区域第一页在 RAM 中的偏移量。所以如果我们的 RAM 从 0x00000000 开始,我们的内存区域开始在 0x0000A000,然后 vm_pgoff = 10。如果您考虑/重新访问 mmap系统调用然后你可以看到我们传递的“偏移量”是偏移量文件中“长度”字节将被映射的起始字节到内存区域。这个偏移量可以左转为地址将其移动到 PAGE_SHIFT 值 12(即每页大小 4KB)

现在不管cr3寄存器是否用线性地址来物理地址转换与否,当我们说“地址 - vm_start”然后这给出了地址之间部分的大小。例子: vm_start = 0xc0080000 地址 = 0xc0090000

address - vm_start = 0x00010000
physaddr = (address - vma->vm_start) + offset;
= 0x00010000 + (10 << PAGE_SHIFT)
= offset_to_page_that_fault + start_addr_of_memoryRegion_in_RAM
= 0x00010000 + 0x0000A000
= 0x0001A000

现在因为这是物理地址所以我们需要转换为页框右移 PAGE_SHIFT 值即 0x0001A000 >> 12 = 0x1A = 26(十进制)因此,第 26 个页框必须加载来自被映射文件的数据。因此,通过使用 inode 的 struct address_sapce 从磁盘检索数据其中包含页面在磁盘上的位置信息(交换空间)。一旦数据被引入,我们返回代表这个数据的结构页面发生此页面错误的 page_frame。我们将其返回给用户。

这是我对最新的理解,但我没有测试过。

关于linux - nopage()方法实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14560538/

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