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