2

我正在按照教程为我自己的操作系统移植 NewLib 。

它说一旦我完成了我的 crt0,我必须“将它作为第一个对象链接”。我怎样才能做到这一点?

4

3 回答 3

4

它说一旦我完成了我的 crt0,我必须“将它作为第一个对象链接”。

这正是所说的。当您的操作系统的应用程序被链接时,crt0 必须是链接器命令行上的第一个目标文件:在任何其他目标文件之前。

传统上,UNIX 链接器通过从第一个对象/库循环到最后一个对象/库开始查找来解析符号。放置crt0为第一个目标文件确保系统符号(函数、变量)是从 crt0 文件中挑选出来的,而不是从其他文件中挑选出来的。

此外,正如 R.. 所指出的,传统的链接器假定应用程序的入口点位于代码段的开头。这也适用于链接页面上的源代码:代码中的第一个符号是_start,程序入口点的常用名称。

例如,gcc -v a.c -o a在我的 Debian 上运行(注意-v),可以看到以下链接命令(为了便于阅读,我添加了新行):

/usr/lib/gcc/i486-linux-gnu/4.4.4/collect2
--build-id
--eh-frame-hdr
-m elf_i386
--hash-style=both
-dynamic-linker /lib/ld-linux.so.2
-o a 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crt1.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crti.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtbegin.o
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib
-L/lib/../lib
-L/usr/lib/../lib
-L/usr/lib/gcc/i486-linux-gnu/4.4.4/../../.. 
/tmp/ccndJ4YV.o
-lgcc
--as-needed
-lgcc_s
--no-as-needed
-lc
-lgcc
--as-needed
-lgcc_s
--no-as-needed 
/usr/lib/gcc/i486-linux-gnu/4.4.4/crtend.o 
/usr/lib/gcc/i486-linux-gnu/4.4.4/../../../../lib/crtn.o

可以看到 crt1 是命令行上的第一个对象。查看链接器脚本(-m elf_i386-> find /usr -name '*elf_i386*'-> 在我的系统上/usr/lib/ldscripts/elf_i386.x)可以验证在 Linux 上没有crt0,但有:crt1, crti, crtbegin, crtend, crtn。并且应用程序对象文件(/tmp/ccndJ4YV.o在上面的示例中)放在crtbegin和之间crtend

于 2010-08-01T11:45:20.223 回答
1

在跳转到 之前main(),c 运行时需要做初始化,这个工作由cert{i,n,0}.

在此处输入图像描述

于 2016-06-09T15:57:56.383 回答
0

至少用于测试的一种方法是将 crt0.o 作为编译器或链接器命令行上的第一个文件。

对于生产,您可以将其放在链接器命令文件中。

于 2010-08-01T11:38:59.200 回答