«

»

Jan
04

Kernel Modül Programlama – Giriş

kernel ilk modülü programlama

ilk kernel modülü programlama

Kernel modülü programlamak sürekli korktuğum ancak merak ettiğim bir konuydu. Eğer mobile programlama yaparak yaşamımı devam ettireceksem bunu da öğrenmem gerekiyordu Java ME’ nin yanında. Kernel işletim sisteminin çekirdeğidir ve Ubuntu dağıtımının (distro) kerneli Linux’tur. Kernel bütün programların trafiğini sağlar ve donanımla yazılım arasında bağ kurar. Basit bir kernel modülünü ekleyip çıkarmayı anlatıyorum bu yazımda.

Kernel Modülü Nedir?

Kernel (isteyen çekirdek diyebilir ancak uzayın kernelından aklımda hep kernel olarak kalacaktır :) ) modülleri kernele ekleyip çıkarabildiğimiz kod parçalarıdır. Kernelin fonksiyonelliğini sistemi reboot etmeden, yani yeniden başlatmamıza gerek kalmadan modüller sayesinde geliştirebiliriz. Örnek olarak bir donanımın driverını gösterebiliriz, bu driverle kernelimiz sistem ve donanımımızın arasındaki bağlantıyı gerçekleştirebilecektir. Modülleri kullanmıyor olsaydık her fonksiyonelliği geliştirişimizde kernele eklenti yapmamız gerekecekti. Bu ise büyük kernele sahip sistemlerde her yeni geliştirmede kernelin yeniden derlenmesi ve sistemin reboot edilmesi gerçekten de kötü bir durumdur.

Kernelimizde kurulu olan modülleri lsmod komutuyla görebiliriz.

cagdas@cagdas:~$ lsmod
Module                  Size  Used by
msdos                  15744  0
fat                    58272  1 msdos
isofs                  39844  1
udf                    87716  0

gibi bir sürü kernel modülümüz görünecektir.

Eğer buradaki örnekler çalışmazsa büyük bir ihtimalle kernelinizin CONFIG_MODVERSIONS u aktif hale getirilmiştir. Eğer versiyon hataları alıyorsanız kernelinizdeki modversioning özelliğini off hale getirerek derlemeniz gerekmektedir.

Gelelim ilk kernel modülümüze. Elebette ki “Hello World!” uygulaması olucak. Başka türlü olsaydı şaşardım :)

/*
*  hello-1.c – The simplest kernel module.
*/
#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */

int init_module(void)
{
printk(KERN_INFO “Hello world 1.\n”);

/*
* A non 0 return means init_module failed; module can’t be loaded.
*/
return 0;
}

void cleanup_module(void)
{
printk(KERN_INFO “Goodbye world 1.\n”);
}

Kernel modülleri en az iki fonksiyondan oluşmaktadır. Bunlar başla ve bitir fonksiyonlarıdır. Genellikle init_module() başla ve cleanup_module() bitir (temizle) isimlendirmeleriyle kullanılırlar ancak kafamıza göre de isimler verebilirdik.

init_module() yapacağımız işi veya asıl fonksiyonu kernelin içine koyarak çağırmamızı veya kerneli denetlemizi sağlar. cleanup_module() kısmı ise init_module() ün yaptıklarını geri alarak modülümüzün güvenli bir şekilde kaldırılmasını sağlar.

linux/module.h kütüphanesi bütün kernel modüllerde kullanılır.

linux/kernel.h kütüphanesini ise printk() uyarısını kullanabilmek için çağırdık. Bu uyarı syslogd ve klogd programları çalışıyorsa /var/log/messages dosyasına çıktımızı loglamaya yarar.

Ardından Makefile’ımızı kodu koyduğumuz dizinin içine koyalım. Dosyanın adı Makefile olacak.

obj-m += hello-1.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

make komutu ile modülümüzü derleyelim.

cagdas@cagdas:~/Belgeler$ make
make -C /lib/modules/2.6.28-16-generic/build M=/home/cagdas/Belgeler modules
make[1]:`/usr/src/linux-headers-2.6.28-16-generic’ dizinine giriliyor
CC [M]  /home/cagdas/Belgeler/hello-1.o
Building modules, stage 2.
MODPOST 1 modules
CC      /home/cagdas/Belgeler/hello-1.mod.o
LD [M]  /home/cagdas/Belgeler/hello-1.ko
make[1]: `/usr/src/linux-headers-2.6.28-16-generic’ dizininden çıkılıyor

Evet ilk kernel modülümüzü derledik. Ardından modinfo komudu ile kernel modülümüz hakkında bazı bilgilere erişebiliriz.

cagdas@cagdas:~/Belgeler$ modinfo hello-1.ko
filename:       hello-1.ko
srcversion:     140276773A3090F6F33891F
depends:
vermagic:       2.6.28-16-generic SMP mod_unload modversions 586

Ve en sonunda kernelimizin içine modülümüzü koyalım. Bunun için root kullanıcı olmamız gerekiyor. sudo -s -H komutuyla bildiğiniz gibi root oluyoruz. insmod ./hello-1.ko ile kernelimize modülümüzü ekledik ve /var/log/messages logunun son satırlarına bakalım :)

Jan  4 03:22:17 cagdas kernel: [37145.098506] hello_1: module license ‘unspecified’ taints kernel.
Jan  4 03:22:17 cagdas kernel: [37145.098594] Hello world 1.

Evet mutlu son :)

Eğer modülümüzü kernelimizden silmek istiyorsak rmmod hello-1 komutunu kullanacağız.

Not: Bu yazı dizisi The Linux Kernel Module Programming Guide belgesinin soft hali olucaktır. Kernelin 2.4 ve 2.6 sürümünlerine uygundur. Kernelinizin versiyonunu uname -a komutuyla öğrenebilirsiniz.

C kodu:

hello-1.c

1 comment

  1. adsız says:

    Kernel Modül Programlama – 2 ‘ de istiyorum :)

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre user="" computer="" escaped="">