3

我正在开发一个玩具操作系统和引导加载程序。我正在尝试用 C 语言编写内核,然后将其转换为二进制文件以便从引导加载程序直接跳转(即,我没有加载 ELF 或类似的东西)。

我已经设置了正确来源的链接器文件(我正在将内核加载到地址 0xC0000000)并确认objdump它正确使用它。但是,它并没有像我想要的那样将我的入口点放在开头(0xC0000000)。我想这不是该ENTRY指令的用途。

我的问题只是我想kernel_main在地址 0xC0000000 处放置一个特定的函数。有没有办法可以使用 gcc 进行编译和链接来完成此操作?

这是我的链接器文件的相关部分的样子:

ENTRY(kernel_main)

SECTIONS
{
   /* Origin */
   . = 0xC0000000;

   .text BLOCK(4K) : ALIGN(4K)
   {
       *(.text)
   }
   /* etc. */
}
4

2 回答 2

4

链接器ENTRY命令告诉链接器加载程序在加载程序时应该跳转到哪个符号。如果您正在制作自己的操作系统,那么它实际上并没有被使用,因为没有加载器。

相反,如您所知,程序只是从第一个代码地址开始。

要首先放置一段特殊的代码,你可以把它放在一个特殊的代码段中,然后把它放在列表的首位:

.text BLOCK(4K) : ALIGN(4K)
{
    *(.text.boot) *(.text)
}

列表中的段按给出的顺序放置。

于 2013-06-29T17:39:18.563 回答
3

ENTRY指令仅对支持入口点的输出格式有用。由于您使用的是二进制输出,因此这是行不通的。您可以做的是在单独的源文件(即或其他)中编写一个小entry.c存根entry.asm。然后,在ld脚本中,在该*(.text)行之前,您可以放置entry.o(.text)​​ . 这指示ld从特定目标文件加载符号(而*表示所有目标文件)。所以新ld脚本看起来像这样:ENTRY(kernel_main)

SECTIONS
{
   /* Origin */
  . = 0xC0000000;

   .text BLOCK(4K) : ALIGN(4K)
   {
       entry.o(.text)
       *(.text)
   }
   /* etc. */
}

只要entry.o只包含一个函数(简单地调用你的内核主函数),这应该可以工作。

于 2013-06-29T17:37:54.147 回答