Bilgisayara bir Sensör Bağlasaydık

Bir sıcaklık sensörü ürettiğimizi ve USB veya PCI ile bilgisayara bağladığımızı düşünelim. Bu sensörü open(), close(), read() ve ioctl() komutları ile bir C programı içinden kontrol etmek istiyoruz. Bunun için sensöre ait sürücü yazılımı yani kendi fonksiyonlarımızı yazmamız gerekir, sensor_ac(), sensor_kapa(), sensor_oku() gibi. Ayrıca karakter tablosundan boş bir satır bulmalıyız ki, cihazımıza o satır üzerinden erişebilelim. Boş satır bulmak, kullanılmayan bir major numarası bulmak ile aynı anlamdadır ancak bu keyfi bir iş değildir (modül geliştirme ve Linux çekirdeği ile gelen belgeler incelenmeli.).

Geliştirilen sürücü yazılımı, Linux çekirdeğe doğrudan entegre edilebildiği gibi; modül olarak da harici derlenebilir böylece çekirdeğin boyutu artmamış olur, ihtiyaç duyulduğunda kurulur.

Linux modülleri “.ko (kernel object)” uzantılıdır ve sistem açıldıktan sonra $ insmod modul_adi.ko ile kurulur, $ rmmod modul_adi.ko ile kaldırılır. lsmod komutu ile yüklü olan modüller listelenir.

Sürücü yazılım için major numarası bulurken sistemin aktif kullandığı major numaraları aşağıdaki şekilde listelenebilir:

$cat /proc/devices

Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
...
...
...
253 tpm
254 gpiochip

Block devices:
259 blkext
  8 sd
 11 sr
 65 sd
...
...
...
133 sd
134 sd
135 sd

Listede bulunan numaralar dışındaki major numaraları kullanılabilir.

mknod /tmp/sensor1 c 260 1
mknod /tmp/sensor2 c 260 2

ile sensör aygıtına ait iki nod oluşturduk.


Böylece şunu demek istedik, bilgisayara iki sensör aynı anda bağlanabilir. 260 ile major numarasını, 1 ve 2 numaralarıyla minor numaralarını belirledik.

sensor1 aygıtına ait open() fonksiyonunu çağıran bir C kodu çalıştıralım.

C kodu fd değerini “-1” olarak döndürdü. Çünkü biz herhangi bir modül geliştirip bu modülü yüklemedik. Tabloda 260. satır ve open() sütununa denk gelen hücre boş.


Şimdi de karakter aygıt tablosunda yeri olan bir aygıtı deneyelim,

Görüldüğü üzere tty aygıtı için “-1” den farklı bir sonuç döndü.

“fd” ile bize dönen sonuç ne ifade ediyor?

Linux sistemde, açık olan tüm dosyalar bir tabloda saklanırlar. Bu tabloya “file descriptor table” (kısaca “fd”) denir. open() fonksiyonu bu tablonun boş bir satırını döndürür. Bu tablonun 0, 1 ve 2. satırları özeldir ve klavye, ekran (stdout), ekran (stderr) için ayrılmıştır. Bizim “/dev/tty” aygıtımızı ifade eden dosya 3. satırda açılmıştır, yani tablonun 3.satırında “/dev/tty” aygıtına ait inode bilgisi bulunmakta.

Şimdi fd tablosunun 1.satırında bulunan aygıta (özel aygıt demiştik, stdout olarak isimlendirilir, ekrandır.) “Merhaba ben Linux öğreniyorum.” mesajı gönderelim:

stdout yani fd tablosunun 1.satırındaki aygıt, ekranı temsil eder.

Dynamic Device Drivers sistemi (bu yöntemi uygulayan programların temel mantığından bahsediyoruz, aslında sistem değil program, Dinamik Aygıt İsmi Üreten Programlar), /dev dizini altında kullanılmayan aygıtların yığılmasını önler. Örneğin USB bellek taktığımızda, /dev dizini altında belleğe ait bir dosya belirir; USB belleği bilgisayardan çıkardığımızda ise /dev dizini altındaki dosyası kendiliğinden kaybolur. Kısacası bu sistem “mknod” komutunu otomatik olarak işletir.


Kaynakça:

Nazım Koç, Gömülü Linux Sistemleri (İstanbul: Pusula Yayıncılık, 2011)

“Major and Minor Numabers” son güncelleme Şubat, 2005, http://www.makelinux.net/ldd3/chp-3-sect-2

“Linux Documentation” son güncelleme 24 Haziran, 2017, http://elixir.free-electrons.com/linux/latest/source/Documentation/admin-guide/devices.txt