link もっと前
   2016年 2月 14日 -
      2016年 2月 14日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

Linux デバイスドライバの probe が呼ばれるまで

Linux はバスにデバイスを追加すると、ドライバの probe() というコールバックが呼ばれますが、こいつがどこから呼ばれているのか?のメモです。

結論から言うと「たくさんありすぎて全部は分からない」ですが、後で調べるときの取っ掛かりになると信じて、とりあえず 2つの経路をメモしておきます。

ドライバとデバイスの例

来年の自分が「何言ってんのお前??」と言っている気がしたので、例を挙げておきます。platform_bus を例に取りますと、下記のようにデバイスドライバを登録します。

platform_bus のデバイスドライバを登録する

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>

static int sample_platform_probe(struct platform_device *pdev)
{
    return 0;
}

static int sample_platform_remove(struct platform_device *pdev)
{
    return 0;
}

static struct platform_driver hogehoge_driver = {
    .probe  = hogehoge_probe,
    .remove = hogehoge_remove,
    .driver = {
        .name   = "hogehoge"
    },
};

module_platform_driver(hogehoge_driver);

このドライバに対して、下記のようにデバイスを追加します。platform_bus の場合、デバイス名は "ドライバ名.ID 番号" つまり hogehoge.0 という名前になるようです。

platform_bus にデバイスを追加する

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>

static struct platform_device *pdev = NULL;

static int __init hogehoge_device_init(void)
{
    int ret;

    pdev = platform_device_alloc("hogehoge", 0);
    if (pdev == NULL) {
        //error
        return -ENOMEM;
    }

    ret = platform_device_add(pdev);
    if (ret != 0) {
        //error
        platform_device_put(pdev);
        return -ENOMEM;
    }

    return 0;
}

static void __exit hogehoge_device_exit(void)
{
    platform_device_del(pdev);
}

module_init(hogehoge_device_init);
module_exit(hogehoge_device_exit);

ドライバの登録とデバイスの追加はどちらが先でも構いません。

ドライバを登録してからデバイスを追加するか、その逆、デバイスを追加してからドライバを登録すれば、デバイスドライバの probe() コールバック、つまり hogehoge_probe() が呼ばれます。

ぱっと見、デバイス追加が先で、ドライバ登録が後の場合をケアする必然性があるのか?疑問を感じるかもしれませんが、USB デバイスが既に筐体に接続されていて、USB ドライバをカーネルモジュールでロードする場合を考えると、ごく普通の状況ですよね。

経路その 1 - デバイス追加がトリガ

ドライバを登録してからデバイスを追加する場合と「思われる」経路の一例です。ちゃんと呼び出しの条件を追っていないので、条件が間違っているかもしれません。

- platform_device_add()
  - device_add()
    - bus_probe_device()
      - device_initial_probe()
        - __device_attach()
          - __device_attach_driver()
            - driver_probe_device()
              - really_probe()
                - drv->probe()

デバイス追加の際に呼ばれる device_add() が契機になるようです。platform_bus の場合は platform_device_add() が内部で呼んでいます。

経路その 2 - ドライバ追加がトリガ

デバイスを追加してからドライバを登録する場合の経路と思われる一例です。ちゃんと呼び出しの条件を追っていないので、条件が間違っているかもしれません。

- __platform_driver_register()
  - driver_register()
    - bus_add_driver()
      - driver_attach()
        - __driver_attach()
          - driver_probe_device()
            - really_probe()
              - drv->probe()

ドライバ追加の際に呼ばれる driver_register() が契機になるようです。先ほどの例だと module_platform_driver() マクロが勝手に呼んでくれます。

補足

他にも device_attach() 時に __device_attach_async_helper() なる関数をワークキューにぶっ込んで非同期でデバイスを検知する系、bind_store() で手動でデバイスを検知する系がありそうです。

他にも probe() を呼び出す系はありそうですが、今のところ良くわかってません。あの手この手で動かしているんだなー、と思いました。

[編集者: すずき]
[更新: 2016年 2月 19日 01:12]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2016年 2月 14日 -
      2016年 2月 14日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 10/17 22:53

カレンダー

<2016>
<<<02>>>
-123456
78910111213
14151617181920
21222324252627
2829-----

最近のコメント 5件

  • link 17年09月23日
    すずき 「そうですね、体験していたはずなんですが、...」
    (更新:10/17 22:53)
  • link 17年09月23日
    hdk 「我々も小学校低学年の頃はまだ学校週5日制...」
    (更新:10/16 23:53)
  • link 17年09月29日
    すずき 「私も IOMMU と DDR のインタリ...」
    (更新:10/09 22:41)
  • link 17年09月29日
    hdk 「非連続物理アドレスは IOMMU を使っ...」
    (更新:10/09 00:35)
  • link 17年09月29日
    すずき 「会社ではビデオ系ハード、グラフィクス、デ...」
    (更新:10/07 12:26)

最近の記事 3件

link もっとみる
  • link 17年09月23日
    すずき 「[土曜日=休日?] 今日は土曜日で祝日(秋分の日)です。サラリーマ...」
    (更新:10/16 03:21)
  • link 17年09月29日
    すずき 「[Linux の CMA と THP] Twitter でボヤきま...」
    (更新:10/06 02:14)
  • link 17年09月30日
    すずき 「[Linux の CMA と THP その 2] 昨日(2017年...」
    (更新:10/06 01:53)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報