无论是千万行的linux ,还是百万行的uefi ,或者百十行的app, 它都有一个主线。应用程序是main() 函数里面全部函数运行完,程序结束。这里main() 做为程序的起点,uefi 能够觉得,就是peimain.c dxemain.c bds.c 这三个函数运行完,bios 结束。假设进一步的细分。 假设 把pei 和 sec 叫做early initialization, 这一阶段 主要就是在做microcode 更新。跳到保护模式,用cache 去模拟内存以便实现C函数的子过程调用,内存配置,内存(控制器)的配置,就是mrc
的运行,事实上就是依照 JEDEC 定好的初始化顺序,主要是取得这些信息, rank的数量。 地址是8 bit 还是16 bit, 内存容量,内存的电源管理。page 关闭策略, 内存初始化好之后,就是进行memory 測试。最常见的就是ECC. 当这一切做完了,就把bios 代码 shadowing 到内存上面。 剩下来就是完毕 板子上其它设备的初始化了, GPIO, 中断控制器,timer, 串口, 时钟(超频), pci bus 初始化(就是找到它们,并给它们分资源。 事实上就是内存,i/o space,
mmio, irq, 找到option rom ,以及运行option rom). 网卡初始化, usb, sata. 最后就是 装载os, 通过efi 的 load image 或者 int 19h 去调用 os loader.
Application Processor (AP) 初始化
这年头。即使手机,平板电脑,也配备了多核处理器。BSP + AP 的组合方式。由BSP 负责去初始化系统, 在内存初始化之前,AP 处于未初始化状态。当内存起来之后。内存被初始化,处于等SIPI 状态。 详细是这样玩的:
1 找到microcode ,拷贝到内存中。
2 在SIPI 里面找到cpu code ,拷贝到内存中
3 向全部的处理器发送IPI
4 Disable NEM
5 对全部处理器进行micro code 更新
6 把全部处理器cache 打开
具体的细节去參考software Developer‘s Manual, 更具体的过程就要參考bios writer‘s guide了。
假设从UEFI 的角度看,那么AP 的初始化能够划在PEI 阶段。
CPUID-线程以及core
如今 对一些常见的术语进行解释:
thread. - 线程。 逻辑上的处理器,与其它logical 处理器处于同一个package上面。并与其它逻辑处理器共享资源。
core. 与其它core 处于同一个packge 上面,但不须要与其它core 共享不论什么资源。
package 即我们看得见的芯片,能够包括随意数量的core 和 thread.
Startup Inter-Processor Interrupt (SIPI)
BSP 通过向每个core ,thread 去发送SIPI 去叫醒(wake up) 它们。
详细来说是通过BSP 的LAPIC , LAPIC 标识了SIPI 要发给哪一个AP.
发送IPI JQA是通过写寄存器ICR完毕的, 先来看一下ICR, ICR是64位寄存器。 可分为两个32位寄存器。ICR 的数据结构例如以下图所看到的:
详细过程就是这种:
AP Wakeup State
当AP 接收到SIPI 之后。就開始运行sipi 指向的代码。
Platform 初始化过程:
现行代码分成mem initial 之前的部分和mem initial 之后的部分。即PlatformInitPreMem.c 和PlatformInit.c。
premem 阶段,主要完毕pch 一些主要的初始化(主要是完毕对gpio的定义, LPC IO 的配置), 还有timer 的初始化,
PCH 初始化入口为:PchInitPreMem.c 它主要也是分两个阶段 :early PEI phase(Memoyr 初始化之前) 和memory is available(memory 能用了)
??
??