移植NewLib:crt0

时间:2010-08-01 10:59:25

标签: c linker cross-compiling newlib

我正按照a tutorial为我自己的操作系统移植NewLib。

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

3 个答案:

答案 0 :(得分:4)

  

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

这恰恰意味着什么。当链接到OS的应用程序时,crt0必须是链接器命令行上的第一个目标文件:在任何其他目标文件之前。

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

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

E.g。在我的Debian上运行gcc -v a.c -o a(请注意-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,但有: crt1crticrtbegincrtendcrtn。并且应用程序对象文件(上例中的/tmp/ccndJ4YV.o)放在crtbegincrtend之间。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

在跳转到main()之前,c运行时需要进行初始化,此作业由cert{i,n,0}处理。

enter image description here