Individual assignment; 100 points total
Submission notes
Submit a single gzipped tarball named UNI-hw4.tgz
The top level directory in the tarball must be hw4
.
Please use the kernel version 4.4.50.
mmk
that automates all the steps starting from make
./mmk 4.4.50 jwl3
mmk
script in the kernel source directory, linux-4.4.50
.In this part, you will reduce your kernel build time drastically.
Go back to the part 1 instruction (and Arch KCT). Regenerate .config
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 .config.UNI-from-lts
Run 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 mmk
script
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:
Place mko
alongside mmk
, in your linux-4.4.50
directory.
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
original version.
First of all, if you don’t know Git, go through my Git tutorial right now.
Start by running git init
in the linux-4.4.50
directory.
Everything you do in this assignment will be inside the directory. We
will call this directory the TOP.
Create your 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 mmk
and mko
in the TOP from part 1 & 2.
You must create a 0-length file named .scmversion
in the TOP by
typing 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
‘+’ character.
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 .config
.
In your 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
following command:
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 CallImplement 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 test
directory and write a user level test program to call the supermom()
system
call. Name your test driver hw4-test.c
. After you’re done with this
part, 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:
Synopsis:
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 errno
to EINVAL
. In addition,
you may optionally print “Not Yo Mama” to kernel log.
man syscalls
for syscall return value convention.uid
is not NULL, the effective user ID of the calling process’s
parent process is written to *uid
.EACCES
.LKD chapter 5 tells you what you need to do to copy values between kernel and user spaces.
getppid()
and geteuid()
, for instance.Documentation
subdirectory 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
the machine.
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 module
directory inside the test
directory and put Makefile
and
supermom.c
:
test/module/Makefile
test/module/supermom.c
The system call will be activated when you call sudo insmod
supermom.ko
and it will be deactivated when you call sudo rmmod
supermom.ko
. When the supermom()
syscall is not activated, it will
return ENOSYS
, indicating that the function is not implemented.
Big hint: use pointer to function.
Good luck!
Last updated: 2017–02–20