RDOS Operating System

License

RDOS source code is distributed as GPL, except for commercial usage.

Commersial users can buy licenses here:

Purpose

The source code

The source code is offered WITHOUT WARRANTY.

To view the source code online go here

The source code is also available from a SVN-repository. You can check it out with SVN at https://svn.rdos.se/trunk.

Supported platforms

Hardware with 386 or higher processor, including multicore support. 2MB RAM. Specific board support packages are included in the board directory of the source.

Hardware abstractions

Software abstractions

Hardware drivers

Software drivers

Device driver API

To be able to link different device-drivers with each other, RDOS has a device driver API. Invalid far calls are built into the calling code. At run-time, these are patched to a far call to the registered destination procedure by the general protection fault handler. RegisterOsGate is used to register a handler. Currently supported APIs are in the kernel/os.inc file in the source distribution. There is also a C include file (kernel/rdosdev.h)

Application API

To be able to link application calls with an defined server procedure, RDOS has a device driver API. Invalid far calls are built into the calling code. At run-time, these are patched to call gates pointing to the registered destination procedure by the general protection fault handler. Device drivers can also call the application API, and when this happens, far calls are patched just as with the device driver API. RegisterUserGate is used to register a bimodal handler, RegisterUserGate16 is used for 16-bit handlers and RegisterUserGate32 is used for 32-bit handlers. Currently supported procedures are in the kernel/user.inc file in the source distribution. There is also a C/C++ include file (kernel/rdos.h)

C++ wrappers and application classes

Most of the application API have wrappers in the form of C++ classes. Some common software is also included as C++ classes to avoid multiple porting. This code is located in the classlib directory. Some of the classes also have Win32 implementations to make porting between Windows and RDOS easier.

Wrapper classes: General classes:

Native applications

The following applications are part of the source distribution:

Build tools

All RDOS source is built with the OpenWatcom compiler. At the moment, a snapshot from 2014 must be used (Win32 build here)

To build RDOS, you first need to download and install the OpenWatcom compiler. You also need to download the SVN source code to the /rdos directory on a partition. You then build the complete source by typing "build" in the /rdos directory.

Creating bootable image files for RDOS

To be able to configure the system without recompiling, RDOS uses separately compiled device drivers. The device drivers usually have the .rdv extension. Any number of device drivers can be included in the OS image.

This has several advantages

All RDOS boot methods use a single binary file. The binary is created with a tool, cfg2bin (apps/cfg2bin). The tool takes a base name parameter, and uses a configuration file (basename.cfg) to create a binary file (basename.bin). The standard boot file is called "rdos.bin", and the fallback boot file is called "safe.bin". Other files will be presented by their names. The cfg2bin tool runs both on Windows and RDOS.

Directives in the configuration file:

A typical configuration file for a modern multicore processor board:

font=../sans.ttf
font=../led.ttf
kernel=../../kernel/os/kernel.exe
device=../../kernel/os/sched.rdv
device=../../kernel/os/task.rdv
device=../../kernel/freetype/freetype.rdv
device=../../kernel/os/util.rdv
device=../../kernel/acpi/acpi.rdv
device=../../kernel/os/fs.rdv
device=../../kernel/os/inifile.rdv
device=../../kernel/os/drive.rdv
device=../../kernel/os/fat.rdv
device=../../kernel/bios/pcbios.rdv (exclude for EFI boots)
device=../../kernel/os/exec.rdv
device=../../kernel/os/pe.rdv
device=../../kernel/os/guidev.rdv
device=../../kernel/os/audio.rdv
device=../../kernel/os/com.rdv
device=../../kernel/os/printer.rdv
device=../../kernel/os/net.rdv
device=../../kernel/os/ip.rdv
device=../../kernel/os/ipc.rdv
device=../../kernel/os/bignum.rdv
device=../../kernel/debug/kdebug.rdv
shutdown=../../kernel/debug/pcshut.exe
device=../../kernel/os/tlist.rdv
device=../../kernel/pcdev/apic.rdv
device=../../kernel/pcdev/rtc.rdv
device=../../kernel/pcdev/pci.rdv
device=../../kernel/bios/vga.rdv (exclude for EFI boots)
device=../../kernel/pcdev/keymap.rdv en
device=../../kernel/pcdev/ps2keym.rdv
device=../../kernel/pcdev/ahci.rdv
device=../../kernel/pcdev/sdcard.rdv
device=../../kernel/netdev/rtl8169.rdv
device=../../kernel/audiodev/hda.rdv
device=../../kernel/usbdev/usb.rdv
device=../../kernel/usbdev/ohci.rdv
device=../../kernel/usbdev/ehci.rdv
device=../../kernel/usbdev/xhci.rdv
device=../../kernel/usbdev/hid.rdv
device=../../kernel/usbdev/hub.rdv
device=../../kernel/usbdev/usbcom.rdv
device=../../kernel/usbdev/usbdisc.rdv
set PROMPT=$p$g
set NETMASK=255.255.255.0
set GATEWAY=192.168.10.1
set IP=192.168.10.167
set DNS1=192.168.10.1
set SYSINI=c:\system.ini
path z:\
file ../../apps/freecom/command.exe
file ../../apps/ftpd/ftpd.exe
file ../../apps/tcpwd/tcpwd.exe
run z:\ftpd.exe
run z:\command.exe

Booting with UEFI USB disc

The easiest way to initially boot RDOS is on a machine that boots with UEFI, and which has not been locked down to Windows or some other operating system. Sometimes BIOS settings must be changed to allow EFI booting from USB.

The first step is to create a GPT formatted USB disc with an EFI system partition. This can be done with the diskpart tool that is part of Windows. It's started from the command line, but needs administrator access rights.

Once you have a GPT formatted disk, you can use Windows file manager to create the directory structure and copy the required files. The first time Windows will ask to format the disk, so let it do this with FAT32 (not NTFS).

If you already have RDOS running, it might be easier to use the RDOS command line to format the USB disk.

After the USB disk is setup for GPT and EFI, the directory structure should be created: Then the following files should be placed on the disk:

The RDOS image files should be placed in the root. When this is done, you should be able to boot RDOS from the USB disc.

Booting with BIOS USB disc

This is easy to setup if you already have RDOS running, but very hard to do for a first install. How the disk is formatted can be seen in the inithd.cpp file in the RDOS source code. It involves merging the boot sector, setting up hidden sectors, and then placing the loader in the hidden sectors.

On the RDOS command line do the following.

As with EFI booting, the RDOS image files should be placed in the root. When this is done, you should be able to boot RDOS from the USB disc.

Permanent install

When a system will run only RDOS, it's most convinient to install the RDOS boot loader to the hard disc. This can be done from the command line from an already running RDOS boot. The inithd command is used to setup the disc. It is either done with the /I and /R switches which will setup a legacy BIOS (MBR) boot, or with the /G switch which will create a GPT partition scheme suitable for an EFI boot. After inithd, reboot, and then create the initial partition(s) with mkpart. After mkpart, reboot, and then create the correct directoty structure and copy the relevant files to the disc (see previous sections).

Booting RDOS with GRUB bootloader

GRUB is a multiboot loader that can run most OSes like Windows, LINUX and many more. You can set up a section in the bootloader to run RDOS. Information about GRUB is here

After you successfully installed GRUB onto your harddisk, just add the following lines in a new section in MENU.LST:

rootnoverify (hd0,0)

kernel /grubload.bin

modulenounzip /rdos.bin

This assumes you have put grubload.bin and rdos.bin on the root of the first partition.

The grupload.bin file can be found here

Switching between running applications

CTRL + Function key is used to switch between applications:

Debugging

The most convinient way to debug code is by using the OpenWatcom application debugger on a remote host. It's possible to trace code from the application into the kernel at source level. For this to work, there must be a working network driver in RDOS.

Debugging session with the ACPI driver:

When the application debugger cannot be used to debug code, the next best choice is to use the kernel debugger:

To map between protected mode selector:offset and source code do like this:

Note that 30h is the kernel selector, and the related map file is kernel.map. The 1B3 selector is the application selector

An alternative way to get a thread into the kernel debugger is to stop it from the thread list (press CTRL-F9). This is done by marking the thread to be stopped, and then pressing S.

When the system doesn't boot properly, this must be debugged with the crash debugger. Just as with the kernel debugger, which runs inside of RDOS, the crash debugger can be triggered by an breakpoint instruction, but in this case in the boot code or in an IRQ. Additionally, the crash debugger can also be invoked with the "CrashGate" instruction. This instruction is also part of some fatal error handling by default. An additonal way to invoke the crash debugger is by pressing CTRL-ALT-ESC. Unlike the kernel debugger that runs alongside with RDOS, the crash debuger takes over the machine completely. Single stepping in the crash debugger is done by emulating instructions, and can only be done if there is a PS/2 keyboard connected. The crash debugger allows debugging spinlocks and the scheduler, and instructions can be traced in arbitrary order on multiple cores. The user interface is similar to the kernel debugger, but register context is shown per core. Registers can be modified and the code can be traced by pressing the T key and the N key is used to switch between cores.

File system performance test

Here are some tests run between RDOS, Win98 and NT 4. The test where run on two different machines, both with a standard IDE drive and 64MB of memory.

Open / close file performance

This test was done by repeatedly open / close the same file.

AMD K6-400, small directory

RDOS, C, FAT32: 0.17ms
Win98, C, FAT32: 0.29ms

AMD-K6 400, large directory:

RDOS, native, FAT32: 0.27ms
Win98, Win32, FAT32: 0.60ms

Pentium 75, small directory: 

RDOS, native, FAT16:  0.23ms
NT, Win32, FAT16: 0.67ms

RDOS is at least twice as fast as Windows when it comes to open a file

Buffered read performance

This test was done by repeatedly perform a read on a 512kB large file in 512 byte blocks

AMD K6-2 400:

RDOS on FAT32:    2.5ms
RDOS on RAM-drive: 2.3ms
Win98 on FAT32:  13.6ms

Pentium 75:

RDOS, Native, RAM-drive:  25ms
NT, C, FAT16:    65ms
NT, Win32, FAT16: 57ms

RDOS is more than twice as fast as NT, and more than five times as fast as Win98.

Mixed access test (assembling RDOS)

This test was performed by making a DOS bat file, which assembles all the assembler files in RDOS OS directory (99 files)

AMD K6-2 400:

RDOS on FAT16, first time:    7.0s
RDOS on FAT16, second time:    5.5s
WinME on FAT16, first time:    9.5s
WinME on FAT16, second time:  7.0s

File copy test

This test was done by performing COPY at the DOS-prompt from one directory to another. None of the files where touched prior to the copy.

AMD K6-2 400:

RDOS: 2s
WinME: 5s

IPC performance test

Local IPC test

This test was perfomed by letting a sender thread send messages to a receiver.

AMD K6-2 400:

Win98, within process: 16,900 transactions / second
RDOS between processes: 22,500 transactions / second

Pentium 75:

WinNT, within process: 3,200 transactions / second
RDOS between processes: 3,750 transactions / second

The tests weren't really compatible, since the Windows performance is achieved between threads in the same process, while the RDOS performance is between different processes. So Windows would loose even more if I could figure out how to pass data from one process to another in Windows.

This test messures mostly the speed of the basic synchronization and scheduling algorithms, and even though RDOS has to flush the TLB a couple of times per transaction, it's still faster than Windows.

Remote IPC test

This is a preliminary comnparison between named pipes in NT and RDOS SMP/IP protocol:

Between 400MHz CPUs on a 10MB Ethernet:

RDOS, NE2000 PCI : 0.5 - 1.0ms / transaction
NT: 10-15ms / transaction

Since SMP protocol is an optimized transaction protocol over IP, this difference is just natural.

One odd thing this test showed was that I could only achieve a 1/5th of this theoretical performance. Only if I used 5 separate senders could I almost achieve the maximum performance. This is due to the network card buffering packets, and working in paralell with the CPU decoding them. Also, the network thread has above-normal priority, so it can keep up with a fully-loaded ethernet card, provided the CPU is fast enough.

Screen shots