Home > skrypty > OpenWrt – bootfromexternalmedia

OpenWrt – bootfromexternalmedia

Grudzień 8th, 2009 Zostaw komentarz Idź do komentarzy

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 .

Kategorie:skrypty Tagi:, , , , ,
  1. Brak komentarzy
  1. Brak jeszcze trackbacków