CECS Home | ANU Home | Search ANU
The Australian National University
ANU College of Engineering and Computer Science
Research School of Computer Science
Printer Friendly Version of this Document

UniSAFE

Operating Systems Implementation

Laboratory 5 - VirtualBox for kernel development with Linux and A simple character device

Learning Objectives

The main learning objectives for this lab are to:
  • use VirtualBox,
  • to learn a bit about the workings of linux devices, and
  • obtain a bit more practice at hacking some c code.

Preparation

Read through the manual pages for mknod. You will also need to gain an understanding about the UNIX the device structure. Also draft your code for the program your are required to write during the lab.

During the Lab

In this lab you will create a simple character device driver as a loadable module. The device file should be called ramp and will output a repeating sequence of characters from 'A' to 'Z'. You will than extend the device driver in a number of ways.

Note that, this device controls no real hardware, however, it highlights how UNIX interfaces with devices. And it is simple to see how you could add some calls within both read_ramp and write_ramp to directly control some underling hardware.

Step 1 - VirtualBox

VirtualBox enables you to run an entire OS as a normal user. This provides a more stable way of doing kernel development.

This can be all done without 'admin' access.

Obtain a copy of an ubuntu 'iso' and place it in the /scratch directory. They are available locally at:

http://mirror.linux.org.au/ubuntu-releases/10.04/
I have used:
 ubuntu-10.04-desktop-i386.iso
This file is also available in class' public directory.

Run VirtualBox (from the applications->accessories menu).

Within the VirtualMachine manager (from the File menu) add the unbuntu iso to the CD/DVD Images.

Click on "New" to create a new virtual machine. Give it a name and say the os is Linux and version Ubuntu. Set the amount of Memory for the Virtual Machine (give it atleast 512MB). Create a virtual hard disk using dynamically expanding storage and placing it in /scratch these are ".vdi" files.

Unbuntu should start running at which point "Install Ubuntu 10.04". If you want to install updates then it is worth pointing the "Update Manager" to the local unbuntu repository (http://mirror.linux.org.au/ubuntu).

Start your new virual machine.

Have a go at doing the rest of the lab in the virtual machine. Add "snapsshots" so you should be able to quickly recover from crashes.

Step 2 - Reading from the device

Start off by grabbing the hello_module.tar.gz kernel module from the second laboratory. Then perform the following steps:
  • Rename the module "ramp", fixing the Makefile and the name of the main source file.
  • Strip out all the code that has to do with /proc. We won't be creating a /proc entry for this kernel module.
  • Declare a file_operations structure and initialise it with a single entry for a read operation called ramp_read. All other operations can be l eft as NULL. You may find it useful to look at /usr/src/linux/drivers/char/mem.c for an example of how to declare a static file_operations structure.
  • Write a ramp_read() function that returns a sequence of characters from 'A' to 'Z'. Make sure that you advance the *ppos file pointer and retrun the number of characters read.
  • Add a call to register_chrdev() in init_module() and unregister_chrdev() in cleanup_module. Use the value 200 for the major number.
  • Add the required "include" files.
  • Compile your module, insmod it and make sure it appears in /proc/devices.
  • Create a character special file using the command "mknod". See the man page for mknod for details.
  • Test your device by reading from your device file.
  • What happens if you try to write to the device?

Step 3 - Writing to the device

In this exercise you will make the device writeable by supplying a ramp_write function. The function should accept data and remember it so that a subsequent read on the device givesthe same data back. This is similar to the writeable /proc exercise in lab3.

The maximum size of the writeable device is up to you, but be warned that making it unlimited in size will be quite difficult.

Optional Extra - Adding an ioctl

In this exercise you will add an ioctl control on the ramp device so that the size of the device (the amount of data that can be written to it) can be set via an ioctl call on the open device. This is a more difficult exercise, only do it if you have time.

To do this you will need to:

  • Decide on an ioctl number for the size operation
  • Add a ramp_ioctl function in the file_operations structure
  • When ramp_ioctl is called you will need to record the maximum device size and possibly allocate some memory.
  • Write a test program that sets the size of the device and then writes to the device
It would be ideal if your device defined a number of minor devices, each of which can have their size set independently. You will need to work out how to find the minor number of the device in the read function (hint: look for the i_rdev entry in file->f_dentry->d_inode and use the MINOR() macro).