PB173 - Ovladače jádra - Linux VII. Komunikace s HW Jiri Slabý Fakulta informatiky Masarykova univerzita 4. 11. 2014 Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 1/18 Komunikace s HW LDD3 kap. 9 a 12 O i/o • l/O -porty • l/O-MMIO Q PCI zařízení O Zobecnění na jiné sběrnice O EDU karta Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 2/ 18 Sekce 1 l/O Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 3/ 18 1/0 Na x86: 2 přístupy • Porty • Memory Mapped l/O Jiri Slabý (Fakulta informatiky, MU) 1/0 - porty Porty • Speciální adresový prostor • Závislé na architektuře • Speciální instrukce (in, out na x86) • Samostatná (malá) sběrnice • Na x86: řadič klávesnice, PC spkr, staré časovače a ovladače přerušení, ladicí port (0x80 => segmentový displej na desce), ... API • linux/io.h, linux/ioport.h • Vytvoření: request_region, release_region 9 R/W: inX(port), outX(co, port), kde X G {b,w, 1} • Vícenásobné R/W: insX, outsX Demo: pb173/07 Úkol: Přečíst port 0x80, zapsat do něj 1B a znovu přečíst Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 5/ 18 1/0-MM 10 Memory Mapped l/O • Součástí fyzického adresového prostoru • Přístup standardním čtením/zápisem • Nutnost přemapovat na virtuální adresy API • linux/io.h, linux/ioport.h • Vytvoření: request_mem_region, release_mem_region • /proc/iomem • Mapování: virt=ioremap(phys), iounmap(virt) • /proc/vmallocinfo(novější jádra) • R/W: readX(odkud), writeX(co, kam), kde X G {b,w, 1,q} • Vícenásobné R/W: memcpy_f romio, memcpy_toio Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 6/ 18 Sekce 2 PCI zařízení Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 7/ 18 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 - specifikace zařízení (výrobce) • lspci • Podrobnosti v PCI specifikaci Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 8/ 18 PCI zařízení v jádře • linux/pci.h, Documentation/pci/* • struct pci_dev, struct pci_bus • pci_{set,get}-_drvdata a Uloží/načte programátorova data do/z struct pci_dev • Referenční počet • Zvýšit: pci_dev_get • Snížit: pci_dev_put • PCI zařízení může být (fyzicky) odebráno ze systému • Ale struct pci_dev zůstává, pokud reference > 0 • Identifikace (ID) zařízení • pci_dev->vendor, pci_dev->device, . .. • pci_any_id značí jakékoliv ID (při hledání) Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 9/ 18 Hledání zařízení Iterátory (starší) • Dovoluje přístup k zařízení více ovladači • Nepodporuje hotplug • pci_get_device (vendor, device) Iterace přes zařízení struct pci_dev *pdev = NULL; while ((pdev = pci_get_device(VENDOR, DEVICE, pdev))) { pr_info("%2.x:%.2x.%.2x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); Úkol: vypsat všechna zařízení v systému (jejich vendor+device ID) Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 10/18 Hledání zařízení Událostmi • Registrace háčků a seznamu chtěných zařízení • Seznam: struct pci_device_id (vendor, device, atd.) • Háčky: struct pci_driver (probe, remove, suspend, atd.) • pci_register_driver, pci_unregister_driver Události a PCI zařízení static struct pci_device_id my_table[] = { { PCI_DEVICE(VENDOR1, DEVICE1)}, { PCI_DEVICE(VENDOR1, DEVICE2)}, { PCI_DEVICE(0x8086, PCI_ANY_ID), .driver_data = 1 }, { 0, } }; MODULE_DEVICE_TABLE(pci, myjable); static struct pci_driver my_pci_driver = { .name = "my_driver", . idjable = my_table, . probe = my_probe, }; int my_probe(struct pci_dev *pdev, const struct pci_device_id *id) { pr_info("%2.x %lu\n", pdev->bus->number, id->driver_data); return 0; } Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 11/18 Úkol Navázání PCI zařízení O linux/pci.h O Definice struct pci_device_id • ispci -nn a najít EDU a jeho vendor+device ID Q Definice struct pci_driver • probe, remove, name, id_table O Definice háčků (viz definici struct pci_driver) • int (*probe)(struct pci_dev *, const struct pci_device_id *) • void (*remove)(struct pci_dev *) O V probe a remove vypsat • pdev->bus->number • PCI_SLOT(pdev->devfn) a PCI_FUNC(pdev->devfn) O Zavolat pci_register_driver a pci_unregister_driver O Vložit a odebrat modul (a zkontrolovat dmesg) Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 12/18 Operace s PCI Probe • Inicializace PCI zařízení • pci_enable_device • Do té doby nelze některé vlastnosti pdev používat (irq) • Rezervace a mapování l/O (první část cvičení) • Vytvoření: pci_request_region, pci_request_regions • Mapování: pci_ioremap_bar - alias pro ioremap(pci_resource_start(), pci_resource_len()) • Nastavení/detekce zařízení Remové • Opak Probe • iounmap, pci_release_region(s),pci_disable_device Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 13/ 18 Sekce 3 Zobecnění na jiné sběrnice Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 14/18 Zobecnění Většina ostatních sběrnic funguje stejně • USB, l2C, HID, IEEE1394, ACPI, INPUT, EISA, ... • Nějaké probe/remove • Seznam ID • Registrace „ovladače" Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 15/18 Sekce 4 EDU karta Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 16/18 Specifikace baru O karty EDU Specifikace baru O karty EDU Offset Len R/W Meaning 0x0000 4B R ID & Revision 0x0004 4B R/W Inverted value 0x0008 4B R/W Factorial 0x0020 4B R Status a ID & Revision: OxRRrrOOedu, RR - major, rr - minor a Inverted value: zapsané číslo se obrátí (operátor ~) • Faktoriál: vypočte se faktoriál (je nutné počkat na status bit) • Status: 0. bit - probíhá výpočet faktoriálu Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 17/18 Úkol Vyčtení identifikace karty EDU a práce s ní O Povolení zařízení (pci_enable_device) O Rezervace baru 0 (pci_request_region) O Vypsat fyzickou adresu baru 0 a porovnat s íspci O Přemapovat bar 0 (ioremap) O Přečíst a rozkódovat identifikaci a revizi (readx) 0 Ověřit živost karty pomocí invertovacího registru O Uklidit v remove (unmap, release, disable) Jiri Slabý (Fakulta informatiky, MU) PB173/02 4.11.2014 18/18