Title: Programming Project
1Programming Project 2Linux Kernel Hacking
- CS-502 Operating SystemsFall 2006
2Objective
- To learn how to work with an operating system
kernel - To understand some of the constraints and
techniques of programming in a kernel (versus
user space)
3Method
- To build and install a new Linux kernel
- To add a new system call to the Linux kernel
- To get useful information from the data
structures of a Linux kernel
4Background User vs. Kernel mode
- Hardware provides two modes
- Indicated by bit in PSW
- Allows OS to protect itself system components
against - Faulty and malicious processes
- Some instructions designated as privileged
- Only executable in kernel mode
- System call, all traps, interrupts change mode
to kernel - return from system call resets it to user
5Transition from User to Kernel Mode
6Accessing the Kernel via System Call
- Normally embedded within a library routine
- User API never uses system calls directly
- System call mechanism is machine specific
- Different CPU architectures make system calls in
different ways - System call numbers different for various
architectures - Even for same operating system version!
- E.g., poll system call is 167 on PowerPC but
168 on Intel 386 platforms (in SUSE Linux 9.3)
7Inside Kernel, the OS can
- Read and modify data structures not in user
address space - Control devices forbidden to user processes
- Invoke operating system functions not available
to user processes -
8In this project, we will
- Add a new system call to the Linux kernel
- It does nothing except announce its presence
- Upgrade that system call to provide information
about the process - Information not readily available via existing
system calls - Follow Linux naming numbering conventions
9In this project, we wont
- bother to make a library routine to encapsulate
our systems calls - try to support them on all machine architectures
10To get started
- Find kernel sources in /usr/src
- linux-2.6.11.4-20alinux-2.6.11.4-21.13linux-2.6
.11.4-21.14 - Clone kernel source tree by linked copy
- cp al /usr/src/linux-2.6.11.4-20a myKernel
- Creates a linked copy of original tree in new
directory called myKernel
11Digression on Unix Hard Links
- Directory entries point to files
- Two entries may point to same file!
- Same or different directories
- Same or different name
- Permissions attached to file, not directory
- Called hard links (as opposed to symbolic links)
- Modifications to file seen via all hard links
- mv and rm commands change directories, not files!
- File goes away when all directory entries (i.e.,
hard links) to that file are deleted.
12Cloned Source Tree
- All directories are copied
- All directory entries in copy are linked back to
files in original source tree - To modify a file
- Unlink it (via mv or rm)
- Replace it with modified copy in that directory
- Original is preserved intact in other directory
- Note Versions of Linux kernel sources are linked
copies of each other
13To Modify a File
- mv file.c file.c
- Edit file.c in your favorite editor
- Save as file.c
- (Eventually) delete file.c
- EMACS and patch do this automatically
- Most other editors require you to do it manually
14Part 1 Build Linux Kernel
- Make configuration
- As ordinary user
- Build source tree
- As ordinary user
- Install
- Needs root privileges
15Make configuration
- In a command shell at top of your cloned
directory, do one of - make config
- Very long and tedious
- make menuconfig
- Still somewhat long and tedious also hokey
- make xconfig
- Nice
- make gconfig
- Really nice, but our virtual machines are missing
some libraries to support this
16Make configuration (continued)
- Edit General Setup to name your Local version
- No other edits necessary at this time.
- Save and quit
- If need to rebuild, use
- make oldconfig
- to reuse same configuration
17To Build Kernel
- make gt make-output.txt
- Execute at top of your kernel tree
- Takes
- 40 minutes on csopt4
- one hour on 3 gigahertz Pentium
- Rebuilds after small edits are much faster
- Changing .h files can cause longer rebuilds
18To Install Kernel
- Requires root privileges
- sudo make install modules_install
- Puts kernel, initrd file, symbols in /boot
- Changes links for vmlinuz, initrd
- Adds entries to /boot/grub/menu.lst
- So you can select which kernel to boot
- Some apparent bugs in this process
- Use YaST to repair manually
19Running Your Kernel
- Restart your virtual machine
- Click in boot window
- Use arrow keys to select desired kernel or system
- To determine which kernel is running
- uname -a
20Creating a Patch File
- In kernel tree, remove all object config files
by - make distclean
- One level above kernel tree, do
- diff urN original myKernel gt patch1
- To recreate your directory from patch
- cp al original newKernel
- cd newKernel
- patch p1 lt patch1
21End of Part 1
22Part 2 Adding a System Call
- See Silbershatz, pp 74-78
- Similar problem statement
- Many details are different (due to version of
Linux) - Clone kernel tree from Part1
- Use make oldconfig before building
23Linux Conventions (all versions)
- If your library routine is alarm,
- then the corresponding system call is sys_alarm
- and the corresponding function prototype for
its implementation is - asmlinkage unsigned long sys_alarm (unsigned int
seconds) - Note that asmlinkage is a compiler directive that
tells how to compile the function call - in gcc
24Linux Conventions (continued)
- To invoke alarm system call from a user or
library routine, use macro - _syscall1(unsigned long, alarm, unsigned int
seconds) - _syscalln has n2 arguments
- Return type
- Name of actual system call (in user space)
- Arguments to system call function
- This macro defines the function
- unsigned long alarm(unsigned int seconds)
25helloworld System Call
- / This is the text of the helloworld system call
/ - asmlinkage int sys_helloworld(void)
printk(KERN_EMERG Hello, world!) return
0 - Add to the file kernel/sys.c
26printk(), the Kernel Debug Print Tool
- Very robust
- May be called from (almost) anywhere in kernel
- Same calling convention as printf()
- Writes to system log
- Output survives crashes (almost all of the time)
- To read output, see
- /var/log/messages
- Needs root privileges to read
- Circular log, newest messages at end
- See Linux Kernel Development, 2nd edition, by
Robert Love, Chapter 18.
27Registering your System Call
- include/asm-i386/unistd.h
- Add entry for your call number
- Increment total number of calls
- arch/i386/kernel/entry.S
- Lists entry points for system calls
- Must be kept in numerical order!
- Number must correspond to entry in unistd.h
- Rebuild and install your kernel
28Testing your System Call
- include ltlinux/errno.hgtinclude
ltsys/syscall.hgtinclude ltlinux/unistd.hgtinclude
ltstdio.hgtdefine __NR_helloworld 288 / or
whatever you set it in unistd.h
/_syscall0(int, helloworld)main ()
printf(The return code from the helloworld
system call is d\n, helloworld()) - Check log for the message!
29Create Patch File
- patch2 is difference between kernel tree for
Part1 and kernel tree for Part2
30End of Part 2
31Part 3 Get Process Information
- Modify you kernel of Part 2 to add system call to
get information about process - System call is
- int getprinfo(struct prinfo info)
- info is pointer to area to store results
- Returns zero if successful, error code if not
- See handout for definition of struct prinfo
32Information needed for prinfo
- See task_struct in include/linux/sched.h
- See getuid and getpid for examples of simple
system calls - See include/asm/current.h to find current process
information - Use copy_to_user to safely copy data from kernel
to user space - Return EFAULT error code if info argument is not
valid pointer in user space
33copy_to_user and copy_from_user
- Functions to safely copy data to/from user space
- Check validity of pointer arguments
- Return zero if successful, number of bytes that
fail if there is a problem - Immune to page faults, pre-emption, etc.
34Implementing getprinfo System Call
- Replace helloworld system call from Part 2
- Implement in kernel/timer.c
- Register in unistd.h and entry.S
- Use printk() to print debugging statements to
system log
35Testing getprinfo
- Write test program in user space
- Run multiple times from same shell, different
shell - Note differences in results
- Compare with what you can find about processes
from ps command
36Create patch3
- Patch3 is difference between Part 2 Part 3.
37Submission
- Submit using web-based turnin program
- http//turnin.cs.wpi.edu8088/servlets/turnin/turn
in.ss - Include
- patch1, patch2, and patch3
- Write up explaining results of testing Part 3
- Starting point for your kernel tree
- Put your name on all documents and at top of
every edited file!
38Due Dates
- This project is due at start of class on Monday,
October 16. - Pace yourself
- Part 1 should be complete by October 2
- Part 2 should be complete by October 9
- Part 3 should be complete by October 16
- Report to instructor any difficulties
39Questions?