OS: Mengerti System Call

From OnnoWiki
Jump to navigation Jump to search

Sumber: http://www.linuxchix.org/content/courses/kernel_hacking/lesson7

Saat kita membaca-baca code device driver akan mulai berfikir, "Bagaimana function foo_read() di panggil?" Atau kita berfikir, "Ketika kita menulis cat /proc/cpuinfo, bagaimana function cpuinfo() dipanggil?"

Setelah kernel selesai booting, flow control berubah dari yang bersifat langsung "Function mana yang akan di panggil selanjutnya?" menjadi tergantung pada system call, exception dan interupsi. Mari kita bahas bagaimana cara sistem call dilakukan?

Apakah system call?

Secara gamblang, system call (biasa di kenal sebagai "syscall") adalah sebuah instruksi, mirip dengan instruksi "add" atau "jump". Pada tingkat tinggi, sebuah system call adalah cara sebuah program pada level user untuk meminta pada sistem operasi untuk menjalankan sesuatu untuknya. Jika kita seorang programmer, dan kita membutuhkkan untuk membaca dari sebuah file, kita akan menggunakan system call untuk meminta sistem operasi untuk membaca file tersebut untuk kita.

Lebih detail tentang System call

Cara system call bekerja adalah sebagai berikut. Pertama-tama, user program akan mensetup argument untuk system call. Salah satu argumen adalah nomor system call. Perlu di catat bahwa semua ini dilakukan secara automatis oleh fungsi library kecuali jika kita menulis menggunakan bahasa assembler. Sesudah semua argumen di setup, program akan menjalankan instruksi "system call". Instruksi ini akan menyebabkan exception: event yang akan menyebabkan processor untuk jump ke satu address dan mulai menjalankan program / code di address tersebut.

Instruksi di alamat yang baru akan menyimpan state user program, menentukan sistem call apa yang kita inginkan, kemudian call fuction tersebut di kernel yang mengimplementasikan system call, setelah selesai maka mengembalikan program state, dan kembali ke user program. Sebuah system call adalah salah satu cara agar function yang di definisikan dalam device driver untuk bisa di panggil.

Bagi yang ingin mendalami lebih lanjut, di persilahkan untuk membaca selanjutnya.

Contoh System Call

Berikut kita akan mulai memperlihatkan code beserta sedikit teorinya. Kita akan mengikuti gerakan dari system call read(), mulai dari instruksi system call di jalankan. Arsitektur PowerPC akan digunakan sebagai contoh dari code yang spesifik arsitektur. Di PowerPC, saat kita menjalankan system call, processor akan jump ke address 0xc00. Code pada lokasi ini di definisikan pada file:

arch/ppc/kernel/head.S

Ini akan tampak seperti:

/* System call */
        . = 0xc00
SystemCall:
        EXCEPTION_PROLOG
        EXC_XFER_EE_LITE(0xc00, DoSyscall)

/* Single step - not used on 601 */
        EXCEPTION(0xd00, SingleStep, SingleStepException, EXC_XFER_STD)
        EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)

Yang akan dilakukan oleh code ini adalah menyimpan state program, dan call function DoSyscall. Berikut adalah penjelasan lebih detail:

  • EXCEPTION_PROLOG adalah sebuah macro yang akan menangani switch dari user ke kernel space, yang akan melakukan hal seperti menyimpan kondisi register dari proses user.
  • EXC_XFER_EE_LITE akan dipanggil menggunakan address dari route tersebut, dan address dari function DoSyscall. Pada suatu saat, register akan di simpan dan DoSyscall akan di panggil. Dua kalimat selanjutnya adalah exception vector pada address 0xd00 dan 0xe00.

EXC_XFER_EE_LITE akan tampak sebagai berikut:

#define EXC_XFER_EE_LITE(n, hdlr)       \
        EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
                          ret_from_except)

EXC_XFER_TEMPLATE adalah macro, dan code akan tampak sebagai berikut:

#define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)     \
        li      r10,trap;                                       \
        stw     r10,TRAP(r11);                                  \
        li      r10,MSR_KERNEL;                                 \
        copyee(r10, r9);                                        \
        bl      tfer;                                           \
i##n:                                                           \
        .long   hdlr;                                           \
        .long   ret

li singkatan dari "load immediate", yang berarti nilai kontanta yang diketahui saat waktu compile di simpan di register. Pertama kali, trap di load ke register r10. Di kalimat selanjutnya, nilai tersebut di simpan ke address yang diberikan oleh TRAP(r11). TRAP(r11) dan dua kalimat selanjutnya melakukan manipulasi bit spesifik, yang pada dasarnya melakukan housekeeping, dan kemudian men-transfer kontrol ke register, oleh karenanya kita akan melihat .long DoSyscall bukan bl DoSyscall.

Selanjutnya, mari kita lihat DoSyscall. Ini ada di file:

arch/ppc/kernel/entry.S

Pada saatnya, function ini akan me-load address dari tabel syscall dan index ke address tersebut menggunakan nomor system call . Tabel syscall adalah apa yang digunakan oleh sistem operasi (OS) untuk menterjemahkan nomor system call ke system call tertentu. Tabel system call bernama sys_call_table didefinisikan di:

arch/ppc/kernel/misc.S

Tabel syscall berisi address dari function yang mengimplementasikan setiap system call. Contoh, function system call read() bernama sys_read. Nomor system call read() adalah 3, oleh karenanya address dari sys_read() adalah entry ke 4 di tabel system call (karena nomor pertama system call adalah 0). Kita membaca data dari address sys_call_table + (3 * word_size) dan kita akan memperoleh address dari sys_read().

Setelah DoSyscall diperoleh address system call yang benar, dia akan mentransfer kontrol ke system call tersebut. Mari kita lihat dimana sys_read() di definisikan, dalam file:

fs/read_write.c

Function ini akan mengambil fice struct yang berhubungan dengan nomor fd yang kita kirim ke function read(). Struct ini berisi pointer ke function yang harusnya digunakan untuk membaca data dari file tertentu. Setelah melakukan beberapa check, dia akan call function read untuk file tertentu untuk membaca data dari file, dan kemudian return. Function file spesifik ini di definisikan di tempat lain, contohnya,socket code, file system code, atau device driver code. Di titik ini, sebuah subsystem kernel yang spesifik akan berinteraksi dengan kernel secara keseluruhan. Setelah function read kita selesai, kita akan kembali dari sys_read(), kembali ke DoSyscall(), akan akan men-switch control ret_from_except, yang di definisikan di:

arch/ppc/kernel/entry.S

Di tempat sini akan di cek task yang perlu diselesaikan sebelum switch kembali ke user mode. Jika tidak ada lagi yang perlu dilakukan, kita akan kembali ke function restore, yang akan me-restore state user proses dan mengembalikan control ke user program. Selesai sudah call ke read(). Jika kita beruntung, kita akan memperoleh data kita kembali.

Kita dapat mengeksplorasi syscall lebih dalam lagi dengan menempatkan printk pada berbagai tempat yang strategis. Pastikan untuk memberi batasan jumlah output dari printk, Contoh, kita dapat menambahkan printk ke syscall sys_read(), kita dapat menambahkan sebagai berikut:

static int mycount = 0;

if (mycount < 10) {
         printk ("sys_read called\n");
         mycount++;
  }

Selamat menikmati!

Referensi

Pranala Menarik

Secara Umum

Instalasi Linux

Compile Kernel

Remaster Linux

Sistem Operasi untuk Embedded

Membuat Firmware Sendiri

Flash ke Device

Beberapa Tip

Tuning Kernel

Tuning Kernel Scheduler

Tuning I/O Scheduler

Tuning Manajemen Memory

Android

Membuat Kernel Module

Monitoring & Benchmark