PB173 - Ovladače jádra - Linux n. Jiří Slabý ITI, Fakulta Informatiky 4. 10. 2011 J. Slabý (ITI) PB173/02 4. 10. 2011 1 / 16 Důležité informace • Kolokvium za DÚ • DÚ do příštího cvičení • Login/heslo • vyvoj/vyvoj • GIT: git://github.com/jirislaby/pbl73.git • git pull —rebase • Qemu Obraz: /home/local/centos . img • 2 účty: root/toor, user/user • ./qemu_startz GITu J. Slabý (ITI) PB173/02 4. 10. 2011 2/16 Dnešní téma Komunikace jádro • uživatelský prostor J. Slabý (ITI) PB173/02 4. 10. 2011 3/16 Komunikace I. O Voláním funkce: systém call (syscall) • Skok do jádra speciální instrukcí (x86_64: syscall) • O skok se stará libc (fwrite^write^syscaii^instrukce) • Drahá operace (přepnutí kontextu) • 1. parametr syscaliu je číslo operace • V jádře: tabulka číslo-funkce • syscall (__NR_fork) • Demo: Ixr ->• __NR_f ork O Speciální syscall • vdso.so Každá nová funkcionalita = nový syscall J. Slabý (ITI) PB173/02 4. 10. 2011 4/16 Úkol V userspace: pomocí syscali vypsat nějakou informaci O syscall a __NR_write Je třeba znát prototypy funkcí. a Většinou jsou dokumentované: man write • Jinak použít Ixr J. Slabý (ITI) PB173/02 4. 10. 2011 5/16 Komunikace II. O Speciální soubory v /dev • Komunikace přes soubor (není nutný nový syscall) • Seznam vDocumentation/devices.txta/proc/devices • Identifikované jako major a minor čísla • Většinou major=ovladač, minor=zanzení (tty: 4, 0-63) • Blokové (disky apod.) • Komunikace po blocích • Nebudeme se jimi zabývat (popsány v LDD) • Znakové (ostatní) • Komunikace po znacích (bajtech) • Viz následující slidy O Sockety, roury, ... J. Slabý (ITI) PB173/02 4. 10. 2011 6/16 Znaková zařízení I. • LDD3 3. a 6. kapitola • 2-3 kroky O Registrace rozsahu major+minor (module.init) • alloc-chrdev_region, register_chrdev_region, unregister_chrdev_region (linux/fs .h) • Přidání záznamu do /proc/devices O Registrace jednotlivých minorů (PCI, USB, .. .probe) • cdev.add, cdev.del (linux/cdev.h) • Po odpovídajícím mknod lze zařízení používat 0 Podat zprávu udev (vytvoření /dev/*) - nepovinné (probe) • device_create, device-destroy (linux/device.h) • Předem je potřeba vytvořit class (module.init) • Implementuje open, close, read, write, ioctl, mmap, . .. J. Slabý (ITI) PB173/02 4. 10. 2011 7/16 Znaková zařízení II. Stačí-li 1 zařízení (1 minor), lze použít vrstvu mise • Dělá všechnu práci z předchozího slidu • Potřebujeme • Seznam implementovaných funkcí (opět; viz dále) • Definici mise zařízení (struct misedevice) • misc.register, misc.deregister • Objeví se v /proc/misc a /dev • linux/misedevice.h J. Slabý (ITI) PB173/02 4. 10. 2011 8/16 Popis funkcí Seznam funkcí, které chceme obsluhovat • struct file_operations(linux/fs.h) « Parametr pro cdev_add, součást miscdevice apod. ssize.t (* write)(struct file *filp , const char ..user *buf, size.t count, loff.t * off p ) • f iip->private_data slouží programátorovi (libovolně) • of fp slouží programátorovi (k poznamenání průběhu) • ..user značí ukazatel od uživatele (tomu nevěříme) • Návratové hodnoty • int - záporné = -Echyba, jinak 0 o ssize.t - záporné = -Echyba, jinak počet zpracovaných znaků J. Slabý (ITI) PB173/02 4. 10. 2011 9/16 Úkol O Najděte všechny možné funkce, které lze obsluhovat o Najděte struct f ile_operations v Ixr 9 Projděte strukturu O Najděte možné chybové návratové hodnoty • Najděte eperm v Ixr » Projděte ostatní J. Slabý (ITI) PB173/02 4. 10. 2011 10/16 Příklad operací struct file.operations my.fops = { .owner = THISJVIODULE, . open = my.open , . write = my.write , . release = my.release , }; int my.open (struct inode *inode , struct file *filp) { f i I p->pri vate.data = ..something; return 0; } ssize.t my.write (struct file *filp , const char ..user *buf, size.t count, loff.t * of f p ) { /* filp->private.data is ..something here */ if (count == 0) return -EINVAL; return 0; J. Slabý (ITI) PB173/02 4. 10. 2011 11/16 Úkol Vytvořit mise (znakové) zařízení s obsluhou open, read, write, release (tj. close). O Definice struct file_operations 0 Vytvoření funkcí dle prototypu z fiie_operations (nalézt v Ixr) • Open a release s nějakým printk • Read a write prozatím prázdná těla • Open a release vracejí 0 (žádná chyba), read též (EOF), write count (zapsáno vše) O Definice struct misedevice • minor = MISC_DYNAMIC_MINOR, name, fops O misc.register/deregister do module_init/exit Q make, insmod O Vyzkoušení cat /dev/name (name je z misedevice) J. Slabý (ITI) PB173/02 4. 10. 2011 12/16 Uživatelská paměť • Něco, čemu nelze věřit (NULL, ukazatel to tabulek oprávnění,...) • Nutnost kontroly • copy.from.user, copy.to.user • „memcpy" s kontrolou • Vracejí počet NEzkopírovaných znaků (0=OK) • get.user, put.user • Jen primitiva (char, short, int, long) • „var = * (type *) buf" a „* (type *)buf = var" s kontrolou • Vracejí O nebo chybu (záporná hodnota) • Definované v linux/uaccess. h Demo: pb173/02 J. Slabý (ITI) PB173/02 4. 10. 2011 13/16 Úkol Dopsat těla funkcí read a write tak, aby zpracovávala data. O write vypíše uživatelský buffer pomocí printk • copy.from.user (chyba = return -EFAULT) • Ukončit zkopírovaný řetězec pomocí \0 Q read bude vracet "Ahoj" • copy.to.user J. Slabý (ITI) PB173/02 4. 10. 2011 14/16 Datové typy • Jádro a proces může běžet s různými bitovými šířkami (32, 64-bit) • Problém s ukazateli a long proměnnými • Jiná délka dat • Jiné zarovnání struktur Uživatel (32-bit) Jádro (64-bit) data ... 4 bajty struct my { void *data; }; data ... 8 bajtů J. Slabý (ITI) PB173/02 4. 10. 2011 15/16 Pevné typy v jádře z hlediska počtu bitů • linux/types. h • __u8, __ul6, __u32, __u64 • __s8, __sl6, __s32, __s64 • Ukazatele musí být v union s __u64 struct my { „u64 flags ; __s1 6 index ; union { void *data; „u64 filler; }; } my; read(fd, &my, sizeof(my)); i o ct I (fd , DO.SOMETHING, &my) ; struct my { unsigned long flags ; short index ; =4> void *data; } my; J. Slabý (ITI) PB173/02 4. 10. 2011 16/16