7

ダミーのブロック デバイスを作成するブロック ドライバー プログラムを作成しました ( sbd0)。そのブロックデバイスのすべてのデバイス操作を登録しました: ( include/linux/blkdev.h2.6.32 カーネルソースを参照)

static struct block_device_operations sbd_ops = {
    .owner           = THIS_MODULE,
    .open            = sbd_open,
    .release         = sbd_close,
    .ioctl           = sbd_ioctl,
    .getgeo          = sbd_getgeo,
    .locked_ioctl    = sbd_locked_ioctl,
    .compat_ioctl    = sbd_compat_ioctl,
    .direct_access   = sbd_direct_access,
    .media_changed   = sbd_media_changed,
    .revalidate_disk = sbd_revalidate_disk
};

ドライバープログラムをコンパイルしました。モジュールを挿入して/dev/sbd0作成しました。次に、ドライバー コードをテストします。というわけで、以下のような申請書を書きました。

fd = open("/dev/sbd0", O_RDONLY); 
retval = ioctl(fd, BLKBSZGET, &blksz); //trying to get logical block size

出力は次のとおりです。4096

私は疑問に思いました: ioctl を実装していませんでしたBLKBSZGET。my を呼び出さずsbd_ioctl、代わりにデフォルトのドライバーを使用して結果を返しました。の場合open、それを実行し、(私が実装した)とclose呼びます。そして、私は試しました:sbd_opensbd_close

retval = ioctl(fd, HDIO_GETGEO, &geoinfo);

呼び出しましsbd_getgeoたが、呼び出すと思いましたsbd_ioctl

ここに私の質問があります:

  1. ドライバーを実装し、デバイスを作成しました。そのデバイスで何らかの操作を実行する場合、ドライバー アプリケーションを呼び出す必要があります。しかし、いくつかのドライバー関数といくつかのデフォルトのドライバー関数をどのように使用するのでしょうか?
  2. ioctl(fd, HDIO_GETGEO, ..)呼び出しを呼び出しませんでし.ioctlたが、呼び出し.getgeoました。これはどのように可能ですか?
4

1 に答える 1

6

ioctlディスパッチは、ドライバーの特定のルーチンを呼び出すことなく、一部の ioctl を直接処理する関数blkdev_ioctlによって処理されます。

の場合HDIO_GETGEO、ドライバーのgetgeo関数を直接呼び出します (カーネル 3.13.6 から、2.6.32 以降あまり変わっていないようです):

[...]
/*
 * We need to set the startsect first, the driver may
 * want to override it.
 */
memset(&geo, 0, sizeof(geo));
geo.start = get_start_sect(bdev);
ret = disk->fops->getgeo(bdev, &geo); /* <- here */
[...]

の場合BLKBSZGET、 を呼び出しblock_size(bdev))、単に を返しますbdev->bd_block_size

他の ioctl で何が起こるかを知る必要がある場合は、ここを参照blkdev_ioctlしてください。block/ioctl.c

于 2014-04-24T10:37:20.317 に答える