This commit is contained in:
blat 2024-12-01 19:31:52 +01:00
commit f713b9f5c9
18 changed files with 657 additions and 0 deletions

27
README.md Normal file
View file

@ -0,0 +1,27 @@
Slides del talk *Puzzle DTS. Racconto di un ciappino su un router* presentato ad [Hack or Di(y|e) 2024](https://hacklabbo.indivia.net/hackordiye24/).
### Descrizione
Come aggiungere in openwrt il supporto per un router simile ad uno già supportato?
In questo talk, rivolto soprattutto a chi ha già un po' visto openwrt,
e talvolta gli capita tra le mani un router che gli farebbe comodo se ci girasse sopra,
ma non è nella lista dei dispositivi supportati.
Vediamo un po' di capire quando/quanto potrebbe valerne la sbatta.
Parliamo delle tecnologie utilizzate per produrre e testare il firmware,
e proviamo a tracciare una lista di step che possono semplificare la risoluzione di questo puzzle.
Prendiamo poi come falsariga i pochi files editati per aggiungere il supporto
ad un router 'facile' - perché ce ne sono tanti di simili già supportati - con SoC MediaTek MT7621AT
per dare uno sguardo al processo di mappatura dell'hardware,
di quali references tenere sotto mano e di come far funzionare le componenti principali.
Infine vediamo quello che volendo si potrebbe ancora fare sul router in oggetto
allo scopo di migliorarne il supporto, per fare due chiacchere in più su altre tecnologie coinvolte.
### Riferimenti
Una lista di riferimenti è in fondo alle slides.
Link al commit di aggiunta del supporto, per vedere i files modificati:
https://git.openwrt.org/?p=openwrt/openwrt.git;a=commit;h=e80b596c58b361c76491b4ec1bd8865d2ccefe7e

BIN
images/gitweb_search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
images/ide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
images/openwrt-project.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
images/openwrt.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 KiB

BIN
images/openwrt_github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

BIN
images/uart_aghi.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

28
papera_hod_2024 Normal file
View file

@ -0,0 +1,28 @@
titolo: |
Puzzle DTS
Racconto di un ciappino su un router
descrizione: |
Come aggiungere in openwrt il supporto per un router simile ad uno già supportato?
In questo talk, rivolto soprattutto a chi ha già un po' visto openwrt,
e talvolta gli capita tra le mani un router che gli farebbe comodo se ci girasse sopra,
ma non è nella lista dei dispositivi supportati.
Vediamo un po' di capire quando/quanto potrebbe valerne la sbatta.
Parliamo delle tecnologie utilizzate per produrre e testare il firmware,
e proviamo a tracciare una lista di step che possono semplificare la risoluzione di questo puzzle.
Prendiamo poi come falsariga i pochi files editati per aggiungere il supporto
ad un router 'facile' - perché ce ne sono tanti di simili già supportati - con SOC MediaTek MT7621AT
per dare uno sguardo al processo di mappatura dell'hardware,
di quali references tenere sotto mano e di come far funzionare le componenti principali.
Infine vediamo quello che volendo si potrebbe ancora fare sul router in oggetto
allo scopo di migliorarne il supporto, per fare due chiacchere in più su altre tecnologie coinvolte.
nick: gothos
durata: [45min, 1h]
proiettore: si
registrazione: ['ok audio', 'ok video']
preferenze_giorni_orario: ['venerdì sera', 'sabato primo pomeriggio']

5
run Executable file
View file

@ -0,0 +1,5 @@
#!/bin/sh
docker run -it -p 8080:8080 \
-v $(pwd)/slides:/app/slides \
-v $(pwd)/images:/app/slides/images msoedov/hacker-slides

597
slides/index.md Normal file
View file

@ -0,0 +1,597 @@
##### Racconto di un ciappino su un router
# Puzzle DTS
Come aggiungere il supporto per openwrt ad un dispositivo simile ad uno già supportato?
<!-- .slide: data-transition="zoom" -->
---
## Premesse
Perché questo talk:
- ninux - http://ninux.org
- antennine - https://antennine.noblogs.org
- libremesh - https://libremesh.org
- battlemesh - https://battlemesh.org/BattleMeshV15
- hacklabbo https://hacklabbo.indivia.net
--
Un paio di considerazioni sul perché potrebbe interessarvi questo talk se anche in genere non vi interessa molto l'argomento networking
--
#### 1. L'interesse per i router potrebbe non essere solo relativo al networking
<small>
Iniziano a vedersi in giro più spesso router che a livello di prestazioni assomigliano quasi
a dei raspberry
Iniziano ad essere dei cosini che qualche sito statico te lo tengono, o varie, in genere li tieni già accesi 24/7/52 e consumano poco (in genere tra i 6 e i 24W)
Per dare un'idea cito il caso di openwrt, che dalla versione 19 (2019)
ha smesso di supportare router con meno di 64MB di RAM, e in seguito ha iniziato a consigliare un minimo di 128MB
</small>
--
#### 2. Dal momento che parliamo di dispositivi embedded
<small>
Cito l'HoD dell'anno scorso che c'è stato un talk interessante sulla storia dell'oggetto furbofono
Nella discussione mi pare si diceva come tra le alternative belle che ci sono una cosa che manca ancora è un framework comune di applicazioni,
per cui vai ad apprezzare magari di più un lineageos o cyanogen che comunque è un android,
piuttosto che un postmarketos che non ha le app android.
</small>
---
## Due parole su OpenWrt
![openwrt](/images/openwrt.jpeg)
--
### Wiki
![openwrt-project](/images/openwrt-project.png)
--
### Forum
![openwrt-forum](/images/openwrt_discourse.png)
--
### Gitweb
![openwrt-gitweb](/images/openwrt_git_summary.png)
--
### Github
![openwrt-github](/images/openwrt_github.png)
--
### Downloads Server
![openwrt-downloads](/images/openwrt_downloads.png)
--
### Elementi che si incontrano in openwrt:
giusto per citarne alcuni
- UCI/LUCI: Unified Configuration Interface - tutto in '/etc/config/'
- il thema di default di luci può non piacere ma si può cambiare
- varie: uci-defaults, rc; iptables-nftables, iw, ubus
--
- LUCI: dopo una modifica cliccando su 'unsaved changes' vedi a che comandi UCI corrispondono le modifiche.
![openwrt](/images/openwrt-luci-unsaved-changes.png)
--
### Elementi in openwrt:
- memorie flash comuni:
- NOR più piccole, fino a 128MB:
- si spaccano dopo 100K-1G cancellazioni
- NAND, più economiche, più grandi fino al GB e oltre:
- MLC si spaccano dopo 1K-10K cancellazioni, pure il processo di lettura potrebbe romperle
- SLC si spaccano dopo 100K-1G cancellazioni
--
- alcuni router le hanno entrambe e solitamente nella NOR ci vanno bootloader e partizioni con dati che non devono essere persi (*pubblicità openwrt ONE)
- se il router ha il buco USB esiste ext-root
---
## Altri talks e informazioni utili:
Lista di riferimenti completa a fine slide
- La ***wiki di openwrt***
- il ***forum di openwrt*** è pieno di informazioni e di persone che hanno documentato le prove che hanno fatto
- ***Device Tree for Dummies! - Thomas Petazzoni, Free Electrons*** (video)
- ***hacking-gemtek*** repo su github, lo stesso autore ha fatto una serie di video, utili perché è un po' come guardarsi il disassembly prima di aprire il router
---
## Racconto
-
### Prima di cominciare
Mi chiedo almeno queste cose:
- se avrebbe senso e per quanto
- fattibilità
- livello di sbatta
--
#### 1. se avrebbe senso e per quanto
- è supportato il System on Chip? andrebbe il WiFi?
- cerco il documento FCCID
- cerco su uno dei wikidevi
- quanto va il processore? ~800MHz
- quanta ram? 128MB
- quanta flash c'ha? 128MB
- se faccio il porting per quanto tempo potrebbe rimanere supportato in openwrt?
--
![uart-aghi](/images/uart_aghi.jpg)
--
Se posso evito di saldare la uart:
C'è l'imbiancatura di stagno?
- si -> aghi
- no -> pins pigiati con lo scotch
--
#### 2 fattibilità
- accedo alla uart?
- accedo al bootloader (uboot)?
- riesco a caricargli sopra le immagini initramfs** e fare dei test?
** https://www.kernel.org/doc/html/latest/filesystems/ramfs-rootfs-initramfs.html
--
Quest ultimo detto in altre parole:
Per **installare** seguiamo in genere questo processo
```
dal mio PC -> alla sua RAM -> alla sua FLASH
```
Per **testare** facciamo solo i primi due
```
dal mio PC -> alla sua RAM
```
--
#### 3 livello di sbatta
- ho accesso root al dispositivo?
- riesco a leggere i log del boot del firmware originale?
- riesco a backuppare tutto prima di testare cose?
---
## Backuppo tutto
--
https://openwrt.org/docs/techref/flash.layout
NOR
![openwrt-flash-layout-nor](/images/openwrt-flash-layout-nor.png)
--
https://openwrt.org/docs/techref/flash.layout
NAND
![openwrt-flash-layout-nand](/images/openwrt-flash-layout-nand.png)
--
In questo caso è possibile e comodo usare il webserver da firmware originale
- gli MTDs
```
cat /proc/mtd
dd if=/dev/mtd7 of=/tmp/eeprom_mtd7.bin
```
- i dati di calibrazione delle radio:
copio anche quelli generici di cui trovo una copia nel dispositivo
--
- se non fosse stato possibile copiare gli mtd
con il firmware originale lo si sarebbe potuto fare da openwrt, caricando una prima initramfs che faccia almeno il boot e parli ad es. via ethernet
- in questo caso (guida hacking-gemtek) backup completo della flash pagina per pagina in ascii (11 ore), ricomposizione e poi estrazione del filesystem
- binwalk, firmware-mod-kit
---
## inizio a definire il dispositivo
--
### documenti utili
- datasheet mediatek mt7621
- programming guide mt7621
- copia del kernel o documentazione online
- un IDE per la ricerca nel clone di openwrt nelle cartelle (elenco le più ricercate in questo caso)
- target/linux
- target/linux/ramips/
- target/linux/ramips/image/
- target/linux/ramips/dts/
- target/linux/ramips/mt7621/
--
- mi collego via seriale e copio i log del boot se non li trovo in rete
- cerco se un wikidevi ha già informazioni sull hardware se no fotografo questo
- guardo come sono definiti altri dispositivi simili,
quali pacchetti per il wireless, o altri driver particolari
--
Esempio di definizione
in `target/linux/ramips/image/mt7621.mk`
```
define Device/gemtek_wvrtm-1xxacn
$(Device/nand)
$(Device/uimage-lzma-loader)
IMAGE_SIZE := 122368k
DEVICE_VENDOR := Gemtek
DEVICE_PACKAGES := kmod-gpio-nxp-74hc164 kmod-spi-gpio \
kmod-usb3 -uboot-envtools
endef
define Device/gemtek_wvrtm-127acn
$(Device/gemtek_wvrtm-1xxacn)
DEVICE_MODEL := WVRTM-127ACN
DEVICE_PACKAGES += kmod-mt7603 kmod-mt76x2
endef
TARGET_DEVICES += gemtek_wvrtm-127acn
define Device/gemtek_wvrtm-130acn
$(Device/gemtek_wvrtm-1xxacn)
DEVICE_MODEL := WVRTM-130ACN
DEVICE_PACKAGES += kmod-mt7615-firmware
endef
TARGET_DEVICES += gemtek_wvrtm-130acn
```
--
Definizione del device di default
in `target/linux/ramips/image/Makefile`
```
define Device/Default
PROFILES = Default
BLOCKSIZE := 64k
KERNEL := $(KERNEL_DTB) | uImage lzma
KERNEL_LOADADDR := $(loadaddr-y)
LZMA_TEXT_START := 0x81800000
SOC := $(DEFAULT_SOC)
DEVICE_DTS_DIR := ../dts
DEVICE_DTS = $$(SOC)_$(1)
NETGEAR_ENC_MODEL :=
NETGEAR_ENC_REGION :=
NETGEAR_ENC_HW_ID_LIST :=
NETGEAR_ENC_MODEL_LIST :=
IMAGES := sysupgrade.bin
COMPILE :=
sysupgrade_bin := append-kernel | append-rootfs | pad-rootfs
IMAGE/sysupgrade.bin := append-kernel | append-rootfs | pad-rootfs | check-size | append-metadata
endef
```
--
- negli MTD backuppati, mi cerco i macaddress, confrontando l'etichetta sul dispositivo
- faccio una prima definizione minimale
in cui imposto almeno
- le partizioni della eeprom e l'image_size
- i driver necessari per la radio
- possibilmente i macaddress e la calibrazione delle radio
- uno schema per le porte ethernet o lascio il default
---
## Device Tree
- .dtb - File name suffix for compiled devicetree.
- .dts - File name suffix for devicetree source.
- .dtsi - File name suffix for devicetree source to be included by a .dts or .dtsi file.
--
Dal Device/Default vedevamo
```
KERNEL := $(KERNEL_DTB) | uImage lzma
```
--
### device tree
Una struttura ad albero, organizzata per nodi, che fornisce al kernel una descrzione dell'hardware
Realizzata con un 'linguaggio di template'
che permette di inclusioni di file o di parziali.
È possibile definire ancore 'phandle' e modificare o ampliare i nodi tramite queste.
--
### device tree
i nodi sono caratterizzati da delle 'compatible' strings
ognuna di queste servirà da riferimento per l'esecuzione di un modulo del kernel se questo è installato, che andrà a leggere e utilizzare le informazioni contenute nel nodo
--
### device tree
Questa è la parte del processo che più di tutte somiglia ad un puzzle
Perché confronteremo ogni riga con dispositivi simili
Usando l'ide, gitweb e github per trovare informazioni e discussioni sui vari nodi e le loro proprietà
--
### Device Tree: Esempi
<em>https://github.com/openwrt/openwrt/pull/16074#issuecomment-2272124140</em>
<em>
Code like:
```
&state_default {
gpio {
groups = "i2c", "uartf", "ephy", "rgmii2";
function = "gpio";
};
};
```
define which outputs are to be switched to GPIO type outputs.
This is necessary if you control something with these outputs, e.g. LEDs, buttons, other chips etc.
</em>
---
## setup di buildroot
![openwrt-menuconfig](/images/openwrt-menuconfig.png)
--
### setup di buildroot
#### immagine
con initramfs
```
CONFIG_TARGET_ROOTFS_INITRAMFS=y
```
#### pacchetti
mi aggiungo alcuni pacchetti di utilities di default
lspci, diffutils, libgpiod (o gpioctl-sysfs)
```
CONFIG_PACKAGE_libgpiod=y
CONFIG_PACKAGE_gpiod-tools=y
CONFIG_PACKAGE_diffutils=y
CONFIG_PACKAGE_pciutils=y
```
--
### setup di buildroot
Se voglio modificare delle configurazioni senza stare ad aprire il menuconfig
posso fare così
```
echo '# CONFIG_PACKAGE_disabilitato is not set' >> .config
echo '# CONFIG_PACKAGE_abilitato=y' >> .config
```
e poi applicare con
```
make defconfig
```
--
### setup di buildroot
### files
Creo la cartella <openwrt-buildroot>/files
e gli scripts sulla reference di openwrt per le gpio e i led
o altri script per esempio per spegnere e riaccendere le radio, es:
```
uci set wireless.radio0.disabled=0; wifi
```
--
## ribuildare
se modifico solo il dts rebuildo con
```
make -j4 target/linux/install
```
se ho modificato anche altri files
```
make -j4
```
se ho modificato altro, tipo il kernel
```
make clean
```
---
## Primi test
caricata l'immagine come prima cosa guardo i log di boot e mi salvo un dmesg
--
### ethernet?
per prima cosa controllo che vadano le porte ethernet (iproute, ethtool), che siano tutte e che macaddress c'hanno associate alle interfacce
Il router è gigabit ma il mio pc ha una porta 100Mbit/s
Trovo un altro ciaffo con le porte gigabit per vedere che vada anche quello
--
### radio?
Guardo il driver che dovrebbe averci questa radio e aggiungo il nodo al dts e al makefile
Negli MTD trovo la calibrazione unica fatta su questo specifico dispositivo
Cerco dove è collocata e guardando anche altri device già mappati cerco di capire se ha una lunghezza standard
--
### radio?
controllo che vadano le radio (iw, iwinfo)
e anche qui i macaddress
nel caso di qualche errore nel dts dovrei notarlo dai log di boot
nel caso in cui non siano giusti i dati di calibrazione od il macaddress dovrei notare delle disfunzioni
---
### Cosa rimarrebbe da fare...
---
#### 1- provare ad individuare la jtag
Dato che non sembra essere usata come gpio potrebbe essere disponibile
Senza la jtag non mi arrischierei a cambiare bootloader
--
#### Cosa rimarrebbe da fare
---
##### 2- migliorare la gestione della nand
Probabilmente si riesce a utilizzare UBI almeno anche per il kernel: `KERNEL_IN_UBI`
E l'immagine di tipo uImage.FIT per kernel e device-tree-blob
---
cfr: altro caso di uboot troppo vecchio
[Q] partition setup: UBI, mtd-concat, U-Boot, FIT #9550
https://github.com/openwrt/openwrt/issues/9550
--
#### Cosa rimarrebbe da fare...
---
##### 3- mettergli sopra un bootloader U-Boot aggiornato
Che supporti del tutto immagini di tipo FIT (Flattened Image Tree).
In poche parole una immagine con un header all'inizio che descrive a uboot quali sono i volumi da usare all'interno dell'immagine
<small>
E quindi si riesca ad avere un volume per ogni parte della flash eccetto il bootloader:
KERNEL_IN_UBI, UBOOTENV_IN_UBI (partizioni di environment di uboot), e il resto (rootfs)
</small>
<small>
Il che sarebbe nell'insieme una gestione il più possibile cauta di una memoria NAND
(cfr riferimenti 'Best-practice for NAND-based firmware using UBI')
</small>
--
#### Cosa rimarrebbe da fare...
---
##### 4- varie
- un led ballerino
- usb regulator che non fa il fast-charge (vabbé neanche con firmware OEM lo faceva ma durante il boot lo fa')
--
#### Cosa rimarrebbe da fare...
---
##### 5- generare una factory
trovare il firmware, o innescare il download dell'update dall 'ACS e sniffarlo, e capire come generare una factory
---
## Altri Esempi
ubootmenu e caricamento firmware originale
```
Please choose the operation:
1: Load system code to SDRAM via TFTP.
2: Load system code then write to Flash via TFTP.
3: Boot system code via Flash (default).
4: Entr boot command line interface.
9: Load Boot Loader code then write to Flash via TFTP.
Check image2 validation:
Image Header Magic Number --> OK
Image Header Checksum --> OK
Image Data Checksum --> OK
3: System Boot system code via Flash.
## Booting image at 81000000 ...
Image Name: =01.01.02.163
Image Type: MIPS Linux Multi-File Image (lzma compressed)
Data Size: 17174476 Bytes = 16.4 MB
Load Address: 80001000
Entry Point: 8000f540
Contents:
Image 0: 1966004 Bytes = 1.9 MB
Image 1: 15208448 Bytes = 14.5 MB
Verifying Checksum ... OK
Uncompressing Multi-File Image ... OK
## Transferring control to Linux (at address 8000f540) ...
## Giving linux memsize in MB, 128
Starting kernel ...
LINUX started...
```
--
#### altri esempi
Caricamento del kernel via tftp dopo aver interrotto il bootloader
```
MT7621 # tftpboot 81000000 test.bin; bootm
```
Oppure carica dalla memoria flash
```
MT7621 # nand read 800000 2000000 81000000; bootm
```
---
## Riferimenti
<small>
- OpenWrt Flash Layout https://openwrt.org/docs/techref/flash.layout
- UBI http://www.linux-mtd.infradead.org/doc/ubi.html
- UBIFS
- http://www.linux-mtd.infradead.org/doc/ubifs.html
- https://www.kernel.org/doc/html/latest/filesystems/ubifs.html
- DTS for dummies https://www.youtube.com/watch?v=m_NyYEBxfn8
- Best-practice for NAND-based firmware using UBI https://www.youtube.com/watch?v=hMoqBtJX2Lg
</small>
--
#### Riferimenti
<small>
- gpio, leds, buttons https://openwrt.org/docs/techref/hardware/port.gpio
- buttons https://openwrt.org/docs/guide-user/hardware/hardware.button
- Macaddress setup
https://openwrt.org/docs/guide-developer/mac.address
- hacking-gemtek
https://github.com/digiampietro/hacking-gemtek
- guida per confrontare step analoghi su postmarketos https://wiki.postmarketos.org/wiki/Porting_to_a_new_device
- Hacking on the Asus DSL-N14U
https://forum.openwrt.org/t/hacking-on-the-asus-dsl-n14u/132852
</small>