Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13672
  • 博文数量: 5
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-30 23:56
个人简介

于无声处鸭子听雷

文章分类

全部博文(5)

文章存档

2015年(3)

2014年(2)

最近访客

分类: 系统运维

2014-12-23 11:23:52


        UEFI+GPT现在基本逐步取代了传统的BIOS+MBR启动,但因为大多数主板都兼容传统BIOS启动,所以大家对它的认识都比较晚,存在很多错误的理解。针对这些谈下我的认识,BIOS和MBR大家都很熟悉了,所以主要说UEFI+GPT及和BIOS+MBR的区别:
     
        一、关于UEFI的错误认识

       1、UEFI和BIOS一样是设备的固件(firmware),存在于设备的ROM内存中,不在你的硬盘上。你修改的启动配置文件是操作系统的boot loader的配置文件,是属于你操作系统的启动文件,具体是哪一种取决于你的操作系统和选用的引导程序,严格说它并不属于固件范畴中,只是能被固件识别并加以引导的一类脚本,我们对UEFI和BIOS,只能设置少数几个启动参数,如告诉你想从哪个盘开始启动,是否选用安全启动等,这些设置并不能修改固件本身。
       2、UEFI是EFI的扩大和发展,并不是不同的版本,不存在兼容的问题。BIOS最早是IBM采用的,然后在世界行业范围内得到了使用,但BIOS并没有统一规范,它是一个事实标准。EFI是Intel公司最早开发的,而不是微软公司,先后有 140多个硬件开发生产商,操作系统开发公司等加入了UEFI论坛,并一同制定了现在的UEFI标准,U是英文单词Unified的开头字母,代表是统一的技术标准,固件上一般都是标注支持UEFI,而操作系统中的EFI启动文件,是UEFI的可执行程序,UEFI现在不属于任何一家公司。
         3、UEFI开发的目标是要取代BIOS的,从而来弥补一些BIOS启动方式的缺陷,所以UEFI是UEFI,BIOS是BIOS,UEFI BIOS的叫法是根本就不存在的。这个错误认识我想是因为很多人在描述UEFI时,都用传统BIOS启动来对比,结果很多人就理解成为UEFI是现代的BIOS启动,这个传统是修饰启动的,不是修饰BIOS的
         4、你的电脑可以选择BIOS还是UEFI方式启动,但是你的固件一定是UEFI的,这是因为一些UEFI固件实现了某种兼容BIOS启动(有时候称为CSM),它可以像BIOS一样启动然后去查找磁盘的MBR,然后从MBR中执行启动装载,接着将后续工作完全交给启动装载程序,人们误以为这是禁用了UEFI而采用了BIOS启动,这种说法是完全错误的,固件的功能是无法禁止的,这是UEFI固件的一个功能,以“BIOS风格”启动,而不是采用原生的UEFI启动。
           5、MBR分区采用的是ms-dos分区表,GPT分区采用的Guid分区表。GPT分区是为了扩展磁盘数据量的不是为UEFI设计的,UEFI为了解决多重启动管理的不是为GPT分区设计的。UEFI可以使用GPT分区,也兼容MBR分区,但操作系统一定要支持UEFI。BIOS就只能用MBR分区,操作系统没有不支持BIOS启动的。32位和64位架构的计算机都能使用UEFI启动,不能使用,是因为你用的是windows它不支持。

         二、UEFI和BIOS的区别

        BIOS的启动大家都很熟悉,但为了说明问题,还是简单在这描述下
        BIOS+MBR启动应该说一个很奇葩的东西,但哪个时代比较有局限性,我们也无可厚非。计算机加电启动后,BIOS开始枚举设备等进行自检,然后根据设定去某个磁盘的初始位置的一小部分空间(也就是MBR)上寻找一小段它可以识别并启动的代码boot loader,这时候BIOS就退出内存仅留一些中断信息等,然后由boot loader去执行操作系统启动。
        MBR位于硬盘的0柱面、0磁头、1扇区称为主引导扇区(也叫主引导记录MBR)。MBR一共只有512字节,硬盘分区表DPT占64字节,结束标志字55AA占两字节,boot loader占剩余的446字节
         整个启动过程,BIOS只负责枚举硬件自检和寻找引导boot loader,至于什么磁盘分区,还有操作系统,它是没有任何概念的。这其中存在几个问题:
        1)MBR是通过特殊工具写入的,你要想检查和修改MBR内容是很麻烦的,而且它是汇编语言写的
        2)MBR的空间是不足以容纳整个启动加载程序的,所以启动加载程序都是把自己的一部分信息放入MBR,其它部分放在MBR末尾和第一分区开始的这部分磁盘空间里。但是第一分区究竟从磁盘的什么位置开始并没有一个成文的规定,但可以肯定的是对于现在操作系统启动加载程序这部分空间都是不够用的(这也是为什么windows分区时候第一分区是从2048扇区开始的原因),通常是通过多段启动来解决这个问题的,这个不做具体描述
         3)如果用户想选择启动多个目标,比如说多重操作系统,在BIOS+MBR这种组合启动方式中实现,只能由boot loader去处理,这个可以有很多种办法实现,但是它们无法彼此协作, 而且也都不是获得广泛认可的标准或规定。而在操作系统/操作系统安装层编写工具的难度很大,无法干净利落地处理多重启动。因此这种设计非常混乱;
          4)BIOS固件层以上的其他层无法配置固件的启动行为,BIOS 没有提供相应机制。

          下面,我们再来看UEFI+GPT的启动机制
           在UEFI规范中定义了一种可执行文件格式,并要求所有 UEFI 固件能够执行此格式的代码。当开发人员为原生 UEFI 编写启动装载程序时,就必须按照这种格式编写。这种设计非常简洁直观,也无需进一步解释
          GPT分区仅仅在磁盘起始位置的信息定义了磁盘所包含的分区并且 UEFI 规范要求 UEFI 兼容固件必须能识别 GPT也要求固件能识别 MBR,以保证向后兼容
           UEFI启动要求系统分出一个独立的ESP分区作为EFI系统分区,EFI分区就是为了解决MBR分区无法容纳启动加载程序所产生的问题的,那些认为EFI分区可有可无的人,完全就是没有理解UEFI启动的原理。我们来看下UEFI规范的具体规定:
        “可扩展固件接口 (EFI) 支持的文件系统基于 FAT 文件系统。EFI 定义了可以明确记录和测试的具体 FAT 版本。FAT 的唯一定义必须符合 EFI 规范及关联参考文档,对 FAT 唯一定义的实现必须支持 EFI。为区分 EFI 文件系统与纯 FAT,定义了新的分区文件系统类型。”
         EFI 系统分区是采用 FAT 变种(UEFI 规范定义的变种之一)格式化的任意分区,该分区被赋予特定 GPT 分区类型,以帮助UEFI固件识别该分区。此分区的目的如上所述:固件层确实可以读取“普通”磁盘分区中的数据。操作系统可以 创建、格式化和挂载分区(采用广泛理解的格式),并将启动装载程序的代码和固件可能需要读取的所有其他内容放到这个分区中,而不用像 MBR 磁盘一样,将启动装载程序的代码写入磁盘的起始位置空间。
        相比于BIOS,UEFI建立了更多基础功能的机制,通过这种机制,固件可以查找各种可能的启动目标,并提供相应的配置方法。包括以下几个方面:
  • 读取分区表
  • 访问某些特定文件系统中的文件
  • 执行特定格式的代码
       下面我们来看下,UEFI是如何实现这些功能的:
        UEFI 规范定义了名为 UEFI 启动管理器的一项功能(Linux发行版包含名为efibootmgr 的工具,可用于更改 UEFI 启动管理器的配置)
      

        “UEFI 启动管理器是一种固件策略引擎,可通过修改固件架构中定义的全局NVRAM 变量来进行配置。启动管理器将尝试按全局 NVRAM 变量定义的顺序依次加载 UEFI 驱动和 UEFI 应用程序(包括 UEFI 操作系统启动装载程序)。”
       对于UEFI启动管理器我们可以简单的把它看作是一个启动菜单,你可以向“启动菜单”添加项或者从中删除项。固件也可以(事实上, UEFI 规范也有此要求)根据连接到计算机的磁盘或根据某些固件配置,在此启动菜单中“生成”有效项。你也可以检查启动菜单,确保正确无误。

    
           我的笔记本上只装了一套系统,没办法给大家演示多重启动系统的操作,简单做了一个启动超时的设置,说明下UEFI管理器的方便之处。
           我在别处找了一个Fedora的efibootmgr输出,来看看具体实例:

           

           由此实例可以看出, 如果你有多重操作系统,BootOrder会按照你设置的顺序启动,0003 0002 0000 0004,BootCurrent显示的是启动的“启动菜单”中的哪一项,如果我们不做任何配置的话,UEFI会按照启动菜单顺序依次尝试启动,这些启 动项可以是系统,也可以是EFI设备,如CD Drive Hard Drive等,但不是所有EFI设备都可以执行启动,象我们知道显卡也有类似的固件,但肯定是无法启 动系统的。重要的在UEFI启动菜单中还有PXE服务器远程启动,显然UEFI的启动方式已经不局限于本地磁盘。在此实例中,我们也看到了UEFI是如何兼容BIOS启动的,0000和0004启动项都是以兼容BIOS模式启动的。
         我们再来看Boot0002和Boot0003这两个原生UEFI启动项,可以看出,UEFI原生启动不是以从某磁盘启动为标识,而是和可以在同一磁盘的不同位置进行启动,就是说在特定磁盘的特定位置执行启动加载程序。本实例中,两个操作系统的启动加载程序都位于同一个ESP分区的EFI目录下,如果你愿意和需要,你可以放十个,二十个,然后通过efibootmgr来管理启动菜单,现在你还觉得ESP分区可有可无吗?
         下面,我们再来说一下,原生UEFI的回退路径(Fallback Path)机制:
         还以上面的实例说明,我们设置一个Boot0001启动项,我们只制定这个启动项要启动那一个磁盘,并不给予它启动程序位置等信息,UEFI会怎么操作呢?其实很简单,UEFI会进行磁盘分区顺序遍历EFI系统分区,在 ESP 内,固件将查找位于特定位置的具有特定名称的文件。在 x86-64 PC 上,固件会查找文件 \EFI\BOOT\BOOTx64.EFI。固件实际查找的是 \EFI\BOOT\BOOT{计算机类型简称}.EFI,其中,“x64”是 x86-64 PC 的“计算机类型简称”。文件名还有可能是 BOOTIA32.EFI (x86-32)、BOOTIA64.EFI (Itanium)、BOOTARM.EFI(AArch32,即32位ARM)和 BOOTAA64.EFI(AArch64,即64位ARM)。直到固件找到的第一个可执行的有效文件
        这个机制的一个常见用途,就是用于启动LIVE CD或者是操作系统安装介质。对支持EFI启动操作系统安装时,由于一些朋友不熟悉操作,在安装完成后,发现UEFI并不去ESP或你想启动的分区去执行启动,出于对这种机制的了解,我们也可以想出一个小技巧,就是通过更改固定位置的EFI启动程序文件名,来迫使UEFI执行另一个你想使用的EFI启动程序,当然这是权宜之计,并不提倡的。
        好,我们现在以LINUX为例(windows这种怪胎是不好说明问题的)回顾下UEFI的启动过程
,整个UEFI虽然功能强大,但是远没有我们想的那么复杂,首先LINUX会创造一个EFI分区(如果之前不存在的话),使用相应配置将 EFI 启动装载程序(通常为 grub2-efi,但是也有例外)安装到 EFI 系统分区中的正确路径下,然后调用 efibootmgr 添加相应的 UEFI 启动管理器项(指向其启动装载程序),然后由gurb2-efi这类程序去执行加载内核等系统启动,多重启动由人工调用efibootmgr添加多个启动菜单项。
         通过上面说明看,UEFI确实操作很简单,但其中有一个问题,调用efibootmgr来管理UEFI启动菜单是在已有操作系统下进行的,而我们安装系统时候是通过固件的UI界面来进行设置的,也就是说你可以在操作系统中用efibootmgr来管理启动菜单,也能通过UI界面来更改efibootmgr,它们是交互作用的,有些固件设计的不合理,仅仅有抽象化的“CSM 启动”“UEFI启动”,如果你已有一套操作系统是兼容BIOS启动的,在你安装另一个UEFI原生启动的系统时,会在UI界面选择禁用BIOS兼容,固件会直接删除掉你原有的BIOS兼容启动设置。这也是一些人刚接触UEFI多重启动,总是发现自己另一套操作系统会消失的原因。
        请谨记,固件界面中的所有配置选项所执行的操作就是在后台配置 UEFI 启动管理器的行为。如果你能理解以上所有内容,那么当你更改固件界面中的选项时,你会更容易理解其背后的本质。
阅读(2003) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~