Skip to content

Tawheed-tariq/linux-kernel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Adding a system call to Linux kernel

Installation

  1. First of all before installing the new linux kernel we check the version of current running linux kernel.
$ uname -a
Linux tawheed 6.6.9-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.6.9-1kali1 (2024-01-08) x86_64 GNU/Linux

my current version is 6.6.9-amd64.

Now we update the system and install some useful packages

sudo apt update && sudo apt upgrade -y
sudo apt-get install build-essential libncurses5-de libssl-dev libelf-dev bison flex dwarves zstd screen -y
  1. Download the source code of latest linux kernel from here, if you already have then no need to download once more. OR you can clone git repository of linux kernel
git clone https://github.com/torvalds/linux.git

if you installed from the kernel.org then you need to extract the package first, to extract the package use:

tar xf <package_name>

change directory to linux kernel

cd <package_name>

in my case it was: cd linux

1. Creation

Now after you have installed necessary packages and linux kernel, we will start adding a basic system call to linux kernel. you are now currently in linux directory which you just downloaded, you can check its content by listing ls the files inside it:

image

  1. Change your directory to kernel
cd kernel

inside kernel directory you can see lot of system calls like fork , exec . Here we will add our system call.

  1. Inside kernel directory, create a folder with name same as your system call name, in my case I choose system call name to be cs12 you can choose your own name.
mkdir cs12
cd cs12
  1. Inside the cs12 directory we will create a file name cs12.c
code cs12.c

I am using vs-code as a text editor you can use nano, vim or any other, based on your choice.

now write the following code to the above created file:

#include <linux/kernel.h>
#include <linux/syscalls.h>

SYSCALL_DEFINE0(cs12)
{
    printk("I am exceptme creating my own system call named cs12\n");
    return 0;
}

You can also change the code as you like.

SYSCALL_DEFINE0 is used for those system calls which have 0 arguments, similarly for n arguments we will use SYSCALL_DEFINEn where n is integer number.

also create a Makefile inside this directory

code Makefile

write the following code inside Makefile:

obj-y := cs12.o
  1. Now we will make changes in Makefile of kernel directory, for that go to kernel directory
cd ..
code Makefile

inside Makefile of kernel directory , and find obj-y, you will find something like this: image

write this line of code anywhere you want:

obj-y += cs12/

in my case it is written after time/ directory (last line).

  1. Now go to the linux directory using :
cd ../

and open this filepath in your text editor include/linux/syscalls.h :

code include/linux/syscalls.h

Navigate to the bottom of it and write the following code just above #endif.

asmlinkage long sys_cs12(void);

Some architectures (e.g. x86) have their own architecture-specific syscall tables, but several other architectures share a generic syscall table. Add your new system call to the generic list by adding an entry to the list in include/uapi/asm-generic/unistd.h:

code include/uapi/asm-generic/unistd.h
#define __NR_cs12 462
__SYSCALL(__NR_cs12, sys_cs12)

Also update the __NR_syscalls count to reflect the additional system call, and note that if multiple new system calls are added in the same merge window, your new syscall number may get adjusted to resolve conflicts.

image

The file kernel/sys_ni.c provides a fallback stub implementation of each system call, returning -ENOSYS. Add your new system call here too:

code kernel/sys_ni.c
COND_SYSCALL(cs12);

image

To wire up your new system call for x86 platforms, you need to update the master syscall tables. Assuming your new system call isn't special in some way (see below), this involves a "common" entry (for x86_64 and x32) in arch/x86/entry/syscalls/syscall_64.tbl:

code arch/x86/entry/syscalls/syscall_64.tbl
462   common   cs12     sys_cs12

image

and an "i386" entry in arch/x86/entry/syscalls/syscall_32.tbl:

code arch/x86/entry/syscalls/syscall_32.tbl
462   i386   cs12     sys_cs12

image

Again, these numbers are liable to be changed if there are conflicts in the relevant merge window.

2. Building Up

  1. Copy the config file of your current kernel version to linux directory
cp -v /boot/config-$(uname -r) .config
  1. Configure the kernel. Make sure the window of your terminal is maximized. Open the configuration window with the following command.
sudo make menuconfig

save and exit.

  1. Edit the .config file
code .config
  • Set CONFIG_SYSTEM_TRUSTED_KEYS to ""
  • Set CONFIG_SYSTEM_REVOCATION_KEYS to ""
  1. Compile the linux kernel
sudo make -j$(nproc)

this will take time , in my case it took about 1 hour and 20 mins to compile.

  1. Install the linux kernel modules
sudo make modules_install -j$(nproc)
sudo make install -j$(nproc)
  1. Update grub config
sudo update-initramfs -c -k 6.9.0-rc1
sudo update-grub

i used here 6.9.0-rc1 because I downloaded this linux kernel version , you will write your own linux kernel version there

  1. Reboot the device

    you can reboot manually or used this command to reboot:

sudo reboot

Result

Now after rebooting the system you can use this command to check your kernel version:

$ uname -a  
Linux tawheed 6.9.0-rc1 #1 SMP PREEMPT_DYNAMIC Mon Mar 25 12:17:01 IST 2024 x86_64 GNU/Linux

in my case kernel version is changed to 6.9.0-rc1.

Now we will check that the system call we added is working or not

create a c file and store it where ever you want to store it, I name the file as report.c. Write the following code inside it:

#include <linux/kernel.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define __NR_cs12 462

long cs12_syscall(void){
	return syscall(__NR_cs12);
}

int main(){
	long activity;
	activity = cs12_syscall();
	if(activity != 0){
		perror("system call cs12 appears to have failed.");
	}
	else{
		system("dmesg");
	}
	return 0;
}

run the file using gcc.

gcc -o report report.c
./report

check the last line of output. At the bottom, you should now see the following.

image

user programs for other system calls

1.get_free_memory

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

#define SYS_GET_FREE_MEMORY 464
int main() {
    long free_memory;
    free_memory = syscall(SYS_GET_FREE_MEMORY);

    if (free_memory == -1) {
        perror("syscall");
        return errno;
    }
    // Print the amount of free memory
    printf("Free memory: %ld kB\n", free_memory);

    return 0;
}

2.get_process_count

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

#define SYS_GET_PROCESS_COUNT 465
int main() {
    long process_count;
    process_count = syscall(SYS_GET_PROCESS_COUNT);
    if (process_count == -1) {
        perror("syscall");
        return errno;
    }
    // Print the process count
    printf("Number of processes: %ld\n", process_count);
    return 0;
}

3.get_uptime

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

#define SYS_GET_UPTIME 463
int main() {
    long uptime_seconds;
    uptime_seconds = syscall(SYS_GET_UPTIME);
    if (uptime_seconds == -1) {
        perror("syscall");
        return errno;
    }
    printf("System uptime: %ld seconds\n", uptime_seconds);
    return 0;
}

About

Added some new system calls to linux kernel

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published