代码之家  ›  专栏  ›  技术社区  ›  user3279360

Linuxx86:在受保护的内核模式下,真实模式地址空间映射到哪里?

  •  2
  • user3279360  · 技术社区  · 11 年前

    在x86平台上运行的Linux中,在受保护的内核模式下,真实模式地址空间映射到哪里?在内核模式下,线程可以直接访问内核地址空间。内核位于较低的8MB,页表位于某个位置,等等(如所述 here ). 但实模式地址空间去哪儿了?可以直接访问吗?例如,BIOS和BIOS插件(请参阅 here )?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Community Mohan Dere    9 年前

    (我的x86-fu有点弱。我会添加一些标签,这样如果我在任何地方说谎,其他人都可以(希望)纠正我。)

    物理地址在真实模式和保护模式下是相同的。唯一的区别在于如何从指令中指定的地址(偏移量)获取物理地址:

    • 在实际模式中,物理地址基本上是 (segment_reg << 4) + offset .

    • 在保护模式下,物理地址为 translate_via_page_table([segment_reg] + offset) .

    通过 [segment_reg] 我是指在 Global or Local Descriptor Table segment_reg . translate_via_page_table() 表示通过分页完成的地址转换(如果启用)。

    here ,BIOS ROM似乎出现在物理地址0x000F0000-0x000FFFFF。要在分页保护模式下获取该内存,必须通过设置正确的 page table 条目。假设4 KB页面(通常情况下),映射整个范围应该需要16((0xFFFFF-0xF0000+1)/4096)个条目。

    要了解Linux内核是如何工作的,可以查看例如。 /dev/mem 它允许读取任意物理地址。实施在 驱动程序/char/mem.c .

    以下命令(来自例如。 this answer )将转储内存范围0xC0000-0xFFFFF(根据上面链接的内存映射,这意味着它也包括视频BIOS):

    $ dd if=/dev/mem bs=1k skip=768 count=256 > bios
    

    1024*768=0xC0000,1024*(768+256)-1=0xFFFFF,这给出了预期的物理内存范围。

    追踪一下事情, read_mem() 在里面 驱动程序/char/mem.c 电话 xlate_dev_mem_ptr() ,在中具有特定于x86的实现 拱/x86/mm/ioremap.c 这个 ioremap_cache() 如果需要,调用该函数似乎负责页面中的映射。

    注意,顺便说一句,BIOS例程不会在保护模式下工作。他们假设CPU以实模式运行。

        2
  •  3
  •   mcleod_ideafix    11 年前

    对于Linux x86 32位,第一个 896MB 物理RAM的地址映射到从虚拟地址开始的连续虚拟内存块 0xC0000000 0xF7FFFFFF 。来自的虚拟地址 0xF8000000 0xFFFFFFFF 动态分配给物理内存的各个部分,因此内核可以有一个窗口 128MB 映射到物理内存的任何部分 896亿 限度

    内核本身以1MB及以上的物理地址加载,从而使第一个MB空闲。例如,第一个MB用于ISA设备所需的DMA缓冲区,因为它们使用8237 DMA控制器,只能映射到这些地址。

    因此,从虚拟内存地址读取 0xC0000000美元 实际上是从物理地址读取 0x00000000 (前提是内核已将该页面标记为存在)