rust_os_docs
  • rCore OS 开发文档
  • 项目整体介绍
  • Rust语言速成
  • 开发环境配置
  • 整体架构和启动过程
  • Bootloader
  • 内存管理模块
  • 线程管理模块
  • 加载外部程序
  • 文件系统模块
  • Q&A
Powered by GitBook
On this page
  • 简介
  • 代码及运行过程
  • x86_64 第一版(已废弃)
  • x86_64 第二版
  • RISCV for QEMU
  • RISCV for FPGA
  • TODO

Bootloader

Previous整体架构和启动过程Next内存管理模块

Last updated 6 years ago

简介

Bootloader作为最早执行的代码,职责是进行平台相关的设置,为Kernel创造运行环境。某种意义上,Kernel是Bootloader的用户程序。

RustOS开发之初,借用的是《》第一版的代码,而现在作者已经推出了第二版,第一版不再维护。两个版本的Bootloader有很大不同:

  • 第一版中使用GRUB,它可以完成从磁盘加载内核代码,及进入32位保护模式的工作,并以multiboot2格式提供必要信息。剩余部分Boot代码,完成进入64位long mode的工作,它和kernel共存于同一个Rust项目中,使用nasm编译。整个构建流程需要依赖很多Rust工具链以外的程序。

  • 第二版中抛弃了GRUB,作者用Rust和汇编从头写了一个,从磁盘加载内核代码,进入64位long mode,并根据kernel elf设置好页表,以自定义格式向kernel提供信息。整个bootloader作为一个独立项目存在。此外作者还写了工具,用来编译kernel并和bootloader打包在一起生成bin,统一了构建流程。

RustOS for x86_64此前一直在使用第一版的boot流程,直到2018.09.12才迁移到bootimage工具链。此次改动后,配置开发环境的难度大大降低(尤其对macOS),Boot和Kernel也实现了分离。

至于RISCV,参考的做法使用,作为M态运行环境,而Kernel运行在S态。目前BBL直接借用ucore中的C代码,以后也许可以仿照x86_64的做法,编写Rust版本的bootloader。

哦对了,如果要跑在我们自己写的RV32I CPU上的话,只需有一个极小的bootloader。

代码及运行过程

x86_64 第一版(已废弃)

执行过程:

  • GRUB识别multiboot_header,从磁盘中加载内核到内存,进入32位保护模式

  • boot.asm:加载GDT,构造初始页表并开启页机制

  • long_mode_init.asm:进入64位long mode,设置rsp寄存器,跳转到Rust代码

多核启动过程:

  • entryother.asm:依次从16位->32位->64位,开启页机制,跳转到Rust代码(借用自xv6)

  • 上述多核boot代码被放置到0x7000,在第一个核启动后,通过lapic向其它核发送信号,让它们从0x7000开始执行。

具体可参考博客第一版前两篇文章:

x86_64 第二版

执行过程,分为三阶段:

  1. boot.s:从0x7c00起<512B的代码,被BIOS放入内存后执行。工作是进入保护模式,从磁盘中加载bootloader剩余代码到内存。

  2. second_stage.s:将磁盘中的kernel(elf格式文件)加载到内存(0x400000),设置初始页表,开启页机制,进入64位long mode。

  3. main.rs:解析elf文件并在页表中建立映射。写入BootInfo信息,跳转到kernel入口点。

目前此bootloader尚无官方文档☹️

RISCV for QEMU

bbl位于 riscv-pk文件夹,相比官方仓库,经过了精简和修改。

bbl除了作为Bootloader,还提供M态运行环境,S态的Kernel可通过系统调用ecall使用bbl的服务,包括读写串口、CPU核间通信等。

RISCV for FPGA

TODO

bbl执行完毕后,跳转到固定地址(0x80020000),,之后仅需设置sp寄存器,然后跳转到Rust代码。

,代替bbl。

Writing an OS in Rust
bootloader
bootimage
ucore
Berkeley bootloader(BBL)
代码在此
A minimal Multiboot Kernel
Entering Long Mode
官方仓库
代码在此
一个极小bootloader