Appearance
部署系统环境
在开始操作系统内核的开发之前,我们需要搭建一套完整的开发环境。本章将详细介绍所需的各类工具软件,包括宿主机操作系统的选择、集成开发环境的配置、编译工具链的安装,以及虚拟机调试环境的搭建。
本文档的开发环境基于 Fedora Linux 操作系统。如果你使用的是其他 Linux 发行版(如 Ubuntu、Arch Linux 等),安装命令可能会有所不同,但整体流程和原理是相通的。
Linux操作系统简介
为什么选择Linux
在开始这个操作系统项目之前,我需要选择一个合适的宿主机操作系统作为开发环境。经过一番考虑,我最终选择了 Linux。
选择 Linux 的原因其实很简单:操作系统开发需要用到的 GCC、GDB、NASM 这些工具,本来就是为 Unix/Linux 环境设计的,在 Linux 下使用它们最省心。如果在 Windows 上折腾,要么用 WSL,要么用 Cygwin,总归会遇到各种奇怪的兼容性问题。
另外,Linux 本身就是一个开源的操作系统内核。在开发过程中遇到不懂的地方,可以直接去看 Linux 的源码是怎么实现的,这对学习操作系统原理很有帮助。Linux 的系统调用设计也可以作为我们设计自己操作系统接口时的参考。
Linux 的命令行工具也很强大。编译内核、制作磁盘镜像、启动虚拟机这些操作,写几行 Shell 脚本就能自动化完成,比在图形界面里点来点去方便多了。
虽然用 Windows + WSL 或者 macOS 也能做操作系统开发,但我个人觉得直接用 Linux 原生环境更省事,不用担心各种环境配置的坑。
Linux发行版概述
Linux 有很多发行版可以选择,像 Ubuntu、Fedora、Arch Linux、Debian 这些都挺常见的。
我这次用的是 Fedora。选它主要是因为 Fedora 的软件包更新比较快,能用到比较新版本的 GCC 和其他开发工具。Fedora 用的是 DNF 包管理器,装软件挺方便的。另外 Fedora 和企业版的 RHEL 是一家的,稳定性也不错。
如果你习惯用 Ubuntu 或者其他发行版,其实也没问题,只是安装软件的命令会有点不一样。Ubuntu 用 apt,Arch 用 pacman,道理都是一样的。后面的教程我都会给出 Fedora 下的命令,如果你用其他发行版,自己换一下对应的包管理器命令就行。
宿主机系统:Fedora
Fedora简介
我用的是 Fedora Linux,具体来说是 Fedora KDE Spin 版本。Fedora 是 Red Hat 社区维护的发行版,特点是软件包更新很积极,基本上能第一时间用上最新版本的各种开发工具。
Fedora 的包管理器叫 DNF,用起来挺顺手的。想装什么软件直接 sudo dnf install 包名 就行,依赖关系它会自动处理好。
我选择 KDE 桌面环境主要是个人喜好,KDE Plasma 看起来比较现代,而且自定义选项很丰富。当然用 GNOME 或者其他桌面环境也完全没问题,这个对开发没什么影响。

系统环境准备
拿到一个新装的 Fedora 系统,第一件事是把系统更新到最新:
bash
sudo dnf update -y
更新完可能需要重启一下,特别是如果有内核更新的话。
接下来装一些基础的开发工具。Fedora 提供了一个开发工具组,一条命令就能把常用的东西都装上:
bash
sudo dnf groupinstall -y "Development Tools" "Development Libraries"这会装上 GCC、Make 这些基础组件,还有一些常用的开发头文件。虽然后面我们还会单独介绍每个工具的安装,但先把这个开发工具组装了可以省去很多麻烦。
Fedora 的软件仓库分成好几个部分,像 fedora、updates 这些。对于我们做操作系统开发需要的工具,官方仓库基本都有,不用额外配置什么第三方源。
最后建议创建一个专门的目录来放我们的操作系统项目:
bash
mkdir -p ~/code/os
cd ~/code/os后面的开发工作我都是在这个目录下进行的。你也可以放到别的地方,按自己习惯来就行。
集成开发环境:CLion
CLion简介
写操作系统的代码量不小,用一个好的 IDE 可以大大提高效率。我选择的是 JetBrains 的 CLion。
CLion 是专门为 C/C++ 开发设计的 IDE,代码补全、跳转定义、重构这些功能都很强。它原生支持 CMake 项目,我们的操作系统项目刚好用的就是 CMake 来管理构建,所以用起来很顺手。
当然 CLion 是收费软件,不过学生可以申请免费的教育许可证。如果不想用 CLion,VS Code 配合 C/C++ 插件也是不错的选择,或者用 Vim/Emacs 这些传统编辑器也行,看个人习惯。
安装步骤
在 Fedora 上安装 CLion 有几种方式。最简单的是用 JetBrains Toolbox:

可以从 JetBrains 官网下载 Toolbox App,然后通过它来安装和管理 CLion。Toolbox 会自动处理更新,比较省心。
另一种方式是直接下载 CLion 的 tar.gz 包解压使用,或者用 Flatpak 安装:
bash
flatpak install flathub com.jetbrains.CLion项目配置
打开 CLion 后,直接选择 Open 然后定位到我们的项目目录就行。CLion 会自动检测到 CMakeLists.txt 并加载项目。

第一次打开可能需要等一会儿,CLion 要建立代码索引。索引完成后,代码跳转和补全就都能用了。

GCC编译器
GCC简介
GCC(GNU Compiler Collection)是我们编译操作系统内核的主力工具。它是一个开源的编译器套件,支持 C、C++ 等多种语言。
我们的内核主要用 C++ 编写,少部分底层代码用 C,所以需要用到 GCC 的 g++ 和 gcc。GCC 在 Linux 下是标准配置,基本上每个发行版都会预装或者很容易安装。
安装配置
如果之前执行了开发工具组的安装,GCC 应该已经装好了。可以验证一下:
bash
gcc --version
g++ --version如果没装的话,手动安装也很简单:
bash
sudo dnf install -y gcc gcc-c++我这里用的是 GCC 15.2.1,Fedora 仓库里的版本比较新。

交叉编译说明
这里有个需要注意的地方:我们编译的是一个独立的操作系统内核,不是运行在 Linux 上的普通程序。所以编译的时候需要加一些特殊的参数,告诉 GCC 不要链接标准库,生成的是 freestanding 代码。
具体的编译参数在 CMakeLists.txt 里已经配置好了,包括 -ffreestanding、-fno-builtin、-nostdlib 这些。后面讲到具体模块的时候会再详细解释。
NASM汇编器
NASM简介
虽然我们的内核主体用 C++ 编写,但有些底层的东西还是得用汇编来写,比如 bootloader、中断处理入口、上下文切换这些。我用的汇编器是 NASM(Netwide Assembler)。
NASM 使用的是 Intel 语法,和 GAS(GNU Assembler)的 AT&T 语法不一样。我个人觉得 Intel 语法更直观一些,mov eax, 1 比 movl $1, %eax 看着顺眼。
安装配置
Fedora 仓库里有 NASM,直接装就行:
bash
sudo dnf install -y nasm这里顺便说一下 Linux 作为开发环境的方便之处。很多人觉得 Linux 难用、麻烦,但实际上对于开发来说恰恰相反。你看,安装 NASM 就一条命令的事,不用去官网下载安装包、不用配环境变量、不用担心版本冲突。包管理器会帮你把一切都处理好。这就是为什么我选择 Linux 作为开发环境的原因之一。
装完验证一下版本:
bash
nasm --version我这里是 NASM 2.16 版本,对于我们的项目来说足够用了。
编译汇编文件的命令大概是这样:
bash
nasm -f elf32 -o output.o input.asm-f elf32 表示输出 32 位的 ELF 格式目标文件,因为我们的内核是 32 位的。这些编译命令在 CMakeLists.txt 里都配置好了,不需要手动执行。
Bochs虚拟机
Bochs简介
开发操作系统需要一个虚拟机来运行和测试。我选择的是 Bochs,一个专门为操作系统开发设计的 x86 模拟器。
为什么不用 QEMU 或者 VirtualBox?主要是 Bochs 的调试功能特别强大。它可以单步执行 CPU 指令、查看寄存器状态、设置断点,这对于调试 bootloader 和内核启动阶段的代码非常有用。普通的虚拟机在 OS 还没起来的时候是没法用 GDB 调试的,但 Bochs 可以。
当然 Bochs 的缺点是比较慢,毕竟是纯软件模拟。等内核开发到后期,可以切换到 QEMU 来跑,速度会快很多。
编译安装
我用的是 Bochs 2.6.2 版本。这个版本比较稳定,而且网上的教程大多基于这个版本。
Fedora 仓库里的 Bochs 可能版本不对或者编译选项不合适,所以我选择从源码编译。先下载源码包,然后:
bash
tar xzf bochs-2.6.2.tar.gz
cd bochs-2.6.2
./configure --prefix=/usr/local/bochs \
--enable-debugger \
--enable-disasm \
--enable-iodebug \
--enable-x86-debugger \
--with-x \
--with-x11
make
sudo make install这里 --enable-debugger 是关键,它会启用 Bochs 的内置调试器。--prefix 指定安装位置,我装到了 /usr/local/bochs。
如果想配合 GDB 远程调试,需要另外编译一份带 GDB stub 的版本:
bash
./configure --prefix=/usr/local/bochs-gdb \
--enable-gdb-stub \
--enable-disasm \
--with-x \
--with-x11
make
sudo make install--enable-debugger 和 --enable-gdb-stub 不能同时启用,所以需要编译两份 Bochs。一份用内置调试器,一份用 GDB 调试。
配置文件
Bochs 启动时需要一个配置文件来指定虚拟机的参数。我的配置文件 bochsrc.disk 长这样:
text
# Bochs使用的内存 单位MB
megs: 32
# BIOS和VGA BIOS
romimage: file=/usr/local/bochs/share/bochs/BIOS-bochs-latest
vgaromimage: file=/usr/local/bochs/share/bochs/VGABIOS-lgpl-latest
# 选择启动盘符
boot: disk
# 设置日志输出
log: bochs.out
debugger_log: bochs_debugger.out
# 关闭鼠标并打开键盘
mouse: enabled=0
keyboard: keymap=/usr/local/bochs/share/bochs/keymaps/x11-pc-us.map
# 硬盘设置
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
ata0-master: type=disk, path="hd64M.img", mode=flat, cylinders=130, heads=16, spt=63
ata0-slave: type=disk, path="hd80M.img", mode=flat, cylinders=162, heads=16, spt=63几个重要的配置项:
megs: 虚拟机内存大小,32MB 对于我们的小内核够用了boot: disk: 从硬盘启动ata0-master: 主硬盘,我们的内核就装在这个镜像里
如果要用 GDB 调试版本的 Bochs,需要额外加一行:
text
gdbstub: enabled=1, port=1234, text_base=0, data_base=0, bss_base=0这样 Bochs 启动后会在 1234 端口等待 GDB 连接。
CMake与Ninja构建系统
CMake简介
我们的项目用 CMake 来管理构建过程。CMake 是一个跨平台的构建系统生成器,它不直接编译代码,而是生成 Makefile 或者 Ninja 构建文件,然后由 Make 或 Ninja 来执行实际的编译。
用 CMake 的好处是配置比较清晰,比手写 Makefile 省事不少。而且 CLion 对 CMake 的支持很好,项目结构可以直接在 IDE 里管理。
安装CMake和Ninja
Fedora 仓库里有现成的:
bash
sudo dnf install -y cmake ninja-build验证安装:
bash
cmake --version
ninja --version我用的是 CMake 3.28 和 Ninja 1.12。
为什么用Ninja
CMake 默认生成 Makefile,但我配置成生成 Ninja 构建文件。Ninja 是 Google 开发的一个构建工具,特点是速度快。
对于我们这种需要频繁修改代码、重新编译的开发场景,Ninja 的增量编译速度比 Make 快不少。在 CMakeLists.txt 所在目录执行:
bash
cmake -B build -G Ninja
cmake --build build第一行生成 Ninja 构建文件到 build 目录,第二行执行编译。CLion 会自动处理这些,不需要手动敲命令。
Git版本控制
Git简介
版本控制对于任何软件项目都很重要,操作系统开发也不例外。我用 Git 来管理代码版本。
Git 可以记录每次代码修改的历史,方便回溯和对比。写操作系统的时候经常会遇到改着改着把系统搞崩了的情况,有了 Git 就可以轻松回退到之前能用的版本。另外 Git 的分支功能也很有用,可以在不影响主线的情况下尝试新的实现方案。
安装配置
Fedora 一般预装了 Git,如果没有的话:
bash
sudo dnf install -y git第一次用 Git 需要配置一下用户信息:
bash
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"基本使用
项目已经是一个 Git 仓库了。在这个项目里,我主要通过 CLion 内置的 Git 功能来管理版本,图形界面用起来比较直观,提交、查看历史、对比差异都很方便。

不过要注意的是,CLion 的 Git 功能只是一个图形前端,它底层还是调用系统安装的 Git。所以即使你打算只用 CLion 来操作 Git,也必须先把 Git 装好。
如果需要用命令行,日常开发中常用的命令就这几个:
bash
git status # 查看当前状态
git add . # 添加所有修改
git commit -m "描述" # 提交
git log --oneline # 查看提交历史
git diff # 查看未提交的修改建议养成经常提交的习惯,每完成一个小功能就 commit 一次。提交信息写清楚改了什么,以后查历史的时候会很有用。
GDB调试器
GDB简介
GDB 是 GNU 项目的调试器,可以用来调试 C/C++ 程序。在操作系统开发中,GDB 配合 Bochs 的 GDB stub 功能,可以实现对内核的源码级调试。
有了 GDB,就可以在内核代码里设断点、单步执行、查看变量值,比光看 Bochs 的汇编级调试方便多了。
安装配置
GDB 一般在开发工具组里已经装好了,如果没有:
bash
sudo dnf install -y gdb验证一下:
bash
gdb --version配合Bochs调试
使用 GDB 调试内核的基本流程是这样的:
1. 启动带 GDB stub 的 Bochs(使用 bochsrc-gdb.disk 配置) 2. Bochs 会在 1234 端口等待连接 3. 启动 GDB,连接到 Bochs:
bash
gdb kernel.bin
(gdb) target remote localhost:1234
(gdb) break kernel_main
(gdb) continue这样就可以在内核代码里调试了。CLion 也可以配置成用图形界面来进行 GDB 远程调试,设置一个 Remote Debug 配置就行。

调试内核和调试普通程序有点不一样,因为内核运行在不同的地址空间。需要确保加载的符号表和实际运行的代码地址匹配,否则断点可能不生效。
