はじめに
この記事はRaspberry Pi 3B+の実際の挙動と公式のドキュメントから大体こんな感じだろうというところで書いてるので正確さは期待しないでください。
下図のような構成でLinux kernel(Raspberry Pi向けのカーネルじゃなくて、mainlineとかstable treeのカーネル)を使うときにdtoverlay・dtparamを使う方法を調べたメモです。なので、自分でビルドしたカーネルを使う必要がなければRaspberry Pi OSとかmeta-raspberrypiを使うのが良いかと思います。
-> Raspberry Piのブートローダー -> u-boot -> Linux kernel
Linux kernel source とdtbファイル
mainlineのカーネルにはbcm2837-rpi-3-b-plus.dts等のdtsファイルがあるのでこれをビルドして使えばmainlineのカーネルでもRaspberry Piで動きます。だがしかし、config.txtでdtoverlay・dtparamを使うのはできませんでした。なんでかというと、Raspberry Piのカーネルとmainlineのカーネルにあるdtsファイルを見比べるとRaspberry Piのカーネルのほうにはoverridesがあって設定をoverrideできるようになってるんですね。例えばarm/boot/dts/bcm2710-rpi-3-b-plus.dtsだとこんな感じで設定があります。
/ { __overrides__ { act_led_gpio = <&act_led>,"gpios:4"; act_led_activelow = <&act_led>,"gpios:8"; act_led_trigger = <&act_led>,"linux,default-trigger"; pwr_led_gpio = <&pwr_led>,"gpios:4"; pwr_led_activelow = <&pwr_led>,"gpios:8"; pwr_led_trigger = <&pwr_led>,"linux,default-trigger"; eee = <ð_phy>,"microchip,eee-enabled?"; tx_lpi_timer = <ð_phy>,"microchip,tx-lpi-timer:0"; eth_led0 = <ð_phy>,"microchip,led-modes:0"; eth_led1 = <ð_phy>,"microchip,led-modes:4"; eth_downshift_after = <ð_phy>,"microchip,downshift-after:0"; eth_max_speed = <ð_phy>,"max-speed:0"; }; };
上記のブロックはmainlineのほうにはありません。そんなわけでdtoverlay・dtparamを手軽に使うならdtbファイルはブートローダーなんかと一緒に配布されてるdtbファイル(firmwareのリポジトリ)を使いましょうという感じです。
dtoverlay・dtparamはどのように処理されてるか
Raspberry Piのブートローダーが自身のデバイスに合う適切なdtbファイルを読んでくれます(公式ドキュメントのどこかにそんなことが書いてありました)。そして、config.txtに記載されてるdtoverlay・dtparamの記述に沿ってメモリ上に読み込まれてるdtbファイルのデータを更新します。そしてそのメモリ上で更新したdtbファイルを使うという流れです。
u-bootをブートローダーとして使いたい場合
Raspberry Piのブートローダーはすでにdtbファイルを読み込んでdtoverlay・dtparamの設定もメモリ上で反映させてます。そのため、u-bootがfatloadとかして自分でdtbファイルを読んじゃうと意味がありません。なので、config.txtでdtbファイルを読み込むアドレスを指定し、u-bootのほうはそのアドレスからdtbファイルを読む感じにします。例えばconfig.txtで下記のように読み込むアドレスを指定しておきます。
device_tree_address=0x02600000
u-bootのほうはこんな感じでfdtコマンドを使ってconfig.txtで指定したメモリアドレスを利用します。
setenv fdt_addr_r 0x02600000 fdt addr ${fdt_addr_r}
こんな感じにすればRaspberry Piのブートローダーが設定したdtbファイルをu-bootから読めて、それを更にカーネルの起動に利用することができます。