Going Further on x86

From OSDev.wiki
Revision as of 15:50, 2 June 2016 by Glauxosdever (talk | contribs) (Add some tips based on some of my experience)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

You have completed Bare Bones for x86. Now what, you may be wondering. Welcome to the OS development world!

Preparing For The Real

Grab a copy of the Intel manuals.

First Steps

You may wish to enable paging in boot.s, and continue with a higher half kernel, so userspace programs can be loaded at 4 MiB without conflicts with the kernel binary. It might look a bit hacky at first, but after a while you will get used to it.

Considering Security

You should have paging enabled at this point. You are also using an ELF format for the kernel binary, right? Do you know what do .text, .data, .rodata, .bss mean? Right, they are the sections of the executable. In .text the instructions for the processor are stored, in .data there is data, in .rodata there is read-only data, in .bss there is uninitialised data. There may be more sections, but let's focus on these for now. You should align them at 4 KiB boundaries, and apply read-only/read-write permissions in your page tables. Of course, set also the WP bit, so these permissions are enforced for the kernel too.

Managing Memory

Soon you will need to allocate something. You first need to obtain the list of free pages. You for sure also need a list of free physical pages, so you know where to physically allocate next. A common way to do it is to create a linked list, that is to store the physical address of the next free page at the start of the previous free page, so only free memory is used to store it. But, you have paging enabled, so you can't arbitrarily write to every part of memory. You can instead map a bit of memory at a time, and write to it the address of the next free page. Now, creating a physical memory manager, a virtual memory manager and a kernel heap allocator is totally in order.

Interrupts

Yes, you need interrupts to create a proper operating system. You will need to handle exceptions when something goes wrong (either with the kernel, either with a user program), and read from peripherals only when data is received (instead of polling). You will also need some efficient and somewhat accurate way to wait when you need to, PIT looks like a good idea for older hardware.

Conclusion

Operating system development is not easy and is not hard. It's pretty hard. The above (incomplete) list is nothing compared to the complexity involved in a mature operating system.