以下均针对 qemu_x86_64
将 am/src/x86/qemu/boot/bootblock.o
, /dev/zero * 1024
, $(IMAGE).elf
写入镜像
镜像文件是由 512 字节的 “MBR”、1024 字节的空白 (用于存放 main
函数的参数) 和 hello-x86_64-qemu.o
组成的。
由 start.S
和 main.c
共同构建
start.S
构建基础数据结构,然后跳转到 load_kernel()
void load_kernel(void) {
Elf32_Ehdr *elf32 = (void *)0x8000;
Elf64_Ehdr *elf64 = (void *)0x8000;
int is_ap = boot_record()->is_ap;
if (!is_ap) {
// load argument (string) to memory
copy_from_disk((void *)MAINARG_ADDR, 1024, -1024);
// load elf header to memory
copy_from_disk(elf32, 4096, 0);
if (elf32->e_machine == EM_X86_64) {
load_elf64(elf64);
} else {
load_elf32(elf32);
}
} else {
// everything should be loaded
}
if (elf32->e_machine == EM_X86_64) {
((void(*)())(uint32_t)elf64->e_entry)();
} else {
((void(*)())(uint32_t)elf32->e_entry)();
}
}
先把 mainarg_addr
读入到 0x10000
再把 elf 加载到 0x8000
接下来加载并跳转至 elf 入口:start64.S:_start
它将会转换至 64 位模式,并跳转到 trm.c:_start_c
更新栈指针,读入参数地址到 rdi,跳转执行 main