1/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Hoşgeldiniz
GNU/Linux İşletim Sistemi
için Sürücü Yazılımı Geliştirme
(GNU/Linux Device Driver Development)
Özgür Yazılım ve Linux Günleri ’15
Abdulkadir YAŞAR
Yazılım Tasarım Mühendisi
Aselsan Inc.
2/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Konu Dışı
Linux Kernel
Konfigürasyon
Derleme ve Geliştirme araçları
Donanım
Elektronik altyapı (USB nasıl çalışır?)
Network (TCP/IP)
Yazılım
C/C++
Algoritmalar ve Veri Yapıları
Yardımcı Kütüphaneler
3/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
# cat ~/agenda.txt
Giriş
Sürücü Yazılımı nedir? Ne işe yarar?
Sürücü Tipleri
Linux Kernel ve Sürücü Desteği
Karakter Sürücüler
Linux Sürücü Modeli
Sürücü Örnekleri
I2C Sürücü Altyapısı
Linux Sürücü Özellikleri
Linux Kernel API (ABI)
Özgür ve Özgün örnek Sürücü Geliştirimi
4/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Sözlük
English Türkçe
Linux Kernel Linux Kernel
Device Aygıt
Device Driver Aygıt Sürücü
Controller/Adapter Kontrolcü/Adaptör
Microprocessor Mikroişlemci
System on Chip (SoC) System on Chip (SoC)
Bus Bus
Register (noun) Yazmaç
Register (verb) Kayıtlanma
Framework Framework
Subsystem Altsistem
Interface Arayüz
5/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Giriş
Sürücü Yazılımı nedir?
İşletim sisteminin donanım desteğini gerçekleyen parçası
Kimler sürücü yazılımı geliştirir?
Sistem geliştiriciler ve destekleyiciler
Donanım geliştiriciler
Sürücü tipleri
Karakter (Character): Mouse, klavye, UART, ..
Blok (Block): USB Disk, IDE, SATA, SCSI, ..
Network: TCP/IP, ieee802.11, ieee802.15 (Bt), PPP, ..
open(), read(),
write(), close(),
ioctl()
socket(),
bind(),
listen()
6/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
GNU/Linux Kernel
Uygulama katmanı
(userspace)
# cat /dev/random
Kernel katmanı
(kernelspace)
7/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
GNU/Linux Kernel
arch/ - mimari bağımlı kaynak kodlar
arm/ - işlemci (cpu) mimarisi
arm/mach-omap2 - işlemci üreticisine ait kaynaklar (BSP)
drivers/- Sürücülerle ilgili bütün kaynaklar
i2c/ input/ usb/ video/ tty/ ….
usb/core - USB sınıfına ait kernel framework ü
usb/storage – USB depolama protokolü ile ilgili kaynaklar
include/ - Veri tanımları, prototipler, makrolar…
Documentation/ - Linux Kernel’daki framework ve API lerle ilgili bilgiler
i2c/ usb/
8/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Karakter Sürücü
Karakter tabanlı erişim sağlanan sürücülerdir (input, seriport, fb, ..)
Linux 2.6 öncesi standart sürücü desteği
struct file_operations veriyapısı kullanıcı uygulamaları ve kernel
arasındaki soyutlamayı sağlar (include/linux/fs.h)
Bütün sürücülere dosya gibi erişim
struct file_operations {
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t,
loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned
long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
[...]
};
9/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Karakter Sürücü
register_chrdev() / unregister_chrdev() yordamı karakter
sürücüsünün Linux Kernel’a eklenmesini/kaldırılmasını sağlar
(include/linux/fs.h)
static dev_t aselsan_dev = MKDEV(202,128);
static struct cdev aselsan_cdev;
static int __init aselsan_init (void)
{
register_chrdev (aselsan_dev, 1, “aselsan-captouch");
cdev_init (&aselsan_cdev, &aselsan_fops );
cdev_add (&aselsan_cdev, aselsan_dev, aselsan_count);
}
static void __exit aselsan_exit (void)
{
cdev_del (&aselsan_cdev);
unregister_chrdev (aselsan_dev, 1);
}
module_init (aselsan_init);
module_exit (aselsan_exit);
10/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Karakter Sürücü
Sürücü dosya işlemleri (struct file_operations) ile uygulama
katmanı için soyutlama sağlanır
Kullanıcı uygulamalarında sürücü kullanımı
Kernel space de sürücü işlemleri
fd = open("/dev/aselsan-captouch", O_RDWR);
ret = read(fd, buf, bufsize);
ret = write(fd, buf, bufsize);
static ssize_t aselsan_captouch_write (struct file *f, …)
{
….
}
static ssize_t aselsan_captouch_read (struct file *f, …)
{
….
}
static struct file_operations aselsan_captouch_fops =
{
.read = aselsan_captouch_read,
.write = aselsan_captouch_write
};
11/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Sürücü Modeli
Standart Sürücü Dosya işlemleri (struct file_operations) bütün sürücü
tiplerini tanımlamak ve sürmek için yetersizdir
Linux 2.6 dan itibaren birçok sürücü direkt karakter ya da blok sürücü olarak
kayıtlanmak yerine belli bir framework altında tanımlanırlar
Framebuffer, Serial, USB, MMC, Input…
12/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Sürücü Modeli
Linux Sürücü Modeli (Linux v2.6)
Platform bağımsız sürücü yazılımı
Framework donanım özellikleri kullanıcı
katmanı için soyutlar
USB, I2C, Serial, Input, ..
Bus Infrastructure donanım
algılama/tanıma ve altyapı erişim desteğini
sağlar
read()
i2c_read()
i2c_read_xfer()
13/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Sürücü Modeli
Sürücü modeli tanımları ve ilişkileri include/linux/device.h
14/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Framebuffer Sürücüsü
Framebuffer (ekran) sürücüsü için framework drivers/video/
Framebuffer sürücü sınıfı (device class)
struct fb_ops yordamları (include/linux/fb.h)
struct fb_info Linux a kayıtlanacak
struct fb_ops {
int (*fb_blank)(int blank, struct fb_info *info);
/* pan display */
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
/* Draws a rectangle */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
/* Copy data from area to another */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
/* Draws a image to the display */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
….
}
int register_framebuffer (struct fb_info *fb_info);
int unregister_framebuffer (struct fb_info *fb_info);
15/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Seri Port Sürücüsü
Seri port (UART) için framework: drivers/tty/serial
struct uart_ops yordamları (include/linux/serial_core.h)
struct uart_driver Linux a kayıtlanacak
struct uart_ops {
unsigned int(*tx_empty)(struct uart_port *);
void(*set_mctrl)(struct uart_port *, unsigned int mctrl);
unsigned int(*get_mctrl)(struct uart_port *);
void(*stop_tx)(struct uart_port *);
void(*start_tx)(struct uart_port *);
void(*send_xchar)(struct uart_port *, char ch);
void(*stop_rx)(struct uart_port *);
….
}
int uart_register_driver (struct uart_driver *uart);
void uart_unregister_driver (struct uart_driver *uart);
16/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
I2C (SMBus) Sürücüsü
17/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
I2C Sürücüsü
Linux kernel altsistemleri (subsystem) sürücü ekleme/çıkarma ve
diğer yönetim yordamlarını sürücü geliştirimi için sağlar
I2C framework yordamları yardımıyla sisteme yeni sürücü eklenir
Sürücünün aktifleştirilmesi için probe() yordamının işletilmesi gerekir
Sürücü veri tanımlarını yapar
struct i2c_driver {
…
/* Standard driver model interfaces */
int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *);
…
…
struct device_driver driver;
const struct i2c_device_id *id_table;
…
};
18/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
I2C Sürücüsü
static struct i2c_driver aselsan_i2c_driver = {
.probe = aselsan_i2c_probe,
.remove = aselsan_i2c_remove,
.driver = {
.name = "aselsan-i2c",
.owner = THIS_MODULE,
}
};
static int __init aselsan_init(void) {
int ret = 0;
if ((ret = i2c_register_driver(&aselsan_i2c_driver)))
pr_err(“Device registration failed. (%d)n", ret);
return ret;
}
static void __exit aselsan_exit(void) {
i2c_del_driver(&aselsan_i2c_driver);
}
module_init(aselsan_init);
module_exit(aselsan_exit);
19/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
I2C Sürücüsü
Sürücünün yanında sürücüye ait bilgilerin de sisteme tanıtılması
gerekmektedir (I2C bus no, I2C adres, IRQ no, …)
Board-file çalışması (non-DeviceTree)
I2C için struct i2c_board_info (include/linux/i2c.h)
I2C sürücülerinin sisteme eklenmesi ve çalıştırılmasını sağlanır
static struct i2c_board_info am335x_i2c2_boardinfo[] = {
{
I2C_BOARD_INFO("atmel_i2c_ts", 0x20),
.irq = <interrupt irq no>,
},
{
I2C_BOARD_INFO(“aselsan_touchkey”, 0x29),
.platform_data= &aselsan_i2c_data,
.irq = <interrupt irq no>,
},
};
…
i2c_register_board_info(1, aselsan_i2c2_boardinfo,
ARRAY_SIZE(aselsan_i2c2_boardinfo));
20/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Sürücü Özellikleri
Sürücü donanımına ait bilgileri (clock, irq, konfigürasyon, ..) saklar
driver-specific data structure
Yardımcı yordamları (helper functions – irq_handler) tanımlar
Sürücünün kayıtlanacağı framework (i2c, usb, fb, ..) sistemi ile ilgili
yordamları tanımlar
probe() donanım ilkleme, üst katmanlara kayıtlanma
remove(), suspend(), resume(), enable(), disable()
Sürücünün kullanacağı bus altsistemine kayıtlanır
Örn. i2c_register(), usb_register()
Uygulama katmanı için ilgili dosya sistemlerini ayarlar
Sysfs, procfs, debugfs
21/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Kernel API (ABI)
Hata ayıklama (debugging)
printk()
dmesg (/proc/kmsg)
kdb – kernel debugger
Debugfs
Kernel configuration: DEBUG_FS
sudo mount -t debugfs none /sys/kernel/debug
Procfs
Sysfs (device classes)
22/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Kernel API
Bellek yönetimi
kmalloc(), kzalloc(), vmalloc()
kfree() – (kernel memory leakage = kernel crash)
Kesilme (interrupt) yönetimi
IRQ numara tanımlama
IRQ servis yordamı request_irq()
23/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Kernel API
Zamanlama (timing)
udelay()
struct timer_list my_time; (Documentation/timers)
Eşzamanlı erişim (Concurrency)
spin_lock(), spin_unlock() (bekleme)
mutex_lock(), mutex_unlock()
Kernel servisleri
kernel_thread()
workqueue
24/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Linux Kernel ABI (API)
Kernel veriyapıları
Linked List (struct list_head) (include/linux/list.h)
Hash List, Binary Tree, Red-black tree
Bildirim Zinciri (Notifier Chains)
Observer design pattern
Uygulama katmanı sürücü bilgilendirme
udev - Hotplug/Softplug
Firmware yükleme (download_firmware())
Kernel modül (module)
insmod, rmmod
25/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Örnek Sürücü Geliştirimi
Beaglebone
Rev.a3
Open Hardware
ARM cortex-a8
TI am335x işlemci
26/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Örnek Sürücü Geliştirimi
Dokunmatik Tuş Sensörünün Linux I2C altsistemine entegrasyonu
i2c-core.c i2c-dev.c I2C framework dosyaları drivers/i2c/
Adaptör/Kontrol Sürücü
(Adapter/Controller driver)
drivers/i2c/busses/omap-i2c.c
/dev/i2c-X
Aygıt Sürücü (Device driver)
drivers/*/aselsan-captouch.c
27/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Örnek Sürücü Geliştirimi
Uygulama katmanından I2C sürücümüze erişim
i2c-tools
i2cset, i2cget, i2cdump
#include <linux/i2c.h>
#define I2C_ADDR 0x29
int main () {
int value;
int fd;
if ((fd = open ("/dev/i2c-2", O_RDWR)) < 0) {
printf("Error opening file: %sn", strerror(errno));
return 1;
}
if (ioctl (fd, I2C_SLAVE, I2C_ADDR) < 0) {
printf("ioctl error: %sn", strerror(errno));
return 1;
}
write (fd, 0xFF, 1);
read (fd, &value, 1)
return 0;
}
Uygulama katmanı
karakter sürücüsü
28/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Örnek Sürücü Geliştirimi
Peki Uygulama katmanı nasıl erişip kullanacak?
Sürücünün uygulama katmanı açısından fonksiyonu nedir?
29/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Örnek Sürücü Geliştirimi
Linux Kernel input altsistemi
Uygulama katmanı
struct input_dev {
const char *name;
...
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
int (*getkeycode)(struct input_dev *dev,
struct input_keymap_entry *ke);
int (*open)(struct input_dev *dev);
int (*event)(struct input_dev *dev,...);
};
int input_register_device (struct input_dev *);
void input_unregister_device (struct input_dev *);
fd = open("/dev/input/eventX", O_RDWR);
ret = read(fd, buf, bufsize);
ret = write(fd, buf, bufsize);
30/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Daha Fazlası
31/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
Aselsan
www.aselsan.com.tr
Profesyonel Haberleşme Cihazları
32/30Kadir Yaşar :: Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15
TEŞEKKÜRLER
Many resources and tricks in the Internet you will find, but
solutions to all technical issues in the Source lie.
Use the Source, Luke
HİÇ ÇEKİNME SOR 
Abdulkadir Yaşar
Aselsan A.Ş.
Ankara, Turkey
Donanım destekleri için Tugser Kutlu’ya
Kaynak destekleri için Thomas Petazzoni’ye teşekkürler..
StackOverflow


Linux Sürücü Geliştirme (Linux Device Driver Development)

  • 1.
    1/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Hoşgeldiniz GNU/Linux İşletim Sistemi için Sürücü Yazılımı Geliştirme (GNU/Linux Device Driver Development) Özgür Yazılım ve Linux Günleri ’15 Abdulkadir YAŞAR Yazılım Tasarım Mühendisi Aselsan Inc.
  • 2.
    2/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Konu Dışı Linux Kernel Konfigürasyon Derleme ve Geliştirme araçları Donanım Elektronik altyapı (USB nasıl çalışır?) Network (TCP/IP) Yazılım C/C++ Algoritmalar ve Veri Yapıları Yardımcı Kütüphaneler
  • 3.
    3/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 # cat ~/agenda.txt Giriş Sürücü Yazılımı nedir? Ne işe yarar? Sürücü Tipleri Linux Kernel ve Sürücü Desteği Karakter Sürücüler Linux Sürücü Modeli Sürücü Örnekleri I2C Sürücü Altyapısı Linux Sürücü Özellikleri Linux Kernel API (ABI) Özgür ve Özgün örnek Sürücü Geliştirimi
  • 4.
    4/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Sözlük English Türkçe Linux Kernel Linux Kernel Device Aygıt Device Driver Aygıt Sürücü Controller/Adapter Kontrolcü/Adaptör Microprocessor Mikroişlemci System on Chip (SoC) System on Chip (SoC) Bus Bus Register (noun) Yazmaç Register (verb) Kayıtlanma Framework Framework Subsystem Altsistem Interface Arayüz
  • 5.
    5/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Giriş Sürücü Yazılımı nedir? İşletim sisteminin donanım desteğini gerçekleyen parçası Kimler sürücü yazılımı geliştirir? Sistem geliştiriciler ve destekleyiciler Donanım geliştiriciler Sürücü tipleri Karakter (Character): Mouse, klavye, UART, .. Blok (Block): USB Disk, IDE, SATA, SCSI, .. Network: TCP/IP, ieee802.11, ieee802.15 (Bt), PPP, .. open(), read(), write(), close(), ioctl() socket(), bind(), listen()
  • 6.
    6/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 GNU/Linux Kernel Uygulama katmanı (userspace) # cat /dev/random Kernel katmanı (kernelspace)
  • 7.
    7/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 GNU/Linux Kernel arch/ - mimari bağımlı kaynak kodlar arm/ - işlemci (cpu) mimarisi arm/mach-omap2 - işlemci üreticisine ait kaynaklar (BSP) drivers/- Sürücülerle ilgili bütün kaynaklar i2c/ input/ usb/ video/ tty/ …. usb/core - USB sınıfına ait kernel framework ü usb/storage – USB depolama protokolü ile ilgili kaynaklar include/ - Veri tanımları, prototipler, makrolar… Documentation/ - Linux Kernel’daki framework ve API lerle ilgili bilgiler i2c/ usb/
  • 8.
    8/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Karakter Sürücü Karakter tabanlı erişim sağlanan sürücülerdir (input, seriport, fb, ..) Linux 2.6 öncesi standart sürücü desteği struct file_operations veriyapısı kullanıcı uygulamaları ve kernel arasındaki soyutlamayı sağlar (include/linux/fs.h) Bütün sürücülere dosya gibi erişim struct file_operations { ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); [...] };
  • 9.
    9/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Karakter Sürücü register_chrdev() / unregister_chrdev() yordamı karakter sürücüsünün Linux Kernel’a eklenmesini/kaldırılmasını sağlar (include/linux/fs.h) static dev_t aselsan_dev = MKDEV(202,128); static struct cdev aselsan_cdev; static int __init aselsan_init (void) { register_chrdev (aselsan_dev, 1, “aselsan-captouch"); cdev_init (&aselsan_cdev, &aselsan_fops ); cdev_add (&aselsan_cdev, aselsan_dev, aselsan_count); } static void __exit aselsan_exit (void) { cdev_del (&aselsan_cdev); unregister_chrdev (aselsan_dev, 1); } module_init (aselsan_init); module_exit (aselsan_exit);
  • 10.
    10/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Karakter Sürücü Sürücü dosya işlemleri (struct file_operations) ile uygulama katmanı için soyutlama sağlanır Kullanıcı uygulamalarında sürücü kullanımı Kernel space de sürücü işlemleri fd = open("/dev/aselsan-captouch", O_RDWR); ret = read(fd, buf, bufsize); ret = write(fd, buf, bufsize); static ssize_t aselsan_captouch_write (struct file *f, …) { …. } static ssize_t aselsan_captouch_read (struct file *f, …) { …. } static struct file_operations aselsan_captouch_fops = { .read = aselsan_captouch_read, .write = aselsan_captouch_write };
  • 11.
    11/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Sürücü Modeli Standart Sürücü Dosya işlemleri (struct file_operations) bütün sürücü tiplerini tanımlamak ve sürmek için yetersizdir Linux 2.6 dan itibaren birçok sürücü direkt karakter ya da blok sürücü olarak kayıtlanmak yerine belli bir framework altında tanımlanırlar Framebuffer, Serial, USB, MMC, Input…
  • 12.
    12/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Sürücü Modeli Linux Sürücü Modeli (Linux v2.6) Platform bağımsız sürücü yazılımı Framework donanım özellikleri kullanıcı katmanı için soyutlar USB, I2C, Serial, Input, .. Bus Infrastructure donanım algılama/tanıma ve altyapı erişim desteğini sağlar read() i2c_read() i2c_read_xfer()
  • 13.
    13/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Sürücü Modeli Sürücü modeli tanımları ve ilişkileri include/linux/device.h
  • 14.
    14/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Framebuffer Sürücüsü Framebuffer (ekran) sürücüsü için framework drivers/video/ Framebuffer sürücü sınıfı (device class) struct fb_ops yordamları (include/linux/fb.h) struct fb_info Linux a kayıtlanacak struct fb_ops { int (*fb_blank)(int blank, struct fb_info *info); /* pan display */ int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info); /* Draws a rectangle */ void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect); /* Copy data from area to another */ void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region); /* Draws a image to the display */ void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image); …. } int register_framebuffer (struct fb_info *fb_info); int unregister_framebuffer (struct fb_info *fb_info);
  • 15.
    15/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Seri Port Sürücüsü Seri port (UART) için framework: drivers/tty/serial struct uart_ops yordamları (include/linux/serial_core.h) struct uart_driver Linux a kayıtlanacak struct uart_ops { unsigned int(*tx_empty)(struct uart_port *); void(*set_mctrl)(struct uart_port *, unsigned int mctrl); unsigned int(*get_mctrl)(struct uart_port *); void(*stop_tx)(struct uart_port *); void(*start_tx)(struct uart_port *); void(*send_xchar)(struct uart_port *, char ch); void(*stop_rx)(struct uart_port *); …. } int uart_register_driver (struct uart_driver *uart); void uart_unregister_driver (struct uart_driver *uart);
  • 16.
    16/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 I2C (SMBus) Sürücüsü
  • 17.
    17/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 I2C Sürücüsü Linux kernel altsistemleri (subsystem) sürücü ekleme/çıkarma ve diğer yönetim yordamlarını sürücü geliştirimi için sağlar I2C framework yordamları yardımıyla sisteme yeni sürücü eklenir Sürücünün aktifleştirilmesi için probe() yordamının işletilmesi gerekir Sürücü veri tanımlarını yapar struct i2c_driver { … /* Standard driver model interfaces */ int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*remove)(struct i2c_client *); … … struct device_driver driver; const struct i2c_device_id *id_table; … };
  • 18.
    18/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 I2C Sürücüsü static struct i2c_driver aselsan_i2c_driver = { .probe = aselsan_i2c_probe, .remove = aselsan_i2c_remove, .driver = { .name = "aselsan-i2c", .owner = THIS_MODULE, } }; static int __init aselsan_init(void) { int ret = 0; if ((ret = i2c_register_driver(&aselsan_i2c_driver))) pr_err(“Device registration failed. (%d)n", ret); return ret; } static void __exit aselsan_exit(void) { i2c_del_driver(&aselsan_i2c_driver); } module_init(aselsan_init); module_exit(aselsan_exit);
  • 19.
    19/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 I2C Sürücüsü Sürücünün yanında sürücüye ait bilgilerin de sisteme tanıtılması gerekmektedir (I2C bus no, I2C adres, IRQ no, …) Board-file çalışması (non-DeviceTree) I2C için struct i2c_board_info (include/linux/i2c.h) I2C sürücülerinin sisteme eklenmesi ve çalıştırılmasını sağlanır static struct i2c_board_info am335x_i2c2_boardinfo[] = { { I2C_BOARD_INFO("atmel_i2c_ts", 0x20), .irq = <interrupt irq no>, }, { I2C_BOARD_INFO(“aselsan_touchkey”, 0x29), .platform_data= &aselsan_i2c_data, .irq = <interrupt irq no>, }, }; … i2c_register_board_info(1, aselsan_i2c2_boardinfo, ARRAY_SIZE(aselsan_i2c2_boardinfo));
  • 20.
    20/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Sürücü Özellikleri Sürücü donanımına ait bilgileri (clock, irq, konfigürasyon, ..) saklar driver-specific data structure Yardımcı yordamları (helper functions – irq_handler) tanımlar Sürücünün kayıtlanacağı framework (i2c, usb, fb, ..) sistemi ile ilgili yordamları tanımlar probe() donanım ilkleme, üst katmanlara kayıtlanma remove(), suspend(), resume(), enable(), disable() Sürücünün kullanacağı bus altsistemine kayıtlanır Örn. i2c_register(), usb_register() Uygulama katmanı için ilgili dosya sistemlerini ayarlar Sysfs, procfs, debugfs
  • 21.
    21/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Kernel API (ABI) Hata ayıklama (debugging) printk() dmesg (/proc/kmsg) kdb – kernel debugger Debugfs Kernel configuration: DEBUG_FS sudo mount -t debugfs none /sys/kernel/debug Procfs Sysfs (device classes)
  • 22.
    22/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Kernel API Bellek yönetimi kmalloc(), kzalloc(), vmalloc() kfree() – (kernel memory leakage = kernel crash) Kesilme (interrupt) yönetimi IRQ numara tanımlama IRQ servis yordamı request_irq()
  • 23.
    23/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Kernel API Zamanlama (timing) udelay() struct timer_list my_time; (Documentation/timers) Eşzamanlı erişim (Concurrency) spin_lock(), spin_unlock() (bekleme) mutex_lock(), mutex_unlock() Kernel servisleri kernel_thread() workqueue
  • 24.
    24/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Linux Kernel ABI (API) Kernel veriyapıları Linked List (struct list_head) (include/linux/list.h) Hash List, Binary Tree, Red-black tree Bildirim Zinciri (Notifier Chains) Observer design pattern Uygulama katmanı sürücü bilgilendirme udev - Hotplug/Softplug Firmware yükleme (download_firmware()) Kernel modül (module) insmod, rmmod
  • 25.
    25/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Örnek Sürücü Geliştirimi Beaglebone Rev.a3 Open Hardware ARM cortex-a8 TI am335x işlemci
  • 26.
    26/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Örnek Sürücü Geliştirimi Dokunmatik Tuş Sensörünün Linux I2C altsistemine entegrasyonu i2c-core.c i2c-dev.c I2C framework dosyaları drivers/i2c/ Adaptör/Kontrol Sürücü (Adapter/Controller driver) drivers/i2c/busses/omap-i2c.c /dev/i2c-X Aygıt Sürücü (Device driver) drivers/*/aselsan-captouch.c
  • 27.
    27/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Örnek Sürücü Geliştirimi Uygulama katmanından I2C sürücümüze erişim i2c-tools i2cset, i2cget, i2cdump #include <linux/i2c.h> #define I2C_ADDR 0x29 int main () { int value; int fd; if ((fd = open ("/dev/i2c-2", O_RDWR)) < 0) { printf("Error opening file: %sn", strerror(errno)); return 1; } if (ioctl (fd, I2C_SLAVE, I2C_ADDR) < 0) { printf("ioctl error: %sn", strerror(errno)); return 1; } write (fd, 0xFF, 1); read (fd, &value, 1) return 0; } Uygulama katmanı karakter sürücüsü
  • 28.
    28/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Örnek Sürücü Geliştirimi Peki Uygulama katmanı nasıl erişip kullanacak? Sürücünün uygulama katmanı açısından fonksiyonu nedir?
  • 29.
    29/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Örnek Sürücü Geliştirimi Linux Kernel input altsistemi Uygulama katmanı struct input_dev { const char *name; ... unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; int (*getkeycode)(struct input_dev *dev, struct input_keymap_entry *ke); int (*open)(struct input_dev *dev); int (*event)(struct input_dev *dev,...); }; int input_register_device (struct input_dev *); void input_unregister_device (struct input_dev *); fd = open("/dev/input/eventX", O_RDWR); ret = read(fd, buf, bufsize); ret = write(fd, buf, bufsize);
  • 30.
    30/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Daha Fazlası
  • 31.
    31/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 Aselsan www.aselsan.com.tr Profesyonel Haberleşme Cihazları
  • 32.
    32/30Kadir Yaşar ::Linux Sürücü Yazılımı Geliştirme :: Özgür Yazılım ve Linux Günleri ’15 :: 27.03.15 TEŞEKKÜRLER Many resources and tricks in the Internet you will find, but solutions to all technical issues in the Source lie. Use the Source, Luke HİÇ ÇEKİNME SOR  Abdulkadir Yaşar Aselsan A.Ş. Ankara, Turkey Donanım destekleri için Tugser Kutlu’ya Kaynak destekleri için Thomas Petazzoni’ye teşekkürler.. StackOverflow 