📄 linux设备驱动程序学习(0)-hello, world!模块 - linux设备驱动程序 - tekkaman ninja.htm
字号:
`/home/tekkaman/working/SBC2440/linux-2.6.22.2'<BR>[root@Tekkaman-Ninja
Helloworld]# make modules_install<BR>cp hello.ko
/home/tekkaman/working/rootfs/lib/modules<BR>[root@Tekkaman-Ninja
Helloworld]#
<BR></TD></TR></TBODY></TABLE><BR><BR>在我的开发板上的操作:<BR>
<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%">[Tekkaman2440@SBC2440V4]#cd
/lib/modules/</P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#ls</P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">cs89x0.ko
<SPAN
style="COLOR: rgb(255,1,2)">hello.ko</SPAN>
p80211.ko prism2_usb.ko <BR></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#insmod
hello.ko <BR></P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%">Hello,
Tekkaman Ninja !</P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#lsmod
<BR></P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%">Module
Size Used by Not tainted <BR></P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%">hello
1376 0 <BR></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#rmmod
hello <BR></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">Goodbye,
Tekkaman Ninja !</P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%">Love
Linux !Love ARM ! Love KeKe ! <BR></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#lsmod
<BR></P>
<P style="MARGIN: 5px; LINE-HEIGHT: 150%">Module
Size Used by Not tainted <BR></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%">[Tekkaman2440@SBC2440V4]#
</P></TD></TR></TBODY></TABLE><BR>
<HR style="WIDTH: 100%; HEIGHT: 2px">
<FONT
size=3>学习心得:<BR>(1)驱动模块运行在内核空间,运行时不能依赖于任何函数库和模块连接,所以在写驱动时所调用的函数只能是作为内核一部分的函数。<BR>(2)驱动模块和应用程序的一个重要不同是:应用程序退出时可不管资源释放或者其他的清除工作,但模块的退出函数必须仔细撤销初始化函数所作的一切,否则,在系统重新引导之前某些东西就会残留在系统中。</FONT><BR><FONT
size=3>(3)处理器的多种工作模式(级别)其实就是为了操作系统的用户空间和内核空间设计的。在Unix类的操作系统中只用到了两个级别:最高和最低级别。<BR>(4)要十分注意驱动程序的并发处理。<BR>(5)内核API中具有双下划线(_
_)的函数,通常是接口的底层组件,应慎用。<BR>(6)</FONT><FONT
size=3>内核代码不能实现浮点书运算。<BR><BR>(7)Makefile文件分析:<BR></FONT><CODE><SPAN
style="COLOR: rgb(0,0,0)">obj<SPAN
style="COLOR: rgb(0,0,204)">-</SPAN>m <SPAN
style="COLOR: rgb(0,0,204)">:</SPAN><SPAN
style="COLOR: rgb(0,0,204)">=</SPAN> hello<SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>o
代表了我们要构造的模块名为hell.ko,make
会在该目录下自动找到hell.c文件进行编译。如果
</SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)"><SPAN
style="COLOR: rgb(255,1,2)">hello.o</SPAN>是由其他的源文件生成(比如file1.c和</SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)">file2.c</SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)">)的,则在下面加上(注意<SPAN
style="COLOR: rgb(255,1,2)">红色字体</SPAN>的对应关系):<BR></SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)"></SPAN></CODE><CODE
style="COLOR: rgb(255,1,2)">hello</CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)"><SPAN
style="COLOR: rgb(255,1,2)">-objs</SPAN> :=
file1.o file2.o
......</SPAN></CODE><BR><BR><CODE><SPAN
style="COLOR: rgb(0,0,0)">
$<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>MAKE<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">-</SPAN>C $<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>KERNELDIR<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN> M<SPAN
style="COLOR: rgb(0,0,204)">=</SPAN><SPAN
style="COLOR: rgb(0,0,204)">$</SPAN><SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>PWD<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN> modules<BR>其中
</SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)"><SPAN
style="COLOR: rgb(0,0,204)">-</SPAN>C $<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>KERNELDIR<SPAN
style="COLOR: rgb(0,0,204)">) <SPAN
style="COLOR: rgb(0,1,2)">指定了内核源代码的位置,其中保存有内核的顶层makefile文件。<BR>
</SPAN></SPAN></SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)">M<SPAN
style="COLOR: rgb(0,0,204)">=</SPAN><SPAN
style="COLOR: rgb(0,0,204)">$</SPAN><SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>PWD<SPAN
style="COLOR: rgb(0,0,204)">) </SPAN></SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)"><SPAN
style="COLOR: rgb(0,0,204)"><SPAN
style="COLOR: rgb(0,1,2)">指定了模块源代码的位置<BR>
</SPAN></SPAN></SPAN></CODE><CODE><SPAN
style="COLOR: rgb(0,0,0)">modules目标指向obj-m变量中设定的模块。<BR><BR></SPAN></CODE><FONT
size=3>(8)insmod使用公共内核符号表来解析模块中未定义的符号。公共内核符号表中包含了所有的全局内核项(即函数和变量</FONT><FONT
size=3>的地址</FONT><FONT
size=3>),这是实现模块化驱动程序所必须的。<BR>(9)Linux使用模块层叠技术,我们可以将模块划分为多个层,通过简化每个层可缩短开发周期。如果一个模块需要向其他模块到处符号,则使用下面的宏:<BR></FONT><BR>
<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: rgb(0,0,0)">EXPORT_SYMBOL<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>name<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR>EXPORT_SYMBOL_GPL<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN>name<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE><FONT
size=3>符号必须在模块文件的全局变量部分导出,因为这两个宏将被扩展为一个特殊变量的声明,而该变量必须是全局的。<BR><BR>(10)所有模块代码中都包含一下两个头文件:<BR></FONT><BR>
<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: rgb(0,0,0)"><SPAN
style="COLOR: rgb(0,0,204)">#</SPAN><SPAN
style="COLOR: rgb(255,0,0)">include</SPAN> <SPAN
style="COLOR: rgb(0,0,204)"><</SPAN>linux<SPAN
style="COLOR: rgb(0,0,204)">/</SPAN>init<SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>h<SPAN
style="COLOR: rgb(0,0,204)">></SPAN><BR><SPAN
style="COLOR: rgb(0,0,204)">#</SPAN><SPAN
style="COLOR: rgb(255,0,0)">include</SPAN> <SPAN
style="COLOR: rgb(0,0,204)"><</SPAN>linux<SPAN
style="COLOR: rgb(0,0,204)">/</SPAN>module<SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>h<SPAN
style="COLOR: rgb(0,0,204)">></SPAN>
</SPAN></CODE></P></TD></TR></TBODY></TABLE><FONT
size=3><BR>(11)所有模块代码都<SPAN
style="COLOR: rgb(255,1,2)">应该</SPAN>指定所使用的许可证:<BR><BR></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: rgb(0,0,0)">MODULE_LICENSE<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">"Dual
BSD/GPL"</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR></SPAN></CODE></P></TD></TR></TBODY></TABLE><BR>此外还有可选的其他描述性定义:<BR><BR>
<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: rgb(0,0,0)">MODULE_AUTHOR<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">""</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR>MODULE_DESCRIPTION<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">""</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR>MODULE_VERSION<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">""</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR>MODULE_ALIAS<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">""</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR>MODULE_DEVICE_TABLE<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(255,0,255)">""</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE><FONT
size=3><BR>上述</FONT><CODE><SPAN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -