1 总体的逻辑。
从这里开始 写 loader 代码了。
1 首先是 从汇编跳转到 C原因呢,
2 然后是 , 再源码中新建新的loader 目录。
3 一直跳转到 loader 目录的C语言函数里面, 做循环操作。
2 代码:
首先 是从 start.s 跳转到 boot.c
.extern boot_entry
//跳转到 C 函数
jmp boot_entry
jmp .
来看一下 , start.s 与 boot.c 是怎么样合成的:
然后是 对于 loarder 目录的创建。
首先是 创建一个 Loader 目录。
然后再 loader 目录先 , 创建 start.S , loader.h , loader_16.h , loader_32.h 文件。
start.S 内容为:
#include "boot.h"
// 16位代码,务必加上
.code16
.text
.global _start
.extern loader_entry
jmp loader_entry
loader.h 里面没有内容。
loader_32.c 里面也没有内容。
loader_16.c 的内容为:
// 这个sam 是跟编译器说的,也就是下面的代码,全部便已成16位的模式
__asm__(".code16gcc");
void loader_entry(void) {
for(;;) {}
}
然后对于 顶层的 cmake 的修改。
然后是再 loarder 目录下 添加一个 cmake
然后还要去修改一下 编译的脚本文件。
所以, 可以知道, 首先是 编译出 boot.bin . loader.bin , 然后 将这两个文件 拼接到 disk1.img 中,并且具体的位置,也设置好了。
那么如何 从 , boot 目录,跳转到 loader 目录呢?
就是通过函数指针 直接跳转的。
#include "boot.h"
// 这里定义的是 loader.bin 加载的地址
#define LOADER_START_ADDR 0x8000
/**
* Boot的C入口函数
* 只完成一项功能,即从磁盘找到loader文件然后加载到内容中,并跳转过去
*/
void boot_entry(void) {
//这里就是实现的跳转,通过指针实现的。
((void (*)(void))LOADER_START_ADDR)();
}
最后还需要配置 一下 vscode , 这个我就不是很理解了。
编译+测试
编译没问题,
并且 单步测试也没有问题。
到达这个地方。
疑问: 这里的代码逻辑是 : 汇编---->C --->汇编----->C , 能不能将第二个汇编文件去掉呢?