Gcc 如何将*.o对象文件链接到内核二进制文件

Gcc 如何将*.o对象文件链接到内核二进制文件,gcc,linker,kernel,Gcc,Linker,Kernel,我一直在研究内核开发。为了开发我的内核二进制文件,我使用以下命令。但是,在包含最后一个C文件(paging.o)之前,一切都很好。尽管我多次检查了paging.c代码,但它会抛出异常(无效操作码中断6)。我怀疑我的编撰稿中可能有一些错误。请帮忙。我在Windows7机器上工作,使用MinGW和Bochs nasm bootsec.asm -f bin -o bootsec.bin nasm kernel_entry.asm -f elf -o kernel_entry.o nasm empty.

我一直在研究内核开发。为了开发我的内核二进制文件,我使用以下命令。但是,在包含最后一个C文件(paging.o)之前,一切都很好。尽管我多次检查了paging.c代码,但它会抛出异常(无效操作码中断6)。我怀疑我的编撰稿中可能有一些错误。请帮忙。我在Windows7机器上工作,使用MinGW和Bochs

nasm bootsec.asm -f bin -o bootsec.bin
nasm kernel_entry.asm -f elf -o kernel_entry.o
nasm empty.asm -f bin -o empty.bin
gcc -ffreestanding -c main.c -o main.o
gcc -ffreestanding -c port_in_out.c -o port_in_out.o
gcc -ffreestanding -c mem.c -o mem.o
gcc -ffreestanding -c screen.c -o screen.o
gcc -ffreestanding -c isr.c -o isr.o
gcc -ffreestanding -c timer.c -o timer.o
gcc -ffreestanding -c paging.c -o paging.o
ld -T NUL -o kernel.tmp -Ttext 0x1000 kernel_entry.o main.o mem.o port_in_out.o screen.o isr.o timer.o paging.o
objcopy -O binary -j .text kernel.tmp kernel.bin
copy /b bootsec.bin+kernel.bin+empty.bin os-image.img 

很明显,你的问题中缺少信息。您应该为代码和“NUL”链接器脚本提供源代码

我建议您使用“objdump-D out.elf”检查最终的elf文件,并确保其中的内容正常

编译脚本中唯一明显的奇怪之处是传递给objcopy的“-j.text”。这告诉objcopy仅从对象文件复制“.text”部分。是否确实要对“.c”文件执行此操作? 大多数“.c”文件都将编译成带有“.data”、““.text”和“.bss”的对象文件,除非您在使用“.c”文件时非常小心

您应该通过链接器脚本而不是objcopy来控制哪些部分应该被丢弃,哪些部分应该保留在最终的elf文件中

例如,如果您确定paging.c不需要“.data”和“.bss”部分,那么:


您确定paging.c中的代码正确吗?我猜这个文件控制MMU,很有可能在这个文件中启用MMU。如果启用了MMU,CPU将立即看到完全不同的内存视图(实际上,在执行一些指令后,取决于管道深度)。如果发生这种情况,您需要确保CPU执行所在的位置包含有效代码(通常通过两次映射内核)。如果不这样做,您的CPU可能会开始执行垃圾,从而导致您看到的无效操作。

代码或编译脚本没有问题。问题出在我身上。我的bootsec.bin只错误地将内核条目的15个扇区加载到内存中。但是当添加paging.o时,我的内核条目变成了29个扇区