$29
Introduction
Welcome to the first programming assignment for CSCI 3753 - Operating Systems. In this assignment we will go over how to compile and install a modern Linux kernel, as well as how to add a custom system call. Most importantly you will gain skills and set up an environment that you will use in future assignments.
You will need the following software:
1. CSCI 3753 Fall 2018 Virtual Machine (https://foundation.cs.colorado.edu/vm/)
All other software and files should be installed on the virtual machine image. It is important that you do not update the virtual machine image as all the assignments are designed and written using the software versions that the VM is distributed with. Also make note that this assignment will require you to re-compile the kernel at least twice, and you can expect each compilation to take at least half an hour and up to 5 hours on older machines.
Assignment Components:
1. Configure GRUB
2. Downloading source code for Linux
3. Compile the kernel
4. Add a system call
5. Write a test program that uses the system call
CSCI 3753: Operating Systems
A. Configuring GRUB
GRUB is the boot loader installed with Ubuntu 14.04. It provides configuration options to boot from a list of different kernels available on the machine. By default Ubuntu 14.04 suppresses much of the boot process from users; as a result, we will need to update our GRUB configuration to allow booting from multiple kernel versions and to recover from a corrupt installation. Perform the following:
Figure 1: Linux GRUB Boot Menu
Step 1:
From the command line, load the GRUB configuration file:
sudo emacs /etc/default/grub
(feel free to replace emacs with the editor of your choice).
Step 2:
Make the following changes to the configuration file:
1. Comment out:
GRUB_HIDDEN_TIMEOUT=0
2. Comment out:
GRUB_HIDDEN_TIMEOUT_QUIET=true
3. Comment out:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
and add the following new line directly below it:
GRUB_CMDLINE_LINUX_DEFAULT=""
4. Save updates
CSCI 3753: Operating Systems
Step 3:
From the command line, update GRUB: sudo update-grub.
Step 4:
Reboot your virtual machine and verify you see a boot menu as shown in Figure 1.
B. Downloading Linux Source Code
First, you have to download the Linux source code that you will be using for this assignment where you will be adding your new system call, compiling the source and then running the kernel with the added system call. For this execute the following commands in the terminal.
1. cd /home
2. sudo mkdir kernel
3. cd kernel
4. sudo apt-get source linux-source-4.15.0
5. sudo apt-get install cu-cs-csci-3753 (command to install all the packages necessary for this course)
6. cd linux-hwe-4.15.0
C. Compiling the Kernel
Step 1:
Typically it takes a long time to compile (2-3) hours to compile the kernel source code. To get around this, install ccache by running the following command
sudo apt-get install ccache
ccache is a compiler cache. It is used to speed up recompilation by caching previous compilations and detecting when the same compilation is being done again. The first compilation will take the usual long time but after you make the necessary changes, the recompilations will be much faster after you install ccache.
Step 2:
The next step is to create the config file
sudo cp /boot/config-$(uname -r) .config
command will create the config file. Run the command in the linux source directory you downloaded and extracted.
The command uname –r gives you the current version of the kernel you are using. So that means you are downloading the same kernel as your current kernel. The command uname –a will give you the system architecture information (for example if your OS is 32 or 64 bit).
CSCI 3753: Operating Systems
Step 3:
In the same folder, execute the command
sudo make menuconfig
A pop up will be generated. Select the general set up (Figure 2) and then select the option append to the release (Figure 3) and enter the name you want to give to the kernel you will be compiling, installing, and running (for example revision1). This name will appear when you reboot and from the grub you can select it and check your new system call.
Figure 2: Configuring the menuconfig
Figure 3: Configuring the menuconfig
CSCI 3753: Operating Systems
Step 4:
Now just run the following commands.
sudo make -j2 CC="ccache gcc"
sudo make -j2 modules_install
sudo make -j2 install
sudo reboot
When the GRUB option shows up, select the version you have installed with the new name appended.
Notes:
On some systems we have encountered build errors using the default command sequence listed above. You may encounter VBox related errors. The files under the ubuntu directory are assumed to be included only in the ubuntu kernel. This problem is caused by not finding the header file correctly.
[Error]
cc1: fatal error: ./ubuntu/vbox/vboxguest/include/VBox/VBoxGuestMangling.h: No such file or directory
compilation terminated.
scripts / Make!le.build: 258: recipe for target ‘ubuntu / vbox / vboxguest / VBoxGuest-linux.o’ failed
[Commands to remedy this error]
cd ubuntu/vbox
ln -s ../include ./r0drv/include
ln -s ../include ./vboxsf/include
ln -s ../include ./vboxguest/include
ln -s ../include ./vboxvideo/include
sudo make -j2 CC="ccache gcc"
[Error]
make [4]: *** No rule to make target ‘ubuntu / vbox / vboxguest / vboxguest / r0drv / alloc-r0drv.o’, needed by ‘ubuntu / vbox / vboxguest / vboxguest.o’. Stop.
[Command]
cd ubuntu/vbox/vboxguest
ln -s ../r0drv/
sudo make -j2 CC="ccache gcc"
See the Tech Note below for solutions to more errors. Start on Step 7 (page 14 of the PDF avail on Moodle)
http://technote.thispage.me/index.php/2016/12/20/ubuntu-16-04-kernel-compile-on-default-setting/
CSCI 3753: Operating Systems
D. Adding System Call
Step 1:
Now you have to write the actual system call. First you will see that the Linux source code is downloaded in the kernel folder. Go to that folder (for example linux-3.13.0) from the terminal. Then follow these steps.
1. sudo gedit arch/x86/kernel/helloworld.c
and copy paste the following code snippet and save it
2.
#include <linux/kernel.h>
#include <linux/linkage.h>
asmlinkage long sys_helloworld(void)
{
printk(KERN_ALERT "hello world\n");
return 0;
}
Explanation:
1. Now kernel.h header file makes us able to use the many constants and functions that are used in kernel hacking, including the printk function.
2. Linkage.h defines macros that are used to keep the stack safe and ordered.
3. Asmlinkage is a #define for some gcc magic that tells the compiler that the function should not expect to find any of its arguments in registers (a common optimization), but only on the CPU's stack. It is defined in the linkage.h header file
4. We have named the function sys_helloworld because all system calls’ name start with sys_ prefix.
5. The function printk is used to print out kernel messages, and here we are using it with the KERN EMERG macro to print out "Hello World!" as if it were a kernel emergency. Note that depending on your system settings, printk message may not print to your terminal. Most of the time they only get printed to the kernel syslog (/var/log/syslog) system. If the severity level is high enough, they will also print to the terminal. Look up printk online or in the kernel docs for more information.
Step 2:
Now we have to tell the build system about our kernel call. Open the file arch/x86/kernel/Makefile. Inside you will see a host of lines that begin with obj+=. After the end of the definition list, add the following line (do not place it inside any special control statements in the file)
obj-y+=helloworld.o
Step 3:
Now you have to add that system call in the system table of the kernel. Go to the directory arch/x86/entry/syscalls/ and open the file syscall_64.tbl (if you are using a 32 bit system then syscall_32.tbl). Look at the file and use the existing entries to add the new system call. Make sure it is added in the 64 bit system call section and remember the system call number as you will be using that later. Ask Google if you find any trouble.
CSCI 3753: Operating Systems
Step 4:
Now you will add the new system call in the system call header file. Go to the location include/linux and open the file syscalls.h and add the prototype of your system call at the end of the file before the endif. Check the file structure or google if you have trouble.
Step 5:
Now recompile the kernel using the instructions given in the previous section (Section C).
Step 6:
Now that you have recompiled the kernel and rebooted into the installed kernel, you will be able to use the system call. Write a test c program (check Google or type man syscall) to see how to call a system call and what header files to include and what are the arguments. The first argument a system call takes is the system call number we talked about before. If everything succeeds a system call returns 0 otherwise it returns -1. Check sudo tail /var/log/syslog to or type dmesg to check the printk outputs.
Step 7:
If everything until now has been perfect, now you have to write a new system call. This system call will be given two numbers and an address of where to store the results.
Name the new system call cs3753_add and pass the three arguments to the routine, number 1, number2, and result pointers.
You will need to write a test program that calls the new system call and passes the correct type of argument.
In your system call implementation, you must use printk to log the numbers to be added, add those two numbers, store the result location, use printk to log the result and then print the result again in the test program that you will be running in the user space. Do all the changes necessary from section 3’s step 1 to step 6 again to test this new system call.
CSCI 3753: Operating Systems
References:
1. Textbooks
2. https://help.ubuntu.com/community/Grub2
3. https://help.ubuntu.com/community/Kernel/Compile
4. http://kernelnewbies.org/
5. /kernels/linux-3.13.0/Documentation
6. http://technote.thispage.me/index.php/2016/12/20/ubuntu-16-04-kernel-compile-on-default-setting/
Grading
1. 10 percent for compiling the first kernel
2. 10 percent for adding the necessary snippets for new system call
3. 10 percent for compiling with the new system call
4. 10 percent for the test program in userspace that will call the new system call,
5. The following files have to be submitted by the due date
a. arch/x86/kernel/cs3753_add.c
b. arch/x86/kernel/Makefile
c. arch/x86/entry/entry/syscalls/syscall_64.tbl
d. include/linux/syscalls.h
e. /var/log/syslog
f. Source code for your test program
g. A README with your contact information, information on what each file contains information on where each file should be located in a standard build tree, instructions for building and running your test program, and any other pertinent info.