【学习笔记】System Address Map Initialization in x86/x64 Architecture Part 1: PCI-Based Systems

原文链接:https://resources.infosecinstitute.com/system-address-map-initialization-in-x86x64-architecture-part-1-pci-based-systems/
摘要

1、 PCI设备内存映射只有在pci设备包含存储空间的时候才需要,例如显卡、网卡(带有板上缓冲或支持pci拓展rom)

2、 对于‘memory’这个词,在文章中多次被引用,容易产生混淆。因此做了如下澄清:

a)
Main memory指的是主板上安装的RAM模块

b)
Memory controller指的是控制RAM的pch或cpu的控制器

c)
Flash memory指的是主板上保存BIOS/UEFI或者PCI拓展ROM的芯片

d)
Memory range或者memory
address range指的是cpu内存空间中设备的首地址到尾地址的空间

e)
Memory space指的是CPU可以访问的内存地址的集合,可以包括ram ROM 或者其他形式的可以被CPU访问到的memory

3、 Boot流程简述

a)
开始执行CPU里的reset vector。在所有的平台中,the bootstrap processor(BSP)开始执行从一个叫做reset
vector的地址中抓取到的指令。在x86/x64中,这个地址是4GB减去16字节(FFFF_FFF0h)。这个地址总是定位到主板上的BIOS/UEFI flash memory中。

b)
CPU操作模式初始化。在此阶段,平台固件会将CPU切换至平台固件CPU操作模式(platform firmware CPU operating mode)它也可能是real mode,
“voodoo” mode, or flat protected mode。这取决于平台的固件。X86 x64的cpu在modified
real mode operating mode下reset。

c)
准备memory初始化。此阶段一般有3个步骤:(1)cpu微代码加载(microcode update)在此步骤下平台将cpu微代码加载进cpu;(2)cpu-specific初始化,此阶段的部分代码会建立一个叫做cache-as-RAM(CAR)的临时堆栈。之所以是临时堆栈,是因为此阶段还没有可以写入的memory,RAM都还没有初始化完成。当前的CPU都支持CAR。之所以需要CAR是因为main memory(RAM)的初始化是一个很复杂的任务,并且需要用到复杂的代码。CAR的存在对此过程有着无法替代的作用。除了CAR的建立,还有某些CPU需要初始化一些machine-specific register(MSRs);(3)chipset的初始化。在此过程中chipset的寄存器被初始化。尤其是chipset的base address
register(BAR)。在一些chipset中,看门狗需要被disable掉,在memory初始化之前,因为它可能会随机的reset系统。

d)
Main memory(RAM)的初始化。在此过程中,内存控制器开始初始化。

e)
后内存初始化阶段。在阶段会将ROM里的code加载到RAM里执行,因为ROM相对于RAM来说太慢了,内存初始化完毕后就可以使用RAM来作为code的载体了:

i.
Memory test。测试内存是否有broken。

ii.
“shadowing”the firmware to RAM。“Shadowing”在这里的意思是将1MB以下的RAM从ROM拷贝到RAM当中。之所以是1MB是由于DOS-era的硬件限制了20bit的寻址长度;

iii.
将memory transaction重定向到正确的目标上。

iv.
建立栈。这一步建立了用于platform firmware代码执行的RAM栈;之前的栈使用的是CAR。在这一步转换为RAM;这一步很重要,因为CAR的栈空间相比于RAM是很有限的;

v.
将平台固件的执行转移到RAM中去;

f)
平台的杂散信号被使能(Miscellaneous platform enabling)。不同的平台有不同的配置,一般来说主要包括时钟芯片的初始化、将平台跑在既定的速率下、一些平台还会在此步骤下初始化GPIO寄存器;

g)
中断的使能。在这一步中断硬件例如中断控制器以及协同的中断处理软件会被使能;

h)
计时器初始化(Timer initialization)。

i)
Memory caching control初始化。

j)
应用处理器初始化(application processor)。非BSP核被称为AP(application processor)。在x86 x64的cpu中,只有BSP会在reset阶段出于活跃状态。因此在OS boot-loader接管系统之前,AP核需要被初始化。AP初始化最重要的事在于MTRR(memory type range register)。MTRR必须在所有的CPU核内连续,否则内存的读写将会misbehave并且使系统宕机。

k)
“simple”IO设备初始化。“simple”IO设备在本文环境中是指例如超级io等硬件设备、嵌入式控制器等。

l)
PCI设备扫描并初始化。在这一步骤检测并初始化PCI总线下的设备。有如下资源分配方式在此过程中执行:IO空间分配、memory mapped IO(MMIO)空间分配、IRQ分配和expansion ROM detection and execution。USB设备也在这一步初始化,这是因为USB是一种PCI总线兼容的协议。其他非legacy设备也在这一步初始化,例如SATA SPI等等。

m)
OS boot-loader执行。这里平台固件将会将执行权交给OS boot-loader,例如GRUB或LILO。

4、 北桥是靠近CPU的芯片组,并且和CPU直接相连。南桥是远离CPU的芯片组并且通过北桥和CPU相连。目前的CPU,北桥一般都已集成到了CPU的封装里。

5、 Intel 815E对目前的标准来说是比较陈旧的,但是它对于新接触PCI 芯片组低层细节的人来说是一个很有趣的学习案例,因为它非常接近“纯净”(pure)的基于pci的系统(pci-based system)。“address mapping router”是一系列的逻辑PCI设备寄存器在北桥中用来控制系统地址映射(system address map)一般来讲,这些寄存器是memory controller和AGP/PCI桥逻辑设备的一部分,在北桥中。平台固件在boot阶段初始化这些地址映射相关的寄存器来为OS下的runtime usage来做准备。

6、 System address map是从CPU端的视角看过去的,而不是系统上的别的芯片;消耗CPU内存空间的设备一般被简称为MMIO设备。
在这里插入图片描述

在这里插入图片描述

7、 从上图的示例可以进一步说明address
mapping的过程。首先假设应用(运行在OS当中的)向video memory请求一个数据。数据的物理地址是11C0_0000h。该请求会发送给北桥,然后北桥会将该地址在所有的address mapping的寄存器中查找,如果某个设备的地址范围包含这个地址,那么将会发送该请求至相应的设备,设备返回对应的内存给北桥,然后北桥在返回至CPU,至此整个过程结束。

8、 有两种PCI BAR,一种是映射到CPU IO空间的,一种是映射到CPU
内存空间的。这两种PCI BAR的形式(format)不一样。BAR的最低位不一样,对于IO space的其最低位是1,对于memory space的最低位是0.

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/u011605941/article/details/88357588