为树莓派4编写裸机操作系统--part2
本文最后更新于:2022年3月14日 晚上
本文档所有内容均翻译自 https://github.com/isometimes/rpi4-osdev,作为自己学习树莓派及操作系统的记录。由于本人英文水平有限,如果出现翻译错误请指出,本人会及时改正。如果出现无法理解的内容,请参考原文学习。
为树莓派 4 编写裸机操作系统 2 - 构建
编写 makefile
我现在就可以一个个告诉你构建这样一个非常简单的操作系统所需的命令,但让我们尝试一种更面向未来的方式。我预计我们的操作系统内核将变得更加复杂,它需要构建多个 C 文件。因此,编写一个 makefile 文件是很有意义的。makefile 使用另外一种语言编写,并能自动化我们构建项目的过程。
如果你在 Linux上使用 Arm gcc,请将以下内容另存为 Makefile(在repo中是Makefile.gcc):
1 |
|
- CFILES 是当前目录中已经存在的 .c 文件的列表(我们的输入)
- OFILES 是同一个列表,但是将文件的后缀由 .c 替换为 .o - 这些是包含二进制代码的目标文件 ,它们将由编译器产生(我们的输出)
- GCCFLAGS 是一个参数列表,告诉编译器我们正在为裸机构建程序,因此它不能依赖于通常我们用于实现简单功能的任何标准库–在裸机上没有什么是免费的
- GCCPATH 是我们的编译器的可执行文件的路径(你之前下载的 Arm 工具的解压位置)
然后是构建目标列表,冒号后面列出了它们的依赖关系。每个目标下方的缩进的命令将被执行用以构建目标。很容易看出,要构建 boot.o,我们依赖于源代码文件 boot.S的存在。然后我们使用正确的标志运行我们的编译器,将 boot.S 作为我们的输入并生成 boot.o。
% 是 makefile 文件中的匹配通配符。因此,对于下一个构建目标,我们使用 .c 文件构建具有相同名称的以 .o 为后缀的任意目标文件。然后执行 makeflie 下面的命令列表,将 $< 替换为 .c 文件名,将 $@ 替换为 .o 文件名。
继续,要构建 kernel8.img 文件,我们必须首先构建 boot.o 以及 OFILES列表中的所有其他 .o 文件。如果这些 .o 文件存在,我们运行 ld 链接将 boot.o 与其他目标文件链接起来,并使用我们的链接脚本 link.ld 定义 kernel8.img 镜像文件的内存布局。遗憾的是,ELF 格式被设计为在其他操作系统中可执行的文件格式,因此,对于在裸机中运行的目标,我们使用 objcopy 将 ELF 文件的必要部分拷贝到 kernel8.img 文件中。这是我们最终启动 RPi4 的内核镜像。
对于 “clean” 和 “all” 的构建目标,我希望不用再作解释。
其他平台上的 Makefile
如果你在 Mac Os X 上使用 clang 编译器,那么在 repo中已经命名为 Makefile 的文件将是你需要的。当然,请确保正确设置 LLVMPATH。它看起来和 Arm gcc没有太大区别,因此上面的解释大多也适用。
同样,如果你在 Windows 上使用本地 Arm gcc,第八部分 part8-breakout-ble 中有一个 Makefile.gcc.windows 可以作为示例。
构建
现在我们已经有了 Makefile 文件,我们只需要简单的输入 make 命令就可以构建我们的内核镜像。由于 “all” 是 makefile 文件中列出的第一个构建目标,除非另有说明,make 命令将默认构建它。在构建 “all” 时,它会首先清理旧的构建目标,然后为我们重新构建 kernel8.img。
将我们的内核镜像拷贝到 SD 卡
希望你已经有了一张带有可运行 Raspbian 操作系统镜像的 micro-SD 卡。为了引导我们的 内核程序而不是 Raspbian 系统,我们需要使用我们构建的 kernel8.img 镜像替换 SD 卡中现有的任何操作系统镜像,同时注意保持目录结构中的其余部分完整。
在你的开发机上,挂载 SD 卡并删除所有以 kernel 开头的文件。更谨慎的作法可能是将 SD 卡中的内容拷贝到本地硬盘下的备份文件夹中。然后,你可以根据需要轻松还原这些文件。
我们现在将 kernel8.img 复制到 SD 卡上。镜像文件的这个名字是有意义的,它向 RPi4 发出我们希望以 64 位模式启动树莓派的信号。我们还可以通过在 config.txt 文件中将 arm_64bit 设置为非零值的方式来强制 RPi4 以 64 位模式启动。将我们的操作系统引导到 64 位模式意味着我们可以使用 RPi4 中可用的更大的内存容量。
引导
从你的开发机上安全的卸载 SD 卡,将它插回 RPi4 并启动。
你已经启动了我们自己的操作系统!
尽管这听起来很令人兴奋,但在显示 RPi4 自己的引导画面后,你可能只会看到一个空白的黑色屏幕。然而,我们不应该感到惊讶,除了在无限循环中挂起,我们还没有要求我们的操作系统做任何事。
不过基础已经打好了,我们现在可以开始做令人兴奋的事情了。恭喜你走到这一步!