EECE-4029 Operating Systems Fall 2016
Lab 1

processes, mutex, semaphores, memory management, producer-consumer, files, deadlock, more..

Install Linux On Something, Compile a Kernel Module

due: Sep 2 - nothing to submit to blackboard

Rationale:
    Teaching theory is fine but it is more useful in the long run if it is accompanied by practical experience. We will use the linux OS as a testbed for ideas and to get a feel for controlling a computer at a low level. This experience will be desirable to numerous employers. Linux is used because it is open and is a testbed for most new OS concepts, making it ideal for this class.
 
Note:
The instructions below are not fool-proof. See the instructor if you have problems
 
Install Linux:
Install linux on either 1) a USB flash drive of 32 GB, 16 GB, 8 GB, or, if desperate, 4 GB; 2) an old, disused computer; 3) a windows computer by repartitioning the hard drive to allow for dual booting (could be dangerous); or 4) as a virtual machine on any computer with spare capacity (safe but slow and be really sure to assign more than one processor to the virtual machine). Instructions for installing linux on a USB drive, from an ISO image, or from the network are given in installinux.html. Or use the instructions provided in the full ubuntu linux installation guide. For option 4) (virtualization) see How to Install Ubuntu on VirtualBox. Another virtualization guide is here or get a ready made Ubuntu 14.04.4 vdi image (watch it - I know nothing about this), but expect no support or guarantees from the instructor who has minimal experience with Windows.
 
Kernel Header Installation Options:
Once you have a working linux system, kernel header files and a compiler must be installed in order to compile kernel modules. To get the headers and compilers use apt-get as directed below or you can download the latest kernel directly from kernel.org.

Note: if you download and use the USB image mentioned above and in installlinux.html, you will already have the headers and compilers installed.

  1. Download the kernel from kernel.org: Download, install, configure (optional), and compile (optional) the latest linux kernel sources. Instructions for doing this are given in kernel.html. You might want to use this config file. If you do, rename it to .config and place it in /usr/src/linux-source-4.6.X where 4.6.X is the kernel version.
    Note: it will not be necessary to compile the kernel but installation of the header files corresponding to the running kernel are necessary.
  2. Use apt-get (ubuntu only): The live DVD install disk that can be downloaded from the ubuntu install page should put the headers on your system (see installlinux.html for details). If not, do this as root:
       prompt> apt-get install linux-headers-3.13.0-91 linux-headers-3.13.0-91-generic
    
    where you type what appears in red above and the system prompts are in blue.
Note: you could alternatively use the kernel.org headers but then you will have to compile the kernel and boot into it in order to compile kernel modules.
Note: you must also have pre-compiled kernel modules in /lib/modules/3.13.0-XX-generic where 3.13.0-XX-generic is the same as the header subdirectory in /usr/src/, after linux-headers-. This should have been done automatically when the kernel is installed but is mentioned here because it has been a source of problems in the past as /lib/modules/3.13.0-XX-generic/build is a link to /usr/src/linux-headers-3.13.0-XX-generic that is traversed when compiling kernel code. If the proper kernel headers are not there, the build link is dangling.
 
C/C++ Compiler Installation:
If you installed using the DVD install disk mentioned above, the C compiler should already be installed and you should be able to being compiling kernel modules. If not, to install the compilers do this as root:
   prompt> apt-get install build-essential fakeroot libxml-parser-perl gcc g++
 
Compiling, Loading, and Unloading a Kernel Module:
The following assumes you installed ubuntu with account name student with password student.
You will have to become super user (a.k.a. root) in order to load and unload kernel modules. Installing Ubuntu Linux as above allows access to root as follows:
  prompt> sudo su
  password for student: student
You should only have to type the password once per session per time-period per shell as ubuntu is set to remember the password on a shell for some time-period or until the session is terminated.

Note: although you need to operate as super user to load and unload kernel modules, you should never compile anything as super user!!! You will be really sorry in the long run if you do. There is no doubt you will feel better compiling as root because it is easy to do so and then load a module but you will certainly regret it if you do as you will eventually be in the instructor's office asking for help to repair your system and the instructor is going to remember this visit at the end of the semester.

Next try to compile a kernel module and observe what happens when it is loaded and unloaded. Create a test directory and download source code and a Makefile for a simple module as user student (not as super user) as follows:

   prompt> mkdir Test
   prompt> cd Test
   prompt> wget http://gauss.ececs.uc.edu/Courses/c4029/labs/tester_1.c
   --2014-08-24 14:23:41--  http://gauss.ececs.uc.edu/Courses/c4029/labs/tester_1.c
   Resolving gauss.ececs.uc.edu (gauss.ececs.uc.edu)... 129.137.4.132
   Connecting to gauss.ececs.uc.edu
      (gauss.ececs.uc.edu)|129.137.4.132|:80... connected.
   HTTP request sent, awaiting response... 200 OK
   Length: 345 [text/x-c]
   Saving to: 'tester_1.c'

   100%[========================================>] 345         --.-K/s   in 0.007s

   2014-08-24 14:23:41 (47.0 KB/s) - 'tester_1.c' saved [345/345]

   prompt> wget http://gauss.ececs.uc.edu/Courses/c4029/labs/Makefile
   --2014-08-24 14:23:55--  http://gauss.ececs.uc.edu/Courses/c4029/labs/Makefile
   Resolving gauss.ececs.uc.edu (gauss.ececs.uc.edu)... 129.137.4.132
   Connecting to gauss.ececs.uc.edu
      (gauss.ececs.uc.edu)|129.137.4.132|:80... connected.
   HTTP request sent, awaiting response... 200 OK
   Length: 534 [text/plain]
   Saving to: 'Makefile'

   100%[========================================>] 534         --.-K/s   in 0.001s

   2014-08-24 14:23:55 (691 KB/s) - 'Makefile' saved [534/534]
Now compile the kernel module like this:
   prompt> make
   make -C /lib/modules/3.9.9-302.fc19.i686/build M=/home/franco/Downloads modules
   make[1]: Entering directory `/usr/src/kernels/3.9.9-302.fc19.i686'
     CC [M]  /home/franco/Downloads/tester_1.o
     Building modules, stage 2.
     MODPOST 1 modules
     CC      /home/franco/Downloads/tester_1.mod.o
     LD [M]  /home/franco/Downloads/tester_1.ko
   make[1]: Leaving directory `/usr/src/kernels/3.9.9-302.fc19.i686'
To see the file that is the kernel module do this:
   prompt> ls -a
   Makefile  tester_1.c        .tester_1.mod.o.cmd  tester_1.mod.o  Module.symvers
   ./        tester_1.mod.c    .tester_1.o.cmd      tester_1.o      .tmp_versions/
   ../       .tester_1.ko.cmd  tester_1.ko          modules.order
The kernel module is tester_1.ko and is shown above in green with a lot of auxilliary files that were created during compilation. Load the module like this (assuming you already ran "sudo su" once successfully):
   prompt> sudo su
   prompt# insmod tester_1.ko
   prompt# exit
Check to see whether the module loaded like this:
   prompt> lsmod | grep tester
   tester_1 12394 0
Observe that the module is running like this:
   prompt> dmesg
   ...
   [21045.273404] tester 1: Module loaded successfully
Unload the module like this:
   prompt> sudo su
   prompt# rmmod tester_1
   prompt# exit
Observe the result of unloading like this:
   prompt> dmesg
   ...
   [21045.273404] tester 1: Module loaded successfully
   [21062.871344] tester 1: Module unloaded successfully
If you get a result that looks something similar to the above, you are able to compile modules and check whether they are loaded, running, or unloaded.