2017-07-24 1 views
7

J'ai écrit un OS en utilisant le tutoriel this. Je suis à la partie où le chargeur de démarrage est terminé et C est utilisé pour la programmation (et ensuite lié ensemble ...). Mais ce n'est qu'une note, je crois que le problème que j'ai est lié à gcc.variable globale toujours initialisée zéro

Je compile un compilateur croisé i386-elf pour le système d'exploitation. Et tout fonctionne bien, je peux exécuter mon code tout fonctionne. Sauf que toutes les variables globales sont initialisées à zéro, bien que j'ai fourni une valeur par défaut.

int test_var = 1234; 

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

Si je déboguer ce code avec GDB, je reçois: (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 

Si je lance le même code sur ma machine locale (gcc-6.3.0, target: x86_64), il imprime 1234.

Ma question est: Ai-je mal configuré gcc, est-ce une erreur dans mon système d'exploitation, est-ce un problème connu? Je n'ai rien trouvé à ce sujet.

Mon entière code source: link J'utilise les commandes suivantes pour compiler mes affaires:

# ... 
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: Comme @EugeneSh. proposé ici une certaine logique pour vous assurer que ce n'est pas supprimé:

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

Malheureusement, il imprime It's zero

+0

avez-vous compilé avec 'gcc -g3'? – alinsoar

+0

@alinsoar Je les ai compilés avec '-g', mais j'ai juste essayé' -g3' et cela ne fait pas de différence. –

+4

Avez-vous un code de démarrage? Il est responsable de la configuration des segments initialize .data et .bss. –

Répondre

1

compilateur efface jamais les variables globales non initialisées à zéro, sa logique intégrée à l'intérieur de chargeur, Ainsi, lorsque vous allouer de la mémoire pour le segment de données, sa taille contient également la section bss. Donc, vous devez vérifier le décalage de la section bss, aligner la taille & avec le segment de données et memset() avec la valeur '0'. Comme vous écrivez votre système d'exploitation, il se peut que toutes les routines de la bibliothèque ne soient pas disponibles, alors mieux écrire la fonction memset() en utilisant l'assemblage.

+0

Si vous allouez de la mémoire ou du memset à la mémoire complète, cela peut ne pas être nécessaire, mais parfois, en raison de l'alignement, loader() copie des données supplémentaires de l'image ELF qui peuvent également être inutiles. Tout dépend de votre chargeur et ROM -> implémentations de transfert RAM – anshkun