[Linux] Menambahkan System Call pada Kernel Linux 2.6


Pehatian! Cara ini sudah pernah diuji dan berhasil. Kesalahan mungkin dapat terjadi, read at your own risk.

Berikut ini adalah langkah untuk menambahkan system call pada kernel linux 2.6 untuk arsitektur x86 baik 32-bit maupun 64-bit. Pada tulisan ini digunakan kernel versi 2.6.39.4 pada Ubuntu 10.04. Mungkin terjadi sedikit perbedaan pada versi 2.6.x lainnya.

  1. Download kernel linux 2.6.39.4 di sini.
  2. Ekstrak file linux-2.6.39.4.tar.gz hasil download tadi ke direktori baru. Misalnya kita akan meletakan di dalam folder ~/kernel/
    $ tar zxvf linux-2.6.39.4.tar.gz -C ~/kernel/

    Maka akan terdapat direktori ~/kernel/linux-2.6.39.4

  3. Masuk ke dalam direktori hasil peng-ekstrak-an kernel tadi
    $ cd ~/kernel/linux-2.6.39.4
  4. Buat direktori baru, misalnya extsyscall. Direktori ini akan menjadi tempat untuk menambahkan kode system call kita nanti.
    $ mkdir extsyscall
  5. Buka file yang berisi daftar system call.
    $ gedit arch/x86/kernel/syscall_table_32.S
  6. Misalkan Anda ingin menambahkan fungsi baru dengan nama randodd(int *). Tambahkan baris .long sys_randodd pada akhir file. (Ganti randoodd sesuai dengan nama fungsi yang akan dibuat).
    	...
    	.long sys_prlimit64		/* 340 */
    	.long sys_name_to_handle_at
    	.long sys_open_by_handle_at
    	.long sys_clock_adjtime
    	.long sys_syncfs
    	.long sys_randodd		/* System Call Baru */
    
  7. Buka file unistd (header API sistem operasi berbasis POSIX). Akan didaftarkan system call yang akan dibuat.
    $ gedit arch/x86/include/asm/unistd_32.h

    Tambahkan baris #define __NR_randodd 345 pada akhir dari sekumpulan baris dengan format #define __NR_namasyscall xxx.
    Ganti randodd dengan nama system call yang akan dibuat.
    Ganti 345 dengan nilai terakhir dari daftar system call yang ada ditambahkan dengan 1. Pada kasus ini, system call terakhir adalah #define __NR_syncfs 344, maka system call randodd akan mendapatkan nomor system call 344 + 1 = 345.
    Selain itu juga, ganti nilai pada #define NR_syscalls 345 menjadi #define NR_syscalls 346, dengan 346 merupakan jumlah system call yang ada, yaitu nomor system call terakhir ditambahkan dengan 1, dalam kasus ini 345 (milik randodd) + 1 = 346.

    	#define __NR_fanotify_mark	339
    	#define __NR_prlimit64		340
    	#define __NR_name_to_handle_at	341
    	#define __NR_open_by_handle_at  342
    	#define __NR_clock_adjtime	343
    	#define __NR_syncfs             344
    	#define __NR_randodd       	345
    	
    	#ifdef __KERNEL__
    	
    	#define NR_syscalls 346
    	
    	#define __ARCH_WANT_IPC_PARSE_VERSION
    	#define __ARCH_WANT_OLD_READDIR
    
  8. Sekarang akan didaftarkan system call untuk sistem dengan 64-bit. Buka file unistd_64.h.
    $ gedit arch/x86/include/asm/unistd_64.h

    Tambahkan dua baris seperti pada potongan kode yang di-highlight.

    	...
    	#define __NR_prlimit64				302
    	__SYSCALL(__NR_prlimit64, sys_prlimit64)
    	#define __NR_name_to_handle_at			303
    	__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
    	#define __NR_open_by_handle_at			304
    	__SYSCALL(__NR_open_by_handle_at, sys_open_by_handle_at)
    	#define __NR_clock_adjtime			305
    	__SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
    	#define __NR_syncfs                             306
    	__SYSCALL(__NR_syncfs, sys_syncfs)
    	#define __NR_randodd				307
    	__SYSCALL(__NR_randodd, sys_randodd)
    	...
    

    Perhatikan bahwa __NR_randodd mendapatkan nomor system call 307 yang merupakan lanjutan dari nomor system call terakhir yang ada.

  9. Buka file syscall.h.
    $ gedit include/linux/syscalls.h

    Tambahkan baris asmlinkage long sys_randodd(int *); sebelum #endif pada akhir file.

    ...
    asmlinkage long sys_old_mmap(struct mmap_arg_struct __user *arg);
    asmlinkage long sys_name_to_handle_at(int dfd, const char __user *name,
    										struct file_handle __user *handle,
    										int __user *mnt_id, int flag);
    asmlinkage long sys_open_by_handle_at(int mountdirfd,
    										struct file_handle __user *handle,
    										int flags);
    asmlinkage long sys_randodd(int *num);
    #endif
    
  10. Buka file Makefile pada direktori utama source.
    $ gedit Makefile

    Tambahkan extsyscall/ (direktori yang dibuat tadi) pada core-y += .

    	...
    	ifeq ($(KBUILD_EXTMOD),)
    	core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/ extsyscall/
    	...
    
  11. Buat kode yang berisi syscall pada direktori extsyscall. Misalkan file kode yang dibuat bernama extsyscall.c juga.
    $ gedit extsyscall/extsyscall.c

    Kode berikut akan menghasilkan bilangan random yang selalu ganjil.

    #include <linux/linkage.h>
    #include <linux/random.h>
    
    asmlinkage long sys_randodd(int *num)
    {
    	*num = (get_random_int() << 1) + 1;
    	return 0;
    }
    
  12. Buat file Makefile pada direktori extsyscall
    $ gedit extsyscall/Makefile

    Isikan dengan

    obj-y := extsyscall.o
    
  13. Lakukan compile kernel. Cara mengompile kernel dapat dilihat di sini.

Untuk melakukan pengujian terhadap kernel yang dibuat, misalnya kita dapat membuat aplikasi yang memanfaatkan system call tersebut. Misalnya:

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

/* Untuk 32-Bit (sesuaikan dengan nilai yang dimasukkan sebelumnya) */
#define sys_randodd 345

/* Untuk 64-bit (sesuaikan dengan nilai yang dimasukkan sebelumnya) 
#define sys_randodd 307
*/

int main()
{
    int num;
    int i;

    for (i=0; i<100; i++)
    {
        syscall(sys_randodd, &num);
        printf("%d\n", num);
    }
    return 0;
}
Advertisements

2 thoughts on “[Linux] Menambahkan System Call pada Kernel Linux 2.6

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s