我一直在使用this教程编写操作系统。我在哪里 引导加载程序完成,C用于编程(然后链接在一起......)。但这只是一个注释,我相信我遇到的问题与gcc有关。
我为操作系统构建了一个i386-elf
交叉编译器。一切正常,我可以执行我的代码一切正常。除了所有全局变量都初始化为零之外,虽然我提供了默认值。
int test_var = 1234;
// yes, void main() is correct (the boot-loader will call this)
void main() {}
如果我使用GDB调试此代码,我会得到:(gcc-7.1.0, target: i328-elf
)
(gdb) b main
Breakpoint 1 at 0x1554: file src/kernel/main.c, line 11.
(gdb) c
Continuing.
Breakpoint 1, main () at src/kernel/main.c:11
11 void main() {
(gdb) p test_var
$1 = 0
如果我在本地计算机(gcc-6.3.0, target: x86_64
)上运行相同的代码,则会打印1234
。
我的问题是:我是否错误配置了gcc,这是我操作系统中的错误,这是一个已知问题吗?我找不到任何关于它的信息。
我的完整源代码:link 我使用以下命令编译我的东西:
# ...
i386-elf-gcc -g -ffreestanding -Iinclude/ -c src/kernel/main.c -o out/kernel/main.o
# ...
i386-elf-ld -e 0x1000 -Ttext 0x1000 -o out/kernel.elf out/kernel_entry.o out/kernel/main.o # some other stuff ...
i386-elf-objcopy -O binary out/kernel.elf out/kernel.bin
cat out/boot.bin out/kernel.bin > out/os.bin
qemu-system-i386 -drive "format=raw,file=out/os.bin"
编辑:@EugeneSh。这里提出了一些逻辑,以确保它没有被删除:
#include <cpu/types.h>
#include <cpu/isr.h>
#include <kernel/print.h>
#include <driver/vga.h>
int test_var = 1234;
void main() {
vga_text_init();
switch (test_var) {
case 1234: print("That's correct"); break;
case 0: print("It's zero"); break;
// I don't have a method like atoi() in place, I would use
// GDB to get the value
default: print("It's something else");
}
}
可悲的是,它打印It's zero
答案 0 :(得分:1)
编译器永远不会将未初始化的全局变量清零,它在内置加载器中的逻辑, 因此,当您为数据段分配内存时,它的大小也包含bss部分。所以你必须检查bss部分偏移,对齐和&amp;带有数据段和memset()的大小为'0'。
在编写操作系统时,可能所有库例程都不可用,因此使用汇编更好地编写memset()函数。