Raspberry Pi 4でU-Bootを起動
やりたいこと
Raspberry Pi 4でU-Bootを起動する
動機
QEMU 上で U-Boot を使って開発してきた自作システム(Hypervisor + ゲスト OS)を Raspberry Pi 4 実機で動かす
Linux は使わず、U-Boot から直接自作システムを起動する
U-Boot に DTB 解析やディスク読み出しなどを任せたい
構成の検討
Linux は必要か
不要。RPi4 の起動シーケンスは以下の通りで、Linux を介さず U-Boot を直接起動できる。
code:_
GPU ファームウェア (start4.elf)
└─ config.txt を読む
└─ U-Boot をロードして実行
└─ 自作システムを起動
記事で紹介されていた「Linux 上で config.txt を書き換えて再起動」という手順は、
すでに RPi OS が動いている環境向けの説明であり、開発者は最初から SD カードにその構成を書けばよい。
自作イメージのメモリ配置
U-Boot の load mmc コマンドで各バイナリを任意のアドレスに配置し、go でジャンプする。
開発初期は個別 load、安定後は FIT Image にまとめる方針とした。
行ったこと
SD カードのファイル構成
boot パーティション(FAT32)に以下を配置する。
code:_
/boot/
├── start4.elf # GPU ファームウェア
├── fixup4.dat # メモリ設定
├── bcm2711-rpi-4-b.dtb # デバイスツリー
├── config.txt
└── u-boot.bin
U-Boot のビルド
WSL2 上でクロスコンパイル。RPi4 用の defconfig を使用する。
code:bash
sudo apt install gcc-aarch64-linux-gnu make bc bison flex libssl-dev \
python3-pyelftools libgnutls28-dev
make CROSS_COMPILE=aarch64-linux-gnu- rpi_4_defconfig
make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
ディスクイメージの作成
WSL2 上で raw イメージを作成し、Win32DiskImager / Rufus で SD カードに書き込む。
code:bash
dd if=/dev/zero of=rpi4.img bs=1M count=256
fdisk rpi4.img # パーティション作成・FAT32・ブートフラグ設定
losetup -P /dev/loop0 rpi4.img
mkfs.fat -F 32 /dev/loop0p1
mount /dev/loop0p1 /mnt/boot
cp start4.elf fixup4.dat bcm2711-rpi-4-b.dtb config.txt u-boot.bin /mnt/boot/
問題と対処
問題 1:U-Boot ビルドエラー
code:_
fatal error: gnutls/gnutls.h: No such file or directory
原因: libgnutls-dev が未インストール
対処: sudo apt install libgnutls28-dev
問題 2:起動メッセージが出ない
調査手順:
1. LED の挙動を確認 →「一瞬点滅してつきっぱなし」= U-Boot は起動しているが UART が出ていない
2. uart_2ndstage=1 を config.txt に追加し、ファームウェア自身の UART 出力を有効化
3. ファームウェアログからパーティションタイプの誤り・ボーレートのずれ・64ビットモードの未設定を発見
発見された個別問題と対処:
table:_
問題 内容 対処
パーティションタイプ誤り fdisk で Id: a(OS/2)になっていた t → b で FAT32 に修正・ブートフラグ追加
ボーレートのずれ ファームウェアが 103448 Hz で出力(115200 Hz が正しい) init_uart_clock=48000000 を追加(U-Boot 動作には不要と判明)
32ビットモード起動(本質的原因) Loaded 'u-boot.bin' to 0x8000(64ビットは 0x80000)。64ビットバイナリを32ビットで実行しようとしていた arm_64bit=1 を config.txt に追加
最終的な config.txt
code:ini
enable_uart=1
arm_64bit=1
dtoverlay=disable-bt
init_uart_clock=48000000
kernel=u-boot.bin
結果
U-Boot の起動メッセージが Tera Term に表示され、正常起動を確認。
code:_
U-Boot 2026.07-rc3-00014-g30b77f6aa146 (May 31 2026 - 11:15:28 +0900)
補足:原因の優先度
init_uart_clock=48000000 はファームウェアログのボーレートには効果がなく、U-Boot は独自に UART を再初期化するため不要だった。本質的な原因は arm_64bit=1がないことだったのでこの設定は無くした