PB173 - Ovladače jádra - Linux X. DMA Jiri Slabý ITI, Fakulta informatiky 26. 11. 2013 J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 1 / 11 Paměť jinak II. LDD3 kap. 15 (zastaralá) a I. (minule): Mapování paměti jádra (mmap) • II. (dnes): Přímý přístup do paměti (DMA) J. Slabý (ITI, Fl) PB173/02 26.11.2013 2/ 11 DMA Přímý přístup do paměti a Prozatím jsme ze/do zařízení četli/zapisovali přes CPU • Tj. standardními operacemi s (přemapovanou) pamětí • Velké přenosy = velká zátěž CPU • Cykly, čekání na pomalou sběrnici atd. • Místo toho naprogramujeme HW, aby přenášel data sám • Nutná podpora HW (sběrnice - arbitrace, zařízení - přenosy) J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 3/11 Princip DMA Princip O Alokace (speciální) paměti O Pro TX. vyplnění daty (paket, zvuk, data na disk,...) 0 Předání ukazatele do zařízení O Odstartování přenosu v zařízení 0 Přerušení či jiná signalizace konce přenosu od zařízení 0 Pro RX. práce s příchozími daty (paket, data z disku,...) J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 4/11 DMA v Linuxu API alokace • linux/dma-mapping.h, Documentation/DMA-* • dma_alloc_coherent, dma_free_coherent void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) • dev - zařízení, které bude k paměti přistupovat (null pokud neznáme) • size - velikost, jakou požadujeme • dma_handie - fyzická adresa (návratová hodnota) - pro zařízení • návratová hodnota - virtuální adresa - pro nás J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 5/11 DMA v Linuxu - příklad int my_do.DMA(struct device *dev) { dma-addr.t phys; char *virt; virt = dma.alloc.coherent(dev, 100, &phys, GFP.KERNEL); if (! virt) return -ENOMEM; memset(virt, 0, 100); my.HW.set.addr(dev, phys); my.H W.start.transfer(dev); while (my.HW.working(dev)) /* polling */ msleep(100); printk(KERNJNFO "%s\n", virt); return 0; } Úkol: alokujte a uvolněte pomocí dma_* 1 stránku paměti (v ovladači EDU z předminulá) J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 6/11 DMA pro PCI Navíc • Nastavení masky adres • Ne všechna zařízení zvládnou adresovat celý fyzický prostor • pci_set_dma_mask(pdev, DMA_BIT_MASK(27)) • Zapnutí „spravování sběrnice" • Tj. zařízení umí samo iniciovat přenosy apod. • pci_set_master(pdev) int my.probe(struct pcLdev *pdev, ...) { dma.addr.t phys; void * virt; ... /* enable etc. here */ ret = pci.set.dma.mask(pdev, DMA.BIT.MASK(27)); pci.set.master(pdev); virt = dma.alloc.coherent(&pdev->dev, 100, &phys, GFP.KERNEL); } "' J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 7/11 EDU a DMA • Zvládá 32bitové adresy • DMA řadič napojený na PCI a lokální paměť • Na adrese 0x40000 o Velikost 4096 B • Generuje přerušení 8 (Oxioo) na kartě • Po dokončení přenosu • (Jen je-li vyžádáno před přenosem) Úkol: doplňte předešlou alokaci (O set_dma_mask a set_master) J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 8/11 EDU DMA registry Offset Len R/W Contents Meaning 0x0080 4B R/W src Source address 0x0084 4B R/W dst Destination address 0x0088 4B R/W count Transfer count 0x008c 4B R/W cmd Command register Tabulka : Specifikace baru 0 (pokračování z minula) • cmd registr o Zapisuje se po nastavení ostatních registrů • Zapisuje se jednou s kombinací bitů • Bit 0: run (transfer now) o Bit 1: direction (0: from RAM, 1: to RAM) • Bit 2: rqint (generate an interrupt after the transaction) J. Slaby (ITI, Fl) PB173/02 26. 11. 2013 9/11 Úkol Práce s DMA na EDU O Naalokovat stránku DMA prostoru O 10 B inicializovat textovým řetězcem O Přenést 10 B do EDU na adresu 0x40000 • Nastavit všechny 4 registry • Bez přerušení (bez rqint) • Počkat na nulovou hodnotu bitu run (na dokončení přenosu) O Přenést 10 B z EDU na DMA stránku + 10 • Vznikne za sebou 2 x stejný řetězec J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 10/ 11 Úkol DMA s přerušením (domácí) O Rozšířit předchozí o přerušení • Přidat ještě jeden přenos z EDU na DMA + 20 • Přenos bude s rqint O Obsloužit přerušení • ACK přerušení a Iniciovat tasklet 0 V taskletu vypsat obsah DMA paměti + 20 O DMA stránku vystavit přes mmap POZOR na prezenci a správnou posloupnost zabíjení taskletu, zákazu přerušení, dealokace atd. J. Slabý (ITI, Fl) PB173/02 26. 11. 2013 11 / 11