BasicOS - A Minimal Operating System - Day1

BasicOS - A Minimal Operating System

Overview

心血来潮,准备写一个操作系统,记录一下学习过程。主要参考著名的《恐龙书》。从bootloader开始,逐步实现一个最小的操作系统。
既然是操作系统,那么就避免不了汇编语言。之后会使用C语言来实现。最后如果有余力的话,会使用Rust来实现。

环境

  • Ubuntu 24.04
  • qemu
  • nasm
  • gcc
  • make

安装环境

sudo apt-get update
sudo apt-get install nasm qemu gcc gcc-multilib

安装debug工具

sudo apt-get install xxd gdb

GitHub地址

https://xxxxx。xxx/toronto-andrew/BasicOS.git

先写一个最简单的bootloader

BIOS (Basic Input/Output System) 我们每个人都最熟悉了。当然,新的计算机都使用 UEFI(Unified Extensible Firmware Interface)了。
UEFI 和单纯使用 BIOS 的区别在于加载内核的方式、准备工作和高级功能等。这里为了方便起见,我们暂时只考虑 BIOS(因为最简单)。

电脑刚一开机,BIOS 的作用是告诉计算机从哪里加载操作系统到内存。于是,有人规定了,操作系统应当放在存储设备最开始的 512 字节(例如磁盘第 0 柱面第 0 磁头第 0 扇区)。这个区域就是我们的引导扇区。也就是说,操纵系统运行的第一行代码就是在引导扇区中。
然而,一台计算机可能有多个存储设备,BIOS 依然不知道哪个设备存储了引导扇区。但不知道谁又规定了,引导扇区的最后两个字节必须是 0xaa55。于是,BIOS 只需要遍历所有存储设备,检查他们的第 511 和 512 字节是否是 0xaa55。如果是,就说明找到了操作系统的位置,把这一段数据加载到内存中,然后跳转到这段代码的第一个字节开始执行。
因此,对于手动编写一个引导扇区来说,只需要:
1 首先把最后两个字节设置为 0xaa55;
2 然后从第一个字节开始写上想要的代码;
3 最后把其它的字节填充为 0,补满 512 字节。

代码如下boot.asm:

[bits 16]             ; 告诉汇编器我们是在 16 位下工作

jmp $                 ; $ 表示当前地址,跳转到当前地址就是死循环

times 510-($-$$) db 0 ; $ 表示当前地址,$$ 表示当前段的开始地址
                      ; 510-($-$$) 计算出当前位置到 510 字节的距离,然后全部填充为 0

dw 0xaa55             ; 最后两个字节是 0xaa55

编译

nasm boot.asm -f bin -o boot.bin

运行

qemu-system-x86_64 boot.bin

你会看到窗口中显示 Booting from Hard Disk...,然后它就开始执行死循环了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容