MAC OS X 技术内幕 学习笔记之四 MAC OS系统的启动引导

MAC OS X 技术内幕 学习笔记之四 MAC OS系统的启动引导

        MAC OS的启动非常快,同样的运行硬件环境,运行MAC系统感觉比运行windows系统要快不少。在使用笔记本时,同样的电池容量,运行MAC的使用时间,要比运行windows待机时间要长。这其中有很多原因,包括操作系统对CPU、内存、存储的调用使用的机制等,导致耗损电量也不一样,本系列教程后面会写专门的文章进行探讨,本文这里先在启动方式上,做一个说明和探讨。

一.启动方式上BIOS 和EFI 的区别

     BIOS是一个固定的程序,通常都是封闭的,程序在机器出厂时,将BIOS程序烧死在芯片中;

     EFI 是一套接口,像是一个运行时环境,规范了一组应用程序编程接口,基于EFI 的程序可以利用这些接口实现相应的功能。

     市场上大部分的PC 机使用BIOS 进行引导,如weindows系统的机器都是基于BIOS引导的。而苹果公司的Mac OS X使用则使用EFI 进行引导,究其使用的目的都是一样的,通过加载一些自举程序代码给CPU执行,由自举程序负责POST(上电自检)阶段,CPU探测各种硬件总线,检测出机器安装了哪些设备,然后由BIOS或固件定位这些引导设备,执行引导加载程序,将所有必要的命令行参数传递给操作系统内核。

       固件接口(EFI),包括用户接口和处理器接口,比BIOS 更为丰富,相比之下,使用BIOS存在很多局限性:如:

       (1)分区方案不扩展;

      (2)无法和强大的图形设备进行接口操作;

      (3)没有可扩展性,没有插件式的驱动程。

     既然存在这么多的异同点,关于BIOS的资料也已经很多了,本文下面的部分重点对EFI方面内容进行介绍。

二.EFI服务分类

     EFI服务分为两类:引导服务和运行时服务。其中引导服务只能在FEI模式下使用,而运行时服务在退出EFI模式,在加载操作系统以后也能使用。

        引导服务:通常情况下,当控制权转交到操作系统之前会调用ExitBootServices()这个函数,当系统还在EFI环境中,并且在还没有调用ExitBootServices()函数之前,就可以访问引导服务。引导环境提供的内容很丰富,支持带抢占的多任务、事务通知、内存管理以及硬件访问等。尤其重要的服务就是提供对硬件的访问,EFI定义了协议的概念,协议封装了和某个特定设备或某一类设备相关的API,每个协议都定义了一个128位的GUID ,在运行时服务中也可以获得这些协议。

       运行时服务:运行时服务可以在系统处于EFI模式的时候使用,在运行时服务在退出EFI模式后仍然可以使用,也就是说在操作系统加载以后也可以访问这些服务。因为运行时服务不能提供引导服务提供的服务以及任何直接控制设备的服务,所以他提供的服务范围比较窄,包括系统时间以及NVRAM中保存的变量的访问。运行时服务中,可以利用nvram命令在命令行和EFI服务进行通信,通过系统调用访问I/O Kit的nvram驱动程序。nvram在系统引导的时候使用,还负责保存一些需要在重新引导之间持久化数据。NVRAM变量是环境变量的功能,它是在系统范围内的,操作系统和固件都可以对其进行访问。

三.Boot.efi的引导执行流程

     可以通过文件命令:od -A x -t x4 /System/Library/CoreServices/boot.efi,进行内容查看。

      整个执行流程内容很多,分多个步骤:

      (1)获得EFI服务指针,查询CPUID,即获得指向EFI运行时服务的指针并保存在全局变量中,然后通过汇编指令检查CPU是否有AESNI这一位(表示是否支持AES-NI指令,用于加速AES加密标准的计算)。

     (2) IntializeIConsole,通过RumTimeServices指针查询NVRAM变量Background clear,然后,在调用LocateProtocol()CONSOLE_CONTROL_PROTOCOL 之后,调用协议的GetMode()获得当前的控制台模式。

       (3)在Lion这个版本的操作系统中,调用一个苹果自有的协议,传入Mac OS X10.7参数,并且获得/设置APPLE_VENDOR_NVRAM_GUID下的ROM和MLB变量。

     (4) 初始化系统上设备的层次树形结构,设备树,之后会将设备树以参数结构中一个成员的形式传入内核。对于XNU内核并不关心这个device tree,但是IOKit子系统严重依赖于这个结构。查看设备树的命令:ioreg -w 0 -l -p IODeviceTree | grep -v \``IO

       (5) 位内核调用门分配内存。内核需要从引导设备加载到内存中,所以要分配好内存。内存调用门的地址保存在全局变量中。

       (6)  一些其他初始化操作

       (7)检查休眠恢复,CheckHibernate函数负责将系统从休眠状态恢复,若确实从休眠中恢复,不必进过下面剩下的步骤。

    (8) 处理引导时的按键。ProcessOptions是引导加载器中一个关键的函数,负责识别出各种引导选项,并且最终将这些选项整合到内核命令行参数中。ProcessOptions使用的主要文件是com.apple.Boot.plist.这个文件在/System/Preferences/SystemConfiguration目录下,是boot.efi使用的主要属性列表文件。

   (9)确认CPU是否支持64位模式(Lion才需要)

    (10)在Lion版开始引入了对CoreStorage的支持,CoreGtorage是苹果的逻辑卷分区机制。如果检查到了CoreStorge,那么引导加载器会获得分区ID和EFI句柄,然后调用LoadCoreStorageConfiguration()函数获得CoreStorage参数。

     (11) SetConsoleMode这个函数用来初始化为图形模式。

     (12) DrawBootGraphics绘制引导LOGO

      (13) LoadKernelCache这个函数负责定位和加载预先链接好的内核。

      (14) InitBootStruct命令分配并初始化引导数据结构,内核只接受一个参数,即一个指向引导数据结构的指针,引导数据结构只是一个巨大的数据结构,包含了内核需要的所有的参数,包括从命令行参数,到设备树和其他RFI相关的参数等内容。

    (15) LoadDrives 这个函数从/System/Library/Extensions.mkext中加载设备驱动程序kext到内核中。

      (16) LoadRamDisk,如果XUN加载了的时候指定了RAMDisk,这个函数负责将RAMDisk加载到内存中。

     (17) StopAnimation 结束EFI引导中的动画。

      (18) FinalizeBootStruct 这个函数最终完成要传给内核的引导数据结构,在返回之前,这个函数还负责退出引导服务。

     (19) 跳转到内核入口点 最后,Start函数尝试跳转到内核调用门。如果成功,永不返回,否则,返回8xxxx15h错误,然后睡眠10秒钟之后退出引导服务。

四.系统引导内核

    在加载了kerne lcache或内核本身之后,boot.efi引导流程结束退出引导服务,将控制权转交给内核。内核被传入包含BootStruct的页面的一个参数,该数据结构实在在boot.efi引导流程的最后阶段完成的,内核可以通过这个数据结构提取出所需要的数据。

五.内核对EFI的使用回调

       EFI的主要职责是加载内核,并不意味着加载完成以后,就没有用途了,而是内核仍然可以和EFI接口对接,继续调用EFI提供的运行时服务,运行时服务很少被用到。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jyl_sh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值