在了解iOS设备系统启动流程之前,我们先来了解一下传统的计算机系统是如何启动的。计算机系统的启动分为前后两个过程,先是底层硬件固件程序的运行以加载操作系统的内核,后是操作系统接管之后的相关进程启动过程。
传统计算机系统启动
大部分PC引导使用BIOS(Basic Input Output System),计算机通电后第一件事即读取运行ROM芯片中的BIOS程序。BIOS做的第一件事是硬件自检,检测计算机硬件是否正常,若有问题,则驱动主板发出蜂鸣,并中止启动。硬件自检没有问题后,BIOS则按照“启动顺序”找到第一个可用于启动的储存设备。判断标准即读取存储设备最前面512个字节,如果其最后两个字节是0x55
和0xAA
,即表明设备可用于启动。这512个字节也叫“主引导记录(Master Boot Record,MBR)”,保存了几乎所有分区和引导逻辑。
BIOS将控制权交给MBR后,MBR通过分区表找到操作系统加载器代码,并将控制权交给加载器。紧接着,操作系统的内核被载入,以Linux为例,即载入./boot
目录下的内核文件。内核载入成功后,开始运行第一个程序./sbin/init
,用于初始化系统环境。由于init
是第一个运行程序,它的PID
即为1,其它进程都是从它衍生出来的后代。init
运行起来后,负责加载运行各种开机启动程序(守护进程),直到执行./bin/login
程序,整个系统才算启动完成。
诸如运行Windows和Linux系统的计算机,都使用了传统的BIOS进行引导,然而,BIOS存在很多局限性。比如,BIOS只能访问大约1MB的内存,无法和现在强大的图形设备进行接口操作,无可扩展性,另外,它还和MBR分区方案紧密耦合,只允许磁盘上有4个可引导分区。正因为这些局限性,苹果在OS X上采用了一种更新的32位/64位兼容标准——可扩展固件接口(Extensible Firmware Interface, EFI)。EFI最早由Intel发起,是一个全功能的运行时系统,引导期间提供了更为强大的接口。但苹果也只在OS X上使用了EFI,而i系列设备都不支持EFI,所以在此就不过多了解。
iOS设备系统启动
苹果在iOS上的引导与OS X完全不同,它属于苹果自创的一套引导流程,这也为避免一些恶意黑客越狱者在苹果移动设备上安装其它操作系统(可是理想是美好的,现实很残酷)。尽管iOS的引导也没有使用BIOS,但计算机系统启动本质上的原理差不多,因此了解了一般计算机系统的引导,再来理解iOS的引导也就不难了。
iOS的启动引导分为三种模式,分别是正常模式引导、恢复模式引导以及固件更新模式引导。恢复模式引导在正常模式引导失败后会进入,固件更新模式在iOS系统升级或者越狱时会使用,这里描述一下正常开机启动的正常模式引导。
当按下电源键后,如果没有其它用户交互,iOS设备正常启动将经历以下几个过程:
引导ROM > LLB > iBoot > 加载内核 > 启动launchd > 启动守护程序和代理程序
上述步骤中一直到内核的加载,除了引导ROM,其它步骤都被加密及数字签名。
引导ROM负责初始化设备,并加载底层引导加载器(Low Level Bootloader,LLB)。ROM属于设备的一部分,所以没法更新。这样的好处就是没法逆向,但是一旦ROM中有缺陷也没法以更新的方式来修正。诸如,苹果早期使用A5芯片之前的i系列设备,其引导ROM就存在严重漏洞,黑客利用这个漏洞可绕过苹果签名并上传自定义镜像,实现设备的完美越狱,设备即可被安装上了Android系统。直到A5使用了新的ROM,才对这一缺陷打了补丁。
LLB负责定位并加载iBoot,如果查找iBoot失败,LLB将放弃加载并切换到固件更新模式引导。LLB是iOS的一部分,不属于设备本身,它和iOS镜像中的其它文件一样,是被加密的IMG3格式文件。
iBoot才是引导过程中的主加载器,它负责加载操作系统内核。iBoot在内存中被加载至地址0x5FF00000处。它有一个内建的HFS+驱动,可以直接访问iOS的文件系统,并支持多线程。iBoot通常会派生出两个线程,一个“main”线程,负责显示启动时的苹果logo,并根据auto-boot和boot-command环境变量的设置(正常引导模式下boot-command被设为fsboot)进行系统引导,引导过程可以根据bootdelay环境变量延迟进行;一个是“uart reader”线程,苹果可能将这个线程用于调试,其基本处于闲置状态。正常引导模式中,iBoot调用fsboot()函数挂载iOS系统分区,定位内核,准备设备数并引导系统,如果引导失败,则进入恢复模式引导。
内核载入后,将启动第一个程序launchd
,launchd
相当于上述Linux系统的init
程序,然后,由launchd
启动守护程序和代理程序,直到桌面应用SpringBoard
运行,系统算启动完成。主流程上和Linux类似,但细节上有很多不同,关于launchd
启动后的详细情况,见后续文章梳理。
网友评论