Creating an RTOS for Solaris with the open-source Real-Time Embedded Multiprocessor System isn't rocket science. This NASA engineer says it's simple. Here's how he did it.
Think of your desktop computer. Chances are, it's running something ranging from Windows XP to Solaris, with Linux, ReactOS, MacOS X, or Darwin in between. Regardless of the operating system, every application that executes is beholden to the system's priorities, commonly called interrupts, traps, or interrupt requests. These priorities do things like write a block to disk, grab a frame from the Ethernet card, or page in some important part of the kernel. These operating systems are nondeterministic, meaning that no two executions of the same piece of code produce exactly the same sequence of events.
To put it in a different perspective, imagine a manned spacecraft in low earth orbit traveling about 17,000 miles an hour. Suppose that every 1,000 seconds, it has to fire an orbital maneuvering system rocket for 3.8 seconds to avoid deorbit. A one second unit of time translates to 25,000 feet of distance covered. Imagine what nightmare would ensue if the spacecraft avionics had to stop, wait for the navigation system to page back in, fire the rockets, and then wait for the next interrupt to stop firing the rockets. It could take five seconds or more. In that time the spacecraft will deviate 25 miles from its projected course.
Enter real-time operating systems, or RTOSes. Your car has one; your cell phone has one; a Boeing 737 has a few thousand of them. RTOSes have one thing in common–they're all deterministic. A task that takes 3.8 seconds on a 300-MHz CPU should complete exactly 1,140,000,000 clock cycles during its execution.
Every RTOS designer knows beforehand what the task lifecycle will be. In the case of a spacecraft, launch should be a limited amount of time at the beginning of execution, followed by a cruise phase, followed by software to run during a prime mission.
An RTOS kernel can be thought of as a single kernel that gets loaded into memory all at once and runs from start to finish without interruptions. It interfaces with the hardware via libraries that are linked in at compile time called BSPs or board support packages. Typically, these are provided by the vendor of that single-board computer (SBC).
There are many RTOS packages to choose from. Some, such as VxWorks from Wind River Systems, cost thousands of dollars and have become the gold standard for successful NASA projects such as the Mars Rovers Spirit and Opportunity, the Mars Pathfinder spacecraft, and countless spacecraft in high atmospheric orbit, not to mention millions of dollars in classified defense-related projects.
For Linux enthusiasts who don't mind kernel hacking, there are real-time application interface extensions to Linux that attempt to bring a degree of real-time scheduling to Linux applications. If you're a fan of open-source software, you'll like the Real-time Embedded Multiprocessor System (RTEMS). Created by Dr. Joel Sherrill of OAR Corp, RTEMS has been open-source software since 1991. Originally designed for use in military applications, it's become so popular that many products are based on it.
What you need to start
To get started, you need a UNIX shell account. You don't need to be root, but you probably need a few gigabytes of disk space. I'd recommend 5 to 10GB, which gives you the ability to keep the source code and build to multiple targets. You'll also need a usable system compiler, preferably gcc. Type
which gcc to see if you have gcc in your path. If not, you'll want to install it. You'll also need GNU tar, GNU make, and GNU patch. You should be able to download and build these relatively simply if you have gcc. With the Sun Companion disk, these will be in either
/opt/sfw/bin and are called gtar, gmake, and gpatch.
Make two directories in your work area, called
cd ~mkdir toolsrc tools
Next, you'll need to download the source code packages and the associated patches from ftp.rtems.com in the directory named
/pub/rtems/SOURCES . Use Table 1 to get the appropriate files. Store them in
After you've downloaded all of the necessary files, you'll uncompress each file using GNU tar. Note that newlib has a slightly different extension, as it's been compressed with gzip and therefore must be uncompressed using a different algorithm.
gtar jxf binutils-2.17.tar.bz2gtar zxf newlib-1.14.0.tar.gzgtar jxf gcc-core-4.1.1.tar.bz2gtar jxf gdb-6.5.tar.bz2
Next, you'll need to patch each package. Use the gpatch program if you have it. If not, you'll need to use patch. Start by patching binutils:
cd newlib-1.14.0cat ../newlib-*.diff | gpatch "p1cd ..
After patching binutils, patch newlib.
cd binutils-2.17cat ../binutils-*.diff | gpatch "p1cd ..
Now, you'll need to patch gcc and then create a link from the gcc source directory to the newlib source package. This is so gcc knows where to find newlib. This may not be necessary in future versions of gcc, but it's necessary for 4.1.1:
cd gcc-core-4.1.1cat ../gcc-*.diff | gpatch "p1ln "s ../newlib-1.14.0/newlibcd ..
Finally, you patch gdb:
cd gdb-6.5cat ../gdb-*.diff | gpatch "p1cd ..
Now you're ready to begin building the tool chain. To build this chain, build the new binutils first, because it's the quickest kit to build. binutils can be built with your existing gcc and installed somewhere in your tools directory. In the toolsrc directory, do the following:
mkdir build-binutilsmkdir build-gccmkdir build-gdb
Change directories into your build-binutils directory and configure it for your system.
cd build-binutils../binutils-2.17/configure "-target=i386-rtems --program-prefix=i386-rtems- -"prefix=`pwd`/../../tools
Many lines of text should scroll by, indicating that the configure script is running. This will find all of the necessary dependencies to build binutils, and it'll build your Makefile. You needn't worry about the specifics.When you're returned to the prompt, you're ready to build binutils. The compile and install processes will take from five to 30 minutes, depending on the speed of your CPU.
gmake ; gmake info ; gmake installcd ..
After you've confirmed that the process completed without errors, back out of your build-binutils directory. Check your tools directory for binaries of the form i386-rtems-*. If you're satisfied, you can even remove your build-binutils directory. Keep the source code so you can build for future targets.Now it's time to build gcc using your built-in gcc. The binutils you've just built will only be useful on RTEMS/i386 binaries and won't be used by the gcc or gdb build process, but will definitely come in handy when it's time to build your first RTEMS kernel.
cd build-gcc../gcc-4.1.1/configure -"target=i386-rtems --with-gnu-as "-with-gnu-ld "-with-newlib "-verbose --enable-threads "-enable-languages="c" --program-prefix=i386-rtems- --prefix=`pwd`/../../tools
Again, you'll see quite a few lines of text scroll by, indicating that the configure script is running. Your gcc kit will take care of all of the necessary dependencies. If it completes error free, you'll be ready to build gcc.
gmake ; gmake info ; gmake install
Now, watch at least one episode of House, M.D . It's going to take a while to build gcc. When you are returned to the UNIX prompt, it will be time to build gdb. Change directories to
~/toolsrc/build-gdb . Configure your gdb kit accordingly.
cd ~/toolsrc/build-gdb../gdb-6.5/configure "-target=i386-rtems --program-prefix=i386-rtems --prefix=`pwd`/../../tools
After the entire configuration is complete, you should be ready to build and install gdb.
gmake ; gmake info ; gmake install
If the build process finishes completely, congratulations are in order! You have built the entire development tool chain for RTEMS and it's time to take a break. But first, clean up your binaries. Be sure to add your tools directory to your PATH.
cd ~/toolsstrip *
The next steps
The next step is to set up an execution environment. If you want to run your RTEMS kernels on actual hardware, you can pick up a 386 PC with a floppy drive, 16MB of RAM, monitor, keyboard, and NE2000 Ethernet card for about $20. Or, you can use QEMU and mtools to emulate a PC. I'd recommend the latter because it's more eco-friendly. You can download the source code for QEMU at www.qemu.com (the latest version is 0.8.2). However, it's difficult to compile on Solaris and the folks at blastwave.org have built a package around QEMU 0.7.0. If you're root, you can install the software in three easy steps.
wget http://www.blastwave.org/pkg_get.pkgyes | pkgadd "d pkg_get.pkgyes | /opt/csw/bin/pkg-get "i qemu
Add /opt/csw/bin to your PATH. You now have QEMU. Next, you'll need something called mtools, which is a neat open-source software package that emulates PC-based storage. With mtools, you can create a 1,440-KB file, and access it as if it's drive A:. This comes in handy when you need to boot an RTEMS kernel, because you can't simply run it from QEMU. You actually have to install it on a bootable floppy disk image as if it were a Linux kernel. Building mtools isn't difficult. Bring up a copy of your favorite browser and go to www.mtools.linux.lu/download.html. Get a copy of mtools-3.9.10.tar.bz2. Build and install it using the following steps. It might take a while to configure.
cd ~/toolsrcgtar jxf mtools-3.9.10.tar.bz2cd mtools-3.9.10./configure --prefix=`pwd`/../../toolsgmakegmake install
Time to build RTEMS
You've now built your RTEMS tool chain and installed your PC emulator along with mtools. You now have the entire cross compiling tool chain needed to build 386 RTEMS targets on your Solaris machine.It's important to understand some of the terminology used. Consult the glossary in Table 2 if necessary.
cd toolsrcwget ftp://ftp.rtems.com/pub/rtems/220.127.116.11/rtems18.104.22.168.tar.bz2gtar jxf rtems-22.214.171.124.tar.bz2cd ..
the gcc build. You'll want to create a separate directory and configure it in place.
cd toolsrcmkdir build-rtemscd build-rtems../rtems-126.96.36.199/configure "-target=i386-rtems --enable-posix "-enable-networking "-enable-rdbg --enable-tests "-enable-rtemsbsp="pc386" --enable-prefix=`pwd`/../../tools/rtems-4.7
Configuring the RTEMS source package should take a few minutes. It'll find all of the necessary components and add them to the Makefile. Also, by telling the configure to use the pc386 BSP, it won't build all of the ancillary BSPs that are not needed right now. If you leave out that option, you get an entire swath of 386, 486, and 486sx BSPs. Assuming that the configure script completes without error, you should be ready to build and install RTEMS. It should finish building in about 15 minutes.
Ready to boot RTEMS
Let's review the location of the most important components. First, in your
tools/bin directory, you have a bunch of binaries that start with
i386-rtems . These are not actually part of RTEMS, but rather are your tool chain. Next, you'll want to find and locate the BSP. It should be underneath your
tools/i386-rtems directory, entitled pc386. Compiling and linking your RTEMS executives is a simple matter of pointing a
RTEMS_MAKEFILE_PATH to this directory before you build. Also, it helps to have manual pages, so add the absolute location of
tools/man to your
MANPATH variable.In the configure process, you told RTEMS you wanted a bunch of tests. You can find these underneath your BSP directory.
cd ~/tools/i386-rtems/pc386/ lib/rtems-4.7/tests
Once there, you should find a bunch of files, such as
ticker.exe , and a few others. We're going to treat these like Linux kernels and boot them. Copy them all to a safe place in your tools directory, so you don't have to remember this long path.
mkdir ~/tools/rtems-demoscp *.exe ~/tools/rtems-demos
Now, you'll need to pick up a floppy disk image with GRUB on it.
cd ~/tools/rtems-demoswget http://www.thoughtwave.com/floppy.img.bz2bunzip2 floppy.img.bz2
Before you can access this with mtools, you must create an mtools configuration file. Bring up your favorite editor and create an
.mtoolsrc in your home directory.
drive a: file=
fat_bits=12 cylinders=80 heads=2 sectors=18 mformat_only
Now you should type
mdir and you'll see:
Volume in drive A has no labelDirectory for A:/stage2 30816 1998-05-13 11:56 stage2grubmenu 45 2006-05-31 8:19 grubmenu 2 files 30 861 bytes 1 425 920 bytes free
This GRUB disk image is designed to boot any compressed kernel in the root directory called
kernel.gz , meaning that to install
hello.exe , you simply compress it and copy it into your virtual disk image.
cd ~/tools/rtems-demoscat hello.exe | gzip -9 > kernel.gzmcopy kernel.gz a:
Now if you type
mdir a: , you should see:
Volume in drive A has no labelDirectory for A:/Kernel gz 68075 2006-08-05 19:37 kernel.gzstage2 30816 1998-05-13 11:56 stage2grubmenu 45 2006-05-31 8:19 grubmenu 3 files 98 936 bytes 1 357 824 bytes free
You're now ready to boot your RTEMS kernel, which can be done in one of two ways. The
floppy.img file is a 1,440-KB image suitable to be written to a floppy disk and booted on a 386 or better. Many utilities let you do this, such as
RAWRITE.EXE , which can be found using Google.
RAWRITE.EXE runs under Windows and is easy to use. Or, if you're running UNIX on a Solaris machine, you can put a floppy in the drive and type the following:
dd if=floppy.img of=/dev/rdiskette
You can also use QEMU to boot it. Make sure your $DISPLAY variable is set and do the following:
After a few moments, the GRUB console screen should show up. Press enter to boot kernel.gz and you should see the following message:
Initialized console on port CONSOLE*** HELLO WORLD TEST ***Hello World*** END OF HELLO WORLD TEST ***EXECUTIVE SHUTDOWN! Any key to reboot...
Click in the close box on the QEMU window to exit. There's no special way to shut down RTEMS. You can boot any RTEMS kernel using the same steps. Simply compress it with
gzip to a file named
kernel.gz and use mcopy to put it in place on the floppy image.
At this point, you have all of the development tools to build embedded applications for i386-based PCs. The steps are similar for other targets, and even for other build environments. RTEMS supports most PowerPC-based VME cards, and also supports C++ and Ada, but that is a more advanced topic.
In addition, RTEMS has a full-featured BSD networking stack, and the pc386 BSP has support for several networking interfaces, including the classic NE2000 Ethernet card, so you can build complex network-based embedded applications.
Jonathan Kalbfeld is a senior staff member at the Jet Propulsion Laboratory in Pasadena, CA. He has supported the Mars Rovers, Mars Reconnaissance Orbiter, Deep Impact, and at was the mission support engineer for the Dawn Project. He is also the founder of ThoughtWave Technologies, an Internet service provider and software company. Jonathan can be reached at .
The research described in this article was carried out at the Jet Propulsion Laboratory, California Institute of Technology, under a contract with the National Aeronautics and Space Administration.