PB173 - Binární programování Linux XI. Komunikace s HW Jiri Slabý Fakulta informatiky Masarykova univerzita 29. 11. 2016 Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 1 /13 Komunikace s HW • Obvykle práce ovladačů v jádře • Ale často není jádro třeba • Zařízení na sériovém portu • Skenery, tiskárny a podobná USB zařízení • I jednoduchá PCI zařízení Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 2/13 Různé přístupy ke komunikaci s HW O Jádro HW ovládá a uživatelovi nevystavuje • V Linuxu téměř nic O Jádro zaštiťuje nízkoúrovňovou komunikaci • Zařízení V /dev/ (ttyS*, ttyUSB*, lp*) • Soubory v /sys/ (gadgety) O Jádro obsluhuje jen přerušení • Vrstva UIO • Dokumentace: uio-howto O Jádro nedělá s HW nic • Uživatel používá instrukce/volání o Získání povolení: ioperm nebo iopi 9 Přímý přístup: out+in • Soubory v /sys/ (PCI) 9 mmap • Knihovny na přímou komunikaci s HW • libusb, libpciaccess Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 3/13 Přístup instrukcemi/voláními l/O porty • Porty jsou specifikum některých CPU (včetně x86) • Samostatná (malá) sběrnice • Speciální instrukce (in, out na x86) • Je zde řadič klávesnice, PC spkr, časovače a ovladače přerušení, ladicí port (0x80 segmentový displej na desce), ... • Žádost O přístup: ioperm, iopl Čtení: inX • Zápis: outx, kde X e {b, w, 1} • Dokumentace: man ioperm a man inb Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 4/13 Úkol Zahrajte melodii na PC speaker (doplňte pbi73-bin/n/speaker.c) O Nastartujte Si Virtuální Stroj (pbl73-bin/qemu-start) Q Dopište tělo funkce beep • Zapište 0xb6 na port 0x43 • Zapište div na port 0x42 • Zapište (div » 8) na port 0x42 • Přečtěte port 0x61 (obsah spodních 2 bitů zahoďte) • Zapište přečtenou hodnotu I 0x03 zpět na port 0x61 O Dopište tělo funkce stop.beep o Přečtěte port 0x61 9 Zapište o na spodní 2 bity portu 0x61 O Po všech zápisech a čteních čekejte alespoň 10 fis 9 Máte k dispozici usleep 0 Přidejte do main před play volání ioperm © Spusťte Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 5/13 PCI zařízení • PCI, PCI-X, PCIe • Hierarchická sběrnice • Identifikace doména:bus:slot.funkce • Bridge (=routery) • Konfigurační prostor • Automatická konfigurace • ID zařízení (vendor, device), l/O prostory, IRQ • Obsah l/O prostorů - specifikace zařízení (výrobce) • lspci 9 Podrobnosti v PCI specifikaci Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 6/13 mmap pro přímou komunikaci s PCI 9 Každé PCI zařízení může mít: • l/O porty (komunikace viz dříve) • Paměť ve fyzickém prostoru • Přerušení, DMA, atd. (UIO) • Soubory /sys/bus/pci/devices/*/resource* o Mapují se pomocí mmap o Obsah: ve specifikaci konkrétního zařízení Jiri Slabý (Fakulta informatiky MU) PB173/05 29. 11. 2016 7/13 Úkol Komunikace s EDU zařízením O Zjistěte číslo EDU karty z výstupu íspci • Má ID Oxlle8 V qemu • Hledáte něco jako 01:01.0 Q Mapujte resourceO EDU zařízení • V /sys/bus/pci/devices/... • Jen V qemu S -device edu • Mapujte jako volatile uint32_t * O Vypište, co je na první a druhé pozici O Zapište nějaké číslo na druhou pozici Q Vypište, co je na druhé pozici O Spusťte Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 8/13 Knihovny pro přímou komunikaci s HW • Kromě přímého mmap přístupu existují i knihovny • libusb, libpciaccess • Jsou přenositelné • Poskytují lepší rozhraní • Pracují se soubory v /proč a /sys Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 9/13 libpciaccess • gcc ... -lpciaccess (pciaccess.h) O Inicializace: pci_system_init • Deinicializace: pci_system_cleanup • Vytvoření iterátoru (struct pci_device_iterator *) • Vím ID: pci_id_match_iterator_create a struct pci_id_match • Vím slot: pci_slot_match_iterator_create a struct pci_slot_match • Procházení iterátoru: pci_device_next 9 Vrací struct pci_device * (a null nakonec) • Zničení iterátoru: pci_iterator_destroy Struktury pci_id_match a pci _slot_match l uint32_t vendorid; uint32_t device_id; uint32_t subvendorid; uint32_t subdevice_id; uint32_t domain; uint32_t bus; uint32_t dev; uint32_t func; PCIJvlATCHANY Jiri Slabý (Fakulta informatiky, MU) PB173/05 29. 11. 2016 10/13 Úkol Výpis PCI zařízení pomocí libpciaccess O Volejte pci_system_init O Vytvořte iterátor • S parametrem null, tj. projdi všechny O Projděte zařízení O Pro každé vypište číslo • Domény Sběrnice • Zařízení • Funkce Q Spusťte a zkontrolujte s íspci -nn Jiri Slabý (Fakulta informatiky MU) PB173/05 29. 11. 2016 11 /13 libpciaccess a zařízení • Před další prací je nutné inicializovat struct pci.device • Pomocí pci_device_probe • Potom lze pracovat s dalšími prvky struct pci_device • vendor_id, device_id, irq, ... Mapování regionu: pci_device_map_range • Mapuje region do paměti Podobné mmap regionu z dnešního cvičení • Konfigurační prostor Zapisuje BIOS a OS Informace o zařízení • Ctení: pci_device_cf g_read* • Zápis: pci_device_cfg_write* Jiri Slabý (Fakulta informatiky MU) PB173/05 29. 11. 2016 12/13 Úkol Práce S EDU pomocí libpciaccess O Mapujte si 0. region • pci_device_map_range • Mapujte jako volatile uint32_t * • Podobně jako mmap předtím O Vypište, co je na první a třetí pozici Q Zapište nějaké malé číslo na třetí pozici O Počkejte, než bude osmá pozice o O Vypište, co je na třetí pozici O Spusťte Jiri Slabý (Fakulta informatiky MU) PB173/05 29. 11. 2016 13/13