今回はRaspberry Piでデバイスツリーをオーバーレイする方法を紹介したいと思います。
デバイスツリーとは、Arm CPUのLinux用に用意されたHW情報を記載した情報のことを指します。
デバイスツリーは起動時に読み込まれ、各種デバイスドライバの初期化に使用されますが、起動後に新たなデバイスを接続する場合にはそのHW情報が読み込まれていない状態です。
そこで、起動後にデバイスツリーを更新したい場合に、オーバーレイという手法でHW情報を読み込むことができます。
今回は、Raspberry PiのSoCに存在しているシステムタイマーのデバイスツリーをオーバーレイしたいと思います。
オーバーレイファイルの作成
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target-path="/soc";
__overlay__ {
system_timer: timer@7e003000 {
compatible = "brcm,bcm2835-system-timer";
reg = <0x7e003000 0x1000>;
interrupts = <1 0>, <1 1>, <1 2>, <1 3>;
clock-frequency = <1000000>;
};
};
};
};
上記はRaspberry Piのシステムタイマー用のオーバーレイファイルになります。
/plugin/という記述は、オーバーレイ用であることを示すものです。
システムタイマーは/soc配下なので、target-pathに”/soc”を指定しています。
後は__overlay__の中にに追加したい情報を記載すればオーバーレイファイルは完了です。
ファイル名は何でもいいのですが、オーバーレイであることがわかるように、「~.dtso」にしておきましょう。
オーバーレイの有効化
コンパイル
先程作成したオーバーレイ用のファイルをコンパイルします。このコマンドはデバイスツリーを作るときと同じです。
dtc -O dtb -o systimer.dtbo systimer.dtso
いくつかwarningが出ますが無視して大丈夫です。
拡張子は何でもOKですが、ここでも末尾にoを付与して「~.dtbo」としときましょう。
有効化
コンパイルしたファイルをloadします。
いくつかやり方はありますが、ここではConfigFSを利用したやり方を紹介します。
まずは現在読み込まれているデバイスツリーを確認しておきましょう。
まだtimer@7e003000は出現していないと思います。
$ ls /proc/device-tree/soc/
'#address-cells' hdmi@7e902000 power
'#size-cells' hvs@7e400000 pwm@7e20c000
aux@7e215000 i2c0mux ranges
axiperf i2c@7e205000 rng@7e104000
compatible i2c@7e804000 serial@7e201000
cprman@7e101000 i2c@7e805000 serial@7e215040
csi@7e800000 i2s@7e203000 smi@7e600000
csi@7e801000 interrupt-controller@7e00b200 sound
dma-ranges local_intc@40000000 spi@7e204000
dma@7e007000 mailbox@7e00b840 spi@7e215080
dpi@7e208000 mailbox@7e00b880 spi@7e2150c0
dsi@7e209000 mmc@7e202000 thermal@7e212000
dsi@7e700000 mmc@7e300000 txp@7e004000
fb mmcnr@7e300000 usb@7e980000
firmware name v3d@7ec00000
firmwarekms@7e600000 phandle vcsm
gpio@7e200000 pixelvalve@7e206000 vec@7e806000
gpiomem pixelvalve@7e207000 virtgpio
gpu pixelvalve@7e807000 watchdog@7e100000
では、loadしていきます。
/sys/kernel/config/device-tree/overlays/配下に今回追加するファイル名(何でもOK)でディレクトリを作成します。
sudo mkdir /sys/kernel/config/device-tree/overlays/systimer
overlays配下にディレクトリを作成すると自動的に「dtbo」「path」「status」というファイルが作成されます。
$ ls -l /sys/kernel/config/device-tree/overlays/systimer/
合計 0
-rw-r--r-- 1 root root 0 10月 3 13:13 dtbo
-rw-r--r-- 1 root root 4096 10月 3 13:13 path
-r--r--r-- 1 root root 4096 10月 3 13:13 status
先程作成された「dtbo」に、コンパイル済みのsystimer.dtboを書き込むことで有効化します。
sudo sh -c 'cat systimer.dtbo > /sys/kernel/config/device-tree/overlays/systimer/dtbo'
「status」が”applied”になっていれば成功です。
$ cat /sys/kernel/config/device-tree/overlays/systimer/status
applied
最後にデバイスツリーを確認しておきます。
timer@7e003000が追加されていることが確認できます。
l$ s /proc/device-tree/soc/
'#address-cells' hvs@7e400000 ranges
'#size-cells' i2c0mux rng@7e104000
aux@7e215000 i2c@7e205000 serial@7e201000
axiperf i2c@7e804000 serial@7e215040
compatible i2c@7e805000 smi@7e600000
cprman@7e101000 i2s@7e203000 sound
csi@7e800000 interrupt-controller@7e00b200 spi@7e204000
csi@7e801000 local_intc@40000000 spi@7e215080
dma-ranges mailbox@7e00b840 spi@7e2150c0
dma@7e007000 mailbox@7e00b880 thermal@7e212000
dpi@7e208000 mmc@7e202000 timer@7e003000
dsi@7e209000 mmc@7e300000 txp@7e004000
dsi@7e700000 mmcnr@7e300000 usb@7e980000
fb name v3d@7ec00000
firmware phandle vcsm
firmwarekms@7e600000 pixelvalve@7e206000 vec@7e806000
gpio@7e200000 pixelvalve@7e207000 virtgpio
gpiomem pixelvalve@7e807000 watchdog@7e100000
gpu power
hdmi@7e902000 pwm@7e20c000
最後に
いかがでしたでしょうか。
起動後にデバイスツリーを更新したい場合にはオーバーレイ、と覚えておきましょう。
コメント