PB173 - Ovladače jádra - Linux VI. Datové typy Jiri Slabý Fakulta informatiky Masarykova univerzita 25. 10. 2016 Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 1 /14 Obsah cvičení Q Základní typy • Chyby jako ukazatele Q Datové struktury 9 Seznam • FIFO Jiri Slabý (Fakulta informatiky, MU) PB173/04 25.10.2016 2/14 Datové typy LDD3 kap. 11 • Základní typy • Endianita (pořadí bytů) • Datové struktury (seznam, FIFO) Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 3/14 Sekce 1 Základní typy Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 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 základních typů pro různé architektury Architektura char short int long void * 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/04 25. 10. 2016 5/14 Základní typy dalších typů (ukazatelů) Architektura long void * phys x86_32 4 4 4 x86_32+PAE 4 4 4.5+ x86_64 8 8 8 Pro práci s fyzickou adresou long nebo void * nestačí Ale u64 nebo long long může být zbytečné (čisté 32-bity) o Proto speciální typy (POZOR) 9 phys_addr_t (RAM, za MMU) • Anebo long, ale pak v něm uchovávat jen pf n (pnys/PAGE_siZE) • dma_addr_t (RAM, před IOMMU) • resource_size_t (PCI prostor apod.) Úkol: opravte typy v pb173/06 (jen prvníTODO) Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 6/14 Pořadí bytů Číslo 0x12345678 reprezentované v paměti ] Pořadí Příklad architektury Offset v paměti 0 12 3 Big-endian Little-endian Mixed-endian arm, s390 arm, x86 PDP-11 0x12 0x34 0x56 0x78 0x78 0x56 0x34 0x12 0x34 0x12 0x78 0x56 Pro typy o velikosti větší než 1 je nutné znát pořadí o Interpretace dat z/do zařízení • Specifikace • CPU (příklady nahoře) • PCI: LE Síťový provoz: BE «... Jiri Slabý (Fakulta informatiky MU) PB173/04 25. 10. 2016 7/14 Funkce pro pořadí bytů • asm/byteorder.h • __leXX, __beXX • XX G {16,32,64} • cpu_to_leXX, cpu_to_beXX • leXX_to_cpu, beXX_to_cpu • ntohs, ntohl, htons, htonl Úkol: doplňte tělo decode_and_print v pb173/06 (druhé TODO) Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 8/14 Chyby jako ukazatele • void *funkce() • Jak vrátit chytřejší chybu než NULL? o V uživatelském prostoru máme errno a ekvivalenty • Díra na konci adresového prostoru • Tj. nevalidní ukazatel (dereference by způsobila pád) • Např. nax86_64: OxfffffffffffOOOOO-Oxffffffffffffffff • Lze použít k zakódování chyby • void *ptr = ERR_PTR(-Eerror) IS_ERR(ptr) == true => int err = PTR_ERR(ptr) o IS_ERR(NULL) je false! Úkol: přepište err or .handling V pb173/06 (třetí TODO) Jiri Slabý (Fakulta informatiky MU) PB173/04 25. 10. 2016 9/14 Sekce 2 Datové struktury Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 10/14 Seznam I. • linux/list.h • struct list_head(obsahuje prev, next) • Jak samotný seznam (počátek), tak jeho prvky 9 LIST_HEAD(my_list)s, INIT_LIST_HEAD(&my_list)o 9 list_add(co, kam), list_add_tail(co, kam), list_del(co) 9 list_move(co, kam), list_move_tail(co, kam) Příklad struct mystruct { struct my struct *s; int a; s = kmalloc(sizeof(*s), GFP KERNEL); struct list head list ; if (Is) { ... } }; s->a = 10; LIST HEAD(my list); list_add(&s->list, &my_list); /* or list_add_tail (&s->list, &myjist); */ Úkol: naalokujte 20 stránek a v seznamu si je pamatujte. Jiri Slabý (Fakulta informatiky, MU) PB173/04 25. 10. 2016 11 /14 Seznam II. • linux/list.h 9 list_empty(list) • Jedna položka: list.entry, list_f irst.entry • Iterace: list_for_each_entry(. . .) { ... } (jako f or)5 list_for_each_entry_reverse(...) { ... } • *_saf e varianty - pokud měním aktuální člen seznamu ' Příklad 1 struct my_struct *s, *s1; s = list_first_entry (&my_list, struct my_struct, list); s = list_entry (s->list.next, struct my_struct, list); 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/04 25. 10. 2016 12/14 FIFO • linux/kfifo.h, samples/kfifo/* • struct kfifo • Statické: declare_kfifo + init_kfifo • Dynamické: kfifo_alloc(&fifo, size, gfp_*), kfifo_free(&fifo) o Zápis: kf if o_in(&f ifo, buf, count) • Čtení: kfifo_out(&fifo, buf, count) • Obsazeno:kfifo_ien(&fifo) • Volno: kf if o_avail(&fifo) Jiri Slabý (Fakulta informatiky MU) PB173/04 25. 10. 2016 13/14 Úkol Práce s FIFO (linux/kf ifo.h) O Globální FIFO 8 intů (declare.kfifo) 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 (< 2.6.33) je jiné rozhraní: • jen dynamicky: my_f if o = kf if o.alloc •__kf if o_put je kf if o_in •__kf if o_get je kf if o_out •__kf if o_len je kf if o_len • avail není Jiri Slabý (Fakulta informatiky, MU) PB173/04 25.10.2016 14/14