1

Temat: proces wgrywania openwrt

proces flashowania przedstawiony w wiki często ogranicza się do lakonicznych poleceń "zrób to, zrób tamto". chciałbym zrozumieć ten proces na jakimś tam pewnym poziomie ogólności. proszę o sprawdzenie, czy przedstawiony poniżej opis zgadza się z rzeczywistością i korektę. pytania zaznaczyłem na czerwono.

na podstawie wiki dla Zyxel P2812HNU-F1 i w luźnym nawiązaniu do tego tematu.

1. wprowadza się SoC w konkretny tryb pracy. tryb ten umożliwia m.in. przesłanie kodu bootloadera u-boot w postaci pliku ASCII. kod ładowany jest do pamięci RAM. załadowany kod u-boot uruchamia się i od tej chwili do dyspozycji są jego polecenia (których skromny opis można poznać wpisując ? w lini poleceń u-boota). w szczególności posiada polecenia operujące na pamięci nand:

P-2812HNU-Fx # nand ?
nand - NAND sub-system

Usage:
nand info - show available NAND devices
nand device [dev] - show or set current device
nand read - addr off|partition size
nand write - addr off|partition size
    read/write 'size' bytes starting at offset 'off'
    to/from memory address 'addr', skipping bad blocks.
nand read.raw - addr off|partition [count]
nand write.raw - addr off|partition [count]
    Use read.raw/write.raw to avoid ECC and access the flash as-is.
nand erase[.spread] [clean] off size - erase 'size' bytes from offset 'off'
    With '.spread', erase enough for given file size, otherwise,
    'size' includes skipped bad blocks.
nand erase.part [clean] partition - erase entire mtd partition'
nand erase.chip [clean] - erase entire chip'
nand bad - show bad blocks
nand dump[.oob] off - dump page
nand scrub [-y] off size | scrub.part partition | scrub.chip
    really clean NAND erasing bad blocks (UNSAFE)
nand markbad off [...] - mark bad block(s) at offset (UNSAFE)
nand biterr off - make a bit error at offset (UNSAFE)

2. kolejnym krokiem jest kasowanie całej pamięci NAND. odbywa się to poleceniem:

nand erase.chip

ten etap przygotowuje pamięć NAND do osadzenia w niej oprogramowania. pierwszym osadzonym kodem będzie kod bootloadera w postaci binarnej.

3. poleceniem:

tftp 0x80700000 openwrt-lantiq-p2812hnufx_nandtpl-u-boot.img

wgrywa się z użyciem protokołu tftp do pamięci RAM pod adres 0x80700000 obraz binarny u-boot. następnie poleceniem:

nand write 0x80700000 0x0 0x{filesize in hex}

osadza się ten obraz w rozmiarze {filesize in hex} z pamięci RAM spod adresu 0x80700000 na pamięć NAND rozpoczynając od adresu 0x0. po tym etapie u-boot jest osadzony w NAND od adresu 0x0 do {filesize in hex}.

1) dlaczego nie można zgrać na NAND kodu u-boot będącego już pamięci RAM tj. przesłanego pliku *.asc?

4. podobnie z użyciem tftp ładuje się do RAM obraz kernela, tym razem pod adres 0x80800000:

tftp 0x80800000 openwrt-lantiq-xrx200-P2812HNUF1-uImage

2) jaki jest powód zmiany adresu w pamięci z 0x80700000 na 0x80800000?

następnie kasuje się pamięć NAND, tym razem pewien jej określony obszar o rozmiarze 0x200000 od adresu 0x60000:

nand erase 0x60000 0x200000 

3) czy ten krok jest potrzebny jeśli wcześniej się wyczyściło NAND poleceniem nand chip.erase i nie wgrywało później openwrt, tj. wszystko jest wyczyszczone?

...i podobnie jak było z u-bootem osadza się kernel znajdujący się w pamięci RAM pod adresem 0x80800000 na pamięć NAND rozpoczynając od adresu 0x60000 i zapisując 0x200000 bajtów.

z tego tematu można zauważyć, że 0x60000 to właśnie początek partycji kernela o rozmiarze 0x20000. czyli w tej chwili na pamięci NAND osadzony jest u-boot oraz kernel.

5. kolejnym etapem jest wgranie initramfs do pamięci RAM, podobnie jak poprzednio pod adres 0x80800000:

tftpboot 0x80800000 openwrt-lantiq-xrx200-P2812HNUF1-uImage-initramfs

3) w sumie nie znalazłem w poleceniach u-boot opisu tftp, jest tylko tftpboot: boot image via network using TFTP protocol. czy jest jakaś różnica pomiędzy tymi poleceniami?

4) czy zadziałałoby gdybym użył tftp?

...i następnie jego uruchomienie poleceniem bootm (boot application image from memory):

bootm 0x80800000

czyli uruchamia się kod spod adresu 0x80800000.

5) tutaj się gubię i nie jestem pewien: czy w linuksie plik initramfs nie jest przypadkiem ramdyskiem i zawiera to, co potrzebuje kernel przy starcie, tj. w "klasycznej" dystrybucji jest plik kernela + plik initramfs i kernel korzysta z initramfs? tutaj mam wrażenie, że initramfs to jakby jedna całość, po prostu kernel z initramfs. zgadza się czy coś pokręciłem?

na tym etapie jest uruchomione Openwrt ale siedzi w pamięci RAM i nie jest osadzone w NAND (a właściwie osadzone jest tylko częściowo: tylko kernel linuksa). z chwilą uruchomienia Openwrt można operować na pojęciach "znanych" już systemowi operacyjnemu, m.in. oznaczeniach partycji w formacie mtdX.

6. kolejną czynnością jest ustawienie hasła dla roota poleceniem passwd aby móc skorzystać z scp, po czym wgrywa się obraz partycji "ubi" do katalogu /tmp. wygląda to mniej więcej tak:

# scp /tftpboot/openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin root@192.168.1.1:/tmp
openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin                                                                    100% 3712KB   1.8MB/s   00:02    

7. następnie należy odmontować obszar pamięci dla partycji mtd3

ubidetach -p /dev/mtd3

oraz "sformatować" go korzystając z przesłanego obrazu dla partycji "ubi":

ubiformat /dev/mtd3 -f /tmp/openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin

6) wygląda to jakoś podobnie do polecenia dd w linuksie. czy analogia jest słuszna czy tez ubiformat robi coś więcej?

8) ostatni etap to określenie kilku zmiennych środowiskowych dla bootladera u-boot. poniższe określa zmienną nboot i przechowuje polecenia u-boota do wykonania: nand oraz bootm wraz z ich parametrami. nand wczytuje z pamięci NAND do pamięci RAM pod adres 0x80800000 dane o rozmiarze 0x200000 zaczynająć od adresu 0x60000 (czyli kernel).

setenv nboot 'nand read 0x80800000 0x60000 0x200000; bootm 0x80800000'

bootcmd jest to zmienna u-boot przechowująca polecenie do wykonania wskazywane przez zmienną nboot: run nboot

setenv bootcmd 'run nboot'

na końcu ustawiamy te zmienne na stałe w partycji uboot-env:

saveenv

2

Odp: proces wgrywania openwrt

geos napisał/a:

1) dlaczego nie można zgrać na NAND kodu u-boot będącego już pamięci RAM tj. przesłanego pliku *.asc?

Sprecyzuj pytanie... co to jest ten plik .asc?

geos napisał/a:

2) jaki jest powód zmiany adresu w pamięci z 0x80700000 na 0x80800000?

Może na wszelki wypadek? Gdyby ktoś raz jeszcze zrzucał obraz U-Boot z RAM do NAND, zapomniawszy że w RAM pod tym adresem ma już kernel smile

geos napisał/a:

3) czy ten krok jest potrzebny jeśli wcześniej się wyczyściło NAND poleceniem nand chip.erase i nie wgrywało później openwrt, tj. wszystko jest wyczyszczone?

Nie jest potrzebny.

geos napisał/a:

3) w sumie nie znalazłem w poleceniach u-boot opisu tftp, jest tylko tftpboot: boot image via network using TFTP protocol. czy jest jakaś różnica pomiędzy tymi poleceniami?

4) czy zadziałałoby gdybym użył tftp?

U-Boot rozpoznaje polecenia porównując je znak po znaku, stąd możliwość skracania poleceń. tftp i tftpboot to jedno i to samo polecenie (U-Boot nie zna innego, rozpoczynającego się od tftp).

3

Odp: proces wgrywania openwrt

wg. tego co napisali na wiki: Upload a special (openwrt-lantiq-p2812hnufx_ram-u-boot.asc) U-Boot RAM image using a serial (baud 115200) cable via „Send File”(terraterm for win or cutecom for linux).

4

Odp: proces wgrywania openwrt

geos napisał/a:

wg. tego co napisali na wiki: Upload a special (openwrt-lantiq-p2812hnufx_ram-u-boot.asc) U-Boot RAM image using a serial (baud 115200) cable via „Send File”(terraterm for win or cutecom for linux).

To jest zupełnie inna metoda przesłania pliku - nie przez protokół tft tylko przez konsolę szeregową. W dodatku "U-Boot RAM image" sugeruje wersję uruchamianą tylko z RAM, nie z NAND/NOR. Generalna zasada jest taka, że obraz do wgrania i uruchomienia z NOR/NAND jest inni niż taki, który startuje z RAM. Najczęściej ten drugi jest pozbawiony całej niskopoziomowej inicjalizacji RAM, zegarów, kontrolerów itd. Platformy nie znam, więc traktuj to jako wypowiedź dotyczącą ogółu, a nie szczegółu.

5 (edytowany przez geos 2015-07-30 16:00:38)

Odp: proces wgrywania openwrt

dzięki pepe2k. czy dobrze rozumiem, że poza ograniczoną funkcjonalnością też tryb UART ma znaczenie? wymuszony do załądowania pliku asc jest inny niż "normalnie" przy starcie, gdzie "rozumie" tylko kod binarny?

to jeszcze z tym adresem 0x8080000 i 0x8070000, tj. ad. 2: pod tym ostatnim nic nie ma, nie ma tam kernela, więc skąd ta zmiana?

6

Odp: proces wgrywania openwrt

geos napisał/a:

dzięki pepe2k. czy dobrze rozumiem, że poza ograniczoną funkcjonalnością też tryb UART ma znaczenie? wymuszony do załądowania pliku asc jest inny niż "normalnie" przy starcie, gdzie "rozumie" tylko kod binarny?

Zupełnie nie rozumiem Twojego pytania.

geos napisał/a:

to jeszcze z tym adresem 0x8080000 i 0x8070000, tj. ad. 2: pod tym ostatnim nic nie ma, nie ma tam kernela, więc skąd ta zmiana?

Przecież Ci napisałem, po prostu wrzucasz kernel pod inny adres, żeby uniknąć pomyłki i wgrania przypadkowo bootloadera w miejsce kernela lub vice versa. To taka kosmetyka zabezpieczająca przed pomyłkami... chcesz, to wgrywaj pod ten sam adres tylko pamiętaj co i skąd potem wgrywasz do NAND.

7 (edytowany przez geos 2015-07-30 16:15:59)

Odp: proces wgrywania openwrt

możłiwe, że się nieprecyzyjnie wysławiam. chodzi mi o coś takiego, że podczas normalnego uruchamiania rutera pojawia się:

ROM VER: 1.1.4
CFG 06
NAND

i pliki, które są ładowane do pamięci RAM z NAND są oczywiście w formacie binarnym.

wymuszając tryb UART pojawia się:

ROM VER: 1.1.4
CFG 02
UART

możliwe jest wtedy wgranie u-boota, ale (tylko?) o ograniczonej funkcjonalności i w dodatku kod nie jest w postaci binarnej tylko ASCII.

stąd moje pytanie: czy to, że ruter jest w trybie UART ma też znaczenie? innymi słowy -- być może, o to pytam właśnie -- nie można w tym trybie przesłać pliku binarnego, pełnego u-boota, tylko trzeba się ograniczyć do formatu ASCII. no bo w sumie przecież jest gotowy obraz *.img dla u-boota więc jakiś problem jest że nie można przesłać *.img a nie *.asc.. dobrze myślę?

8

Odp: proces wgrywania openwrt

geos napisał/a:

możłiwe, że się nieprecyzyjnie wysławiam. chodzi mi o coś takiego, że podczas normalnego uruchamiania rutera pojawia się:

ROM VER: 1.1.4
CFG 06
NAND

i pliki, które są ładowane do pamięci RAM z NAND są oczywiście w formacie binarnym.

wymuszając tryb UART pojawia się:

ROM VER: 1.1.4
CFG 02
UART

możliwe jest wtedy wgranie u-boota, ale (tylko?) o ograniczonej funkcjonalności i w dodatku kod nie jest w postaci binarnej tylko ASCII.

stąd moje pytanie: czy to, że ruter jest w trybie UART ma też znaczenie? innymi słowy -- być może, o to pytam właśnie -- nie można w tym trybie przesłać pliku binarnego, pełnego u-boota, tylko trzeba się ograniczyć do formatu ASCII. no bo w sumie przecież jest gotowy obraz *.img dla u-boota więc jakiś problem jest że nie można przesłać *.img a nie *.asc.. dobrze myślę?

Tak jak pisałem, nie znam tej platformy i nie wiem skąd się biorą te dwa tryby, ale "ROM" wskazuje na to, że ten SoC ma jakiś zintegrowany, bardzo podstawowy bootloader w jakiejś wbudowanej pamięci (tzw. I stopień), z przynajmniej dwiema funkcjami: start z NAND lub start z UART. Bardzo podobną funkcjonalność mają układy Kirkwood (http://lists.denx.de/pipermail/u-boot/2 … 23655.html).

I odpowiadając na pytanie, tak - tryb ma znaczenie, bo ten wbudowany bootloader oczekuje konkretnego formatu pliku (w Kirkwoodach też tak jest - nie przyjmie po UART pliku nieprzygotowanego dla tego trybu).

9

Odp: proces wgrywania openwrt

dzięki pepe2k! i jeszcze pytanie o kernela i initramfs. kernela osadza się na partycji "kernel", initramfs się uruchamia poleceniem bootm.

5) tutaj się gubię i nie jestem pewien: czy w linuksie plik initramfs nie jest przypadkiem ramdyskiem i zawiera to, co potrzebuje kernel przy starcie, tj. w "klasycznej" dystrybucji jest plik kernela + plik initramfs i kernel korzysta z initramfs? tutaj mam wrażenie, że initramfs to jakby jedna całość, po prostu kernel z initramfs. zgadza się czy coś pokręciłem?

jak to jest z tym kernelem i initramfs w openwrt?

10

Odp: proces wgrywania openwrt

Może być jeden, może być rozdzielony. chodzi o to że initramfs nie szuka systemu plików we flash tylko właśnie w pamięci.

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

11 (edytowany przez geos 2015-07-30 16:55:27)

Odp: proces wgrywania openwrt

Cezary, bazuję na przykładzie P2812HNU -- tam initramfs nie jest w ogóle osadzany w pamięci NAND. osadzany jest tylko plik kernela: openwrt-lantiq-xrx200-P2812HNUF1-uImage. czyli po restarcie nie ma initramfs w pamięci. czy to oznacza, że plik kernela (openwrt-lantiq-xrx200-P2812HNUF1-uImage) zawiera w sobie właściwy kernel oraz initramfs? pożniej przy starcie wykonuje się

run nboot

co jest równoważne zaczytaniu z nand całej partycji kernela i uruchomieniu -- już pamięci:

nand read 0x80800000 0x60000 0x200000; bootm 0x80800000

rozumiem, że pod adresem 0x80800000 jest właściwy kernel a gdzieś tam dalej initramfs, zgadza się?

12

Odp: proces wgrywania openwrt

Piszesz o początku tej instrukcji? Tam masz kernel który zapisujesz do nandu a później wczytujesz initramfs z kernelem który uruchamiasz.

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

13 (edytowany przez geos 2015-07-30 17:20:56)

Odp: proces wgrywania openwrt

tak, piszę o tej instrukcji. bo wcześniej jest wgranie przez tftp do RAM pliku kernela:

tftp 0x80800000 openwrt-lantiq-xrx200-P2812HNUF1-uImage

później zapisanie go do NAND pod odpowiedni adres:

nand write 0x80800000 0x60000 0x200000

a następnie wczytanie przez tftp initramfs do RAM i uruchomienie go:

tftpboot 0x80800000 openwrt-lantiq-xrx200-P2812HNUF1-uImage-initramfs
bootm 0x80800000

stąd moje pytanie. initramfs pojawia się tylko na chwilę, jest w pamięci RAM, ale po restarcie go już nie będzie. uboot do RAM wczyta obszar z NAND zawierający partycję kernela:

nand read 0x80800000 0x60000 0x200000

a następnie uruchomi kod spod adresu 0x80800000:

bootm 0x80800000

po prostu szukam analogi z systemem linux, gdzie jest wyraźny podział na plik kernela oraz initramfs. grubowi w parametrach podaje się lokalizację pliku kernela i pliku initramfs, np:

root (hd0,0)
kernel /boot/vmlinuz-2.6.32-504.16.2.el6.x86_64 ...
initrd /boot/initramfs-2.6.32-504.16.2.el6.x86_64.img

i nie do końca rozumiem, czy "kernel" (plik openwrt-lantiq-xrx200-P2812HNUF1-uImage) osadzany w NAND pod adresem 0x60000 i o rozmiarze 0x200000 to tak naprawdę "właśiwy kernel" + initramfs...?

14

Odp: proces wgrywania openwrt

To jest kernel + initramfs: openwrt-lantiq-xrx200-P2812HNUF1-uImage-initramfs

razem w jednym pliku, nie rozdzielnie jak w normalnym linuksie. Wgrywasz kernel, zapisujesz go do nand, ładujesz i uruchamiasz inny system do pamięci i przy jego pamięci formatujesz i robisz system plików ubi. Restart i wstaje z kernela który w pierwszym etapie zapisałeś do nand, a on dalej grzebie po flash i czyta ten ubifs.

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

15 (edytowany przez geos 2015-07-30 18:06:39)

Odp: proces wgrywania openwrt

a ja myślałem, że uImage-initramfs to tylko initamfs. czyli podsumowując kernel zapisany do NAND (openwrt-lantiq-xrx200-P2812HNUF1-uImage) nie potrzebuje już dodatkowo initramfs, zgadza się?

16

Odp: proces wgrywania openwrt

Nie.

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

17

Odp: proces wgrywania openwrt

no to gdzie jest ten initramfs później, już po restarcie? przychodzi z tym plikiem openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin i jest gdzieś na partycji ubi?

18

Odp: proces wgrywania openwrt

Nie ma go. To system w pamięci, wgrywasz, uruchamiasz, restartujesz to znika. Jak myślisz, skąd taka nazwa?

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

19

Odp: proces wgrywania openwrt

ok, może jestem nieprecyzyjny, nie wiem... jeszcze raz: podczas flashowania kernel wczytywany jest do RAM (plik openwrt-lantiq-xrx200-P2812HNUF1-uImage) i następnie zapisany do NAND. później wczytywany jest kernel + initramfs do RAM (plik openwrt-lantiq-xrx200-P2812HNUF1-uImage-initramfs), jest on uruchamiany, odłącza się mtd3, formatuje mtd3 z użyciem pliku openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin, i reboot.

czy do tego miejsca jest poprawnie?

po reboocie nie ma już w RAM kodu z pliku openwrt-lantiq-xrx200-P2812HNUF1-uImage-initramfs, czyli nie ma w RAM kernela wraz z initramfs. uboot wczytuje z NAND całą partycję od 0x60000 i o rozmiarze 0x200000. w tym obszarze poprzednio był wgrany tylko plik kernela (openwrt-lantiq-xrx200-P2812HNUF1-uImage). dla ustalenia uwagi powiedzmy, że "normalnie" w linuksie są dwa pliki na dysku: kernel i initramfs, a w grubie wskazuje się ściezki do nich. szukam analogii do tej "klasycznej" sytuacji: gdzie w NAND jest odpowiedni plik initramfs? lub co i kiedy tworzy taki plik w pamięci (skoro go nie ma na dysku) podczas uruchamiania systemu?

20

Odp: proces wgrywania openwrt

Nie ma w ogóle w nand initramfs. W normalnym linuksie też nie musi być, o ile sterowniki do dysku masz w kompilowane w jądro.

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

21 (edytowany przez geos 2015-07-30 18:36:13)

Odp: proces wgrywania openwrt

no właśnie. czyli jak to jest w openwrt: czy plik openwrt-lantiq-xrx200-P2812HNUF1-uImage, który jako jedyny jest zapisywany do NAND do partycji kernel ma wszystko wkompilowane i nie potrzebuje już osobnego initramfs?

22

Odp: proces wgrywania openwrt

Tak

Masz niepotrzebny router, uszkodzony czy nie - chętnie przygarnę go.

23

Odp: proces wgrywania openwrt

dziękuję Cezary! już myślałem, że zgłupiałem do końca, ale się udało. smile