linux内核 硬件reset,深入UEFI内核(一)ResetVector

深入UEFI内核前面通过《UEFI原理与编程》一书介绍了如何使用UEFI编写应用程序和驱动,编程一书是从上层应用和驱动开发者的角度认识UEFI的,UEFI就像一个黑盒子,书中详细介绍了这个黑盒子的表面(即UEFI提供给上层开发者的接口和服务)。接口通过Protocol呈现给开发者。主要的Protocol包括控制台输入输出Protocol;文件及硬盘Protocol;操作外部设备的Protocol(...
摘要由CSDN通过智能技术生成

深入UEFI内核

前面通过《UEFI原理与编程》一书介绍了如何使用UEFI编写应用程序和驱动,编程一书是从上层应用和驱动开发者的角度认识UEFI的,UEFI就像一个黑盒子,书中详细介绍了这个黑盒子的表面(即UEFI提供给上层开发者的接口和服务)。接口通过Protocol呈现给开发者。主要的Protocol包括控制台输入输出Protocol;文件及硬盘Protocol;操作外部设备的Protocol(PciIo等);驱动框架Protocol;人机交互接口Protocol;网络Protocol。服务通过启动服务和运行时服务提供,主要包括Protocol服务,内存管理服务,事件管理服务等。UEFI虽然庞大,但它通过模块化被很清晰的组织在一起,当逐步掌握了这些主要的Protocol和服务之后,UEFI也就变得简单起来,那么是时候深入到这个盒子内部,了解UEFI内核的运行机制了。

下面将以系统启动过程为主线介绍UEFI内核。

第一条指令(ResetVector)

先说结论:X86 CPU启动后,将从地址0xFFFFFFF0处开始执行(此地址并非内存地址。此时,内存还远远没有初始化。)。这一章来看X86系统是如何实现这一点的。

加电或者RESET针脚被激发(Assert)后[ref intel] CPU会经历如下几个过程:

1. CPU首先会进行硬件初始化(hardware reset)。

2. 然后是可选的自检过程(BIST built-in self-test)。

3. CPU开始执行第一条指令。从此开始CPU进入软件初始化过程。

1.CPU硬件初始化

CPU硬件初始化完成后,CPU被设置为实地址模式,地址无分页。所有寄存器被初始化为特定的值, Cache、TLB(Translation Lookup Table)、BLB(Branch Target Buffer)这三个部件的内容被清空(Invalidate)。

2.自检

CPU硬件初始化过程中,硬件可能请求执行自检。如果执行自检,自检完成后,EAX的值为自检错误码,0表示没有任何错误;

3.第一条指令

现在,完事俱备,CPU已经准备好,迫不及待地要执行第一条指令了。且慢,这是一个重要的时刻,此刻决定了CPU能否正常指令,让我们详细了解一下CPU目前的状态。

表1-1 CPU初始化后的寄存器(部分)RegisterPentium 4 and Intel Xeon ProcessorP6 Family Processor Including DisplayFamily = 06H)Pentium ProcessorEFLAGS100000002H00000002H00000002H

EIP0000FFF0H0000FFF0H0000FFF0H

CR060000010H60000010H60000010H

CR2, CR3, CR400000000H00000000H00000000H

CSSelector = F000H

Base = FFFF0000H

Limit = FFFFH

AR = Present, R/W, AccessedSelector = F000H

Base = FFF0000H

Limit = FFFFH

AR = Present, R/W, AccessedSelector = F000H

Base = FFFF0000H

Limit = FFFFH

AR = Present, R/W, Accessed

SS, DS, ES, FS, GSSelector = 0000H

Base = 00000000H

Limit = FFFFH

AR = Present, R/W, AccessedSelector = 0000H

Base = 00000000H

Limit = FFFFH

AR = Present, R/W, AccessedSelector = 0000H

Base = 00000000H

Limit = FFFFH

AR = Present, R/W, Accessed

EDX00000FxxH000n06xxH000005xxH

EAX000

EBX, ECX, ESI, EDI, EBP,ESP00000000H00000000H00000000H

此处我们最关心的是指令执行相关的两个寄存器EIP(Instruction Pointer)、CS(Code Segment)。

在实地址模式下(寄存器字长为16位),指令的物理地址是CS << 4 + EIP。段寄存器CS左移四位作为基址,再加上作为偏移的EIP,最终形成指令的物理地址。现代CPU中为了加速指令地址的计算,为每个段寄存器增加了两个寄存器:Base和Limit。Base存放基址,Limit存放最大偏移值。Base和Limit寄存器不能通过指令直接读写,他们的值是在写段寄存器时由CPU自动设置的。通常Base等于段寄存器左移四位,如果CS的值为0xF000,CS的Base寄存器则为0xF0000,但CPU初始化时例外。从表1-1可以看出CS的值为0xF000, 但其Base为0xFFFF0000,EIP为0xFFF0,此时对应的指令地址为0xFFFF0000+0xFFF0 = 0xFFFFFFF0。0xFFFFFFF0就是CPU将要执行的第一条指令。这造成这样一个有趣的事实,16位程序眼中的指令地址空间0x0000~0xFFFF(大小为64K)被CPU翻译到物理地址空间(0xFFFF0000~0xFFFFFFFF)。也就是说,从CPU初始化,到段寄存器被重写(通过跨段跳转指令)前,指令空间0x0000~0xFFFF通过段寄存器被映射到物理地址空间0xFFFF0000~0xFFFFFFFF。

前面讲到第一条指令地址为0xFFFFFFF0,X86系统初始化时会将ROM中的固件映射的(0xFFFFFFFF-固件大小)~0xFFFFFFFF的地址空间。故而0xFFFFFFF0对应ROM中的某条指令,无论ROM中存放的是传统的BIOS固件,还是存放的UEFI固件,这个规则都是一样的。下面将从这天指令开始继续CPU初始化之旅。

开始讲0xFFFFFFF0对应的指令之前,还要熟悉UEFI ROM的的结构。

ROM固件(Flash Device binary image)由一个或多个Firmware volume(FV)构成,每个FV里存放了FFS Image(EFI Firmware File system),FFS Image则由

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值