320 lines
13 KiB
HTML
320 lines
13 KiB
HTML
|
<!--startcut ==============================================-->
|
||
|
<!-- *** BEGIN HTML header *** -->
|
||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||
|
<HTML><HEAD>
|
||
|
<title>So You Wanna Create Your Own x86 Operating System? LG #85</title>
|
||
|
</HEAD>
|
||
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#0000AF"
|
||
|
ALINK="#FF0000">
|
||
|
<!-- *** END HTML header *** -->
|
||
|
|
||
|
<!-- *** BEGIN navbar *** -->
|
||
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="lodato.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue85/mahoney.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="nielsen.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
|
<!-- *** END navbar *** -->
|
||
|
|
||
|
<!--endcut ============================================================-->
|
||
|
|
||
|
<TABLE BORDER><TR><TD WIDTH="200">
|
||
|
<A HREF="http://www.linuxgazette.com/">
|
||
|
<IMG ALT="LINUX GAZETTE" SRC="../gx/2002/lglogo_200x41.png"
|
||
|
WIDTH="200" HEIGHT="41" border="0"></A>
|
||
|
<BR CLEAR="all">
|
||
|
<SMALL>...<I>making Linux just a little more fun!</I></SMALL>
|
||
|
</TD><TD WIDTH="380">
|
||
|
|
||
|
|
||
|
<CENTER>
|
||
|
<BIG><BIG><STRONG><FONT COLOR="maroon">So You Wanna Create Your Own x86 Operating System?</FONT></STRONG></BIG></BIG>
|
||
|
<BR>
|
||
|
<STRONG>By <A HREF="../authors/mahoney.html">Patrick Mahoney</A></STRONG>
|
||
|
</CENTER>
|
||
|
|
||
|
</TD></TR>
|
||
|
</TABLE>
|
||
|
<P>
|
||
|
|
||
|
<!-- END header -->
|
||
|
|
||
|
|
||
|
|
||
|
<h2>1. Introduction</h2>
|
||
|
|
||
|
One of the great difficulties a hobbyist programmer faces when trying
|
||
|
to start the development of his own OS is finding out where to
|
||
|
start. Many books describe in-depth theoretical OS concepts, yet noone
|
||
|
seems to take a hobyist programmer by the hand and bring him face to
|
||
|
face with these concepts. This is precisely what this article aims at
|
||
|
doing.
|
||
|
<p>
|
||
|
Several articles related to this topic appeared in the last few issues
|
||
|
of the Linux Gazette. I plan to approach it in a much less programming
|
||
|
oriented manner, only presenting to the reader the tools and tips he
|
||
|
will need to begin the development of his own OS. Once done with this
|
||
|
article, the interested reader should be all set to start browsing the
|
||
|
resources available to him and start designing and coding.
|
||
|
<p>
|
||
|
You might not be aware of it, but operating system development doesn't
|
||
|
start at the beginning. (!!) Writing a solid bootloader is a whole
|
||
|
project in itself, and I would not advise one to begin an OS
|
||
|
development project by writing a bootloader. Many reliable ones are
|
||
|
available for free (Grub, lilo, ppcboot, etc...). If you plan on
|
||
|
writing your own, I suggest you delay this task to a later stage of
|
||
|
the project. In this article, I will be using GNU Grub, the Grand
|
||
|
Unified Bootloader.
|
||
|
|
||
|
<h2>2. Description of the development environment</h2>
|
||
|
|
||
|
To ease the pain that OS development will bring to you, you will need
|
||
|
to set up an adapted development environment which meets a certain
|
||
|
number of requirements:
|
||
|
<p>
|
||
|
<ul>
|
||
|
<li>You should get to rapidly test your newly compiled kernel
|
||
|
<li>You should never have to reboot your development machine
|
||
|
<li>You should not need to use floppies as a storage medium for your OS
|
||
|
</ul>
|
||
|
<p>
|
||
|
This article will present one of many possible environments which
|
||
|
meets these requirements. It will consist of a development machine and
|
||
|
a testbed machine that both lie on a common network.
|
||
|
|
||
|
<h3>2.1 The development machine</h3>
|
||
|
|
||
|
Obviously, this machine will need to be equipped with a good set of
|
||
|
programming tools: assembly and C compilers, a linker and a 'make'
|
||
|
utility are musts.
|
||
|
<p>
|
||
|
A tool I found more useful than I initially thought it would be is an
|
||
|
emulator. Such a tool will help debug your kernel and will allow you
|
||
|
to rapidly test your newly added line of code. Don't be fooled,
|
||
|
though. An emulator never replaces a good ol' testbed machine.
|
||
|
<p>
|
||
|
Next, you need a TFTP server. This tool will allow your testbed machine's
|
||
|
tftp enabled bootloader to acquire a kernel from the development
|
||
|
machine via the network connection.
|
||
|
|
||
|
<h3>2.2 The testbed machine</h3>
|
||
|
|
||
|
All this machine needs is a network card and a TFTP enabled bootloader
|
||
|
that supports it.
|
||
|
|
||
|
<h2>3. Setup of the development environment</h2>
|
||
|
|
||
|
<h3>3.1 The development machine</h3>
|
||
|
|
||
|
The chosen programming tools are:
|
||
|
<ul>
|
||
|
<li>gcc 2.95.4
|
||
|
<li>ld 2.13.90.0.10
|
||
|
</ul>
|
||
|
<p>
|
||
|
Bochs version 1.4.1 is the chosen x86 emulator. Special care should be
|
||
|
taken to compile it with debugger mode enabled. These commands should do
|
||
|
the job:
|
||
|
<pre>
|
||
|
$ ./configure --enable-x86-debugger
|
||
|
$ make
|
||
|
</pre>
|
||
|
In order to properly use Bochs, you need to create a disk image. This
|
||
|
image needs to have both a bootloader and a filesystem. This can
|
||
|
be done using the <a href="misc/mahoney/mkbimage">mkbimage</a>
|
||
|
script. If you're too lazy to do it yourself, grab <a
|
||
|
href="misc/mahoney/c.img.gz">this</a> gzipped 10MB disk image and add
|
||
|
<pre>
|
||
|
diskc: file=c.img, cyl=24, heads=16, spt=63
|
||
|
</pre>
|
||
|
to your .bochrc file.
|
||
|
<p>
|
||
|
As for the TFTP server, I chose to use atftpd. It's an easy to use
|
||
|
linux-based TFTP server implementation.
|
||
|
|
||
|
<h3>3.2 The testbed machine</h3>
|
||
|
|
||
|
The chosen bootloader is GNU Grub version 0.92. Special care should be
|
||
|
taken to enable Grub's tftp client to talk to your network card. My
|
||
|
testbed machine has a cheap NE2000 ISA clone. Following carefully the
|
||
|
netboot/README.netboot instructions, I used these commands:
|
||
|
<pre>
|
||
|
$ ./configure --enable-ne --enable-ne-scan=0x220
|
||
|
$ make
|
||
|
</pre>
|
||
|
Note that a PnP PCI card would be easier to configure. Now, you can
|
||
|
either install the Grub images on the testbed machine's MBR or on a
|
||
|
floppy which your testbed machine will boot from. I prefer the latter,
|
||
|
since my testbed machine is also used for other purposes, and
|
||
|
therefore, I'd rather not play with its HD.
|
||
|
<pre>
|
||
|
$ cat ./stage1/stage1 ./stage2/stage2 > /dev/fd0
|
||
|
</pre>
|
||
|
Now just insert your floppy in your testbed machine to see if your
|
||
|
network card gets recognized. You can either configure it by hand or
|
||
|
use a dhcp server, if any.
|
||
|
<pre>
|
||
|
grub> dhcp
|
||
|
Probing... [NE*000]
|
||
|
NE2000 base 0x220, addr 00:C0:A8:4E:5A:76
|
||
|
Address: 192.168.22.14
|
||
|
Netmask: 255.255.255.0
|
||
|
Server: 192.168.22.1
|
||
|
Gateway: 192.168.22.1
|
||
|
</pre>
|
||
|
Note that you won't have to configure these parameters by hand each
|
||
|
time you boot. See the GNU Grub documentation and the 'grub-install'
|
||
|
script for details.
|
||
|
<p>
|
||
|
That's it! You're all set to test your setup!
|
||
|
|
||
|
|
||
|
<h2>4. Testing your development environment setup...</h2>
|
||
|
|
||
|
As I mentioned earlier, I will leave the core OS programming stuff to
|
||
|
the experts out there. So in order to test your setup, we will use the
|
||
|
example kernel from the GNU Grub sources located in the /docs directory.
|
||
|
<p>
|
||
|
The kernel is built from three source files: boot.S, kernel.c and
|
||
|
multiboot.h. You can build the kernel by doing:
|
||
|
<pre>
|
||
|
$ gcc -I. -c ./boot.S
|
||
|
$ gcc -I. -c ./kernel.c
|
||
|
$ ld ./kernel.o ./boot.o -o kernel -Ttext 100000
|
||
|
</pre>
|
||
|
Here's a quick and incomplete explanation. Multiboot is a standard
|
||
|
that defines a way for the bootloader to pass information to the
|
||
|
kernel it tries to load. boot.S accepts this information, sets up a
|
||
|
stack, and calls 'cmain'. This function sets up the vga display,
|
||
|
reads the information passed to him, prints some stuff and
|
||
|
leaves. Then, boot.S gets the control back, prints the string
|
||
|
'Halted.', and enters an infinite loop. Pretty simple stuff, right?
|
||
|
The reader is invited to dig into the code to get more details.
|
||
|
|
||
|
<h3>4.1 ...with Bochs</h3>
|
||
|
|
||
|
The plan is to mount your disk image via a loopback device, copy your
|
||
|
kernel on the filsystem of the image, unmount it, and fire off
|
||
|
Bochs. Of course, you have to add an offset to the start of the
|
||
|
filesystem. But you knew that, right?
|
||
|
<pre>
|
||
|
# /sbin/losetup -o 32256 /dev/loop1 ./c.img
|
||
|
# /bin/mount -t ext2 /dev/loop1 /mnt/osdev/
|
||
|
# cp <path-to-grub>/docs/kernel /mnt/osdev
|
||
|
# umount /mnt/osdev/
|
||
|
# /sbin/losetup /dev/loop1 -d
|
||
|
$ bochs
|
||
|
</pre>
|
||
|
Of course, that can be automated by your Makefile. Once in Grub,
|
||
|
simply do:
|
||
|
<pre>
|
||
|
grub> kernel (hd0,0)/kernel
|
||
|
grub> boot
|
||
|
</pre>
|
||
|
<a href="misc/mahoney/bochs_screenshot.jpg">
|
||
|
<img alt="Bochs screenshot" src="misc/mahoney/bochs_screenshot.jpg" width="400" height="220"></a>
|
||
|
<BLOCKQUOTE><EM>(Click the image for the full size.)</EM></BLOCKQUOTE>
|
||
|
|
||
|
|
||
|
<h3>4.2 ...with your testbed machine</h3>
|
||
|
|
||
|
First, setup your TFTP server so that the client can retrieve your
|
||
|
kernel:
|
||
|
<pre>
|
||
|
# /usr/sbin/atftpd --daemon /home/bono/src/grub-0.92/docs
|
||
|
</pre>
|
||
|
Fire off your testbed machine. Configure your network connection as
|
||
|
shown above. Next, specify your devel machine's ip address as the TFTP
|
||
|
server address and the location of the kernel image. Note that this
|
||
|
option can be set by the dhcp server. Finally, start the boot
|
||
|
process.
|
||
|
|
||
|
<pre>
|
||
|
(...)
|
||
|
|
||
|
grub> tftpserver 192.168.22.36
|
||
|
Address: 192.168.22.14
|
||
|
Netmask: 255.255.255.0
|
||
|
Server: 192.168.22.36
|
||
|
Gateway: 192.168.22.1
|
||
|
|
||
|
grub> kernel (nd)/kernel
|
||
|
[Multiboot-elf, <0x100000:0x807:0x0>, <0x101808:0x0:0x4018>,
|
||
|
shtab=0x106190, entry=0x100568]
|
||
|
|
||
|
grub> boot
|
||
|
</pre>
|
||
|
|
||
|
A screen similar to that of Bochs should appear on your testbed
|
||
|
machine's display.
|
||
|
|
||
|
<h2>5. Where to go from here</h2>
|
||
|
|
||
|
Well you're pretty much set to start the development of your
|
||
|
OS. Lots of good documentation resides on the web. Browse, post,
|
||
|
ask, think. Monolithic or micro kernel? Segmentation or paging?
|
||
|
<p>
|
||
|
If your debugging needs come to outgrow both the emulator and your
|
||
|
kernel's printk's, one setup you could add to your OS is a serial
|
||
|
debugger. This can range from some bytes thrown on the serial port, to
|
||
|
a gdb-compatible remote-debugging extension. This information could be
|
||
|
retrieved and processed by your development machine through a
|
||
|
null-modem serial cable. It's a handy common practice in OS
|
||
|
development.
|
||
|
|
||
|
|
||
|
|
||
|
<h2>6. Resources</h2>
|
||
|
<ul>
|
||
|
|
||
|
<dt><li><a href="http://cwx.prenhall.com/bookbind/pubbooks/tanenbaum/">Tanenbaum' os dev book</a>
|
||
|
<dd>The bible of operating system development
|
||
|
|
||
|
<dt><li><a href="http://groups.google.ca/groups?q=alt.os.development">alt.os.development</a>
|
||
|
<dd>There, you'll find the solution to many of your problems!
|
||
|
|
||
|
<dt><li>Freenode IRC's #osdev (irc.debian.org)
|
||
|
<dd> Friendly folks who never go to bed!
|
||
|
|
||
|
<dt><li><a href="http://osdev.berlios.de/">A few osdev tutorials</a> including Tim Robinson's.
|
||
|
<dd> Tim's been there!
|
||
|
|
||
|
<dt><li><a href="http://www.nondot.org/sabre/os/articles">The Operating System Resource Center</a>
|
||
|
|
||
|
<dt><li><a href="http://inferno.cs.univ-paris8.fr/~am/tutorial/os/tutorial00.html">BosoKernel</a>
|
||
|
<dd>Nicely done x86 beginner's tutorial. (French)
|
||
|
|
||
|
<dt><li><a
|
||
|
href="ftp://download.intel.com/design/PentiumII/manuals/24319202.pdf">
|
||
|
Intel Architecture Software Developer's Manual Volume 3: System
|
||
|
Programming</a>
|
||
|
<dd>Don't leave home without it.
|
||
|
</dl>
|
||
|
</ul>
|
||
|
|
||
|
<h2>7. Thanks</h2>
|
||
|
|
||
|
Many thanks to all those who have accepted to patiently answer
|
||
|
my never-ending questions on #osdev: pavloskii, geist, oink,
|
||
|
byrdkernel, air.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<!-- *** BEGIN copyright *** -->
|
||
|
<hr>
|
||
|
<CENTER><SMALL><STRONG>
|
||
|
Copyright © 2002, Patrick Mahoney.
|
||
|
Copying license <A HREF="../copying.html">http://www.linuxgazette.com/copying.html</A><BR>
|
||
|
Published in Issue 85 of <i>Linux Gazette</i>, December 2002
|
||
|
</STRONG></SMALL></CENTER>
|
||
|
<!-- *** END copyright *** -->
|
||
|
<HR>
|
||
|
|
||
|
<!--startcut ==========================================================-->
|
||
|
<CENTER>
|
||
|
<!-- *** BEGIN navbar *** -->
|
||
|
<IMG ALT="" SRC="../gx/navbar/left.jpg" WIDTH="14" HEIGHT="45" BORDER="0" ALIGN="bottom"><A HREF="lodato.html"><IMG ALT="[ Prev ]" SRC="../gx/navbar/prev.jpg" WIDTH="16" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="index.html"><IMG ALT="[ Table of Contents ]" SRC="../gx/navbar/toc.jpg" WIDTH="220" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../index.html"><IMG ALT="[ Front Page ]" SRC="../gx/navbar/frontpage.jpg" WIDTH="137" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="http://www.linuxgazette.com/cgi-bin/talkback/all.py?site=LG&article=http://www.linuxgazette.com/issue85/mahoney.html"><IMG ALT="[ Talkback ]" SRC="../gx/navbar/talkback.jpg" WIDTH="121" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><A HREF="../lg_faq.html"><IMG ALT="[ FAQ ]" SRC="./../gx/navbar/faq.jpg"WIDTH="62" HEIGHT="45" BORDER="0" ALIGN="bottom"></A><A HREF="nielsen.html"><IMG ALT="[ Next ]" SRC="../gx/navbar/next.jpg" WIDTH="15" HEIGHT="45" BORDER="0" ALIGN="bottom" ></A><IMG ALT="" SRC="../gx/navbar/right.jpg" WIDTH="15" HEIGHT="45" ALIGN="bottom">
|
||
|
<!-- *** END navbar *** -->
|
||
|
</CENTER>
|
||
|
</BODY></HTML>
|
||
|
<!--endcut ============================================================-->
|