PB173 - Ovladače jádra - Linux VI. Datové typy Jiri Slabý ITI, Fakulta informatiky 29. 10. 2013 J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 1 / 13 Datové typy LDD3 kap. 11 • Základní typy • Endianita (pořadí bytů) • Datové struktury (seznam, FIFO) J. Slabý (ITI, Fl) Část I Základní typy J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 3/ 13 Základní typy • char, short, int, long, long long (+ unsigned) • u8, ul6, u32, u64,__u8, __ul6, __u32, __u64 • s8,sl6,s32,s64,__s8, __s!6,__s32, __s64 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 Tabulka : sizeof základních typů pro různé architektury J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 4/ 13 Základní typy arch long virt phys X86.32 4 4 4 X86.32+PAE 4 4 4.5+ X86.64 8 8 8 Tabulka : sizeof dalších typů (ukazatelů) 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) J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 5/ 13 Pořadí bytů Tabulka : Čí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 J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 6/ 13 Funkce pro pořadí bytů a asm/byteorder.h a __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) J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 7/ 13 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) a 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 Jiandling v pb173/06 (třetí TODO) J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 8/ 13 Část II Datové struktury J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 9/ 13 Seznam I. a linux/list.h a struct list_head (obsahuje prev, next) • 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(myJist); s = kmalloc(sizeof(*s), GFP.KERNEL); if (!s) { ... } lisLadd (&s->list, &my.list); /* list-add-tail (&s->list, &myJist); */ J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 10/ 13 Seznam II. • linux/list.h • list_empty • list_entry,list_first_entry, list_for_each_entry(...){ ... } (jako for), list_for_each_entry_reverse(...){ ... } • *_saf e varianty - pokud měním aktuální člen seznamu 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); /* or */ listJor.each.entry (s, SmyJist, list) { s->a; } list.for.each.entry.safe (s, s1, SmyJist, list) { list.del (&s->list); } Úkol: předchozích 20 stránek uvolněte. J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 11 / 13 FIFO a linux/kfifo.h, samples/kfifo/* a struct kfifo • Statické: declare_kfifo + init_kfifo • Dynamické:kfifo_alloc(&fifo, size, gfp_*), kfifo_free a Zápis: kfifo_in(&fifo, buf, count) a Čtení: kfifo_out(&fifo, buf, count) a Obsazeno:kfifo_ien(&fifo) a Volno:kfifo_avail(&fifo) J. Slaby (ITI, Fl) PB173/02 29. 10. 2013 12/ 13 Úkol Práce s FIFO (iinux/kfifo.h) O Globální FIFO 8 intů (DECLARE_KFIFD) Q INIT_KFIFO Q Zapisovat čísla (kf if o_in) dokud je místo O Vypsat všechna čísla (kf ifo_out + kf ifo_ien) Pozn.: ve starších jádrech je jiné rozhraní: • jen dynamicky: my_fifo=kfifo_alloc • __kfifo_put=kfifo_in • __kfifo_get=kfifo_out • __kfifo_len=kfifo_len « avail není J. Slabý (ITI, Fl) PB173/02 29. 10. 2013 13/ 13