PB173 - Ovladače jádra - Linux VI. Datové typy Jiri Slabý Fakulta informatiky Masarykova univerzita 21. 10. 2014 Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 1/14 Obsah cvičení Q Základní typy • Chyby jako ukazatele £ Datové struktury • Seznam • FIFO Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 2/ 14 Datové typy LDD3 kap. 11 • Základní typy • Endianita (pořadí bytů) • Datové struktury (seznam, FIFO) Jiri Slabý (Fakulta informatiky, MU) Sekce 1 Základní typy Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 4/ 14 Základní typy • char, short, int, long,long long (+ unsigned) • u8, ul6, u32, u64, __u8, __ul6, __u32, __u64 • s8, sl6,s32,s64,__s8,__sl6, __s32, __s64 f základních typů pro různé architektury arch char short int long ptr long long alpha 1 2 4 8 8 8 arm 1 2 4 4 4 8 ia64 1 2 4 8 8 8 m68k 1 2 4 4 4 8 mips 1 2 4 4 4 8 ppc 1 2 4 4 4 8 spare 1 2 4 4 4 8 sparc64 1 2 4 8 8 8 x86_32 1 2 4 4 4 8 x86_64 1 2 4 8 8 8 Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 5/ 14 Základní typy f dalších typů (ukazatelů) arch long virt phys x86_32 4 4 4 x86_32+PAE 4 4 4.5+ x86_64 8 8 8 Pro práci s fyzickou adresou iong/ukazatel nestačí • Ale u64 může být zbytečné (čisté 32-bity) « Proto speciální typy (POZOR) • phys_addr_t (RAM) • dma_addr_t (RAM, ale IOMMU!) • resource_size_t (PCI prostor apod.) • Anebo long, ale pak v něm uchovávat pf n (phys/PAGE_siZE) Úkol: opravte typy v pb173/06 (první TODO) Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 6/ 14 Pořadí bytů Číslo 0x12345678 v paměti Adresa: 0 1 2 3 Big-endian 0x12 0x34 0x56 0x78 Little-endian 0x78 0x56 0x34 0x12 Mixed-endian 0x34 0x12 0x78 0x56 Pro typy o velikosti větší než 1 je nutné vědět pořadí • Interpretace dat z/do zařízení • Specifikace • x86: LE • PowerPC: LE nebo BE (dle nastavení CPU) • PCI: LE • Síťový provoz: BE Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 7/ 14 Funkce pro pořadí bytů • asm/byteorder.h • __leXX, __beXX • cpu_to_leXX, cpu_to_beXX • leXX_to_cpu, beXX_to_cpu • XX G {16,32,64} • ntohs, ntohl, htons, htonl Úkol: doplňte tělo decode_and_print v pb173/06 (druhé TODO) Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 8/ 14 Chyby jako ukazatele • void *funkce() • Jak vrátit chytřejší chybu než NULL? « Díra na konci adresového prostoru • Tj. nevalidní ukazatel (dereference by způsobila pád) • Např. Oxf f f f f f f f f f f 00000-Oxf f f f f f f f f f f f f f f f (x86_64) » Lze použít k zakódování chyby • void *ptr=ERR_PTR(-Eerror) • IS_ERR(ptr) int err=PTR_ERR(ptr) • IS_ERR(NULL)=false Úkol: přepište error_handling v pb173/06 (třetí TODO) Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 9/ 14 Sekce 2 Datové struktury Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 10/14 Seznam I. • linux/list.h • struct list_head(obsahuje prev, next) o Jak samotný seznam (počátek), tak jeho prvky • LIST_HEAD(my_list), INIT_LIST_HEAD(&my_list) • list_add(co, kam), list_add_tail, list_del • list_move, list_move_tail struct my_struct { struct my_struct *s; Úkol: naalokujte 20 stránek a v seznamu si je pamatujte. int a; struct list_head list ; }; LIST_HEAD(my_list); s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) { ... } list_add(&s->list, &my_list); /* list_add_tail (&s->list, &my_list); */ Jiri Slabý (Fakulta intormatiky, MU) PB173/02 21.10.2014 11/14 Seznam II. • linux/list.h • list_empty • list_entry, list_first_entry, list_f or_each_entry (. . .){ ... } (jako f or), list_for_each_entry_reverse(...){ ... } • *_saf e varianty - pokud měním aktuální člen seznamu struct my_struct *s, *s1; s = Iist_first_entry (&my_list, struct my_struct, list); s= list_entry (s->list.next, struct my_struct, list); /* or */ list_for_each_entry(s, &my_list, list) { s->a;} list_for_each_entry_safe(s, s1, &my_list, list) { list_del (&s->list); } Úkol: předchozích 20 stránek uvolněte. Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 12/14 FIFO • linux/kfifo.h, samples/kfifo/* a struct kfifo o Statické: declare_kfifq + init_kfifo • Dynamické: kfifo_alloc(&fifo, size, gfp_*), kfifo_free • Zápis: kfifo_in(&fifo, buf, count) • čtení: kfifo_out(&fifo, buf, count) a Obsazeno:kfifo_len(&fifo) a Volno:kfifo_avail(&fifo) Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 13/14 Úkol Práce s FIFO (linux/kf if o.h) O Globální FIFO 8 intů (DECLAREJÍFIFO) O INIT_KFIFO O Zapisovat čísla (kf if o_in) dokud je místo O Vypsat všechna čísla (kf if o_out + kf if o_ien) Pozn.: ve starších jádrech je jiné rozhraní: • jen dynamicky: my_f if o=kf if o_alloc • __kfifo_put=kfifo_in • __kfifo_get=kfifo_out • __kfifo_len=kfifo_len • avail není Jiri Slabý (Fakulta informatiky, MU) PB173/02 21.10.2014 14/14