Code: Select all
mov bx, 0x1000
mov dh, 2
mov dl, [boot_drive]
call load_disk ; loads [dh] sectors to [bx] from [boot_drive]
; enter protected mode
...
; jumps to 0x1000
jmp 0x1000
Code: Select all
section .text
global _start
_start:
mov esp, _stack+8192
extern main
call main
jmp $
section .bss
_stack:
resb 8192
The problem is: global and static variables do not work at all.
Code: Select all
int main() { *((char*)0xB8000) = 0x38; } // works, displays 8
Code: Select all
// global
char* vga = (char*)0xB8000;
int main() { vga[0] = 0x38; } // does not work
Code: Select all
int main() {
char* video = (char*)0xb8000;
char ch = 'P';
video[0] = ch;
}
The same applies to static variables in any function.
My setup is:
gcc/tcc elf cross-compilers (this behavior does not depend on the compiler I use);
nasm assembler;
ld linker;
qemu.
Attached is the linker script. At first I did not follow OSDev Wiki, but I read every related article when I got this issue and found no solution.
What could I do to solve this problem? I guess it comes from the linking stage; changing the values of declared global variables in C does not change their values at all. Writing their addresses to known locations and reading them from assembly doesn't work (prints random data or nothing), so probably their addresses are got wrong by the compiler. I'm sure I'm missing something.