Linux设备驱动程序学习(6) -高级字符驱动程序操作[(3)设备文件的访问控制]

提供访问控制对于 一个设备节点来的可靠性来说有时是至关重要的。这部分的内容只是在open和release方法上做些修改,增加一些检查机制既可。

独享设备
最生硬的访问控制方式是只允许一个设备一次被一个进程打开(独享),这是一个设备驱动最简单的访问控制。实现十分简单,具体的代码看实验源码吧!
模块程序链接: scullsingle.tar.gz
模块测试程序链接: scullsingle-test.tar.gz
ARM9实验板的实验现象是:
[Tekkaman2440@SBC2440V4]#cd /lib/modules/

[Tekkaman2440@SBC2440V4]#insmod scullsingle.ko

[Tekkaman2440@SBC2440V4]#cat /proc/devices

Character devices:

  1 mem

  2 pty

  3 ttyp

  4 /dev/vc/0

  4 tty

  4 ttyS

  5 /dev/tty

  5 /dev/console

  5 /dev/ptmx

  7 vcs

 10 misc

 13 input

 14 sound

 81 video4linux

 89 i2c

 90 mtd

116 alsa

128 ptm

136 pts

180 usb

189 usb_device

204 s3c2410_serial

252 scullsingle

253 usb_endpoint

254 rtc

Block devices:

  1 ramdisk

256 rfd

  7 loop

 31 mtdblock

 93 nftl

 96 inftl

179 mmc

[Tekkaman2440@SBC2440V4]#mknod -m 666 scullsingle c 252 0

[Tekkaman2440@SBC2440V4]#cd /tmp/

[Tekkaman2440@SBC2440V4]#./scullsingle-test &

[Tekkaman2440@SBC2440V4]#open scullsingle is file=3

[Tekkaman2440@SBC2440V4]#echo 12345 > /dev/scullsingle

-sh: cannot create /dev/scullsingle: Device or resource busy

[Tekkaman2440@SBC2440V4]#cat /dev/scullsingle

cat: can't open '/dev/scullsingle

单用户访问
open 调用在第一次打开记住了设备拥有者,此用户可多次打开设备,并协调多个进程对设备并发操作。同时,没有其他用户可打开它,避免了外部干扰。这个模块我是利用completion模块改的,这要既可以实现功能,也方便测试。
模块程序链接: completion-singleUID.tar.gz
模块测试程序链接: completion-singleUID-test.tar.gz
ARM9实验板的实验现象是:
[Tekkaman2440@SBC2440V4]#insmod /lib/modules/singleUID.ko[Tekkaman2440@SBC2440V4]#cat /proc/devices

Character devices:

  1 mem

  2 pty

  3 ttyp

  4 /dev/vc/0

  4 tty

  4 ttyS

  5 /dev/tty

  5 /dev/console

  5 /dev/ptmx

  7 vcs

 10 misc

 13 input

 14 sound

 81 video4linux

 89 i2c

 90 mtd

116 alsa

128 ptm

136 pts

180 usb

189 usb_device

204 s3c2410_serial

252 singleUID

253 usb_endpoint

254 rtc

Block devices:

  1 ramdisk

256 rfd

  7 loop

 31 mtdblock

 93 nftl

 96 inftl

179 mmc

[Tekkaman2440@SBC2440V4]#mknod -m 666 /dev/singleUID c 252 0

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testr&

[Tekkaman2440@SBC2440V4]#login tekkaman

Password:

Set search library path int /etc/profile

Set user path in /etc/profile

runing /etc/profile ok

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testw

open singleUID code=-1

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testr

open singleUID code=-1

[Tekkaman2440@SBC2440V4]#exit

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testw

write code=0

[Tekkaman2440@SBC2440V4]#read code=0

[1] + Done /tmp/singleUID_testr
阻塞型单用户访问
模块程序链接: completion-singleUIDnb.tar.gz
模块测试程序链接: completion-singleUIDnb-test.tar.gz
ARM9实验板的实验现象是:
[Tekkaman2440@SBC2440V4]#insmod /lib/modules/singleUIDnb.ko

[Tekkaman2440@SBC2440V4]#cat /proc/devices

Character devices:

  1 mem

  2 pty

  3 ttyp

  4 /dev/vc/0

  4 tty

  4 ttyS

  5 /dev/tty

  5 /dev/console

  5 /dev/ptmx

  7 vcs

 10 misc

 13 input

 14 sound

 81 video4linux

 89 i2c

 90 mtd

116 alsa

128 ptm

136 pts

180 usb

189 usb_device

204 s3c2410_serial

252 singleUIDnb

253 usb_endpoint

254 rtc

Block devices:

  1 ramdisk

256 rfd

  7 loop

 31 mtdblock

 93 nftl

 96 inftl

179 mmc

[Tekkaman2440@SBC2440V4]#mknod -m 666 /dev/singleUIDnb c 252 0

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testrnb&

[Tekkaman2440@SBC2440V4]#login tekkaman

Password:

Set search library path int /etc/profile

Set user path in /etc/profile

runing /etc/profile ok

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testrnb &

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testwnb &

[Tekkaman2440@SBC2440V4]#exit

[Tekkaman2440@SBC2440V4]#ps

  PID Uid VSZ Stat Command

    1 root 1744 S init

    2 root SW< [kthreadd]

    3 root SWN [ksoftirqd/0]

    4 root SW< [watchdog/0]

    5 root SW< [events/0]

    6 root SW< [khelper]

   59 root SW< [kblockd/0]

   60 root SW< [ksuspend_usbd]

   63 root SW< [khubd]

   65 root SW< [kseriod]

   77 root SW [pdflush]

   78 root SW [pdflush]

   79 root SW< [kswapd0]

   80 root SW< [aio/0]

  707 root SW< [mtdblockd]

  708 root SW< [nftld]

  709 root SW< [inftld]

  710 root SW< [rfdd]

  742 root SW< [kpsmoused]

  751 root SW< [kmmcd]

  769 root SW< [rpciod/0]

  778 root 1752 S -sh

  779 root 1744 S init

  781 root 1744 S init

  782 root 1744 S init

  783 root 1744 S init

  814 root 1336 D /tmp/singleUID_testrnb

  816 tekkaman 1336 S /tmp/singleUID_testrnb

  817 tekkaman 1336 S /tmp/singleUID_testwnb

  818 root 1744 R ps

[Tekkaman2440@SBC2440V4]#/tmp/singleUID_testwnb&

[Tekkaman2440@SBC2440V4]#read code=0

write code=0

write code=0

read code=0

[2] + Done /tmp/singleUID_testwnb

[1] + Done /tmp/singleUID_testrnb

[Tekkaman2440@SBC2440V4]#ps

  PID Uid VSZ Stat Command

    1 root 1744 S init

    2 root SW< [kthreadd]

    3 root SWN [ksoftirqd/0]

    4 root SW< [watchdog/0]

    5 root SW< [events/0]

    6 root SW< [khelper]

   59 root SW< [kblockd/0]

   60 root SW< [ksuspend_usbd]

   63 root SW< [khubd]

   65 root SW< [kseriod]

   77 root SW [pdflush]

   78 root SW [pdflush]

   79 root SW< [kswapd0]

   80 root SW< [aio/0]

  707 root SW< [mtdblockd]

  708 root SW< [nftld]

  709 root SW< [inftld]

  710 root SW< [rfdd]

  742 root SW< [kpsmoused]

  751 root SW< [kmmcd]

  769 root SW< [rpciod/0]

  778 root 1752 S -sh

  779 root 1744 S init

  781 root 1744 S init

  782 root 1744 S init

  783 root 1744 S init

  820 root 1744 R ps

在 open 时复制设备
访问控制的另一个技术是根据打开条件创建不同的设备私有副本。这只有当设备没有绑定到一个硬件实体时才有可能。 /dev/tty 的内部使用类似的技术来给它的进程一个不同的 /dev 入口点所呈现的“景象”。这类访问控制较少见,但这个实现可说明内核代码可以轻松改变应用程序的运行环境,类似windows中的虚拟机概念。
我将书中的例子作了修改,实现了不同的用户使用scull的不同私有副本,这样方便了在ARM9实验板上做测试。
这个实验源码需要一定的linux 链表的知识(在第十一章),下一篇会介绍。
模块程序链接: scullcloned.tar.gz
ARM9实验板的实验现象是:
[Tekkaman2440@SBC2440V4]#cd /lib/modules/

[Tekkaman2440@SBC2440V4]#insmod scullcloned.ko

[Tekkaman2440@SBC2440V4]#cat /proc/devices

Character devices:

  1 mem

  2 pty

  3 ttyp

  4 /dev/vc/0

  4 tty

  4 ttyS

  5 /dev/tty

  5 /dev/console

  5 /dev/ptmx

  7 vcs

 10 misc

 13 input

 14 sound

 81 video4linux

 89 i2c

 90 mtd

116 alsa

128 ptm

136 pts

180 usb

189 usb_device

204 s3c2410_serial

252 scullcloned

253 usb_endpoint

254 rtc

Block devices:

  1 ramdisk

256 rfd

  7 loop

 31 mtdblock

 93 nftl

 96 inftl

179 mmc

[Tekkaman2440@SBC2440V4]#mknod -m 666 scullcloned c 252 0

[Tekkaman2440@SBC2440V4]#echo root > /dev/scullcloned

[Tekkaman2440@SBC2440V4]#cat /dev/scullcloned

root

[Tekkaman2440@SBC2440V4]#login tekkaman

Password:

Set search library path int /etc/profile

Set user path in /etc/profile

runing /etc/profile ok

[Tekkaman2440@SBC2440V4]#cat /dev/scullcloned

[Tekkaman2440@SBC2440V4]#echo tekkaman >/dev/scullcloned

[Tekkaman2440@SBC2440V4]#cat /dev/scullcloned

tekkaman

[Tekkaman2440@SBC2440V4]#exit

[Tekkaman2440@SBC2440V4]#cat /dev/scullcloned

root
《Linux设备驱动程序(第3版)》第六章高级字符驱动程序操作的学习终于结束了,内容比较多,碰到的问题也多。但是在解决问题的过程中可以学到很多的知识,所以有了问题不要马上问别人,试着自己看源码来发现问题,不仅记得牢,也学得多。

你可能感兴趣的:(linux)