简体   繁体   中英

global variable always initialized zero

I've been writing an OS using this tutorial. I am at the part where the boot loader is completed and C is used for programming (and then linked together ...). But that just as a note, I believe the problem I have is related to gcc.

I build an i386-elf cross compiler for the OS. And everything works fine, I can execute my code everything works. Except that all global variables are initialized zero, although I provided a default value .

int test_var = 1234;

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

If I debug this code with GDB, I get: ( 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

If i run the same code on my local machine ( gcc-6.3.0, target: x86_64 ), it prints 1234 .

My question is: Did I misconfigure gcc, is this a mistake in my OS, is this a known problem? I couldn't find anything about it.

My entire source-code: link I use the following commands to compile my stuff:

# ...
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: As @EugeneSh. suggested here some logic to make sure, that it's not removed:

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

Sadly it prints It's zero

Compiler never clears uninitialized global variables to zero, its logic in built inside loader, So when you allocate memory for data segment then it size contains bss section also. So you have to check bss section offset, alignment & size withing data segment and memset() them to '0'.

As you are writing your OS so may be all the library routines are not available so better write memset() function using assembly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM