M3 Operating System Development

A chronicle of the development of the M3 operating system

Archive for the ‘Status Update’ Category

Initialization Order of Operations – getting to pmode

leave a comment »

I was playing around with my initialization code and realized I had a problem. I had stripped down my boot sector so that it basically just loaded up my environment initialization code (which is a mixture of assembly and C) and threw control to that. I eliminated the code that enabled the A20 gate (since I moved this to the init code) and removed the code that put the processor into protected mode with a simple flat memory mode. However, when I tried to boot my code in the emulator, it would triple fault, which basically means the processor was put into a bad state and pooped out.

After thinking about it for a bit, I realized my error. By removing the code that put the processor in protected mode, I was keeping things running in 16-bit real mode. The initialization code that I was trying to pass control to was compiled as a 32-bit ELF file and converted to a 32-bit flat binary file. If I wasn’t putting the processor into 32-bit protected mode, then I obviously couldn’t hand it a bunch of 32-bit code to execute.

Duh.

So I restored the code that puts the processor into 32-bit protected mode, using a very simple GDT that sets up a flat memory model. Voila! Everything was back in working order. I was hoping to delay enabling 32-bit protected mode until I had the environment completely set up, but instead I will have to go with the following strategy: 

1. In the boot sector, load up the initialization code into memory, enable the A20 gate, and enable pmode with a simple flat memory model. Then hand control to the initialization code.

2. In the initialization code, fully set up the operating environment – set up the proper GDT, IDT, TSS, setup paging, etc, etc. Load up the kernel. Then activate the new memory model, turn on paging, load up the interrupts, and refresh pmode. Once we’ve got a properly initialized environment, hand over control to the kernel.

Advertisements

Written by m3os

April 17, 2009 at 6:44 pm

Code Reorg

leave a comment »

Quick update.

I did a bit of code reorganization this week, in order to prepare to meet my new boot loader / environment initialization goals. I moved some of the initialization code out of the kernel folder and into the boot folder. That folder is where the boot sector and environment initialization code will live. I also added a file – init.c – that will mediate the environment initialization. I will try to do as much as possible in C, but some things will still need to be done in assembly, which is the reason for the init.asm file.

Right now, most of the code in the init files is stubbed out with lots of TODO comments. In the next couple of days, I will be filling out some of those portions.

Written by m3os

April 14, 2009 at 8:30 pm

False Start – Setting up for development on OS X

leave a comment »

I mentioned in an earlier post that I had switched over to my EeePC once I started work on my C kernel. I was forced to switch because the development tools that come with OS X do not include support for ELF binaries, and many of the GNU development tools are not available. The version of gcc that is installed only supports the creation of Mach-O executable files, and I want to target ELF binaries, so that I can enjoy the benefit of full usage of the GNU toolchain.

In that previous post, I had mentioned that rather than go through the hassle of building a cross-compiler on my Mac that would target i386-elf binaries, I preferred to keep my development momentum going and just switch over to develop under Linux on my EeePC.

Developing on the EeePC is fine, very portable and handy. However, I often wish I could work on M3 on my Mac, with its full-size keyboard and bigger screen. So I did some research today into exactly what it would take to build a cross-compiler on OS X.

What’s a cross-compiler, you ask? Good question! A cross-compiler is a compiler that generates executables that target another platform. In my case, I would like to target ELF binaries that run on the IA-32 architecture. The flavor of Unix at the heart of OS X is called Darwin, and it does not currently support the ELF executable format. Lucky for me (and for the development world), the GNU project has built their most-excellent C compiler to be very portable, and to support a wide variety of target architectures and executable formats. So what I am able to do is to compile a version of the gcc compiler that targets ELF binaries on the i386 architecture. Once I have a cross compiler, I will be able to compile ELF binaries on OS X, but obviously will not be able to execute them on OS X. That’s perfectly OK though, since I don’t want to execute them on OS X, I want to execute them on my IA-32 system emulated by Q(emu).

There is a project out there on the interwebs that is called DarwinPorts. Essentially, it’s a repository for tools that have been built for Darwin, with a nice client application that manages dependencies and handles downloading, building and installing the software for you. Easy! And hey, they have packages for a cross-compiler toolchain. Great! I figured I would install binutils and gcc and be off to the races.

Unfortunately, things didn’t quite work out that way. There is some problem in the binutils package that was causing the compile to error out. After thoroughly googling the issue and attempting several fixes over a couple of hours, I threw in the towel. As nice as DarwinPorts is, it didn’t work out for me in this case. 

I wasn’t ready to throw in the towel on building a cross-compiler on OS X yet though. I just had to roll up my sleeves, get the source code for the packages that I needed, and build the tools myself. After a bit of work, I got everything built.

The first litmus test of course was to run my make script and have the cross-compiler build my binaries. Yes! They compiled!

Then I needed to test that the binutils tools that I used would work with my binary file, and create a floppy disk image properly. Yes! It looks like everything worked OK, and I’ve got a floppy image sitting in my folder.

Then for the big test – see if the floppy image will boot in Q… Ding! Ding! Ding! We have a winner!

Phew. In the next post I will describe exactly how I built the toolchain, because while it’s not too difficult, it’s not a walk in the park either. The end result is totally worth it though – now I can continue development of M3 on my Mac!

Written by m3os

March 29, 2009 at 9:56 am

Posted in Status Update

Rough plan of action for the near future

leave a comment »

This might be completely off, and is completely subject to change by the minute, but here’s my current thinking about what to work on in the near future. I’d like to keep development rolling, while I read up and do some research into some of the major pieces of the kernel such as memory management, process management, etc.

  • Interrupts – set up an Interrupt Descriptor Table (IDT) and write some Interrupt Service Routines (ISRs) so that the kernel can be responsive to certain important interrupts, such as clock ticks, page faults, etc.
  • Write a driver that handles the keyboard.
  • Write some test routines. I’d like to build as many tests as possible along the way, so that I know that everything is working exactly how I think it is.

I think that a two-pronged approach to this project will keep the momentum going. When I feel like coding, I will. When I don’t feel up to coding, I’ll be reading and researching and planning.

Written by m3os

March 28, 2009 at 8:50 am

Posted in Status Update

Plan for the kernel – baby steps

leave a comment »

Now that I have successfully booted into my very rudimentary C kernel, I can start working to expand that into something that is truly functional.

I’m not just going to jump right into the heavy stuff yet though. Instead, I will ease myself into the shallow waters, and once I’m comfortable I’ll wade into greater depths. It’s been many years since I wrote C code, and even back then I didn’t really get into anything too difficult. Therefore, the first order of business is to refamiliarize myself with programming in C. 

I’ve spent the last couple of days reading up, and I’m ready to start writing some code.

I’ll start exercising my C muscles by coding up some routines that will be immediately useful as I start to build out the rest of the kernel. First up is a clearscreen routine, which will clear the entire screen. Next up will be a print routine, a function that will print a null-terminated string to the screen at the current cursor position. That means it will also need to track the current cursor position. I’ll also need to add cursor handling into the clearscreen function, which will reset the screen position to line 0, position 0.

From there, I plan to write several functions that will assist in debugging, by dumping the contents of the registers to the screen, or the contents of a certain section of memory, etc. Whatever I think will be useful for debugging purposes as I start to tread into the gnarly areas of paging, memory management, etc.

Written by m3os

March 20, 2009 at 7:18 pm

Posted in Status Update

Tagged with , ,

Success! I booted my C kernel!

leave a comment »

After several hours of missteps and travel down dead-end paths, I have just now managed to boot my simple C kernel using my bootloader. All it does right now is display the letter M in the top left corner of the screen, but that M represents a lot of sweat and nearly a few tears.

I ended up having to switch over my development environment to my EeePC running Linux. The development tools for OS X do not support the ELF executable format in any fashion. I could go through the process of building a cross-compiler and getting the missing tools on my Mac, but I don’t want to go through that hassle right now. I want to just work on my kernel.

The biggest problem I had was getting the kernel code built and linked properly. I knew from previous tests with my assembly kernel that the bootloader was working properly and handing over control to the code at address 0x1000. I dutifully cobbled together a linker script that I handed to ld, and it seemed to link without error. However, whenever I loaded my code into the emulator, it would just sit there. No little M in the top left corner. No clue as to why it wasn’t working. My assumption is that the linker wasn’t linking things exactly the way that I thought it was. I don’t know what code was sitting at 0x1000, but I do know that it wasn’t the right code.

After a lot of research into linker parameters and writing linker scripts, and about a zillion failed modify/build/run cycles, I saw the light. I realized that what I needed to do to get everything glued together properly was to write a tiny little assembly program that I would link to my C kernel. The assembly program does two very important things: it provides useful information to the linker, and it calls into the kernel’s main function.

So what happens now is that the boot loader does its thing and then calls the code at address 0x1000. My little glue assembly program sits at that address, and it calls into the kernel’s main function, which right now simply displays an M in the top left corner of the screen. Eureka! Voila! Joy!

In the next day or so I will write up another tutorial explaining this entire process, complete with source code. However, right now I’m thinking about doing a little happy dance. 🙂

Written by m3os

March 15, 2009 at 8:10 am

Posted in Status Update

Tagged with , , , ,

Booting a C kernel on OS X – a bit of a snag

leave a comment »

Things were cruising along smoothly for a little while with the boot loader, but now I’ve run into a bit of a snag. Right now, the M3 boot loader will load up my simple “kernel” stub written in assembly just fine, but the goal for the M3 kernel is to have the entire thing written in C. So the next logical step in my development process is to figure out how to get my boot loader to load and hand over control to a simple C “kernel”, which is really just a stub that will print a line of text on the screen or something equally simple.

For this purpose, I’ve borrowed a simple C “kernel” from this article about mixing C and assembly. I was able to compile the code just fine, but my problems started when it came time to link everything together. I was getting errors about invalid command line parameters and the like. Particularly, it didn’t like the -T option, which indicates to the linker where the text section of the code should be loaded in memory. On OS X, the ld command has no such option.

After digging a bit deeper, I learned that the OS X tools don’t support the same binary file types as those on Linux or Windows. Notably absent is the ELF binary type – OS X dev tools simply don’t support the creation of such files, because OS X doesn’t support that format. Instead, OS X uses what’s called the Mach-O binary format.

I found what I think to be the command line equivalent of -T for ld on OS X. The option is -segaddr. I got everything linked together, but when I tried to run my code on Q(emu) it just hung.

At this point, I have two choices. The first is that I could dig around through some OS X documentation and try to figure out how to output a flat binary file instead of Mach-O. The second is that I take out the Eee PC and move my development over to that box, since it’s Linux.

I’m not giving up on OS X just yet, so for now I’m going to do a bit of research into the OS X dev tools and try to figure out how to get the linker to do my bidding. If that proves to be a no-go, then I’ll move over to Linux. Gotta keep the momentum going.

Written by m3os

March 14, 2009 at 9:03 am

Posted in Status Update

Tagged with , , ,