2012-03-28 50 views
2

我想出了这个问题,因为我不明白如何在内核区域执行地址转换。CPU要求地址高于0xC0000000时如何执行地址转换(virt-> phy)?

据我所知,要翻译0xC0000000以上的任何地址,我们只需要减去这个地址PAGE_OFFSET(除了内核初始化过程,我们需要一个8MB范围的页表)。但是在CPU执行需要地址的指令时,例如0xF0000020,而系统只有256MB RAM,这没有意义。

由于上述原因,我认为内核确实有一个页表,它允许MMU将高于0xC0000000的虚拟地址转换为物理地址。因此,在什么情况下我们可以直接减去PAGE_OFFSET以及在什么情况下我们需要内核页表?

我可能在开始的时候出错,所以请更正。


编辑

从< <了解Linux的虚拟内存管理>>,它说:内核页表存在。现在,越来越迷茫......

3.6内核页表

当系统第一次启动,分页没有启用,因为页表不 神奇初始化自己。每个体系结构实现这个不同,所以只讨论x86情况。页表初始化分为两个 阶段。引导阶段为8MiB设置页表,以便可以启用分页 单元。 第二阶段初始化其余页表。我们 在下面的章节中讨论这两个阶段。

3.6.1自举

...

3.6.2敲定

负责敲定页表的函数被调用paging_init()。图3.4中可以看到x86上该函数的调用图。 enter image description here

功能首先调用pagetable_init()来初始化必要 页表以引用的所有物理存储器中ZONE_DMA和ZONE_NORMAL。请记住,无法直接引用ZONE_HIGHMEM中的 高内存,并且临时为其设置映射 。对于内核使用的每个pgd t,调用引导存储器 分配器(请参阅第5章)为PGD分配一个页面,并且如果可以使用PSE 位,则使用4MiB TLB条目而不是4KiB。如果不支持PSE 位,则会为每个pmd分配一个PTE页面。如果CPU 支持PGE标志,则它也将被设置,以便页表项将为全局 ,并且对所有进程都可见。然后,pagetable_init()调用fixrange_init()在FIXADDR_START开始的虚拟地址空间末尾设置固定地址 空间映射。这些映射用于诸如本地高级可编程中断控制器(APIC)之类的用途以及kmap_atomic()所需的FIX_KMAP_BEGIN 和FIX_KMAP_END之间的原子映射。最后,该函数调用 fixrang_init()来初始化与kmap()映射的普通高内存映射所需的页表项。

pagetable_init()返回之后,内核空间中的页表现在完全 初始化,因此静态PGD(swapper_pg_dir)被装入CR3寄存器,从而 该静态表现在正在使用的寻呼单元。

paging_init()的下一个任务是负责调用kmap_init()到 用PAGE_KERNEL保护标志初始化每个PTE。最后的任务是 来调用zone_sizes_init(),它初始化所有使用的区域结构。

回答

0

虽然线性映射对人类来说可能看起来很特殊,但它对于MMU配置来说(通常)并不是特殊的。

正如你所说,要将虚拟地址从3G转换到3G + 900MB,我们可以直接用PAGE_OFFSET减去这些地址。这是否意味着内核不需要任何页表?

它仍然需要这些表来解释到MMU的特定(线性)映射。虽然有一些特殊情况,如MIPS R3000

但是,在CPU执行,在需要地址的指令这没有任何意义,说0xF0000020

我问是否有意义在首位的是地址指令执行。我的意思是,在具有256MB RAM的系统上,你不会只是遇到这样的请求(至少假设代码不是越野车)。

令您困惑的一点是IMO:谁负责做地址翻译?答案是(通常)MMU,通过硬件实现。因此,页表是MMU如何进行翻译的方式 - 这不是内核责任。内核只需要配置MMU。

当CPU需要高于0xC0000000的地址时,如何执行地址转换(virt-> phy)?

就像下面的地址一样。 This阅读可能会有所帮助。

0

对于前900MB的物理内存(如果存在)有一个线性映射,以便该内存的虚拟地址等于物理内存加上PAGE_OFFSET。当然,这并不妨碍将相同的物理内存映射到进程地址空间中的其他地方,如果内核想要将该内存用于其他目的。

+0

正如你所说,要将虚拟地址从3G转换到3G + 900MB,我们可以直接用PAGE_OFFSET减去这些地址。这是否意味着内核不需要任何页表?但是,它确实存在,所以我不明白为内核页表提供什么服务。请参阅编辑。 – sliter 2012-03-28 20:49:55

+0

一切都需要线性模式的页表;这个映射只是一个约定,可以更容易地访问第一个900MB的物理内存。 – Neil 2012-03-29 20:43:51

0

实际上你的用户空间程序甚至内核都使用虚拟寻址。这意味着每个内存请求都通过MMU。如果这样下去,通过MMU它使用页表(见86 CR3寄存器)

virtual addr --> MMU --> physical addr 

和内核不使用,当你访问lowmem一些神奇的优化。是lowmem是直接映射的,这就是为什么从人的角度来看,您可以通过简单的减法将虚拟地址lowmem转换为物理地址,但是CPU通过内核页表进行这种转换。