Kompilacja jądra Linuxa

Mając już jakieś pojęcie o Linuxie chcemy zainstalować go na mikrokontrolerze. Oczywiście nie każdy mikrokontroler ma możliwość obsługi systemu operacyjnego. Należy szukać takie procesory, które mają MMU (Memory Management Unit). Ja szukając jakiejś płytki testowej na której zacznę pracę z systemami wbudowanymi kierowałem się nie ceną, ale dobrym opisem do zestawu. Mój wybór padł na zestaw DevKit8000 z procesorem o rdzeniu Cortex-A8, ponieważ znalazłem książkę, która krok po kroku opisuje proces instalacji, kompilacji i obsługi peryferiów w tym właśnie zestawie, książkę można znaleźć w BTC http://www.btc.pl/index.php?ukey=product&productID=188239 oraz w kamami http://www.kamami.pl/index.php?ukey=product&productID=188239 (z tego linka pobierzcie wszystkie dodatkowe pliki). Sam zestaw jest strasznie drogi i kosztuje tyle co nowy komputer. Można go zamówić z całym okablowaniem i wyświetlaczem 7 calowym TFT http://www.kamami.pl/index.php?ukey=product&productID=137790 za około 1700 zł, lub samą płytkę http://www.kamami.pl/index.php?ukey=product&productID=136943 za około 1000zł. Do tego z kamami można pobrać wszystkie potrzebne rzeczy, do skompilowania jądra linuxa. Możecie odwiedzić także stronę http://www.lukasz-skalski.com na której jest bardzo dużo informacji z devkit8000. Drugą przymusową lekturą jest książka linux embedded Marcina Bisa, którą możecie zamówić z BTC http://www.btc.pl/index.php?ukey=product&productID=184248 Znajdziecie tam praktycznie wszystkie podstawowe informacje na temat linuxa i systemów wbudowanych. W książce poruszane są zarówno podstawy jak i bardziej złożone projekty, krok po kroku opisywany jest cały system linux począwszy od struktury plików, a skończywszy na kompilatorach. Zachęcam także do odwiedzenia strony Marcina Bisa http://bis.org.pl/systemy%20wbudowane

1) Wstęp:

Do skompilowania jądra będę nam potrzebne proste komendy. Jeśli macie telefon z androidem, to polecam aplikację:

https://play.google.com/store/apps/details?id=com.dekryptedit.LinuxCommands&hl=pl - Wszystkie możliwe polecenia z Linuxa;

Jest także masa poleceń Linuxowych na różnych stronach np. tu:

http://www.gabo.hi.pl/linux/polecenia.htm

My będziemy potrzebowali na razie tylko kilu z nich:

cd - wchodzi do katalogu (Przykład: cd /home/user/OMAP3; 
mkdir - tworzy katalog (Przykład: /home/user/OMAP3/tools);
gedit - otwiera program do edycji tekstu (Przykład: sudo gedit /etc/bash.bashrc - otworzy nam plik bash.bashrc w notatniku);
sudo - uruchamia program jako administrator (Przykład: sudo gedit /etc/bash.bashrc);
echo - wywołuje na ekran zmienne itp (Przykład: echo $PATH - poda nam wszystkie ścieżki plików w zmiennej PATH);
cp - kopiuje pliki (Przykład: /home/user/Pobrane/tools/mkimage /home/user/OMAP3/tools - kopiuje z katalogu pobrane do katalogutools);
chamod - nadaje prawa dostępu (Przykład: chamod a+x /home/user/OMAP3/tools/mkimage - nadje prawo wszystkim (a-all) do wykonania(x - wykonanie));
df - wyświetla zamontowane urządzenia (Przykład: df -h );

2) Przygotowanie do kompilacji Jądra:

Najpierw należy ściągnąć program, który te jądro skompiluje. W plikach, które zassaliście z kamami jest arm-none-linux-gnueabi (jest on w paczce lxpiae_arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar). Jest to narzędzie, które umożliwi nam kompilację jądra Linuxa. Jeśli zapisywaliśmy te pliki w Linuxie, to znajdują się one w /home/user/Pobrane (zamiast user oczywiście wpisujecie nazwę swojego użytkownika :)). Teraz rozpakowujemy je do katalogu /home/user/OMAP3. Następnie wystarczy dodać ten program do zmiennej PATH, dzięki czemu nie będziemy musieli pisać ścieżki tego programu, aby go uruchomić. Będziemy mogli go uruchomić wpisując tylko jego nazwę w konsoli. Aby tego dokonać wpisujemy sudo gedit /etc/bash.bashrc i w ostatniej linijce dopisujemy ścieżkę naszego katalogu z programem PATH=$PATH:/home/user/OMAP3/arm-2007q3/bin:/home/user/OMA3/tools
Teraz sprawdzamy czy dodał się nasz katalog poleceniem echo $PATH i odpalamy nasz program poleceniem arm-none-linux-gnueabi-gcc -v

Jeśli uzyskaliście podobny efekt, to znaczy, że dodanie ścieżki PATH się powiodło i lecimy dalej. Jeśli na ekranie macie coś innego, to musicie przeanalizować swój błąd.
W drugim etapie instalujemy program mkimage oraz signGP (jest to paczka nazwana lxpiae_kernel_and_tools.zip). Pierwszy służy do tworzenia obrazów systemu, a drugi do ich podpisania. Oczywiście wszystkie pliki są dostępne w załącznikach do książki. Możecie podziękować autorowi tej książki za takie udogodnienie kupując tę lekturę. Teraz wystarczy obydwa programy przekopiować do katalogu tools poleceniami lub za pomocą trybu graficznego. 
cp /home/user/Pobrane/tools/mkimage /home/user/OMAP3/tools
cp /home/user/Pobrane/tools/signGP /home/user/OMAP3/tools
a następnie zmienić prawa dostępu za pomocą polecenia chamod a+x /home/user/OMAP3/tools/mkimage i to samo powtórzyć dla signGP. Dawanie praw dostępu w trybie graficznym u mnie nie bardzo działało, dlatego róbcie to w konsoli.

3) Kompilacja jądra:

Mając już zainstalowane wszystkie potrzebne programy zaczynamy kompilację jądra. Całość sprowadza się do wykonaniu kilku poleceń i ściągnięciu plików konfiguracyjnych. W tym miejscu znowu z pomocą przychodzą nam pliki ze strony kamami. Oczywiście jeśli kupiliście zestaw DevKit8000, to powinniście dostać te same pliki na płytce CD (ja dostałem). Otwieramy katalog tools/source/ i tam znajduje się nasz plik z systemem linux-2.6.28-omap.tar.bz2. Wystarczy go rozpakować i wgrać do katalogu /home/user/OMAP3. Następnie otwieramy katalog linux-2.6.28-omap i kopiujemy plik omap3_devkit8000_defconfig do pliku .config. Można to zrobić poleceniem:
cp arch/arm/configs/omap3_devkit8000_defconfig .config
zrobienie tego w trybie graficznym dawało nieoczekiwane efekty, dlatego róbcie to w konsoli. Następnie w konsoli wchodzimy w katalog z Linuxem /home/user/OMAP3/tools/linux-2.6.28-omap i tworzymy obraz za pomocą polecenia:
make uImage
Tak oto kompilujemy jądro linuxa pod zestaw devkit8000, którego obraz pojawi się w katalogu ../linux-2.6.28-omap/arch/arm/boot/. Oczywiście, aby skompilować jądro można użyć polecenia make uImage z dodatkami, ale w tym przypadku mamy pewność, że producent tego zestawu zrobił to za nas. Polecenie wybierające kompilator to:
make Image ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
można także modyfikować plik konfiguracyjny za pomocą gedit .config (hardcore w trybie tekstowym) lub make menuconfig.

4) Kompilacja Bootloadera pierwszego poziomu:

W tym samym katalogu, gdzie był nasz system jest spakowany boorloader (x-load-1.41). Jest to program, który pomaga wystartować systemowi w mikrokontrolerze. My musimy go rozpakować, wejść do niego i wykonać polecenia:
make distclean
make omap3devkit8000_config
make
signGP x-load.bin
mv x-load.bin.ift MLO

W rezultacie otrzymamy plik MLO

5) Bootloader drugiego poziomu:

Znowu rozpakowujemy bootlodera (u-boot-1.3.3), wchodzimy do katalogu z tym programem i wykonujemy polecenia:
make distclean
make omap3devkit8000_config
make

Otrzymamy plik wynikowy u-boot.bin

6) Dystrybucja:

Aby wszystko działało tak jak na komputerach PC należy do jądra dograć programy obsługujące np. pliki itp. Wszystkie programy zebrane w jedność noszą nazwę dystrybucji. Można stworzyć własny zestaw programów przy pomocy strony http://www.angstrom-distribution.org/. Ze strony kamami mamy dystrybucję bez GUI, czyli bez graficznego interfejsu wszystko jest w pliki rootfs.tar.gz.

7) Przygotowanie Karty SD:

Karta SD najlepiej, aby miała 2 partycje sformatowane jako FAT32 (BOOT) i ext3 Linux (dla systemu Linux Angstrom). Każdy system ma specjalne wymagania co do formatu karty, dlatego prawidłowe przygotowanie karty SD jest najtrudniejszym elementem wgrywania systemu operacyjnego na mikrokontrolery. Do tego celu można użyć gotowych skryptów, które można pobrać z http://www.slimlogic.co.uk/2011/05/omap3-sd-booting/ lub zrobić to samodzielnie za pomocą jakiegoś programu do partycji np. GParted, którego opis macie tu : http://forum.mobione.pl/android-ogolnie/formatowanie-karty-sd-dla-androida-to-cie-nie-zabije/. Ja wklejam printscreny z tego procesu używając konsolowego programu fdisk.


Ważne jest aby odmontować kartę przed wykonaniem polecenia (poleceniem umount)
sudo mkfs.msdos -F 32 /dev/sdb1 -n BOOT
sudo mkfs.ext3 -L Angstrom /dev/sdb2
bo inaczej nie sformatujecie karty.

8) Uruchomienie systemu:

Kopiujemy pliki:
cp ./x-load-1.41/MLO /media/BOOT
cp ./u-boot-1.3.3/u-boot.bin /media/BOOT
cp ./linux-2.6.28-omap/arch/arm/boot/uImage /mediaBOOT

Następnie rozpakowujemy rootfs.tar.gz na pratycje Angstrom:
sudo rm -rf /media/Angstrom/*
sudo tar -xvzf rootfs.tar.gz -C /media/Angstrom
sync
Następnie odmontowujemy kartę i wsadzamy do naszego jednoukładowego komputera. Oczywiście, aby zobaczyć jakiś efekt należy mieć wyświetlacz, albo podłączyć wyprowadzenia UART, na RS232. Jeśli zainstalowaliście dystrybucję z książki, to na wyświetlaczu TFT i tak nie będzie efektu, trzeba podłączyć kabel. Oczywiście, aby odpalić system trzeba u-boot'owi wskazać miejsce obrazu jądra i dystrybucji. Dlatego na samym początku (gdy będzie napis Hit space key to stop autoboot) musicie kliknąć spacje na terminalu, aby wejść do konfiguracji uboota. Aby zobaczyć dostępne funkcje piszemy help, a żeby zobaczyć zmienne piszemy printenv. Ustawiamy zmienne wpisujęc polecenia:

setenv bootcmd 'mmcinit;fatload mmc 0 80300000 uImage;bootm 80300000'
setenv bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait'

Jeśli macie wyświetlacz to dodajcie go tak:

setenv bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait video=omapfb:mode:7inch_LCD'

lub dla wszystkich urządzeń VGA:

setenv bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait video=omapfb:mode:VGA'

Aby zapisać zmiany w pamięci nieulotnej wpisujemy saveenv. Oczywiście jeśli źle wpiszecie te zmienne, to system się nie odpali. Konfiguracja powinna wyglądać następująco:

Po ponownym odpaleniu zestawu powinniśmy otrzymać taki efekt (w windowsowym terminalu):

Jeśli macie Linuxa możecie sprawdzać efekty za pomocą programu putty, należy go skonfigurować w taki sposób:

Możecie także zainstalować gotową dystrybucję Ubuntu na minikomputer. Opis tego jak to zrobić można znaleźć tu:

http://elinux.org/Devkit8000_Ubuntu