1,请写出开机到os分哪些阶段。
sec->pei->dxe-.bds->tsl->rt->al
2.sec 阶段主要做哪些事?
1,建立cache as ram.
在reset 之后,memory 初始化之前,bios 配置出一段区域用来读写数据,这段区域我们叫datastack.还要配置出一段只读的作为coderegion.
整个过程是这样子的:
名词解释: NEM: no Eviction mode
evict ,就是赶出的意思, 这时候,cache 既然作为程序的代码段,数据段,也就不允许用作常规用途去缓存memory的内容的,就是它里面的内容不能去被随便更新(evict)
注意:
1.在NEM模式里面,不允许发生C-state状态的迁移。
2.NEM 里面 Prefetcher (分支预测?) 会自动关闭
3.确保所有有AP(Application processor) 处于等sipi 状态,
4.将所有的MTRR寄存器初始化为0.
5. 通过IA32_MTRR_DEF_TYPE MSR 将内存(主存) 配置成 un-cacheable.
6. 用作datastack 和codestack 的大小是有限制的。
7.通过MTRR 把coderegion 配置成write-protected 类型。
8.通过NO_EVICT_MODE(MSR 2E0h) 将cache 置成NO-Eviction mode
;-----------------------------------------------------------------------------
;
; Section: SecCarInit
;
; Description: This function initializes the Cache for Data, Stack, and Code
; as specified in the BIOS Writer's Guide.
;
;-----------------------------------------------------------------------------
SecCarInit PROC NEAR PUBLIC
;
; Detect Boot Guard Boot
;
DetectBootGuard:
mov ecx, MSR_BOOT_GUARD_SACM_INFO ;
rdmsr
and eax, 01h
jnz BootGuardNemSetup
SkipDetectBootGuard:
;
; Enable cache for use as stack and for caching code
; Ensure that the system is in flat 32 bit protected mode.
;
; Ensure that only one logical processor in the system is the BSP.
; (Required step for clustered systems).
;
; Ensure all APs are in the Wait for SIPI state.
; This includes all other logical processors in the same physical processor
; as the BSP and all logical processors in other physical processors.
; If any APs are awake, the BIOS must put them back into the Wait for
; SIPI state by issuing a broadcast INIT IPI to all excluding self.
;
mov edi, APIC_ICR_LO ; 0FEE00300h - Send INIT IPI to all excluding self
mov eax, ORALLBUTSELF + ORSELFINIT ; 0000C4500h - Broadcast INIT IPI
mov [edi], eax
@@:
mov eax, [edi]
bt eax, 12 ; Check if send is in progress
jc @B ; Loop until idle
; Ensure that all variable-range MTRR valid flags are clear and
; IA32_MTRR_DEF_TYPE MSR E flag is clear. Note: This is the default state
; after hardware reset.
;
; Initialize all fixed-range and variable-range MTRR register fields to 0.
;
mov ecx, IA32_MTRR_CAP ; get variable MTRR support
rdmsr
movzx ebx, al ; EBX = number of variable MTRR pairs
shl ebx, 2 ; *4 for Base/Mask pair and WORD size
add ebx, MtrrCountFixed * 2 ; EBX = size of Fixed and Variable MTRRs
xor eax, eax ; Clear the low dword to write
xor edx, edx ; Clear the high dword to write
InitMtrrLoop:
add ebx, -2
movzx ecx, WORD PTR cs:MtrrInitTable[ebx] ; ecx <- address of mtrr to zero
wrmsr
jnz InitMtrrLoop ; loop through the whole table
;
; Configure the default memory type to un-cacheable (UC) in the
; IA32_MTRR_DEF_TYPE MSR.
;
mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index
rdmsr
and eax, NOT (00000CFFh) ; Clear the enable bits and def type UC.
wrmsr
; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
; based on the physical address size supported for this processor
; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
;
; Examples:
; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
;
mov eax, 80000008h ; Address sizes leaf
cpuid
sub al, 32
movzx eax, al
xor esi, esi
bts esi, eax
dec esi ; esi <- MTRR_PHYS_MASK_HIGH
;
; Configure the DataStack region as write-back (WB) cacheable memory type
; using the variable range MTRRs.
;
;
; Set the base address of the DataStack cache range
;
mov eax, PcdGet32 (PcdTemporaryRamBase)
or eax, MTRR_MEMORY_TYPE_WB
; Load the write-back cache value
xor edx, edx ; clear upper dword
mov ecx, MTRR_PHYS_BASE_0 ; Load the MTRR index
wrmsr ; the value in MTRR_PHYS_BASE_0
;
; Set the mask for the DataStack cache range
; Compute MTRR mask value: Mask = NOT (Size - 1)
;
mov eax, PcdGet32 (PcdTemporaryRamSize)
dec eax
not eax
or eax, MTRR_PHYS_MASK_VALID
; turn on the Valid flag
mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
mov ecx, MTRR_PHYS_MASK_0 ; For proper addressing above 4GB
wrmsr ; the value in MTRR_PHYS_BASE_0
;
; Configure the BIOS code region as write-protected (WP) cacheable
; memory type using a single variable range MTRR.
;
; Ensure region to cache meets MTRR requirements for
; size and alignment.
;
;
; Save MM5 into ESP before program MTRR, because program MTRR will use MM5 as the local variable.
; And, ESP is not initialized before CAR is enabled. So, it is safe ot use ESP here.
;
movd esp, mm5
;
; Get total size of cache from PCD if it need fix value
;
mov eax, PcdGet32 (PcdNemCodeCacheSize)
;
; Calculate NEM size
; Determine LLC size of the code region and data region combined must not exceed the size
; of the (Last Level Cache - 0.5MB).
;
; Determine Cache Parameter by CPUID Function 04h
;
xor edi, edi
Find_LLC_parameter:
mov ecx, edi
mov eax, 4
cpuid
inc edi
and al, 0E0h ; EAX[7:5] = Cache Level
cmp al, 60h ; Check to see if it is LLC
jnz Find_LLC_parameter
;
; Got L3 parameters
;
; This Cache Size in Bytes = (Ways + 1) * (Partitions + 1) * (Line_Size + 1) * (Sets + 1)
; = (EBX[31:22] + 1) * (EBX[21:12] + 1) * (EBX[11:0] + 1) * (ECX + 1)
;
mov eax, ecx
inc eax
mov edi, ebx
shr ebx, 22
inc ebx
mul ebx
mov ebx, edi
and ebx, NOT 0FFC00FFFh
shr ebx, 12
inc ebx
mul ebx
mov ebx, edi
and ebx, 0FFFh
inc ebx
mul ebx
;
; Maximum NEM size <= (Last Level Cache - 0.5MB)
;
sub eax, 512*1024
Got_NEM_size:
;
; Code cache size = Total NEM size - DataStack size
;
sub eax, PcdGet32 (PcdTemporaryRamSize)
;
; Set the base address of the CodeRegion cache range from PCD
; PcdNemCodeCacheBase is set to the offset to flash base,
; so add PcdFlashAreaBaseAddress to get the real code base address.
;
mov edi, PcdGet32 (PcdNemCodeCacheBase)
add edi, PcdGet32 (PcdFlashAreaBaseAddress)
;
; Round up to page size
;
mov ecx, eax ; Save
and ecx, 0FFFF0000h ; Number of pages in 64K
and eax, 0FFFFh ; Number of "less-than-page" bytes
jz Rounded
mov eax, 10000h ; Add the whole page size
Rounded:
add eax, ecx ; eax - rounded up code cache size
;
; Define "local" vars for this routine
; @todo as these registers are overlapping with others
; Note that mm0 is used to store BIST result for BSP,
; mm1 is used to store the number of processor and BSP APIC ID,
; mm6 is used to save time-stamp counter value.
;
CODE_SIZE_TO_CACHE TEXTEQU
CODE_BASE_TO_CACHE TEXTEQU
NEXT_MTRR_INDEX TEXTEQU
NEXT_MTRR_SIZE TEXTEQU
;
; Initialize "locals"
;
sub ecx, ecx
movd NEXT_MTRR_INDEX, ecx ; Count from 0 but start from MTRR_PHYS_BASE_1
;
; Save remaining size to cache
;
movd CODE_SIZE_TO_CACHE, eax ; Size of code cache region that must be cached
mov edi, 0xFFFFFFFF
sub edi, eax
inc edi
test edi, 0xFFFF
jz @f
add edi, 0x10000
and edi, 0xFFFF0000
@@:
movd CODE_BASE_TO_CACHE, edi ; Base code cache address
NextMtrr:
;
; Get remaining size to cache
;
movd eax, CODE_SIZE_TO_CACHE
and eax, eax
jz CodeRegionMtrrdone ; If no left size - we are done
;
; Determine next size to cache.
; We start from bottom up. Use the following algorythm:
; 1. Get our own alignment. Max size we can cache equals to our alignment
; 2. Determine what is bigger - alignment or remaining size to cache.
; If aligment is bigger - cache it.
; Adjust remaing size to cache and base address
; Loop to 1.
; If remaining size to cache is bigger
; Determine the biggest 2^N part of it and cache it.
; Adjust remaing size to cache and base address
; Loop to 1.
; 3. End when there is no left size to cache or no left MTRRs
;
movd edi, CODE_BASE_TO_CACHE
bsf ecx, edi ; Get index of lowest bit set in base address
;
; Convert index into size to be cached by next MTRR
;
mov edx, 1h
shl edx, cl ; Alignment is in edx
cmp edx, eax ; What is bigger, alignment or remaining size?
jbe gotSize ; JIf aligment is less
;
; Remaining size is bigger. Get the biggest part of it, 2^N in size
;
bsr ecx, eax ; Get index of highest set bit
;
; Convert index into size to be cached by next MTRR
;
mov edx, 1
shl edx, cl ; Size to cache
GotSize:
mov eax, edx
movd NEXT_MTRR_SIZE, eax ; Save
;
; Compute MTRR mask value: Mask = NOT (Size - 1)
;
dec eax ; eax - size to cache less one byte
not eax ; eax contains low 32 bits of mask
or eax, MTRR_PHYS_MASK_VALID ; Set valid bit
;
; Program mask register
;
mov ecx, MTRR_PHYS_MASK_1 ; setup variable mtrr
movd ebx, NEXT_MTRR_INDEX
add ecx, ebx
mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
wrmsr
;
; Program base register
;
sub edx, edx
mov ecx, MTRR_PHYS_BASE_1 ; setup variable mtrr
add ecx, ebx ; ebx is still NEXT_MTRR_INDEX
movd eax, CODE_BASE_TO_CACHE
or eax, MTRR_MEMORY_TYPE_WP ; set type to write protect
wrmsr
;
; Advance and loop
; Reduce remaining size to cache
;
movd ebx, CODE_SIZE_TO_CACHE
movd eax, NEXT_MTRR_SIZE
sub ebx, eax
movd CODE_SIZE_TO_CACHE, ebx
;
; Increment MTRR index
;
movd ebx, NEXT_MTRR_INDEX
add ebx, 2
movd NEXT_MTRR_INDEX, ebx
;
; Increment base address to cache
;
movd ebx, CODE_BASE_TO_CACHE
movd eax, NEXT_MTRR_SIZE
add ebx, eax
;
; if carry happens, means NEM base + size over 4G
;
jc CodeRegionMtrrdone
movd CODE_BASE_TO_CACHE, ebx
jmp NextMtrr
CodeRegionMtrrdone:
;
; Program the variable MTRR's MASK register for WDB
; (Write Data Buffer, used in MRC, must be WC type)
;
mov ecx, MTRR_PHYS_MASK_1
movd ebx, NEXT_MTRR_INDEX
add ecx, ebx
mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag
wrmsr
;
; Program the variable MTRR's BASE register for WDB
;
dec ecx
xor edx, edx
mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC
wrmsr
;
; Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag.
;
mov ecx, MTRR_DEF_TYPE ; Load the MTRR default type index
rdmsr
or eax, MTRR_DEF_TYPE_E ; Enable variable range MTRRs
wrmsr
;
; Enable the logical processor's (BSP) cache: execute INVD and set
; CR0.CD = 0, CR0.NW = 0.
;
mov eax, cr0
and eax, NOT (CR0_CACHE_DISABLE + CR0_NO_WRITE)
invd
mov cr0, eax
;
; Enable No-Eviction Mode Setup State by setting
; NO_EVICT_MODE MSR 2E0h bit [0] = '1'.
;
mov ecx, NO_EVICT_MODE
rdmsr
or eax, 1
wrmsr
;
; Restore MM5 from ESP after program MTRR
;
movd mm5, esp
;
; Restore MM4 which is Patch Pointer.
; Current implementation it's the same with the PcdNemCodeCacheBase + PcdFlashAreaBaseAddress
;
mov edi, PcdGet32 (PcdNemCodeCacheBase)
add edi, PcdGet32 (PcdFlashAreaBaseAddress)
movd mm4, edi
;
; One location in each 64-byte cache line of the DataStack region
; must be written to set all cache values to the modified state.
;
mov edi, PcdGet32 (PcdTemporaryRamBase)
mov ecx, PcdGet32 (PcdTemporaryRamSize)
shr ecx, 6
mov eax, CACHE_INIT_VALUE
@@:
mov [edi], eax
sfence
add edi, 64
loopd @b
;
; Enable No-Eviction Mode Run State by setting
; NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
;
mov ecx, NO_EVICT_MODE
rdmsr
or eax, 2
wrmsr
jmp FinishedCacheConfig
;
; Jump to here when Boot Guard boot and NEM is initialized by Boot Guard ACM
;
BootGuardNemSetup:
;
; Finished with cache configuration
;
; Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
; based on the physical address size supported for this processor
; This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
;
; Examples:
; MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
; MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
;
mov eax, 80000008h ; Address sizes leaf
cpuid
sub al, 32
movzx eax, al
xor esi, esi
bts esi, eax
dec esi ; esi <- MTRR_PHYS_MASK_HIGH
;
; Configure the DataStack region as write-back (WB) cacheable memory type
; using the variable range MTRRs.
;
;
; Find available MTRR
;
CALL_EBP FindFreeMtrr
;
; Set the base address of the DataStack cache range
;
mov eax, PcdGet32 (PcdTemporaryRamBase)
or eax, MTRR_MEMORY_TYPE_WB
; Load the write-back cache value
xor edx, edx ; clear upper dword
wrmsr ; the value in MTRR_PHYS_BASE_0
;
; Set the mask for the DataStack cache range
; Compute MTRR mask value: Mask = NOT (Size - 1)
;
mov eax, PcdGet32 (PcdTemporaryRamSize)
dec eax
not eax
or eax, MTRR_PHYS_MASK_VALID
; turn on the Valid flag
mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
inc ecx
wrmsr ; the value in MTRR_PHYS_BASE_0
;
; Program the variable MTRR's MASK register for WDB
; (Write Data Buffer, used in MRC, must be WC type)
;
;
; Find available MTRR
;
CALL_EBP FindFreeMtrr
FoundAvailableMtrr:
;
; Program the variable MTRR's BASE register for WDB
;
xor edx, edx
mov eax, WDB_REGION_BASE_ADDRESS OR MTRR_MEMORY_TYPE_WC
wrmsr
inc ecx
mov edx, esi ; edx <- MTRR_PHYS_MASK_HIGH
mov eax, WDB_REGION_SIZE_MASK OR MTRR_PHYS_MASK_VALID ; turn on the Valid flag
wrmsr
;
; One location in each 64-byte cache line of the DataStack region
; must be written to set all cache values to the modified state.
;
mov edi, PcdGet32 (PcdTemporaryRamBase)
mov ecx, PcdGet32 (PcdTemporaryRamSize)
shr ecx, 6
mov eax, CACHE_INIT_VALUE
@@:
mov [edi], eax
sfence
add edi, 64
loopd @b
;
; Finished with cache configuration
;
FinishedCacheConfig:
;
; Optionally Test the Region
;
;
; Test area by writing and reading
;
cld
mov edi, PcdGet32 (PcdTemporaryRamBase)
mov ecx, PcdGet32 (PcdTemporaryRamSize)
shr ecx, 2
mov eax, CACHE_TEST_VALUE
TestDataStackArea:
stosd
cmp eax, DWORD PTR [edi-4]
jnz DataStackTestFail
loop TestDataStackArea
jmp DataStackTestPass
;
; Cache test failed
;
DataStackTestFail:
STATUS_CODE (0D0h)
jmp $
;
; Configuration test failed
;
ConfigurationTestFailed:
STATUS_CODE (0D1h)
jmp $
DataStackTestPass:
;
; At this point you may continue normal execution. Typically this would include
; reserving stack, initializing the stack pointer, etc.
;
;
; Temporary Set stack top pointer for C code usage.
;
mov esp, PcdGet32 (PcdTemporaryRamBase)
add esp, PcdGet32 (PcdTemporaryRamSize)
;
; program resource decoding
;
pushad
call EarlyCycleDecoding
popad
pushad
call SerialIoUartConfiguration
popad
;
; After memory initialization is complete, please follow the algorithm in the BIOS
; Writer's Guide to properly transition to a normal system configuration.
; The algorithm covers the required sequence to properly exit this mode.
;
xor eax, eax
SecCarInitExit:
RET_ESI
SecCarInit ENDP
2. 跳到保护模式
3. 找到pei core, 并验证其是否正确
4.再找到BFV把控制权交给pei.
3. sec 是什么语言写的? 汇编语言
4. 什么是Boot firmware volume?
第一个被执行的firmware volume,遵循 efi file system.包含pei core和peim,在开机时sec会到固定位置找到bfv.
5. pei 最主要做哪些事?
(1)detecting and recovery 坏掉的FV
(2)初始化系统内存
(3)把控制权交给dxe
6. pei 有哪些元件,分别做什么的?
(1) pei core: 可以视为pei的核心,用来dispatch peim 和提供基本的service.
(2)pei module: 被pei core所dispatch来做各种任务和初始化。功能有对processor, chipset,device做基本的初始和其他特定的功能。
(3)ppi: peim和peim之间沟通的介面
(4)pei dispatcher 为pei core 的一部分,用来搜寻和执行peim.
(5)pei service: 功能由pei core所提供给peim使用。
7. pei service 有哪些? 各service 功能 ?
(1)ppi service
(2)boot mode service
(3)hob service
(4)firmware volume service
(5)memory service
(6)status code service
7.1.1ppi service :: installppi 具体分析
181-187: PeiInstallPpi() 定义, 安装输入的PPI服务列表到PeiCore数据库里面,并触发满足条件的call back 函数。输入参数是PeiService
指针及安装的PPI列表,返回值是标识是否安装成功的状态值。
193-195: 对输入的参数进行检查,如果输入的PPI列表为空,则是非法输入值,返回不合法的状态。
197-200: 通过PeiService指针,获得PeiCore的内部数据结构,从从进一步获得内部维护的PPI数据库。
214-216:当内部维护的PPI数据库已经被填满,则无法继续存储更多的PPI, 此时返回资源不够的状态值。
217-226:检查传进来的参数到底是不是一个合法的PPI,如果不是,打印出有问题的部分。
229-230:记录PPI到内部维护的PPI数据库,并输出调式信息。
232 - 238: 检查当前的PPI是不是输入列表中的最后一个PPI,如果是的话,则退出循环。
239-240:跳到下一个PPI,再继续安装。
243-253:当有新的PPI安装以后,调用派遣通知函数,触发满足条件的callback函数。
256: 如果PPI列表里面的所有的 PPI都成功安装了,返回成功标识的状态值。
420-423 : PeiNotifyPpi() 定义,安装PPI的回调函数列表到PPI数据库,并触发满足条件的回调函数。输入参数分别PeiService指针及回调函数列表,
返回值是标识是否安装成功的状态值。
435-437:对输入参数的检查,如果输入的PPI回调函数列表为空,则是不合法的输入值,返回不合法的状态。
439: 通过PeiService指针,获得PeiCore的内部数据结构,从而进一步的获得内部维护的PPI及回调函数的数据库。
450: 遍历输入的PPI回调函数列表,安装它们到内部维护的PPI回调函数数据库。
451-458: 当内部维护的PPI回调函数数据库已经被填满,则无法继续存储更多的PPI回调函数,此时返回资源不够的状态值。
460-467:如果需要安装的PPI回调函数没有标识自己是回调类型的PPI,则是不合法的PPI回调函数,它无法被安装,打印出有问题的部分。
469-471: 记录派遣类型的PPI回调函数的个数,以便在安装完成后立即对回调类型的PPI进行派遣,即核查它们是否满足回调条件,一旦满足,则它们
立即触发。
484-485: 跳到下一个PPI回调函数,再继续安装。
8. pei 的code在哪里执行?
cache as ram
9 pei dispatch 四大rule
:peim 未被dispatch, peim 为正确的格式,peim为可信赖的,peim的dependency条件符合。
9.1 PeiDispatcher的具体实现:
640: 传进来两个指向结构体的指针,这两个结构体具体为:
10,什么时dependency? dependency关系记录在哪里?如何表示?
一个peim 在执行时,有可能会用到其他peim的功能。所以要等其他peim先执行后,并install ppi至 ppi database中,
该peim才能使用,该ppi也才能继续执行下去。dependency 关系放在在fv的一个特殊的section中,一个peim有可能会
需要很多其他peim先执行才能执行,所以表示方法用boolean运算符 and, or, 和sequencing .
11. 如何dispatch other fv?
不一定所有的peim都在bfv中,有可能在其他的fv,所以要用dispatch other fv的机制。此时需要一个特别的peim来告诉
pei core 说其他fv还有peim要dispatch, 所以当pei core dispatch 到这个peim时,会把其他peim的dispatch顺序加到
pei core 的搜寻algorithm中。
12. 什么是notification
假设一个peim有十个function,在执行完九个后,最后一个function 需要其他peim的功能,但该peim尚未被dispatch,
此时可能用notify的功能告诉pei core,需要ppi才能执行,然后就继续dispatch其他peim,当有ppi被install,就会和notify
的ppi guid做比较,如果是notify的ppi就跳回到下notify的peim去把剩下的function执行完,提供了一个call back 的机制。
13. 什么是 PPI?
peim 和peim 的沟通介面,当peim需要提供功能给其他peim使用时,需要先install 一个PPI至ppi database中,其他的
peim 就可以通过pei core 来使用该ppi,ppi 的栏们为guid和interface.guid是128位的数据,它是唯一性的,即使不同的
在同一时间建立也不会相同,Interface是一个function pointer, 用来指向ppi 所提供的function.
应该说interface 指向一堆数据,可以是一个函数指针,也可以是多个。
///
/// The data structure through which a PEIM describes available services to the PEI Foundation.
///
typedef struct {
///
/// This field is a set of flags describing the characteristics of this imported table entry.
/// All flags are defined as EFI_PEI_PPI_DESCRIPTOR_***, which can also be combined into one.
///
UINTN Flags;
///
/// The address of the EFI_GUID that names the interface.
///
EFI_GUID *Guid;
///
/// A pointer to the PPI. It contains the information necessary to install a service.
///
VOID *Ppi;
} EFI_PEI_PPI_DESCRIPTOR;
struct _EFI_PEI_S3_RESUME2_PPI {
///
/// Restores the platform to its preboot configuration for an S3 resume and
/// jumps to the OS waking vector.
///
EFI_PEI_S3_RESUME_PPI_RESTORE_CONFIG2 S3RestoreConfig2;
};
14. 什么是hob?
由pei 阶段传送给dxe的信息只能通过hob来传送,所以他包含dxe所需的所有信息,如phit, physical memory,firmware
volume ,dxe core, dxe stack/bsp, guid hob, 它是linking list的数据结构,标头为phit,其中包含了boot mode的信息,
尾巴是termination.如果搜寻hob时找到termination表示没有些hob,guid hob 是由chipset vendor 提供的信息,
有自己的格式,不想被其他人所使用,是属于private information.
关于hob 的一些具体函数 解析:
PeiCreateHob 创建hob,并返回hob的地址
070-077:PeiCreateHob() 定义, 创建请求类型的HOB数据块,并返回HOB数据块的地址。输入 参数分别是PeiService指针、HOB类型及长度、用于存储创建的HOB地址的
指针,返回值是标识是否成功创建的状态值。
085-088: 获得HOB列表的起始地址。
090:HOB列表的起始是HandOffHob 数据块,存储当前的系统信息。
92-94: 调整新创建HOB长度为8字节对齐,并计算当前可用的HOB数据块的空间。
103-107: 如果可用的空间不足够创建请求的HOB时,则打印出调试信息说明当前系统资源不足够满足系统运行,并返回系统资源不够的状态值。
110-113: 当空间足够时,追加新的HOB在当前HOB列表的最末端,并记录HOB数据块的地址。
121-123:更新可用空间的末端地址,因为新的HOB占用了一部分空间。
124:返回成功的状态值。
15, Recovery 的步骤
(1)由platform policy来决定是否要reset platform.
(2)不管platform有没有reset,core dispatch都会做reset,然后重新dispatch,只dispatch有标为recovery的peim.
(3)读取boot mode 来决定要dispatch哪些peim.