Kernel: Anatomi Kernel Source

From OnnoWiki
Jump to navigation Jump to search

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

Pada bagian ini, kita akan mempelajari secara umum berbagai bagian dari kernel, seperti,

  • letak pada source tree (pohon source code).
  • urutan mereka di jalankan / di eksekusi.
  • bagaimana cara mencari source code tertentu.

Dimana source code berada?

Mulai dari directory pada top-level di Linux source tree, biasanya (walaupun belum tentu selalu) ada di bawah /usr/src/linux-<version>. Kita tidak akan terlalu detail disini, karena source Linux selalu berubah, paling tidak informasi yang akan diberikan cukup untuk mencari driver atau function tertentu berada.

Makefile

File ini adalah top-level Makefile untuk seluruh source tree. File ini mendefinisikan banyak sekali variable dan rule, seperti flag kompilasi gcc dll.

Documentation/

Directory ini berisi banyak sekali informasi bermanfaat (walaupun kadang-kadang kadaluarsa) tentang cara konfigurasi kernel, menjalankan dengan ramdisk, dan banyak lagi. Informasi help yang berhubungan dengan berbagai pilihan konfigurasi tidak dapat ditemukan disini - walaupun mereka dapat di temukan pada file Kconfig di masing-masing directory source.

arch/

Semua code spesifik arsitektur berada di directory ini dan di directory include/asm-<arch>. Setiap arsitektur mempunyai directory di bawah directory ini. Contoh, code untuk komputer PowerPC dapat di temukan di arch/ppc. Kita dapat menemukan low-level memory management, penanganan interupsi, inisialisasi awal, dan banyak lagi di directory ini.

crypto/

Ini adalah API cryptographic untuk digunakan oleh kernel itu sendiri.

drivers/

Aturan umum, code untuk menjalankan device peripheral dapat di temukan di subdirectory dari directory ini. Ini termasuk, driver video, driver network card, driver SCSI low-level, dan berbagai hal sekitar itu. Contoh, kebanyakan driver network card dapat ditemukan di drivers/net. Beberapa higher level code digunakan untuk menempelkan semua tipe driver, yang mungkin tidak berada di directory yang sama seperti low level driver itu sendiri, menjadi satu kesatuan.

fs/

Baik code file sistem generik (dikenal sebagai VFS, atau Virtual File System) dan code untuk berbagai file sistem yang berbeda dapat di temukan pada directory ini. Root file sistem yang kita gunakan mungkin ext2; code untuk membaca format ext2 dapat di temukan dalam fs/ext2. Tidak semua file sistem dapat di compile dan di run, file system yang baru dan aneh adalah contoh yang baik bagi mereka yang ingin mencari proyek baru untuk kernel.

include/

Sebagian besar file header yang di include di awal file source code .c dapat di temukan di directory ini. Arsitektur spesifik dari include file biasanya di asm-<arch>. Bagian dari proses kernel build adalah membuat link simbolik dari asm ke asm-<arch>, sehingga #include <asm/file.h> dapat memperoleh file yang benar untuk arsitektur tersebut tanpa harus melakukan hard code ke dalam file .c. Directory lain berisi header yang non-arsitektur spesifik. Jika sebuah struktur, konstanta, atau variable digunakan di lebih dari satu file .c, maka kemungkinan besar itu akan ada dalam salah satu file header ini.

init/

Directory ini berisi file main.c, version.c, dan code untuk membuat "early userspace". version.c mendefinisikan string Linux version. main.c dapat dilihat sebagai "lem" kernel. kita akan membicarakan lebih dalam tentang main.c di bagian selanjutnya. Userspace awal akan memberikan fungsionalitas yang dibutuhkan saat Linux kernel nyala, tapi tidak perlu berada / berjalan dalam kernel itu sendiri.

ipc/

"IPC" singkatan dari "Inter-Process Communication". Ini berisi code untuk shared memory, semaphores, dan berbagai bentuk IPC.

kernel/

Code level kernel generic yang tidak masuk ke mana-mana ada dalam directory ini. Level atas dari code sistem call ada disini, bersama dengan code printk(), scheduler, code untuk handling sinyal, dan banyak lagi. Nama file cukup informatif, kita dapat mengetik ls kernel/ dan dapat mengira-ngira dengan akurat fungsi dari masing-masing file.

lib/

Subroutine yang secara generic bermanfaat untuk semua code kernel diletakan disini. Operasi string, routing debugging, dan code untuk parsing command line semua ada disini.

mm/

High level memory management code berada dalam directory ini. Virtual memory (VM) di implementasikan melalui subroutine disini, dibantu oleh subroutine arsitektur spesifik low level yang biasanya ada di arch/<arch>/mm/. Saat awal boot memory management (dibutuhkan sebelum subsistem memory di setup secara penuh) dilakukan disini, termasuk memory mapping dari file, manajemen dari page cache, alokasi memory, dan swap out dari page di RAM (dan masih banyak lagi).

net/

Networking code high level berada disini. Network driver low-level akan menerima dan mengirim paket melalui level ini, yang kemudian meneruskannya ke level aplikasi, atau membuang data, atau menggunakannya di kernel, tergantung jenis paketnya. Directory net/core berisi code yang berguna untuk berbagai protokol jaringan, juga beberapa file di directory /net. Protokol jaringan yang spesifik di implementasikan di subdirectory net/. Contoh, code IP (versi 4) ada di directory net/ipv4.

scripts/

Directory ini berisi script yang berguna untuk membangun kernel, tapi tidak termasuk code yang masuk dalam kernel itu sendiri. Contoh, berbagai tool untuk konfigurasi tersimpan file-nya disini.

security/

Code untuk berbagai model security di Linux dapat di temukan disini, seperto NSA Security-Enhanced Linux maupun kait untuk socket dan network security.

sound/

Driver untuk sound card dari berbagai code berhubungan dengan sound / audio berada disini.

usr/

Directory ini berisi code untuk build arsip dengan format cpio berisi image root file sistem, yang akan digunakan untuk user space awal.

Bagaimana semua ini menjadi satu?

Pusat dari seluruh kernel Linux adalah file init/main.c. Setiap arsitektur akan menjalankan function untuk setup low level dan kemudian akan mengeksekusi function start_kernel, yang dapat ditemukan di init/main.c.

Urutan eksekusi code akan tampak seperti berikut ini:

 Architecture-specific setup code (di arch/<arch>/*)
   |
   v
 function start_kernel() (di init/main.c)
   |
   v
 function init() (di init/main.c)
   |
   v
 user level "init" program

Untuk lebih detailnya, berikut adalah yang terjadi:

   Architecture-specific set up code yang akan melakukan:
       Unzip dan move ke kernel code itu sendiri, jika dibutuhkan
       Inisialisasi hardware
           Ini dapat termasuk setup low-level memory management
       Transfer control ke function start_kernel()
   start_kernel() akan melakukan, antara lain:
       Print out versi kernel dan command line
       Start output ke console
       Aktifkan interupsi
       Kalibrasi delay loop
       Call rest_init(), yang akan melakukan:
           Start kernel thread untuk menjalankan function init()
           Masuk ke idle loop
   init() akan melakukan:
       Start processor lainnya (di mesin SMP)
       Start subsystem device
       Mount root filesystem
       Bebaskan kernel memory yang tidak digunakan
       Jalankan /sbin/init (atau /etc/init, atau ...)

Pada titik ini, userlevel init program sudah berjalan, yang akan menjalankan berbagai hal seperti start layanan jaringan dan jalankan getty (login program) pada console.

Kita dapat mengenali kapan sebuah subsistem di inisialisasi dari start_kernel() atau init() dengan menulis printk oleh kita dan melihat kapan printk dari subsistem tersebut muncul relatif terhadap printk kita. Contoh, kita ingin mengetahui kapan sound system ALSA di inisialisasi, tulis printk di awal start_kernel() dan init() dan cari kapan "Advanced Linux Sound Architecture [...]" di cetak relatif terhadap printk. Untuk mengerti lebih lanjut ada baiknya membaca cara menggunakan function printk() dalam hacking kernel.

Mencari berbagai hal di kernel source tree

Misalnya kita ingin mengerjakan sebuah driver, misalnya, USB driver. Mulai dari manakah kita untuk mencari USB code tersebut?

Pertama-tama, kita dapat mencoba menggunakan perintah find pada directory kernel pada top-level, sebagai berikut:

$ find . -name \*usb\*

Perintah ini akan mem-print setiap filename yang ada kata "usb" di tengahnya.

Cara lain, kita dapat mencoba untuk mencari string yang unik. String unik ini dapat berupa output dari printk(), nama file di /proc, atau string unik lainnya yang dapat di temukan di source code dari dari driver tersebut. Contoh, USB akan mengeluarkan message seperti:

usb-ohci.c: USB OHCI at membase 0xcd030000, IRQ 27

Oleh karenanya kita dapat mencoba untuk melakukan recursive grep untuk menemukan bagian dari to find printk yang menulis, misalnya:

$ grep -r "USB OHCI at" .

Cara lain, kita dapat mencari USB source code dengan melihat /proc. Jika kita ketik

find /proc -name usb

mungkin kita akan menemukan sebuah directory dengan nama /proc/bus/usb. Kita mungkin akan menemukan string unik untuk di grep sesudah membaca entry dari directory tersebut.

If all else fails, try descending into individual directories and listing the files, or looking at the output of ls -lR. You may see a filename that looks related. But this should really be a last resort, and something to be tried only after you have run many different find and grep commands.

Once you've found the source code you are interested in, you can start reading it. Reading and understanding Linux kernel code is another lesson in itself. Just remember that the more you read kernel code, the easier it gets. Have fun exploring the kernel!

Referensi

Pranala Menarik