COL788: Embedded Computing


Lab Assignment – 1


Due Date: 2nd Sep, 2016. 5pm.


Objective:

  1. Getting Linux kernel build for ARM setup on your system.

  2. Understand how system calls are implemented.

  3. Implement your own system call and user program to test it.


Procedure:


  1. Get Linux kernel setup working as per instructions at https://balau82.wordpress.com/2012/03/31/compile-linux-kernel-3-2-for-arm-and-emulate-with-qemu/

  1. Once you have the kernel built and booting over qemu, proceed with the next assignment to implement system calls.

  2. Understand the system call implementation in Linux.

  3. Implement a new system call named getprocinfo with the following features. Once the system call implementation is done, write a user program which makes use of this system call to test the system call.

It takes two arguments: a process identifier value; and a reference to a process information struct that you need to define in a new header file.


getprocinfo fills in the field values of the second argument with information about the specified process. If the pid argument is 0, then getprocinfo should "return" information about the calling process, otherwise it should "return" information about the process with a matching pid value. The system call returns 0 on success, and one of the following error values otherwise (feel free to add additional error return values):


(ESRCH, EINVAL, ... , are defined in linux/errno.h). Take a look at how other system calls return error values to figure out how your code should do this.


Start by defining a the proc_info_struct in a new header file that you create in include/linux/. The struct should have the following fields:


pid_t pid; /* pid of process */

pid_t parn_pid; /* pid of its parent process */

pid_t gid; /* group id */

unsigned long user_time; /* total CPU time in user mode*/

unsigned long sys_time; /* total CPU time in system mode*/

long state; /* its current state */

unsigned long long sched_avg_running; /* its scheduled ave running time */

unsigned int time_slice; /* its scheduling time slice */

unsigned int policy; /* its scheduling policy */

unsigned long num_cxs; /* number of context switches it has had

(sum of voluntary and involuntary cxs) */

int num_children; /* the number of child processes it has */

char prog[16]; /* its exec'ed file name (e.g. a.out) */



You can fill in these values by accessing a process' task_struct that is defined in include/linux/sched.h. Field values in the proc_info_struct that correspond to null pointer values in the process' task_struct should be set to -1. Not all field values in your struct match the names of fields in the task_struct, so you may need to read through some code and/or try some things out before you get the right values for these fields. Additionally, some values may need to be obtain indirectly via task_struct fields. Types are defined in types.h files in architecture neutral and architecture specific subdirectories of include. For example: linux-source-<version>/include/linux/types.h. Errors are defined in linux-source-<version>/linux/asm-generic/errno.h


When dealing with pointer parameters, you need to make sure that your system call doesn't dereference bad addresses: the kernel should never crash when the user passing in a bad address value to a system call. Also, remember that you need to explicitly copy values passed-by-reference to/from kernel space from/to user space. Use the functions access_ok, copy_from_user, and copy_to_user. Look at other system calls to see how these are used. A few things to help you determine what to do and if your system call returns correct information:




Submission Instructions:


Please create a tarball containing the below files and submit on moodle before the deadline.

  1. The files which have been modified compared to the base source code (for implementing the system call).

  2. Source code for user program(s) created to test the implemented syscall.

  3. A short report containing:

    1. Your approach to implementing the system call.

    2. What features have been tested using the user program (e.g. normal functionality, error handling, etc.).

    3. Any limitations/caveats in your implementation.

    4. 3 key learnings from this exercise.