Mungkin sudah banyak dari kawan kawan sekalian yang berkecimpung di bidang embedded system, baik yang sekedar hobi ataupun sebagai profesi / pekerjaan. Banyak dari kita yang menggunakan linux maupun windows dalam mengembangkan sistem embedded. Kelebihan linux dalam hal open source, kebebasan kustomisasi, berbiaya rendah, suport komunitas yang luas maupun kehandalan dan kemampuan jaringan yang mumpuni membuat linux semakin berkembang, hal ini kemudian menjadi dasar untuk membawa linux ke dalam dunia embedded. Pada dasarnya Embedded linux menggunakan kernel yang sama digunakan dalam sistem linux lainnya akan tetapi akan membutuhkan beberapa packages tambahan maupun modifikasi sehingga dapat digunakan dalam sistem embedded yang umumnya memiliki fungsi yang khusus dan memiliki keterbatasan seperti kapasitas RAM dan ROM yang kecil.
Contoh development board yang mudah didapatkan dan populer dalam embedded linux adalah beaglebone dan raspberry pi. Kali ini kita akan lebih spesifik dalam membahas penerapan embedded linux dalam beaglebone black board. Beaglebone black ditenagai oleh AM3358
ARM Cortex-A8 (1 GHz) dengan RAM sebesar 512MB, 4GB (Rev C) eMMC, microSD card slot, port USB dan 10/100 Ethernet. Sebagai gambaran umum, proses booting pada beaglebone dapat diurutkan menjadi :
- ROM Boot Loader : Eksekusi program yang ada di dalam ROM SoC (AM335x), inisialisasi bus clock. kemudian meload SPL/MLO ke dalam internal SRAM SoC.
- Secondary Program Loader (SPL) / Memory Loader (MLO) : inisialisasi SoC sehingga bootloader selanjutnya (U-Boot) dapat dijalankan di ekternal DDR RAM (meload U-Boot ke dalam DDR).
- U-Boot : Inisialisasi peripheral seperti I2C, UART, FLASH, ETHERNET dll. U-Boot akan meload linux kernel dari sumber yang dipilih ke dalam DDR RAM.
- Linux Kernel : eksekusi kode di dalam ekternal DDR RAM.
- Root File System : eksekusi kode di dalam ekternal RAM/ eMMC/ SD Card.
Pada edisi awal beaglebone, eMMC / SD Card akan memiliki dua buah partisi, dimana partisi pertama (FAT16/32 – BOOT) akan berisi MLO, u-boot.img and uEnv.txt file, sedangkan partisi kedua (ext3) akan berisi root file system. Pada edisi terbaru, beaglebone hanya akan memiliki 1 buah partisi dimana MLO dan u-boot.img akan terletak di bagian depan dari partisi area. Hal ini dimaksudkan untuk mengurangi resiko pengguna menghapus secara tidak sengaja file file tersebut.
Note: SPL/MLO dihasilkan ketika kita mengkompile U-Boot. Berikut cara mengkompile U-Boot dan mengkopinya ke dalam partisi BOOT SD card.
sudo apt install gcc-arm-linux-gnueabihf
export CROSS_COMPILE=arm-linux-gnueabihf-
git clone git://git.denx.de/u-boot.git
cd u-boot
git checkout v2022.04
make am335x_evm_defconfig
make menuconfig
make
cp MLO u-boot.img /media/madopick/boot
uEnv.txt file berisi setting/setup parameter untuk U-Boot seperti sumber yang digunakan untuk meload linux kernel (uImage). uImage terdiri atas zImage + 64 bytes u-boot header. Apabila kita tidak ingin mengcompile sendiri kernel image, kita bisa mendownload pre-built image yang sudah dilengkapi pula dengan root file system, image ini dapat didownload secara gratis di situs mereka. Pre-built image tadi dapat dikopikan ke dalam SD-Card dengan menggunakan tool balenaEtcher atau win32diskImager. Untuk melakukan boot dari SD-Card, maka ketika power on, tombol S2/Boot button harus ditekan karena secara default, eMMC akan dipilih sebagai sumber utama. Apabila kita bedah pre-built image tersebut, kita dapat menemukan uImage ini di dalam boot folder. Di dalam folder tersebut kita dapat menemukan pula uEnv.txt yang nanti dapat kita gunakan untuk mengupdate eMMC beaglebone dengan SD-Card. Berikut adalah contoh modifikasi dari uEnv.txt file apabila akan digunakan untuk meload uImage dari SD-Card. Direkomendasikan untuk menggunakan UART untuk memonitor boot log message apabila terdapat error selama proses booting.
console=ttyO0,115200n8 ipaddr=192.168.7.2 serverip=192.168.7.1 loadaddr=0x82000000 fdtaddr=0x88000000 loadsd=load mmc 0:2 ${loadaddr} /boot/uImage;load mmc 0:2 ${fdtaddr} /boot/am335x-boneblack.dtb linuxbootargs=setenv bootargs console=${console} root=/dev/mmcblk0p2 rw uenvcmd=setenv autoload no; run loadsd; run linuxbootargs; bootm ${loadaddr} - ${fdtaddr}