linux sürücü geliştirme (linux device driver development)

32
1/30 Kadir 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.

Upload: kyasar

Post on 05-Aug-2015

170 views

Category:

Software


0 download

TRANSCRIPT

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

1/30 Kadir 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.

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

2/30 Kadir 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

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

3/30 Kadir 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

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

4/30 Kadir 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

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

5/30 Kadir 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()

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

6/30 Kadir 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)

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

7/30 Kadir 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/

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

8/30 Kadir 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 *); [...]

};

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

9/30 Kadir 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);

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

10/30 Kadir 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 };

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

11/30 Kadir 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…

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

12/30 Kadir 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()

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

13/30 Kadir 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

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

14/30 Kadir 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);

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

15/30 Kadir 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);

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

16/30 Kadir 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ü

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

17/30 Kadir 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; …

};

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

18/30 Kadir 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);

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

19/30 Kadir 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));

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

20/30 Kadir 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

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

21/30 Kadir 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)

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

22/30 Kadir 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()

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

23/30 Kadir 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

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

24/30 Kadir 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

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

25/30 Kadir 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

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

26/30 Kadir 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

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

27/30 Kadir 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: %s\n", strerror(errno));

return 1; } if (ioctl (fd, I2C_SLAVE, I2C_ADDR) < 0) { printf("ioctl error: %s\n", strerror(errno)); return 1; } write (fd, 0xFF, 1); read (fd, &value, 1) return 0;

}

Uygulama katmanı

karakter sürücüsü

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

28/30 Kadir 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?

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

29/30 Kadir 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);

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

30/30 Kadir 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ı

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

31/30 Kadir 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ı

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

32/30 Kadir 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