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.chipten 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.imgwgrywa 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-uImage2) 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-initramfs3) 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 0x80800000czyli 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/mtd3oraz "sformatować" go korzystając z przesłanego obrazu dla partycji "ubi":
ubiformat /dev/mtd3 -f /tmp/openwrt-lantiq-xrx200-P2812HNUF1-squashfs-ubinized.bin6) 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