引自免费微信小程序:皆我百晓生
看起来你在尝试编译一个简单的操作系统内核,并且遇到了一些链接错误。这些错误与GLOBAL_OFFSET_TABLE_
有关,这是链接器在处理全局偏移表(GOT)时使用的符号。全局偏移表用于支持动态链接和位置无关代码(PIC)。在你的例子中,由于使用了-nostdlib
选项,标准库函数没有被正确链接。
解决这个问题的方法是移除-nostdlib
选项,让GCC自动链接所需的库。同时,为了保持兼容性,你需要确保你的代码符合古老的i386体系结构,因此需要添加额外的链接选项。以下是修改后的compile.sh
脚本:
#!/bin/bash
rm -rf temp
mkdir temp
nasm -f elf32 oskernel.asm -o ./temp/oskernel.o
nasm -f elf32 liba.asm -o ./temp/liba.o
# 移除 nostdlib 选项
gcc -c -m16 -march=i386 -masm=intel -ffreestanding -mpreferred-stack-boundary=2 libc.c -o ./temp/libc.o
# 添加 -nodefaultlibs 和 -static 链接选项
ld -m elf_i386 -N -Ttext 0x8000 --oformat binary \
./temp/oskernel.o ./temp/liba.o ./temp/libc.o -o ./temp/kernel.bin \
-nodefaultlibs -static
echo "Done!"
这个脚本做了两处更改:
- 删除了
-nostdlib
选项,这样链接器将自动链接标准库。 - 添加了
-nodefaultlibs
和-static
选项,这将阻止链接器链接任何默认的标准库,并强制静态链接所有的依赖项。
请注意,如果你的代码包含对C标准库的调用(例如strlen、strcmp等),那么你需要提供相应的实现,因为在这种情况下你不再链接到标准库。如果你的代码不依赖于C标准库,那么上述改动应该可以解决问题。如果还有其他问题,可能需要检查libc.c
中的函数实现,确保它们正确地编写并链接。