内核地址空间和内核页表

内核地址空间和内核页表

我正在学习专业 Linux 内核架构,并且正在学习第 3 章内存管理。而我研究的时候内核地址空间本身就分为直接映射区、vmalloc区、kmap区和固定映射区。

在此输入图像描述

我想知道的是就像下面这样。

  1. 32位机内核地址空间的直接映射区(896MB)可以通过__va、__pa等函数在没有MMU的情况下访问吗?

  2. 如果 1. 为 true 那么主内核页表(swapper_pg_dir)仅管理 128MB ?

  3. 当我研究内核代码时,我发现 32 位和 64 位之间的 paging_init 函数存在差异。在32位中,我发现pagetable_init函数初始化并主控内核页表分页初始化功能。

32 位的 paging_init 函数

void __init pageit_init(void){
    pagetable_init();
    __flush_tlb_all();

    kmap_init();

    olpc_dt_build_devicetree();
    sparse_memory_present_with_active_regions(MAX_NUMNODES);
    sparse_init();
    zone_sizes_init(); 
}

但在64位中,我找不到内核页表相关的函数分页初始化功能。

void __init paging_init(void)
{
    sparse_memory_present_with_active_regions(MAX_NUMNODES);
    sparse_init();

    node_clear_state(0, N_MEMORY);
    if (N_MEMORY != N_NORMAL_MEMORY)
        node_clear_state(0, N_NORMAL_MEMORY);

    zone_sizes_init();
}

64位内核没有主内核页表吗?如果是真的,它是否只是通过直接映射来访问内核内存?

答案1

问题 1 和 2 的答案:不,一旦启用分页,CPU 指令仅使用虚拟地址,在读取或写入 RAM 之前使用 MMU 将虚拟地址转换为物理地址。__va和宏__pa不访问内存,它们只是在地址空间之间转换地址。在 32 位机器上,__va只需添加0xc0000000作为参数给出的物理地址,因为映射已设置为物理地址N位于虚拟地址处N+0xc0000000

CPU要访问的地址必须有映射;你无法绕过MMU。因此,仅管理 128 MB 的映射是不够的。

相关内容