OpenWrt – bootfromexternalmedia
Dużym problemem na routerach z OpenWrt jest ograniczona ilość pamięci, na szczęście dzięki sdmod tudzież usbstorage – możemy łatwo tą pamięć rozszerzyć. To co pozostało, to umożliwienie instalacji pakietów na zewnętrznym nośniku. Można to osiągnąć przy pomocy funkcjonalności opkg, lecz same pakiety są często niedostosowane do instalacji w innych lokalizacjach niż / (root). Dlatego najprostszym wyjściem jest przeniesienie całego „/” na zewnętrzny nośnik.
Instrukcję do przeprowadzenia tej operacji można znaleźć na openwrt wiki.
Znajdują się tam pliku konfiguracyjne, które do mojej wersji trzeba zmodyfikować – parametr enabled jest teraz liczbą, nie stringiem (zamieniamy „option enabled ’1′” na „option enabled 1″).
0. Tworzenie pliku konfiguracyjnego
konfiguracje umieszczamy w /etc/config/bootfromexternalmedia
Przykładowy config dla dir-320, dla pendrive’a podpiętego pod USB
config bootfromexternalmedia option target '/mnt/sda1' option device '/dev/sda1' option modules 'scsi_mod usbcore jbd ext3 sd_mod ehci-hcd ohci-hcd usb-storage' option sleep 5 option enabled 1
Nową opcją (w stosunku do pierwotnej wersji skryptu) jest sleep która specyfikuje liczbę sekund którą należy odczekać po załadowaniu modułów (konieczne dla nośników podpinanych pod usb).
1. Formatowanie i montowanie
Należy szczególną uwagę zwrócić na nazwę urządzenia (u mnie /dev/sda1), zależy ona od wielu czynników.
ipkg install e2fsprogs mkfs.ext3 /dev/sda1 # samo formatowanie polecam przeprowadzić na innym systemie, by nie zajmować miejsca na routerze ipkg install kmod-fs-ext3 mount -t ext3 /dev/sda1 /mnt/
2. Kopiowanie plików na nowy root
mkdir -p /tmp/root mount -o bind /rom /tmp/root cp /tmp/root/* /mnt -a sync umount /tmp/root umount /mnt
3. Zainstalowanie nowego skryptu init
(/sbin/init, to domyślnie symlink do busybox)
Należy go nadpisać nowym skryptem i zmienić prawa dostępu.
rm -f /sbin/init wget http://kyberian.jumpingcrab.com/hg/openwrt_custom/raw-file/tip/external_boot.sh -O -|tr '\r' ' ' > /sbin/init chmod a+x /sbin/init
Po restarcie jeśli wszystko zostało poprawnie skonfigurowane w pliku /etc/config/bootfromexternalmedia zostanie uruchomiony router już z nowym /
Skrypt przewiduje sytuacje „awaryjne”:
- brak pliku konfiguracyjnego lub enabled ustawione na 0 (lub tez brak tej linii) [skrypt przed moją modyfikacją zdawał się te warunki niepoprawnie sprawdzać]
- nie udało się przejść na zewnętrzny nośnik
w obu sytuacjach odpala defaultowy init.
Podejście tu przedstawione umożliwia konfiguracje niezależną dla routera z i bez zewnętrznego nośnika. Dla innych rozwiązań polecam zajrzeć na openwrt wiki.
Udostępniam moją zmodyfikowaną wersję skryptu (wraz z odnośnikami do wersji oryginalnych).
#!/bin/sh
#
# External boot script, for original please refer to:
# http://nuwiki.openwrt.org/oldwiki/openwrtdocs/kamikazeconfiguration/packagesonexternalmediahowto
# https://forum.openwrt.org/viewtopic.php?id=22298
#
# Note: Some cosmetic changes, also config parametr "enabled" is handled properly
# config must be changed! from "option enabled '1'" to "option enabled 1"
# also "sleep" was added (wait time after insmod - needed for usbstorage)
log(){
echo "EXTERNAL BOOT: $*"
}
run_init(){
log "Run busybox init"
exec /bin/busybox init
}
. /etc/functions.sh
boot_config(){
local cfg="$1"
local "target" "device" "gpiomask" "modules" "sleep" "enabled" "oldroot"
config_get "target" "$cfg" "target"
config_get "device" "$cfg" "device"
config_get "gpiomask" "$cfg" "gpiomask"
config_get "modules" "$cfg" "modules"
config_get "sleep" "$cfg" "sleep"
config_get "enabled" "$cfg" "enabled"
config_get "oldroot" "$cfg" "oldroot" "/mnt/oldroot"
[ 1 == "$enabled" ] && {
[ -z "$target" -o -z "$device" ] && {
log "Undefined device or mount point"
run_init
}
[ -n "$gpiomask" ] && {
log "Appling gpiomask $gpiomask"
echo "$gpiomask" > /proc/diag/gpiomask
}
log "Loading modules: $modules"
for module in $modules; do
insmod $module
done
[ "$sleep" -gt 0 ] && {
log "Waiting for $sleep seconds"
sleep $sleep
}
for i in `seq 1 5`; do
log "Mount: $device on: $target (try $i)"
if mount -o rw "$device" $target; then
break
else
log "FAILED to mount $device"
sleep 1
fi
done
[ -x $target/sbin/init ] && {
log "Run firstboot"
. $target/sbin/firstboot
log "Pivot Root"
#$target/sbin/pivot_root $target $oldroot
#call func pivot from firstboot
mkdir -p $target$oldroot
pivot $target $oldroot
}
run_init
}
[ 1 != "$enabled" ] && log " DISABLED! "
}
config_load bootfromexternalmedia
[ "$?" != "0" ] && log "Failed to load config"
config_foreach boot_config bootfromexternalmedia
run_init
Dla najnowszej wersji mojej modyfikacji zapraszam do mojego repozytorium .