- 文件:
boot.asm
- 完整项目代码在末尾
从上篇可知, 留给我们的代码部分只有420字节. 而boot代码需要完成的任务也很简单, 只需要从磁盘加载loader到内存中, 并跳转到loader执行
- 文件:
fat32.inc
幸运的是我们不用自己编写这个文件, 不幸的是我们需要编写生成这个文件的程序
我们需要先做些准备, 方便未来的开发
在后续中, 我会使用/dev/sda
代指磁盘或磁盘镜像, 如果你使用的是U盘, 那么我建议你修改可以临时修改磁盘的权限, 使得所有用户都可以读写磁盘 sudo chmod 666 /dev/sda
哦对的对的,哎呀不对不对,对…对吗?
并非全力
0x500 处的内存不要碰,否则可能导致程序跑飞
可能是由于BIOS占用了这个区间的一部分内存,随便改写导致异常。
但是实模式内存分布图上显示这一块确实是随便用。
- 文件:
def.inc
众所周知x86的cpu在启动之后处于实模式, 只能访问前1MiB的内存, 且很多位置是不能随便写的, 因此我们需要提前设计好每个在boot和loader阶段用到的变量存放的位置, 防止因为不小心将数据写入错误的位置而导致boot和loader跑崩
当我第一次接触操作系统后, 我就觉得我一定要开发一个属于自己的. 然而当时的我并没有意识到这是一个不见底的深渊
开发平台和环境
始于Debian10, 目前已经Debian12了(这闪电般的开发进度, 不愧是我), 各种工具可以直接使用apt
直接安装, 不必担心因为各种操作系统开发书籍和教程里的各种古早的系统版本和工具版本而发愁(我已经帮大家愁完了)
gcc会在call
指令之前让rsp
按16
字节对齐。
cpu在call
的时候将rip
压栈rsp -= 8
,所以进入被调用者之后rsp = 8 (mod 16)
。如果在这个函数里面还要call
其他函数的话就要将rsp
减掉奇数个8
让它重新16
字节对齐。
初始化寄存器
我将物理地址0x050000-0x070008
之间的内存分配给了堆栈。栈顶设置为0x070008
的原因是,kernel函数在编译后会在函数开头加上这样一行汇编代码sub $0x8,%rsp
,将栈顶设置为0x070008
可以保证在经过此操作后,栈顶为0x070000
。