1 Setting up a Virtual Machine In all the assignments, we will work with the same virtual environment. This ensures that everybody has the same platform and that your current machine doesn’t get corrupted while playing with the kernel :) You need to install either VMWare or VirtualBox. VMWare download VirtualBox download Tip. We advice you to use VirtualBox because is free and open source. You can also use a free version of VMWare, however this version does not support snapshots. We also recommend you to assign at least 20GB of harddrive space. Once installed, create a new virtual machine based on Ubuntu 12.04 (Precise) Ubuntu download The process should be quite straighforward, but if you need a tutorial please refer to LMGTFY.
Trang 1Operating Systems ’14 - CS 323
Assignment #1
System Call February 24, 2014
1 Setting up a Virtual Machine
In all the assignments, we will work with the same virtual environment This ensures that everybody has the same platform and that your current machine doesn’t get cor-rupted while playing with the kernel :)
You need to install either VMWare or VirtualBox [VMWare download] [Virtual-Box download]
Tip We advice you to use VirtualBox because is free and open source You can also use a free version of VMWare, however this version does not support snapshots
We also recommend you to assign at least 20GB of hard-drive space
Once installed, create a new virtual machine based on Ubuntu 12.04 (Precise) [Ubuntu download]
The process should be quite straighforward, but if you need a tutorial please refer
to [LMGTFY]
2 Getting started with the Kernel
As we saw in the exercise session, the kernel is a very important part of an Operating System While the outermost part of the OS is made out of user-interface like pro-grams, the inner part - called kernel - is in charge of providing the basic services for all the other parts of the system, it manages hardware and distributes system resources
We also saw in the lectures, that a system call is part of the kernel The user can operate in kernel mode thanks to system calls They let users manage processes, files and devices
In this assignment we will implement a simple system call, therefore we will need
to recompile the Linux kernel
A useful reference: Ubuntu Build Your Own Kernel
Trang 22.1 Kernel source code and Git
The Linux Kernel, as any opensource project, has many collaborators and they need
to rely on a tool to distributedly control its versions Some examples of such tools are: CVS, SVN and Git Linus Torvalds (creator of Linux) himself created Git and, like the kernel hackers, we will use it for the assignment
Although you dont need to know some of Git commands for this assignment, we recommend you to take a look to this basic Git tutorial [Git tutorial] Knowing Git basics is helpful to any kind of collaboration with source code, which you will for sure need in the future, starting from using it in other course projects to collaborate with your mates to working for a company like Google, Microsoft, Facebook, Twitter and
so many others that use Git
To have the Linux Kernel source code in your machine, you first need to install some packages and use Git to clone the code from the official site:
sudo apt-get install dpkg-dev git
sudo apt-get build-dep linux-image-$(uname -r)
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise.git
Now you need to switch to the tag with the same kernel version in the installed Ubuntu You can first verify if the correct tag is in the downloaded source
cd ubuntu-precise
git tag -l Ubuntu-lts-3.11*
Now you can checkout the tag and create a new branch to avoid any potential problems with different kernel versions
git checkout -b os_assignment_1 Ubuntu-lts-3.11.0-15.25
If you are not running as a root, you will need to install fakeroot: fakeroot to simulate root privileges:
sudo apt-get install fakeroot
Then, you can simply build the kernel by going to the source directory and using the following two commands:
sudo fakeroot debian/rules clean
sudo fakeroot debian/rules binary-headers binary-generic
Note Please be advised that this last step will take a considerable long time (up
to 1-2 hours), specially if compiling for the first time To speed things up on next compilation (especially if cleaned), consider installing ccache before the compilation: sudo apt-get install ccache
vi ~/.bashrc
+export CCACHE_DIR="<your home directory>/.ccache"
+export CC="ccache gcc"
Trang 3+export CXX="ccache g++"
+export PATH="/usr/lib/ccache:$PATH"
source ~/.bashrc
ccache -M 4G
If the compilation is successful, three debian packages (.deb) will be created in the directory above
ls /*.deb
would output:
/linux-headers-3.11.0-15-generic_3.11.0-15.25~precise1_amd64.deb /linux-image-3.11.0-15-generic_3.11.0-15.25~precise1_amd64.deb /linux-tools-3.11.0-15-generic_3.11.0-15.25~precise1_amd64.deb
In addition you might also have this debian package
/linux-headers-3.11.0-15_3.11.0-15.25~precise1_all.deb
Then you need to install missing dependencies:
sudo apt-get install linux-lts-saucy-tools-3.11.0-15
Tip To maintain the same version of kernel in your source and in the Ubuntu in-stalled, do not update any of the kernel packages (update manager will prompt asking
to install them)
Finally, to load your new kernel, use:
sudo dpkg -i *.deb
sudo reboot
After reboot, verify the correct version of the kernel (including the date and time!) by:
uname -a
Tip Use snapshots of your VM everytime you install/compile, this way if some-thing goes wrong you can revert to a previous stable state
3 Your system call
It is now time to implement your custom system call This system call should return
a system wide unique identifier each time it is called, even for system calls made concurrently by different threads or processes These identifiers can repeat after each reboot Such a system call can be used for example to generate names for temporary files The specifications are as follow:
1 The system call should be named get_unique_id
Trang 42 It should take exactly one argument int *uuid which is the memory location where the unique identifier will be stored after the call
3 It should return long indicating the return value — 0 for success and (minus) error code otherwise
4 The system call should check whether memory location supplied by the user is valid and return -EFAULT otherwise Consider using function put_user from
#include<linux/uaccess.h>
To implement a system call, you have to modify and add multiple files (in the following instructions we assume an x86 processor):
1 Add your system call to the list in arch/x86/syscalls/syscall_64.tbl (should
be 543)
2 Do the same in arch/x86/syscalls/syscall_32.tbl (should be 351)
3 Add the prototype of your system call to include/linux/syscalls.h
4 Create a new file get_unique_id.c in the kernel folder with the following skele-ton code:
# include < l i n u x / l i n k a g e h >
a s m l i n k a g e l o n g s y s _ g e t _ u n i q u e _ i d ( int * u u i d ) {
// y o u r c o d e }
5 Add the file to the Makefile in /kernel/Makefile by adding get_unique_id.o
to the list in obj-y +=
You may now implement and test your system call according to the specifications
Do not forget to recompile and reload the kernel before testing!
To test it, you can use following userland code:
# i n c l u d e < s t d i o h >
# i n c l u d e < e r r n o h >
# i n c l u d e < sys / s y s c a l l h >
# d e f i n e I S _ 3 2 _ B I T 0
# if I S _ 3 2 _ B I T
# d e f i n e _ _ N R _ g e t _ u n i q u e _ i d 351
# e l s e
# d e f i n e _ _ N R _ g e t _ u n i q u e _ i d 543
# e n d i f
l o n g g e t _ u n i q u e _ i d ( int * u u i d ) {
r e t u r n s y s c a l l ( _ _ N R _ g e t _ u n i q u e _ i d , u u i d ) ? e r r n o : 0; }
Trang 5int m a i n () {
int u u i d ; int res ;
res = g e t _ u n i q u e _ i d (& u u i d );
p r i n t f ( " S y s c a l l r e t u r n e d % d , u u i d is % d \ n " , res , u u i d );
res = g e t _ u n i q u e _ i d (& u u i d );
p r i n t f ( " S y s c a l l r e t u r n e d % d , u u i d is % d \ n " , res , u u i d );
res = g e t _ u n i q u e _ i d ( 4 7 4 2 4 7 4 2 ) ; // a r b i t r a r y m e m o r y a d d r e s s
p r i n t f ( " S y s c a l l r e t u r n e d % d \ n " , res );
r e t u r n 0;
}
Note Please bear in mind that this program is just an example of how you can
test your program and it is not a complete test suite nor the one we will use in grading
In particular you need to test for concurrent access yourself
Hint To deal with concurrency you can use atomic counters
Some additional useful references: [Source1] [Source2]
Note: if you come across ”xyz is not clean, please run ’make mrproper’” error,
do
rmdir /include/config
4 Deliverable
This assignment is due in March 18, 11:59pm
You will be submitting a git patch Commit your work using git commit (do not
forget to git add new files) Use
git format-patch HEAD~1
to prepare your submission It should create 0001-xxx.patch file and you will submit
this file Note that if you already committed and you need to change your submission,
you can either
• amend your last commit by git commit amend [Git amend]
• commit second time and then git rebase squashing your commits together
[Interactive rebase]
You can test that your submission can compile by creating a new VM, git apply-ing
the patch and building the kernel