Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
i'm writing a very simple basic os, for test. Since i've started to write some basic c functions in protected mode, as my test kernel size is growed from 4K to 8K, i see that 2 global variables are no more initialized to 0. Only if i initialize them to 0 later, the value remain stored right.
unsigned long cur_x = 0;
unsigned long cur_y = 0;
void _kmain ()
{
cur_x = 0; cur_y=0; // work only in this way.
if ((cur_y == 0) && (cur_x == 0))
{
for (;;);
}
}
Seems that the values, after the code has been loaded, are not initialized from anyone.
Basically the linker script sets up the entire binary to use certain memory locations, in this case to be linked to run at the 1 MB mark.
I use GRUB which loads my kernel to the 1 MB mark, hence the reason '.' (which is the start of the output file) is at 1 MB.
I'm not sure about a binary file, but I would make sure that all symbols are at the correct address (if you load your kernel to 0x00100000 without relocation, it won't read symbols properly).
is defined as '0x0', and '0x4'... Which would explain why you don't have 0 in them as you thought, because you would be reading from the real-mode IVT. Upon setting them to 0, you take out entry 0 of the IVT and replace it with 0.
pcmattman is totally correct in that it was probably the lack of a linker script that was the problem.
However not all of this script applies to you. All the section about *(.ctor*) and *(.dtor*) is C++ specific and is not required for C code.
Important to note is the .data section. Because you initialised your global variables, they go in here as opposed to the usual .bss segment. Originally, without a linker script, you didn't set the location of this segment, so what was possibly happening was that the .text (code) segment was getting too big and expanding into the .data area, overwriting your initial values.
Another possible explanation is that because you didn't specify the location of your .data segment, LD was placing it somewhere outside the 1MB mark, which will of course not be accessible until you set the A20 line.
Thought i'd mention this as it's always important to know WHY something went wrong, not just how to hack/fix it.
And I agree with pcmattman, if you're doing a kernel for funsies, skip the bootloader, it'll only make your life hell. If you are successful with your kernel, come back and make your own bootloader but its so nasty I would'nt reccomend it!
many thanks to have clarified the link script meaning.
Gate A20 has been enabled.
I'm developing this little kernel for a job research purpose, we need it as indipendent os, so i've also written the mbr, the loader, a little file system, and now im into the interrupt routines stuff.
JamesM wrote:However not all of this script applies to you. All the section about *(.ctor*) and *(.dtor*) is C++ specific and is not required for C code.
My kernel is C++, and I didn't think of removing them...
The same holds for my 3.4.4 gcc. Its just a valid optimisation as the bss is to be zeroed anyway and you don't need to store those 0's in the data section.
Also for completeness sake, C++ isn't the only language using ctors/dtors sections. I need it for freebasic as well, and several other languages might use it as well.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]