即使有完美的启动装载机,我也会在业余时间一次打开和关闭作为教育练习。我遇到了一个问题。
我能够执行初始启动和链接加载其他扇区没有问题。如果我正在编写自己的操作系统,我会很高兴。 :)相反,我正在尝试引导Linux。我面临的挑战是双重的。
需要注意的另一点是我已经处于32位保护模式,因为我正在处理创建EFI启动系统,所以16位实模式在这里不是一个真正的选项,消除了实模式的启动在内核中的位置。
答案 0 :(得分:2)
@Jester找到了我的问题并回答了这两个问题。解决方案实际上在file that I had linked,但我错过了相关部分。我在这里列出了相关内容供后人使用:
在32位引导协议中,加载Linux内核的第一步 应该是设置启动参数(struct boot_params, 传统上称为“零页面”)。 struct boot_params的内存 应该被分配并初始化为全零。然后是设置标题 从内核映像的偏移0x01f1开始应该加载到struct中 boot_params并检查。设置标头的结尾可以计算为 遵循:
0x0202 +偏移量0x0201处的字节值
除了读取/修改/写入struct的setup头之外 boot_params作为16位引导协议的引导加载程序应该 也填充struct boot_params的其他字段 在zero-page.txt中描述。
设置struct boot_params后,引导加载程序可以加载 32/64位内核的方式与16位引导协议相同。
在32位启动协议中,内核通过跳转到启动来启动 32位内核入口点,即加载的起始地址 32/64位内核。
在进入时,CPU必须处于32位保护模式并进行分页 禁用;必须使用选择器的描述符加载GDT __BOOT_CS(0x10)和__BOOT_DS(0x18);两个描述符必须是4G扁平段; __BOOT_CS必须具有执行/读取权限,并且__BOOT_DS 必须具有读/写权限; CS必须是__BOOT_CS和DS,ES,SS 必须是__BOOT_DS;必须禁用中断; %esi必须占据基础 struct boot_params的地址; %ebp,%edi和%ebx必须为零。
64位指令也可以在同一份文件中找到。