机器的启动过程是嵌入式软件开发的基础知识之一,之前课上学过一些,但是有些混乱,一些x86的启动过程和arm的启动过程知识混在一起,现在重新梳理一下。有助于之后理解和开发qemu设备。
x86架构启动过程
x86架构机器的启动过程可以分为以下几个主要阶段:
- 上电和CPU初始化:
当计算机加电时,CPU会进行自检并初始化寄存器。此时,CS寄存器被设置为0xF000,EIP寄存器被设置为0xFFF0,指向BIOS的入口地址0xFFFF0。
在x86架构中,通常使用的是BIOS(Basic Input/Output System)。BIOS是固化在主板上的一组程序,负责基本的硬件初始化和从非易失性存储中加载引导程序。在现代系统中,BIOS的功能逐渐被UEFI(Unified Extensible Firmware Interface)所取代。 - BIOS执行:
CPU从BIOS ROM中读取并执行第一条指令,通常是一个长跳转指令,跳转到BIOS的实际入口地址。
BIOS会进行一系列硬件初始化和自检(POST),包括检查RAM、键盘、显示器、硬盘等设备。 - 引导设备选择:
BIOS根据用户设置的启动顺序(通常存储在CMOS中)选择引导设备,如硬盘、光盘或USB设备。 - 加载主引导记录(MBR):
BIOS从选定的引导设备的第一个扇区(MBR)读取512字节的数据到内存地址0x7C00。
MBR包含引导加载程序的初始代码和分区表信息。 - 执行引导加载程序:
MBR中的引导加载程序代码开始执行,通常会加载并执行操作系统的引导加载程序(如GRUB或LILO)。
引导加载程序负责加载操作系统内核到内存中,并将控制权交给操作系统。 - 操作系统启动:
操作系统内核开始执行,初始化硬件和软件资源,最终启动用户空间的应用程序。
arm架构启动过程
ARM架构机器的启动过程可以分为以下几个主要阶段:
上电和初始引导:
- 当ARM设备上电时,CPU会从一个固定的地址(通常是0x00000000或0xFFFF0000)开始执行代码。这段代码通常存储在片内ROM(iROM)中,由芯片制造商预先烧录。
- iROM代码会进行基本的硬件初始化,并决定从哪个存储设备(如eMMC、SD卡、NAND Flash等)加载引导加载程序(Bootloader)。
引导加载程序(Bootloader):
- 引导加载程序通常分为多个阶段,如BL1、BL2和BL3。每个阶段负责不同的初始化任务。
- BL1:初始化系统时钟、UART、SDRAM等基本硬件,并加载BL2到内存中执行。
- BL2:进一步初始化硬件,并加载完整的引导加载程序(如U-Boot)到内存中执行。
- U-Boot:U-Boot是一个常用的引导加载程序,负责加载操作系统内核到内存中,并将控制权交给内核。
内核启动:
- 内核开始执行,进行硬件探测和初始化。此时,内核会加载设备树(Device Tree)文件,以获取系统硬件配置的信息。
- 内核初始化完成后,会挂载初始的根文件系统(通常是initrd或initramfs),并执行初始化脚本。
挂载根文件系统:
- 内核会卸载initrd,并挂载实际的根文件系统(如从eMMC或NAND Flash中)。
- 内核将控制权交给用户空间的第一个进程(通常是
/sbin/init),继续系统启动过程。
用户空间初始化:
init进程开始执行,启动各种系统服务和守护进程,最终进入用户登录界面或启动应用程序。