Difference between revisions of "OS: Membuat Kernel Modul"
Onnowpurbo (talk | contribs) |
Onnowpurbo (talk | contribs) |
||
Line 85: | Line 85: | ||
Selamat! Kita baru saja menulis & menjalankan kernel module yang baru. | Selamat! Kita baru saja menulis & menjalankan kernel module yang baru. | ||
− | == | + | ==Interface module/kernel== |
− | + | Selanjutnya, mari kita bermain dengan module yang kita buat. Satu hal yang harus kita sadari bahwa module hanya dapat "melihat" function dan variable yang secara sengaja oleh kernel dibuat terlihat ke module. | |
− | Edit | + | Pertama-tama, mari kita coba cara yang SALAH! :) .. |
+ | |||
+ | Edit file kernel/printk.c dan tambhakan kalimat berikut sesudah semua include file dan dekat deklarasi variable global (tapi di luar semua function): | ||
int my_variable = 0; | int my_variable = 0; | ||
− | + | Sekarang compile ulang kernel dan reboot ke kernel yang baru. Selanjutnya, tambahkan kalimat ini di awal dari module kita berupa function mymodule_init, sebelum code lainnya: | |
extern int my_variable; | extern int my_variable; | ||
Line 99: | Line 101: | ||
my_variable++; | my_variable++; | ||
− | + | Simpan file yang kita ubah, dan di recompile module menggunakan perintah: | |
# make -C path/to/kernel/src SUBDIRS=$PWD modules | # make -C path/to/kernel/src SUBDIRS=$PWD modules | ||
− | + | Dan load module (ini harusnya akan gagal): | |
# insmod ./mymodule.ko | # insmod ./mymodule.ko | ||
− | + | Saat loading module yang kita buat harusnya fail dengan message berikut: | |
insmod: error inserting './mymodule.ko': -1 Unknown symbol in module | insmod: error inserting './mymodule.ko': -1 Unknown symbol in module |
Revision as of 13:06, 2 April 2013
Sumber:
- http://www.linuxchix.org/content/courses/kernel_hacking/lesson8
- http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html
Pada bagian ini, kita akan menulis dan load sebuah kernel modul sederhana. Dengan menuliskan sendiri modul kita menjadi belajar bagaimana menulis code kernel yang berdiri sendiri, belajar bagaimana menggunakan modul, dan menemukan beberapa aturan bagaimana kernel terkait menjadi satu kesatuan.
Catatan: instruksi disini ditulis untuk kernel 2.6.x yang mungkin tidak cocok untuk versi kernel yang berbeda.
Apakah kernel mendukung modul?
Kernel yang kita gunakan, harus di compile dengan option:
Loadable module support ---> [*] Enable loadable module support [*] Module unloading [ ] Module versioning support (EXPERIMENTAL) [*] Automatic kernel module loading
Pastikan pada saat kita mengcompile kernel opsi di atas di aktifkan. Jika tidak, kita perlu mengcompile ulang kernel.
Rangka Kernel Modul Sederhana
Pertama kali, kita perlu mencari lokasi directory tempat kernel di compile, biasanya di /usr/src/linux. Kemudian ubah directory ke drivers/misc dari directory source code Linux.
Sekarang, copy paste code berikut ke file dengan nama, misalnya, mymodule.c
#include <linux/module.h> #include <linux/config.h> #include <linux/init.h> static int __init mymodule_init(void) { printk ("My module worked!\n"); return 0; } static void __exit mymodule_exit(void) { printk ("Unloading my module.\n"); return; } module_init(mymodule_init); module_exit(mymodule_exit); MODULE_LICENSE("GPL");
Simpan file .c tersebut. Edit Makefile di directory tersebut. Tambahkan kalimat:
obj-m += mymodule.o
Compile module yang kita tulis:
# make -C [top directory dari source kernel] SUBDIRS=$PWD modules
Jalankan Module
Load module. Tergantung versi kernel yang kita gunakan, ketik:
# insmod ./mymodule.o
Atau:
# insmod ./mymodule.ko
Cek apakah message yang kita ketik keluar:
# dmesg | tail
Kita harusnya melihat di akhir printout sebagai berikut:
My module worked!
Selanjutnya, coba kita buang kernel module tersebut menggunakan perintah:
# rmmod mymodule
Cek output di dmesg, kita harusnya akan melihat:
Unloading my module.
Selamat! Kita baru saja menulis & menjalankan kernel module yang baru.
Interface module/kernel
Selanjutnya, mari kita bermain dengan module yang kita buat. Satu hal yang harus kita sadari bahwa module hanya dapat "melihat" function dan variable yang secara sengaja oleh kernel dibuat terlihat ke module.
Pertama-tama, mari kita coba cara yang SALAH! :) ..
Edit file kernel/printk.c dan tambhakan kalimat berikut sesudah semua include file dan dekat deklarasi variable global (tapi di luar semua function):
int my_variable = 0;
Sekarang compile ulang kernel dan reboot ke kernel yang baru. Selanjutnya, tambahkan kalimat ini di awal dari module kita berupa function mymodule_init, sebelum code lainnya:
extern int my_variable; printk ("my_variable is %d\n", my_variable); my_variable++;
Simpan file yang kita ubah, dan di recompile module menggunakan perintah:
# make -C path/to/kernel/src SUBDIRS=$PWD modules
Dan load module (ini harusnya akan gagal):
# insmod ./mymodule.ko
Saat loading module yang kita buat harusnya fail dengan message berikut:
insmod: error inserting './mymodule.ko': -1 Unknown symbol in module
What this is saying is that the kernel is not allowing modules to see that variable. When the module loads, it has to resolve all it's external references, like function names or variable names. If it can't find all of it's unresolved names in the list of symbols that the kernel exports, then the module can't write to that variable or call that function. The variable my_variable has space allocated for it somewhere in the kernel, but the module can't figure out where.
To fix this, we're going to add my_variable to the list of symbols that the kernel exports. Many kernel directories have a file specifically for exporting symbols defined in that directory. Bring up the file kernel/printk.c again and add this line after the declaration of your variable:
EXPORT_SYMBOL_NOVERS(my_variable);
Recompile and reboot into your new kernel. Now try to load your module again:
# insmod ./mymodule.ko
This time, when you check dmesg, you should see:
my_variable is 0 My module worked!
Reload your module:
# rmmod mymodule && insmod ./mymodule.ko
Now you should see:
Unloading my module. my_variable is 1 My module worked!
Each time you reload the module, my_variable should increase by one. You are reading and writing to a variable which is defined in the main kernel. Your module can access any variable or function in the main kernel, as long as it is explicitly exported via the EXPORT_SYMBOL() declaration. For example, the function printk() is defined in the kernel and exported in the file kernel/printk.c.
A simple loadable kernel module is a fun way to explore the kernel. For example, you can use a module to turn a printk on or off, by defining a variable do_print in the kernel which is initially set to 0. Then make all your printk's dependent on "do_print":
if (do_print) printk ("Big long obnoxious message\n");
And turn on do_print only when your module is loaded. You can add a function defined in your module to the list of functions that are called when the kernel receives a certain interrupt (use cat /proc/interrupts to find out what interrupts are in use). The function request_irq() adds your function to the list of handlers for a selected irq line, which you can use to print out a message each time you receive an interrupt on that line. You can investigate the current value of any exported variable by loading a module that reads that value and immediately exits (returns a non-zero value from the module_init() function). The variable jiffies, which increments every 1/100th of a second (on most platforms), is a good candidate for this kind of module.
Play with your new kernel module - modules are fun!
Referensi
- http://www.linuxchix.org/content/courses/kernel_hacking/lesson8
- http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html
Pranala Menarik
- Linux
- Ubuntu
- Sistem Operasi
- Linux: Instalasi Sistem Operasi
- Linux: Skema Partisi di Linux
- Kernel
- Compile Kernel
- Compile Kernel: Konfigurasi Kernel
- Kernel: Anatomi Kernel Source
- OS: Linux Kernel
- OS: Parameter Kernel Default
- OS: Kernel Scheduler
- OS: Complete Teori Tuning Kernel Scheduler
- OS: Complete Teori Tuning I/O Performance
- OS: Tuning Kernel Scheduler
- OS: Tuning Completely Fair Queueing CFQ I/O scheduler
- OS: Tuning Completely Fair scheduler CFS
- OS: Build in Monitoring Tool
- Linux Benchmarking
- OS: Benchmarking menggunakan UnixBench
- OS: Benchmarking menggunakan LLCBench
- OS: Mengerti System Call
- OS: Membuat Kernel Modul