These are the steps I followed.
1) I was running on 4.15.0 kernel so I updated to more recent kernel.
wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.17.4.tar.xz
2)Extracted the kernel source code using
sudo tar -xvf linux-4.17.4.tar.xz -C/usr/src/
3) In cd /usr/src/linux-4.17.4/
created a new directory called it
sub
Then created
sub.c
inside
sub
directory.
In
sub.c
I wrote the code to subtract y from x if (y>x) or else return 0; Here x is Integer and y is double.
#include <linux/kernel.h>
asmlinkage int sys_sub(int x,double y)
{
printk("working...");
if(y>x){
return ((int)y-x);}
else
return 0;
}
4) created a Makefile in the same sub directory and added obj-y := sub.o
5) In
/usr/src/linux-4.17.4
opened Makefile and modified the core-y line to
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ sub/
6) Then in
cd arch/x86/entry/syscalls/
I opened
gedit syscall_64.tbl
and as 548th system call I entered
548 64 hello sys_sub
7) In
cd include/linux/
I opened
gedit syscalls.h
and added
asmlinkage int sys_sub(int x,double y);
as the last line just before endif
8) I made sure ext4 is chosen in
sudo make menuconfig
9) I compiled the kernel using
sudo make modules_install install
10) performed
shutdown -r now
11) Checked
uname -r
to make sure that I'm running
4.17.4
indeed which I was.
12) I created a C program to check the system call
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
int res = syscall(548,10,44);
printf("System call sys_sub returned %d ", res);
return 0;
}
But it is only returning
System call sys_sub returned 0
and
dmesg
shows Hello World for some reason. Please help me. What am I doing wrong?
Edit:
I made necessary changes in my code as per the comments I read. Now my system call code looks like this:
#include <linux/kernel.h>
asmlinkage long sys_sub(int a,int b)
{
printk("System call is working...\n");
printk("Inputs are %d and %d",a,b);
if(b>a)
{
int c= b-a;
printk("Answer is %d",c);
return c;
}
printk("Answer is 0");
return 0;
}
I added some print statements to make sure that the system calls are correctly invoked. I recompiled the kernel and ran again and now I'm getting
dmesg
output as
System call is working... Inputs are 1114685272 and 1114685272 Answer is 0
Seems like the kernel is getting random junk values instead of the parameters that I'm passing which makes it to always fail the if loop. The random values for both parameters seems to always be the same! I dont know where I'm going wrong now.