UEFI Secure Boot

linux的boot有一套流程:firware->media->bootloader->kernel(kernel module)->init

  • firmware发现可启动media,加载media(远程启动等)
  • bootloader从boot media加载kernel到RAM里,然后启动(会根据硬盘分区表之类的发现kernel,然后继续加载kernel module之类)
  • kernel会根据bootloader传递给kernel的指令去找到主文件系统
  • 启动文件系统中的init脚本

在第二步,uefi找到硬盘分区表后,发现文件系统,然后会开始加载kernel
如何加载,在按照系统时就已经确定好efi命令文件的路径,然后UEFI会执行这个程序
执行efibootmgr命令可以看到:

1
2
3
4
5
6
7
8
9
# efibootmgr -v
BootCurrent: 0004
Timeout: 5 seconds
BootOrder: 0001,0004,0000,0003,0002
Boot0000* EFI VMware Virtual IDE Hard Drive (IDE 0:0) ACPI(a0341d0,...
Boot0001* EFI VMware Virtual SATA CDROM Drive (1.0) ACPI(a0341d0,...
Boot0002* EFI Network ACPI(a0341d0,0)PCI(12,0)MAC(000c29cf6279,0)
Boot0003* EFI Internal Shell (Unsupported option) MM(b,bee94000,...
Boot0004* Red Hat Enterprise Linux HD(spec)File(\EFI\redhat\shim.efi)

对于readhat来说,efi相关文件结构如下.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# tree /boot/efi
+-- EFI
+-- BOOT
| +-- BOOTX64.EFI
| +-- fallback.efi
+-- redhat
+-- BOOT.CSV
+-- fonts
| +-- unicode.pf2
+-- gcdx64.efi
+-- grub.cfg
+-- grubx64.efi
+-- MokManager.efi
+-- shim.efi
+-- shim-redhat.efi

4 directories, 10 files

而当UEFI启动时,调用程序的流程是UEFI->shim.efi->grubx64.efi->grub.cfg

查看shim.efi里的十六进制信息,可以看到调用grubx64.efi的过程

1
# hexdump -C /boot/efi/EFI/redhat/shim.efi | egrep -i -C 2 'grub|g.r.u.b'

接着查看grubx64.efi

1
2
# strings /boot/efi/EFI/redhat/grubx64.efi | grep grub.cfg
%s/grub.cfg

到最后就到了执行grub的地方,或者叫做Grand Unified Boot Loader
GRUB访问文件系统,找到kernel文件,加载到内存,然后启动kernel,传入一系列参数
kernel需要知道如何找到root目录,才能加载各种库和配置文件等,但是前提是要加载各种驱动后才可以做接下来的操作

那么下一步就是加载/lib/modules下的内核模块了

参考一个中文对linux boot的简介: http://blog.jobbole.com/33224/