views:

2145

answers:

19

This might be in vain, as I know writing an operating system is unbearably complicated (especially by oneself).

I don't expect to build the next linux, or windows.

I know it will be horrible, and buggy, and won't work, but that's fine.

I want to write everything myself, in assembly, C, and (some) C++.

This is a future project, as I'm busy with some other things at the moment and don't have the time immediately, but I figured I would ask it now, so maybe I could get lots of answers to this, and it could build up and be a useful resource for this kind of approach (everything else I have seen involved building off of minix, using an existing bootloader, building it in a virtual booting program thing, etc).

I want to set up one of my older desktops with a monitor, keyboard and mouse, and start working on a blank hard drive.

I want to learn how to write my own bootloader (I've found lots of resources about this, but for completeness, please still add some good ones), my own USB driver (if that's necessary), a CD driver (if that's necessary), etc. Everything, from the ground up.

How do I put the code onto the computer? Is it best to do it with a floppy disk? Can most computers do it from a USB stick?

What drivers do I need, and can you suggest any references to building those?

After the booting sequence--then what? How do I get into protected mode etc.

How do I manage memory without the help of an operating system? Do I just use whatever addresses I want? No initialization necessary?

What will I undoubtedly run into that will confuse me?

How can I make it either a command line O/S, and a graphical one?

What is a graphical O/S built on? Like, how would I do something like, a command line, with a font, and a picture at the top?

Where can I read about setting up a multitasking environment? (ie., having two graphical-like command lines running side-by-side).

How would I set up a sort of windowing system? How do I display graphics on the screen once simple multitasking is set up?

Believe me, I understand that this is a very complicated project, and I probably will never get around to completing it or writing anything on it of any use.

There are lots of other pieces to this I haven't mentioned, if you think of any, feel free to add those too.

Please put one "topic" per answer--for example, USB drivers, and then maybe a list of resources, things to look out for, etc.

Also, please don't suggest building off of another O/S or pre-existing code. I know I will read a lot of pre-existing code (such as the linux kernel, or example resources, existing drivers, etc) but ultimately I want to do all the writing myself. I know I should build off of something else, and there are lots of other questions on SO about that that I can read if I change my mind and go that route. But this one is all about doing the whole thing from scratch.

update

I've got lots of great answers to this, mostly about the booting process, file systems and various existing projects to read for reference.

Any suggestions on how to get it graphical? Different video modes and how to work with them, etc?

+13  A: 

http://www.osdev.org/ and http://www.osdever.net/

welcome to the OS Development world

tr3
And especially http://wiki.osdev.org!
Matthew Iselin
+8  A: 

A basic guide to making a bootable volume, a bootloader, and keyboard input:

http://joelgompert.com/OS/TableOfContents.htm

Amber
That's pretty cool.
Barry Brown
+7  A: 

I would suggest working, at least at first, on Bochs or some other virtual machine the reason being that you can take it with you wherever you want, it's easier to debug (you can see the exact state of the hardware), and if you need outside help debugging they can use the exact same 'hardware' as you.

The most useful advice I have is to get yourself into a state where you can be running C code as quickly as possible -- i.e. boot up, setup your descriptor tables, and get yourself to a point where it's safe to run compiled C. Most if not all the kernel should be in C if you want to stay sane and keep working on it. Assembly, while required in some places, is tedious and tends to be hard to debug.

hbar
I'll look into Bochs to play around for now, but I eventually want to just be building this on some PC
Carson Myers
+1  A: 

Many schools have OS classes that do much of what you describe. My school (CMU) taught OS in C, and we wrote a kernel, file system, and shell, and were provided with code for a boot loader.

Unfortunately, I wasn't able to find any definitive resource for this course (15-412) on the web, and it's evolved over time. But perhaps people could post links to sources and assignments for schools that do have good resources on the web.

Drew Hoskins
+1  A: 

check out MikeOS. Its a fairly simple OS written is readable (as in commented) assembly. Even though its fairly simple, it does have a GUI and supports some networking and multimedia.

edit: MenuetOS is graphical. Its also written is straight asm, but its more sophisticated than MikeOS

Alex
+3  A: 

I would start small and purchase an 8086 embedded development kit, and develop a multitasking OS on that. Once you have a kernel and are acquainted with working at the hardware level, you will be ready to do something more challenging.

Building even a VGA display DOS clone is a fairly challenging thing. The details are enormous. :-)

specific topics.

How do I put the code onto the computer? Is it best to do it with a floppy disk? Can most computers do it from a USB stick?

The BIOS will do elementary bootstrapping.


What drivers do I need, and can you suggest any references to building those?

anything that isn't direct cpu/memory operations. Anything that isn't directly in the CPU reference manual.


After the booting sequence--then what? How do I get into protected mode etc.

Protected mode will be part of the boot sequence.

then you start multitasking and figuring out how to start processes.


How do I manage memory without the help of an operating system? Do I just use whatever addresses I want? No initialization necessary?

Correct. You will probably want to sort out a virtual memory system eventually.


What will I undoubtedly run into that will confuse me?

not having debugging tools, not having IO


How can I make it either a command line O/S, and a graphical one?

With grief. Look up Windows 3.1 and Linux, in particular X windows.


What is a graphical O/S built on? Like, how would I do something like, a command line, with a font, and a picture at the top?

Look up X windows.


final advice: study linux/x windows. It's not perfect, but it provides an understanding of one approach. Also study embedded systems.

Paul Nathan
great answer, I already have the linux kernel handy and I'll look into windows 3.1 for sure.
Carson Myers
+17  A: 
Bob Somers
+1, but I prefer Tanenbaum Minix book (which is more aimed toward implementation), and there's really no need to only focus on theory first. He won't write an OS on the first try, anyway. He will first write a bootloader, then switch to protected mode, then handle I/O, and so on.
Bastien Léonard
+1 Used the same text book here at UNSW Australia. Very good book and he keeps the subject fun imo.
Robert Massaioli
+1  A: 

You might enjoy this tutorial named "Roll your own toy UNIX-clone OS", its very insightful and should help you on your way.

Good luck.

blacky
Matthew Iselin
+5  A: 

If you don't mind using hardware virtualisation, there is a course (book + lectures + software) that will take you 'From Nand to Tetris'. You create a full computer system entirely yourself from the (for these purposes atomic, and given) electrical NAND gate, right through to building the OS, a language, and finally coding a simple game on your personal machine.

I think it's a great idea and something I fully intend to get stuck into soon. The book is surprisingly cheap and I believe the course is taught at MIT. I can imagine no greater feeling than having the full, complete knowledge of an entire system you built yourself from the ground up.

Link: http://www1.idc.ac.il/tecs/

Sam
I will take a look at this
Carson Myers
+4  A: 

At its lowest level the minimum that an operating system needs to be able to do is to drive a system's hardware in some way. If you're going to start with a PC then you need to write code that can be loaded by it from some device or another. PCs have a BIOS in firmware which determines how the hardware performs some initialization (at least video, keyboard, and some form of storage or boot loader).

So start by learning the low level details of how to use the BIOS (how to write a program that the BIOS can load and execute). That will eventually morph into your boot loader. Start small. Just get a program that prints: "Hello, Linus" directly from the BIOS boot process (on a floppy would be a good start ... or on a hard drive if you like).

From there I'd recommend writing a very simple serial driver ... update your boot loader to initialize some serial port, and start a download there from. Then it can execute the code it pulls across. From there write a bit of bootstrap that can write to another set of blocks (we haven't implemented a file system yet ... not even partition table parsing; so we'd just deal with raw ranges of blocks on the disk at first).

At that point your boot loader should be able to pull new code across the serial line, dump it into a partition (yes, implement partition table handling of some sort ... whether it conforms to standard PC conventions is up to you at this point), and execute it.

From there you should be able to work on far more sophisticated features. From this base you can write and compile a new "kernel" ... reboot your testbed, and have the new kernel deployed to it.

(Your bootloader should take some signal, such as a BREAK over the serial handshaking lines as a command to skip the download and just boot the existing image; and it should handle some timeout in this way as well).

From there write a very simple terminal layer and command shell? A filesystem? Implement commands to download new executable content other than the kernel (files or objects of some sort). And so on.

Naturally you could have started with a console driver using the PC keyboard and video (the BIOS INT 0x16h and INT 0x10H stuff, respectively, if I recall correctly). However, I'd suggest starting with a serial driver since you can then automate your build/deploy/test cycle from any other existing (functional) system. Since your new OS will start as a cross-compiled project it's going to be essential for you to have a streamlined way of handling that.

I don't know how far you want to take your project. A reasonably impressive goal would be to achieve "self hosting." If you can create a simple assembler/compiler that can allow you to use your new OS to (re-)build, link, and boot into a working version of your new OS ... then you've achieved that goal. (Note that's not a requirement. Many embedded systems are never going to be self-hosting and there's nothing wrong with that).

Jim Dennis
good rundown of what's to come in the near future. +1
Carson Myers
+3  A: 

I see plenty of good references to OS development sites, so I'll describe a different approach:

If you want the experience of implementing an OS from bare metal, there are way better hardware choices than an old PC. With the PC architecture, you will spend an inordinate amount of your time coding around uninteresting artifacts of its 30 year design history. For example, just the bootloader part of the project has probably burned out many a brave programmer.

For example, you'll need one set of drivers to read your kernel off of disk and/or the network. Then you'll need code to get into protected mode. At that point, you need another set of drivers! Very little of the work you do to get the chip into protected mode will be transferable after that point. You want to run it on a different PC +- 4 years and you'll need yet another set of drivers.

Look into bootstrapping an ARM or other 32-bit "embedded" chip. Inexpensive development boards are available, or you can solder your own! Some have built-in ethernet and usb. I think you will have more fun working on a sane, non-crusty architecture, and perhaps end up with some re-usable skills.

Marsh Ray
not exactly what I asked for, but +1 for sending me on a tangent of reading
Carson Myers
Marsh is giving you good advice. The low-level details of the x86/BIOS architecture are complex. You'll likely get bogged down on these details, leaving you unable to focus on the bigger issues like memory management and process scheduling. Go for a "cleaner" architecture with a serial port. You'll be happier in the long run.
Barry Brown
+1  A: 

Study the A2 System (formerly called the Oberon system) for ideas you can steal. It is a graphical OS built by just two people, although admittedly one is Niklaus Wirth. First released around 1990 and the speed is astonishingly good. There is a book by Gutknecht.

Norman Ramsey
+1  A: 

Take a look at Minix. Study the source code along with "Operating Systems Design and Implementation". Consider making contributions to the project. I think Minix is a really good and promising OS in the making. It is also well funded project. That means, you might even get paid for your contributions!

Vijay Mathew
+2  A: 

More than anything else, if you want this to run on real hardware, you absolutely need a copy of your processor's manual. The Intel manuals (http://www.intel.com/products/processor/manuals/) are invaluable. They go over everything from switching modes (real/protected) to virtual memory management (if you choose to go that far) to making syscalls (if you ever get to doing user mode). Most importantly they explain in great detail a number of things that must be set up for things to function, like the TSS and segment registers, that most OS texts don't discuss because they're more concerned with higher-level concepts than processor-specific details.

csgordon
And you can get paper copies for free through Intel.
Matthew Iselin
+1  A: 
amaterasu
Silbershatz is really quite good, but very high-level.
Paul Nathan
Agreed; However, I'd say its fundamentally essential. Documentation right up there with Modern Operating Systems by Tanenbaum (mentioned earlier)
amaterasu
+1  A: 

The OS Development Series @ BrokenThorn might interest you.

tomzx
+3  A: 

I maintain a list of resources on StackOverflow: How to get started in operating system development. Please add new resources to it as you begin you're adventure (I'm about to begin :) )

Giovanni Galbo
+2  A: 

You have an ambitious goal. But execution is key.

Most of the structured approaches (textbook or college class) will walk you through the process, but they supply a lot of the nitty-gritty code that glosses over the arcane details of your chosen platform and lets you focus on the big-picture ideas: process scheduling, memory management, deadlock prevention, I/O, and so forth.

My advice is this: cut way back on your expectations and start with a basic question.

What is an operating system?

A computer scientist will (hopefully) never say that an OS is a graphical user interface, or a web browser, or a way to hook up USB devices, or anything that a user can actually see or touch. Instead, an OS at its most fundamental level are those things I mentioned above. They all fall under one big umbrella: resource management.

An operating system is nothing more than a program that manages the hardware resources of the computer: memory, CPU, and peripherals.

Here's a simple operating system: a program lets the user type in a program (in hexadecimal or binary) using a serial connection. Once the program has been typed in, it runs the program. When the program is finished, control is returned to the user where they can either run the program again or type in a new one.

Do this on a "clean" architecture such as an embedded ARM processor with 64K of memory or so. You can code this up in assembly after a few days of learning the ins and outs of the ARM. And voila!, you've got yourself an operating system.

It does everything an OS is supposed to do:

  • It manages memory by not letting the user overwrite the OS itself.
  • It schedules a single process to run.
  • It handles the I/O to the single serial peripheral.

This gives you a building block to start from. You have many choices now. Perhaps one of them would be to allow two programs to be loaded into memory and let the user decide which one to run next.

Or you could let the user suspend execution of one program, switch to the other, suspend, and switch back. This is rudimentary multitasking, even though it's entirely manual.

Your choices are unlimited but each one is a baby step from what you had before.

It's fun if you don't set your sights too high!

Barry Brown
+2  A: 

About low-level graphics programming, this will give you a lot of information: http://www.osdever.net/FreeVGA/home.htm. (It's very interesting for text mode as well.)

What will I undoubtedly run into that will confuse me?

You will realize that on PC there's an awful lot of stuff that is unclear: the x86 instruction set itself is complicated, and when you get direct access to hardware, it can take quite a while before you understand how to write a single character on screen.

Don't worry about floppy disk and such, most of the time you will use an emulator such as Bochs or QEmu.

Bastien Léonard