2017-07-24 115 views
7

我一直在使用this教程編寫操作系統。我在 引導加載程序完成的部分,C用於編程(然後鏈接在一起...)。但是,就像一個筆記,我相信我的問題與gcc有關。全局變量始終初始化爲零

我構建了一個用於OS的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

你用'gcc -g3'編譯過嗎? – alinsoar

+0

@alinsoar我用'-g'編譯了它們,但我只是嘗試了'-g3',它沒有什麼區別。 –

+4

你有啓動代碼嗎?它負責設置初始化.data和.bss段。 –

回答

1

編譯器不會清除未初始化的全局變量爲零,其邏輯在建內部裝載機, 所以當你分配內存對於數據段,那麼它的大小也包含BSS部分。所以你必須檢查bss段偏移量,使用數據段和memset()將它們對齊爲'0',以調整&的大小。

由於您正在編寫操作系統,所以可能所有的庫例程都不可用,所以最好使用匯編編寫memset()函數。

+0

如果你正在分配內存或memset完整的內存,那麼這可能不是必需的,但有時由於對齊loader()從ELF圖像複製一些額外的數據,這可能也是垃圾。這一切都取決於你的加載器和ROM - > RAM傳輸實現 – anshkun