Release Date: 1/31/2025
Due Date: 2/16/2025 11:59pm
Introduction
The goal of this project is to familiarize yourself with the Linux development environment and gain hands-on experience modifying the Linux kernel source code. The project consists of three parts:
- Analyzing a user-space socket application and instrumenting the Linux kernel by adding
printk()
statements to system call entries. - Measuring the system call overhead
- Implementing a new system call that encrypts a given string and prints the encrypted output to the kernel message log.
Please submit ${YourPID}-lkp25-p1.tar.gz
on Canvas, organize your files in the folllowing format:
${YourPID}-lkp25-p1/
- code-socket.tar.gz
- printk.patch
- gettimeofday.c
- paper-review.md
- …
Recommended Background Reading
Part 1. Adding printk()
The attached source code p1.tar.gz is a simple socket application that exchanges messages between a server and client. It consists of three files as shown in below.
$ cd code-socket
$ ls
client.c Makefile server.c
1.1: Understanding source code
[10 points] Carefully read above three source file to understand how a simple network client/server works. Once you completely understand each file, add comments of each line (M1-M10, S1-S9, and C1-C7) explaining what the line means. Turn in a gzip-ed tarball.
$ tar czvf code-socket.tar.gz code-socket/
code-socket/
code-socket/client.c
code-socket/server.c
code-socket/Makefile
1.2: Adding printk()
[10 points] Now you understand how the user-space application works. To understand how a kernel system call is called, print any message at the very beginning of system call implementations of accept()
and connect()
in Linux kernel v6.12. Check if the modified kernel prints out messages you added when you run the network client/server. Then create a patch against kernel v6.12 using git diff
command and turn in the patch named printk.patch
.
1.3: Test your kernel
[10 points] Upload the screenshot of your kernel debug message using dmesg
while running the network client/server. Run server
, client
, and dmesg
in one ssh session using tmux
.
Part 2: Adding a new system call
Add a new system call named sys_s2_encrypt()
that takes two arguments, a NULL-terminated string and an encryption key, which is a positive integer between 1 and 5. The system call encrypts the given string by simply adding the given integer number (i.e., encryption key). For example, it encrypts “hello” to “ifmmp” by adding 1 to each character of the string. After encryption, it prints out the encrypted string using printk()
. The system call returns 0 when everything is okay. If the encryption key is out of bound, it returns EINVAL
.
1.4: Implementing the system call
[10 points] You should implement the system call in a separate file under linux/kernel directory. Then create a patch against kernel v6.12 using git diff
command and turn in the patch named syscall.patch
. Please make sure if your patch contains your added code.
1.5: Writing a test program
[10 points] Write a simple test program takes two options, -s string -k key
and calls sys_s2_encrypt()
with the string and key from the command line. You should implement command line argument processing using GETOPT(3) and the code should be able to build using make
and clean using make clean
. The program prints out the return value of sys_s2_encrypt()
. Turn in gzip-ed tarball of the source code and Makefile.
1.6: Test your system call
[10 points] Upload the screenshot of your kernel debug message using dmesg
while running your test program. Run your test program and dmesg
in one ssh session using tmux
.
Part 3: Measuring system call overhead
1.7: Test the latency of a “NULL” system call
[10 points] Please create a customized “NULL” system call that does nothing. Modify the following code to measure the latency of this “NULL” system call.
$ gcc gettimeofday.c -o syscall-gettimeofday -DUSE_SYSCALL_GETTIMEOFDAY
$ gcc gettimeofday.c -o syscall-null -DUSE_SYSCALL_NULL
$ gcc gettimeofday.c -o vdso-gettimeofday
Run the executables:
$ time ./syscall-gettimeofday && time ./vdso-gettimeofday && time ./syscall-null
Append the following to the end of gettimeofday.c
in /* comments */.
- The output of the above commands, showing both the
time
output and your calculated average latency - A brief report to compare and analyze the latency reported by
vdso-gettimeofday
,syscall-null
, andsyscall-gettimeofday
, explain- Does
vdso-gettimeofday
report a lower latency thansyscall-gettimeofday
? Why? - What about
syscall-gettimeofday
vs.syscall-null
? Why?
- Does
#define _GNU_SOURCE
#include <sys/syscall.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define N (100000000)
int main(int argc, char *argv[])
{
int i;
struct timeval curr;
/* TODO: Modify the code to measure per-call latency in nanoseconds */
for (i = 0; i < N; i++) {
#ifdef USE_SYSCALL_GETTIMEOFDAY
if (syscall(__NR_gettimeofday, &curr, NULL) == -1)
exit(EXIT_FAILURE);
#elif defined(USE_SYSCALL_NULL)
/* TODO: call your NULL syscall here */
#else
if (gettimeofday(&curr, NULL) == -1)
exit(EXIT_FAILURE);
#endif
}
return 0;
}
/* TODO: Append your results and report here */
Reference:
1.8: Paper reading
[20 points] Read and summarize the paper using your own words based on your understanding! Do NOT copy text from the paper, Do NOT use AI tools for this task. The summary should be concise and clear.
- Summary of the paper (What’s the research problem? Why is it important? What idea did the authors propose? And how good is it?)
- Strength of the proposed approach (a bullet list please)
- Weakness of the proposed approach (a bullet list please)
- Your comments to improve the research (how much do you agree with the authors? What would you do differently?)