--- /dev/null
+[[!meta title="Embedded Linux"]]
+
+[[!toc]]
+
+Aim of the Exercises
+====================
+
+The aim of this exercise is to practice building of the base
+system from open-source components presented during 2-nd lecture
+and motivate and practically introduce students for topics presented
+during 4-th lecture “*Linux kernel - beginning, development, components
+and device drivers; GNU libc and user space*”. If there are some
+steps or relations clear to you, we recommend you try Google to find
+information first and prepare to ask questions at the 4-th lecture.
+
+Open Source Software (OSS) projects are often not used alone but
+in combination with other OSS projects, resulting in the so-called OSS stacks
+or even distributions. Perhaps the best known is the LAMP stack - Linux,
+Apache, MySQL, PHP. In today's exercise you will learn and experiment
+with another, very often used, a stack of [Linux][kenrel] + [BusyBox][bb] (+[Dropbear][dropbear] SSH server).
+
+
+[BusyBox][bb] is a set of basic/standard UNIX utilities (shell, editor
+and such utilities as ls, mkdir, …) compiled into one binary.
+In combination with the Linux kernel it forms a complete minimal
+operating system with a relatively small footprint. Thanks to this
+combination is often used in embedded applications such
+as [WiFi routers and ADSL modems][owrt].
+
+We try to create a complete open source operating system from the
+Linux kernel and user space environment consisting of just busybox
+during this exercise. Next, you try to program and load a simple
+module into the kernel.
+
+[kenrel]: http://kernel.org/
+[bb]:http://busybox.net/
+[owrt]:http://www.openwrt.org/
+[dropbear]:http://matt.ucc.asn.au/dropbear/dropbear.html
+
+The Steps
+=========
+
+1. Download/clone [source code][bbgit] of [BusyBox][bb] project:
+
+ git clone git://busybox.net/busybox.git --reference /usr/src/busybox.git
+ cd busybox
+
+ Because expanded source tree is a current development snapshot, it is
+ quite possible that some problem is encountered during compilation, installing
+ or use of the project. Our significant advantage is that cloned project
+ repository contains whole project development history
+
+ qgit
+
+ and we can choose an older/stable version which is not affected by such problems.
+ For example
+
+ git checkout -f 1_18_3
+
+[bbgit]:http://git.busybox.net/busybox/
+
+2. Next step is to configure BusyBox such way as intended.
+
+ make menuconfig
+
+ There is possibility to control build of many components but default
+ configuration is suitable for our task. Selection of `Exit` and confirm
+ by `Yes` to save configuration is enough for our case then.
+
+3. Project is compiled by standard command
+
+ make
+
+4. Command
+
+ make install
+
+ installs busybox into local directory `./_install`. Notice, please,
+ that there is only single binary executable file `bin/busybox` and all
+ other directory contents are symbolic links to that binary file.
+
+ Because we have not used *cross compilation*, which is quite often in case
+ of build for embedded devices, it is possible to test functionality of
+ our result of *native build* directly on build machine. The shell
+ `./_install/bin/sh` can be run for example (it can be terminated by `exit` command).
+
+ In the case of a real embedded system would have to go on and test the BusyBox
+ after booting on the target hardware.
+
+5. If you can use supervisor (root) rights on build system, then it is possible
+ to test BusyBox in [chroot environment][chroot], i.e. with actual running kernel
+ instance, but with minimal filesystem populated during BusyBox install:
+
+ # chroot _install /bin/sh
+
+ But you find that the attempt to execute BusyBox would fail, because there are
+ necessary system libraries for default/non-static build of BusyBox and these
+ libraries are not available in `_install` substree after chroot.
+
+[chroot]:http://en.wikipedia.org/wiki/Chroot
+
+6. Chybějící knihovny zjistíte příkazem
+
+ ldd _install/bin/busybox
+
+ Tyto knihovny musíte nakopírovat do adresáře `_install`. Na
+ 32-bitovém systému to může vypadat například takto:
+
+ mkdir _install/lib
+ cp /lib/i686/cmov/libm.so.6 /lib/i686/cmov/libc.so.6 /lib/ld-linux.so.2 _install/lib
+
+ Na 64-bitovém systému jádro hledá pro dynamicky linkované programy
+ "interpreter" `/lib64/ld-linux-x86-64.so.2` v adresáři `/lib64`.
+ Vytvoříme ho jako symbolický odkaz na adresář `/lib`
+
+ ( cd _install && ln -s lib 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.
+
+ Aby vše fungovalo jak má, kromě souborů v adresáři `_install` musí
+ RAM-disk obsahovat i několik 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ástroje
+ [gen_init_cpio][gic].
+
+ (
+ cat <<EOF
+ dir /dev 755 0 0
+ nod /dev/tty0 644 0 0 c 4 0
+ nod /dev/tty1 644 0 0 c 4 1
+ nod /dev/tty2 644 0 0 c 4 2
+ nod /dev/tty3 644 0 0 c 4 3
+ nod /dev/tty4 644 0 0 c 4 4
+ slink /init bin/busybox 700 0 0
+ dir /proc 755 0 0
+ dir /sys 755 0 0
+ EOF
+
+ 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
+
+[gic]:http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=usr/gen_init_cpio.c;hb=HEAD
+
+5. **Jádro Linuxu**. Příprava jádra je téměř stejná jako u BusyBoxu:
+ 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.
+
+ 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):
+
+ Na 32-bitovém systému spustíme emulátor následovně:
+
+ qemu -kernel /boot/vmlinuz-2.6.26-2-686 -initrd ramdisk
+
+ Na 64-bitovém systému může být potřeba použít příslušnou variantu QEMU:
+
+ qemu-system-x86_64 -kernel /boot/vmlinuz-2.6.32-5-amd64 -initrd ramdisk
+
+ Pokud systém nabízí hardwarovou podporu virtualizace, je výhodné
+ použít [KVM][kvm]. Výsledek pak běží rychleji. Například:
+
+ kvm -kernel /boot/vmlinuz-2.6.32-5-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.
+
+ Po stisku Enteru se spustí shell a můžete začít pracovat ve
+ vašem právě vytvořeném systému.
+
+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.
+
+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.
+
+ mount -t proc none /proc
+
+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 <<EOF > _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.
+
+Jaderné moduly
+==============
+
+Jaderné moduly jsou přeložené kusy kódu, které lze za běhu nahrávat do
+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ř.
+firewall) či sloužit jako knihovna pomocných funkcí pro jiné moduly
+(např. libata).
+
+Zdrojový kód jednoduchého jaderného modulu vypadá následovně:
+
+ #include <linux/init.h>
+ #include <linux/module.h>
+ MODULE_LICENSE("Dual BSD/GPL");
+
+ static int hello_init(void)
+ {
+ printk(KERN_ALERT "Hello, world\n");
+ return 0;
+ }
+
+ static void hello_exit(void)
+ {
+ printk(KERN_ALERT "Goodbye, cruel world\n");
+ }
+
+ module_init(hello_init);
+ module_exit(hello_exit);
+*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ý
+soubor se jmenuje **khello.c**):
+
+ obj-m = khello.o
+
+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
+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
+adresáři a slovo `modules` na konci znamená, že chcete, aby se
+zkompilovaly pouze moduly.
+
+Pokud vše dopadlo dobře, objevil se vám soubor `khello.ko`, což je
+modul, který můžete zavést do jádra příkazem
+
+ insmod khello.ko
+
+
+
+Zadání
+======
+
+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
+ `Ctrl-R` následovanou textem hledaného příkazu. Např:
+
+ <Ctrl-R>cpio<Enter>
+
+* 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
+ 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.
+
+Reference
+=========
+
+* [ramfs, rootfs and initramfs](http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/filesystems/ramfs-rootfs-initramfs.txt;hb=HEAD)
+* [Early userspace support](http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/early-userspace/README;hb=HEAD)
+* [Inside the Linux boot process](http://www.ibm.com/developerworks/linux/library/l-linuxboot/)
+* [The Linux Bootdisk HOWTO](http://www.tldp.org/HOWTO/Bootdisk-HOWTO/)
+* [Linux Loadable Kernel Module HOWTO](http://tldp.org/HOWTO/Module-HOWTO/)
+* [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)
+
+[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