晨钟暮鼓-Y 2024-04-17 15:33 采纳率: 25%
浏览 8

操作系统编译内核报错

自己想写一个操作系统,在链接内核的时候报错

img


这是什么原因

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
gcc -c -m16 -march=i386 -masm=intel -nostdlib -ffreestanding -mpreferred-stack-boundary=2 -lgcc -shared libc.c -o ./temp/libc.o
ld -m elf_i386 -N -Ttext 0x8000 --oformat binary ./temp/oskernel.o ./temp/liba.o ./temp/libc.o -o ./temp/kernel.bin
echo "Done!"

.o文件都能生成,最后一个ld会报错

  • 写回答

5条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-17 15:33
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试编译一个简单的操作系统内核,并且遇到了一些链接错误。这些错误与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!"
    

    这个脚本做了两处更改:

    1. 删除了-nostdlib选项,这样链接器将自动链接标准库。
    2. 添加了-nodefaultlibs-static选项,这将阻止链接器链接任何默认的标准库,并强制静态链接所有的依赖项。

    请注意,如果你的代码包含对C标准库的调用(例如strlen、strcmp等),那么你需要提供相应的实现,因为在这种情况下你不再链接到标准库。如果你的代码不依赖于C标准库,那么上述改动应该可以解决问题。如果还有其他问题,可能需要检查libc.c中的函数实现,确保它们正确地编写并链接。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月17日

悬赏问题

  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑
  • ¥15 上传图片时提交的存储类型
  • ¥15 VB.NET如何绘制倾斜的椭圆