X-Git-Url: http://rtime.felk.cvut.cz/gitweb/edu/osp-wiki.git/blobdiff_plain/bc01fb39bb5e908dc7975d92c4ac63e8dd59d98a..HEAD:/cviceni/2.mdwn diff --git a/cviceni/2.mdwn b/cviceni/2.mdwn index a593a62a..1b0568f6 100644 --- a/cviceni/2.mdwn +++ b/cviceni/2.mdwn @@ -5,133 +5,164 @@ Cíl cvičení =========== -Open source projekty se často nepoužívají osamoceně, ale v kombinaci s -jinými OSS projekty, čímž vznikají tak tzv. OSS stacky. Asi -nejznámějším stackem je LAMP – Linux, Apache, MySQL, PHP. Na dnešním -cvičení se seznámíme s dalším, velmi často používaným, stackem -[Linux][kenrel] + [BusyBox][bb] (+[Dropbear][dropbear] SSH server). - -[BusyBox][bb] je sada UNIXových uživatelských nástrojů (shell, editor, -utility jako ls, mkdir, …) zkompilovaná do jedné binárky. V kombinaci -s jádrem Linuxu tak dostáváme kompletní operační systém s poměrně +Cílem tohoto cvičení je prakticky si procvičit informace probírané na +2. přednášce a motivovat vás ke 4. přednášce "*Linuxové jádro – vznik, +vývoj, skladba a ovladače; GNU libc a uživatelský prostor*". Pokud vám +nejsou jasné některé souvislosti, doporučujeme zkusit si informace +vygooglovat a připravit si otázky na 4. přednášku. + +Open source software (OSS) projekty se často nepoužívají osamoceně, +ale v kombinaci s jinými OSS projekty, čímž vznikají tak tzv. OSS +stacky. Asi nejznámějším stackem je LAMP – Linux, Apache, MySQL, PHP. +Na dnešním cvičení se seznámíme s dalším, velmi často používaným, +stackem [Linux][] + [BusyBox][] (+[Dropbear][] SSH server). + +[BusyBox][] je sada UNIXových uživatelských nástrojů (shell, editor, +utility jako ls, mkdir, …) zkompilovaná do jedné binárky. V kombinaci +s jádrem Linuxu tak dostáváme kompletní operační systém s poměrně malými nároky na paměť. Díky tomu se tato kombinace často používá ve vestavěných (embedded) aplikacích jako například [WiFi routery či ADSL modemy][owrt]. -V tomto cvičení si zkusíte vytvořit kompletní open source operační -systém z Linuxového jádra a uživatelského prostředí tvořeného právě +V tomto cvičení si zkusíte vytvořit kompletní open source operační +Systém z Linuxového jádra a uživatelského prostředí tvořeného právě BusyBoxem. Dále si vyzkoušíte naprogramovat jednoduchý modul do jádra. -[kenrel]: http://kernel.org/ -[bb]:http://busybox.net/ +[Linux]: http://kernel.org/ +[BusyBox]:http://busybox.net/ [owrt]:http://www.openwrt.org/ -[dropbear]:http://matt.ucc.asn.au/dropbear/dropbear.html +[Dropbear]:http://matt.ucc.asn.au/dropbear/dropbear.html Postup ====== -1. Stáhneme [zdrojové kódy][bbgit] projektu [BusyBox][bb]: +1. Stáhněte si zdrojové kódy z git repozitáře projektu [BusyBox][] + (adresu repozitáře si najděte sami). - git clone git://busybox.net/busybox.git --reference /usr/src/busybox.git - cd busybox + git clone ... + cd busybox Protože se jedná o aktuální vývojový snapshot, je možné, že se při překladu, instalaci nebo používání vyskytne chyba. Naší výhodou - však je, že máme k dispozici kompletní historii projektu + však je, že máme k dispozici kompletní historii projektu - qgit + gitk a můžeme si vybrat verzi, kde se chyba nevyskytuje. Například - git checkout -f 1_18_3 - -[bbgit]:http://git.busybox.net/busybox/ + git checkout -f 1_22_0 2. Zkonfigurujeme jak chceme BusyBox přeložit. - make menuconfig + make menuconfig - Vystačíme s výchozí konfigurací, takže zvolit `Exit` a odpovědět - `Yes`, že chceme konfiguraci uložit. + Vystačíme s výchozí konfigurací, takže zvolte `Exit` a odpovězte + `Yes`, že chcete konfiguraci uložit. 3. Kompilaci provedeme tradičně příkazem - make + make 4. Příkazem - make install + make install - nainstalujeme busybox do adresáře `./_install`. Všimněte si, že se - tam nachází pouze jedna binárka `bin/busybox` a všechno ostatní - jsou pouze symbolické odkazy na tuto binárku. + nainstalujeme busybox do adresáře `./_install`. Všimněte si (`ls + -lR _install`), že se tam nachází pouze jedna binárka `bin/busybox` + a všechno ostatní jsou pouze symbolické odkazy na tuto binárku. - Protože neprovádíme tzv. *křížový překlad*, který je běžný pro v - případě vestavěných zařízení, můžeme výsledek hned otestovat - například spuštěním shellu: `./_install/bin/sh` (ukončíme ho např. - příkazem `exit`). + Protože neprovádíme tzv. *křížový překlad* (cross compilation), + který je běžný v případě vestavěných zařízení, můžeme výsledek + hned otestovat například spuštěním shellu: `./_install/bin/sh` + (ukončíme ho např. příkazem `exit`). - V případě skutečného vestavěného systému bychom museli pokračovat + V případě skutečného vestavěného systému bychom museli pokračovat dál a busybox otestovat až po nabootování na cílovém hardwaru. -5. Pokud máte na vašem počítači práva superuživatele root, můžete - otestovat BusyBox v chroot prostředí, t.j. se stejným jádrem jako +5. Pokud máte na svém počítači práva uživatele `root`, můžete + otestovat BusyBox v [chroot prostředí][chroot], t.j. se stejným jádrem jako právě běží na vašem počítači, ale se souborovým systémem tvořeným pouze BusyBoxem: - # chroot _install /bin/sh + # chroot _install /bin/sh Fungovat to ale nebude, protože ke spuštění BusyBoxu jsou potřeba - knihovny, které v nejsou v adresáři `_install` dostupné. + knihovny, které v nejsou v adresáři `_install` dostupné. + +[chroot]:http://en.wikipedia.org/wiki/Chroot + +6. Knihovny, které `busybox` potřebuje ke svému běhu, zjistíte + příkazem + + ldd _install/bin/busybox -6. Chybějící knihovny zjistíte příkazem + Na 32-bitovém systému to může vypadat například takto: - ldd _install/bin/busybox - - Tyto knihovny musíte nakopírovat do adresáře `_install` + linux-gate.so.1 => (0xffffe000) + libm.so.6 => /lib/i686/cmov/libm.so.6 (0xf777c000) + libc.so.6 => /lib/i686/cmov/libc.so.6 (0xf7635000) + /lib/ld-linux.so.2 (0xf77aa000) - mkdir _install/lib - cp /lib/i686/cmov/libm.so.6 /lib/i686/cmov/libc.so.6 /lib/ld-linux.so.2 _install/lib + `linux-gate.so.1` (nebo `linux-vdso.so.1`) je virtuální knihovna, + kterou poskytuje jádro Linuxu, takže o tu se starat nemusíte. + Ostatní knihovny je potřeba nakopírovat do cílového systému + (adresáře `_install`) například následujícím způsobem: - Nyní už můžete spustit BusyBox v chroot prostředí. + mkdir _install/lib + cp /lib/i686/cmov/libm.so.6 /lib/i686/cmov/libc.so.6 /lib/ld-linux.so.2 _install/lib + + Nezapomeňte, že v cílovém filesystému musí být i tzv. interpretr + (`ld-linux`), který je na **64-bitovém systému v adresáři + `/lib64`**. + + Nyní už můžete spustit BusyBox v chroot prostředí. 5. Nejjednodušší možnost jak nabootovat do právě vytvořeného uživatelského prostředí je uložit ho ve formátu pro Linuxový - startovací RAM-disk a nabootovat Linux s tímto RAM-diskem. + startovací RAM-disk a nabootovat Linuxové jádro s tímto RAM-diskem. - Aby vše fungovalo jak má, kromě souborů v adresáři `_install` musí - RAM-disk obsahovat i někoik položek v adresáři `/dev` pro přístup k - virtuálním terminálům. - - 1. Pokud máte root práva, použijte ke tvorbě RAM-disku následující příkazy: - - mkdir _install/{dev,etc,proc,sys} - sudo cp -a /dev/tty? _install/dev - ln -s bin/busybox _install/init - (cd _install; find . | cpio -o -H newc | gzip) > ramdisk - - 2. Bez rootovských práv můžete RAM-disk vytvořit pomocí nástoje - [gen_init_cpio][gic]. - - ( - cat < ramdisk + + 2. Bez rootovských práv můžete RAM-disk vytvořit pomocí nástroje + [gen_init_cpio][gic]. Pokud program nemáte na svém počítači, + zkompilujte si ho ze [zdrojových kódů][gic]. + + ( + cat < filelist + find _install -mindepth 1 -type d -printf "dir /%P %m 0 0\n" + find _install -type f -printf "file /%P %p %m 0 0\n" + find _install -type l -printf "slink /%P %l %m 0 0\n" + ) > filelist - gen_init_cpio filelist | gzip > ramdisk + gen_init_cpio filelist | gzip > ramdisk + + Výše uvedené příkazy fungují následovně: Nejprve vytvoříme + seznam souborů (`filelist`), které má ramdisk obsahovat. Nástroj + `gen_init_cpio` pak podle toho seznamu vytvoří obraz ramdisku, + který "zazipujeme" příkazem `gzip` a uložíme do souboru + `ramdisk`. [gic]:http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=usr/gen_init_cpio.c;hb=HEAD @@ -139,19 +170,35 @@ Postup stáhneme zdrojový kód, nakonfigurujeme a přeložíme. Vzhledem k rozsáhlosti jádra (zkompilované zabere na disku cca 1 GB a překlad trvá cca 20 minut) tyto kroky přeskočíme a použijeme již připravené - jádro z distribuce. + jádro z distribuce. - Pokud byste si chtěli přeložit vlastní jádro, v následujícím - příkazu byste za parametrem *-kernel* uvedli cestu k vámi + Pokud byste si chtěli přeložit vlastní jádro, v následujícím + příkazu byste za parametrem *-kernel* uvedli cestu k vámi zkompilovanému jádru. -6. Bootování jádra s naším filesystémem (v emulátoru): +6. Bootování jádra s naším filesystémem (v softwarovém emulátoru + systému): + + Na 64-bitovém systému spustíme emulátor následovně: - qemu -kernel /boot/vmlinuz-2.6.26-2-686 -initrd ramdisk + qemu-system-x86_64 -kernel /boot/vmlinuz-3.2.0-4-amd64 -initrd ramdisk + + Na 32-bitovém systému použijte: + + qemu-system-i386 -kernel /boot/vmlinuz-2.6.26-2-686 -initrd ramdisk + + Pokud systém nabízí hardwarovou podporu virtualizace, je výhodné + použít virtualizační nástroj [KVM][kvm]. Výsledek pak běží + rychleji. KVM vychází z qemu a má tudíž téměř stejné parametry + příkazové řádky. Například: + + kvm -kernel /boot/vmlinuz-3.2.0-4-amd64 -initrd ramdisk + +[kvm]:http://www.linux-kvm.org/ 7. Pokud vše proběhlo správně, zobrazila se hláška - Please press Enter to activate this console. + Please press Enter to activate this console. Po stisku Enteru se spustí shell a můžete začít pracovat ve vašem právě vytvořeném systému. @@ -159,33 +206,71 @@ Postup Možná vylepšení =============== -Dále můžete provést drobná vylepšení vašeho systému, která vám mohou -zjednodušit další práci. +Dále můžete provést drobná (či větší) vylepšení svého nového systému, +která vám mohou zjednodušit další práci. 1. Můžete připojit souborový systém `/proc`, aby fungovaly příkazy - jako např. `ps` (výpis běžících procesů). Příkaz spusťte v - emulátoru, ne na vaší pracovní stanici. + jako např. `ps` (výpis běžících procesů). Příkaz spusťte + v emulátoru, ne na vaší pracovní stanici. - mount -t proc none /proc + mount -t proc none /proc -2. V RAM-disku můžete vytvořit soubor `/etc/init.d/rcS`, který bude +2. V RAM-disku můžete vytvořit soubor `/etc/init.d/rcS`, který bude obsahovat příkazy, které budou spuštěny při bootu systému. - mkdir -p _install/etc/init.d - cat < _install/etc/init.d/rcS - #!/bin/sh - mount -t proc none /proc - echo Nazdar!!!! - EOF - chmod +x _install/etc/init.d/rcS # nastavení spustitelnosti + mkdir -p _install/etc/init.d + cat < _install/etc/init.d/rcS + #!/bin/sh + mount -t proc none /proc + echo Nazdar!!!! + EOF + chmod +x _install/etc/init.d/rcS # nastavení spustitelnosti Nyní musíte znovu vytvořit RAM-disk a nabootovat. +3. Zachytávání zpráv jádra spuštěného v emulátoru QEMU do souboru. + Zprávy jádra je možné přesměrovat na virtuální sériový port a + odtamtud pak například na standardní výstup: + + qemu -serial stdio ... + + a jádru předáme parametr `console=ttyS0` + + qemu -serial stdio -append console=ttyS0 ... + +4. Pokud chcete z vašeho systému komunikovat po síti, připojte ho na + vnější síť pomocí NAT na uživatelské úrovni: + + qemu -net nic,vlan=0,model=ne2k_pci -net user,vlan=0 ... + +5. Pokud QEMU nebo KVM podporuje vytvoření virtio sítě Plan9 a virtuálního + souborového systému, tak je možné propagovat do vnitřního systému + obsah adresáře hostitelského systému: + + qemu -virtfs local,path=shared_dir_name,security_model=none,mount_tag=shared_tag ... + + Adresářovou strukturu lze z vnitřního systému připojit následujícími + příkazy + + modprobe virtio + modprobe virtio_ring + modprobe virtio_pci + modprobe 9pnet + modprobe 9pnet_virtio + modprobe 9p + mkdir -p /mnt/shareddir + mount -t 9p -o trans=virtio shared_tag /mnt/shareddir + +Další tipy a triky v oblasti virtualizace používané a odzkoušené zprávci +sítě na naší katedře nalezente na [Wiki Technické Podpory (support)][support-qemu]. +[support-qemu]:http://support.dce.felk.cvut.cz/mediawiki/index.php/Kategorie:Virtualiza%C4%8Dn%C3%AD_stroje + Jaderné moduly ============== Jaderné moduly jsou přeložené kusy kódu, které lze za běhu nahrávat do -Linuxvého jádra. Pokud bychom chtěli nalézt analogickou věc v +Linuxového jádra. Pokud bychom chtěli nalézt analogickou věc v uživatelském prostředí, pak by to byly *sdílené knihovny*. Jaderný modul může obsahovat kód ovladače zařízení, podporu určitého souborového systému, může přidávat do jádra nové funkce (např. @@ -211,7 +296,7 @@ Zdrojový kód jednoduchého jaderného modulu vypadá následovně: module_init(hello_init); module_exit(hello_exit); -*Příklad převzat z [LDD3][LDD3].* +*Příklad převzat z [LDD3][LDD3].* Překlad modulu provedeme pomocí jednoduchého souboru Makefile, který bude obsahovat jedinou řádku (zde předpokládáme, že výše uvedený @@ -223,10 +308,10 @@ Nyní stačí zavolat `make` se správnými parametry: make -C /lib/modules/$(uname -r)/build M=$(pwd) modules -Tímto říkáme, že příkaz `make` načte `Makefile` z adresáře se +Tímto říkáme, že příkaz `make` načte `Makefile` z adresáře se zdrojovými kódy aktuálně běžícího jádra (o který adresář se jedná -můžete zjistít pomocí `readlink -f /lib/modules/$(uname -r)/build`), -pomocí proměnné `M` řeknete, že se váš modul nachází v aktuálním +můžete zjisti pomocí `readlink -f /lib/modules/$(uname -r)/build`), +pomocí proměnné `M` řeknete, že se váš modul nachází v aktuálním adresáři a slovo `modules` na konci znamená, že chcete, aby se zkompilovaly pouze moduly. @@ -240,32 +325,53 @@ modul, který můžete zavést do jádra příkazem Zadání ====== -Vytvořte jednoduchý jaderný modul, který po zavedení do jádra vypíše -vaše jméno (objeví se ve výstupu `dmesg`). Jinak nemusí dělat nic. -Předveďte činnost vašeho modulu ve vámi vytvořeném systému běžícím v -emulátoru. - -**Pozor:** V zadání je drobný chyták! - -Kdo se bude nudit, může zkusit rozšířit modul tak, aby se jeho jméno -objevilo v souboru `/proc/myname` nebo vytvořit jednoduchý ovladač, -který bude vracet vaše jméno při čtení z `/dev/myname`. Návod najdete -v [tomto článku][henson_drivers] (strany 2 a 3). +1. Stáhněte si [[tento program|magic]] ([[32-bitová verze|magic32]]) a + zprovozněte ho ve vámi vytvořeném systému. Zprovoznění znamená, že + po spuštění program nevypíše žádnou chybu. Nezapomeňte nastavit + práva pro spouštění příkazem `chmod +x`. + + Ke zjištění případným problémů by se vám mohly hodit příkazy + `strace` a `ltrace`. Ten prvý vypisuje všechna systémová volání + vyvolaná daným programem a druhý vypisuje jaké funkce ze sdílených + knihoven program volá. Zkuste si například spustit následující + příkazy: + + echo Ahoj + strace echo Ahoj + ltrace echo Ahoj + +2. Vytvořte jednoduchý jaderný modul, který po zavedení do jádra vypíše + vaše jméno (objeví se ve výstupu příkazu `dmesg`). Jinak nemusí dělat nic. + Předveďte činnost vašeho modulu ve vámi vytvořeném systému běžícím v + emulátoru. + + Kdo se bude nudit, může zkusit rozšířit modul tak, aby se jeho jméno + objevilo v souboru `/proc/myname` nebo vytvořit jednoduchý ovladač, + který bude vracet vaše jméno při čtení z `/dev/myname`. Návod najdete + v [tomto článku][henson_drivers] (strany 2 a 3). Tipy a triky ============ -* Pro vyvolání určitého příkazu z historie můžete použít klávesu +* Pro vyvolání určitého příkazu z historie můžete použít klávesu `Ctrl-R` následovanou textem hledaného příkazu. Např: - cpio + cpio -* Pro rychlé kopírování textu mezi programy (např. příkazy z této stránky do shellu), +* Pro rychlé kopírování textu mezi programy (např. příkazy z této stránky do shellu), můžete použít prostřední tlačítko myši. Funguje to tak, že text označíte myší - (nemačkáte při tom Ctrl-C) a stiskem prostředního tlačítka myši v terminálovém + (nemačkáte při tom Ctrl-C) a stiskem prostředního tlačítka myši v terminálovém okně ho vložíte na příkazovou řádku shellu. Tím, že při tom nemusíte šahat na klávesnici vám to půjde rychleji. +* Pokud je Qemu spouštěný přes vzdálené připojení (např. server postel), + je potřeba pro zobrazení emulované obrazovky spouštěného stroje + buď provést protunelování X protokolu (`ssh -X`) nebo používat Qemu + s emulací obrazovky v textovém režimu `qemu -curses`. Další možnost + je emulovat HW bez grafické karty `qemu -nographic` a nastavit testovaný + systém tak, aby systémová konzole směřovala na sériový port + (`-append console=ttyS0`). + Reference ========= @@ -277,6 +383,14 @@ Reference * [Linux Device Drivers, Third Edition][LDD3] * [Kbuild & modules](http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/kbuild/modules.txt;hb=HEAD) * [/dev/hello_world: A Simple Introduction to Device Drivers under Linux](henson_drivers) +* [Rostislav Lisový: Diplomová práce - Rozšíření QEMU o podporu PCI I/O karty a tvorba ovladačů](http://rtime.felk.cvut.cz/hw/index.php/Humusoft_MF6xx) +* [Filip Navara: Diplomová práce - Rozšíření QEMU o podporu mikrokontroléru AT91SAM7X256](http://rtime.felk.cvut.cz/hw/index.php/AT91SAM7X256) +* [Aleš Kapica a další: Stránky o virtualizaci z oddělení IT K13135](https://support.dce.felk.cvut.cz/mediawiki/index.php/Kategorie:QEMU) [LDD3]:http://lwn.net/Kernel/LDD3/ [henson_drivers]:http://linuxdevcenter.com/pub/a/linux/2007/07/05/devhelloworld-a-simple-introduction-to-device-drivers-under-linux.html + +