Linux

Basit Bir Karakter Aygıtı Uygulaması

Merhaba arkadaşlar. Bu yazıda sizlere Linux’ta basit bir karakter aygıtının nasıl yazılacağını anlatmaya çalışacağım.

Karakter aygıtları(character device) karakter akımlarını kabul eder yada dağıtırlar.Adreslenemezler ve bu aygıtlarda arama işlemi gerçekleştirilemez.Yazıcılar, ağ aygıtları, mouse bu aygıtlara örnek verilebilir.
İşletim sisteminin dosya sistemi bu aygıtların hepsi ile soyut aygıtlar olarak ilgilenir. Aygıtların arka planında aygıta özel olan olaylar ile ilgilenmezler.(Kaynak)

Şimdi bizim yazacağımız karakter aygıtı girilen bir stringi ters çevirip aygıt dosyasına yazacak. C kodumuz ve açıklaması şu şekilde:

aygitimiz.c Kodu

#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

static char mesaj[100]={0};
static short okumaPozisyonu=0;
static int kacDefa=0;

static int aygit_ac(struct inode *,struct file *);
static int aygit_kapat(struct inode *,struct file *);
static ssize_t aygit_oku(struct file *,char *,size_t,loff_t *);
static ssize_t aygit_yaz(struct file *,const char *,size_t,loff_t *);

static struct file_operations fops=
{
.read =aygit_oku,
.open =aygit_ac,
.write=aygit_yaz,
.release=aygit_kapat,
};

int init_module(void)
{
int t=register_chrdev(89,"aygitimiz",&fops);
if(t<0)
printk(KERN_ALERT "Aygıt yüklenemedin");
else
printk(KERN_ALERT "Aygıt Yüklendin");
return t;
}

void cleanup_module(void)
{
unregister_chrdev(89,"aygitimiz");
}

static int aygit_ac(struct inode *inod,struct file *fil)
{
 kacDefa++;
 printk(KERN_ALERT"Aygıt %d kez açıldın",kacDefa);
return 0;
}

static ssize_t aygit_oku(struct file *filp,char *buff,size_t len,loff_t *off)
{
short sayac=0;
while(len!=0 && (mesaj[okumaPozisyonu]!=0))
{
put_user(mesaj[okumaPozisyonu],buff++);
sayac++;
len--;
okumaPozisyonu++;
}
return sayac;
}

static ssize_t aygit_yaz(struct file *filp,const char *buff,size_t len,loff_t *off)
{
short indis=len-1;
short sayac=0;
memset(mesaj,0,100);
okumaPozisyonu=0;
while(len>0)
{
mesaj[sayac++]=buff[indis--];
len--;
}
return count;
}

static int aygit_yaz(struct inode *inod,struct file *fil)
{
printk(KERN_ALERT"Aygıt kapatıldı.n");
return 0;
}

Kodumuz içinde yazılan aygıtı kernel’a yüklemek için init_module ve cleanup_module fonksiyonları bulunmakta. Bu iki fonksiyon konsoldan verilecek komutlar vasıtası ile çalışacak.

struct file_operations fops ifadesi ile tanımladığımız yapının içine aygitimizin kullancağı fonksiyonları tanıttık. Örneğin aygıtın okunması işlemi sırasında aygit_oku fonksiyonu çalışacak.

aygit_ac ve aygit_kapa fonksiyonları aygıt ile işlem yapıldığında çalışacaklar. Bizim asıl işimizi üstlenecek fonksiyonlarımız ise aygit_yaz ve aygit_oku fonksiyonları.

Konsoldan aygıt dosyasına yazılmak üzere bir string verildiğinde bu string aygit_yaz fonksiyonun buff parametresine düşüyor. String’in uzunluğuda len parametresi içinde tutuluyor. Biz de bu parametredeki değeri 100 boyutlu olarak tanımladığımız mesaj dizisine tersten atıyoruz.

aygit_oku fonksiyonu da çekirdek ile kullanıcı katmanı arası iletişimi sağlayan metotlardan biri olan put_user metodu ile aygıt dosyası içindeki veriyi konsola basıyor.

Makefile Kodu

Her ne kadar yazdığımız kod bir C kodu da olsa çekirdek seviyesinde işlem yaptığımız için bu kodu derlemek bir dosya ve bir komut aracılığı ile olur. Konsoldan make komutunu verdiğimizde bu dosya aracılığı ile C kodumuz derlenecek.

ifneq ($(KERNELRELEASE),)
   obj-m := aygitimiz.o
else

#KERNELDIR ?= /lib/modules/$(shell uname -r)/build
 KERNELDIR ?= /home/nitin/Desktop/src/linux-3.16.5/

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

Aygıt Dosyasını Oluşturma

İşlemlerimizi yürüteceğimiz C kodumuz için fonksiyonlarla çalışacak aygıt dosyasını oluşturmamız gerekiyor. Bunun için konsoldan şu komutları veriyoruz:

mknod /dev/aygitimiz c 89 1
chmod a+r+w /dev/aygitimiz

Bu komutları vermeden işlem yapmaya çalışırsak dosya yine oluşur ancak C kodumuz içindeki kuralları yerine getirmez.

Ekran Çıktıları

Aygıt dosyasını oluşturuyorum.

Screenshot from 2014-11-25 18:24:06

 

 make komutunu veriyorum ve kernel object(ko) dosyasını oluşturuyorum.

Screenshot from 2014-11-25 18:16:09

ko dosyasını çekirdeğe yükleyip aygıt dosyasının içine kod5.net yazılması için komut verip cat ile dosya içeriğine bakıyorum ve karakter aygıtının düzgün bir şekilde çalıştığını görüyorum.

Screenshot from 2014-11-25 18:28:46

 

Bu yazıda da bu kadar arkadaşlar. Başka bir yazıda görüşmek üzere hoşçakalın.

1 Yorum

ahmet için bir yanıt yazın X