Individual assignment; 100 points total
Submit a single gzipped tarball named
The top level directory in the tarball must be
Please use the kernel version 4.4.50.
mmkthat automates all the steps starting from
./mmk 4.4.50 jwl3
mmkscript in the kernel source directory,
In this part, you will reduce your kernel build time drastically.
Go back to the part 1 instruction (and Arch KCT). Regenerate
so that it contains only those modules that you are currently using.
This will cut down the number of modules from something like 3000 to
under 100. Here is how.
First, backup your
.config to something like
make localmodconfig. This will take your current .config and
turn off all modules that you are not using. It will ask you a few
questions. You can hit ENTER to accept the defaults.
Now you have a much smaller
.config. You can follow the rest of
the steps starting from
make -jN. (You can run your
instead of following the steps manually, of course.)
When you are hacking the kernel code, a lot of times you make simple
changes to some .c files. If you didn’t touch any header file, the
modules will not be rebuilt when you run
make, thus there is no reason
to reinstall all modules.
Make a stripped-down version of your
mmk script called
mko (for “make
kernel only”), which does only the following 3 things:
mmk, in your
Now you have
mmk to build the kernel, install modules, and rebuild
vboxguest, but much, much faster than before thanks to the smaller
.config. In addition, you have
mko for quick build & reboot cycles
when you didn’t recompile any modules. You are ready to add some system
calls to your kernel.
You will make the
linux-4.4.50 directory a git repo, but a sparse one.
What do I mean by that? You will leave most of the files in the directory
untracked. You will track only those files that you modify from the
First of all, if you don’t know Git, go through my Git tutorial right now.
Start by running
git init in the
Everything you do in this assignment will be inside the directory. We
will call this directory the TOP.
README.txt in the TOP. Note that there is Linux kernel
README in that directory. Do not touch that. Your homework readme is
README.txt. Track the
README.txt in the git repo.
Don’t forget to track
mko in the TOP from part 1 & 2.
You must create a 0-length file named
.scmversion in the TOP by
touch .scmversion. This will prevent the Makefile in the TOP
to mess up your kernel version string by appending a git commit id or a
You may find
git status -uno command handy. The
-uno option hides
all untracked files from the report. (I got into the habit of typing
“Ctrl-R uno” to pull up the command from bash history.)
So the only files you track are:
Do NOT track any dot files such as
README.txt, tell us which git commit ID represent which part.
For example, given the following git log:
commit 23d9a93737638b81a6eaed53e4c492c1efdb5469 Put supermom implementation in a module. commit 3c2657bd8cc59f2818d52a65d5a30370bed2112a Replaced hello() syscall with supermom(). commit 7cffa3e6ceed114be353eae812af3524677b8874 Tested hello() syscall in test/hw4-test.c. commit be6fb3dd89e105ec1d4da32df4c6d40d0d097bf9 Added hello() system call. ...
You will write in your README.txt:
part5: 23d9a93737638b81a6eaed53e4c492c1efdb5469 part4: 3c2657bd8cc59f2818d52a65d5a30370bed2112a ...
This way, the grader can
git checkout 3c265 to revert your repo to
part2 state if necessary.
When you are ready to submit your work, you will go into the directory
one level above the
linux-4.4.50, and clone the repo using the
git clone linux-4.4.50 hw4
Note that the hw4 directory will contain only a handful of files and directories. You then make a tar ball for submission.
tar czvf UNI-hw4.tgz hw4
The tar file is supposed to be very small, probably under 100KB. If you have a big file, you did something wrong.
If you are a git ninja and use branches, maybe to collaborate among the team members, please make sure that the master branch has everything that matters and is currently checked out when you tar.
If you have set up a shared directory between your VM and the host
machine, you can git-clone into your host directory to make a backup of
your code. It’s an incremental backup too–you go into the shared
directory from your VM and run
git pull to bring it up to date.
The graders will copy your repo over the pristine linux–4.4.50
directory and build the kernel. They will also look at your git log and
the diffs (using
git log -u). Please make your commit log meaningful.
Please make sure you understand the process. Ask in the mailing list if you have any questions.
supermom() system call that checks if the parent process of the
calling process has a superuser privilege.
You must read LKD chapter 5 in order to understand how adding a system call works in general. Unfortunately, some of the steps described in the LKD book have changed since the book was written.
You are welcome to consult any source for the procedure to add a system call into a recent kernel. Here is a very good one that I verified that it works: http://www.cs.albany.edu/~sdc/CSI500/Fal13/Labs/OwnSyscallV3plus/OwnSyscallFE.html
At the time of this writing, Linux kernel has about 380 system calls. New
system calls are constantly being added to the Linux kernel. Let’s leave
some room and use 400 for our
supermom() system call.
Please put your system call code in
kernel/hw4.c. Create a
directory and write a user level test program to call the
call. Name your test driver
hw4-test.c. After you’re done with this
git ls-files should look like this:
$ git ls-files README.txt mmk mko arch/x86/entry/syscalls/syscall_32.tbl kernel/Makefile kernel/hw4.c test/hw4-test.c
The system call works as follows:
long supermom(pid_t pid, uid_t *uid)
If the given pid is NOT the pid of the calling process’s parent
process, it will return –1 and set
EINVAL. In addition,
you may optionally print “Not Yo Mama” to kernel log.
man syscallsfor syscall return value convention.
uidis not NULL, the effective user ID of the calling process’s parent process is written to
LKD chapter 5 tells you what you need to do to copy values between kernel and user spaces.
geteuid(), for instance.
Documentationsubdirectory of the kernel source. Check out
credentials.txt, for example.
man 7 credentials
The purpose of this part is to learn how to add a system call, and get a little bit of practice navigating through kernel code and documentation. As such, we are going to ignore a big issue in correctly implementing a system call – we are going to ignore race conditions. You don’t have to worry about synchronization in implementing supermom().
By now, you must be tired of rebooting your VM every time you make a small
change in system call code. In this part, we will move the code for
supermom() into a dynamically loadable kernel module. Our goal is to be
able to make modifications to the system call code without having to reboot
There are two ways to implement a system call using a module. You can try to modify the system call table from the module initialization code. Changes in recent kernels on the mechanics of setting up system calls make this method more cumbersome than it used to be, so we are not going to do this.
Another way is to leave the system call definition in the static kernel code, but have it call another function defined in a module. This is our approach.
First, read this article, The Kernel Newbie Corner: Kernel Symbols: What’s Available to Your Module, What Isn’t, to learn about kernel symbols.
Use the module skeleton code and Makefile from HW2. Make a
directory inside the
test directory and put
The system call will be activated when you call
supermom.ko and it will be deactivated when you call
supermom.ko. When the
supermom() syscall is not activated, it will
ENOSYS, indicating that the function is not implemented.
Big hint: use pointer to function.
Last updated: 2017–02–20