or <url url="http://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.0-test1.tar.gz" name="2.4.0-test1"> (x86, PowerPC, Alpha) into /usr/src/ and untar it. Also put a fresh copy of
RTLinux kernel (version 3.0) from
<url url="http://www.rtlinux.org" name="www.rtlinux.org"> in /usr/src/rtlinux/.
(We will use $ to represent the prompt).
<enum>
<item>
Now, configure the Linux kernel :
<verb>
$ cd /usr/src/linux
$ make config
or
$ make menuconfig
or
$ make xconfig
</verb>
<item>
For building the kernel image, type :
<verb>
$ make dep
$ make bzImage
$ make modules
$ make modules_install
$ cp arch/i386/boot/bzImage /boot/rtzImage
</verb>
<item>
Next step is to configure LILO. Type in the following lines in the file
/etc/lilo.conf
<verb>
image=/boot/rtzImage
label=rtl
read-only
root=/dev/hda1
</verb>
WARNING: replace /dev/hda1 in the above with your root filesystem. The
easiest way to find out which filesystem it should be, take a look
at the existing entry in your /etc/lilo.conf for "root=".
<item>
Now, restart your computer and load the RTLinux kernel by typing 'rtl'
at the LILO prompt. Then 'cd' to /usr/src/rtlinux/ and configure RTLinux.
<verb>
$ make config
or
$ make menuconfig
or
$ make xconfig
</verb>
<item>Finally, for compiling RTLinux
<verb>
$ make
$ make devices
$ make install
</verb>
</enum>
The last step will create the directory:
/usr/rtlinux-xx (xx denotes the version)
which contains the default installation directory for RTLinux which is
needed to create and compile user programs (that is, it contains the
include files, utilities, and documentation). It will also create a
symbolic link:
/usr/rtlinux
which points to /usr/rtlinux-xx. In order to maintain future
compatibility, please make sure that all of your own RTLinux programs
use /usr/rtlinux as its default path.
NOTE : If you change any Linux kernel options, please don't forget to do:
<verb>
$ cd /usr/src/rtlinux
$ make clean
$ make
$ make install
</verb>
<sect>
Why RTLinux
<p>
The reasons for the design of RTLinux can be understood by examining the
working of the standard Linux kernel. The Linux kernel separates the hardware
from the user-level tasks. The kernel uses scheduling algorithms and assigns
priority to each task for providing good average performances or throughput.
Thus the kernel has the ability to suspend any
user-level task, once that task has outrun the time-slice allotted to it
by the CPU. This scheduling algorithms along with device drivers,
uninterruptible system calls, the use of interrupt disabling and virtual
memory operations are sources of unpredictability. That is to say,
these sources cause hindrance to the realtime performance of a task.
<p>
You might already be familiar with the non-realtime performance, say,
when you are listening to the music played using 'mpg123' or any other player.
After executing this process for
a pre-determined time-slice, the standard Linux kernel could preempt the
task and give the CPU to another one
(e.g. one that boots up the X server or Netscape). Consequently,
the continuity of the music is lost. Thus, in trying to ensure fair distribution of
CPU time among all processes, the kernel can prevent other events from
occurring.
<p>
A realtime kernel should be able to guarantee the timing requirements of
the processes under it.
The RTLinux kernel accomplishes realtime performances by removing such
sources of unpredictability as discussed above. We can consider the RTLinux
kernel as sitting between the standard Linux kernel and the hardware. The
Linux kernel sees the realtime layer as the actual hardware. Now, the
user can both introduce and set priorities to each and every task. The user
can achieve correct timing for the processes by deciding on the
scheduling algorithms, priorities, frequency of execution etc. The
RTLinux kernel assigns lowest priority to the standard Linux kernel. Thus
the user-task will be executed in realtime.
<p>
The actual realtime performance is obtained by intercepting all
hardware interrupts. Only for those interrupts that are related to
the RTLinux, the appropriate interrupt service routine is run. All other
interrupts are held and passed to the Linux kernel as software interrupts when
the RTLinux kernel is idle and then the standard Linux kernel runs. The RTLinux
executive is itself nonpreemptible.
<p>
Realtime tasks are privileged (that is, they have direct access to hardware), and they
do not use virtual memory. Realtime tasks are written as special Linux
modules that can be dynamically loaded into memory. The
initialization code for a realtime tasks initializes the realtime task
structure and informs RTLinux kernel of its deadline,
period, and release-time constraints.
<p>
RTLinux co-exists along with the Linux kernel since it leaves the Linux
kernel untouched. Via a set of relatively simple modifications,
it manages to convert the existing Linux kernel into a hard realtime environment
without hindering future Linux development.
<sect>
Writing RTLinux Programs
<sect1>
Introduction to writing modules
<p>
So what are modules? A Linux module is nothing but an object file, usually
created with the -c flag argument to gcc. The module itself is created by
compiling an ordinary C language file without the main() function. Instead
there will be a pair of init_module/cleanup_module functions:
<itemize>
<item>
The init_module() which is called when the module is inserted into the kernel.
It should return 0 on success and a negative value on failure.
<item>
The cleanup_module() which is called just before the module is removed.
</itemize>
Typically, init_module() either registers a handler for something with the
kernel, or it replaces one of the kernel function with its own code
(usually code to do something and then call the original function).
The cleanup_module() function is supposed to undo whatever init_module() did,
so the module can be unloaded safely.
For example, if you have written a C file called module.c
(with init_module() and cleanup_module() replacing the main() function),
the code can be converted into a module by typing :
<verb>
$ gcc -c {SOME-FLAGS} my_module.c
</verb>
This command creates a module file named module.o, which can now be inserted
into the kernel by using the 'insmod' command :
<verb>
$ insmod module.o
</verb>
Similarly, for removing the module, you can use the 'rmmod' command :
<verb>
$ rmmod module
</verb>
<sect1>
Creating RTLinux Threads
<p>
A realtime application is usually composed of several ``threads'' of execution.
Threads are light-weight processes which share a common address space.
In RTLinux, all threads share the Linux kernel address space.
The advantage of using threads is that switching between threads
is quite inexpensive when compared with context switch. We can have
complete control over the execution of a thread by using different functions
as will be shown in the examples following.
<sect1>
An example program
<p>
The best way to understand the working of a thread is to trace a realtime
program. For example, the program shown below will execute once every second,
and during each iteration it will print 'Hello World'.