OSC:Introduction

From SOFTICE

Jump to: navigation, search

Contents



Introduction to SOFTICE's OSC Labs

Pedagogical Objectives
  • Connecting to the softice cluster
  • Using the User Mode Linux virtual machine
  • Compiling a (UML) kernel
  • Writing a simple Loadable Kernel Module (LKM)
  • Inserting, removing and listing LKMs
Developed by:

Synopsis

This lab's objective is to take the time to get you started working on softice, connecting to the server, discussing with your instructor what's behind its IP, learning about the virtual machine we will be using (User Mode Linux -- UML) and learning how to start one, log into it and work there. Then, we will conclude this laboratory by writing, inside of the UML virtual machine, our first loadable kernel module. This first LKM will simply log messages like "hello world" to the console of the system.


[Briefing] Getting started

Connecting to SOFTICE

The first step is to connect to the SOFTICE cluster (from home / classrooms / ...). The exact procedures will likely vary from course to course; check with your instructor, who should have used a presentation similar to this one during the first class session.


Using a UML virtual box

Once you have logged in, you can run the following command to start the UML virtual machine:

softice-osc-run

After a few moments, the UML kernel will boot up and present you with a login prompt. Enter root as the login. You will not be prompted for a password and will be directly logged on the virtual machine where you can do anything a root user could do on a physical Linux system. Play around, enjoy your super user privileges and, once done using UML, type:

halt 

The virtual machine will shutdown and the process halting it will exit. You will have the shell prompt form your user account on the softice server available to you again.

Moving information into / out of your virtual machine

At this point, you can distinguish two things:

* your regular-user account on the softice server, inside of which you can execute a virtual machine
* your root account inside of your own personal virtual machine 

While it is easy, using tools such as SSH client or PUTTY (cf Downloads for OSC course wiki page), to transfer files between your desktop and your softice account, it isn't obvious how you can do so with your virtual machine since it isn't open to the internet. For your convenience, each virtual machine has been configured so that it has a directory /root/SOFTICE-USER-ACCOUNT/ which is mapped (the correct term is mounted) from the softice machine. Inside of this directory, you will find subdirectories for all the students accounts on the machine. You can navigate through them to reach yours and simply work on its contents irectly from within your virtual machine. Once again, the specific details might vary from course to course and your instructor will brief you up during the first day of class.


Compiling your own (UML) kernel

Make sure you are out of your virtual machine before you start this section. We are going to download and compile the source of the Linux kernel on your regular softice user account.

First thing first; we need to download a new kernel source tree that we are going to recompile into an UML virtual machine.

wget ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.16.20.tar.gz

(There may be later versions of the kernel available. If you wish to use one, substitute its version number in place of "2.6.16.20" in this and subsequent commands.)

If in a hurry, you can find this archive in /home/sys/osc/src/. Once you have it, we are going to uncompress it:

tar xzvf linux-2.6.16.20.tar.gz

You should see a flurry of filenames cross the screen as the archive is unpacked.

Then, we move on to configuring the kernel:

cd linux-2.6.16.20/
make ARCH=um defconfig

And eventually (1-2 minutes) compile it into an executable called linux which will be our virtual machine (6-9 minutes).

make ARCH=um

Notice that this procedure is almost identical to the one used to compile a kernel for a physical machine. The ARCH=um command line option specifies which architecture we want to compile our kernel for. We could compile on an intel-based server a kernel to be copied and used to boot a sparc machine. In our case, we target a specific architecture which doesn't physically exist (no um CPU have been designed) but to which the Linux kernel has been ported; the User Mode (um) architecture.

The result of this compilation process is an executable file named linux which will be located in your current working directory. Now we can test our brand new UML virtual machine to make sure it's working:

./linux ubd0=~/.softice-osc/core-debian.rfs con=null con0=fd:0,fd:1

Note that we are this time running the UML virtual machine ourselves, without using the softice-osc-run script mentioned above and which is meant to spare us the typing of all the options. If you are curious you can look at this script and you will see that all it does is using the same syntax. Here is the meaning of the command line:

./linux we run the UML executable we just compiled
ubd0=~/.softice-osc/core-debian.rfs Each UML virtual machine will need a disk to boot from. We are not using physical disk but virtual disk images which store inside of a single file anything that would be stored on a real physical disk. This option specifies which disk image to use and, by convention, all our disk images will have suffix .rfs standing for Root File System.
con=null con0=fd:0,fd:1 These options, which we won't detail, instruct the virtual machine to use the terminal you are currently executing it from to display what the Linux machin would display on its physical console


Try to login with the same username root and no password and you're in. Once you have tried couple of commands (ps, top, whoami, ...), shutdown the UML instance with a:

 
shutdown -h now

[Solved] Hello Kernel World module

Loadable Kernel Modules (LKMs)

One of the advantages of Linux is the ability to add code to a running kernel (e.g. device drivers) without need for rebooting the machine. This is accomplished by using Loadable Kernel Modules (LKM). LKMs are units of code which are not linked as a complete executable but meant to be dynamically linked into a running kernel. They extend the functionality of the kernel without the need to reboot the system and are typically used to add support for new hardware, filesystems, or for adding and modifying system calls. When a module is no longer needed, it can be removed from the kernel, thus freeing up system resources. This makes for a very flexible and convenient way to add "features" and "capabilities" to the kernel.

Without Linux Loadable Kernel Modules, the Linux kernel would have to be built with all possible anticipated functionality directly into the kernel image. This would result in a larger kernel requiring more system resources. Also, changing directly the kernel code means that it must be re-compiled and re-installed on the system for the new functionality to be available.

Your account on the softice server is a regular user account. This means that while you could write and compile LKMs on it, you wouldn't be allowed to load them on the running kernel. On the other hand, when you execute a UML virtual machine, you are root inside of it and can therefore write a module, compile it and run it inside the virtual machine without problems.


We are going to start our work with LKMs by starting a UML virtual machine, logging into it as root, and writing our first module. Here is the source code of a simple LKM which is going to display a "hello world" message when loaded into the kernel of the virtual machine and another message when unloaded. Of course, LKMs are not like the programs you have been writing all along. They execute as part of the kernel in what has been defined in the lectures as "kernel land". One of the (many) particularities of programming in "kernel land" vs. "user land" is that your programs can't just print a message on the screen. This is due to the fact that LKMs have no terminals with which to communicate, they are meant to be executed without supervision when appropriate and inside the kernel.

For this reason, when we want our LKMs to display a message we will have them add an entry to the kernel logs. Fortunately, the syntax of the printk system call available for programs written in the kernel is very similar to the syntax of the printf function which is made available for "user space" programs by the C standard Library. It is worth pointing out that other standard C library functions (malloc, realloc, ...) are also unavailable to kernel programmers. Think of stdlib as being "a layer" on top of the kernel itself, no way to use it when programming at the kernel level!


Sample program to test

Here's a code sample which uses printk to implement the LKM equivalent of a hello world program:

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("GPL"); 

static int hello_init(void)
{
        printk( KERN_ALERT "[hello mod]   Hi there \n"); 
        return 0; 
}

static void hello_exit(void)
{
        printk(KERN_ALERT "[hello mod]   all done\n"); 
}


module_init(hello_init); 
module_exit(hello_exit); 


[Solved] Playing around with our first LKM

Now that we have a first LKM, we can compile it and insert it inside of the kernel of our UML virtual machine.


Compiling a LKM

Login to your SOFTICE account and create a subdirectory 00_hello in which you will copy the above example into a file mylkm.c.

We can then start a UML virtual machine with softice-osc-run and access the information in your SOFTICE account from the directory /root/SOFTICE-USER-ACCOUNT/. Making your SOFTICE user account home directory accessible from within the virtual machine is done automatically when starting it.

softice-osc-run

You can now go inside the 00_hello directory you created and compile the source code of the kernel module using the make-lkm script followed by the name of your LKM .c file without the .c suffix. If you need to edit the code, you can use another editor in a ssh windows connected to your SOFTICE user account.

cd /root/SOFTICE-USER-ACCOUNT/YourUserName/00_hello/

Where YourUserName is your account login name

make-lkm mylkm

Inserting a module in the UML Kernel

This section describes the steps necessary to insert a module into the kernel.

Issue the following commands to insert a module, called hello.ko, into the kernel:

insmod mylkm.ko 
lsmod  (shows information about all loaded modules)

Removing a Module from the UML Kernel

Modules are unlinked from the kernel by the rmmod program.

Issue the following commands to remove a module from the kernel:

rmmod hello
lsmod  

The latter shows information about all loaded modules.

References

[LDD] Linux Device Drivers, Third Edition (safary reference)


[LPMPG] The Linux Kernel Module Programming Guide