原文地址:
http://blog.csdn.net/wooin/archive/2007 ... 62825.aspx
《Linux设备设备驱动程序(第三版)》学习笔记之三:
sleepy设备的使用
By: 吴垠
Date: 2007-07-05
Email: lazy.fox.wu#gmail.com
Homepage:
http://blog.csdn.net/wooin
Copyright: 该文章版权由吴垠所有。可在非商业目的下任意传播和复制。
对于商业目的下对本文的任何行为需经作者同意。
联系方式:lazy.fox.wu#gmail.com
--------------------------------------------------------------------------------
1. 写在前面:
a.
在进行下面的工作之前请先阅读我 的文章《在 Linux 2.6内核下编译可以加载的内核模块》,配 置好可加载内核模块的Linux环境
b.
下载《Linux设备设备驱动程序(第三版)》配套的源代 码,在这里可 以下载到,如果无法下载的话可以留言或者给我发邮件索取。
c.
本文的工作环境是Fedora Core 5,用“uname -r”查看内核版本是:2.6.15-1.2054_FC5
d.
本文主要针对的是《Linux设备设备驱动程序(第三 版)》中第六章:高级字符设备驱动程序操作,第151页中举了个例子用来说明简单的休眠,本文记录了我对该例子的实现和运行。
e.
下文的有些操作需要root权限,所以请尽量用root用 户来执行命令。
2. 源代码包解压后进入misc-modules文件夹,其中的文件有:
[wooin@15:05 misc-modules]$ pwd
/home/wooin/ldd.3rd.examples/misc-modules
[wooin@15:06 misc-modules]$ ll
总计 60K
-rw-r--r-- 1 wooin bao 2.1K 2005-02-01 04:31 complete.c
-rw-r--r-- 1 wooin bao 2.0K 2005-02-01 04:31 faulty.c
-rw-r--r-- 1 wooin bao 463 2005-02-01 04:31 hello.c
-rw-r--r-- 1 wooin bao 1.2K 2005-02-01 04:31 hellop.c
-rw-r--r-- 1 wooin bao 6.1K 2005-02-01 04:31 jiq.c
-rw-r--r-- 1 wooin bao 7.4K 2005-02-01 04:31 jit.c
-rw-r--r-- 1 wooin bao 2.3K 2005-02-01 04:31 kdataalign.c
-rw-r--r-- 1 wooin bao 1.5K 2005-02-01 04:31 kdatasize.c
-rw-r--r-- 1 wooin bao 987 2005-02-01 04:31 Makefile
-rw-r--r-- 1 wooin bao 2.0K 2005-02-01 04:31 seq.c
-rw-r--r-- 1 wooin bao 6.1K 2005-02-01 04:31 silly.c
-rw-r--r-- 1 wooin bao 2.2K 2005-02-01 04:31 sleepy.c
其中sleepy.c就是本文要讲的文件,先打开该文件,将printk()函数中的“KERN_DEBUG1”改为
“KERN_ALERT”,保存退出,这是为了可以在/var/log/messages 文件中看到调试信息。
3. 编译:
直接在misc-modules目录下运行make命令就可以编译通过,如果编译有问题请看我的这篇文章
《在 Linux 2.6内核下编译可以加载的内核模块 》
编译成功后会生成很多文件,其中有一个sleepy.ko,就是我们要的内核模块,其部分源码在《Linux设备设备驱动程序(第三 版)》中第六章:高级字符设备驱动程序操作,第151页。
4. 将设备添加到内核中去:
运行命令:
# ismod sleepy.ko
将其添加到内核中去,此时内核已经可以认出sleepy设备了,但是我们用户却无法访问,因为目前在用户空间中还没有sleepy这个设备,也就是说在 /dev/中还没有sleepy设备,需要我们手动添加。首先查看
/proc/devices文件找到sleepy设备,并找到其主设备号,比如:
[root@FOX misc-modules]# cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
4 ttyS
:
:
180 usb
189 usb_device
226 drm
253 sleepy # 查到sleepy的主设备号是253
254 pcmcia
Block devices:
1 ramdisk
1 ramdisk
3 ide0
7 loop
8 sd
:
:
再在/dev/目录中创建sleepy设备:
// 其中253是主设备号,你可以根据你的情况自己修改这个值,0是次设备号
# mknod /dev/sleepy c 253 0
// 查看我们新添加的设备
# ls -l /dev/sleepy
crw-r--r-- 1 root root 253, 0 08-03 15:34 /dev/sleepy
5. 试试设备:
根据书中介绍,sleepy设备是用来演示简单休眠的:当读该设备的时候进程会进入休眠状态,直到有其他进程写该设备,读进程才会被唤醒,我们来读 sleepy设备:
# dd if=/dev/sleepy of=~/temp
上面命令的意思是从/dev/sleepy设备中读取数据,并写到 ~/temp文件中,当按下回车键后,命令行就被挂起了,想死掉了一样,查看/var/log/messages文件可以看到类似下面的内 容:
“Aug 3 15:58:20 FOX kernel: process 13534 (dd) going to sleep”
这个是sleepy.c中函数sleepy_read()里的调试信息,告诉你进程已经sleep了
此时我们打开另一个终端运行下面的命令来写sleepy设备:
# ll > /dev/sleepy
该命令会马上返回,并且在/var/log/messages文件中输出调试信 息:
“Aug 3 16:05:22 FOX kernel: process 13583 (ls) awakening the readers...”
这个是sleepy.c中函数sleepy_write()里的调试信息,告诉你当前进程开始唤醒读进程了。
我们再回过头看看刚才挂起的读操作,发现“dd if=/dev/sleepy of=~/temp”命令已经返回了,并且在/var/log/messages文件中输出调试信息:
Aug 3 16:05:22 FOX kernel: awoken 13534 (dd)
这个是sleepy.c中函数sleepy_read()里的调试信息,告诉你进程已经被唤醒了
6. 相关代码:
跟踪一下printk打印出来信息的先后顺序,就可以大致了解整个“休眠”和“唤醒”的过程了。
34 ssize_t sleepy_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)35 {36 printk(KERN_ALERT "process %i (%s) going to sleep\n",37 current->pid, current->comm);38 wait_event_interruptible(wq, flag != 0);39 flag = 0;40 printk(KERN_ALERT "awoken %i (%s)\n", current->pid, current->comm);41 return 0; /* EOF */42 }43 44 ssize_t sleepy_write (struct file *filp, const char __user *buf, size_t count,45 loff_t *pos)46 {47 printk(KERN_ALERT "process %i (%s) awakening the readers...\n",48 current->pid, current->comm);49 flag = 1;50 wake_up_interruptible(&wq);51 return count; /* succeed, to avoid retrial */52
《Linux设备设备驱动程序(第三版)》学习笔记之三:sleepy设备的使用
-
- 帖子: 37
- 注册时间: 2006-11-15 11:50