<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Senghoo&#039;s Blog</title>
	<atom:link href="http://senghoo.com/feed" rel="self" type="application/rss+xml" />
	<link>http://senghoo.com</link>
	<description>因为简单。所以美丽</description>
	<lastBuildDate>Tue, 10 Aug 2010 11:18:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>linux内核技术手册英文电子版</title>
		<link>http://senghoo.com/254.html</link>
		<comments>http://senghoo.com/254.html#comments</comments>
		<pubDate>Tue, 10 Aug 2010 11:18:03 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[书]]></category>
		<category><![CDATA[内核]]></category>
		<category><![CDATA[内核配置]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=254</guid>
		<description><![CDATA[关于这本书的详细介绍在 新书入账-LINUX内核技术手册 本书根据CC2.5协议免费发布，看完了感觉不错。 对gentoo等从零开始类发行版安装的时候作为内核帮助手册很不错。 分享下。 官网：http://www... ]]></description>
			<content:encoded><![CDATA[<p>关于这本书的详细介绍在<br />
<a title="新书入账-LINUX内核技术手册" rel="bookmark" href="../221.html">新书入账-LINUX内核技术手册</a><br />
本书根据CC2.5协议免费发布，看完了感觉不错。<br />
对gentoo等从零开始类发行版安装的时候作为内核帮助手册很不错。<br />
分享下。<br />
官网：<a>http://www.kroah.com/lkn/</a><br />
下载地址：<a href="http://www.kernel.org/pub/linux/kernel/people/gregkh/lkn/lkn_pdf.tar.bz2">linux内核技术手册英文电子版</a></p>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/254.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>container_of分析</title>
		<link>http://senghoo.com/229.html</link>
		<comments>http://senghoo.com/229.html#comments</comments>
		<pubDate>Fri, 06 Aug 2010 08:35:49 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[container_of]]></category>
		<category><![CDATA[list_entry]]></category>
		<category><![CDATA[内核源码]]></category>
		<category><![CDATA[技巧]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=229</guid>
		<description><![CDATA[内核源码中存在这么一个宏container_of 用于从一个结构体的成员指针获取结构体的指针。 如： ?View Code C1 2 3 4 struct my&#123; int a; int b; &#125;; 在此如果知道成员b的指针可用container_of函数来获取包含... ]]></description>
			<content:encoded><![CDATA[<p>内核源码中存在这么一个宏container_of<br />
用于从一个结构体的成员指针获取结构体的指针。<br />
如：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p229code6'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2296"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p229code6"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> my<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> a<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> b<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>在此如果知道成员b的指针可用container_of函数来获取包含b的my结构体的指针。<br />
在此列中使用如以知b的指针pb:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p229code7'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2297"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p229code7"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> my <span style="color: #339933;">*</span>getmy<span style="color: #339933;">;</span>
getmy <span style="color: #339933;">=</span> container_of<span style="color: #009900;">&#40;</span>pb<span style="color: #339933;">,</span><span style="color: #993333;">struct</span> my<span style="color: #339933;">,</span>b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>这样就获取到了my的指针。<br />
这个宏的工作原理比较简单，下面简单介绍下其工作原理和实际代码。<br />
<span id="more-229"></span><br />
大体思路是，获取b成员相对my的偏移量，然后从b的指针（地址）减去偏移量就能获取到指向my的指针。<br />
实际的代码在内核include/linux/kernel.h中定义，如下:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p229code8'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2298"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p229code8"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)-&gt;member ) *__mptr = (ptr); \
	(type *)( (char *)__mptr - offsetof(type,member) );})</span></pre></td></tr></table></div>

<p>挺简单就两行语句。<br />
第一句定义一个变量来__mptr来保存ptr指针。<br />
这里使用了一个typeof操作符，此操作符由GCC编译器指定的，并不是标准操作符，用来返回变量的类型。<br />
其中包含 ((type *)0)->member 这里把0强制转换为 type类型的指针（这种把零转换为特定指针的操作下面还会遇到）。然后获取其成员，并当typeof的参数来获取其成员的类型。<br />
这里复制指针可能是为了防止操作时误改写指针的值。是不是这个用意我也无从得知了(*^__^*) 。<br />
接下就是关键的减肥来获取需要的指针。 这里又有个宏offsetof 用来获得type结构体的member成员的偏移量，稍候我们会解释。<br />
这里我们看到整体框架用花括号来包起来。这是为了在内部定义的__mptr 称为局部变量（也就是在这个花括号外边无法使用），以及让整条语句的值结果为第二个语句所执行的结果。<br />
接下来我们看下offsetof宏，这个宏在 include/linux/stddef.h中定义<br />
如下</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p229code9'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2299"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p229code9"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#ifdef __compiler_offsetof</span>
<span style="color: #339933;">#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)</span>
<span style="color: #339933;">#else</span>
<span style="color: #339933;">#define offsetof(TYPE, MEMBER) ((size_t) &amp;((TYPE *)0)-&gt;MEMBER)</span>
<span style="color: #339933;">#endif</span></pre></td></tr></table></div>

<p>这里有两种方法，如果编译器支持直接获取。就调用编译器的方法来获取，这个我们没兴趣。下面来看看内核的实现。<br />
&#038;((TYPE *)0)->MEMBER)这里和上面说过的一样。强制转换0为需要的指针，并且获取其成员,当然这里的成员是非法的，如果进行读写会产生不可预知的错误。<br />
前面有个取地址符来获取该成员的指针，这里我们想一下。如果结构体的地址为0，其成员的地址不就是该结构体中成员的偏移量吗！！！o(∩∩)o&#8230;<br />
然后是强制类型转换为size_t型来返回。<br />
如果看过内核当中的链表实现你可能会看过list_entry这个宏，感觉两个宏操作差不多，我们来看看实际代码,在文件include/linux/list.h中。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p229code10'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p22910"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p229code10"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)</span></pre></td></tr></table></div>

<p>果不其然。list_entry 其实就是一个照搬container_of的宏。</p>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/229.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新书入账-LINUX内核技术手册</title>
		<link>http://senghoo.com/221.html</link>
		<comments>http://senghoo.com/221.html#comments</comments>
		<pubDate>Thu, 05 Aug 2010 12:12:09 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[gentoo]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[书]]></category>
		<category><![CDATA[内核配置]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=221</guid>
		<description><![CDATA[原书名： Linux Kernel in a Nutshell 很薄的一本书，主要讲述linux内核配置 因为我使用的是gentoo系统，必须手动配置内核。 而网上讲解内核配置的文章比较零散。 感觉买来需要时当手册用确实不错... ]]></description>
			<content:encoded><![CDATA[<p>原书名：  Linux Kernel in a Nutshell<br />
很薄的一本书，主要讲述linux内核配置<br />
因为我使用的是gentoo系统，必须手动配置内核。<br />
而网上讲解内核配置的文章比较零散。<br />
感觉买来需要时当手册用确实不错。<br />
看到作者是gentoo系统开发者，稍微支持下拉。。<br />
因为书薄的关系很短时间内能看完，也确实学到了内核配置方面以前不知道的技巧。<br />
<div id="attachment_222" class="wp-caption alignnone" style="width: 210px"><a href="http://senghoo.com/wp-content/uploads/2010/08/lkn.jpg"><img src="http://senghoo.com/wp-content/uploads/2010/08/lkn.jpg" alt="LINUX内核技术手册 " title="LINUX内核技术手册" width="200" height="200" class="size-full wp-image-222" /></a><p class="wp-caption-text">LINUX内核技术手册 </p></div><br />
<span id="more-221"></span></p>
<blockquote><p>
　　《Linux内核技术手册》由顶尖的Linux内核开发及维护人员编写，它详尽描述了内核的配置和构建——这对于系统管理员和开发人员而言是一个至关重要的工作。由于没有一个Linux发行套件能够提供完全符合用户要求的Linux内核，所以针对不同计算机的特殊需求，重新配置和编译内核就在所难免。本书介绍如何配置Linux，使其满足您的需要。本书的内容针对Linux 2．6内核。2．6内核与之前的版本相比，几乎在所有的子系统(尤其是内存管理部分和块设备部分)都作出了极其重要的改进，可以满足企业IT环境的需求。 2．6版内核具有相当的灵活性，它可以运行在从手持设备到主流计算机的各种系统中，既可以用作桌面系统，也可以用作服务器系统。其某些功能需要通过用户手动配置，这也就是这本颇具深度的参考手册的写作目的所在。阅读本书您可以了解到：<br />
　　从下载源码到内核配置、构建和安装的整个过程。<br />
　　如何保证您使用的工具版本与内核版本相匹配。<br />
　　参考材料和相关主题的讨论。例如，如何在运行时控制内核。<br />
　　完成各种内核配置任务的技巧。<br />
　　Linux几乎为所有可以与计算机相连的设备都提供了驱动程序。本书第8章介绍了如何根据自己计算机的硬件特性选择正确的驱动程序。这也是本书的特色之一。<br />
　　无论您希望为自己的电脑提供声音支持，或者想让便携式计算机支持无线网络或电源管理，还是使其包含企业级的特性，比如大型服务器上的逻辑卷管理功能，2．6内核几乎可以完成您分配给它的任何任务。然而为了最大地发挥它的潜力，您必须了解Linux 提供的配置选项。本书提供了您所需的一切。
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/221.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>新书入账-深入linux内核架构</title>
		<link>http://senghoo.com/217.html</link>
		<comments>http://senghoo.com/217.html#comments</comments>
		<pubDate>Thu, 05 Aug 2010 11:59:34 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[书]]></category>
		<category><![CDATA[内核]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=217</guid>
		<description><![CDATA[购书癖 又犯了。 去新华书店逛的时候看到全场打折，就忍不住。 《深入linux内核架构》在国内刚刚出版。 原书名： Professional Linux Kernel Architecture 也算是一个经典书籍。 英文版几次升级主要是... ]]></description>
			<content:encoded><![CDATA[<p>购书癖 又犯了。</p>
<p>去新华书店逛的时候看到全场打折，就忍不住。</p>
<p>《深入linux内核架构》在国内刚刚出版。</p>
<p>原书名： Professional Linux Kernel Architecture<br />
也算是一个经典书籍。</p>
<p>英文版几次升级主要是跟随内核的修改。</p>
<p>第一版写的是2.6.0版内核，之后升级到2.6.18，现在又更新到2.6.24。</p>
<p>2.6.24版发布于2008年1月份，中文版翻译的是最新的2.6.24（英语水平不行不能流畅看英文版，惭愧）。</p>
<div id="attachment_218" class="wp-caption alignnone" style="width: 210px"><a href="http://senghoo.com/wp-content/uploads/2010/08/PLKA.jpg"><img class="size-full wp-image-218" title="PLKA" src="http://senghoo.com/wp-content/uploads/2010/08/PLKA.jpg" alt="深入Linux内核架构" width="200" height="200" /></a><p class="wp-caption-text">深入Linux内核架构</p></div>
<p><span id="more-217"></span></p>
<blockquote><p>
　本书讨论了Linux内核的概念、结构和实现。主要内容包括多任务、调度和进程管理，物理内存的管理以及内核与相关硬件的交互，用户空间的进程如何访问虚拟内存，如何编写设备驱动程序，模块机制以及虚拟文件系统，Ext文件系统属性和访问控制表的实现方式，内核中网络的实现，系统调用的实现方式，内核对时间相关功能的处理，页面回收和页交换的相关机制以及审计的实现等。此外，本书借助内核源代码中最关键的部分进行讲解，帮助读者掌握重要的知识点，从而在运用中充分展现Linux系统的魅力。<br />
　　本书适合Linux内核爱好者阅读。
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/217.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDD读书笔记第十二章-PCI驱动程序</title>
		<link>http://senghoo.com/201.html</link>
		<comments>http://senghoo.com/201.html#comments</comments>
		<pubDate>Fri, 30 Jul 2010 11:51:08 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[drivers]]></category>
		<category><![CDATA[pci]]></category>
		<category><![CDATA[模块]]></category>
		<category><![CDATA[配置空间]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=201</guid>
		<description><![CDATA[PCI接口 PCI的设计目标： 更好的传输性能 平台无关性 简化往系统中添加删除外设的工作 更多关于PCI的内容查看PCI规范 PCI寻址 Linux支持PCI域（16位），每个PCI域可以有256个总线（8位）每个总线... ]]></description>
			<content:encoded><![CDATA[<h3>PCI接口</h3>
<p>PCI的设计目标：</p>
<ul>
<li>更好的传输性能</li>
<li>平台无关性</li>
<li>简化往系统中添加删除外设的工作</li>
</ul>
<p>更多关于PCI的内容查看<a href="http://senghoo.com/wp-content/uploads/2010/07/pci中文规范.pdf">PCI规范</a></p>
<h4>PCI寻址</h4>
<p>Linux支持PCI域（16位），每个PCI域可以有256个总线（8位）每个总线上32个设备（5位）每个设备8种功能（3位）。<br />
在硬件级每个功能由16位地址来表示（没有域），在linux中因为添加了域每个功能应该用32位来表示。<br />
PCI总线中I/O空间使用32位地址总线，而内存空间可通过32位或64位来访问。<br />
<a href="http://senghoo.com/wp-content/uploads/2010/07/pci.png"><img src="http://senghoo.com/wp-content/uploads/2010/07/pci-300x159.png" alt="" title="pci" width="300" height="159" class="alignnone size-medium wp-image-202" /></a><br />
<strong>点击查看大图</strong><br />
<span id="more-201"></span></p>
<h4>配置寄存器和初始化</h4>
<p>所有的PCI设备都至少包含256个字节的配置地址空间，前64字节是标准化的后面的字节是设备相关的。<br />
PCI寄存器始终是小头的，使用时用相关的转换宏转换，详情查看第十章。<br />
标准化PCI配置寄存器图示：<br />
<div id="attachment_204" class="wp-caption alignnone" style="width: 310px"><a href="http://senghoo.com/wp-content/uploads/2010/07/pci_config_memory.png"><img src="http://senghoo.com/wp-content/uploads/2010/07/pci_config_memory-300x170.png" alt="标准化PCI配置寄存器结构图" title="pci_config_memory" width="300" height="170" class="size-medium wp-image-204" /></a><p class="wp-caption-text">标准化PCI配置寄存器结构图</p></div><br />
<strong>点击查看大图</strong><br />
各字段含义：<br />
vendorID<br />
制造商ID，每个制造商从PCI Special Interest Group申请一个唯一的ID<br />
deviceID<br />
设备ID，又制造商指定<br />
class<br />
设备所属的组。<br />
subsystem vendorID<br />
subsystem deviceID<br />
用来进一步识别硬件，用于通用芯片链接到PCI接口的情况。<br />
struct pci_device_id 结构体表示驱动程序所支持的PCI设备。该结构体有如下字段，这些字段可以使用 PCI_ANY_ID来表示通用。<br />
__u32 vendor;<br />
__u32 device;<br />
指定厂商和设备ID。<br />
__u32 subvendor;<br />
__u32 subdevice;<br />
子系统厂商和子系统ID<br />
__u32 class;<br />
__u32 class_mask;<br />
设备类型<br />
kernel_ulong_t driver_data;<br />
用来区分设备。<br />
初始化struct pci_device_id结构体所用的宏</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code18'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20118"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p201code18"><pre class="c" style="font-family:monospace;">PCI_DEVICE<span style="color: #009900;">&#40;</span>vendor<span style="color: #339933;">,</span> device<span style="color: #009900;">&#41;</span>
PCI_DEVICE_CLASS<span style="color: #009900;">&#40;</span>device_class<span style="color: #339933;">,</span> device_class_mask<span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*分别使用厂家ID，设备ID来和设备类型来表示所支持的硬件*/</span>
<span style="color: #808080; font-style: italic;">/*例子*/</span>
<span style="color: #808080; font-style: italic;">/*drivers/usb/host/ehci-hcd.c:*/</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">const</span> <span style="color: #993333;">struct</span> pci_device_id pci_ids<span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #808080; font-style: italic;">/* handle any USB 2.0 EHCI controller */</span>
	PCI_DEVICE_CLASS<span style="color: #009900;">&#40;</span>
		<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>PCI_CLASS_SERIAL_USB <span style="color: #339933;">&lt;&lt;</span> <span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #208080;">0x20</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ~<span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	.<span style="color: #202020;">driver_data</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>ehci_driver<span style="color: #339933;">,</span>
	<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#123;</span> <span style="color: #808080; font-style: italic;">/* end: all zeroes */</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*drivers/i2c/busses/i2c-i810.c:*/</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">struct</span> pci_device_id i810_ids<span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#123;</span> PCI_DEVICE<span style="color: #009900;">&#40;</span>PCI_VENDOR_ID_INTEL<span style="color: #339933;">,</span>
 			PCI_DEVICE_ID_INTEL_82810_IG1<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span> PCI_DEVICE<span style="color: #009900;">&#40;</span>PCI_VENDOR_ID_INTEL<span style="color: #339933;">,</span>
 			PCI_DEVICE_ID_INTEL_82810_IG3<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span> PCI_DEVICE<span style="color: #009900;">&#40;</span>PCI_VENDOR_ID_INTEL<span style="color: #339933;">,</span>
 			PCI_DEVICE_ID_INTEL_82810E_IG<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span> PCI_DEVICE<span style="color: #009900;">&#40;</span>PCI_VENDOR_ID_INTEL<span style="color: #339933;">,</span>
 			PCI_DEVICE_ID_INTEL_82815_CGC<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span> PCI_DEVICE<span style="color: #009900;">&#40;</span>PCI_VENDOR_ID_INTEL<span style="color: #339933;">,</span>
 			PCI_DEVICE_ID_INTEL_82845G_IG<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>MODULE_DEVICE_TABLE</h4>
<p>和模块的初始化和拆除函数一样需要到处此结构让系统知道那个模块针对那个硬件</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code19'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20119"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p201code19"><pre class="c" style="font-family:monospace;">	MODULE_DEVICE_TABLE<span style="color: #009900;">&#40;</span>pci<span style="color: #339933;">,</span> i810_ids<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>注册PCI驱动程序</h4>
<p>pci主要结构体：struct pci_driver结构体。个字段含义为</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code20'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20120"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code" id="p201code20"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>name<span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*驱动程序的名字*/</span>
<span style="color: #993333;">const</span> <span style="color: #993333;">struct</span> pci_device_id <span style="color: #339933;">*</span>id_table<span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*pci_device_id表的指针*/</span>
<span style="color: #993333;">int</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>probe<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">struct</span> 	 
			pci_device_id <span style="color: #339933;">*</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*探测函数的指针*/</span>
<span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>remove<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*移除函数的指针*/</span>
<span style="color: #993333;">int</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>suspend<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> u32 state<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*挂起函数的指针*/</span>
<span style="color: #993333;">int</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>resume<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*恢复函数的指针*/</span>
<span style="color: #808080; font-style: italic;">/*例子*/</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">struct</span> pci_driver pci_driver <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
	.<span style="color: #202020;">name</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;pci_skel&quot;</span><span style="color: #339933;">,</span>
	.<span style="color: #202020;">id_table</span> <span style="color: #339933;">=</span> ids<span style="color: #339933;">,</span>
	.<span style="color: #202020;">probe</span> <span style="color: #339933;">=</span> probe<span style="color: #339933;">,</span>
	.<span style="color: #202020;">remove</span> <span style="color: #339933;">=</span> remove<span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*注册结构*/</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">int</span> __init pci_skel_init<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> pci_register_driver<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>pci_driver<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #808080; font-style: italic;">/*拆除*/</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span> __exit pci_skel_exit<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	pci_unregister_driver<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>pci_driver<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>老式PCI探测</h4>
<p>相关函数</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code21'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20121"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p201code21"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*查找特定设备：*/</span>
<span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>pci_get_device<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> vendor<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> 
			<span style="color: #993333;">int</span> device<span style="color: #339933;">,</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>from<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/*查找后打开计数器会+1所以必须调用pci_dev_put函数来减少计数器*/</span>
<span style="color: #808080; font-style: italic;">/*例子*/</span>
<span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">;</span>
dev <span style="color: #339933;">=</span> pci_get_device<span style="color: #009900;">&#40;</span>PCI_VENDOR_FOO<span style="color: #339933;">,</span> PCI_DEVICE_FOO<span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>dev<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #808080; font-style: italic;">/* Use the PCI device */</span>
	...
	<span style="color: #202020;">pci_dev_put</span><span style="color: #009900;">&#40;</span>dev<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #808080; font-style: italic;">/*查找设备时指定子系统:*/</span>
<span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>pci_get_subsys<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> vendor<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> device<span style="color: #339933;">,</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ss_vendor<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ss_device<span style="color: #339933;">,</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>from<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*在struct pci_bus 上的系统PCI设备列表中查询指定设备和功能编号：*/</span>
<span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>pci_get_slot<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_bus <span style="color: #339933;">*</span>bus<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> devfn<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>激活PCI设备</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code22'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20122"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p201code22"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> pci_enable_device<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>访问配置空间</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code23'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20123"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p201code23"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> pci_read_config_byte<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u8 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_read_config_word<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u16 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_read_config_dword<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u32 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_write_config_byte<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u8 val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_write_config_word<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u16 val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_write_config_dword<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> where<span style="color: #339933;">,</span> u32 val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_bus_read_config_byte <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_bus <span style="color: #339933;">*</span>bus<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> devfn<span style="color: #339933;">,</span> <span style="color: #993333;">int</span>
where<span style="color: #339933;">,</span> u8 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_bus_read_config_word <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_bus <span style="color: #339933;">*</span>bus<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> devfn<span style="color: #339933;">,</span> <span style="color: #993333;">int</span>
where<span style="color: #339933;">,</span> u16 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> pci_bus_read_config_dword <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_bus <span style="color: #339933;">*</span>bus<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> devfn<span style="color: #339933;">,</span> <span style="color: #993333;">int</span>
where<span style="color: #339933;">,</span> u32 <span style="color: #339933;">*</span>val<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>访问I/O和内存空间</h4>
<p>PCI有6个I/O区他们的符号名称分别为PCI_BASE_ADDRESS_0到PCI_BASE_ADDRESS_5</p>
<p>获取I/O区域基地址</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p201code24'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p20124"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p201code24"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> pci_resource_start<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> bar<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> pci_resource_end<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> bar<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> pci_resource_flags<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> pci_dev <span style="color: #339933;">*</span>dev<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> bar<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*这些函数分别返回头地址，未地址和标志。*/</span>
<span style="color: #808080; font-style: italic;">/*资源标志存储在&lt;linux/ioport.h&gt;中。其中重要的项目*/</span>
IORESOURCE_IO
IORESOURCE_MEM
<span style="color: #339933;">&lt;</span>h4<span style="color: #339933;">&gt;</span>PCI中断<span style="color: #339933;">&lt;/</span>h4<span style="color: #339933;">&gt;</span>
PCI的中断号能直接在配置寄存器中读取
<span style="color: #339933;">&lt;</span>pre lang<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;C&quot;</span><span style="color: #339933;">&gt;</span>
result <span style="color: #339933;">=</span> pci_read_config_byte<span style="color: #009900;">&#40;</span>dev<span style="color: #339933;">,</span> PCI_INTERRUPT_LINE<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>myirq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

</pre>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/201.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDD读书笔记第十一章-内核的数据类型</title>
		<link>http://senghoo.com/180.html</link>
		<comments>http://senghoo.com/180.html#comments</comments>
		<pubDate>Thu, 29 Jul 2010 08:08:41 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[ldd]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[内核]]></category>
		<category><![CDATA[数据类型]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=180</guid>
		<description><![CDATA[Linux数据类型 Linux内核C语言数据类型大小 &#160; Arch &#160; &#160; char &#160; &#160; short &#160; &#160; int &#160; &#160; long &#160; &#160; ptr &#160; &#160; long-long &#160; &#160; u8 &#160; &#160; u16&#160; &#160; u32&#160; &#160; u64&... ]]></description>
			<content:encoded><![CDATA[<h3>Linux数据类型</h3>
<table border="1" >
<caption align=top>Linux内核C语言数据类型大小<br />
<caption>
<tr>
<td>&nbsp; Arch &nbsp; </td>
<td>&nbsp; char &nbsp; </td>
<td>&nbsp; short &nbsp; </td>
<td>&nbsp; int &nbsp; </td>
<td> &nbsp;  long &nbsp; </td>
<td> &nbsp;  ptr &nbsp; </td>
<td> &nbsp; long-long &nbsp; </td>
<td> &nbsp; u8 &nbsp; </td>
<td>&nbsp; u16&nbsp; </td>
<td>&nbsp; u32&nbsp; </td>
<td>&nbsp; u64&nbsp;  </td>
</tr>
<tr>
<td>i386</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>alpha</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>armv41</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>ia64</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>m86k</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>mips</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>ppc</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>sparc</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>sparc64</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>4</td>
<td>4</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
<tr>
<td>x86_64</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
<td>8</td>
<td>8</td>
<td>1</td>
<td>2</td>
<td>4</td>
<td>8</td>
</tr>
</table>
<p>需要注意的是sparc64架构运行的是32位用户空间。但是在内核空间是64位的。<br />
在当前的所有平台上指针和long型的大小总相同<br />
u8等固定大小的值有其有符号版本以s代替u如：s8<br />
如果需要在用户空间使用固定大小的话使用双下划线版本如__u8<br />
固定大小的类型是linux特有的 如果考虑向其他unix变种移植应使用C99标准类型变量如:uint8_t<br />
<span id="more-180"></span></p>
<h3>其他有关移植性的问题</h3>
<h4>时间变量</h4>
<p>使用时间变量的时候不要使用特定的值而是使用HZ宏如：<br />
n毫秒为：n*HZ/1000</p>
<h4>页大小</h4>
<p>同样不要使用特定的值。而是使用如下函数</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code35'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18035"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p180code35"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;asm/page.h&gt;</span>
<span style="color: #993333;">int</span> order <span style="color: #339933;">=</span> get_order<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">16</span><span style="color: #339933;">*</span><span style="color: #0000dd;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/*传递的参数必须是2的幂*/</span>
buf <span style="color: #339933;">=</span> get_free_pages<span style="color: #009900;">&#40;</span>GFP_KERNEL<span style="color: #339933;">,</span>order<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>字节序</h4>
<p>不要对字节序做任何假设。<br />
头文件<i>asm/byteorder.h</i>根据平台定义了__BIG_ENDIAN 或 __LITTLE_ENDIAN。<br />
也可以使用如下函数转换成需要的类型</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code36'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18036"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p180code36"><pre class="c" style="font-family:monospace;">u32 cpu_to_le32 <span style="color: #009900;">&#40;</span>u32<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
u32 le32_to_cpu <span style="color: #009900;">&#40;</span>u32<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>这些宏相对le有be版本如be32_to_cpu，并且有相应的16为版本。<br />
更多资料查看：<br />
linux/byteorder/big_endian.h<br />
linux/byteorder/little_endian.h</p>
<h4>数据对齐</h4>
<p>访问未对其的数据</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code37'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18037"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p180code37"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;asm/unaligned.h&gt;</span>
get_unaligned<span style="color: #009900;">&#40;</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
put_unaligned<span style="color: #009900;">&#40;</span>val<span style="color: #339933;">,</span> ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>对结构添加__attribute__可防止编译器自动对齐如</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code38'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18038"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p180code38"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
	u16 id<span style="color: #339933;">;</span>
	u64 lun<span style="color: #339933;">;</span>
	u16 reserved1<span style="color: #339933;">;</span>
	u32 reserved2<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> __attribute__ <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>packed<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> scsi<span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>指针和错误值</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code39'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18039"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p180code39"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;linux/err.h&gt;</span>
<span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ERR_PTR<span style="color: #009900;">&#40;</span><span style="color: #993333;">long</span> error<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #808080; font-style: italic;">/*错误码到指针类型的错误指针*/</span>
<span style="color: #993333;">long</span> IS_ERR<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #808080; font-style: italic;">/*判断是否为错误指针*/</span>
<span style="color: #993333;">long</span> PTR_ERR<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #808080; font-style: italic;">/*错误指针到错误码*/</span></pre></td></tr></table></div>

<h3>链表</h3>
<p><a href="http://senghoo.com/wp-content/uploads/2010/07/kernel_link_struct.jpg"><img src="http://senghoo.com/wp-content/uploads/2010/07/kernel_link_struct.jpg" alt="" title="kernel_link_struct" width="553" height="331" class="alignnone size-full wp-image-195" /></a><br />
如果重入的时候可能并发访问必须给链表添加锁机制。<br />
定义在linux/list.h中：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code40'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18040"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code" id="p180code40"><pre class="c" style="font-family:monospace;">	<span style="color: #993333;">struct</span> list_head <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>next<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>prev<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
使用链表：
<span style="color: #339933;">&lt;</span>pre lang<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;C&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">#include &lt;linux/list.h&gt;</span>
<span style="color: #993333;">struct</span> todo_struct <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> list_head list<span style="color: #339933;">;</span>
	<span style="color: #993333;">int</span> priority<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* driver specific */</span>
	<span style="color: #808080; font-style: italic;">/* 其他字段 */</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*运行时初始化链表头*/</span>
<span style="color: #993333;">struct</span> list_head todo_list<span style="color: #339933;">;</span>
INIT_LIST_HEAD<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>todo_list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*编译时初始化*/</span>
LIST_HEAD<span style="color: #009900;">&#40;</span>todo_list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*添加删除相关函数*/</span>
list_add<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>new<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*添加到头部*/</span>
list_add_tail<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>new<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*添加到尾部*/</span>
list_del<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>entry<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
list_del_init<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>entry<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*删除链表项，如果可能插入到其他链表，使用init版本*/</span>
list_move<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>entry<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
list_move_tail<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>entry<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*把给定的链表移动到头部或尾部*/</span>
list_empty<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*如果链表为空返回非零值*/</span>
list_splice<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>list<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*head之后插入list来合并链表*/</span></pre></td></tr></table></div>

<p>获取包含链表的结构的指针</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code41'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18041"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p180code41"><pre class="c" style="font-family:monospace;">list_entry<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>ptr<span style="color: #339933;">,</span> type_of_struct<span style="color: #339933;">,</span> 				field_name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*ptr为链表结构，type_of_struct为包含链表的结构的名称
*field_name为结构中链表字段的名称
*/</span></pre></td></tr></table></div>

<p>遍历链表</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code42'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18042"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p180code42"><pre class="c" style="font-family:monospace;">list_for_each<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>cursor<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head 			<span style="color: #339933;">*</span>list<span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*遍历链表*/</span>
list_for_each_prev<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>cursor<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> 					list_head <span style="color: #339933;">*</span>list<span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*向前遍历链表*/</span>
list_for_each_safe<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>cursor<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> 					list_head <span style="color: #339933;">*</span>next<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span>
				list_head <span style="color: #339933;">*</span>list<span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*如果在遍历中需要删除链表使用此方法*/</span>
list_for_each_entry<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">*</span>cursor<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>list<span style="color: #339933;">,</span> 				member<span style="color: #009900;">&#41;</span>
list_for_each_entry_safe<span style="color: #009900;">&#40;</span>type <span style="color: #339933;">*</span>cursor<span style="color: #339933;">,</span> type <span style="color: #339933;">*</span>next<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> 			list_head <span style="color: #339933;">*</span>list<span style="color: #339933;">,</span>member<span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*遍历并且直接获取包含链表的结构体的指针*/</span></pre></td></tr></table></div>

<p>两个例子：</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code43'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18043"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p180code43"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> todo_add_entry<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> todo_struct <span style="color: #339933;">*</span>new<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>ptr<span style="color: #339933;">;</span>
	<span style="color: #993333;">struct</span> todo_struct <span style="color: #339933;">*</span>entry<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>ptr <span style="color: #339933;">=</span> todo_list.<span style="color: #202020;">next</span><span style="color: #339933;">;</span> ptr <span style="color: #339933;">!=</span> <span style="color: #339933;">&amp;</span>todo_list<span style="color: #339933;">;</span> ptr <span style="color: #339933;">=</span> ptr<span style="color: #339933;">-&gt;</span>next<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		entry <span style="color: #339933;">=</span> list_entry<span style="color: #009900;">&#40;</span>ptr<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> todo_struct<span style="color: #339933;">,</span> list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>entry<span style="color: #339933;">-&gt;</span>priority <span style="color: #339933;">&lt;</span> new<span style="color: #339933;">-&gt;</span>priority<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			list_add_tail<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>new<span style="color: #339933;">-&gt;</span>list<span style="color: #339933;">,</span> ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	list_add_tail<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>new<span style="color: #339933;">-&gt;</span>list<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>todo_struct<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p180code44'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18044"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p180code44"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> todo_add_entry<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> todo_struct <span style="color: #339933;">*</span>new<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> list_head <span style="color: #339933;">*</span>ptr<span style="color: #339933;">;</span>
	<span style="color: #993333;">struct</span> todo_struct <span style="color: #339933;">*</span>entry<span style="color: #339933;">;</span>
	list_for_each<span style="color: #009900;">&#40;</span>ptr<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>todo_list<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		entry <span style="color: #339933;">=</span> list_entry<span style="color: #009900;">&#40;</span>ptr<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> todo_struct<span style="color: #339933;">,</span> list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>entry<span style="color: #339933;">-&gt;</span>priority <span style="color: #339933;">&lt;</span> new<span style="color: #339933;">-&gt;</span>priority<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			list_add_tail<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>new<span style="color: #339933;">-&gt;</span>list<span style="color: #339933;">,</span> ptr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	ist_add_tail<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>new<span style="color: #339933;">-&gt;</span>list<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>todo_struct<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/180.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDD读书笔记第十章-中断处理</title>
		<link>http://senghoo.com/174.html</link>
		<comments>http://senghoo.com/174.html#comments</comments>
		<pubDate>Wed, 28 Jul 2010 06:33:34 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[中断]]></category>
		<category><![CDATA[并发]]></category>
		<category><![CDATA[延迟]]></category>
		<category><![CDATA[硬件]]></category>
		<category><![CDATA[驱动]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=174</guid>
		<description><![CDATA[当硬件需要处理器关注时（如硬盘读取完成，通知可以继续读取其他内容。），产生某个事件通知处理器。这种机制叫做中断。一个中断仅仅是个信号。 准备并口 在没有设定产生中断之前，设... ]]></description>
			<content:encoded><![CDATA[<p>当硬件需要处理器关注时（如硬盘读取完成，通知可以继续读取其他内容。），产生某个事件通知处理器。这种机制叫做中断。一个中断仅仅是个信号。</p>
<h3>准备并口</h3>
<p>在没有设定产生中断之前，设备不会产生中断。<br />
对于并口标准来说设置端口2(0x37a:<em>0&#215;378+2</em>,0x27a:<em>0&#215;278+2</em>或者其他）的第四位来启用中断报告，初始化的时候用outb莱斯设置这个位。<br />
中断启用时，每当引脚10（ACK）位的电平发生从底到高改变时，并口就会产生一个中断。<br />
<a href="http://senghoo.com/wp-content/uploads/2010/07/LPT.png"><img src="http://senghoo.com/wp-content/uploads/2010/07/LPT.png" alt="" title="LPT" width="552" height="382" class="alignnone size-full wp-image-168" /></a><br />
<span id="more-174"></span></p>
<h3>安装中断处理列程</h3>
<p>相关函数和定义</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code56'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17456"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p174code56"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;linux/interrupt.h&gt;</span>
<span style="color: #993333;">int</span> request_irq<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span>
		irqreturn_t <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>handler<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*,</span>
				 <span style="color: #993333;">struct</span> pt_regs <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> flags<span style="color: #339933;">,</span>
		<span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>dev_name<span style="color: #339933;">,</span>
		<span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dev_id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*函数request_irq函数返回0时表示成功，为负值时表示错误码 返回-EBUSY表示已经有另一个程序占用了中断信号线*/</span>
<span style="color: #993333;">void</span> free_irq<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dev_id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> can_request_irq<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> flags<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*can_request_irq用于查询中断线是否可用，注意can_request_irq后request_irq之前可能发生一些事情导致中断线被其他程序占用*/</span></pre></td></tr></table></div>

<p>参数的具体意义如下</p>
<blockquote><p>
unsigned int irq<br />
所请求的中断号<br />
irqreturn_t (*handler)(int, void *, struct pt_regs *)<br />
中断处理函数。<br />
unsigned long flags<br />
中断有关的位掩码选项<br />
const char *dev_name<br />
用来在/proc/interrupts中显示中断拥有者的字符串<br />
void *dev_id<br />
共享中断信号线时他是唯一标示来表示设备，驱动程序也可以使用它指向驱动程序自己的私有数据区。<br />
在flags中设置的位选项<br />
SA_INTERRUPT<br />
表明是快速处理例程<br />
SA_SHIRQ<br />
表示中断可以在设备之间共享<br />
SA_SAMPLE_RANDOM<br />
是否能对/dev/random设备和/dev/urandom设备使用的熵池有贡献。
</p></blockquote>
<p>short_irq中的的例中断申请</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code57'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17457"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p174code57"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	result <span style="color: #339933;">=</span> request_irq<span style="color: #009900;">&#40;</span>short_irq<span style="color: #339933;">,</span> short_interrupt<span style="color: #339933;">,</span>
				SA_INTERRUPT<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;short&quot;</span><span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		printk<span style="color: #009900;">&#40;</span>KERN_INFO <span style="color: #ff0000;">&quot;short: can't get <span style="color: #000099; font-weight: bold;">\
</span>			assigned irq %i<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>short_irq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		short_irq <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span> 
		<span style="color: #808080; font-style: italic;">/* actually enable it -- assume this 
			*is* a parallel port */</span>
		outb<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x10</span><span style="color: #339933;">,</span>short_base<span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>自动检测irq号</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code58'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17458"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p174code58"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #808080; font-style: italic;">/* 未指定信号线根据基地址使用默认值*/</span>
	<span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span>short_base<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #208080;">0x378</span><span style="color: #339933;">:</span> short_irq <span style="color: #339933;">=</span> <span style="color: #0000dd;">7</span><span style="color: #339933;">;</span>break<span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #208080;">0x278</span><span style="color: #339933;">:</span> short_irq <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>break<span style="color: #339933;">;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #208080;">0x3bc</span><span style="color: #339933;">:</span> short_irq <span style="color: #339933;">=</span> <span style="color: #0000dd;">5</span><span style="color: #339933;">;</span>break<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>内核帮助下探测</h4>
<p>内核提供了底层设施来探测中断号。它只能在非共享中断模式下工作。<br />
相关函数:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code59'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17459"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p174code59"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;linux/interrupt.h&gt;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> probe_irq_on<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*返回一个未分配中断的掩码，返回值传递给probe_irq_off函数，
此函数执行后驱动程序要安排设备至少产生一次中断*/</span>
<span style="color: #993333;">int</span> probe_irq_off<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*请求设备产生中断以后以probe_irq_on的返回值为参数调用。
如果没有中断产生返回0，如果产生了多次中断（产生二义性）返回一个负值。*/</span></pre></td></tr></table></div>

<p>\<br />
注意在probe_irq_on()之后启用中断在probe_irq_off()之前禁用中断，并且在probe_irq_off之后，需要处理设备上待处理的中断。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code60'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17460"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
</pre></td><td class="code" id="p174code60"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> count <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> mask<span style="color: #339933;">;</span>
	mask <span style="color: #339933;">=</span> probe_irq_on<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x10</span><span style="color: #339933;">,</span>short_base<span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* enable reporting */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x00</span><span style="color: #339933;">,</span>short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* clear the bit */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0xFF</span><span style="color: #339933;">,</span>short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* set the bit: interrupt! */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x00</span><span style="color: #339933;">,</span>short_base<span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* disable reporting */</span>
	udelay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* give it some time */</span>
	short_irq <span style="color: #339933;">=</span> probe_irq_off<span style="color: #009900;">&#40;</span>mask<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">=</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #808080; font-style: italic;">/* none of them? */</span>
	printk<span style="color: #009900;">&#40;</span>KERN_INFO <span style="color: #ff0000;">&quot;short: no irq reported by probe<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	short_irq <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #808080; font-style: italic;">/*
	* if more than one line has been activated, the 
	*result is negative. We should service the interrup
	*(no need for lpt port) and loop over again. Loop 
	*at most five times, then give up
	*/</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">&amp;&amp;</span> count<span style="color: #339933;">++</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
	printk<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;short: probe failed %i times, 
		giving up<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>DIY探测</h4>
<p>DIY探测时测试所有可能的IRQ，来取得真正的IRQ号。</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code61'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17461"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code" id="p174code61"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>pre lang<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;C&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #993333;">int</span> trials<span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">5</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">7</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">9</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> tried<span style="color: #009900;">&#91;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> i<span style="color: #339933;">,</span> count <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*
* install the probing handler for all possible lines.
*Remember the result (0 for success, or -EBUSY) in order
*to only free what has been acquired
*/</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> trials<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
	tried<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> request_irq<span style="color: #009900;">&#40;</span>trials<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> short_probing<span style="color: #339933;">,</span>
				SA_INTERRUPT<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;short probe&quot;</span><span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
	short_irq <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* none got, yet */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x10</span><span style="color: #339933;">,</span>short_base<span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* enable */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x00</span><span style="color: #339933;">,</span>short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0xFF</span><span style="color: #339933;">,</span>short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* toggle the bit */</span>
	outb_p<span style="color: #009900;">&#40;</span><span style="color: #208080;">0x00</span><span style="color: #339933;">,</span>short_base<span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* disable */</span>
	udelay<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* give it some time */</span>
	<span style="color: #808080; font-style: italic;">/* the value has been set by the handler */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">=</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #808080; font-style: italic;">/* none of them? */</span>
		printk<span style="color: #009900;">&#40;</span>KERN_INFO <span style="color: #ff0000;">&quot;short: no irq reported <span style="color: #000099; font-weight: bold;">\
</span>					by probe<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #808080; font-style: italic;">/*
	* If more than one line has been activated, 
	*the result is negative. We should service the
	*interrupt (but the lpt portdoesn't need it) and 
	*loop over again. Do it at most 5 times
	*/</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&lt;=</span><span style="color: #0000dd;">0</span> <span style="color: #339933;">&amp;&amp;</span> count<span style="color: #339933;">++</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* end of loop, uninstall the handler */</span>
	<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> trials<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>tried<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
	free_irq<span style="color: #009900;">&#40;</span>trials<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> NULL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>short_irq <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
		printk<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;short: probe failed %i times, giving <span style="color: #000099; font-weight: bold;">\
</span>				up<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>快速和慢速处理例程</h4>
<p>顾名思义快速处理例程和慢速处理例程区别是速度。慢速处理例程处理时课要求处理器再次启用中断。<br />
在现代内核中这种区别已经消失。只剩下一个快速中断（使用SA_INTERRUPT标志申请的中断，快速中断执行时当前处理器上的所有其他中断都会被禁止。</p>
<h3>实现中断处理例程</h3>
<p>中断处理例程的限制：</p>
<ul>
<li>不能向用户空间发送或接收数据</li>
<li>不能做可能发生休眠的操作</li>
<li>不能调用schdule函数</li>
</ul>
<p>short中的示例</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code62'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17462"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p174code62"><pre class="c" style="font-family:monospace;">irqreturn_t short_interrupt<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dev_id<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> pt_regs <span style="color: #339933;">*</span>regs<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #993333;">struct</span> timeval tv<span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> written<span style="color: #339933;">;</span>
do_gettimeofday<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>tv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/* Write a 16 byte record. Assume PAGE_SIZE is a multiple of 16 */</span>
written <span style="color: #339933;">=</span> sprintf<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>short_head<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;%08u.%06u<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>tv.<span style="color: #202020;">tv_sec</span> <span style="color: #339933;">%</span> <span style="color: #0000dd;">100000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>tv.<span style="color: #202020;">tv_usec</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
BUG_ON<span style="color: #009900;">&#40;</span>written <span style="color: #339933;">!=</span> <span style="color: #0000dd;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
short_incr_bp<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>short_head<span style="color: #339933;">,</span> written<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
wake_up_interruptible<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>short_queue<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
<span style="color: #808080; font-style: italic;">/* awake any reading process */</span>
<span style="color: #b1b100;">return</span> IRQ_HANDLED<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">static</span> <span style="color: #000000; font-weight: bold;">inline</span> <span style="color: #993333;">void</span> short_incr_bp<span style="color: #009900;">&#40;</span><span style="color: #993333;">volatile</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> <span style="color: #339933;">*</span>index<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> delta<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> new <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>index <span style="color: #339933;">+</span> delta<span style="color: #339933;">;</span>
	barrier<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* Don't optimize these two together */</span>
	<span style="color: #339933;">*</span>index <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>new <span style="color: #339933;">&gt;=</span> <span style="color: #009900;">&#40;</span>short_buffer <span style="color: #339933;">+</span> PAGE_SIZE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> 		short_buffer <span style="color: #339933;">:</span> new<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>处理例程的参数及返回值</h4>
<p>函数原型</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code63'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17463"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p174code63"><pre class="c" style="font-family:monospace;">irqreturn_t handler<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span> dev_id<span style="color: #339933;">,</span>
			<span style="color: #993333;">struct</span> pt_regs <span style="color: #339933;">*</span>reg<span style="color: #009900;">&#41;</span></pre></td></tr></table></div>

<p>irq为中断号，<br />
dev_id为一种客户数据类型，一般存储指向设备数据结构的指针<br />
regs包含进入中断代码之前的处理器上下文快照<br />
返回值，用来指明是否真正处理了一个中断。如果发现需要处理返回<br />
IRQ_HANDLED否则为IRQ_NONE<br />
也可以用IRQ_RETVAL来产生返回值<br />
典型用法</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code64'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17464"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code" id="p174code64"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> irqreturn_t sample_interrupt<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dev_id<span style="color: #339933;">,</span> 		<span style="color: #993333;">struct</span> pt_regs <span style="color: #339933;">*</span>regs<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> sample_dev <span style="color: #339933;">*</span>dev <span style="color: #339933;">=</span> dev_id<span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* now `dev' points to the right hardware item */</span>
	<span style="color: #808080; font-style: italic;">/* .... */</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">static</span> <span style="color: #993333;">void</span> sample_open<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> inode <span style="color: #339933;">*</span>inode<span style="color: #339933;">,</span> <span style="color: #993333;">struct</span> file
				<span style="color: #339933;">*</span>filp<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">struct</span> sample_dev <span style="color: #339933;">*</span>dev <span style="color: #339933;">=</span> hwinfo <span style="color: #339933;">+</span> MINOR<span style="color: #009900;">&#40;</span>inode<span style="color: #339933;">-&gt;</span>i_rdev<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	request_irq<span style="color: #009900;">&#40;</span>dev<span style="color: #339933;">-&gt;</span>irq<span style="color: #339933;">,</span> sample_interrupt<span style="color: #339933;">,</span>
		<span style="color: #0000dd;">0</span> <span style="color: #808080; font-style: italic;">/* flags */</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;sample&quot;</span><span style="color: #339933;">,</span> dev <span style="color: #808080; font-style: italic;">/* dev_id */</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/*....*/</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>h4<span style="color: #339933;">&gt;</span>启用和禁用中断<span style="color: #339933;">&lt;/</span>h4<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>h5<span style="color: #339933;">&gt;</span>禁用单个中断<span style="color: #339933;">&lt;/</span>h5<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>pre lang<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;C&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #993333;">void</span> disable_irq<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> disable_irq_nosync<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #808080; font-style: italic;">/*立即返回*/</span>
<span style="color: #993333;">void</span> enable_irq<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>禁用中断的时候只有禁用中断的次数和启用中断的次数相同的情况下才再次启用中断。</p>
<h5>禁用所有中断</h5>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code65'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17465"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p174code65"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> local_irq_save<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> flags<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> local_irq_disable<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> local_irq_restore<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> flags<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> local_irq_enable<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>顶半部和底半部</h3>
<p>为了解决工作量和速度的冲突linux通过将中断处理例程分成两部分来解决这个问题。<br />
顶半部：是实际响应的处理例程也就是用request_irq注册的例程<br />
底半部：是一个被顶半部调度，并在稍候更安全的时间内延迟执行的例程。<br />
典型操作是顶半部保存设备的数据导一个设备特定的缓冲区并调度底半部，然后退出。<br />
稍候底半部会执行其他必要的操作。<br />
底半部的调度方法有两种分别是tasklet和工作队列<br />
tasklet速度块但是所有操作必须是原子的。<br />
工作队列会有更长的延迟但是它可以休眠。<br />
tasklet和工作队列的更多资料查看第五章<br />
<a title="并发和竞态（一）" href="http://senghoo.com/79.html" rel="bookmark">并发和竞态（一）</a><br />
<a title="并发和竞态（二）" href="http://senghoo.com/99.html" rel="bookmark">并发和竞态（二）</a></p>
<h3>中断共享</h3>
<p>中断共享也是通过request_irq安装的，但是有两处不同：</p>
<ul>
<li>必须指定flages参数的SA_SHIRQ位</li>
<li>dev_id参数必须是唯一的</li>
</ul>
<p>如果满足下列条件之一request_irq就会成功。</p>
<ul>
<li>中断信号线空闲</li>
<li>任何已经注册了该信号线的处理例程也标示了是共享的</li>
</ul>
<p>当共享的信号线中出现信号时内核会用各自的dev_id调用各个中断处理例程。<br />
所以驱动程序必须判断是否是自己的中断。如果不是需要迅速退出。<br />
shrot当中的范例</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p174code66'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p17466"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p174code66"><pre class="c" style="font-family:monospace;">irqreturn_t short_sh_interrupt<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> irq<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dev_id<span style="color: #339933;">,</span> 
					<span style="color: #993333;">struct</span> pt_regs <span style="color: #339933;">*</span>regs<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #993333;">int</span> value<span style="color: #339933;">,</span> written<span style="color: #339933;">;</span>
	<span style="color: #993333;">struct</span> timeval tv<span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* If it wasn't short, return immediately */</span>
	value <span style="color: #339933;">=</span> inb<span style="color: #009900;">&#40;</span>short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>value <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x80</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> IRQ_NONE<span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* clear the interrupting bit */</span>
	outb<span style="color: #009900;">&#40;</span>value <span style="color: #339933;">&amp;</span> <span style="color: #208080;">0x7F</span><span style="color: #339933;">,</span> short_base<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #808080; font-style: italic;">/* the rest is unchanged */</span>
	do_gettimeofday<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>tv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	written <span style="color: #339933;">=</span> sprintf<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>short_head<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;%08u.%06u<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
		<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>tv.<span style="color: #202020;">tv_sec</span> <span style="color: #339933;">%</span> <span style="color: #0000dd;">100000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>tv.<span style="color: #202020;">tv_usec</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	short_incr_bp<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>short_head<span style="color: #339933;">,</span> written<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wake_up_interruptible<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>short_queue<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
	<span style="color: #808080; font-style: italic;">/* awake any 	reading process */</span>
	<span style="color: #b1b100;">return</span> IRQ_HANDLED<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h3>中断驱动的I/O</h3>
<p>如果与驱动程序管理的硬件之间的数据传输有延迟。驱动程序应该该实现缓冲。<br />
一个输入缓冲区在中断时间内被填充，并由读取该设备的进程取走缓冲区内的数据。<br />
一个输出缓冲区由写入设备的进程填充，在中断时间内被取走。<br />
要正确进行中断驱动的数据传输，则要求设备应该能按照下面的语意来产生中断。</p>
<ul>
<li>对于输入。当新的数据已经到达并且处理器准备好接收它时，设备就中断处理器。</li>
<li>对于输出。当设备准备号接收新的数据或者对成功的数据传送进行应答时产生中断
</li>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/174.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDD读书笔记第九章-与硬件通信</title>
		<link>http://senghoo.com/161.html</link>
		<comments>http://senghoo.com/161.html#comments</comments>
		<pubDate>Mon, 26 Jul 2010 10:35:45 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>
		<category><![CDATA[ldd]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[硬件]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=161</guid>
		<description><![CDATA[I/O端口和I/O内存 i/o寄存器和常规内存 为了防止边界效应的干扰，驱动程序必须确保不使用高速缓存，并且在访问寄存器时不发生读或写指令的从新排序。 高速缓存：把底层硬件配置成在访问IO... ]]></description>
			<content:encoded><![CDATA[<h3>I/O端口和I/O内存</h3>
<h4>i/o寄存器和常规内存</h4>
<p>为了防止边界效应的干扰，驱动程序必须确保不使用高速缓存，并且在访问寄存器时不发生读或写指令的从新排序。<br />
高速缓存：把底层硬件配置成在访问IO区域时禁止硬件缓存。<br />
从新排序：使用内存屏障<br />
<span id="more-161"></span></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code74'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16174"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p161code74"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;linux/kernel.h&gt;</span>
<span style="color: #993333;">void</span> barrier<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*会把cpu中修改过的所有数据保存到内存中，在使用时从新读出来*/</span>
<span style="color: #339933;">#include &lt;asm/system.h&gt;</span>
<span style="color: #993333;">void</span> rmb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*保证读操作不会乱序*/</span>
<span style="color: #993333;">void</span> wmb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*保证写操作不会乱序*/</span>
<span style="color: #993333;">void</span> mb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*保证读写操作不会乱序*/</span>
<span style="color: #993333;">void</span> smp_rmb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #993333;">void</span> smp_wmb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #993333;">void</span> smp_mb<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #808080; font-style: italic;">/*只在针对SMP系统编译时有效，单处理器情况会扩展为上述简单屏障*/</span>
<span style="color: #808080; font-style: italic;">/*赋值并设置屏障宏*/</span>
<span style="color: #339933;">#define set_mb(var, value) do {var = value; mb( );} while 0</span>
<span style="color: #339933;">#define set_wmb(var, value) do {var = value; wmb( );} while 0</span>
<span style="color: #339933;">#define set_rmb(var, value) do {var = value; rmb( );} while 0</span></pre></td></tr></table></div>

<h3>使用IO端口</h3>
<h4>IO端口分配</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code75'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16175"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p161code75"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*注册端口*/</span>
<span style="color: #339933;">#include &lt;linux/ioport.h&gt;</span>
<span style="color: #993333;">struct</span> resource <span style="color: #339933;">*</span>request_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> first<span style="color: #339933;">,</span> 
					<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> n<span style="color: #339933;">,</span>
					<span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*释放端口*/</span>
<span style="color: #993333;">void</span> release_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> start<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*下面的函数用于查询指定的端口号是否可用。所做的操作并非是原子操作。
不能保证分配成功。尽量避免使用*/</span>
<span style="color: #993333;">int</span> check_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> first<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>端口的分配表可在系统中/proc/ioports查询到。</p>
<h4>操作IO端口</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code76'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16176"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p161code76"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;asm/io.h&gt;</span>
<span style="color: #993333;">unsigned</span> inb<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outb<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">char</span> byte<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*字节大小传送*/</span>
<span style="color: #993333;">unsigned</span> inw<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outw<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">short</span> word<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*字大小传送*/</span>
<span style="color: #993333;">unsigned</span> inl<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outl<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> longword<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> port<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*双字大小传送*/</span></pre></td></tr></table></div>

<h4>在用户空间访问IO</h4>
<p>GNU的C库在sys/io.h定义。<br />
条件：</p>
<ul>
<li>编译该程序时必须带-O参数来强制内联函数展开</li>
<li>必须用ioperm或iopl系统调用来获取对端口io操作的权限</li>
<li>必须以root身份运行才能嗲用ioperm或iopl</li>
</ul>
<h4>串操作</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code77'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16177"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p161code77"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> insb<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outsb<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> insw<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outsw<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> insl<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> outsl<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>暂停式IO</h4>
<p>当处理器时钟比外设时钟快时会遇到问题。<br />
暂停式IO在一般IO函数后加_p来实现</p>
<h3>IO端口示列</h3>
<h4>并口简介</h4>
<p>并口由三个8位端口组成。<br />
第一个端口从0&#215;378开始，是双向数据寄存器，链接到2-9号引脚。<br />
第二个端口从0&#215;278开始，是只读状态寄存器。<br />
第三个端口是输出控制寄存器。<br />
并行通信中使用标准TTL电平：0V和5V阀值1.2<br />
并口连接器没有和计算机内部电路隔离，这点在把逻辑门直连到端口时很有用。<br />
但是很容易烧坏端口和主板。<br />
<a href="http://senghoo.com/wp-content/uploads/2010/07/LPT.png"><img src="http://senghoo.com/wp-content/uploads/2010/07/LPT.png" alt="" title="LPT" width="552" height="382" class="alignnone size-full wp-image-168" /></a></p>
<h3>使用IO内存</h3>
<h4>IO内存分配和映射 </h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code78'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16178"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code" id="p161code78"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> resource <span style="color: #339933;">*</span>request_mem_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> start<span style="color: #339933;">,</span> 					<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> len<span style="color: #339933;">,</span>
					<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*从start开始分配lan字节长的内存区域成功返回非null指针*/</span>
<span style="color: #993333;">void</span> release_mem_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> start<span style="color: #339933;">,</span>
				 <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*释放*/</span>
<span style="color: #993333;">int</span> check_mem_region<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> start<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> len<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*由于和check_region一样的原因，不安全。避免使用*/</span>
<span style="color: #339933;">#include &lt;asm/io.h&gt;</span>
<span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ioremap<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> phys_addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ioremap_nocache<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> phys_addr<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> size<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iounmap<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span> addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*书上对ioremap_nocache的解释态绕口看英文
It’s useful if some control registers are in such an area, and write combining or read caching is not desirable.
*/</span></pre></td></tr></table></div>

<p>分配情况可在/proc/iomem查询</p>
<h4>访问IO内存</h4>
<p>ioremap返回值可以直接当指针使用。<br />
但是为了可移植性尽量使用下面函数</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code79'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16179"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code" id="p161code79"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;asm/io.h&gt;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ioread8<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ioread16<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> ioread32<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite8<span style="color: #009900;">&#40;</span>u8 value<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite16<span style="color: #009900;">&#40;</span>u16 value<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite32<span style="color: #009900;">&#40;</span>u32 value<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> ioread8_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> ioread16_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> ioread32_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite8_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite16_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> iowrite32_rep<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> memset_io<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #339933;">,</span> u8 value<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> memcpy_fromio<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dest<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>source<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> memcpy_toio<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>dest<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>source<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/*老的函数*/</span>
<span style="color: #993333;">unsigned</span> readb<span style="color: #009900;">&#40;</span>address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> readw<span style="color: #009900;">&#40;</span>address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">unsigned</span> readl<span style="color: #009900;">&#40;</span>address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> writeb<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> value<span style="color: #339933;">,</span> address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> writew<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> value<span style="color: #339933;">,</span> address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> writel<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> value<span style="color: #339933;">,</span> address<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>像IO内存一样使用端口</h4>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p161code80'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p16180"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p161code80"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>ioport_map<span style="color: #009900;">&#40;</span><span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> port<span style="color: #339933;">,</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">int</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> ioport_unmap<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span>addr<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/161.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>川子-《郑钱花》歌词</title>
		<link>http://senghoo.com/156.html</link>
		<comments>http://senghoo.com/156.html#comments</comments>
		<pubDate>Sun, 25 Jul 2010 12:09:14 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[心情故事]]></category>
		<category><![CDATA[社会]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=156</guid>
		<description><![CDATA[偶然间看到。 反映着这个社会的某些事情。 那歌声，那嗓音。 值得深思。 值得思考。 川子，北京南城土著。他自幼生性刚猛、桀骜不驯，早年因为打架斗殴饱受牢狱之苦。在狱中，川子开始... ]]></description>
			<content:encoded><![CDATA[<p>偶然间看到。<br />
反映着这个社会的某些事情。<br />
那歌声，那嗓音。<br />
值得深思。<br />
值得思考。</p>
<blockquote><p>
川子，北京南城土著。他自幼生性刚猛、桀骜不驯，早年因为打架斗殴饱受牢狱之苦。在狱中，川子开始学习吉他写歌，因为表现出色获得减刑。出狱后，川子的精 神世界发生了彻底的改变，他不再同过去的朋友圈子密切交往，甚至不太喜欢结识新的朋友。他的世界一下子狭小得让人透不过气来，家人还有他的爱犬嘟嘟几乎成 了他生活中的唯一。<br />
<span id="more-156"></span><br />
不久后，在北京南城，川子开了一间音乐主题的酒吧。去过川子酒吧的人都知道，酒吧除了老板歌唱非常好听之外，还有一条可以唱歌的狗，那就是嘟嘟。如今，会唱的嘟嘟越来越红，他的主人川子每晚在自己的酒吧里喝酒唱歌，同嘟嘟一起表演，性格也渐渐开朗起来。</p>
<p>《郑钱花》 歌词</p>
<p>宝贝来到这世界的时候，</p>
<p>你知道爸爸有多高兴吗？</p>
<p>那天我请了我们很多的朋友，</p>
<p>还给你起了这个好听的名字，</p>
<p>从此以后你就叫郑钱花，</p>
<p>钱是挣钱的钱，</p>
<p>花是花钱的花，</p>
<p>你的爸爸我是个穷光蛋啦！</p>
<p>你将来一切全靠自己啦。</p>
<p>宝贝来这世界的时候，</p>
<p>你知道妈妈有多幸福吗？</p>
<p>她为你织了件漂亮的毛衣，</p>
<p>我想你穿在身上肯定很美！</p>
<p>但是我的宝贝，你知道吗？</p>
<p>现在的钱有多么难挣啊！</p>
<p>养一个孩子多么不容易呀！</p>
<p>计划生育还有什么必要吗？</p>
<p>伟大的祖国她超有钱呐！</p>
<p><strong>四万个亿跟我有蛋关系呢？</p>
<p>骄傲的GDP他噌噌的长啊！</p>
<p>能为我换来几包尿不湿吗？</strong></p>
<p>宝贝，你就叫郑钱花，</p>
<p>爸爸我爱你却无能为力呀！</p>
<p>所以以后全靠你自己啦！</p>
<p>爸爸我只有祝福你啦！<br />
<strong><br />
好好的成长，可别生病呀！</p>
<p>努力学习才能省掉赞助费呀！</strong></p>
<p>长大了工作自己挣钱花，<br />
<strong><br />
希望你能过得比我好哇！！</strong>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/156.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python戒律</title>
		<link>http://senghoo.com/152.html</link>
		<comments>http://senghoo.com/152.html#comments</comments>
		<pubDate>Thu, 22 Jul 2010 13:21:09 +0000</pubDate>
		<dc:creator>Senghoo</dc:creator>
				<category><![CDATA[程序设计]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://senghoo.com/?p=152</guid>
		<description><![CDATA[在Python Shell中输入 ?View Code PYTHON1 import this 会出现Python戒律。 全文如下 Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. ... ]]></description>
			<content:encoded><![CDATA[<p>在Python Shell中输入</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p152code82'); return false;">View Code</a> PYTHON</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p15282"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p152code82"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> this</pre></td></tr></table></div>

<p>会出现Python戒律。<br />
全文如下</p>
<blockquote><p>
Beautiful is better than ugly.<br />
Explicit is better than implicit.<br />
Simple is better than complex.<br />
Complex is better than complicated.<br />
Flat is better than nested.<br />
<span id="more-152"></span><br />
Sparse is better than dense.<br />
Readability counts.<br />
Special cases aren&#8217;t special enough to break the rules.<br />
Although practicality beats purity.<br />
Errors should never pass silently.<br />
Unless explicitly silenced.<br />
In the face of ambiguity, refuse the temptation to guess.<br />
There should be one&#8211; and preferably only one &#8211;obvious way to do it.<br />
Although that way may not be obvious at first unless you&#8217;re Dutch.<br />
Now is better than never.<br />
Although never is often better than *right* now.<br />
If the implementation is hard to explain, it&#8217;s a bad idea.<br />
If the implementation is easy to explain, it may be a good idea.<br />
Namespaces are one honking great idea &#8212; let&#8217;s do more of those!
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://senghoo.com/152.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
