Adım Adım Linux Driver Yazıyoruz
Giriş
Bu yazımda Linux driver eklemeyi ele alacağım.
Kullanacağımız başlık dosyalarından(header file) yazacağımız koda, teorik
bilgilerden uygulamalı anlatıma hatta konsol komutları ve çıktılarına kadar değinip
anlaşılması ve öğrenilmesi kolay bir içerik oluşturmaya çalışacağım. Bu sayede
daha öncesinde örümcek ağı gibi gelen konular ve sorular gittikçe açılacak.
Hatta yazının sonunda bunlar o kadar da zor değilmiş diyeceksiniz ki bu da zor
olduğu halde bilinen(becerilen) iş kolay iştir cümlesini size hatırlatacak.
Her ne kadar basit bir anlatım oluşturmayı amaçlasam
da bu dokümanda bulunanları tam olarak anlamak için işin bir kısmı da sizin üzerinizde.
Size yüklediğim görev yazılan her kodu satır satır bakarak yazmak, ismi geçen
başlık dosyasını bulup bahsi geçen fonksiyonlara göz atmak, koşulan konsol
komutlarını koşmak ve buradaki çıktılar ile karşılaştırmak olacak. Her zaman söylendiği
gibi “Yazılım” nasıl öğrenileceğini kendi içinde saklar. “YAZ ılım”. Bu yüzden
yazın yazın yazın tekrar tekrar yazın.
Kernel Nedir?
Eğer bir sözlüğe bakarsanız
kernel kelimesinin anlamının çekirdek, öz olduğunu görürsünüz. Fakat Kernel bizim bildiğimiz gibi bir işletim
sisteminin tüm çekirdeğidir. Kernel sistem yöneticisidir. Tüm sistem kaynaklarını
yönetir. Sistem kaynakları nelerdir diyecek olursanız eğer: CPU, memory,
input/output, network...
Kernel' dan neden bu kadar az bahsettim derseniz ilk olarak uzun uzun yazıp konu dışına çıkmamak için bu özet bilgi ile yetindim diyebilirim. İkinci olarak ilerde anlatılacak konuların, özellikle yazılacak kodların bu katmana ait olduğunu belirtmek isterim. Burada aklınızda bir soru oluşmasını bekliyorum. “Başka katmanlar da mı var?” sorusu ya da en azından şu kelimenin aklınıza gelmesini umut ediyorum. User space(kullanıcı katmanı). Fark ettiyseniz iki katmanımız oluştu, kernel ve user space. User space çok yakın olduğumuz alan hatta sürekli kullandığımız alan. Hani şu printf ile “Hello World” uygulamasını koşup çıktısını konsolda gördüğümüz katman.
Kernel' dan bu kadar az bahsetmemin sebebinin anlaşıldığını
umarak ana konunun derinliklerine doğru giriş yapıyorum.
Kernel C (Pure C)
Kernel modül yazmadan önce Kernel katmanında
kullanacağımız Kernel C tanımamız gerekir. Bu sayede yazılan kodları daha kolay
ve hızlı kavrayabiliriz. Kernel C dedim, bu sizi yanıltmasın. Hemen telaş edip
"Kernel modüle yazmak için yeni bir dil mi öğreneceğim?" sorusunu
aklınıza getirmeyin. Kernel C normal kullandığımız C dilidir. Sadece Kernel
seviyesinde GNU uzantıları ile kullanılır. Biraz daha açıklayıp sizi rahatlatmak
için şöyle söyleyeyim: Kernel C, kullanıcı katmanında kullandığımız
kütüphaneleri içermez. Yani C dilini elimizde glibc kütüphaneleri olmadan
kullanacağız. (glibc için busiteye ve bu siteye gözatabilirsiniz. glibc bahsetmişken şu sayfaya da
göz atın derim.) Peki elimizde o çok sevdiğimiz başlık dosyaları olmadan(stdio.h,
stdlib.h, string.h) nasıl kod yazacağız derseniz eğer imdadımıza Kernel
seviyesine ait başlık dosyaları yetişir. <kernel_source>/kernel/lib. Ufak
bir örnek #include
<linux/module.h> İşte Kernel C ile kullandığımız C arasındaki fark
bu, başlık dosyaları.
Kernel seviyesinde çalışırken bile en sevdiğimiz dil C kullanmamız işin en güzel yanlarından. Fakat burada nesne dayalı programlama mantığı kullanılmıştır. Biraz C++ bilenler için şu iki kelime constructor ve destructor tanıdık gelecektir. C++ bilmeyenler bu durumu dert etmesine gerek yok. Çünkü bu işleri yine basit bir fonksiyonla yapacağız. Bu kadar yazıdan sonra basit bir modül kodu örneğine bakalım.
Gördüğünüz gibi modül constructor ve destructor fonksiyonlarını
içerir. mymodule_init modülün constructor fonksiyonu, mymodule_exit modülün destructor
fonksiyonudur. C++ bilenler constructor fonksiyonunun obje yaratılırken
çağrıldığını bilirler. Fakat burada constructor (kurucu fonksiyon) fonksiyonu -mymodule_init-
modül dinamik olarak Kernel yüklenirken çağrılır. Peki destructor fonksiyonu -mymodule_exit-
ne zaman ne zaman çağrılır. Tabi ki de
modül Kernel' dan çıkartılırken yani modül sistemden geri alınırken.
Kernel' ın Mesaj Kayıtcısı printk()
Basit Bir Kernel Modul Kodunda kullanılan constructor ve destructor fonksiyonlarının dışında biraz bu basit modülde ismi geçen printk()
fonksiyonundan bahsedelim. printk(), çok
yakından bildiğimiz printf() in Kernel seviyesinde çalışan eşdeğeridir. Tabi
kullanımı ve görevi printf()' den biraz farklıdır.
printk, printf gibi çıktılarını standart output basmaz. Peki printk nereye yazar? Kullanıcı katmanında(user space) çalışan syslog daemon bu mesajları toplar ve son işlem olarak çeşitli cihazlara yönlendirir. Yani kısaca bazı mesajları konsol komutuna yolladığı gibi bazılarını da sadece dosya da saklar. Tüm printk çıktılarını
default olarak /var/log/messages dosyasına basılır. Ayrıca ayarlanarak bazı printk mesajları seri port üzerinden
konsola(/dev/ttyS0) basılabilir. Örneğin KERN_ERR mesajları konsolda gözlenebilir.
NOT 1:
/var/log/messages
dosyası normal kullanıcılar için okunabilir biri dosya değildir.
Fakat $dmesg komutu ile bu verilere ulaşabilirsiniz
NOT 2:
kernel seviyesinde çağrılan tüm printk mesajlarını konsol ekranına basmak için
şu komutu koşmanız yeterli: $dmesg
NOT 3:dmesg
kullanıma yönelik pratik bilgi: $dmesg koştuktan
sonra ekranda bir sürü kernel seviyesinden gelen mesaj göreceksiniz. Bunların içinde kaybolmamak için bir anahtar kelime ile arama yapabilirsiniz. $dmesg | grep my_key_word
sonra ekranda bir sürü kernel seviyesinden gelen mesaj göreceksiniz. Bunların içinde kaybolmamak için bir anahtar kelime ile arama yapabilirsiniz. $dmesg | grep my_key_word
printf("first text" " second text\n"); [çıktısı: first text second text]
kodu her ne kadar geçerli ise prink çağrımı da o kadar geçerli ve aynı. Bu açıklamadan sonra printk gizemi gittikçe azalıyor olması lazım. Artık printk ya da bizim printf gibi bir yakınlık duymamız lazım.
Printk sadece KERN_INFO makrosu kullanılmaz. #include<linux/kernel.h> başlık dosyasında printk mesaj durumunu
anlatan sekiz adet makro bulunmaktadır.
Yazının devamı olan Adım Adım Linux Driver Yazıyoruz -2- de bu uyku getirici teorik bilgilerden biraz daha uzaklaşıp daha fazla kod göreceğiz. Hatta ilk modülümüzü derleyeceğiz ve cihaza yükleyip çalıştıracağız. Böyle zevkli işler olacak pek yakında. Yazının devamında görüşmek üzere.
Faydalanacağını düşündüğünüz kişilere iletin, eksik ya da yanlış olduğunu düşündüğünüz yerleri belirtin.
Şimdi Yazmaya Devam ....
Yazının devamı olan Adım Adım Linux Driver Yazıyoruz -2- de bu uyku getirici teorik bilgilerden biraz daha uzaklaşıp daha fazla kod göreceğiz. Hatta ilk modülümüzü derleyeceğiz ve cihaza yükleyip çalıştıracağız. Böyle zevkli işler olacak pek yakında. Yazının devamında görüşmek üzere.
Faydalanacağını düşündüğünüz kişilere iletin, eksik ya da yanlış olduğunu düşündüğünüz yerleri belirtin.
Şimdi Yazmaya Devam ....
Hiç yorum yok:
Yorum Gönder
Son Ütücü