LDD3读书笔记.Chapter6

Posted by Sah in Sah写的 | Tagged | 7 Comments

第六章的笔记。

Advanced Char Driver Operations

看完第六章之后,时间安排有了变化。接下来的第七、八章(Time, Delays, and Deffered Work 和 Allocating Memory)只能暂时略过,从第九章继续看。

第六章中介绍的是Char设备驱动中,除读写操作以外的常见操作,包括:

  • ioctl
  • Blocking I/O
  • poll and select
  • Asynchronous Notification
  • Seeking a Device
  • Access Control on a Device File

ioctl

ioctl以前给我感觉挺神秘的,原来就是选好cmd的号码,然后写个switch就行了。关键是这一章还没介绍如何真正操作硬件,所以用的ioctl的例子也只是在软件部分的一些动作。这样当然就没什么神秘的了。

Blocking I/O

使用sleep时应该注意的一点是,必须十分确定自己一定会被wake up,才可以开始sleep。其实前面讲Semaphore的时候,已经涉及到了sleep的概念。但是到了这里才开始真正介绍sleep的种类,以及进程如何使自己开始sleep的两种方式(simply调用wait_event()的方式,和所谓”manual”的方式)。

  • 第一种,也是比较简单的sleep
  • 基本上是这样:

    1. 创建一个wait_queue_head。两种方法:
    2. DECLARE_WAIT_QUEUE_HEAD(my_queue);

      wait_queue_head_t my_queue;init_waitqueue_head(my_queue);

    3. 调用wait_event()(或者个系列的其他函数):
    4. wait_event(myqueue, condition);

      其中的condition就是这个进程wake up的条件。

      然后,当然了,应该会有另一个进程调用wake up进程的函数”wake_up(&my_queue)”。这个函数会wake up所有my_queue上的进程。(对应wait_event()系列的其他函数,wake_up()也有若干变形。)

  • 第二种,manual sleep
  • 实际上就是把wait_event()这个宏拆开。这样可以做出更复杂的sleep(比如可以用prepare_to_wait_exclusive())。

使用第一种sleep方式时,一般的情况下,当wake_up(&my_queue)被调用时,如果my_queue上面有多个进程在等待condition这个条件,则它们将同时被wake up。在看了wait_event()的定义以后,发现其实它内部就是一个循环,一旦被wake_up,就去检查condition是否确实为真,以判断是否需要继续sleep。但是必须注意的是,由于race的存在,这也并不意味着从wait_event()返回后condition就一定是真。

另外,这一章里,还学到了schedule()函数。schedule()就是告诉Linux,你现在应该马上重新考虑下应该把CPU交给哪个进程使用,也就是当年操作系统课中讲的”从用户态切换到系统态”。这个动作就是一个进程在把自己的state设置为TASK_INTERRUPTIBLE或TASK_UNITERRUPTIBLE,并把自己加入sleep队列以后,要做的事情。这里还有一个有意思的事情就是,如果在进程完成了这两项动作以后,而还没有调用schedule()之前的空隙,有人调用了wake_up()试图唤醒这个进程,Linux并不会出乱子。因为wake_up()正好做了和那两项动作相反的事,所以当这个进程重新获得CPU,并继续执行到schedule()时,scheduler会直接返回。

回顾一下Blocking I/O这部分的内容,感觉最重要的就是要想清楚流程。down_interruptible()以后进入一个循环,除非condition成立才可以退出循环。在循环体内,当condition不成立时,要先up(),再开始sleep,睡醒了之后再down_interruptible()并回到循环开始,重新判断condition。而循环体内的sleep那部分也挺烦。要先prepare_to_wait(),然后在睡前最后确认一次condition,确实仍然不成立,才调用schedule()。schedule()返回以后先finish_wait(),再看看是怎么醒的。如果是某Signal给吵醒的,要return -ESYSRESTART;重新来过。否则是自然醒,那就算是睡眠结束,继续上面说的”睡醒了之后在down_interruptible()那段”。

poll and select

poll和select是Unix时代传下来的一个系统调用的两个版本,在file_operations结构中都是用poll()实现的。poll用来查看当前某设备可用的操作(读、写等)。在程序不希望进入sleep状态等待某个I/O设备时,它们通常会在操作前调用poll来查看设备状态。

poll涉及到一些乱七八糟的数据结构,什么poll_table之类的。这部分只了解了poll的作用,更深的没仔细看。

Asynchronous Notification

异步通知。也就是POSIX进程通信机制中的”Signal”,信号机制。其目的是为了让(尤其是低优先级的)进程可以更迅速地响应某些事件。这部分也没仔细看,只是知道进程需要用fcntl()在设备上注册自己。

Seeking a Device

就是讲了一些和fops.llseek()有关的内容,说有些设备不支持seek操作的,该怎么办。

Access Control on a Device File

scull系列的最后几个终于出场了。这章介绍了几种常见的访问控制方式:

  • Single Open
  • 很直接的方法。在设备的结构中加个锁,第一次open就锁住,以后再open就返回一个-EBUSY。这样一个设备就只能open一次了。

  • Restricting Access to a Single User at a Time
  • 有时候要求同一个设备可以被open多次,但必须只能是由同一个用户。有一种可能就是为了确保在进行多个进程在某个设备上的race时,不希望其他用户的进程打扰。这可以在open中判断uid,至于判断之后的处理方法有几种:

    • Returning -EBUSY
    • 直接返回”忙”,没啥说的。

    • Blocking open
    • 让后来的用户的进程sleep。<

    • Cloning the Device on open
    • 为后来的用户的进程创建一个副本。一个例子就是console设备。

这就是第六章的内容了,很杂。单独写一篇看来是对了。

7 Responses to LDD3读书笔记.Chapter6

  1. okstop says:

    白羊座(3月21日至4月19日)埋头苦干、震撼十足的跃进年
      2006年对主运落在伙伴宫的白羊座而言,将是带点宿命与传奇意味的辉煌腾达期。虽然傲骨与霸气一度无法恣意伸展,生命和工作热情也转趋理性与自制,但即使不能发挥百分之一百的潜力,仍有可能在结盟关系或决策高人的庇荫下,一路过关斩将、无坚不摧。不断借着忘情敛聚名利、力争上游来证明自己的价值和存在。
      事业在新年度之初就比别人更早到位、就绪,7月中以后将挣脱温情包袱,全心跻身要职并绽放异彩,10月中和12月底可望先后创下两大高峰。前3季半事业成绩主要靠团队、人脉与交情,合作、签约、交易案大增,岁末半季财务最具戏剧性起落。爱情之星金星显示,1月中旬容易一见钟情,10月将写下今年度爱情最美丽的章节。
      3月底到4月底的「白羊座之月」是运势最有爆发力的时段,其中4月9日的「白羊座日蚀」(也是白羊座新月日)尤其震撼,10月中的「白羊座月蚀」(也是白羊座月圆)及10月1日到12月9日的守护星退行周期是另一个戏剧高峰。
      年度叮咛:学习换个角度、异地而处,对别人的贡献心存感激。
      致胜秘诀:体贴、随和、客观、公道、借力使力
      魅力出击:红宝石戒指、绿色系配饰助爱情、人气与旺财。
      最大收获:爱情婚约、法律协议、结盟关系、外部资源、共有资产
      成功障碍:急功近利、自以为是、目无尊长

  2. angelwu says:

    sah 你在做LINUX方面的吗?

  3. Sah says:

    Oh! Yeah! 我在研究Linux里的驱动程序。

  4. spone says:

    sah写的很不错,不过有些地方解释有误。等下个月忙完测试程序,然后再下个月写完驱动程序。我也要整理一篇这样的文章了。

  5. Sah says:

    Spone是谁?是做驱动程序的?是培训的同学吗?哪里说的不对,帮我指正一下嘛!我这些就是看完了随便记的,好多地方是对是错都没有途径求证,很郁闷啊。

  6. spring says:

    很喜欢你写的笔记,怎么不继续写了啊

  7. Sah says:

    没想到居然有人喜欢噢。呵呵。因为我最后还是没有做驱动方面的工作,而且现在的公司很忙,所以就不继续看后面的章节了。如果让读者们失望了还请谅解啊!

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>