Pagini
Workshops
Parteneri
Download and unzip the tasks archive sesiune-03 on the virtual machine.
# My syscall #* Use the code in the my_syscall
directory. # code in kernel
directory is a kernel module and code in user
is an user space application. # my_syscall.c
implements a module that adds a custom syscall on position 0 in the syscall table. # Note: In the later kernel version, the syscall table cannot be accessed from modules (is not exported) but our kernel was modified in order to export it. # bell.c
implements the userspace part (caller) of our syscall. It uses the syscall
libc function to make a system call identified by number. #* compile the kernel module and insert it into the running kernel # use dmesg to confirm load. #* compile the userspace utility ('make bell
') and run it. # use dmesg again to see that your kernel code has been run by the bell process. # Bonus: remove the kernel module, run the bell utility and see dmesg for you first Oups message :) Any idea why that happened? # Task information #* While in kernel space, the syscall handler function has access to several kernel structures. Like information about processes. # each process in the system has an instance of task_struct. # 'current
' is a macro that points to the task_struct of the process that currently runs the kernel code. # Use 'current→pid
' in a printk inside the syscall handler to see the process ID of the process using the syscall.
#include <linux/slab.h> #include <linux/list.h> struct pid_list { pid_t pid; struct list_head list; }; LIST_HEAD(my_list); static int add_pid(pid_t pid) { struct pid_list *ple = kmalloc(sizeof *ple, GFP_KERNEL); if (!ple) return -ENOMEM; ple->pid = pid; list_add(&ple->list, &my_list); return 0; } static int del_pid(pid_t pid) { struct list_head *i, *tmp; struct pid_list *ple; list_for_each_safe(i, tmp, &my_list) { ple = list_entry(i, struct pid_list, list); if (ple->pid == pid) { list_del(i); kfree(ple); return 0; } } return -EINVAL; } static void destroy_list(void) { struct list_head *i, *n; struct pid_list *ple; list_for_each_safe(i, n, &my_list) { ple = list_entry(i, struct pid_list, list); list_del(i); kfree(ple); } }