3.1、キャラクターデバイスドライバーの基礎
デバイスファイルは通常/ devディレクトリにあります:
crw-rw-rw- 1 root root 5, 0 2020-04-17 18:51 tty
crw-rw---- 1 radio radio 237, 3 2020-04-17 18:51 ttyC0
crw-rw---- 1 radio radio 237, 7 2020-04-17 18:51 ttyC1
ここで、cはキャラクターデバイスを表します。現在のLinuxシステムでは、デバイスファイルは通常自動的に作成されますが、mknodコマンドを使用して手動でデバイスファイルを作成することもできます。
# mknod /dev/vser0 c 256 0
# ls -li /dev/vser0
46347 crw-rw---- 1 root root 256, 0 2020-04-19 17:36 /dev/vser0
mknodコマンドはノードを作成します。Linuxでは、ノードはファイルを表します。ファイルを作成する主な仕事は、ノード番号(46347一意)を含む新しいノード(ノード)を割り当てることです。例としてext2ファイルシステムを取り上げます。
/*fs/ext2/ext2.h*/
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Creation time */
__le32 i_mtime; /* Modification time */
......
__le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
......
};
iノードメンバーの構造は、/ fs / ext2 / inode.cの上記の構造で説明されています。
static int __ext2_write_inode(struct inode *inode, int do_sync) {
struct ext2_inode *raw_inode = ext2_get_inode(sb, ino, &bh); //获得一个要写入磁盘的ext2_inode结构,并初始化了部分成员。
}
同様に、ディレクトリ自体はファイルであり、fs / ext2 / ext2.hにstruct ext2_dir_entry
ディレクトリを記述する構造もあります。
mknodを実行すると、ファイル名、ファイルタイプ、メジャーおよびマイナーデバイス番号、その他の情報がディスクに保存されます。
3.2ファイルを開くには?
- プロセスのメンバー(task_struct)(task_struct-> file_struct)この構造体には、開いているファイルの情報を保持するために使用されるポインター配列fd_arrayがあります。配列fd_arrayの各要素は、ファイル構造へのポインターです。
- カーネルのオープンシステムコールに対応する関数はsys_openで、sys_openはdo_sys_openを呼び出します。
- do_sys_openはgetname関数を呼び出してファイル名をユーザー空間からカーネル空間にコピーし、次にget_unused_fd_flagsを呼び出して未使用のファイル記述子fdを取得します。
- do_filp_openを呼び出してファイル構造を構築し、内部のメンバーを初期化します。最も重要なことは、f_opメンバーがドライブ操作メソッドfile_operationsを指すようにすることです。ドライバーのオープン操作は、file_operationsのオープン関数ポインターを介して呼び出すことができます。
- do_filp_openの呼び出しが成功すると、fd_install関数が呼び出され、取得したファイル記述子を添え字として使用してfd_array配列にアクセスし、添え字に対応する要素が新しく作成されたファイル構造を指します。
- 最後に、システムコールはアプリケーションレイヤーに戻り、開いているファイルのファイル記述子として配列のインデックスを返します。
キャラクターデバイスの場合、デバイス番号、cdev、およびfile_operationsは非常に重要です。カーネルがパス名に対応するiノードを見つけた後、ドライバーとの接続を確立するには、最初に、iノードのデバイス番号に従ってcdevを見つけ、次にcdevに従ってfile_operationsを見つけますコレクション。