准备加载内核

时间:2015-12-17 01:02:51

标签: linux assembly boot

即使有完美的启动装载机,我也会在业余时间一次打开和关闭作为教育练习。我遇到了一个问题。

我能够执行初始启动和链接加载其他扇区没有问题。如果我正在编写自己的操作系统,我会很高兴。 :)相反,我正在尝试引导Linux。我面临的挑战是双重的。

  1. 我理解I need to load the kernel (Linux) into memory at 0x100000。我知道我应该在内核的偏移量0x202处找到“HdrS”签名。我也知道起始地址应该是0x214。但是,当我跳到该位置的地址时,它会停止。显然,围绕这个包装调试器非常困难。 :) 我是否遗漏了确定内核正确起始地址所必需的一系列事实?
  2. 我怀疑(1)的答案可能与需要用硬件发现信息填充某些内存区域有关。我在OSDev Wiki上看到了几个对此的传递引用,但我似乎在这里缺少,并且确切地说需要哪些数据。 引导加载程序是否负责硬件发现?如果是这样,需要将哪些数据放在哪里?
  3. 需要注意的另一点是我已经处于32位保护模式,因为我正在处理创建EFI启动系统,所以16位实模式在这里不是一个真正的选项,消除了实模式的启动在内核中的位置。

1 个答案:

答案 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位指令也可以在同一份文件中找到。