0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Device Treeは何をしているのか【組み込みLinuxの仕組み C-7】

0
Last updated at Posted at 2026-07-23

この記事の前提

  • C-5C-6で、ブートローダーがカーネルとDTBを準備する流れを見た方を想定します
  • Device Treeの読み方と小さな変更までを扱い、ドライバ実装は扱いません
  • コード例とコマンド出力は説明用です。実機のモデル、OS、接続デバイスに合わせて確認してください

はじめに

C-6の説明用ログには、.dtbというファイルが登場しました。今回は、このDevice Treeが何を記述し、Linuxがどう使うかを整理します。

DTS、DTSI、DTB、overlayと似た用語が並びますが、押さえる流れは「ハードウェアの事実を記述し、起動時にカーネルへ渡す」です。

Device Treeが必要な理由

PCIやUSBのように列挙の仕組みを持つバスでは、OSが接続デバイスから情報を取得できます。一方、SoC内蔵ペリフェラルや基板直結のデバイスには、OSが実装状態を完全には自動判定できないものがあります。

I2Cでは応答するアドレスを走査できますが、その結果だけで正確な型番、割り込み線、リセットGPIO、電源、クロックまで確定できません。そこで、基板上の構成をデータとしてOSへ渡します。

Linuxカーネルの公式資料では、Device Treeを「OSが機械の詳細をハードコードせずに済むよう、ハードウェアを記述するデータ構造」と説明しています。Linux and the Devicetree

Device Tree自体がレジスタを設定して機器を動かすわけではありません。記述を読んだブートローダーやカーネル、デバイスドライバが、必要な初期化を行います。

組み込みLinuxの仕組み_⑩DeviceTree橋渡し_icon

DTS、DTSI、DTB、overlay

用語 役割 注意点
DTS Device Tree Source。ボードや構成を記述するソース .dts
DTSI 複数DTSからincludeする共通記述 .dtsi。SoC共通部などに使われる
DTB DTSをdtcで変換したFlattened Device Treeのバイナリ カーネルへ渡される形式
overlay/DTBO ベースツリーへ適用する差分 ブート前適用と実行時適用があり、仕組みは環境依存
binding 各デバイスのノード名・プロパティ・制約を定める仕様 LinuxではYAML schemaによる検証が進んでいる

典型的には、SoC共通のDTSIをボードDTSがincludeし、ボードで使用するI/O、接続デバイス、GPIOなどの差分を記述します。ただし、ファイル分割の方針はベンダーBSPやカーネル版で異なります。

DTSの中身を読む

UARTとI2C接続OLEDを説明用に簡略化した例です。実際に必要なプロパティは、対象カーネルのbindingを確認してください。

&uart1 {
    pinctrl-names = "default";
    pinctrl-0 = <&uart1_pins>;
    status = "okay";
};

&i2c0 {
    status = "okay";

    oled@3c {
        compatible = "solomon,ssd1306";
        reg = <0x3c>;
    };
};

status

ノードを利用可能として扱うかを示します。よく見る値は"okay""disabled"です。statusが存在しない場合の扱いも仕様で定義されているため、「すべてのノードに必須」ではありません。

compatible

ハードウェアがどのbindingに適合するかを示す文字列です。Linuxはこの値などを用いて、対応するドライバとのマッチングを行います。

「ドライバ名を直接指定する文字列」ではありません。ハードウェアを表す安定した識別子であり、利用できる文字列と必須プロパティはカーネルのDocumentation/devicetree/bindings/で確認します。

regなどのプロパティ

regは親バスにおけるアドレスなどを表します。値のセル数と意味は、親ノードの#address-cells#size-cellsやbindingで決まります。割り込み、クロック、リセット、GPIO、電源なども、bindingに従って記述します。

pinctrl

コントローラーを有効にしても、信号が目的の端子へ割り当てられているとは限りません。pinmux、プルアップ/プルダウン、ドライブ能力などをpinctrlで指定する構成があります。

Raspberry PiでI2Cを有効にする

Raspberry Pi OSでは、config.txtからDevice Treeパラメーターとoverlayを利用できます。Bookworm世代の標準パスは/boot/firmware/config.txtです。

dtparam=i2c_arm=on

再起動後、I2Cデバイスファイルを確認します。

ls -l /dev/i2c*

i2c-toolsを導入した環境では、バス番号を確認してから走査できます。

sudo apt install i2c-tools
sudo i2cdetect -y 1

SSD1306系モジュールがアドレス0x3cへ応答する構成なら、説明上は次のように見えます。

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --

これはそのアドレスに応答があったことを示すだけで、SSD1306だと識別した結果ではありません。カーネルドライバがアドレスを使用中の場合はUUと表示されることもあります。また、走査処理が不具合を起こすデバイスもあるため、対象デバイスの仕様を確認し、製品運用中にむやみに実行しません。

Raspberry Piのdtparamdtoverlayの適用方法は、公式Device Tree設定資料/boot/firmware/overlays/READMEで確認できます。

カーネルが受け取ったツリーを確認する

ソースファイルではなく、実行中のカーネルが受け取った内容を確認します。

ls /sys/firmware/devicetree/base

device-tree-compilerが入っていれば、ファイルシステム表現からDTS形式へ変換できます。

sudo apt install device-tree-compiler
dtc -I fs -O dts /sys/firmware/devicetree/base | less

逆変換時の警告が、直ちに実機の異常を意味するとは限りません。元のラベルやinclude構造はDTBに残らないため、逆変換結果は元ソースと同じ見た目にはなりません。

確認したいノードがある場合は、次も組み合わせます。

dmesg | grep -i -E 'i2c|ssd130|probe|defer'
ls -l /sys/bus/i2c/devices/

変更時のハマりどころ

  • bindingを確認せずプロパティを書く:似たデバイスでも必須項目が異なります。対象カーネルのYAML schemaとドライバを確認します
  • compatibleの誤記:ドライバがマッチしません。ビルド時のdtbs_checkや起動後のdmesgで確認します
  • コントローラーと子デバイスを混同する:I2Cバスを有効にする記述と、バス上のデバイスを記述する作業は別です
  • pinctrlや電源を見落とすstatus = "okay"だけでは、端子、クロック、レギュレーターがそろわない場合があります
  • BSPの構成要素を別々に更新する:カーネル、DTB、overlay、ブートローダーを、ベンダーが検証した組み合わせから外す場合は互換性を評価します
  • 編集対象を間違える:別パーティションや別ファイルのconfig.txt、別DTBを編集していることがあります。ブートログと実行中ツリーで確認します

Device Treeを契約書として扱う

SoMと自社キャリアを組み合わせる場合、回路図の変更とDevice Treeの変更を対応づけます。

回路側の変更 Device Treeで確認する項目
UARTの接続先を変更 ノード、pinctrl、alias、console指定
I2Cデバイスを追加 親バス、compatiblereg、割り込み
GPIO極性を変更 GPIO指定子とactive high/low
PHYやクロックを変更 PHYノード、clock、reset、電源
基板リビジョン追加 対応DTS/overlayと識別方法

Device Treeは回路図の代わりではなく、Linuxが必要とするハードウェア情報の表現です。回路図、部品表、DTS、ドライバ、評価項目をまとめてレビューすると、基板改版時の漏れを減らせます。

実行中のモデルとaliasを追う

手元のLinuxボードで、モデル名と起動引数を確認してみてください。

tr -d '\0' < /sys/firmware/devicetree/base/model; echo
cat /proc/cmdline

次に/sys/firmware/devicetree/base/aliasesを開き、serial0i2cが実際のどのノードを指すかを追うと、Device TreeがLinuxのデバイス名へつながる感覚をつかめます。

まとめと次回

  • Device Treeは、OSが自動判定できない基板構成を記述するデータ
  • DTS/DTSIからDTBを作り、必要に応じてoverlayを適用する
  • 読む鍵はstatuscompatiblereg、pinctrlとbinding
  • I2Cアドレス走査は型番識別ではなく、ドライバ使用中はUUになる場合もある
  • 実行中のツリーとdmesgを確認し、編集したソースだけで判断しない

次回C-8では、rootfsと自動起動を扱います。自作アプリを、電源投入後にサービスとして起動する構成へ進めます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?