Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将函数放在二进制文件的最开头_C_Gcc_Linker - Fatal编程技术网

C 将函数放在二进制文件的最开头

C 将函数放在二进制文件的最开头,c,gcc,linker,C,Gcc,Linker,我正在开发一个玩具操作系统和引导程序。我试图用C编写内核,然后将其转换为二进制文件,以便从引导加载程序直接跳转到(也就是说,我没有加载ELF或类似的东西) 我已经用正确的来源设置了链接器文件(我正在加载内核以地址0xC0000000),并用objdump确认它使用正确。但是,它并没有像我所希望的那样将我的入口点放在起始点(0xC0000000)。我想这不是ENTRY指令的目的 我的问题很简单,我想把一个特殊的函数,kernel\u main放在地址0xC0000000处。有没有一种方法可以通过使

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

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

我的问题很简单,我想把一个特殊的函数,
kernel\u main
放在地址0xC0000000处。有没有一种方法可以通过使用gcc编译和链接来实现这一点

以下是我的链接器文件的相关部分:

ENTRY(kernel_main)

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

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

ENTRY
指令仅对支持入口点的输出格式有用。因为您使用的是二进制输出,所以这不起作用。您可以在一个单独的源文件中编写一个小存根(即
entry.c
entry.asm
或其他任何文件)。然后,在
ld
脚本中,在
*(.text)
行之前,您可以将
entry.o(.text)
放入。这指示
ld
从特定对象文件加载符号(而
*
表示所有对象文件)。因此,新的
ld
脚本如下所示: 条目(内核_主)


只要
entry.o
只包含一个函数(只调用内核main),就应该可以工作。

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

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

要先放置特殊代码段,可以将其放置在特殊代码段中,然后将其放在列表的第一位:

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

列表中的段按给定顺序排列。

谢谢,这是一个很好的解决方案。我测试过了,效果很好。我之所以选择Drew的答案,是因为它依赖于编译器特定的语法来为段分配函数。在我看来,Drew的回答更一般、更清晰,但两种方法似乎都很有效。非常好,谢谢。我测试了这个,它似乎工作得很好。
.text BLOCK(4K) : ALIGN(4K)
{
    *(.text.boot) *(.text)
}