Kernel compilition without -O flag results in garbage
Posted: Tue May 01, 2012 6:52 am
Hello friends,
I tried searching for this specific problem, but can't seem to find an answer to my problem. Nor can I find one on my own.
The situation: I am trying to write my own OS (just for learning purposes), nothing special. I've written my own bootloader, totally from scratch, I am not using GRUB, Lilo or anything else. This bootloader of mine, loads a C-written kernel, compiled using GCC (cross compiler, following the instructions from the OSDev Wiki).
The problem: when I compile the C code, I have to pass the -O flag to gcc. Otherwise, when my bootloader loads the kernel all I get is garbage written to the screen, instead of a small text, that it should print out. When I specify the -O flag, it works OK, until I start doing loops and some more serious programming, then it shows random errors (e.g. just stopping to work at some point, or printing garbage, or other random stuff).
The kernel is loaded at address 0x10000 and executed by the bootloader via "jmp 0x10000". Here is the kernel source code:
Linker script:
Compilation commands:
Like I said, this code works if the "-O" flag is there, otherwise I get garbage on the screen. But I don't want the -O flag, because it messes with my loops later.
Please, give me an idea what I am doing wrong and how to remove the "-O" flag.
I tried searching for this specific problem, but can't seem to find an answer to my problem. Nor can I find one on my own.
The situation: I am trying to write my own OS (just for learning purposes), nothing special. I've written my own bootloader, totally from scratch, I am not using GRUB, Lilo or anything else. This bootloader of mine, loads a C-written kernel, compiled using GCC (cross compiler, following the instructions from the OSDev Wiki).
The problem: when I compile the C code, I have to pass the -O flag to gcc. Otherwise, when my bootloader loads the kernel all I get is garbage written to the screen, instead of a small text, that it should print out. When I specify the -O flag, it works OK, until I start doing loops and some more serious programming, then it shows random errors (e.g. just stopping to work at some point, or printing garbage, or other random stuff).
The kernel is loaded at address 0x10000 and executed by the bootloader via "jmp 0x10000". Here is the kernel source code:
Code: Select all
void kmain() {
clear_screen(); // my own function, it just clears the screen
printf("Hello, cruel world! This is my OS!"); // my own function, assembly code writing to the video memory
set_cursor_position(0,1); // again my own function, using out assembly to set the cursor
// get start and end address of memory probe
uint16_t end_address_memory_map = (uint16_t)*((uint16_t*)0x7bfb);
uint16_t start_address_memory_map = 0x7e00;
uint16_t memory_map_length = end_address_memory_map - start_address_memory_map;
// print some info
printf("Memory map start address %d and its end is at %d (length: %d).", start_address_memory_map, end_address_memory_map, memory_map_length);
set_cursor_position(0,2);
}
Code: Select all
OUTPUT_FORMAT("binary")
ENTRY(kmain)
startaddr = 0x10000;
SECTIONS {
.text startaddr : {
code = .;
*(.text)
*(.rodata)
}
.data (startaddr + (data - code)) : {
data = .;
*(.data)
}
.bss (startaddr + (bss - code)) : {
bss = .;
*(.bss)
}
end = .;
}
Code: Select all
TOP := $(shell pwd)
MY_LD := /usr/src/cross/bin/i586-elf-ld
MY_GCC := /usr/src/cross/bin/i586-elf-gcc
GCC_FLAGS := -Wall -nostdinc -nostartfiles -nodefaultlibs -nostdlib -fno-builtin -c -O -masm=intel
$(MY_GCC) $(GCC_FLAGS) -o kernel/src/main.o kernel/src/main.c
$(MY_LD) -T $(TOP)/kernel/ld.script -o kernel/kernel.img kernel/src/main.o kernel/src/console.o kernel/src/port.o
Please, give me an idea what I am doing wrong and how to remove the "-O" flag.