0
点赞
收藏
分享

微信扫一扫

关于E820表的几个问题

1.E820表的来源

    E820表是Linux内核在x86架构上启动时,用于描述物理内存布局的关键数据结构。它详细记录了系统中哪些物理地址范围是可供操作系统使用的“可用内存”(RAM),哪些又被BIOS或其他系统组件“保留”而不可使用。     E820表的构建始于内核启动的早期阶段,具体过程如下: ​​    BIOS查询​​:计算机启动后,内核(通常由引导加载程序如GRUB加载)会通过​​BIOS中断调用int 0x15​​,并在AX寄存器中传入功能号0xE820,来向BIOS请求系统的物理内存布局信息。之所以叫“E820表”,正是源于这个功能号。 ​​    数据填充​​:BIOS处理该中断后,会将内存布局信息返回并填充到一个预定的结构体数组中,即boot_params.e820_table。每条记录都包含起始地址、大小和类型(如可用RAM、保留区域等)。 ​​    内核整理与转换​​:获取到原始数据后,内核在start_kernel()-> setup_arch()函数中,会调用e820__memory_setup_default()函数。这个函数负责将BIOS提供的原始E820表转换并合并到内核自己使用的e820_table中,并进行一些整理工作,比如合并相邻的相同类型的区域。

    E820表中记录的​​所有地址都是物理地址​​。这是因为E820表是在内核初始化过程中、​​分页机制尚未完全建立之前​​就被构建出来的。它的核心使命是告诉操作系统“物理内存的真实地图”,比如从0到640KB的基本内存,以及1MB以上的扩展内存是可用的,而中间一些区域(如用于BIOS或设备内存映射的区域)则是保留的。内核的内存管理子系统(如memblock分配器)正是基于这张“物理地图”来开始工作的。

2.怎么理解保留内存

    要理解“保留内存”,关键在于理解x86系统的​​内存映射I/O​​机制。X86的架构,内存与外设是统一编址的,CPU用于访问内存的地址总线,同时也被用来访问外部设备的寄存器。

注意 ARM的内存与IO是独立编址的,但是ARM有由于其它原因保留内存(例如DMA缓存、给协处理器预留共享内存区等等),所以ARM没有E820表,注意这里的区别。

    当CPU访问一个被E820表标记为“保留”的物理地址时,它实际上是在访问​​外设内部自带的存储单元​​,而非内存条上的DRAM。这背后的核心技术是​​内存映射I/O​​。     计算机启动时,BIOS的任务是探测并初始化所有关键硬件。它清楚地知道系统中有哪些设备,以及这些设备需要占用哪部分物理地址空间来正常工作(比如显卡需要一块空间来作为显存的映射窗口)。BIOS将这些​​不能被操作系统当作普通内存分配使用的地址区域​​标记为“Reserved”(保留),并汇总到E820表中。所以,E820表中的保留内存,本质上就是BIOS告诉内核:“​​这片地址区域已经被‘征用’了,有专门的硬件设备驻扎在这里,你不能把它们分配给普通程序使用。

3.与保留内存地址重合的内存条上的存储空间怎么办

    访问这些保留地址空间,是CPU通过“内存映射I/O”机制直接访问外设内部的寄存器或自带存储器,而非访问内存条上的物理内存。外设的这些存储单元被预先映射到了系统统一的物理地址空间中。​​ 而内存条本身的物理地址是从0开始编址的,例如X86上物理地址​​640KB到1MB会被BIOS征用,那么内存条上对应物理地址​​640KB到1MB(即0xA0000至0xFFFFF)的这段存储空间,因为与外设地址范围重合,故其存储能力无法被系统作为普通内存来访问和使用​​,实际上就是被浪费掉了

4.保留内存的一个景点例子

    一个经典的例子:0xA0000-0xFFFFF区域     这个640KB到1MB之间的区域是理解保留内存的绝佳案例: ​​    历史背景​​:在早期PC(如基于8086CPU)中,1MB以下的物理内存被分为两段:0到640KB为​​基本内存​​,供操作系统和应用程序使用;640KB到1MB这384KB的地址空间,则被预留给硬件。     ​​具体用途​​:这部分地址空间被映射给了​​显卡的显存​​(如经典的VGA模式)、​​系统的BIOS ROM​​等。当CPU向这个范围内的地址写入数据时,实际上是在直接操作显卡硬件;当CPU从这个范围读取指令时,可能是在执行BIOS固件代码。 ​​    影响延续​​:尽管现在的计算机物理内存远大于1MB,但为了兼容历史上的硬件和规范,这段空间依然被保留下来,形成了著名的“​​640KB内存空洞​​”。

5.现代计算机的演变

    动态资源分配​​:对于PCI/PCIe等现代总线设备,其所需的内存映射空间(称为MMIO空间)是由操作系统在启动时​​动态分配​​的,通常会将其映射到物理地址空间的高端(例如3.5GB以上),从而避免与主内存区域的冲突

举报

相关推荐

0 条评论