UEFI实战SlimBootloader使用

Posted jiangwei0512

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UEFI实战SlimBootloader使用相关的知识,希望对你有一定的参考价值。

说明

【UEFI实战】SlimBootloader简介中已经介绍了Slim Bootloader的基本内容,不过因为时间有点久远,不少内容已经过期不能使用,所以这里更新一版。

简述

Intel® Slim Bootloader,简称Intel® SBL(后文都以SBL来指代Intel® Slim Bootloader),是Intel推出的一款Bootloader,关于它的完整介绍可以在如下的网站找到:https://www.intel.com/content/www/us/en/design/products-and-solutions/technologies/slim-bootloader/overview.html,可以认为它是Intel版的coreboot,在平台支持、安全、可扩展方面更偏向于x86平台,其特性如下:

并且它支持各种常用的操作系统,而且还是开源的(使用BSD许可)。

源码下载

SBL的源代码可以在https://github.com/slimbootloader/slimbootloader下载到,另外在Gitee上也有镜像,地址是https://gitee.com/jiangwei0512/slimbootloader

由于SBL版本一直在进化,因此代码可能会因为更新而导致差异,请以实际下载到的代码为准。当前使用的版本:

下载到的源代码目录结构如下:

下面简单说明其中主要的文件或目录:

文件或目录说明
BaseTools生成SBL二进制实际使用的工具,它由一部分工具位于BootloaderCorePkg\\Tools。
BootloaderCommonPkg包含通用的库函数供SBL使用。
BootloaderCorePkgSBL将启动分为几个不同的阶段,它们的主体代码包含在这个目录下:
Stage1A:最起始的阶段,跨度从Reset Vector开始到Case As RAM(CAR)设置好为止,它会调用FSP-T;
Stage1B:从CAR设置后开始到内存初始化完成为止,它会调用FSP-M;
Stage2:进行其它的平台初始化(内存之外的CPU、Chipset相关的初始化),并跳转到Payload,它会调用FSP-S。
IntelFsp2PkgFSP支持包。
MdePkgEDKII通用代码。
PayloadPkg包含加载OS、升级固件的代码。
Platform平台支持的代码。
SiliconSOC支持代码。
BuildLoader.py生成Slim Bootloader二进制使用的脚本,它会进行编译链的设置,预编译,编译以及编译完成之后的其它操作。

SBL的代码组织逻辑是为了保持模块的独立性和可扩展性,以下的要求必须得到保证:

  1. BootloaderCorePkg和PayloadPkg两者应该是独立的,互不相干;
  2. PayloadPkg的代码不应该依赖于Platform或者Silicon;
  3. PayloadPkg只应该依赖于BootloaderCommonPkg。

构建SBL二进制

这里使用Windows10进行SBL的构建,通常情况下Windows下编译生成的二进制要比使用GCC要小,且对于Intel平台来说,Windows下的UEFI开发更常见,这是使用Windows的原因。

SBL使用Python脚本BuildLoader.py来完成整个构建过程,目前的SBL版本使用的是Python3版本,所以需要安装Python3并将执行路径放到环境变量中:

版本信息如下(Ctrl+z + Enter退出Python界面):

之后通过执行BuildLoader.py脚本可以看到使用方式:

构建SBL二进制使用的命令是(上图中没有指定XXX所以报错了):

BuildLoader.py build XXX

XXX指的是目标平台,可以通过查看Platform\\xxxBoardPkg\\BoardConfig.py中的self.BOARD_NAME来确定,比如本例构建QEMU使用的SBL二进制,对应的是Platform\\QemuBoardPkg\\BoardConfig.py,其中的self.BOARD_NAME的值如下:

self.BOARD_NAME           = 'qemu'

所以真正的构建指令是:

BuildLoader.py build qemu

执行结果如下:

BuildLoader.py会检查依赖的工具及其版本信息,所以整个图很重要,需要在当前的Windows环境下安装上述的工具,因为本机之前用于UEFI开发,所以大部分工具都是有的,只不过openssl、iasl和Visual Studio的版本并不满足要求。其中openssl可以在https://sourceforge.net/projects/openssl-for-windows/下载到最新的版本,iasl可以在https://www.acpica.org/downloads/binary-tools下载到最新版本,Visual Studio需要使用2015以上版本,这里选择2019版本,可以在官网下载并在线安装,需要注意的是安装时需要选择如下的内容:

这里可以保证SBL编译需要的工具(比如cl.exe等)能够被正确安装,再次执行编译命令,得到的结果如下:

可以看到工具检测已经通过了,不过最终还是会报错:

前面的内容是构建BaseTools中的编译工具,可以看到是完成了,之后再构建SBL二进制之前还有一步操作来生成秘钥,使用的命令是:

F:\\Gitee\\slimbootloader>BootloaderCorePkg\\Tools\\GenerateKeys.py -k ..\\SblKeys

主要这里特别写明了执行命令时所在的目录,原因在于SBL默认会在于其所在目录同层的位置放置秘钥,对应的目录名默认是SblKeys,执行命令之后生成如下的秘钥:

之后再执行前面的构建命令,就可以成功完成构建:

生成的二进制位于Build\\BootloaderCorePkg\\DEBUG_VS2019\\FV,名称是SlimBootloader.bin

使用

因为构建的是QEMU上用的SBL二进制,因此要使用的话就直接通过QEMU命令启动即可,当然QEMU需要额外安装,可以在https://www.qemu.org/download/下载到。使用命令如下:

qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Build\\BootloaderCorePkg\\DEBUG_VS2019\\FV\\SlimBootloader.bin

这里贴出执行结果:

F:\\Gitee\\slimbootloader>qemu-system-x86_64 -machine q35 -nographic -serial mon:stdio -pflash Build\\BootloaderCorePkg\\DEBUG_VS2019\\FV\\SlimBootloader.bin
WARNING: Image format was not specified for 'Build\\BootloaderCorePkg\\DEBUG_VS2019\\FV\\SlimBootloader.bin' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.

============= Intel Slim Bootloader STAGE1A =============
SBID: SB_QEMU
ISVN: 001
IVER: 001.000.001.001.03646
SVER: 7F461C59E0D513D9
FDBG: BLD(D IA32) FSP(R)
FSPV: ID($QEMFSP$) REV(00001000)
Loader global data @ 0x00001C38
Run  STAGE1A @ 0x00070000
Load STAGE1B @ 0x00040000
HASH verification for usage (0x00000001) with Hash Alg (0x2): Success

============= Intel Slim Bootloader STAGE1B =============
Host Bridge Device ID:0x29C0
Board ID:0x1 - Loading QEMU!
QEMU Flash: Attempting flash detection at FFC00000
QemuFlashDetected => FD behaves as FLASH
QemuFlashDetected => Yes
SpiInstance = 0000E470
Variable region: 0xFFCA0000:0x2000
  SPI WRITE: FFCA0010  00000004
  SPI WRITE: FFCA0011  00000001
  SPI WRITE: FFCA0014  00000008
  SPI WRITE: FFCA001C  00000004
  SPI WRITE: FFCA0011  00000001
Loading Component KEYH:_HS_
Registering container KEYH
HASH verification for usage (0x00000100) with Hash Alg (0x2): Success
SignType (0x2) SignSize (0x180)  SignHashAlg (0x2)
RSA verification for usage (0x00000100): Success
HASH verification for usage (0x00000000) with Hash Alg (0x2): Success
Append public key hash into store: Success
Load EXT CFG Data @ 0x0000EB54:0x0158 ... Success
HASH verification for usage (0x00000200) with Hash Alg (0x2): Success
SignType (0x2) SignSize (0x180)  SignHashAlg (0x2)
RSA verification for usage (0x00000200): Success
BOOT: BP0
MODE: 0
BoardID: 0x01
PlatformName: QEMU_01
Memory Init
Found Config TAG: 0x180 @ 0x0000ECCC
  MemCfg.Test1=11223344, MemCfg.Test2=11223346
Found Config TAG: 0x200 @ 0x0000ECDC
  SilCfg.Test1=11223347, SilCfg.Test2=04030201
Call FspMemoryInit ... Success
Loader global data @ 0x06EBFD70
Load page table from memory @ 0x06B74000
Remapping Stage to 0x06B77000
    FSP Resource HOB Range        Type       Owner
================================= ==== ====================================
0000000000000000-00000000000A0000  00  00000000-0000-0000-0000-000000000000
00000000000A0000-0000000000100000  05  00000000-0000-0000-0000-000000000000
0000000000100000-0000000006F00000  00  00000000-0000-0000-0000-000000000000
0000000006F00000-0000000007000000  05  69A79759-1373-4367-A6C4-C7F59EFD986E
0000000007000000-0000000008000000  05  D038747C-D00C-4980-B319-490199A47D55

Switch to memory stack @ 0x06EFFF00
Stage1 stack: 0x2000 (0xF28 used)
Stage1 heap: 0xE000 (0x1F14 used)
Call FspTempRamExit ... Success
Memory FSP @ 0x06F00000
Memory TOP @ 0x06B74000
Loading Component FLMP:SG02
HASH verification for usage (0x00000002) with Hash Alg (0x2): Success
Loaded STAGE2 @ 0x06E55000

============= Intel Slim Bootloader STAGE2 =============
Unmapping Stage
Board GPIO Init
Get base platform GPIO table from board ID 0
Programming 7 GPIO entries
GPIO GPP_A00 DATA: 0x00000000 0x00000010
GPIO GPP_A02 DATA: 0x80000002 0x00000012
GPIO GPP_A03 DATA: 0xC0000003 0x00000013
GPIO GPP_A04 DATA: 0x01000004 0x00000014
GPIO GPP_A05 DATA: 0x41000005 0x00000015
GPIO GPP_A06 DATA: 0x81000006 0x00000016
GPIO GPP_A07 DATA: 0xC1000007 0x00000017
Test variable services
  SPI WRITE: FFCA0020  00000004
  SPI WRITE: FFCA0021  00000001
  SPI WRITE: FFCA0024  00000008
  SPI WRITE: FFCA002C  00000004
  SPI WRITE: FFCA0011  00000001
  SPI WRITE: FFCA0021  00000001
  SPI WRITE: FFCA0011  00000001
Loading Component IPFW:TST3
Registering container IPFW
HASH verification for usage (0x00001000) with Hash Alg (0x2): Success
SignType (0x2) SignSize (0x180)  SignHashAlg (0x2)
RSA verification for usage (0x00001000): Success
HASH verification for usage (0x00000000) with Hash Alg (0x2): Success
SignType (0x2) SignSize (0x180)  SignHashAlg (0x2)
RSA verification for usage (0x00000000): Success
Load IP firmware @ 0:0x0 - Bad Buffer Size
Silicon Init
Select VBT ImageId 0x00000001
Call FspSiliconInit ...
Success
Graphics Info: 800 x 600 x 32 @ 0x80000000
MEM: 0000000000000000 00000000000A0000 00 1
MEM: 00000000000A0000 0000000000060000 00 2
MEM: 0000000000100000 0000000006A00000 00 1
MEM: 0000000006B00000 0000000000004000 01 2
MEM: 0000000006B04000 0000000000068000 00 3
MEM: 0000000006B6C000 0000000000008000 00 4
MEM: 0000000006B74000 000000000038C000 00 2
MEM: 0000000006F00000 0000000000100000 00 2
MEM: 0000000007000000 0000000001000000 00 2
MEM: 00000000FFC00000 0000000000400000 00 2
MP Init (Wakeup)
MP Init (Run)
Detected 1 CPU threads
 CPU  0 APIC ID: 0
SMM rebase done on 1 CPUs
PCI Enum
Call FspNotifyPhase(20) ... Success
ACPI Init
Publish ACPI table: FACP
Publish ACPI table: HPET
Publish ACPI table: APIC
Publish ACPI table: MCFG
Publish ACPI table: FPDT
Publish ACPI table: BGRT
Publish ACPI table: TEST
ACPI Ret: Success
Enable SMRR
Loading Payload ID PYLD
Loading Component FLMP:PYLD
HASH verification for usage (0x00000004) with Hash Alg (0x2): Success
Load Payload ID 0x00000000 @ 0x06CB7000
PE32 Format Payload
HOB @ 0x06EC0000
Created 4 OS boot options (Current: 0)
Stage2 stack: 0x40000 (stack used 0x9CC, HOB used 0xFB0, 0x3E684 free)
Stage2 heap: 0x34C000 (0x209000 used, 0x143000 free)
Payload entry: 0x06CB7260
Jump to payload


Payload startup
ACPI PmTimer Base: 0x408
PCI Express  Base: 0xE0000000


====================Os Loader====================


Press any key within 1 second(s) to enter the command shell
Boot options (in HEX):

Idx|ImgType|DevType|DevNum|Flags|HwPart|FsType|SwPart|File/Lbaoffset
  0|      0|    SD |    0 |   0 |    0 | AUTO |    0 | iasimage.bin
  1|      0|  SATA |    0 |   0 |   FF | AUTO |    0 | iasimage.bin
  2|      0|  NVME |    0 |   0 |    0 | AUTO |    0 | iasimage.bin
  3|      0|   USB |    0 |   0 |    0 | AUTO |    0 | iasimage.bin


======== Try Booting with Boot Option 0 ========
BootMediumPciBase(0x300)
Getting boot image from SD
MMC global data init
Use SDMA instead of ADMA2
MMC Phase 1 init
SdMmcHcReset: reset done with Time out
SdMmcHcReset Fail Status = 0x80000012
Failed to init media - Time out
Failed to Initialize Boot Device - Type 1, Instance 0
Payload normal heap: 0x2000000 (0xB000 used)
Payload reserved heap: 0x4000 (0x0 used)
Payload stack: 0x10000 (0x4D4 used)


======== Try Booting with Boot Option 1 ========
BootMediumPciBase(0x1F02)
Getting boot image from SATA
Init AHCI controller E00FA000
AHCI port [2] has a [cdrom]
Try to find boot partition
AhciDeviceRead Status = Device Error
Partition type: UNKNOWN  (1 logical partitions)
Find partition success
Init File system
AhciDeviceRead Status = Device Error
AhciDeviceRead Status = Device Error
No partitions found, Status = Device Error
Failed to Initialize Boot File System - SwPart 0
Payload normal heap: 0x2000000 (0x10F000 used)
Payload reserved heap: 0x4000 (0x0 used)
Payload stack: 0x10000 (0x664 used)

Deinit AHCI controller 0
Not a AHCI controller or Disabled

======== Try Booting with Boot Option 2 ========
BootMediumPciBase(0x300)
Getting boot image from NVME
NvmExpressDriverBindingStart: start
NvmeControllerInit: the controller doesn't support NVMe command set
NvmExpressDriverBindingStart: end with Unsupported
Failed to init media - Unsupported
Failed to Initialize Boot Device - Type 6, Instance 0
Payload normal heap: 0x2000000 (0x10F000 used)
Payload reserved heap: 0x4000 (0x0 used)
Payload stack: 0x10000 (0x664 used)


======== Try Booting with Boot Option 3 ========
BootMediumPciBase(0x400)
Getting boot image from USB
Failed to initialize USB bus !
Failed to init media - Unsupported
Failed to Initialize Boot Device - Type 5, Instance 0
Payload normal heap: 0x2000000 (0x10F000 used)
Payload reserved heap: 0x4000 (0x0 used)
Payload stack: 0x10000 (0x664 used)


Shell>

最终进入到了UEFI Shell。

以上是关于UEFI实战SlimBootloader使用的主要内容,如果未能解决你的问题,请参考以下文章

UEFI实战SlimBootloader使用

UEFI实战SlimBootloader代码流程分析

UEFI实战SlimBootloader定制化

UEFI实战SlimBootloader定制化

UEFI实战SlimBootloader中的构建脚本BuildLoader.py

UEFI实战SlimBootloader中调用FSP