一、macOS 开发环境准备

学习目标 🎯

  • 在 macOS 上搭建完整的 Rust 操作系统开发环境
  • 配置 macOS 特有的开发工具
  • 成功编译并运行第一个内核程序

第一部分: macOS 开发环境准备

安装 Rust 必要组件

Rust 版本 1.70.0 (稳定版本)

bash 复制代码
# 安装 Rust 源码
rustup component add rust-src

# 安装Rust nightly工具链(必需不稳定特性)
rustup install nightly
rustup default nightly

# 添加编译目标(生成裸机二进制)
rustup target add x86_64-unknown-none

# 安装 LLVM 工具
rustup component add llvm-tools-preview

# 安装 bootimage 工具
cargo install bootimage

# 验证安装
bootimage --version
rust-src

rust-src 是 Rust 编程语言的源代码包,它包含了 Rust 标准库和编译器的完整源代码。

nightly

nightly 是 Rust 编程语言的每日构建版本,它包含了最新的、尚未稳定的功能和改进。 在这里用最新版。

为什么需要 nightly

  1. bootloader 编译需要 -Z 标志 (-ZRust 编译器的不稳定标志,用于启用实验性功能和内部选项。)
  2. 裸机开发需要最新的编译器功能
  3. 工具链支持需要实验性功能
x86_64-unknown-none

x86_64-unknown-none 是面向64 位 x86 架构裸机环境的目标标识,用于无操作系统的开发场景(如内核、嵌入式系统)。

llvm-tools-preview

llvm-tools-preview 是 Rust 生态系统中的一个组件,它提供了 LLVM 工具链的预览版本。 包含的工具有:

  • llvm-objcopy:用于复制和修改目标文件
  • llvm-objdump:用于显示目标文件信息
  • llvm-readelf:用于读取 ELF 文件格式
  • llvm-strip:用于去除符号表
  • llvm-size:用于显示目标文件大小
  • 其他 LLVM 工具

Rust 项目中的作用:

  • 用于交叉编译
  • 处理目标文件
  • 调试和优化
  • 嵌入式开发
bootimage

bootimage 是一个 Rust 工具,专门用于创建可引导的磁盘镜像。它主要用于操作系统开发和嵌入式系统开发。bootimage 在这个项目中特别有用:

  • 将Rust 内核编译成可引导镜像
  • 在 QEMU 虚拟机中测试内核
  • 创建用于实际硬件部署的镜像

第二部分:安装 QEMU

1. 使用 Homebrew 安装 QEMU

bash 复制代码
# 安装 QEMU(推荐方法)
brew install qemu

# 验证安装
qemu-system-x86_64 --version
which qemu-system-x86_64

2. 配置 QEMU 路径

bash 复制代码
# 检查 QEMU 安装路径
ls -la /opt/homebrew/bin/qemu*  # Apple Silicon Mac

# 添加到 PATH(通常 Homebrew 会自动处理)
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc  # Apple Silicon

3. 测试 QEMU

bash 复制代码
# 测试 QEMU 是否正常工作
qemu-system-x86_64 -version

QEMU (Quick EMUlator) 是一个开源的硬件虚拟化工具,可以模拟不同的计算机硬件架构。

QEMU 的主要功能:

  1. 硬件模拟
    • 模拟 CPU、内存、硬盘、网络等硬件
    • 支持多种架构:x86_64、ARM、PowerPC 等
    • 提供虚拟的计算机环境 2. 系统虚拟化
    • 运行完整的操作系统
    • 支持 Windows、Linux、macOS 等
    • 提供隔离的虚拟环境 3. 用户模式模拟
    • 运行单个程序
    • 跨架构程序执行
    • 调试和测试工具

QEMU 的优势

  1. 跨平台支持
    • 在 macOS 上运行 Linux 程序
    • 在 ARM 机器上运行 x86_64 代码
    • 支持多种操作系统 2. 性能优秀
    • 接近原生性能
    • 支持硬件加速
    • 高效的模拟 3. 功能丰富
    • 网络支持
    • 图形界面
    • 调试工具

常用 QEMU 命令

  1. 基本运行
bash 复制代码
qemu-system-x86_64 -drive format=raw,file=kernel.bin
  1. 指定内存
bash 复制代码
qemu-system-x86_64 -m 512M -drive format=raw,file=kernel.bin
  1. 启用图形界面
bash 复制代码
qemu-system-x86_64 -display gtk -drive format=raw,file=kernel.bin
  1. 网络支持
bash 复制代码
qemu-system-x86_64 -net nic -net user -drive format=raw,file=kernel.bin

第三部分 创建项目

bash 复制代码
cargo new blog_os --bin
cd blog_os

修改 Cargo.toml 添加配置:

toml 复制代码
[package]
name = "blog_os"
version = "0.1.0"
edition = "2021"  # 兼容较旧版本

[dependencies]
bootloader = "0.9"  # 引导加载程序

[build-dependencies]
bootimage = "0.10.3"  # 镜像创建工具

修改 main.rs

rust 复制代码
// 1. 禁用标准库
#![no_std] 

// 2. 禁用Rust运行时(无main函数)
#![no_main]

// 3. 定义入口点(取代main函数)
#[no_mangle]
pub extern "C" fn _start() -> ! {
    // 内核入口函数
    loop {}
}

// 4. 实现panic处理函数
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    loop {}
}

第四部分:编译和运行

bash 复制代码
# 编译内核
cargo +nightly build --target x86_64-unknown-none

# 运行内核 (直接运行 ELF 文件)
qemu-system-x86_64 -drive format=raw,file=target/x86_64-unknown-none/debug/blog_os

此时:

写在最后-电脑开机启动发生了什么

开机启动流程

  • POST(加电自检)
    • 进行一系列诊断
    • 按固件配置顺序寻找可启动设备(软盘、CD-ROM、硬盘等)
  • 主引导记录(MBR)
    • BIOS检查引导扇区的引导签名(0x55、0xAA,位于510和511字节偏移处)
    • 找到后加载到内存特定位置(0x0000:0x7c00或0x7c0:0x0000,物理地址相同) -硬盘MBR结构:446字节可执行代码 + 分区表(16字节/项,共4项) + 2字节签名
  • 早期执行环境
    • 高度依赖BIOS实现,寄存器内容不确定(包括FLAGS、SP,栈可能无效)
    • 唯一确定:DL寄存器存引导代码加载的驱动器代码
    • CPU通常处于实模式(少数BIOS可能已激活保护模式)
  • 内核加载与控制转移
    • 引导程序加载内核到内存并移交控制权 内核加载前的任务
  • 确定启动分区(找活动分区或让用户选择)
  • 确定内核在引导分区的位置(解析文件系统或从固定位置加载)
  • 加载内核到内存(需基础磁盘I/O)
  • 启用保护模式
  • 为内核准备运行环境(如设置栈空间) 解决引导记录空间限制的方法
  • 极客加载:将所有任务挤入引导记录(几乎不可能,无特殊处理和错误信息空间)
  • 单阶段加载:写转换存根程序链接到内核前,引导记录加载内核到1MB以下,存根切换到保护模式并准备环境后跳转内核
  • 两阶段加载:写单独存根程序加载到1MB以下,完成所有加载前任务
  • 传统链式加载:MBR relocation到0x0000:0x0600,加载活动分区引导记录到0x0000:0x7c00并跳转 推荐与其他启动方式
  • 推荐使用现成引导程序(如GRUB)
    • 提供启动菜单和链式加载功能
    • 初始化早期环境到确定状态(含保护模式、读取BIOS信息)
    • 支持多种文件系统、内核模块、无盘启动等
  • 其他启动方式
    • 利用未使用分区加载第二阶段

    • 将第二阶段放在MBR和第一个分区起始之间

    • 类似Lilo:检测扇区/簇列表,第一阶段加载对应扇区

    • DOS和Windows:格式化空文件系统,加载根目录第一、二个文件

    • 旧Linux软盘启动:第一扇区加载第二阶段(setup),其设置系统后加载内核

    • nuni引导程序:在一个引导扇区内切换到保护模式并加载文件

参考文档

Boot Sequence

相关推荐
林太白2 小时前
Rust-搞定图片上传功能
前端·后端·rust
dongowu4 小时前
Rust 大白话- <所有权、借用、引用>
rust
Hello.Reader1 天前
Rust × Elasticsearch官方 `elasticsearch` crate 上手指南
elasticsearch·rust·jenkins
林太白1 天前
Rust知识篇05-所有权和借用
前端·后端·rust
林太白1 天前
Rust知识篇04-函数
前端·后端·rust
林太白1 天前
Rust知识篇03-字符、布尔、单元类型、输出、语句表达式
前端·后端·rust
林太白1 天前
Rust搜索优化
前端·后端·rust
RustFS1 天前
用 mc 对 RustFS 对象存储进行操作
rust