📄 linux设备驱动程序学习(15)-linux设备模型(热插拔、mdev 与 firmware) - linux设备驱动程序 - tekkaman ninja.htm
字号:
style="COLOR: rgb(0,0,204)">*</SPAN> echo
tekkaman <SPAN
style="COLOR: rgb(0,0,204)">></SPAN> <SPAN
style="COLOR: rgb(0,0,204)">/</SPAN>tmp<SPAN
style="COLOR: rgb(0,0,204)">/</SPAN>mdev</SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
<DIV>
这样,在挂载和卸载sculld.ko时,在/tmp/下会出现mdev文件,里面字符为tekkaman<BR><BR></DIV>
<DIV>具体的实验源码和现象在文章后面有。</DIV>
<DIV> </DIV>
<DIV>
<HR id=null>
</DIV>
<P><FONT color=#0000ff
size=4><STRONG>firmware</STRONG></FONT></P>
<P>硬件市场的激烈竞争, 使得制造商连一点用于设备控制固件的 EEPROM
的成本都不愿意花费。因此固件一般发布在和硬件配套的驱动包中,由操作系统(其实是驱动程序)负责传送固件到设备。</P>
<P><FONT color=#0000ff
size=3><STRONG>内核固件接口</STRONG></FONT></P><BR>
<P>获取固件的正确方法是当需要时从用户空间获取它。一定不要试图从内核空间直接打开包含固件的文件,那是一个易出错的操作,
因为它把策略(以文件名的形式)包含进了内核。正确的方法是使用固件接口:
<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)"><FONT face=新宋体><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>firmware<SPAN
style="COLOR: rgb(0,0,204)">.</SPAN>h<SPAN
style="COLOR: rgb(0,0,204)">></SPAN><BR><SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
request_firmware<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">const</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
firmware <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN><SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>fw<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN>
</FONT></SPAN></CODE></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN
style="COLOR: rgb(0,0,255)"><FONT
color=#000000>
</FONT>const</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">char</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>name<SPAN
style="COLOR: rgb(0,0,204)">, <FONT
color=#ff9900>/* name
为固件文件名*/</FONT></SPAN></FONT></SPAN></CODE></P>
<P
style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN
style="COLOR: rgb(0,0,0)"><FONT
face=新宋体> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> device
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>device<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*要求用户空间定位并提供一个固件映象给内核;若成功加载,
返回值是 0(否则返回错误码)*/</SPAN><BR><BR><SPAN
style="COLOR: rgb(255,153,0)">/*因为
request_firmware 需要用户空间的操作,
所以返回前将保持休眠。若驱动必须使用固件而不能进入休眠时,可使用以下异步函数:*/</SPAN><BR><SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
request_firmware_nowait<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> module
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>module<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(255,153,0)">/* =
THIS_MODULE*/</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">int</SPAN>
uevent<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">const</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">char</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>name<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN>
<BR> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN> device
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>device<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN>
<BR> <SPAN
style="COLOR: rgb(0,0,255)">void</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>context<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN><SPAN
style="COLOR: rgb(255,153,0)">/*不由固件子系统使用的私有数据指针*/</SPAN><BR> <SPAN
style="COLOR: rgb(0,0,255)">void</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>cont<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">const</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
firmware <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>fw<SPAN
style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN
style="COLOR: rgb(0,0,255)">void</SPAN> <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>context<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*如果一切正常,request_firmware_nowait
开始固件加载过程并返回 0. 过了一段时间后(默认10秒),将用加载的结果(若加载失败, fw
为 NULL)作为参数调用 cont。*/</SPAN><BR><BR><SPAN
style="COLOR: rgb(255,153,0)">/* fw
参数指向以下结构体:*/</SPAN><BR><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
firmware <SPAN
style="COLOR: rgb(0,0,204)">{</SPAN><BR> <SPAN
style="COLOR: rgb(255,0,0)">size_t</SPAN>
size<SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR> u8
<SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>data<SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(0,0,204)">}</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN
style="COLOR: rgb(255,153,0)">/*那个结构包含实际的固件,
它现在可被下载到设备中.但是请注意:在发送它到硬件之前,必须检查这个文件以确保它是正确的固件映象(设备固件常常包含标识字符串、
校验和等等)*/</SPAN><BR><BR><SPAN
style="COLOR: rgb(255,153,0)">/*当固件已经发送到设备后,应当释放
firmware 结构体, 使用:*/</SPAN><BR><SPAN
style="COLOR: rgb(0,0,255)">void</SPAN>
release_firmware<SPAN
style="COLOR: rgb(0,0,204)">(</SPAN><SPAN
style="COLOR: rgb(0,0,255)">struct</SPAN>
firmware <SPAN
style="COLOR: rgb(0,0,204)">*</SPAN>fw<SPAN
style="COLOR: rgb(0,0,204)">)</SPAN><SPAN
style="COLOR: rgb(0,0,204)">;</SPAN>
</FONT></SPAN></CODE></P></TD></TR></TBODY></TABLE></P>
<P>注意:要使用<CODE><SPAN
style="COLOR: rgb(0,0,0)"><FONT
face=新宋体>firmware<SPAN
style="COLOR: rgb(0,1,2)">,必须要在配置内核时选上:</SPAN></FONT></SPAN></CODE></P>
<P><CODE><SPAN style="COLOR: rgb(0,0,0)"><FONT
face=新宋体><SPAN
style="COLOR: rgb(0,1,2)"> Device
Drivers --->
<BR></SPAN></FONT></SPAN></CODE></P>
<P><CODE><SPAN style="COLOR: rgb(0,0,0)"><FONT
face=新宋体><SPAN
style="COLOR: rgb(0,1,2)">
Generic Driver
Options --->
<BR></SPAN></FONT></SPAN></CODE></P>
<P><CODE><SPAN style="COLOR: rgb(0,0,0)"><FONT
face=新宋体><SPAN
style="COLOR: rgb(0,1,2)">
<SPAN
style="COLOR: rgb(0,1,255)"><*> Userspace
firmware loading support
</SPAN><BR></SPAN></FONT></SPAN></CODE></P>
<P><CODE><SPAN style="COLOR: rgb(0,0,0)"><FONT
face=新宋体><SPAN style="COLOR: rgb(0,1,2)">否则会出现:
Unknown symbol release_firmware 和: Unknown symbol
request_firmware 的错误。<BR>
<BR></SPAN></FONT></SPAN></CODE></P>
<P><FONT color=#0000ff
size=3><STRONG>固件接口工作原理</STRONG></FONT></P>
<P><FONT color=#000000><FONT color=#ff0000
size=3><STRONG>固件子系统使用 sysfs
和热插拔机制工作</STRONG></FONT>。当调用 request_firmware时,
函数将在 /sys/class/firmware 下创建一个以设备名为目录名的新目录,其中包含 3
个属性:</FONT></P>
<P><FONT color=#000000><FONT
color=#0000ff><STRONG>loading</STRONG>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -