Operating Systems ’14 - CS 323 Assignment #1 System Call February 24, 2014 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 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] 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 programs, 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 SinhVienZone.com https://fb.com/sinhvienzonevn 2.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="/.ccache" +export CC="ccache gcc" SinhVienZone.com https://fb.com/sinhvienzonevn +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 installed, 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 something goes wrong you can revert to a previous stable state 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: The system call should be named get_unique_id SinhVienZone.com https://fb.com/sinhvienzonevn It should take exactly one argument int *uuid which is the memory location where the unique identifier will be stored after the call It should return long indicating the return value — for success and (minus) error code otherwise 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 To implement a system call, you have to modify and add multiple files (in the following instructions we assume an x86 processor): Add your system call to the list in arch/x86/syscalls/syscall_64.tbl (should be 543) Do the same in arch/x86/syscalls/syscall_32.tbl (should be 351) Add the prototype of your system call to include/linux/syscalls.h Create a new file get_unique_id.c in the kernel folder with the following skeleton code: # include < linux / linkage h > asmlinkage long sys_g et_uni que_id ( int * uuid ) { // your code } 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: # include < stdio h > # include < errno h > # include < sys / syscall h > # define IS_32_BIT # if IS_32_BIT # define NR _g et _u ni qu e_ id 351 # else # define NR _g et _u ni qu e_ id 543 # endif long get_unique_id ( int * uuid ) { return syscall ( NR_get_unique_id , uuid ) ? errno : 0; } SinhVienZone.com https://fb.com/sinhvienzonevn int main () { int uuid ; int res ; res = get_unique_id (& uuid ); printf ( " Syscall returned %d , uuid is % d \ n " , res , uuid ); res = get_unique_id (& uuid ); printf ( " Syscall returned %d , uuid is % d \ n " , res , uuid ); res = get_unique_id (47424742); // arbitrary memory address printf ( " Syscall returned % d \ n " , res ); return 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, rmdir /include/config 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 SinhVienZone.com https://fb.com/sinhvienzonevn