簡単なのから
順に作ってみよう。まず open/close 対応なソレから。簡単なキャラクタデバイスを作るを参考にしつつ。
とりあえず
デバイスファイル作らんと。メジャー番号は 128 とか空いてそげ。こんなカンジ?
# mknod /dev/fifo100128 c 128 100 # mknod /dev/fifo101128 c 128 101 # ls /dev/fifo10* -l crw-r--r-- 1 root root 128, 100 Aug 13 22:41 /dev/fifo100128 crw-r--r-- 1 root root 128, 101 Aug 13 22:41 /dev/fifo101128 #
一応なんとかなっている模様。次は実装。ええと open/close の前に register_chrdev と unregister_chrdev の使い方というあたりを参考にしつつ以下。
#include <linux/module.h> // required by all modules #include <linux/kernel.h> // required by printk() #include <linux/init.h> #include <linux/fs.h> MODULE_LICENSE("GPL"); #define DRIVERNAME "yamanetoshi" int fifo_major = 128; struct file_operations fifo_fops = { .owner = NULL, .read = NULL, .write = NULL, .ioctl = NULL, .open = NULL, .release = NULL, }; // Start/Init function static int yamanetoshi_init(void) { int ret; printk("initialize the fifo device\n"); ret = register_chrdev(fifo_major, DRIVERNAME, &fifo_fops); if(ret < 0) return ret; if(fifo_major == 0) fifo_major = ret; return 0; } // End/Cleanup function static void yamanetoshi_exit(void) { printk("cleanup the fifo device\n"); unregister_chrdev(fifo_major, DRIVERNAME); } module_init(yamanetoshi_init); module_exit(yamanetoshi_exit);
動作確認
insmod してみたら以下
# insmod yamanetoshi.ko insmod: error inserting 'yamanetoshi.ko': -1 Device or resource busy #
む。128 は SCSI 用にアサイン済みなのか (Documentation/devices.txt)。ええと、130 でヤッてみます。とりあえずデバイス消して再度作成
# rm -rf /dev/fifo10* # mknod /dev/fifo100130 c 130 100 # mknod /dev/fifo101130 c 130 101 #
でソース直して make して insmod と rmmod してみたら一応以下が出力
# tail -f /var/log/messages Aug 13 22:41:09 debian -- MARK -- Aug 13 22:52:46 debian kernel: initialize the fifo device Aug 13 23:02:03 debian kernel: initialize the fifo device Aug 13 23:02:45 debian kernel: cleanup the fifo device
printk はいっちゃん最後の方が良いな。次は open/close か。
open/close
とりあえず i/f だけ。以下なカンジ
#include <linux/module.h> // required by all modules #include <linux/kernel.h> // required by printk() #include <linux/init.h> #include <linux/fs.h> MODULE_LICENSE("GPL"); #define DRIVERNAME "yamanetoshi" int fifo_major = 130; static int yamanetoshi_open(struct inode *inode, struct file *file) { printk("yamanetoshi_open\n"); printk(" file->f_version : %lu\n", file->f_version); printk(" MINOR(inode->i_rdev): %d\n", MINOR(inode->i_rdev)); return 0; } static int yamanetoshi_release(struct inode *inode, struct file *file) { printk("yamanetoshi_close\n"); printk(" file->f_version : %lu\n", file->f_version); return 0; } struct file_operations fifo_fops = { .owner = NULL, .read = NULL, .write = NULL, .ioctl = NULL, .open = yamanetoshi_open, .release = yamanetoshi_release, }; // Start/Init function static int yamanetoshi_init(void) { int ret; printk("initialize the fifo device\n"); ret = register_chrdev(fifo_major, DRIVERNAME, &fifo_fops); if(ret < 0) return ret; if(fifo_major == 0) fifo_major = ret; return 0; } // End/Cleanup function static void yamanetoshi_exit(void) { printk("cleanup the fifo device\n"); unregister_chrdev(fifo_major, DRIVERNAME); } module_init(yamanetoshi_init); module_exit(yamanetoshi_exit);
コンパイルしてみる。
# make make -C /lib/modules/2.6.20/build M=/home/rms/kernel/kernel_exercise/5.driver_exercize modules make[1]: Entering directory `/home/rms/kernel/linux-2.6.20' CC [M] /home/rms/kernel/kernel_exercise/5.driver_exercize/yamanetoshi.o Building modules, stage 2. MODPOST 1 modules LD [M] /home/rms/kernel/kernel_exercise/5.driver_exercize/yamanetoshi.ko make[1]: Leaving directory `/home/rms/kernel/linux-2.6.20' #
パス。insmod したら??
# insmod yamanetoshi.ko #
syslog に以下のメセジ出力を確認
Aug 13 23:24:16 debian kernel: initialize the fifo device
で、試験用の以下のプログラムを用意
#include <stdio.h> #include <stdlib.h> int main(void) { FILE *fptr = NULL; if(NULL == (fptr = fopen("/dev/fifo100130", "r"))) { fprintf(stderr, "open error /dev/fifo100130"); exit(1); } fclose(fptr); fptr = NULL; return 0; }
コンパイルして実行。
$ gcc -o test_yamanetoshi -Wall test_yamanetoshi.c $ ./test_yamanetoshi $
syslog のメセジが以下
Aug 13 23:26:05 debian kernel: yamanetoshi_open Aug 13 23:26:05 debian kernel: file->f_version : 0 Aug 13 23:26:05 debian kernel: MINOR(inode->i_rdev): 100 Aug 13 23:26:05 debian kernel: yamanetoshi_close Aug 13 23:26:05 debian kernel: file->f_version : 0
f_version 属性のナニが不明ですが、一応何とかなってる模様。今後もコツコツ進めます。