Presentation is loading. Please wait.

Presentation is loading. Please wait.

■デバイスドライバIF - ドライバの登録 ブロックデバイスのドライバの登録は、register_blkdev関数を用いて、ブロックデバイスドライバの 登録テーブルblkdev[ ]に、デバイス名とデバイス操作関数テーブルの登録を行う。 unregister_blkdev関数はその逆に登録を抹消する。

Similar presentations


Presentation on theme: "■デバイスドライバIF - ドライバの登録 ブロックデバイスのドライバの登録は、register_blkdev関数を用いて、ブロックデバイスドライバの 登録テーブルblkdev[ ]に、デバイス名とデバイス操作関数テーブルの登録を行う。 unregister_blkdev関数はその逆に登録を抹消する。"— Presentation transcript:

1 ■デバイスドライバIF - ドライバの登録 ブロックデバイスのドライバの登録は、register_blkdev関数を用いて、ブロックデバイスドライバの 登録テーブルblkdev[ ]に、デバイス名とデバイス操作関数テーブルの登録を行う。 unregister_blkdev関数はその逆に登録を抹消する。 キャラクタデバイスの場合は、register_chrdev関数、unregister_chrdev関数を用いる。 register_blkdev(デバイスメジャー番号, デバイス名, デバイス操作関数テーブル) {     if (デバイスメジャー番号 の指定が無いなら) { ブロックデバイス登録テーブルblkdev[]の空きスロットを探し、        デバイス名とデバイス操作関数テーブルを登録する。 } else { ブロックデバイス登録テーブルblkdev[デバイスメジャー番号]に、 }

2 ブロック型デバイスの場合は、これ以外にもデバイスの初期化時に以下のテーブルにデバイス情報を
設定しておかねばならない。 また割り込みを利用するデバイスでは、request_irq関数を用いて割り込みハンドラを登録して置かねば ならない。(非常に汚いインターフェイスだ) blk_dev[]テーブル メジャー番号毎に、ドライバ起動関数を登録する(request_fnメンバ)。 この関数の登録は必須である。 blk_size[][]テーブル ・メジャー番号マイナー番号毎に、デバイスのサイズを設定する. 未設定の場合は、ブロックデバイスアクセス時にサイズのチェックを行わない. ・blksize_size[][]テーブル メジャー番号マイナー番号毎に、ブロックサイズを指定する。 ・未設定時は1Kbyteとなる。通常は設定しないで良い。 hardsect_size[][]テーブル ・メジャー番号マイナー番号毎にセクタサイズを指定する。 ・未設定時は512byteとなる。 ・現在は参照されていないように思われる。 read_ahead[]テーブル メージャー番号毎に、先読みするブロック数を指定する。

3 ■デバイスドライバIF - ブロック I/O起動インターフェイス
Linuxでは、ファイルシステムからのI/O要求をブロックデバイスのドライバへの要求に変換する モジュールが存在する。 ブロック型デバイスドライバは、以下のようなデータ構造を利用して呼び出される。 各デバイス(メジャー番号)毎に、I/Oリクエストを繋ぐためのヘッダを用意している。 ファイルシステムからI/O要求(ll_rw_block関数) があるとブロック I/O共通関数内に用意されている request構造体にファイルシステムから渡されたbufferを繋ぐ。 I/O要求のリンクが完了したのち、ヘッダに登録されているデバイスドライバの起動関数を呼び出す。 blk_dev[ ] (*request_fn)() current_request do_baa_request () (*request_fn)() current_request next cmd bh bhtail next cmd bh bhtail next cmd bh bhtail (*request_fn)() current_request (*request_fn)() current_request (*request_fn)() current_request b_reqnext b_reqnext b_reqnext

4 /O要求(request)をblk_devにリンクするとき、I/Oブロック順に繋ぎ直し I/Oのスケジューリングを行う。
ll_rw_block()の処理 隣り合ったセクタへのI/Oを一つにまとめている。 ブロックの順序をセクタ順に並び替えている。 ドライバを起動する。 I/O完了時の処理 デバイスからの終了通知 end_request関数。(伝統UNIXのiodone関数相当) bh->b_end_io()を呼び出し、バッファをファイルシステムヘ返却 このリクエストにバッファが無くなれば、 リクエスト自体も解放 リクエストをキューから外し、bh->b_end_io()を呼び出す。汎用関数を利用せず、同様の処理を 自前で持っているものもある。

5 ■デバイスドライバIF - デバイスファイル
デバイスファイル自体は各ファイルシステム上の通常のファイルとして存在する。 単にファイルタイプがデバイスファイルを示していることと、属性としてデバイス番号を持っているだけ である。 ブロックデバイスファイルをオープンすると、各ファイルシステム(ext2など) はメモリiノードの初期化時 (read_inode関数)に、ブロックデバイスファイル共通の仮のiノード操作関数テーブル blkdev_inode_operationsをiノードに登録、ファイル操作関数テーブルdef_blk_fopsをファイル構造体に 登録する。 その後、vfsはこの操作関数テーブルを通して、仮のブロックデバイスオープン関数 blkdev_open関数を呼び出す。 blkdev_open関数は、デバイス番号をインデックスとしてドライバ登録テーブルblkdev[]を検索 (get_blkfops関数)し、目的のデバイスドライバ固有のデバイス操作関数テーブルを見つけ出し、 これを登録し直す。 登録後、本当のデバイスのオープン関数を呼びなおす。(図ではbaa_open関数) その後のデバイスへのアクセスは全て新しく登録しなおしたデバイス操作関数テーブルを通して 行われる。 ブロックデバイスでは通常、read/write/fsync処理関数としてそれぞれ block_read, block_write, block_fsync がファイル操作テーブルに登録されている。これらの関数は、バッファキャッシュ経由のread/writeとして 動作する。バッファキャッシュ管理から上記ブロック I/Oインターフェイスを通して、再度デバイスドライバが 呼び出される。 ブロックデバイス特有の機能はデバイス操作関数テーブルに登録されている。デバイスのioctlや、 リムーバル可能なデバイスに対する操作などが登録されている。(ドライバの各種テーブルもここのデバイス 操作関数テーブルに統合した方が美しいと思われる)

6 VFS Device File EXT2FS Block Device Driver file f_op dentry inode
i_fop i_op i_bdev Device File def_blk_fops block_device blkdev_open() blkdev_close() blkdev_ioctl() bd_op blkdev_read() blkdev_write() blkdev_fsync() resister_blkdev() EXT2FS Buffer Cache ll_rw_block() baa_fops baa_open() baa_release() baa_ioctl() baa_media_change() Block Device Driver

7 character Devoce Driver
キャラクタ型デバイスの場合も同様である。キャラクタ型デバイスファイルのiノード生成時に iノードに キャラクタデバイスファイル共通の仮の iノード操作関数テーブルchrdev_inode_operationsが、ファイル 構造体にデバイス操作関数テーブルdef_chr_fopsが登録される。 その後、この操作関数テーブルを通して呼びだされる、仮のキャラクタデバイスオープン関数chrdev_open 関数が、ドライバ登録テーブルchrkdev[]を参照しそのデバイスのデバイス操作関数テーブルに登録しな おす。登録後、そのデバイス操作関数テーブルを通してデバイスへのアクセスが行われる。 VFS file f_op dentry inode i_fop i_op i_bdev Device File def_blk_fops chrdevs[ ] (dummy) chrdev_open() EXT2FS resister_chrdev() 補足 Linuxのブロックデバイスアクセスは 必ずバッファキャッシュ経由となる。 伝統的UNIXのようなRAWデバイス アクセスは存在しない。 (rawアクセスをサポートするための パッチは存在する) foo_fops foo_read() foo_write() foo_open() foo_ioctl() character Devoce Driver

8 ■デバイスドライバIF - デバイスドライバのモデル
以下に、典型的なブロックデバイスドライバの構成を示す。 (ここでは仮にxxxデバイスドライバとする) ファイルオペレーションテーブルのread/write/fsyncオペレーションは、バッファキャッシュ経由の関数 block_read,block_write,block_fsync が登録されている。これらの関数は、blk_dev[]テーブルに登録した I/O起動関数のインターフェイスから再度ドライバ呼び出しを行う。(下図の、baa_request関数) block_read,block_write,block_fsyncの要求に加え、ファイルシステムからのファイルやディレクトリの 操作要求は全て同じパスでアクセスされる。(ll_rw_block関数) これらの要求は、全てblk_dev[]テーブル に登録したI/O起動関数の呼び出しに一本化される。(下図の、baa_request関数) baa_request関数は、blk_dev[]に登録された要求に従い、I/Oを発行する。この関数中では待ちに入らず、 即関数呼び出しもとに戻る。しばらくしてI/Oが完了すると、ハードウェアからI/O完了割り込みが発生し、 割り込みハンドラbaa_interrupt関数が起動される。この関数ではend_request関数を呼び出しI/Oの完了 を上位モジュールに告げる。その後まだblk_dev[]テーブルに要求が溜まっていたら、その要求に対し 再度I/Oを発行する。このループはblk_dev[]テーブルに要求が無くなるまで続けられる。 baa_open関数は、デバイスファイルのopen処理時の他に、 mount処理時に呼び出される。この関数は、 デバイスを利用可能の状態にする。 baa_release関数はbaa_open関数の逆で、umount処理/デバイスの close処理から呼び出される。またmount処理はリムーバブルデバイスに対応するため、 check_baa_change関数、baa_revalidate関数を呼び出す。それぞれメディアの交換があったかいなかを 調べる関数、再度デバイスを利用可能な状態にする関数、である。 baa_ioctl関数は、そのドライバ(もしくはそのハードウェア)固有の処理であり、そのインターフェイス および処理内容はドライバ設計者にゆだねられている。

9 File System Baa device Driver Baa Hardware Buffer Cache
read(file) write(file) open(“/dev/xxx”) mount(“/dev/xxx”) umount(“/dev/xxx”) close(device) ioctl(device) read(device) write(device) fsync(device) file_operations defblk_fops block_device_operations baa_fops check_baa_change() baa_revalidate() baa_open() baa_re;lease() baa_ioctl() File System blk_dev[ ] Baa device Driver Baa Hardware block_read() block_write() block_fsync() do_baa_request() Buffer Cache ll_rw_block() end_request() end_buffer_io_sync() end_buffer_io_async() baa_interrupt()

10 ■デバイスドライバIF - SCSIドライバの構成
Scsi_Host Scsi_Driver scsi_hostlist Scsi_Cmnd Scsi_Cmnd Scsi_Cmnd host_queue hostt select_queue_depth hostdata[ ] (aic7xxx host) host device_queue id: lun vendor[ ] model[ ] host device scsi_hosts Scsi_Host Scsi_Device Scsi_Device Scsi_Device sym5c8XX Driver host_queue hostt scsi_request_fn scsi_request_fn scsi_request_fn Scsi_Host_ Template Scsi_Host Scsi_Device host_queue hostt hostdata[ ] scsi_request_fn aic7XXX Driver SD Driver rscsi_disks SD Driver Scsi_Host_ Template device do_sd_request() sd_detect() sd_init() device do_sr_request() sr_detect() sr_init() Scsi_Host_ Template sd templete Scsi_Host_ Template sr templete scsi_devicelist

11 SD Driver SCSI common routine Host Adapter Driver do_sd_request()
block_device_operations sd_fops aic7xxx_queue() do_aic7xxx_isr() sd_open() sd_ioctl() scsi_do_cmd() scsi_rctrf_command() scsi_buttom_half_handler() scsi_done() scsi_finish_command() do_sd_request() rw_intr() blk_dev [ ] sym53c8xxx_queue_ command() sym53c8xx_intr() end_scsi_request() ll_rw_block() end_buffer_io_sync() rw_intr() do_sr_request() block_device_operations sr_fops SR Driver


Download ppt "■デバイスドライバIF - ドライバの登録 ブロックデバイスのドライバの登録は、register_blkdev関数を用いて、ブロックデバイスドライバの 登録テーブルblkdev[ ]に、デバイス名とデバイス操作関数テーブルの登録を行う。 unregister_blkdev関数はその逆に登録を抹消する。"

Similar presentations


Ads by Google