PB173 - Ovladače jádra - Linux II. Komunikace Jiri Slabý Fakulta informatiky Masarykova univerzita 23. 9. 2014 Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 1 / 19 Důležité informace • Kolokvium za DÚ • DÚ do příštího cvičení • Login/heslo • vyvoj/vyvoj • GIT: http://github.com/jirislaby/pbl73 • git pull --rebase a Studijní materiály v ISu Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 2/ 19 Sekce 1 Komunikace jádro ^ uživatelský prostor Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 3/ 19 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 (f write^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 Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 4/ 19 Ú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 Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 5/ 19 Komunikace II. ® Speciální soubory v /dev 0 Komunikace přes soubor (není nutný nový syscall) • Seznam V Documentation/devices.txt a /proc/devices • Identifikované jako major a minor čísla • Většinou major=ovladač, minor=zanzení (tty: 4, 0-63) • Blokové (disky apod.) o 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, ... Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 6/ 19 Sekce 2 Znaková zařízení Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 7/ 19 Obsluhované funkce struct file_operations (linux/fs.h) • Funkce jako: ssize_t (*write) (struct file *file, constchar_user *buf, size_t count, loff_t *offp) • f iie->private_data slouží programátorovi (libovolně) • of f p slouží programátorovi (k poznamenání průběhu) •__user značí ukazatel od uživatele (POZOR tomu nevěříme) a Návratové hodnoty 9 int - záporné = -Echyba, jinak 0 • ssize_t - záporné = -Echyba, jinak počet zpracovaných znaků • Vždy podle standardu (např. POSIX) Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 8/ 19 Úkol O Najděte všechny možné funkce, které lze obsluhovat • Najděte struct f ile_operations v Ixr a Projděte strukturu Q Najděte možné chybové návratové hodnoty • Najděte eperm v Ixr • Projděte ostatní • Podívejte se do man write na možné návratové hodnoty Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 9/ 19 Příklad operací struct file_operations my_fops = { .owner = THIS_MODULE, .open = my_open, .write = my_write, }; int my_open(struct inode *inode, struct file * filp ) { filp ->private_data = 3; return 0; } ssize_t my_write(struct file *filp, const char_user *buf, size_t count, loff_t *offp) { /* filp ->private_data is 3 here */ if (count == 0) return -EINVAL; return 0; } Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 10/ 19 Úkol Obsluha open, read, write, release (tj. Close) O Definice struct f ile_operations O Vytvoření funkcí dle prototypu z f ile_operations (Ixr) • Open a release s nějakým printk • Read a write prozatím prázdná těla • Návratové hodnoty • Open a release vracejí 0 (žádná chyba) • Read též (0 = EOF) • Write vrací count (zapsáno vše) Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 11 / 19 Vytvoření znakového zařízení • 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 (liímx/f s .h) • Přidání záznamu do /proc/devices O Registrace jednotlivých minorů (při objevení zařízení) • cdev_init, cdev_add, cdev_del (liímx/cdev.h) • Parametr pro cdev_init je struct f ile_operations • Po odpovídajícím mknod lze zařízení používat O Podat zprávu udev (vytvoření /dev/*) - nepovinné • device_create, device_destroy (liímx/device .h) • Předem je potřeba vytvořit class (moduie_init) Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 12/ 19 Úkol Vytvoření znakového zařízení O Globální struct cdev O V module_init • alloc_chrdev_region(&dev, 0, 1, "jméno") • Vypište MAJQR(dev) a MINQR(dev) • cdev_init • cdev_add O V module_exit • cdev_del a unregister_chrdev_region O insmod 0 Ověřte vytvoření v /proc/devices O Podle výpisu Shora: mknod soubor c maj min O Vyzkoušejte cat soubor Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 13/ 19 Vytvoření znakového zařízení pomocí mise Mise vrstva • Stačí-li 1 minor • Dělá všechnu práci včetně volání udev • Potřebujeme • Definici mise zařízení (struct misedevice) • Opět struct file_operations • misc_register, misc_deregister • Objeví se V /proc/misc a /dev • linux/miscdevice.h Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 14/ 19 Úkol Vytvořit mise zařízení O Definice struct misedevice • minor = MISC_DYNAMIC_MINQR • name - jméno vytvářeného zařízení • fops - předchozí Q misc_register/deregister do module_init/exit Q insmod O Ověřte vytvoření v /proc/misc Q Vyzkoušejte cat /dev/name (name je shora) Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 15/ 19 Uživatelská paměť • Něco, čemu nelze věřit (NULL, ukazatel do tabulek oprávnění,...) • Nutnost kontroly POZOR O 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 = *buf" a „*buf = var" S kontrolou • Vracejí 0 nebo chybu (záporná hodnota) o Definované V linux/uaccess .h Demo: pb173/02 Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 16/ 19 Úkol Dopsat těla funkcí read a write tak, aby zpracovávala data O write vypíše uživatelský buffer pomocí printk • copy_f rom.user (při chybě return -EFAULT) • Ukončit zkopírovaný řetězec použitím \o O read bude vracet „Ahoj" • copy_to_user Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 17/ 19 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 Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 18/ 19 Pevné typy v jádře z hlediska počtu bitů • linux/types.h « __u8, __ul6, __u32, __u64 « __s8, __sl6, __s32, __s64 o Ukazatele musí být v union s __u64 struct good { . i i . u64 flags; struct bad { — ., 0 ■ , s16 index; unsigned long flags, , . ™. , a a , union { short index; ^> .._:J void *data; } my; read(fd, &my, sizeof(my)); ioctl(fd, DO_SOMETHING, &my); void *data; _u64 filler : }; } my; Jiri Slabý (Fakulta informatiky, MU) PB173/02 23.9.2014 19/ 19