You will build your own Linux kernel for this class. For each homework assignment, you will build a new Linux kernel. The image of the kernel you build for this assignment should be vmlinuz.hmwk2. Grading for this assignment will be done based on vmlinuz.hmwk2.
$ make installOn the first time that you install a new kernel, and everytime you make changes that may affect modules (e.g. modifying an important include file) you also need to install the modules and create a matching initrd image. It is also recommended to update the vmware-tools to match the new kernel. Assuming that your kernel version suffix is ".hmwk2", you can do these by:
$ make modules_installTo let the bootloader, grub, know where to find your kernel, be sure to enter the appropriate information into your /boot/grub/menu.lst file. You can create a new entry by copying an existing one (e.g. that of linux-2.6.18.8-base) and changing all instances of the kernel version to 2.6.18.hmwk2, for example:
$ update-initramfs -c -k 2.6.18.hmwk2
[edit /boot/grub/menu.lst]
[reboot with new kernel]
$ vmware-config-tools.pl
Your task is to add a system call getprocinfo(pid_t pid, struct procinfo *inf) that returns the following data about the specified process:
You can find all of the information you need in task_struct, which is defined in include/linux/sched.h.struct procinfo {
pid_t pid; /* Process ID */
pid_t ppid; /* Parent process ID */
int prio; /* Process priority */
struct timespec last_ran; /* When the process last ran */
int state; /* -1 unrunable, 0 runnable, >0 stopped */
};
If pid is greater than 0, it represents a processID who's information is sought. If it's zero, return the information for the current process. If it's less than zero, return the information for the parent of the current process.
Make sure to check inputs for validity. Return error EINVAL if necessary.
You'll find it useful to look at the kill system call; see sys_kill in kernel/signal.h. Also see sys_getpid in kernel/timer.c.
You need to create a system call entry; use number 223, which is currently unused. You'll also need to create a function getprocinfo() that is called by your test programs. Your kernel has partially reserved a slot in the syscall table for ni_syscall (when you see it, you will know what we are talking about). Since ni_syscall means "not implemented", do not be afraid to commandeer that slot.
Linux maintains a list of all processes in a doubly linked list. Each entry in this list is a task_struct structure, which is defined in include/linux/sched.h. When traversing the process tree data structures, it is necessary to prevent the data structures from changing in order to ensure consistency. For this purpose the kernel relies on a special lock, the tasklist_lock. You should grab this lock before you begin the traversal, and only release the lock when the traversal is completed. While holding the lock, your code may not perform any operations that may result in a sleep, such as memory allocation, copying of data into and out from the kernel etc. Use the following code to grab and then release the lock:
read_lock(&tasklist_lock);
...
...
read_unlock(&tasklist_lock);
Big Hint: In order to learn about system calls, you
may
also find it helpful to
search the Linux kernel for other system calls and see how they are
defined. The file kernel/sched.c
might give some useful
examples of this. The getpid
and getuid
system calls might be useful starting points. The system call
sys_getpid defined in kernel/sched.c uses current and
provides a good reference point for defining
your
system call.
You should create a patch to store changes you've made to the kernel and to submit your changes for this problem. If you've changed 50 lines of code, a patch will be about 50 lines long. This is much easier to store, email, or move around than the full 283,000-line source tree.
Git is a perfect tool to create a patch and apply it. First back up your .config file, then do a ``make distclean'' in your changed source tree (you don't want object files, config files, etc. in your patch). Then, run git format-patch -k --stdout v2.6.18 > ../homework2.patch. Please run git commit for each step of the homework.