# OS Homework1 ##### 310551126 蔡鎔駿 https://hackmd.io/@roger90810/OS-HW1 ## Prepare Environment ```shell sudo apt install libncurses5 libncurses5-dev libncurses-dev qtbase5-dev-tools flex \ bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf ``` ## 1. Modify Version number suffix ```shell cd linux make defconfig make -j4 LOCALVERSION=-os-310551126 sudo make modules_install install sudo update-grub2 ``` ![](https://i.imgur.com/b7CiFsx.png) ## 2. Add System Call ### sys_hello in linux-5.19.12, create a folder `hello` ```shell cd linux-5.19.12 mkdir hello ``` create a file `hello.c`, implement our system call SYSCALL_DEFINEn means there are n arguments in this system call. ```c #include <linux/kernel.h> #include <linux/syscalls.h> SYSCALL_DEFINE0(hello) { printk("Hello world\n"); printk("310551126\n"); return 0; } ``` create a Makefile for our system call ```make obj-y := hello.o ``` Modify system call entry table `arch/x86/entry/syscalls/syscall_64.tbl` ``` ... 547 x32 pwritev2 compat_sys_pwritev64v2 # This is the end of the legacy x32 range. Numbers 548 and above are # not special and are not to be used for x32-specific syscalls. 548 common hello sys_hello # add this line ``` add our system call to kernel header file `include/linux/syscalls.h` ```h ... int __sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); asmlinkage long sys_hello(void); // add this line #endif ``` Modify kernel's Makefile, add our system call module in it. ```make ... ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ hello/ core-$(CONFIG_BLOCK) += block/ core-$(CONFIG_IO_URING) += io_uring/ ... ``` Result: ![](https://i.imgur.com/xHIjR0d.png) ### sys_revstr in linux-5.19.12, create a folder `revstr` ```shell cd linux-5.19.12 mkdir revstr ``` create a file `revstr.c`, implement our system call * Here we need two arguments, *length* and *string*, so we use `SYSCALL_DEFINE2` here. * The modifiers `__user` means this is from user address space. * We can not access the data from userspace address directly, we need to use `copy_from_user` to copy the data from userspace to kernel space. * Before we copy the data, we need to allocate a space for the data copy, using `kmalloc` to allocate a space in kernel space. * After reverse the string, we need to save it to userspace, using `copy_to_user` to copy back to the userspcae. * Here I encounter a problem, the return value of `copy_to_user` is the number of bytes that could not be copied. On success, this will be zero. My return value is the length I want to copy, but the copy is success (I check the string at user program, it is reversed). ```c #include <linux/kernel.h> #include <linux/syscalls.h> SYSCALL_DEFINE2(revstr, int, len, char __user *, str) { int i = 0; int j = len - 1; char *kstr; unsigned long ret; kstr = (char *)kmalloc(len + 1, GFP_KERNEL); if (!kstr) return -ENOMEM; if (copy_from_user(kstr, str, len)) return -EFAULT; kstr[len] = '\0'; printk("The origin string: %s\n", kstr); while (i < j) { char tmp = kstr[i]; kstr[i] = kstr[j]; kstr[j] = tmp; i++; j--; } printk("The reversed string: %s\n", kstr); ret = copy_to_user(str, kstr, len); /* if (copy_to_user(str, kstr, len)) */ /* return -EFAULT; */ kfree(kstr); return 0; } ``` create a Makefile for our system call ```make obj-y := revstr.o ``` Modify system call entry table `arch/x86/entry/syscalls/syscall_64.tbl` ``` ... 547 x32 pwritev2 compat_sys_pwritev64v2 # This is the end of the legacy x32 range. Numbers 548 and above are # not special and are not to be used for x32-specific syscalls. 548 common hello sys_hello 549 common revstr sys_revstr # add this line ``` add our system call to kernel header file `include/linux/syscalls.h` ```h ... int __sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); asmlinkage long sys_hello(void); asmlinkage long sys_revstr(int len, char __user *str); // add this line #endif ``` Modify kernel's Makefile, add our system call module in it. ```make ... ifeq ($(KBUILD_EXTMOD),) core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ hello/ revstr/ core-$(CONFIG_BLOCK) += block/ core-$(CONFIG_IO_URING) += io_uring/ ... ``` Result: ![](https://i.imgur.com/tDLX7yG.png)