PB173 - Ovladače jádra - Linux II. Komunikace Jiri Slabý Fakulta informatiky Masarykova univerzita 1. 10. 2015 Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 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 • Studijní materiály v isu Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 2/19 Sekce 1 Komunikace jádro o uživatelský prostor Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 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^syscall-Hnstrukce) • Drahá operace (přepnutí kontextu) • Do registru se uloží číslo operace • V libc: převodní „tabulka" funkce^číslo • V jádře: převodní tabulka číslo^funkce • syscall(__NR_fork) • Demo: __NR_f ork V unistd.h; příklady Z pbl73/02/syscalls/ O Speciální syscall • Knihovna přilinkovaná jádrem • vdso.so Každá nová funkcionalita = nový syscall Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 4/19 Úkol V userspace: pomocí funkce syscali vypsat nějakou informaci O Inspirujte se V pbl73/02/syscalls/c . c O Použijte syscall a __NR_write Je třeba znát prototypy funkcí. • Většinou jsou dokumentované: man write • Jinak použít Ixr a najít implementaci v jádře Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 5/19 Komunikace II Q Speciální soubory v /dev • Komunikace přes soubor • Standardní operace - open, read,... • Tj. není nutný nový syscall o Identifikované trojicí blokové/znakové, major a minor číslo • Většinou major=ovladač, minor=zařízení (tty: c, maj 4, min 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) • Zbytek tohoto cvičení 9 Seznam rezervovaných v Documentation/devices.txt a /proc/devices O Sockety, roury, ... Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 6/19 Sekce 2 Znaková zařízení Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 7/19 Obsluhované funkce struct f ile_operations (linux/fs.h, LDD3 3. kapitola) • Funkce jako: ssize_t (*write) (struct file * file , const char_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) • Návratové hodnoty (podle návratového typu funkce) • int - záporné = -Echyba, jinak 0 • ssize.t - záporné = -Echyba, jinak počet zpracovaných znaků o Vždy podle standardu (např. POSIX) Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 8/19 Úkol O Najděte všechny možné funkce, které lze obsluhovat • Najděte struct file.operations v Ixr • 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/04 1. 10. 2015 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; *offp += count; /* remember position for the next time */ return count; /* "written" all */ Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 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 a return o Read a write prozatím jen return • Návratové hodnoty • Open a release vracejí 0 (žádná chyba) • Read též (0 znamená EOF) • Write vrací count (zapsáno vše) O Jen zkuste přeložit Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 11/19 Vytvoření znakového zařízení • LDD3 3. a 6. kapitola • 2-3 kroky O Registrace rozsahu major+minor (vmodule.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_init, cdev_add, cdev_del (linux/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 (linux/device.h) • Předem je potřeba vytvořit class (module.init) Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 12/19 Úkol Vytvoření znakového zařízení O Definujte si globální struct cdev O V module_init • Zavolejte alloc_chrdev_region(&dev, 0, 10, "jméno") • dev je návratová hodnota typu dev_t • Vypište Si MAJOR (dev) a MINOR (dev) • Zavolejte cdev.init na svou globální struct cdev • Zavolejte cdev.add na SVOU globální struct cdev a dev O V module_exit • cdev_del • unregister_chrdev_region O make a insmod 0 Ověřte vytvoření v /proc/devices O Podle výpisu Z 2. bodu: mknod soubor c MAJ MIN O Vyzkoušejte cat soubor Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 13/19 Uživatelská paměť • Něco, čemu nelze věřit (NULL, ukazatel do tabulek oprávnění,...) • Nutnost kontroly POZOR • copy_from_user, copy_to_user • „memcpy" S kontrolou • Vracejí počet NEzkopírovaných znaků (0 znamená OK) • get_user, put_user • „var = *buf" a „*buf = var" S kontrolou • Tzn. jen pro primitiva (char, short, int, long) • Vracejí 0 nebo chybu (záporná hodnota) • Definované v linux/uaccess.h Demo: pb173/02 Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 14/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) • Nezapomeňte ukončit zkopírovaný řetězec použitím \o Q read bude vracet řetězec „Ahoj" • copy_to_user Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 15/19 Vytvoření znakového zařízení pomocí mise Mise vrstva • Stačí-li 1 minor (málokdy) • Dělá všechnu práci včetně volání udev • Potřebujeme o Definici mise zařízení (struct misedevice) o Opět struct file_operations • struct cdev není třeba • misc_register, misc_deregister • Objeví se V /proc/misc a /dev • linux/misedevice.h Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 16/19 Úkol Vytvořit mise zařízení O Definice struct misedevice • minor = MISC_DYNAMIC_MINOR (automaticky přidělit) • name-jméno vytvářeného zařízení • f ops — vaše struct f ile_operations O misc_register/deregister do module_init/exit O make a insmod O Ověřte vytvoření v /proc/misc O Vyzkoušejte cat /dev/ (jméno shora) Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 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/04 1. 10. 2015 18/19 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; _s16 index; union { void *data; _u64 filler }; } my; read(fd, &my, sizeof(my)); ioctl(fd, DO_SOMETHING, &my); struct bad { unsigned long flags; short index; =4> void *data; } my; Jiri Slabý (Fakulta informatiky, MU) PB173/04 1. 10. 2015 19/19