UEFI简介

https://en.opensuse.org/openSUSE:UEFI

2 关于UEFI

2.1 EFI标准简介

UEFI(Unified Extensible Firmware Interface)是一个新的工业标准,规定了一个预启动环境中的系统接口。UEFI会在电源加电之后以及操作系统完全加载之后控制系统。而且,UEFI也负责在系统提供的资源和运转中的系统之前提供接口。

换句话说,UEFI是用于取代和扩展旧的BIOS固件。

UEFI并不是一件全新的事物。Intel在90年代中期就开始了EFI/UEFI的相关工作,而一些厂商例如HP或者Apple早已提供了EFI的机器。不过,直到微软的windows8发布,UEFI才成为引导新的认证机器所必须的。

UEFI规范(http://www.uefi.org/specs/)是一份非常全面的文档,它包含了固件制造商必须提供的、可以为操作系统访问的所有的接口、变量和结构的定义。而Linux从2000年开始已经可以通过grub或者elilo提供EFI支持。

Secure boot是UEFI的一个扩展。UEFI的一个关键点就是它可以被扩展。UEFI有一个内部的虚拟机,其运行是独立于架构的。该标准接受为此虚拟机编译的特定二进制文件(EFI执行文件),并在次环境中执行。这些执行文件可以是设备驱动、应用程序或者UEFI标准的扩展。UEFI,在某种意义上说,像是计算机启动时运行的一个小型的操作系统,改操作系统的主要任务就是查找并加载另一个主力的操作系统。

2.2 GPT

UEFI改动的不止有固件,系统调用和接口。它也提议了一种新的硬盘分区结构。GUID分区表(GPT)将取代老式的主引导记录(MBR)方案。

MBR有一些重要的限制,比如主分区和逻辑分区的数量,分区的大小等。GPT解决了这些问题,现在我们可以有不超过128个的任意数量的分区,可寻址的磁盘空间达到128PB(1PB=1024TB),因此这种分区方式适合大硬盘。另外一个很重要的特性是GPT采用UUID来标识每一个分区,避免了分区标识的冲突。

如果安装程序检测到我们处于EFI模式,它就会创建GPT分区。但是一旦使用了GPT分区,我们就不能在创建、删除和编译旧的分区类型。GPT采用gdisk来取代fdisk的功能,二者的方法是类似的。

2.3 EFI系统分区

EFI系统分区(ESP)是一个放置EFI程序的地方。而EFI程序就是用来启动安装在设备上的操作系统的。同时。EFI也会查找启动时所用的设备驱动以及其他的在操作系统启动前所要运行的工具。

EFI分区采用FAT文件系统。如果之前已经安装过一个windows系统的话,就可以通过将Linux的EFI bootloader放在同一个分区并挂载到Linux的/boot/efi目录即可。

默认情况下,固件会去搜索/EFI/BOOT/bootx64.efi作为要装载和执行的EFI扩展来启动操作系统。而在Windows系统中,正确的EFI扩展位于/EFI/Microsoft/Boot/BCD.efi,openSUSE系统则是/EFI/opensuse/grubx64.efi(如果secure boot启动的话则是shim.efi)

2.4 启动管理器(Boot Manager)

如果选择一个正确的EFI扩展区load操作系统,EFI提供给用户一个内部的启动管理器。操作系统可以为自己创建一个新的入口,我们可以在开机时使用F9/F12键区launch启动管理器,并且列出所有的启动项,也可以通过efibootmgr工具区查询和编辑所有的启动项。例如,我们可以使用efibootmgr -v列出当前所有的启动项。

如果因为某些原因导致启动项消失,可以通过efibootmgr命令重新创建。例如

# efibootmgr -c -L "OS NAME" -l "\EFI\path\grubx64.efi"

2.5 EFI变量

UEFI指定了一个变量集,存储在固件的非可变区域。这些变量用于存储信息以及控制UEFI系统的行为。当我们使用启动管理器创建一个新的启动项的时候,或者当我们启动/禁用一个secure boot选项的时候,我们就会访问和修改这些变量的值。

我们可以通过sysfs直接查看访问这些变量。sysfs是kernel提供的一个虚拟文件系统,用于导出一些信息到用户空间中。我们可以在/sys/firmware/efi/vars/目录下找到这些变量。
举例来讲,我们可以通过下面命令查询最后一个启动项

$ hexdump -C /sys/firmware/efi/vars/Boot0007-*/data

3 关于Secure Boot

3.1 背景

UEFI secure boot是一种用来限制可以启动系统的二进制文件的方法。固件会只执行那些已知签署者的boot loader。在Secure boot X.509认证的上文中被标识的条目。

如今大部分的消费PC硬件都默认启用secure boot用来加载windows 8系统,因此这些固件就只认可微软签名boot loader。如果没有重新配置签名者列表也没有禁用secure boot,其他的bootloader就必须经过微软的签名。

3.2 openSUSE12.3中的实现

openSUSE 12.3在UEFI系统中的默认采用的bootloader是grub2.当处于secure boot模式时,还需要再额外使用一个名字叫”shim.efi”的boot loader,这时候固件会首先调用shim而不是grub2。shim才有微软的微软的认证以便固件能够辨认。而shim会辨认opensuse认证,这些认证用来签名grub2以及由grub2所引导的kernel。在Linux kernel加载之后,secure boot的scope便结束了。

为了像定制boot loader一样定制kernel,shim提供了一种方法去导入定制的签名。“MokManager”程序就是用于此目的的。当使用shim去装载一个没有被已知签署者(“well known entity”)签名的二进制文件时,它调用MokManager, MokManager会允许将一个认证导入已知签署者数据库。

3.2.1 如何启用/禁用Secure boot启动

在opensuse 12.3中,secure boot的支持仍然是作为专家项的,YaST安装程序不会启动探测secure boot是否启用。在安装过程中会提供一个选项供用户手动启动Secure Boot支持。开启该选项就需要安装shim.efi.在一个已经安装好的系统中启用/禁用secure boot,需要用到YaST的bootload模块。

3.2.2 如何判断系统是否启动/禁用secure boot

可以在Linux shell中,以root权限运行下列命令:

od -An -t u1 /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data

如果返回1则表明secure boot启用。不过有一些固件版本因为一些问题会在启用的情况下也返回0

3.2.3 启动一个定制的kernel

Secure Boot不会禁止你使用自己编译的kernel,不过你需要为他加上一个自己的签名并确保这个签名可以被firmware或者MOK知道。

  • 创建一个定制的 X.509 key并使用它做签名认证
    openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout key.asc -out cert.pem -nodes -days 666 -subj "/CN=$USER/"
  • 将key打包为PKCS#12结构
    openssl pkcs12 -export -inkey key.asc -in cert.pem -name kernel_cert -out cert.p12
  • 产生一个pesign使用的NSS数据库
    certutil -d . -N
  • 将key和包含认证的PKCS#12导入数据库
    pk12util -d . -i cert.p12
  • 签署kernel
    pesign -n . -c kernel_cert -i arch/x86/boot/bzImage -o vmlinuz.signed -s
  • 列出kernel image中的签名
    pesign -n . -S -i vmlinuz.signed

之后可以将kernel安装在/boot目录下。现在kernel已经有了一个定制签名,下一步就是将签名导入固件或者MOK

  • 将认证转换为DER格式用于导入到UEFI固件或者MOK
    openssl x509 -in cert.pem -outform der -out cert.der
  • 将认证copy到ESP以便访问
    sudo cp cert.der /boot/efi

由于opensuse 12.3中的mokutils是broken的,因此没有很便捷的方式自动launch MOK。下列过程描述了手动launch MOK的方法:

reboot
在grub菜单中键入c键
输入(假定ESP是hd上的gpt1)


chainloader (hd0,gpt1)/EFI/opensuse/MokManager.efi
boot

选择"Enroll key from disk"
指向cert.der文件然后enter
接下来就是enroll key的过程。按提示按'0'或者'y'来确认。

另外还有一些固件可以提供方法将新的key写入db

3.2.4 不是用vender提供的key启动机器

如果固件菜单提供选项,可以重置secure boot提供的key,你也可以自己安装新PK、KEK或者db而不需要微软的keys。将/usr/lib64/efi/shim-opensuse.der导入db使得opensuse内核启动就属于这种情况。
opensuse默认提供的shim是经微软和opensuse双签名的。有些固件版本可能不支持双签名。这种情况下可以安装/usr/lib64/efi/shim-opensuse.efi这个只有opensuse签名的efi文件来作为/boot/efi/EFI/opensuse/shum.efi.

3.3 词汇表

  • PK
    Platform Key。指硬件发布商提供的认证。如果要修改KEK就需要一个有效的PK
  • KEK
    Key Exchange Key. 更新签名数据库的时候需要
  • db
    签名数据库。包含了所有已知的二进制认证、签名及hash,只有能够被数据库验证的二进制文件才能被固件执行。一个有效的KEK签名需要更新签名数据库。
  • dbx
    相对于db,是禁止签名的数据库,也就是认证、签名和hash的黑名单。如果由二进制匹配这里的内容,就不会被固件执行,一个有效的KEK签名也需要更新Forbidden Signature Database.
  • MOK
    机器拥有者的key。由MokManager所使用的一个额外的认证数据库。MokManager可以使用户在启动阶段交互式的以更新MOKs。
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值