Difference between revisions of "OS: Mengerti System Call"

From OnnoWiki
Jump to navigation Jump to search
 
(12 intermediate revisions by the same user not shown)
Line 7: Line 7:
 
==Apakah system call?==
 
==Apakah system call?==
  
In the most literal sense, a system call (also called a "syscall") is an instruction, similar to the "add" instruction or the "jump" instruction. At a higher level, a system call is the way a user level program asks the operating system to do something for it. If you're writing a program, and you need to read from a file, you use a system call to ask the operating system to read the file for you.
+
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.
  
==System calls in detail==
+
==Lebih detail tentang System call==
  
Here's how a system call works. First, the user program sets up the arguments for the system call. One of the arguments is the system call number (more on that later). Note that all this is done automatically by library functions unless you are writing in assembly. After the arguments are all set up, the program executes the "system call" instruction. This instruction causes an exception: an event that causes the processor to jump to a new address and start executing the code there.
+
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.
  
The instructions at the new address save your user program's state, figure out what system call you want, call the function in the kernel that implements that system call, restores your user program state, and returns control back to the user program. A system call is one way that the functions defined in a device driver end up being called.
+
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.
  
That was the whirlwind tour of how a system call works. Next, we'll go into minute detail for those who are curious about exactly how the kernel does all this. Don't worry if you don't quite understand all of the details - just remember that this is one way that a function in the kernel can end up being called, and that no magic is involved. You can trace the control flow all the way through the kernel - with difficulty sometimes, but you can do it.
+
Bagi yang ingin mendalami lebih lanjut, di persilahkan untuk membaca selanjutnya.
  
==A system call example==
+
==Contoh System Call==
  
This is a good place to start showing code to go along with the theory. We'll follow the progress of a read() system call, starting from the moment the system call instruction is executed. The PowerPC architecture will be used as an example for the architecture specific part of the code. On the PowerPC, when you execute a system call, the processor jumps to the address 0xc00. The code at that location is defined in the file:
+
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
 
  
It looks something like this:
+
arch/ppc/kernel/head.S
 +
 
 +
Ini akan tampak seperti:
  
 
  /* System call */
 
  /* System call */
Line 34: Line 35:
 
         EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
 
         EXCEPTION(0xe00, Trap_0e, UnknownException, EXC_XFER_EE)
  
What this code does is save some state and call another function called DoSyscall. Here's a more detailed explanation (feel free to skip this part):
+
Yang akan dilakukan oleh code ini adalah menyimpan state program, dan call function DoSyscall. Berikut adalah penjelasan lebih detail:
  
EXCEPTION_PROLOG is a macro that handles the switch from user to kernel space, which requires things like saving the register state of the user process. EXC_XFER_EE_LITE is called with the address of this routine, and the address of the function DoSyscall. Eventually, some state will be saved and DoSyscall will be called. The next two lines save two exception vectors on the addresses 0xd00 and 0xe00.
+
* 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 looks like this:
+
* 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)      \
 
  #define EXC_XFER_EE_LITE(n, hdlr)      \
Line 44: Line 47:
 
                           ret_from_except)
 
                           ret_from_except)
 
   
 
   
EXC_XFER_TEMPLATE is another macro, and the code looks like this:
+
EXC_XFER_TEMPLATE adalah macro, dan code akan tampak sebagai berikut:
 
   
 
   
 
  #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)    \
 
  #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret)    \
Line 56: Line 59:
 
         .long  ret
 
         .long  ret
  
li stands for "load immediate", which means that a constant value known at compile time is stored in a register. First, trap is loaded into the register r10. On the next line, that value is stored on the address given by TRAP(r11). TRAP(r11) and the next two lines do some hardware specific bit manipulation. After that we call the tfer function (i.e. the transfer_to_handler function), which does yet more housekeeping, and then transfers control to hdlr (i.e. DoSyscall). Note that transfer_to_handler loads the address of the handler from the link register, which is why you see .long DoSyscall instead of bl DoSyscall.
+
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:
  
Now, let's look at DoSyscall. It's in the file:
+
'''arch/ppc/kernel/entry.S'''
  
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:
  
Eventually, this function loads up the address of the syscall table and indexes into it using the system call number. The syscall table is what the OS uses to translate from a system call number to a particular system call. The system call table is named sys_call_table and defined in:
+
'''arch/ppc/kernel/misc.S'''
  
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().
  
The syscall table contains the addresses of the functions that implement each system call. For example, the read() system call function is named sys_read. The read() system call number is 3, so the address of sys_read() is in the 4th entry of the system call table (since we start numbering the system calls with 0). We read the data from the address sys_call_table + (3 * word_size) and we get the address of 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:
  
After DoSyscall has looked up the correct system call address, it transfers control to that system call. Let's look at where sys_read() is defined, in the file:
+
'''fs/read_write.c'''
fs/read_write.c
 
  
This function finds the file struct associated with the fd number you passed to the read() function. That structure contains a pointer to the function that should be used to read data from that particular kind of file. After doing some checks, it calls that file-specific read function in order to actually read the data from the file, and then returns. This file-specific function is defined somewhere else - the socket code, filesystem code, or device driver code, for example. This is one of the points at which a specific kernel subsystem finally interfaces with the rest of the kernel. After our read function finishes, we return from the sys_read(), back to DoSyscall(), which switches control to ret_from_except, which is in defined in:
+
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
+
'''arch/ppc/kernel/entry.S'''
  
This checks for tasks that might need to be done before switching back to user mode. If nothing else needs to be done, we fall through to the restore function, which restores the user process's state and returns control back to the user program. There! Your read() call is done! If you're lucky, you even got your data back.
+
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.
  
You can explore syscalls further by putting printks at strategic places. Be sure to limit the amount of output from these printks. For example, if you add a printk to sys_read() syscall, you should do something like this:
+
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;
 
  static int mycount = 0;
Line 86: Line 90:
 
   }
 
   }
  
Have fun!
+
Selamat menikmati!
 
 
  
 
==Referensi==
 
==Referensi==
Line 97: Line 100:
 
* [[Linux]]
 
* [[Linux]]
 
* [[Ubuntu]]
 
* [[Ubuntu]]
 +
* [[Buku Sistem Operasi]]
 +
 +
===Secara Umum===
 +
 
* [[Sistem Operasi]]
 
* [[Sistem Operasi]]
 +
 +
===Instalasi Linux===
 +
 +
* [[Linux: CLI untuk Survival]]
 +
* [[Linux: Skema Partisi di Linux]]
 +
* [[Linux: Instalasi Sistem Operasi]]
 +
 +
===Compile Kernel===
 +
 
* [[Kernel]]
 
* [[Kernel]]
 +
* [[OS: Linux Kernel]]
 +
* [[Kernel: Anatomi Kernel Source]]
 
* [[Compile Kernel]]
 
* [[Compile Kernel]]
 
* [[Compile Kernel: Konfigurasi Kernel]]
 
* [[Compile Kernel: Konfigurasi Kernel]]
* [[Kernel: Anatomi Kernel Source]]
+
 
* [[OS: Linux Kernel]]
+
===Remaster Linux===
 +
 
 +
* [[Cara Cepat Melakukan Remastering Ubuntu]]
 +
 
 +
===Sistem Operasi untuk Embedded===
 +
 
 +
* [[OpenWRT]]
 +
* [[OpenWRT: Download Firmware yang sudah jadi]]
 +
* [[OpenWRT: Source Repository Download]]
 +
* [[OpenWRT: Melihat Daftar Package]]
 +
 
 +
====Membuat Firmware Sendiri====
 +
 
 +
* [[OpenWRT: Build Firmware]]
 +
* [[OpenWRT: Build Firmware Buffalo WZRHPG450H]]
 +
* [[OpenWRT: Build Firmware Buffalo WZRHPG300N]]
 +
* [[OpenWRT: Build Firmware Ubiquiti NanoStation2]]
 +
* [[OpenWRT: Build Firmware Mikrotik RB433]]
 +
* [[OpenWRT: Build Firmware Linksys WRT160NL]]
 +
* [[OpenWRT: Build Firmware Linksys WRT54GL]]
 +
 
 +
====Flash ke Device====
 +
 
 +
* [[OpenWRT: Flash Linksys WRT54GL]]
 +
* [[OpenWRT: Flash Buffalo WZRHP450H]]
 +
* [[OpenWRT: Flash Buffalo WZRHP300N]]
 +
* [[OpenWRT: Flash UBNT NanoStation2]]
 +
 
 +
====Beberapa Tip====
 +
 
 +
* [[OpenWRT: Mikrotik RB433]]
 +
* [[OpenWRT: 3G modem]]
 +
* [[OpenWRT: Build Firmware dengan 3G Modem Support]]
 +
* [[OpenWRT: Setup Firewall]]
 +
* [[OpenWRT: Konfigurasi UBNT NanoStation2 tanpa WebGUI]]
 +
 
 +
===Tuning Kernel===
 +
 
 
* [[OS: Parameter Kernel Default]]
 
* [[OS: Parameter Kernel Default]]
 +
 +
====Tuning Kernel Scheduler====
 +
 
* [[OS: Kernel Scheduler]]
 
* [[OS: Kernel Scheduler]]
 +
* [[OS: Tuning Kernel Scheduler]]
 +
* [[OS: Tuning Completely Fair scheduler CFS]]
 
* [[OS: Complete Teori Tuning Kernel Scheduler]]
 
* [[OS: Complete Teori Tuning Kernel Scheduler]]
 +
 +
====Tuning I/O Scheduler====
 +
 +
* [[OS: Tuning Completely Fair Queueing CFQ I/O scheduler]]
 
* [[OS: Complete Teori Tuning I/O Performance]]
 
* [[OS: Complete Teori Tuning I/O Performance]]
* [[OS: Tuning Kernel Scheduler]]
+
 
* [[OS: Tuning Completely Fair Queueing CFQ I/O scheduler]]
+
====Tuning Manajemen Memory====
* [[OS: Tuning Completely Fair scheduler CFS]]
+
 
 +
* [[OS: Tuning Manajemen Memory]]
 +
 
 +
===Android===
 +
 
 +
* [[OS: Android - Download]]
 +
 
 +
===Membuat Kernel Module===
 +
 
 +
* [[OS: Mengerti System Call]]
 +
* [[OS: Membuat Kernel Modul]]
 +
 
 +
===Monitoring & Benchmark===
 +
 
 
* [[OS: Build in Monitoring Tool]]
 
* [[OS: Build in Monitoring Tool]]
 
* [[Linux Benchmarking]]
 
* [[Linux Benchmarking]]
 
* [[OS: Benchmarking menggunakan UnixBench]]
 
* [[OS: Benchmarking menggunakan UnixBench]]
 
* [[OS: Benchmarking menggunakan LLCBench]]
 
* [[OS: Benchmarking menggunakan LLCBench]]
* [[OS: Mengerti System Call]]
 
* [[OS: Membuat Kernel Modul]]
 

Latest revision as of 13:44, 7 April 2013

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