因此,我一直在研究汇编,并且一直想知道,在加载内核时如何将不同的段加载到不同的内存区域中。我知道对于OS中的用户代码,链接器和OS可以简单地将代码和数据放在他们想要的任何区域,但是这个问题更特定于内核,而内核没有OS来放置.code和。数据放入不同的区域。
说我有一个简单的内核:
.data
var dw 123
.code
mov eax ebx
引导加载程序或如何处理引导加载程序实际上将内核代码加载到数据的单独区域中?并说我有5个不同的程序集文件,都带有.data段,这些变量是否都一个接一个地加载到同一区域?
由引导加载程序来处理,因此它最终取决于引导加载程序的工作,但是通常,引导加载程序以PECOFF或ELF之类的标准格式加载标准可执行映像。它们像操作系统加载程序可执行文件一样加载内核。
部分存在,因此具有相同名称的部分的内容都将在可执行文件中连续分组在一起。链接器将获取所有输入目标文件中所有.text
节的内容,并将它们组合为输出可执行文件中的一个.text
节。同样,它对.data
和其他命名部分也将执行相同的操作。
链接器将所有这些组合的节放在一个可执行文件中,并将它们一个接一个地放置,从而创建一个可以加载到内存中的连续映像。在操作系统下,可执行文件将以单个连续块的形式加载到内存中。如有必要,将使用重定位来说明可执行文件在与打算加载的位置不同的地址处加载,并且未初始化的数据段(.bss)将用零初始化。最后,可执行文件在内存中每一页的权限将根据它们所属的段进行调整。例如,在.text
部分中的页面将被标记为只读和可执行,而在.data
部分中的页面将被标记为可读/写而不是可执行。
((请注意,这简化并掩盖了链接器和操作系统如何创建和加载可执行文件的许多细节。可以合并,重命名,丢弃等部分。可以在段之间插入填充空间,以便它们在页面上对齐。 。在ELF下,目标文件中的命名节实际上是在可执行文件中转换的未命名程序段,而这些程序段决定了页面权限。)
引导加载程序加载的内核可执行文件非常类似于操作系统,但是可能不支持重定位,并且不会更改页面权限,因为它们需要操作系统才能工作。内核本身负责设置自己的页面权限。
因此,内核代码和数据被加载到一个连续的内存区域中,而该内存区域又细分为代码,数据和内核使用的任何其他部分的单独区域。