Table of Contents
Flashing La Fonera
In questa pagina trovate i miei appunti generici per aggiornare le immagini flash (il firmware) e in particolare per installare OpenWrt. Altri documenti migliori di questo:
- Wiki ufficiale di OpenWrt: http://wiki.openwrt.org/toh/fon/fonera
- Istruzioni per compilare OpenWrt: OpenWRTCompile
La Fonera bricked
Si è deciso di installare OpenWrt perché la Fonera si è danneggiata e non si avvia più (in gergo: bricked). Il danno è accaduto installando e poi rimuovendo un pacchetto con ipkg (per la precisione il pacchetto gpsd): si è avuto un segmentation fault e da quel momento la Fonera non si è più riavviata. Dalla console seriale il boot si blocca con questi messaggi:
mini_fo_lookup: ERROR, meta data corruption detected. mini_fo_d_delete: negative dentry passed. mini_fo_d_release: no private data.
Tipi di filesystem
squashfs | Squashfs is a readonly filesystem, OpenWrt boots from this one. |
---|---|
jffs2 | For writable support, OpenWrt creates a jffs2 partition and on bootup swaps to the jffs2 root. |
Un filesystem di tipo JFFS2 generalmente viene montato da un device MTD, per montarlo da un file immagine si può usare questa procedura (Linux kernel 2.6):
# Associate a loop device with the regular file: modprobe loop; sleep 1 losetup /dev/loop0 /path/mtdblock2.jffs2 # Load the MTD support and the emulation using a block device: modprobe mtdblock modprobe block2mtd block2mtd=/dev/loop0,256; sleep 1 # Load the filesystem support and mount it: modprobe jffs2 mount -t jffs2 /dev/mtdblock0 /mnt
I was unable to mount the jffs image (rootfs1) downloaded from the Fonera, may be for an endianess problem? Check the jffs2dump
command with a syntax like this:
jffs2dump -l -c -e <rootfs.jffs2.be> <rootfs.jffs2>
Magic bitmask is backwards at offset 0x00560000. Wrong endian filesystem?
The following code will undo the previous setup:
umount /mnt modprobe -r jffs2 modprobe -r block2mtd modprobe -r mtdblock losetup --detach /dev/loop0 modprobe -r loop
Backup delle immagini flash
Se la Fonera non è bricked ed è accessibile via ssh, possiamo fare una copia delle immagini flash esistenti:
root@OpenWrt:~# cat /proc/mtd dev: size erasesize name mtd0: 00030000 00010000 "RedBoot" mtd1: 006f0000 00010000 "rootfs" mtd2: 00570000 00010000 "rootfs1" mtd3: 00010000 00010000 "config" mtd4: 000b0000 00010000 "vmlinux.bin.l7" mtd5: 0000f000 00010000 "FIS directory" mtd6: 00001000 00010000 "RedBoot config" mtd7: 00010000 00010000 "board_config"
Questo il contenuto di ciascuna immagine:
RedBoot | mtd0 | |
---|---|---|
rootfs | mtd1 | Root filesystem di tipo squashfs (read-only, per failsafe boot?) (versione 0.7.1-1) |
rootfs1 | mtd2 | Immagine principale del root filesystem, tipo jffs2 (versione 0.7.1-3) |
config | mtd3 | |
vmlinux.bin.l7 | mtd4 | Immagine del kernel Linux |
FIS directory | mtd5 | |
RedBoot config | mtd6 | Configurazione del boot manager RedBoot |
board_config | mtd7 |
Non si capisce bene il significato di rootfs
e rootfs1
. Dal prompt RedBoot
è visibile solo un blocco di nome rootfs
, che è quello che viene sovrascritto con l'immagine ufficiale squashfs durante l'operazione di flash.
Con questo comando lanciato dal PC possiamo salvare sul PC stesso un file con l'immagine che contiene il kernel:
ssh root@169.254.255.1 'dd if=/dev/mtdblock/4' > mtdblock4
L'immagine del rootfs1 (mtd2) ottenuta in questo modo non è adatta ad essere flashata come descritto in seguito! Con il seguente metodo si ottiene un file di 5.5M (di tipo data), mentre l'immagine rootfs distribuita da Fon è un file di 1.5M (di tipo Squashfs filesystem).
Flash di un'immagine ufficiale Fon
Questa procedura è stata sperimentata flashando un'immagine rootfs originale Fon (versione fonera_0.7.1.3.fon), per recuperare una Fonera bricked. Abbiamo flashato due file sulla Fonera: rootfs.squashfs e kernel.lzma
Il flashing è stato fatto operando dal prompt di RedBoot
. In teoria dovrebbe essere possibile riscrivere la flash anche da riga di comando utilizzando il comando write
di mtd
, ma noi non ci siamo riusciti! Abbiamo riscritto sia l'mtd device rootfs
che rootfs1
: al reboot successivo abbiamo ritrovato la Fonera con il vecchio rootfs.
Iniziamo con rootfs.squashfs, si tratta di un Squashfs filesystem. Avviare La Fonera controllandola via seriale, interrompere la sequenza ed entrare al prompt RedBoot:
+PHY ID is 0022:5521 Ethernet eth0: MAC address 00:18:84:1e:61:98 IP: 169.254.255.1/255.255.0.0, Gateway: 0.0.0.0 Default server: 169.254.255.46 RedBoot(tm) bootstrap and debug environment [ROMRAM] Non-certified release, version v1.3.0 - built 16:57:58, Aug 7 2006 Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. Board: ap51 RAM: 0x80000000-0x81000000, [0x80040450-0x80fe1000] available FLASH: 0xa8000000 - 0xa87f0000, 128 blocks of 0x00010000 bytes each. == Executing boot script in 10.000 seconds - enter ^C to abort ^C RedBoot>
Controlliamo le immagini presenti nella memoria flash (Fonera originale, versione 0.7.1-3):
RedBoot> fis list Name FLASH addr Mem addr Length Entry point RedBoot 0xA8000000 0xA8000000 0x00030000 0x00000000 rootfs 0xA8030000 0xA8030000 0x00700000 0x00000000 vmlinux.bin.l7 0xA8730000 0x80041000 0x000B0000 0x80041000 FIS directory 0xA87E0000 0xA87E0000 0x0000F000 0x00000000 RedBoot config 0xA87EF000 0xA87EF000 0x00001000 0x00000000
Se RedBoot non avesse già assegnato un indirizzo IP alla Ethernet lo si fa adesso, qui lo facciamo solo a scopo didattico, perché l'indirizzo è stato già assegnato come si vede dall'output sopra. Si carica quindi in RAM l'immagine del nuovo rootfs tramite protocollo tftp (bisogna configurare un PC con tftpd e condividere il file immagine):
RedBoot> ip_address -l 169.254.255.1/16 -h 169.254.255.46 IP: 169.254.255.1/255.255.0.0, Gateway: 0.0.0.0 Default server: 169.254.255.46 RedBoot> load -r -b %{FREEMEMLO} -m tftp -h 169.254.255.46 rootfs.squashfs Raw file loaded 0x80040800-0x801c07ff, assumed entry at 0x80040800
I parametri specificati al comando load
sono:
-r | Indica che il file è raw data. |
---|---|
-b | Indirizzo in RAM a cui caricare il file. Si usa un alias che rappresenta l'inizio della RAM libera. |
Quindi si crea l'immagine nella memoria flash:
RedBoot> fis create rootfs -e 0 An image named 'rootfs' exists - continue (y/n)? y ... Erase from 0xa8030000-0xa8730000: .......................................... ... Program from 0x80040800-0x801c0800 at 0xa8030000: ........................ ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
Non abbiamo specificato né l'indirizzo di origine della memoria RAM (parametro -b) né l'indirizzo destinazione nella memoria flash (parametro -f) dei dati da scrivere. Come valori predefiniti sono stati presi rispettivamente l'indirizzo dell'ultimo file caricato (0x80040800) e l'indirizzo dell'immagine rootfs esistente (0xA8030000). È stato dato il parametro -e 0, perché per l'immagine rootfs non ha senso specificare un entry point. Vedere eventualmente la documentazione di RedBoot.
Controlliamo nuovamente le immagini esistenti:
RedBoot> fis list Name FLASH addr Mem addr Length Entry point RedBoot 0xA8000000 0xA8000000 0x00030000 0x00000000 rootfs 0xA8030000 0x80040800 0x00700000 0x00000000 vmlinux.bin.l7 0xA8730000 0x80041000 0x000B0000 0x80041000 FIS directory 0xA87E0000 0xA87E0000 0x0000F000 0x00000000 RedBoot config 0xA87EF000 0xA87EF000 0x00001000 0x00000000
Si esegue operazione analoga per caricare l'immagine del kernel kernel.lzma:
RedBoot> load -r -v -b 0x80041000 -m tftp -h 169.254.255.46 kernel.lzma Raw file loaded 0x80041000-0x800c0fff, assumed entry at 0x80041000 RedBoot> fis create -r 0x80041000 -e 0x80041000 vmlinux.bin.l7 An image named 'vmlinux.bin.l7' exists - continue (y/n)? y ... Erase from 0xa8730000-0xa87e0000: ........... ... Program from 0x80041000-0x800c1000 at 0xa8730000: ........ ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
In questo caso si è indicato il base address per il caricamento in ram (-b). Nel creare la nuova immagine si è indicato l'indirizzo di rilocazione (-r) e l'entry point (-e) rispettando lo schema originale.
Per riavviare:
RedBoot> reset
OpenWrt
Sulla Fonera si possono installare due versioni di OpenWrt: Kamikaze e Backfire, occorre il build per Atheros:
Compilazione
ATTENZIONE: Operazione da fare solo in casi particolari, la distribuzione binaria precompilata va più che bene.
OpenWrt Download
In una directory dedicata, si scarica da SVN il trunk di OpenWrt e tutti i pacchetti extra disponibili:
svn co https://svn.openwrt.org/openwrt/trunk/ svn co https://svn.openwrt.org/openwrt/packages
La compilazione di OpenWrt cerca i pacchetti nella directory trunk/package, quindi si creano dei link simbolici alle directory dei pacchetti extra:
cd trunk/package ln -sv ../../packages/*/* . cd ../..
OpenWrt Configure
cd trunk make menuconfig
Target System (Atheros [2.6]) ---> Base System ---> <*> busybox Configuration ---> Networking Utilities ---> [*] arp [*] ether-wake [*] hostname Network ---> <*> vtun <*> wget <*> wol <*> wpa-supplicant <*> wpa-cli ... ...
La configurazione viene salvata nel file .config.
OpenWrt Compile
cd trunk make
Al termine della compilazione le immagini e i pacchetti *.ipk si trovano nella directory trunk/bin.
L'immagine del root filesystem viene create in alcune varianti:
squashfs | The firmwares with squashfs in the filename use a combination of a readonly squashfs partition and a writable jffs2 partition. This gives you a /rom with all the files that shipped with the firmware and a writable root containing symlinks to /rom. This is considered the standard install. |
---|---|
jffs2 | The firmwares with jffs2 in the name are jffs2 only; all of the files are fully writable. |
64k, 128k, … | Most 4M flash chips use a block size of 64k while most 8M chips tend to use a 128k block size. The jffs2 partition needs to be formatted for the correct block size. |
Flash dell'immagine OpenWrt Backfire
Qui le istruzioni ufficiali: http://wiki.openwrt.org/toh/fon/fonera.
Scaricati i file openwrt-atheros-vmlinux.lzma e openwrt-atheros-root.squashfs dal repository e resi disponibili sul server tftp all'indirizzo IP 169.254.255.46.
Avviata La Fonera e raggiunto il prompt RedBoot dalla console seriale, con fis list
si possono vedere le immagini caricate in flash:
RedBoot> fis list Name FLASH addr Mem addr Length Entry point RedBoot 0xA8000000 0xA8000000 0x00030000 0x00000000 rootfs 0xA8030000 0xA8030000 0x00700000 0x00000000 vmlinux.bin.l7 0xA8730000 0x80041000 0x000B0000 0x80041000 FIS directory 0xA87E0000 0xA87E0000 0x0000F000 0x00000000 RedBoot config 0xA87EF000 0xA87EF000 0x00001000 0x00000000
Si carica in RAM l'immagine del kernel via tftp, quindi si copia in flash memory specificando a che indirizzo dovrà essere caricata in RAM (-r) e specificando anche l'entry point (-e) a cui iniziare l'esecuzione (si mantengono gli stessi valori del kernel Fon):
RedBoot> ip_address -h 169.254.255.46 -l 169.254.255.1/24 IP: 169.254.255.1/255.255.255.0, Gateway: 0.0.0.0 Default server: 169.254.255.46 RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma Using default protocol (TFTP) Raw file loaded 0x80040800-0x801207ff, assumed entry at 0x80040800 RedBoot> fis init About to initialize [format] FLASH image system - continue (y/n)? y *** Initialize FLASH Image System ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: . RedBoot> fis create -e 0x80041000 -r 0x80041000 vmlinux.bin.l7 ... Erase from 0xa8030000-0xa8110000: .............. ... Program from 0x80040800-0x80120800 at 0xa8030000: .............. ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
Si carica in RAM via ftp l'immagine del root filesystem (nella posizione più bassa della RAM, variabile FREEMEMLO) e si copia in flash alla prima posizione libera:
RedBoot> load -r -b %{FREEMEMLO} openwrt-atheros-root.squashfs Using default protocol (TFTP) Raw file loaded 0x80040800-0x802207ff, assumed entry at 0x80040800 RedBoot> fis create rootfs ... Erase from 0xa8110000-0xa82f0000: .............................. ... Program from 0x80040800-0x80220800 at 0xa8110000: .............................. ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
Si verifica la configurazione di boot, per sicurezza la si riscrive:
RedBoot> fconfig -l -n boot_script: true boot_script_data: .. fis load -l vmlinux.bin.l7 .. exec boot_script_timeout: 1 bootp: false bootp_my_gateway_ip: 0.0.0.0 bootp_my_ip: 0.0.0.0 bootp_my_ip_mask: 255.255.255.255 bootp_server_ip: 0.0.0.0 console_baud_rate: 9600 gdb_port: 9000 info_console_force: false net_debug: false RedBoot> fconfig boot_script_data boot_script_data: .. fis load -l vmlinux.bin.l7 .. exec Enter script, terminate with empty line >> fis load -l vmlinux.bin.l7 >> exec >> Update RedBoot non-volatile configuration - continue (y/n)? y ... Erase from 0xa87e0000-0xa87f0000: . ... Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
Infine si riavvia:
RedBoot> reset
OpenWrt Backfire installa l'interfaccia web LuCI e un telenet con accesso root senza password, l'indirizzo di rete predefinito è 192.168.1.1. Una volta impostata una password per l'utente root il telenet viene disabilitato e al suo posto viene abilitato l'ssh.
Configurare OpenWrt
/etc/config/network
Configurazione Ethernet via DHCP:
config interface wan option ifname eth0.1 option proto dhcp option hostname MyRouter
Configurazione Ethernet statica:
config interface lan option ifname eth0.0 option proto static option ipaddr 192.168.1.2 option netmask 255.255.255.0 option gateway 192.168.1.1 option dns 192.168.1.1
Dopo aver modificato la configurazione dovrebbe bastare dare il comando:
/sbin/ifup lan
/etc/config/wireless
Per attivare l'interfaccia wireless bisogna mettere nel file di configurazione due sezioni. Una sezione wifi-device con la configurazione della radio, il cui risultato è l'attivazione dell'interfaccia wifi0. Una seconda sezione di nome wifi-iface con la configurazione dell'interfaccia di rete vera e propria (quella effettivamente usata con il TCP/IP ecc.), il cui risultato è l'attivazione dell'interfaccia ath0:
config wifi-device wifi0 option type atheros option channel 5 # option diversity 1 # option txantenna 0 # option rxantenna 0 # option distance 2000 # disable radio to prevent an open ap after reflashing: option disabled 0 config wifi-iface option device wifi0 option network lan # Mode is "ap" (master access point), "sta" (station, managed client): option mode sta option ssid OpenWrt option hidden 0 # option txpower 15 # option bgscan enable option encryption none
Un esempio per associarsi come client ad un access point con crittografia wep:
config wifi-iface option device wifi0 option network wan option mode sta option ssid MyEssid option encryption wep option key 's:supersecret01'
Per creare una nuova interfaccia wireless ath1 (ovviamente basata sullo stesso hardware wifi0) si aggiunge un'altra sezione config wifi-iface. Non è possibile avere due interfacce contemporaneamente in modalità managed.
Un altro comando per creare interfacce wlan:
wlanconfig ath1 create wlandev wifi0 wlanmode monitor
Per applicare la nuova configurazione wireless:
/sbin/wifi down /sbin/wifi up
/etc/init.d/
Per avviare e formare i servizi ci sono gli script in /etc/init.d/
. Oltre ai classici start e stop dovrebbero essere supportate anche le opzioni enable e disable per abilitare o meno l'avvio automatico del servizio al bootstrap.
Attivare un servizio al bootstrap generalmente significa creare l'opportuno link simbolico in /etc/rc.d/
.
/etc/config/firewall e /etc/firewall.user
Nel file /etc/config/firewall
si scrive la configurazione con una sintassi semplificata, ad esempio:
accept:proto=tcp dport=22
Altre istruzioni iptables vanno invece in /etc/firewall.user
. Rispetto ad una configurazione vanilla si può approfittare di alcune catene predefinite:
- input_rule
- input_wan
- output_rule
- forwarding_rule
- forwarding_wan
- NEW
- prerouting_rule
- prerouting_wan
- postrouting_rule
Come configurazione predefinita vengono accettate tutte le connessioni RELATED, ESTABLISHED e il traffico icmp. Vedere per maggiori dettagli /etc/init.d/firewall
.
## Allow full forwarding iptables -A forwarding_rule -i eth0 -o ath0 -j ACCEPT ## Allow masquerading iptables -t nat -A postrouting_rule -s 192.168.1.0/24 -o ath0 -j MASQUERADE