回忆我们需要做的事情:
为了支持 shell 程序的执行,我们需要提供:
1.缺页中断(不理解为什么要这个东西,只是闪客说需要,后边再说)
2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的,所以需要这两个东西)
3.fork,execve, wait 这三个系统调用,也可以说是 进程调度 (否则无法 halt shell 程序并且启动另外的程序)
4.键盘驱动、VGA/console/uart 驱动、中断处理 (支持键盘输入和屏幕显示)
5.内存管理 (shell 启动其它进程时,不能共用内存,而是切换其它进程的页表)
6.为了写代码方便,我们需要从 MBR 进入到 main 函数,这也是从 汇编 切换到 C 语言
7.应用程序申请内存的接口
经历了 Day11,看到了 Linux 0.11 中的内存管理代码后。
显然,这样复杂的功能用汇编写会很花时间,所以我们得想办法从汇编转为 C 代码,随后进入一个 C main 函数
直接看闪客文章第十回:https://mp.weixin.qq.com/s?__biz=Mzk0MjE3NDE0Ng==&mid=2247499838&idx=1&sn=6e7335be30fb24b03c54ccaaf135f236&chksm=c2c5ba93f5b23385a21191ea0ba60431340b195a3d63ae4d0e737f8274920d4c372940e4094c&scene=178&cur_album_id=2123743679373688834#rd
从上图可以看到,进入 C main 之间还要做许多工作,代码为 bootsect.s, setup.s 以及 head.s
为什么要做这么多工作?为什么不能直接 jmp main 呢?
首先 MBR 不能直接 jmp main。因为 MBR 的程序并不是一个和 C 程序链接在一起的程序,也不能是一个和 C 程序链接在一起的程序。因为 MBR 的大小仅为 512 字节,根本不可能和 C 程序链接在一起。
所以 MBR 能做的事情只有:把内核(和 C main 链接的程序) 从磁盘上加载到内存中。
那么 MBR 已经能把内核加载到内存里了,为什么还需要 setup.s 和 head.s 呢?
这个问题后边再思考吧,我们先看看 bootsect.s 是如何把 setup.s 和 内核 从磁盘加载到内存上的
TODO: here