📄 linux设备驱动程序学习(12)-linux设备模型(底层原理简介) - linux设备驱动程序 - tekkaman ninja.htm
字号:
cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%">
<DIV id=art style="MARGIN: 15px" width="100%">
<P align=center><FONT color=#0000ff
size=4><STRONG>Linux设备驱动程序学习(12)</STRONG></FONT></P>
<P align=center><FONT color=#0000ff
size=4><STRONG>-Linux设备模型</STRONG></FONT><STRONG><FONT
color=#0000ff
size=4>(底层原理简介)</FONT></STRONG></P><FONT
color=#000000>
<P align=left>
<HR id=null>
<P></P>
<P
align=left>以《LDD3》的说法:Linux设备模型这部分内容可以认为是高级教材,对于多数程序作者来说是不必要的。但是我个人认为:<FONT
color=#ff0000>对于一个嵌入式Linux的底层程序员来说,这部分内容是很重要的。</FONT>以我学习的ARM9为例,有很多总线(如SPI、IIC、IIS等等)在Linux下已经被编写成了子系统,无需自己写驱动;而这些总线又不像PCI、USB等在《LDD3》上有教程,有时还要自己研究它的子系统构架,甚至要自己添加一个新的总线类型。</P>
<P
align=left>对于这方面的学习,我推荐几个网页,这些也是我这部分文章的参考资料:</P>
<P align=left>(1)《 <FONT
face="宋体, SimSun">Linux</FONT>那些事儿 之 我是<FONT
face="宋体, SimSun">Sysfs</FONT>》来源于复旦和交大三个牛人的Linux技术博客:<FONT
face="Times New Roman, serif"><A
href="http://blog.csdn.net/fudan_abc"><FONT
face="宋体, SimSun"
color=#0000ff><B>http://blog.csdn.net/fudan_abc</B></FONT></A>
</FONT><FONT
face="Courier New">(复旦_abc)他们还分析了很多Linux的驱动,值得珍藏!</FONT></P>
<P align=left>(2)《linux设备模型详解》也是一个牛人的博客文章,博客网址:<A
href="http://hi.baidu.com/csdeny/blog"><STRONG>http://hi.baidu.com/csdeny/blog</STRONG></A></P>
<P
align=left>(3)《s3c2410设备的注册》是一篇关于2410中linux内核实现设备模型的不可多得的好资料。网址:<A
href="http://blog.chinaunix.net/u1/41638/showart_438078.html"><STRONG>http://blog.chinaunix.net/u1/41638/showart_438078.html</STRONG></A></P>
<P align=left>(4)luofuchong的博客
,此人分析了一些2410中的Linux子系统(如SPI,input等),实力不凡,值得关注。网址:<A
href="http://www.cnitblog.com/luofuchong/">http://www.cnitblog.com/luofuchong/</A></P>
<P
align=left>在这部分的学习中,将会先研究linux设备模型的每个元素,最后将其一步一步整合,至底向上地分析。一开始会比较摸不着头脑,到了整合阶段就柳暗花明了。我之所以没有先介绍整体,再分析每个部分是因为如果不对每个元素做认真分析,看了整体也会云里雾里(我试过了,恕小生愚钝)。所以一开始要耐着性子看,到整合阶段就会豁然开朗。</P>
<P align=left>
<HR id=null>
<P></P>
<P align=left>Linux设备模型的目的是:</FONT><FONT
color=#ff0000>为内核建立起一个统一的设备模型,从而有一个对系统结构的一般性抽象描述。</FONT></P>
<P align=left>现在内核使用设备模型支持多种不同的任务:<BR><FONT
color=#0000ff>电源管理和系统关机</FONT>
:这些需要对系统结构的理解,设备模型使OS能以正确顺序遍历系统硬件。</P>
<P align=left><FONT color=#0000ff>与用户空间的通讯</FONT>
:sysfs 虚拟文件系统的实现与设备模型的紧密相关,
并向外界展示它所表述的结构。向用户空间提供系统信息、改变操作参数的接口正越来越多地通过 sysfs
, 也就是设备模型来完成。</P>
<P align=left><FONT color=#0000ff>热插拔设备</FONT>
</P>
<P
align=left>设备类型:设备模型包括了将设备分类的机制,在一个更高的功能层上描述这些设备,
并使设备对用户空间可见。</P>
<P align=left><FONT
color=#0000ff>对象生命周期</FONT>:设备模型的实现需要创建一系列机制来处理对象的生命周期、对象间的关系和对象在用户空间的表示。</P>
<P align=left>Linux 设备模型是一个复杂的数据结构。但对模型的大部分来说,
Linux 设备模型代码会处理好这些关系,
而不是把他们强加于驱动作者。模型隐藏于交互的背后,与设备模型的直接交互通常由总线级的逻辑和其他的内核子系统处理。所以许多驱动作者可完全忽略设备模型,
并相信设备模型能处理好他所负责的事。
<P>
<HR id=null>
<P></P>
<P><FONT color=#0000ff
size=3>在此之前请先了解一下sysfs</FONT>,请看 <FONT
face="Times New Roman, serif"><A
href="http://blog.csdn.net/fudan_abc/archive/2007/09/01/1768277.aspx"><FONT
color=#0000ff><FONT
face="宋体, SimSun"><U>Linux</U></FONT></FONT></A></FONT><A
href="http://blog.csdn.net/fudan_abc/archive/2007/09/01/1768277.aspx"><FONT
color=#0000ff><U>那些事儿之我是<FONT
face="Times New Roman, serif"><FONT
face="宋体, SimSun">Sysfs(1)sysfs</U></FONT></FONT></A></FONT><A
href="http://blog.csdn.net/fudan_abc/archive/2007/09/01/1768277.aspx"><FONT
color=#0000ff><U>初探</U></FONT></A> 我就不在这里废话了!这里还建议先看看
sysfs 的内核文档<FONT color=#0000ff>\Documentation<FONT
color=#0000ff>\<SPAN lang=EN-US
style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">filesystems\</SPAN></FONT>sysfs.txt</FONT>,我将其翻译好做成PDF,下载地址:<STRONG><FONT
color=#0000ff><A
href="http://blogimg.chinaunix.net/blog/upfile2/071229162826.pdf">http://blogimg.chinaunix.net/blog/upfile2/071229162826.pdf</A> </FONT></STRONG></P>
<P><STRONG><FONT
color=#660099>如有错误欢迎指正!</FONT></STRONG></P>
<P> </P>
<P></P>
<P align=left><FONT color=#0000ff
size=4><STRONG>Kobject、Kset 和
Subsystem</STRONG></FONT> </P>
<P align=left><STRONG><FONT color=#0000ff
size=3>Kobjects</FONT></STRONG></P>
<P align=left>kobject是一种数据结构,定义在 <FONT
color=#0000ff><linux/kobject.h></FONT> 。
<TABLE style="BORDER-COLLAPSE: collapse"
borderColor=#999999 cellSpacing=0 cellPadding=0
width="95%" bgColor=#f1f1f1 border=1>
<TBODY>
<TR>
<TD>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: #000000"><FONT face=新宋体><SPAN
style="COLOR: #0000ff">struct</SPAN> kobject
<SPAN
style="COLOR: #0000cc">{</SPAN><BR> <SPAN
style="COLOR: #0000ff">const</SPAN> <SPAN
style="COLOR: #0000ff">char</SPAN> <SPAN
style="COLOR: #0000cc">*</SPAN> k_name<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*kobject 的名字数组(sysfs
入口使用的名字)指针;如果名字数组大小小于KOBJ_NAME_LEN,它指向本数组的name,否则指向另外分配的一个名字数组空间
*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">char</SPAN> name<SPAN
style="COLOR: #0000cc">[</SPAN>KOBJ_NAME_LEN<SPAN
style="COLOR: #0000cc">]</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*kobject
的名字数组,若名字数组大小不小于KOBJ_NAME_LEN,只储存前KOBJ_NAME_LEN个字符*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
kref kref<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*kobject
的引用计数*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
list_head entry<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*kobject 之间的双向链表,与<FONT
color=#ff9900>所属的kset形成环形链表</FONT>*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
kobject <SPAN
style="COLOR: #0000cc">*</SPAN> parent<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*在sysfs分层结构中定位对象,指向上一级kset中的struct
kobject kobj*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
kset <SPAN
style="COLOR: #0000cc">*</SPAN> kset<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*指向所属的kset*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
kobj_type <SPAN
style="COLOR: #0000cc">*</SPAN> ktype<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*负责对该kobject类型进行跟踪的struct
kobj_type的指针*/</SPAN><BR> <SPAN
style="COLOR: #0000ff">struct</SPAN>
dentry <SPAN
style="COLOR: #0000cc">*</SPAN> dentry<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*sysfs文件系统中与该对象对应的文件节点路径指针*/</SPAN><BR> wait_queue_head_t poll<SPAN
style="COLOR: #0000cc">;</SPAN><SPAN
style="COLOR: #ff9900">/*等待队列头*/</SPAN><BR><SPAN
style="COLOR: #0000cc">}</SPAN><SPAN
style="COLOR: #0000cc">;</SPAN></FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE><BR>kobject
是组成设备模型的基本结构,初始它只被作为一个简单的引用计数,
但随时间的推移,其任务越来越多。现在kobject 所处理的任务和支持代码包括:</P>
<P align=left><FONT color=#0000ff>对象的引用计数</FONT>
:跟踪对象生命周期的一种方法是使用引用计数。当没有内核代码持有该对象的引用时,
该对象将结束自己的有效生命期并可被删除。</P>
<P align=left><FONT color=#0000ff>sysfs
表述</FONT>:在 sysfs 中出现的每个对象都对应一个 kobject,
它和内核交互来创建它的可见表述。</P>
<P align=left><FONT
color=#0000ff>数据结构关联</FONT>:整体来看,
设备模型是一个极端复杂的数据结构,通过其间的大量链接而构成一个多层次的体系结构。kobject
实现了该结构并将其聚合在一起。</P>
<P align=left><FONT color=#0000ff>热插拔事件处理</FONT>
:kobject 子系统将产生的热插拔事件通知用户空间。</P>
<P
align=left>一个kobject对自身并不感兴趣,它存在的意义在于把高级对象连接到设备模型上。因此内核代码很少(甚至不知道)创建一个单独的
kobject;而kobject
被用来控制对大型域(domain)相关对象的访问,所以kobject
被嵌入到其他结构中。kobject 可被看作一个最顶层的基类,其他类都它的派生产物。 kobject
实现了一系列方法,对自身并没有特殊作用,而对其他对象却非常有效。</P>
<P align=left> 对于给定的kobject指针,可使用<FONT
color=#0000ff>container_of</FONT>宏得到包含它的结构体的指针。</P>
<DIV><FONT color=#0000ff><STRONG>kobject
初始化</STRONG></FONT></DIV>
<P>kobject的初始化较为复杂,但是<FONT
color=#ff0000>必须的步骤</FONT>如下:</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -