Monday, June 1, 2009

segments

By the way - my segmenting problem has disappeared without delving into compiler internals. I think someone has added the correct segment prefix overrides when generating x86 code, and that has fixed my problem. I'm not going to investigate exactly who fixed what; I'm just happy that it works. Now I can concentrate on writing user code, and fixing the kernel when it breaks. Things are starting to move ahead, and there is light at the end of the tunnel. I have loadable modules that load (using GRUB). I can then parse the elf header, map the various elf segments to virtual memory addresses, and execute them. If I don't use stdlib it works great. My next job is to figure out why I can link with stdlib, but printf doesn't print. I can call puts() and it works just fine (which is a user-space function that calls a kernel-space function) so I know the overall mechanism is ok - I wonder why printf doesn't work. It may have to do with me not porting newlib as I should have.

GCC versions and features

Just a quick update:
I have finally managed to get multitasking working. It was working before, but not exactly what I wanted - now it runs all in user mode. So to try it out, I created 2 loadable modules for GRUB, so I could see how to load an executable. The modules are elf executables that I created with my newly ported GCC 4.3.3. Everything went well until link time. Then I discovered that I needed a file called crt0.o. It's a bit hard to find information on this file, because its standard, but OS specific. Anyway, again thanks to the guys as OSDEV I ported newlib (stdclib) and created the crt0.o file as well. So then I was suprised to find out that I needed 2 more files - crtbegin.o and crtend.o. These are even harder to find information about, and to this day I am not clear on their responsibilities, and how it is different from crt0.o. I think it has to do with C++, but my load modules are written in pure C, so I don't really know why I need them. Well, I found out that GCC is supposed to provide implementations of these files, and since I'm using ELF format I figured if I copied their configuration files everything would be ok. For some reason when I built GCC 4.3.3 as a cross compiler for KOS, these files were not created. I didn't even know where I should start looking for them, so I did a search to find the native-compiled versions. Interestingly enough, I did find cross-compiled versions, but in my GCC 4.2.1 directory. I guess back when I was testing different versions of GCC to find out why I couldn't port them to Cygwin without major headaches, I build 4.2.1 as a cross-compiler as well, and created these files. So now it seems that 4.3.3 has a bug that won't let me create crtbegin.o and crtend.o when building as a cross compiler. I will have to try 4.4 one of these days to see if it is still the case.

Sunday, April 5, 2009

A truly brave band

I know this is supposed to be a blog about my operating system, but I just found out that the famous rock band Coldplay is planning on recording at least part of their next album in Syria. This really takes guts - not many bands these days are willing to support a country so wholeheartedly that is known for gross human rights violations. I guess when you believe in something, you have to show it. And I heard Bashar Assad is a personal fan - maybe he will let the band members help him torture some political prisoners or shoot some Lebanese - you know, just for fun. Way to go, guys.

Sunday, March 29, 2009

Some confusing results. Just by changing the compiler, my kernel function seems to work - at least on one computer. I'm going to have to investigate this a bit further, because the changes don't seem to work on the second computer. There are slight differences in the emulator versions (Bochs) as well as slight changes in the code. In any case, the real test is trying it on real hardware - hopefully this weekend I will have some time. In the meantime, my next goals are to port stdlib (and of course fill in any missing kernel functions along the way) and then to get a disk running. I have a floppy driver, but that is obsolete hardware these days. I need to write a proper ATA driver (or maybe SATA). But first I will get stdlib started (at least as far as I can before I need file access).

Wednesday, March 25, 2009

tools

Well I ran into some problems with my code. Turns out that the same kernel function I was calling from kernel mode crashes when called from user mode. I couldn't figure it out for the longest time - until I thought about the differences I have between kernel mode and user mode. Turns out that the root of the problem is two-fold. First of all, I am using a segmented memory model, which not a lot of people do these days. It's a great feature of the chip, and I'm glad iNTel left it in. But of course, the compiler I'm using doesn't know how to generate code using segments. That's fine when I'm running in kernel mode, because my segments start from 0x0 and run the full 4GB, so they really don't come into play. But when I switch over to user mode, all of a sudden my stack segment and code segment have different bases. So my poor compiler (GCC 3.4.6) is generating a DIV instruction which takes the code segment as a default, and generating an address for a variable which is on the stack! This would work fine in any case where the code segment happened to be equal to the stack segment (which is 99% of the code out there today). But when they are different, the compiler just doesn't know how to differentiate between the heap and the stack, and gives me the wrong address. I guess it was lucky that I got a divide by zero exception so it was easy to spot. It could have been a lot worse.
So now my next task is getting my tools up to speed so my user mode code works! That means getting GCC to understand segments. Today I completed the first step - adding KOS as a new target OS to GCC. That sounds palpable - except for the horrible lack of documentation to GCC. Sure, they go into detail on all kinds of useless things [http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gccint/index.html#toc_Target-Macros], but where's the step-by-step on how to add a new target? Ok, maybe that's too much to ask. But how about a listing of the files I need to edit? Thanks to the guys on OSDEV [http://wiki.osdev.org/OS_Specific_Toolchain], this task moved from possibly months of painful searching, to about 2 weeks (an hour here and there of course) of playing around. That tutorial was a real life saver. I mean - my interest here is to write a new OS, not play around with these tools until I happen across the correct configuration to do what I need!
Enough for now - I now have a ported, cross-compiling binutils 2.18 and GCC 4.3.3. Now for the real challenge for which there is no tutorial (hmm, maybe I should look again) - getting GCC to understand that I have different segments! The theory is simple - each time an (assembly) instruction is generated that can accept a segment override prefix (for example, div) I want to give the prefix for either the stack (SS) or the heap (CS) depending on where the variable in question is coming from. This requires understanding a bit more about GCC internals, but it is a bit more into the realm of understanding the compiler tree, rather than which files I need to edit (which I actually find easier). So good luck to me - if it works, you will hear about it here.

Monday, March 23, 2009

First Post

This is my first post for the KOS blog. Let's see how this turns out.
I needed a place where I could put all my updates in the development of the OS. I've run into some interesting problems over the past few years, and the solutions were not always easy. Hopefully if someone else runs into the same problems, they will be able to get some ideas from how I solved things.