Dav*_*zer 5 linux boot assembly
即使有完美的引导装载机可供使用,我也在业余时间一次打开和关闭作为教育练习.我遇到了一个问题.
我能够执行初始启动和链接加载其他扇区没有问题.如果我正在编写自己的操作系统,我会很高兴.:)相反,我正在尝试引导Linux.我所面临的挑战是双重的.
需要注意的另一点是我已经处于32位保护模式,因为我正在处理创建EFI启动系统,因此16位实模式在这里不是一个真正的选项,从而消除了实际模式的起始位置.核心.
@Jester 找到了我的问题并回答了这两个问题。解决方案实际上位于我链接的文件中,尽管我错过了相关部分。我将相关的文章放在这里供后代使用:
在32位启动协议中,加载Linux内核的第一步应该是设置启动参数(struct boot_params,传统上称为“零页”)。struct boot_params 的内存应该被分配并初始化为全零。然后,应将内核映像偏移 0x01f1 处的设置标头加载到 struct boot_params 中并进行检查。设置头的结尾可以计算如下:
0x0202 + 偏移量 0x0201 处的字节值
除了像 16 位引导协议那样读取/修改/写入 struct boot_params 的设置头之外,引导加载程序还应该填充 struct boot_params 的附加字段,如 Zero-page.txt 中所述。
设置struct boot_params后,引导加载程序可以像16位引导协议一样加载32/64位内核。
在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 位指令也可以在同一文档中找到。