日別アーカイブ: 2016/04/21

[Linux] device tree について

2.6.32 から 4.4 へ

Linux driver の参考書は kernel 2.6.32 辺りの知識で書かれていて,組込みの世界ではあまり新しい kernel を積極的に取り込まないこともあって,私がいる部門でも長い間内部で保持されてきた kernel を使って driver を書いていたのですが,独自の分岐で進化した kernel を maintainance する人材もいなくなり,昨年からいろいろ一新する上で kernel も vanilla kernel に追従することになりました.

昨今では自社向けソースをすべて内部で抱え続けるのも難しく,外に公開していける部分は OpenSource に貢献して協力関係を築いていくのも至極当然の流れでしょう.何故今までそうして来なかったのか不思議なくらいですが…という前置きはおいといて,そんな 2.6 時代の知識から突然最新 LTS の v4.4 の開発手法や kernel API に刷新する必要が出てきたわけです.

device tree とは

最もインパクトがあったのは device tree の導入でした.eLinuxの解説に記載がありますが,OpenFirmware の ePAPR 仕様で規定されているものを元にしたデバイス固有情報を記述するフォーマットです.Linux 以外にも FreeBSD や U-boot でも採用されていて,標準化の動きがあります.
(OpenFirmware とか PAPR と聞くと Mac 互換機の CHRP や BeOS を思い出してしまうのですが…)

実際の記述方法は devicetree.org の文法解説や Linux source の Documentation/devicetree/bindings/ に記載されていますが,実際の arch/arm/boot/dts/ 以下の各 SoC 向けソースが参考になります.

device tree の driver への取り込み方

device tree を導入すると,driver 側の記述の仕方も変わってきます.元々 module_init() や module_exit() で最初と最後を書くだけだったのが,device tree から情報を取り込む操作が必要になるわけですが,その操作は platform driver の framework がベースになります.

例えば,以下のように device tree に foo driver の記述を行うとします.識別文字列の他に,使いたいレジスタアドレスとサイズが書かれています.

/ {
    foo {
        compatible = "hoge,foo";
        reg = <0x12340000 0x200>;
    };
}; 

platform driver は,起動関数・終了関数・識別テーブルを定義します.

static struct platform_driver foo_driver = { 
    .probe  = foo_probe,
    .remove = foo_remove,
    .driver = { 
        .name = "foodriver",
        .of_match_table = foo_of_match,
    },
};
module_platform_driver(foo_driver);

識別テーブルの方は compatible で device tree に適合する識別文字列を定義します.

static const struct of_device_id foo_of_match[] = { 
    { .compatible = "hoge,foo",},
    {},
};
MODULE_DEVICE_TABLE(of, foo_of_match);

このように定義しておいて,起動関数 foo_probe() では device tree の情報を取り込んで,実際の動作に反映させていきます.

static void __init foo_probe(struct platform_device *pdev)
{
    sturce resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    void __iomem *vptr = devm_ioremap_resource(res);
    :
}

この他にも device tree 情報を取り込む platform 関数や of 関数はたくさんあり,方法もさまざまです.
一つサンプルを作って自分なりに確立しておくのが良いかと思います.