Help us understand the problem. What is going on with this article?

LinuxのUIO(User space I/O) その2

More than 1 year has passed since last update.

前回の続き

デバイスツリーを使わずにUIOを使用する方法

peri_pmcという名のレジスタを0x120a0000からの4KBをユーザー空間からアクセス可能にします。
その情報をセットしてuio_pdrv_genirqのドライバを登録するだけです。

そのコードの全体はgistに貼りました。ここ
要点は以下の部分です。
実質的にplatform_device_register()を呼びだすだけです。

static struct uio_info mydev_mem = {
    .name = "my_device",
    .version = "0.1",
    .irq = UIO_IRQ_NONE,
};

static struct resource uio_resources[] = {
    [0] = {
        .name   = "peri_pmc",
        .start  = 0x120a0000,
        .end    = 0x120a0fff,
        .flags  = IORESOURCE_MEM,
    },
    [1] = {
        .name   = "DUMMY",
        .flags  = IORESOURCE_IRQ,
    },
};

static struct platform_device my_dev = {
    .name = "uio_pdrv_genirq",
    .id = -1,
    .dev = {
        .platform_data = &mydev_mem,
    },
    .resource   = uio_resources,
    .num_resources  = ARRAY_SIZE(uio_resources),
};

static int __init uio_init(void)
{
    printk(KERN_INFO "uio_init\n");
    return platform_device_register(&my_dev);
}

実際に使用するときには、struct resourceの初期化のところだけを変更すればよいと思います。
このソースをビルドしてカーネルモジュールを作成し、それを insmodコマンドで登録すれば、/dev/uio0 のデバイスファイルが作成されます。
あとは前回の記事と同様です。

注意点

  • 割り込みを使用しない場合は、上記のようにstruct uio_info のirqにUIO_IRQ_NONEするとともに、struct resourceの方にもダミーのIORESOURCE_IRQのエントリが必要です。これが無いとinsmodしたときに、"failed to get IRQ" というメッセージでエラー終了してしまいます。

  • アクセス可能にするメモリ範囲の情報は struct uio_info ではなくて、struct resourceの方に書きます。

  • rmmodするとデバイスを削除することができますが、カーネルのログに"uio_pdrv_genirqのデバイスにreleaseの関数が実装されていない" という旨のエラーメッセージが出ます。

余談

私が最初にUIOを試してみたのは、数年前のカーネル3.0の頃でした。その当時はまだARMのデバイスドライバのデバイスツリー化が必須ではなかったので、この記事のカーネルモジュールの方式でやりました。
最近になって、またUIOを試してみようとしたのですが、当時のコードはもう紛失していて、かすかな記憶を頼りに思い出すのに苦労しました。やっぱりブログに書いておくのがいいですね。

UIOのカーネル内のドキュメント、The Userspace I/O HOWTOは最終更新が2006年12月になっていて、その後の更新が反映されていません。
このドキュメントによると、割り込みを使用せずにメモリのマッピングだけ行いたい場合には"uio_pdrv" というドライバを使用すればよいように書かれています。確かにカーネル3.0の当時はこのドライバは存在しました。
しかし、その後の変更で"uio_pdrv" は削除されてしまっています。おそらくは"uio_pdrv_genirq" でirq=UIO_IRQ_NONE にして使えばよいということだったのでしょう。
その後の変更の履歴は追えていませんが、ARMのデバイスツリーの対応が追加されています。
注意点のところにも書きましたが、uio_pdrv_genirqで割り込みを使用しない場合にはuioinfoのirqをUIO_IRQ_NONEにするだけでは足りなくて、struct resourceの方にもダミーのIORESOURCE_IRQのエントリが必要でした。とてもバグくさい挙動です。
UIO_IRQ_NONEの値は0なのですが、どうやらいろいろな人が建て増し的にコードを追加した結果、uio_infoのirqが0である場合に"割り込みは使用しない"という意味と"割り込みは未設定のため他の情報を参照せよ" の2つの意味がごちゃごちゃになってしまっているようです。
本来なら最新版カーネルでも同様の症状が出るかを確認して、バグをレポートしたいところですが、組み込みLinuxでは簡単に最新のカーネルを動かすことができないのがつらいところです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした