1. 上电启动流程

当x86电源打开后,CPU将自动进入实模式,并从地址0xFFFF0(CS:0xFFFF,IP:0x0)开始自动运行程序代码,此地址一般是BIOS的地址。
BIOS启动后,将启动设备的主引导记录。主引导记录位于第0磁道的第1个扇区,它的大小是512字节,里面存放了用汇编语言编写的预启动信息、分区表信息、魔数0x55AA等。
BIOS将主引导记录读入内存绝对地址0x7C00处,并跳转到此地址运行。
在SylixOS平台中,事实上被拷贝到物理内存0x7C00处的内容就是GRUB。

2. GRUB的作用

GRUB是目前较流行启动引导程序。
GRUB(Grand Unified Bootloader)是当前Linux诸多发行版本默认的引导程序,SylixOS遵循了GRUB的引导协议Multiboot后,也可以使用GRUB进行引导。
GRUB执行后,将初始化设置内核执行所需的环境,载入内核镜像。
GRUB分为1.x版本和2.x版本,两个版本的架构有所不同,目前SylixOS启动还是使用1.x版本的GRUB。
GRUB1.x磁盘引导SylixOS全过程

  • stage1
    GRUB读取磁盘的第一个512字节的主引导记录MBR。
  • stage1.5
    识别各种不同的文件系统格式,目的是为了GRUB能识别到文件系统。
  • stage2
    载入系统引导菜单(“/boot/grub/menu.lst”或“grub.lst”),载入SylixOS的x86镜像bspx86.elf。

    3. Multiboot协议

    为了统一x86平台GRUB引导各式操作系统的流程,GRUB支持了Multiboot的引导协议,该协议定义了一个可识别的系统镜像文件头部应具备的格式协议,Multiboot首部定义如下表所示。

Offset Type Field Name Note
0 u32 magic required
4 u32 flags required
8 u32 checksum required
12 u32 header_addr if flags[16] is set
16 u32 load_addr if flags[16] is set
20 u32 load_end_addr if flags[16] is set
24 u32 bss_end_addr if flags[16] is set
28 u32 entry_addr if flags[16] is set
32 u32 mode_type if flags[02] is set
36 u32 width if flags[02] is set
40 u32 height if flags[02] is set
44 u32 depth if flags[02] is set

SylixOS参照上表所示的Multiboot首部定义规则,对SylixOS的x86镜像的Multiboot首部进行了定义,如下图所示。

并且按照Multiboot的协议要求,Multiboot的首部应当位于整个elf镜像的首部位置,所以对于SylixOS的BSP镜像工程,在链接Multiboot文件时需要指定其地址,如下图所示。

4. SylixOS启动

4.1 GRUB解析bspx86.elf

GRUB启动时,会根据menu.lst文件加载对应的系统镜像。
SylixOS的RealEvo-IDE默认提供的menu.lst文件内容如下图所示。

在menu.lst文件中指定了GRUB启动的默认等待时间timeout、默认加载菜单项default以及各菜单条目。
如,菜单条目“title SylixOS(UP)”,其定义了使用GRUB的kernel命令引导bspx86.elf文件,并为其传递“ncpus=1 hz=1000”等参数。
GRUB的kernel命令会解析bspx86.elf文件,判断其Multiboot首部的有效性,在有效性完整判断结束之后,根据elf的头信息,对bspx86.elf的各个段进行重定位。

4.2 重定位入口地址

elf文件的头信息中包含了该elf文件众多的信息,使用elf文件分析工具等程序,可以查看elf文件头部的信息,如下图所示。

程序的入口地址是在elf文件中设定好的,所以GRUB在将SylixOS镜像重定位后,也会将该入口地址设置在elf头信息中指定的位置。

4.3 跳转到主核入口地址

x86主核入口代码如下图所示。

以SylixOS的32位系统为例,在跳转到该入口地址后,应先设置栈指针,而设置栈指针之前,需要关闭中断。
最后调用CALL命令,跳转到C程序入口bspInit,而bspInit的两个参数由%EBX和%EAX寄存器传递,分别为Multiboot的魔数和Multiboot信息结构体的首地址。

4.4 主核引导从核启动

主核引导从核启动也是遵循了Intel制定的从核启动规则。
如下图所示,BSP为BIOS引导的主核,AP为待BSP启动的从核。BSP需要首先向AP发送INIT IPI命令,之后连续发送两次STARTUP IPI命令。
INIT IPI命令与STARTUP IPI命令都是固定的带有参数的指令,通过核间中断的方式进行发送。

INIT IPI命令可以使AP自动进行复位操作,并完成上电启动后POST自检等硬件所需流程。
STARTUP IPI命令中可以指定从核跳转到实模式执行的指令内容和地址,由此可以使从核按照SMP或AMP的流程进行初始化。