This series is neither totally theoritical nor totally hands-on. It is amalgammation of both. Just the way I think. You will not become expert which should be implied.
What is Syscall ?
System call is the programmatic way in which a computer program requests a service from the kernel of the operating system it is executed on. This may include hardware-related services (for example, accessing a hard disk drive), creation and execution of new processes, and communication with integral kernel services such as process scheduling. Ref
Some Syscall
Straight from the Source.
So is adding a new one tough ?
No not so much, but the pain of compiling will definitely kill you(took me 3 hrs to compile a single syscall change in kernel).
Writing a new syscall
First download kernel source code.
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.18.1.tar.xz
sudo -s
tar -xvf linux-4.18.1.tar.xz -C /usr/src/
cd /usr/src/linux-4.18.1
mkdir helloworld
cd helloworld
nano helloworld.c
In helloworld.c
Now make a makefile
nano makefile.c
# add this
obj-y := helloworld.o
After saving this makefile
cd ..
Now open makefile and go to line no 947 and add
helloworld/
Now open file syscall.h by
nano include/linux/syscalls.h
Now go to line 908 and add these lines
asmlinkage long sys_helloworld(void);
open syscall_64.tbl
nano /arch/x86/entry/syscalls/syscall_64.tbl
Now go to line 346 and you will feel like adding
335 64 helloworld __x64_sys_helloworld
I added this line compiled and got error.
335 64 helloworld sys_helloworld
By adding this line it compiled successfully. I might be wrong you can try that line as well if it works then I would really like to know but it didn’t work last time. And I might be wrong.
cp /boot/config-$(uname -r) .config
make menuconfig
# exit immediately after a semi colorful menu opens.
make
make modules_install install
Yup! you did it yourself. Restart your computer and Now you have added a syscall. Now if you want to check if syscall works or not then make some file name try.c
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(){
long int s = syscall(335);
printf("Syscall returned %ld \n",s);
return 0;
}
Now compile this programm with gcc try.c and then run it by ./a.out. if it prints syscall returned 0, then your syscall worked else not.
dmesg
# kernel log, you will see hellowold printed in last