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.
- Download kernel linux 2.6.39.4 di sini.
- 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
- Masuk ke dalam direktori hasil peng-ekstrak-an kernel tadi
$ cd ~/kernel/linux-2.6.39.4
- Buat direktori baru, misalnya
extsyscall
. Direktori ini akan menjadi tempat untuk menambahkan kode system call kita nanti.
$ mkdir extsyscall
- Buka file yang berisi daftar system call.
$ gedit arch/x86/kernel/syscall_table_32.S
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 */
- 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
- 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.
- 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
- 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/
...
- 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;
}
- Buat file
Makefile
pada direktori extsyscall
$ gedit extsyscall/Makefile
Isikan dengan
obj-y := extsyscall.o
- 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;
}