2017-07-24 50 views
7

Pisałem system operacyjny przy użyciu samouczka this. Jestem w części, gdzie program ładujący został zakończony, a C jest używane do programowania (a następnie połączone razem ...). Ale tak na marginesie uważam, że problem, który mam, jest związany z gcc.zmienna globalna zawsze zainicjalizowana zero

Buduję kompilator krzyżowy i386-elf dla systemu operacyjnego. I wszystko działa dobrze, mogę wykonać mój kod, wszystko działa. Poza tym, że wszystkie zmienne globalne są inicjowane jako zero, , chociaż podałem domyślną wartość.

int test_var = 1234; 

// yes, void main() is correct (the boot-loader will call this) 
void main() {} 

Jeśli debugować kod z GDB, otrzymuję: (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 

jeśli uruchomię ten sam kod na moim komputerze lokalnym (gcc-6.3.0, target: x86_64), drukuje 1234.

Moje pytanie brzmi: czy źle skonfigurowałem gcc, czy jest to błąd w moim systemie operacyjnym, czy jest to znany problem? Nie mogłem nic na ten temat znaleźć.

Mój cały kod źródłowy: link używam następujące polecenia skompilować moje rzeczy:

# ... 
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" 

EDIT: jak @EugeneSh. Sugeruje tu logika, aby upewnić się, że nie jest usuwany:

#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"); 
    } 
} 

Niestety drukuje It's zero

+0

czy kompilowałeś z 'gcc -g3'? – alinsoar

+0

@alinsoar I skompilowałem je za pomocą '-g', ale po prostu próbowałem' -g3' i nie ma to znaczenia. –

+4

Czy masz kod startowy? Jest odpowiedzialny za konfigurację segmentów initialize .data i .bss. –

Odpowiedz

1

Kompilator nie czyści niezainicjowane zmiennych globalnych do zera, jego logikę w wbudowany wewnątrz ładowarki, Więc kiedy przydzielić pamięci dla segmentu danych, a następnie jego rozmiar zawiera również sekcję bss. Musimy więc sprawdzić offset sekcji bss, wyrównanie & wielkości z segmentem danych i memset() do "0".

Podczas pisania systemu operacyjnego wszystkie funkcje biblioteczne mogą być niedostępne, więc lepiej zapisz funkcję memset() przy użyciu zespołu.

+0

Jeśli przydzielasz pamięć lub pamięć kompletną pamięci, może to nie być wymagane, ale czasami z powodu programu ładującego wyrównania() skopiuj dodatkowe dane z obrazu ELF, które mogą być również wiadomościami śmieciowymi. Wszystko zależy od twoich ładowarek i ROM -> implementacji transferu RAM – anshkun