PB173 - Ovladače jádra - Linux n. Jiri Slabý ITI, Fakulta Informatiky 27. 9. 2012 J. Slabý (ITI) PB173/06 27.9.2012 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 O Qemu Obraz: /home/local/centos . img • 2 účty: root/toor, user/user • ./qemu_startZ GITu J. Slabý (ITI) PB173/06 27.9.2012 2/ 16 Dnešní téma Komunikace jádro • uživatelský prostor J. Slabý (ITI) PB173/06 27.9.2012 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) • Do registru se uloží číslo operace • V jádře: tabulka číslo-funkce • syscall (__NR_fork) • Demo: Ixr ->• __NR_f ork; příklady O Speciální syscall • vdso.so Každá nová funkcionalita = nový syscall J. Slabý (ITI) PB173/06 27.9.2012 4/ 16 Úkol V userspace: pomocí syscali vypsat nějakou informaci O syscall a __NR_write Je třeba znát prototypy funkcí. • Většinou jsou dokumentované: man write • Jinak použít Ixr J. Slabý (ITI) PB173/06 27.9.2012 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 0 Sockety, roury, ... J. Slabý (ITI) PB173/06 27.9.2012 6/ 16 Znaková zařízení I. • LDD3 3. a 6. kapitola • 2-3 kroky O Registrace rozsahu major+minor (v 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ů (při objevení zařízení) • cdev.add, cdev.del (linux/cdev.h) • Po odpovídajícím mknod lze zařízení používat O Podat zprávu udev (vytvoření /dev/*) - nepovinné • device-create, device-destroy (linux/device.h) • Předem je potřeba vytvořit class (module-init) J. Slabý (ITI) PB173/06 27.9.2012 7/ 16 Znaková zařízení II. Mise vrstva 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 a Definici mise zařízení (struct misedevice) • Seznam implementovaných funkcí (např. open, read apod.) a misc.register, misc.deregister • Objeví se v /proc/misc a /dev • linux/miscdevice.h J. Slaby (ITI) PB173/06 27.9.2012 8/ 16 Obsluhované funkce Seznam implementovaných funkcí • Funkce jako: ssize.t (* write)(struct file *filp , const char ..user *buf, size.t count, loff.t * of f p ) • struct file_operations(linux/fs.h) • Parametr pro cdev.add, součást miscdevice apod. • 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) a Návratové hodnoty o int - záporné =-Echyba, jinak 0 o ssize.t - záporné = -Echyba, jinak počet zpracovaných znaků J. Slabý (ITI) PB173/06 27.9.2012 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/06 27.9.2012 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 Ip->private.data = 3; 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 3 here */ if (count == 0) return -EINVAL; return 0; J. Slaby (ITI) PB173/06 27.9.2012 11 / 16 Úkol Vytvořit mise (znakové) zařízení s obsluhou open, read, write, release (tj. close). O Definice struct file_operations Q Vytvoření funkcí dle prototypu z fiie_operations (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éž (0 = 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/06 27.9.2012 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/06 27.9.2012 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/06 27.9.2012 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 na offsetu 4 struct my { char x; void *data; }; data ... 8 bajtů na offsetu 8 J. Slabý (ITI) PB173/06 27.9.2012 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 good { „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 bad { unsigned long flags ; short index ; =4> void *data; } my; J. Slaby (ITI) PB173/06 27.9.2012 16/ 16