備忘録

趣味に生きるオタクの備忘録

Raspi4B+ Boot Sequence の再整理とBoot LoaderのUART出力

前回の記事から1年位ほったらかしてしまってすみませんというかサボってましたはい。(コレ:Raspi4B+でBootの初期段階からUARTを出したい - 備忘録
そもそもPi3→Pi4でBoot SequenceがかなりModifyされた様ですが、ほぼほぼ実機いじれない状況が続いていました、すみません。

途中でPi4にKODIを入れてメディアプレイヤー化したりもしていましたが、もっと低レイヤの部分やれよって感じで、、、
仕切り直しで、公式が出しているDocumentationを少しずつ読み続けてみようかなと思います。

まずは勉強から。
[2021.02.24 画像を追加し一部文言を改定]

Raspberry Pi4 関連資料

GitHub(SoCのDocumentationが保管されている)

とりあえずデータシートはここにあります。
documentation/rpi_DATA_2711_1p0.pdf at master · raspberrypi/documentation · GitHub

github.com
Raspberry PiのSoC関連のHW Manual/DocumentationははGitHubにあるんですね。
Raspberry Pi 4の採用SoCはBCM2711です。Cortex-A72@1.5GHz x4発なのでとてもパワフルです。。。(ARMコアだけで見ればそのへんの格安スマホ@クアッドコアと似たようなモンです)
ところでPi3はBCM2837だったので型番がなんだか戻ってますね。

Boot関連のDocumentation

PiのBootの仕組みを見るには公式のDocumentを見る必要があります。
Boot Flowをたどりたい場合は、下記の紹介順でみていくと順番に見ることができるかなと思います。

Pi4 Bootflow

Pi4 Bootflow - Raspberry Pi Documentation
全般的なブートフロー

Raspberry Pi 4 boot EEPROM

Raspberry Pi 4 boot EEPROM - Raspberry Pi Documentation
Boot Loader(EEPROM内蔵分)について

Raspberry Pi 4 bootloader configuration

Raspberry Pi 4 bootloader configuration - Raspberry Pi Documentation
EEPROMに書き込む、Boot Loaderの設定について

Boot options in config.txt

Boot options in config.txt - Raspberry Pi Documentation
config.txtでいじれる、Boot Loaderの設定について

かるーく現状の理解をまとめて、Linux Kernel起動までに関係するBoot Loader及び設定呼び出しの流れです。
f:id:hu2mmc:20210224223755p:plain
※bootcode.bin/start4.elfのソースコードが公開されていないため、一部推測を含みます

実機で確認

さて現状がどうなっているのか、SDブートで、最新版のRaspberry Pi OSを動かしながら確認してみましょう。
以前に備忘録にしたときは"Raspbian OS"でしたが、Raspberry Pi OSに名前が変わった?のでしょうか。いずれにせよ以下の記事と同じような手順です。
Raspbian buster(Lite)のダウンロードとmicroSD焼き - 備忘録

最新版のRaspberry Pi OSの取得

この記事を書いている時点で、Raspberry Pi OSは2021-01-11が最新のリリースのようです。下記のリンクからリリースを確認できます。
www.raspberrypi.org
今回は説明されているBoot Sequenceを実機で確認することだけが目的なので、Graphicsは不要です。伴いLiteを選択しました。

ミラー(日本鯖)

公式からのダウンロードが遅いときに。

ttp://ftp.jaist.ac.jp/pub/raspberrypi/raspbian_lite/images/
ttp://ftp.jaist.ac.jp/pub/raspberrypi/raspios_lite_armhf/images/raspios_lite_armhf-2021-01-12/

SDへの書き込み

システムディスクを間違って破壊しないように要注意。

~/$ <b>lsblk
</b>
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
:
sdb      8:16   1  29.6G  0 disk 
:

~/$ <b>sudo dd if=2021-01-11-raspios-buster-armhf-lite.img of=/dev/sdb bs=1M status=progress && sync</b>
1861222400 bytes (1.9 GB, 1.7 GiB) copied, 64 s, 29.1 MB/s 
1776+0 records in
1776+0 records out
1862270976 bytes (1.9 GB, 1.7 GiB) copied, 99.5097 s, 18.7 MB/s

書き込みが終わってもそのままではシリアルコンソール出力がされません。(かつてハマった)
Raspian buster(Lite)でUARTコンソールを使う - 備忘録
/boot パーティションのconfig.txtに

enable_uart=1

を追記する必要があります。

実機の準備

AmazonでこんなUSBシリアル変換が激安で売っています。今回はこれを使いました。

実機にはピンヘッダがたくさん生えています。それぞれのPin配置については公式Documentを見てください。
GPIO - Raspberry Pi Documentation

このうちUARTのTX/RX、GNDを今回使います。USBシリアルのTXをPiのRXに、USBシリアルのRXをPiのTXにつなぎます。
私はあまり記憶力が良くない(ピンの場所なんて特に)ので、私の環境ではこんな具合に印をつけてあります。
f:id:hu2mmc:20210224222427p:plain

シリアルターミナルの準備

Pi4にSD、UARTを刺したらPi側準備は終わりです。
PCの方にUSBシリアル変換を刺して、minicomかなにかのTerminalソフトを立ち上げて115,200bpsでモニタすれば出力が確認できます。
minicomのHardware Flow Controlはオフにしておきましょう。(Ctrl+A -> O->Serial Port Setup)※ONだと実機への入力ができなくなります。

そうすると、こんな具合でいろいろ出るはずです

Welcome to minicom 2.7.1

OPTIONS: I18n 
Compiled on Dec 23 2019, 02:06:26.
Port /dev/ttyUSB0, 17:46:24

Press CTRL-A Z for help on special keys

[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.4.83-v7l+ (dom@buildbot) (gcc version 8.4.0 (Ubuntu/Linaro 8.4.0-3ubuntu1)) #1379 SMP Mon Dec 14 13:11:50
[    0.000000] CPU: ARMv7 Processor [410fd083] revision 3 (ARMv7), cr=30c5383d
[    0.000000] CPU: div instructions available: patching division code
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[    0.000000] OF: fdt: Machine model: Raspberry Pi 4 Model B Rev 1.2
:
:

しかしこの表示はあくまでLinux Kernelの初期化処理が出力されているに過ぎません。
EEPROMのBootloaderなど、それよりもっと前段階のモノを表示したい場合はさらなる設定が必要です。

bootcode段階でシリアル表示を出す:EEPROMの書き換え

bootcode(.bin)相当のバイナリはEEPROMに格納されています。Raspberry Pi OSに用意されているコマンドで、この中身をReadすることができます。
(公式説明はこの辺を見てください:Raspberry Pi 4 boot EEPROM - Raspberry Pi Documentation

vcgencmd bootloader_version
pi@raspberrypi:~$ vcgencmd bootloader_version
Sep  3 2020 13:11:43
version c305221a6d7e532693cc7ff57fddfc8649def167 (release)
timestamp 1599135103
update-time 0
capabilities 0x00000000
pi-eeprom-config
pi@raspberrypi:~$ rpi-eeprom-config
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                              
                                                                             
                                                                              
             
pi@raspberrypi:~$ 

ちょっとEEPROMに記録されているBootLoaderが古い気がしますね。(KODIを入れて運用していたので、少しは更新があたっているかもしれません)

EEPROMファームを最新に更新(必要に応じて)

というわけで、aptが使えるので更新してFirmwareを最新に出来るか試してみます。
これは必要に応じてでOKなはずです。

pi@raspberrypi:~$ sudo apt update           #リポジトリデータを最新のモノ取得
pi@raspberrypi:~$ sudo apt upgrade         #最新版のPackage/Firmwareを取得
:
The following packages will be upgraded:
  base-files bind9-host bluez-firmware ca-certificates device-tree-compiler
  file firmware-atheros firmware-brcm80211 firmware-libertas
  firmware-misc-nonfree firmware-realtek iproute2 libbind9-161
  libdns-export1104 libdns1104 libgnutls30 libisc-export1100 libisc1100
  libisccc161 libisccfg163 libldap-2.4-2 libldap-common liblwres161
  libmagic-mgc libmagic1 libpam-systemd libraspberrypi-bin libraspberrypi-dev
  libraspberrypi-doc libraspberrypi0 libssl1.1 libsystemd0 libudev1 libzstd1
  openssl python-rpi.gpio raspberrypi-bootloader raspberrypi-kernel
  raspberrypi-sys-mods raspi-config <b>rpi-eeprom</b> rpi.gpio-common sudo systemd
  systemd-sysv tzdata udev unzip
48 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
:
EEPROMデータの更新(最新版にする場合)
pi@raspberrypi:~$ sudo rpi-eeprom-update
BCM2711 detected
Dedicated VL805 EEPROM detected
Checking for updates in /lib/firmware/raspberrypi/bootloader/default
Use raspi-config to select either the default-production release or latest update.
BOOTLOADER: up-to-date
CURRENT: Thu  3 Sep 12:11:43 UTC 2020 (1599135103)
 LATEST: Thu  3 Sep 12:11:43 UTC 2020 (1599135103)
RELEASE: default
VL805: up-to-date
CURRENT: 000138a1
 LATEST: 000138a1

ちなみに、EEPROMのバイナリは/lib/firmware以下にあるみたいです。

pi@raspberrypi:~$ ls -al /lib/firmware/raspberrypi/bootloader/
total 44
drwxr-xr-x 5 root root  4096 Feb 23 09:03 .
drwxr-xr-x 3 root root  4096 Jan 11 12:54 ..
drwxr-xr-x 2 root root  4096 Feb 23 09:03 beta
drwxr-xr-x 2 root root  4096 Feb 23 09:03 critical
lrwxrwxrwx 1 root root     8 Feb 22 17:53 default -> critical
lrwxrwxrwx 1 root root     6 Feb 22 17:53 latest -> stable
-rw-r--r-- 1 root root 23771 Feb 22 17:53 release-notes.md
drwxr-xr-x 2 root root  4096 Feb 23 09:03 stable
↓
defaultをみる
↓
pi@raspberrypi:~$ ls -al /lib/firmware/raspberrypi/bootloader/default/
total 1328
drwxr-xr-x 2 root root   4096 Feb 23 09:03 .
drwxr-xr-x 5 root root   4096 Feb 23 09:03 ..
-rw-r--r-- 1 root root 524288 Apr 29  2020 pieeprom-2020-04-16.bin
-rw-r--r-- 1 root root 524288 Sep 14 14:27 pieeprom-2020-09-03.bin
-rw-r--r-- 1 root root  98196 Sep 14 14:27 recovery.bin
-rw-r--r-- 1 root root  98904 Jan 22  2020 vl805-000137ad.bin
-rw-r--r-- 1 root root  99224 Sep 14 14:27 vl805-000138a1.bin

現状defaultがcriticalへのシンボリックリンクになっているみたいですね。


話を戻して、EEPROMのデータを書き換えていきます。
BootLoaderでUARTを有効化するためには

BOOT_UART

のエントリを0から1にするだけです。

EEPROMの設定値をTextファイルに書き出す

下記コマンドで、使っているFirmwareにおけるconfigを書き出します。

pi@raspberrypi:~$ rpi-eeprom-config \
/lib/firmware/raspberrypi/bootloader/default/pieeprom-2020-09-03.bin \
> eeprom_conf.txt               

先程rpi-eeprom-configでチェックした日付とあっているbinを選べばOKそうですね。
さっそくeeprom_conf.txtをcatで見てみます。

pi@raspberrypi:~$ cat eeprom_conf.txt 
[all]
<b>BOOT_UART=0</b>
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
ENABLE_SELF_UPDATE=1
DISABLE_HDMI=0
BOOT_ORDER=0xf41

EEPROMの設定値の変更と書き戻し

適当にnanoで編集しましょう。
私はファイル名を新しくeeprom_conf_bootuart1.txtにしておきました。

pi@raspberrypi:~$ cat eeprom_conf_bootuart1.txt 
[all]
BOOT_UART=1
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
ENABLE_SELF_UPDATE=1
DISABLE_HDMI=0
BOOT_ORDER=0xf41

バイナリにします。

pi@raspberrypi:~$ rpi-eeprom-config --out pieeprom_uart.bin --config \
eeprom_conf_bootuart1.txt \
/lib/firmware/raspberrypi/bootloader/default/pieeprom-2020-09-03.bin

新しいバイナリができました。

pi@raspberrypi:~$ ls -al
:
-rw-r--r-- 1 pi   pi      172 Feb 23 09:21 eeprom_conf_bootuart1.txt   << 変えたコンフィグ
-rw-r--r-- 1 pi   pi      172 Feb 23 09:11 eeprom_conf.txt             << もともとのコンフィグ
-rw-r--r-- 1 pi   pi   524288 Feb 23 09:30 pieeprom_uart.bin           << 新しいEEPROMイメージ

これをEEPROMに焼きます。

pi@raspberrypi:~$ sudo rpi-eeprom-update -d -f pieeprom_uart.bin 
BCM2711 detected
Dedicated VL805 EEPROM detected
*** INSTALLING pieeprom_uart.bin  ***
BOOTFS /boot
EEPROM update pending. Please reboot to apply the update.

表示の通り、再起動が必要です。

リブートします。

pi@raspberrypi:~$ sudo reboot


次回起動から下記のようにEEPROM内蔵のBootLoaderの出力が出るようになります。やったね!

Welcome to minicom 2.7.1

OPTIONS: I18n 
Compiled on Dec 23 2019, 02:06:26.
Port /dev/ttyUSB0, 18:38:25

Press CTRL-A Z for help on special keys
# おそらくこの辺はEEPROMのBootloaderですね #
[2021-02-23 18:43:15.038] PM_RSTS: 0x00001000
[2021-02-23 18:43:15.039] RPi: BOOTLOADER release VERSION:c305221a DATE: Sep  3 2020 TIME: 13:11:46 BOOTMODE: 0x00000006 part: 0 BUILD_TIMESTAMP=1599135103 0x26eeacfe 0x00c03112
[2021-02-23 18:43:15.054] uSD voltage 3.3V
[2021-02-23 18:43:15.066] Initialising SDRAM 'Micron' 16Gb x2 total-size: 32 Gbit 3200
[2021-02-23 18:43:16.735] XHCI-STOP
[2021-02-23 18:43:16.736] xHC ver: 256 HCS: 05000420 fc000031 00e70004 HCC: 002841eb
[2021-02-23 18:43:16.741] xHC ports 5 slots 32 intrs 4
[2021-02-23 18:43:16.747] Reset USB port-power 1000 ms
[2021-02-23 18:43:17.885] Boot mode: SD (01) order f4
[2021-02-23 18:43:17.889] SD HOST: 250000000 CTL0: 0x00000000 BUS: 100000 Hz actual: 100000 HZ div: 2500 (1250) status: 0x1fff0000 delay: 1080
[2021-02-23 18:43:17.905] SD HOST: 250000000 CTL0: 0x00000f00 BUS: 100000 Hz actual: 100000 HZ div: 2500 (1250) status: 0x1fff0000 delay: 1080
[2021-02-23 18:43:17.915] CID: 00744a6055534455310267202cfa0108
[2021-02-23 18:43:17.919] CSD: 400e00325b590000ec5d7f800a400000
[2021-02-23 18:43:17.922] SD: bus-width: 4 spec: 2 SCR: 0x02358003 0x00000000
[2021-02-23 18:43:17.928] SD HOST: 250000000 CTL0: 0x00000f04 BUS: 50000000 Hz actual: 41666666 HZ div: 6 (3) status: 0x1fff0000 delay: 2
[2021-02-23 18:43:17.937] MBR: 0x00002000,  524288 type: 0x0c
[2021-02-23 18:43:17.941] MBR: 0x00082000,61429760 type: 0x83
[2021-02-23 18:43:17.944] MBR: 0x00000000,       0 type: 0x00
[2021-02-23 18:43:17.947] MBR: 0x00000000,       0 type: 0x00
[2021-02-23 18:43:17.950] lba: 8192 oem: 'mkfs.fat' volume: ' boot       '
[2021-02-23 18:43:17.955] rsc 32 fat-sectors 4033 c-count 516190 c-size 1 r-dir 2 r-sec 0
[2021-02-23 18:43:18.009] PM_RSTS: 0x00001000
[2021-02-23 18:43:18.011] Partition: 0
[2021-02-23 18:43:18.012] lba: 8192 oem: 'mkfs.fat' volume: ' boot       '
[2021-02-23 18:43:18.016] rsc 32 fat-sectors 4033 c-count 516190 c-size 1 r-dir 2 r-sec 0
[2021-02-23 18:43:18.027] Read config.txt bytes     1799 hnd 0x000003e5 hash '68ca07b419dcf6ab'
[2021-02-23 18:43:18.043] recover4.elf not found (6)
[2021-02-23 18:43:18.048] recovery.elf not found (6)
[2021-02-23 18:43:19.044] Read start4.elf bytes  2227200 hnd 0x000135a2 hash '0e07ea2d056832e8'
[2021-02-23 18:43:19.121] Read fixup4.dat bytes     5430 hnd 0x00017fef hash 'c2eb2ff734648cae'
[2021-02-23 18:43:19.127] 0x00c03112 0x00000000 0x0000003f
[2021-02-23 18:43:19.130] MEM GPU: 76 ARM: 948 TOTAL: 1024
# ここからがstart.4.elf (Firmware)かな? #
[2021-02-23 18:43:19.344] Starting start4.elf @ 0xfec00200 partition 0
# ここからLinux Kernelの出力 #
[    0.000000] Booting Linux on physical CPU 0x0
[2021-02-23 18:43:25.551] [    0.000000] Linux version 5.10.11-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1399 SMP Thu Jan 28 12:09:1
[2021-02-23 18:43:25.569] [    0.000000] CPU: ARMv7 Processor [410fd083] revision 3 (ARMv7), cr=30c5383d
[2021-02-23 18:43:25.576] [    0.000000] CPU: div instructions available: patching division code
[2021-02-23 18:43:25.582] [    0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[2021-02-23 18:43:25.589] [    0.000000] OF: fdt: Machine model: Raspberry Pi 4 Model B Rev 1.2
:

うーむ、EEPROMのBootLoaderで4秒くらい食ってたんですね。。。
start4.elfのログはもしかたら出せるんでしょうかね?もう少し調べてみましょう。

というわけでこの記事(https://hu2mmc.hatenablog.com/entry/2020/03/09/045143)のやりたいことを1年越しに記事化できました。サボっててすいません。。。