Program do składania własnych obrazów OpenWrt
Ostatnia zmiana: 2024-04-07 10:11

Imagebuilder jest systemem pozwalającym na złożenie własnego obrazu OpenWrt bazując na liście plików i pakietów wg naszego uznania. W przeciwieństwie do zwykłej kompilacji opisanej w tym poradniku, imagebuilder nie kompiluje już elementów systemu, bazuje na gotowych paczkach które następne w odpowiedni sposób składa w gotowy obraz dla danego urządzenia.

Argumenty za zastosowaniem imagebuildera:
- brak potrzeby kompilacji całego środowiska
- możliwość zbudowana obrazów bazując na innych pakietów, niekoniecznie dostępnych w repozytorium OpenWrt

Argumenty przeciw:
- opieramy się na tym co już powstało
- brak możliwości kompilacji własnych pakietów
- brak możliwości zmiany DTS'ów
- brak możliwości zmiany opcji kompilacji pakietów

Oznacza to także że po prostu używamy gotowych pakietów i nie mamy wpływu czy jakaś dodatkowa opcja włączona przy kompilacji czy nie.

Podobnie jak zwykła kompilacja, do uruchomienia imagebuildera wymagany jest Linuks lub WSL oraz zainstalowanie podstawowych narzędzi do pobierania i niezbędnych do kompilacji, dla Ubuntu/Debiana mogą to być:


    $ sudo apt install build-essential libncurses-dev zlib1g-dev gawk git gettext libssl-dev xsltproc rsync wget unzip python3 python3-distutils


Pobranie imagebuildera

Należy ze strony OpenWrt pobrać pakiet dla wydania które chcemy używać i architektury którą ma nasz router. Załóżmy że chcemy złożyć sobie obraz dla Netgera R6220. Można posłużyć się wyszukiwarką obrazów https://firmware-selector.openwrt.org aby dowiedzieć się, że Netgear R6220 to platforma ramips/mt7621. Chcemy składać obraz na podstawie np. bieżącego wydania stabilnego; mając te dane wchodzimy po kolei do https://downloads.openwrt.org/ , następnie klikamy OpenWrt 23.05.3, katalog ramips, mt7621, na dole strony dostępny jest plik o nazwie openwrt-imagebuilder-23.05.3-ramips-mt7621.Linux-x86_64.tar.xz - należy go pobrać i umieścić gdzieś w linuksie, np. w katalogu domowym. Następnie należy to rozpakować i przejść do tego katalogu:


    $ wget https://downloads.openwrt.org/releases/23.05.3/targets/ramips/mt7621/openwrt-imagebuilder-23.05.3-ramips-mt7621.Linux-x86_64.tar.xz
    $ tar Jxvf openwrt-imagebuilder-*
    $ cd openwrt-imagebuilder-*/

Mamy więc imagebuildera. Wykonujemy (wszystko już robimy będąc w katalogu imagebuilda)


    $ make help

I dostaniemy listę poleceń których możemy użyć. Najbardziej interesują nas zmienne typu PROFILE, PRACKAGES czy FILES, bo to one definiują co składamy i z czego składamy obraz.

Zobaczmy jak nazywa się profil dla naszego urządzenia


    $ make image | grep -i r6220
    netgear_r6220:
        NETGEAR R6220
        SupportedDevices: netgear,r6220 r6220


Nazwa profilu - w tym przykładzie "netgear_r6220" jest kluczowa, bo tak jest identyfikowany model urządzenia.

Budowanie obrazów

Podstawowy obraz

Aby zrobić obraz dla danego urządzenia uruchamiamy make z odpowiednimi argumentami:


    $ make image PROFILE="netgear_r6220"

Po pewnej chwili zależnej od szybkości łącza internetowego i szybkości komputera, w podkatalogu "bin" pojawią się gotowe obrazy. Dla tego przypadku - będą to "gołe" obrazy bez żadnego środowiska graficznego, bo luci nie wchodzi w skład domyślnych pakietów dla routera.

Obraz z dodatkowymi pakietami

Załóżmy że chcemy obraz z LuCI, z językiem polskim. Musimy wiedzieć jak nazywają się te pakiety i po prostu wymienić je na liście, np.


    $ make image PROFILE="netgear_r6220" PACKAGES="luci luci-i18n-base-pl luci-i18n-firewall-pl luci-i18n-opkg-pl"

Można tak zrobić ze wszystkimi pakietami które są w repozytorium OpenWrt; zależności tych pakietów zostaną dodanie automatycznie i nie trzeba ich specjalnie wymieniać na liście.
Ale powiedzmy że chcemy aby w obrazie znalazły się także inne pakiety spoza repozytorium. Ściągamy taki pakiet (musi być dla architektury naszego urządzenia!) oraz wszystkie jego zależności jeżeli nie ma ich w repozytorium OpenWrt i umieszczamy go w katalogu packages, np. dla przykładu mój pakiet od statystyk.


    $ cd packages
    $ wget https://dl.eko.one.pl/openwrt-23.05/packages/mips_24kc/base/ekooneplstat_20150706_all.ipk
    $ cd ..

Koniecznie należy pamiętać o zależnościach bo inaczej nie złoży się obraz. Ponowne złożenie obrazu wraz z dodanym pakietem:


    $ make image PROFILE="netgear_r6220" PACKAGES="luci luci-i18n-base-pl luci-i18n-firewall-pl luci-i18n-opkg-pl ekooneplstat"

Obraz z dodatkowymi plikami

Następny krok - w obrazie chcemy mieć swoje dodatkowe pliki - konfiguracyjne, jakieś dane czy skrypty. Robimy katalog o nazwie np. files:


    $ mkdir -p files

Następnie umieszczamy w nim pliki, skrypty lub katalogi które mają znaleźć się w docelowym obrazie. Cała struktura katalogów zostanie przeniesiona w identyczny sposób, więc np. jeżeli chcemy podmienić plik /etc/banner w obrazie wynikowym na swój, to w katalogu files robimy podkatalog etc a w nim umieszczamy plik banner z własną zawartością:


    $ mkdir -p files/etc
    $ echo ">>>> to dziala!!! <<<<" > files/etc/banner

Jeżeli chcemy dodać skrypt który wykonuje się jeden raz przy uruchomieniu routera (np. wprowadza jakiś ustawienia - poniższy przykład uruchamia wifi przy starcie routera) to należy to zrobić w katalogu etc/uci-defaults, np tak:


    $ mkdir -p files/etc/uci-defaults
    $ chmod 755 files/etc/uci-defaults/01-mojskrypt.sh

    $ echo "#!/bin/sh" > files/etc/uci-defaults/01-mojskrypt.sh
    $ echo "uci del wireless.@wifi-device[0].disabled" >> files/etc/uci-defaults/01-mojskrypt.sh
    $ echo "uci commit" >> files/etc/uci-defaults/01-mojskrypt.sh

Oczywiście nie trzeba tych plików tworzyć ręcznie, można je skopiować już gotowe jeżeli takie mamy. W taki sam sposób możemy umieścić gotową konfigurację umieszczając odpowiednie pliki w files/etc/config.
Jeżeli teraz skompilujemy obraz ze zmienną FILES wskazującą na nasz katalog:


    $ make image PROFILE="netgear_r6220" FILES="files"

To wszystkie pliki z katalogu files znajdą się w obrazie. Oczywiście zmienne można łączyć, więc dla naszego przykładu obrazu z LuCI może to wyglądać tak:


    $ make image PROFILE="netgear_r6220" PACKAGES="luci luci-i18n-base-pl luci-i18n-firewall-pl luci-i18n-opkg-pl ekooneplstat" FILES="files"

Imagebuidler ma jeszcze kilka opcji np. wyłączania serwisów na starcie czy sprawdzania zależności itd, ale do podstawowego zbudowania obrazów wystarczą na razie powyższe opcje.

Firmware selector

Wspomniany imagebuilder wymaga systemu linuksowego do uruchomienia. Jeżeli wystarczają nam pakiety które są w repozytorium OpenWrt to można się posłużyć także witryną OpenWrt Firmware Selector, która służy głównie do pobierania obrazów. Ale jeżeli wybierzemy określony router to pojawi się opcja "Dostosuj zainstalowane pakiety i/lub skrypt pierwszego rozruchu". Jest tam lista domyślnych pakietów dla danego modelu; dodając tam (dodając, nie zastępując!) nazwy pakietów np. "luci luci-i18n-base-pl luci-i18n-firewall-pl luci-i18n-opkg-pl" można wygenerować obraz z dodatkowymi elementami.
Niestety w ten sposób nie można zbudować obrazów z pakietami które nie są standardowo w repozytorium OpenWrt, nie można także dodawać własnych plików czy skryptów poza tym jednym zawartym w etc/uci-defaults który uruchomi się jeden raz przy pierwszym starcie systemu.

Podobny mechanizm uzyskamy używając Attendend sysupgrade, który buduje i pobiera obraz na podstawie zainstalowanych pakietów w routerze (jest możliwość edycji listy pakietów przed budową), pozwalając także na zachowanie bieżącej konfiguracji. Identycznie jak w firmware selectorze automat Attendend sysupgrade nie zbuduje obrazu jeżeli będziemy mieli zainstalowany jakiś pakiet spoza repozytorium OpenWrt.