﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-luofuchong</title><link>http://www.cnitblog.com/luofuchong/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 28 Aug 2008 05:22:40 GMT</lastBuildDate><pubDate>Thu, 28 Aug 2008 05:22:40 GMT</pubDate><ttl>60</ttl><item><title>转：Linux I2C 驱动分析</title><link>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sat, 23 Aug 2008 03:01:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/48280.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/48280.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/48280.html</trackback:ping><description><![CDATA[最近在看Linux 2.6.21内核的I2C驱动，也在网上查了一下资料，有错也有对，有些心得，记录下来吧。里面认识或许多有不当之处，还恳请指正。
<div>&nbsp;</div>
<div>1. I2C 协议</div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><span></span></span></v:shapetype></span>&nbsp;</div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><v:shapetype coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><span>&nbsp;</span>1.1&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线工作原理</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;"> </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;" lang="EN-US"><o:p></o:p></span></v:shapetype></span></div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总线是由数据线</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">和时钟</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">构成的串行总线，各种被控制器件均并联在这条总线上，每个器件都有一个唯一的地址识别，可以作为总线上的一个发送器件或接收器件</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">(</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">具体由器件的功能决定</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">)</span></div>
<div><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">1.2&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">总线的几种信号状态</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></span></div>
<div>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">空闲状态：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">和</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">都为高电平。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">开始条件</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">(S)</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">为高电平时，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">由高电平向低电平跳变，开始传送数据。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">结束条件</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">(P)</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">：</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">为低电平时，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">由低电平向高电平跳变，结束传送数据。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">数据有效：在</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的高电平期间，</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"> SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">保持稳定，数据有效。</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SDA</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的改变只能发生在</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">的底电平期间。</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;">&nbsp;</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">5.&nbsp; ACK</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">信号</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">: </span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">数据传输的过程中，接收器件每接收一个字节数据要产生一个</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">ACK</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">信号，向发送器件发出特定的低电平脉冲，表示已经收到数据。</font></span></p>
<span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">1.3&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线基本操作</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: Verdana;"> <span lang="EN-US"><o:p></o:p></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><font face="宋体">总线必须由主器件（通常为微控制器）控制，主器件产生串行时钟（</font></span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US">SCL</span><font face="宋体"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;">），同时控制总线的传输方向，并产生开始和停止条件。</span><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%; font-family: verdana;" lang="EN-US"><o:p></o:p></span></font></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">数据传输中，首先主器件产生开始条件，随后是器件的控制字节（前七位是从器件的地址，最后一位为读写位</span><span style="font-size: 9pt; color: #3b3b3b; font-family: Verdana;"> </span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">）。接下来是读写操作的数据，以及</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"> ACK</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">响应信号。数据传输结束时，主器件产生停止条件</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span>&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><strong>2. Linux I2C 结构分析</strong></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">2.1 层次分析</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">1. I2C Core</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">&nbsp;I2C Core<font size="2">用于维护Linux的I2C核心部分，<span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">其中维护了两个静态的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">List</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">，分别记录系统中的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> driver</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">结构和</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adapter</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">结构。</span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span></font></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">static LIST_HEAD(adapters);</span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;">static LIST_HEAD(drivers);</font></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> core</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">提供接口函数，允许一个</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adatper</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">，</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> driver</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">和</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> client</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">初始化时在</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> core</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">中进行注册，以及退出时进行注销。具体可以参见i2c_core.c代码。</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">同时还提供了</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总线读写访问的一般接口（具体的实现在与</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">控制器相关的</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv> adapter</span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">中实现），主要应用在</span><span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">设备驱动中。</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">常用的主要是</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_master_send()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_master_recv()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">i2c_transfer()</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font style="background-color: #c7c7c7;" size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"></span></span></font></span>&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">2. I2C&nbsp;bus driver</span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;">总线驱动的职责，是为系统中每个</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">总线增加相应的读写方法。但是总线驱动本身并不会进行任何的通讯，它只是存在在那里，等待设备驱动调用其函数。</span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"></span></span></span></font></span><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">在系统开机时，首先装载的是</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">总线驱动。一个总线驱动用于支持一条特定的</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">I<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2C</st1:chmetcnv></font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">总线的读写。一个总线驱动通常需要两个模块，一个</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_adapter</font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">和一个</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_algorithm</font></span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: 宋体;">来描述：</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman"> </font></span></span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">在
buses目录下的i2c-pxa.c中实现了PXA的I2C总线适配器，I2C adapter 构造一个对I2C
core层接口的数据结构，并通过接口函数向I2C core注册一个控制器。I2C
adapter主要实现对I2C总线访问的算法，iic_xfer() 函数就是I2C adapter底层对I2C总线读写方法的实现。同时I2C
adpter 中还实现了对I2C控制器中断的处理函数。 <br></font></span></span></span></span></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: 宋体;"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font face="Times New Roman">1) i2c-pxa.c定义了i2c_algorithm，并且实现了master的发送函数i2c_pxa_xfer()，以及设备查询总线的模式的函数i2c_pxa_functionality()</font></span></span></span></span></font></span></p>
</span>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 24pt; line-height: 150%; text-align: left;" align="left"><span style="font-size: 9pt; color: black; line-height: 150%; font-family: ˎ̥;" lang="EN-US"><font size="2"><font face="Times New Roman"><o:p>
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static const struct i2c_algorithm i2c_pxa_algorithm = {<br>&nbsp;.master_xfer&nbsp;= i2c_pxa_xfer,<br>&nbsp;.functionality&nbsp;= i2c_pxa_functionality,<br>};</td>
        </tr>
    </tbody>
</table>
</o:p></font></font></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">2) i2c-pxa.c中，实现了i2c_adapter，主要是在定义pxa-i2c时进行初始化，并且i2c_pxa_probe()中进行填充parent指针，并且调用</font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">ret = i2c_add_adapter(&amp;i2c-&gt;adap);</font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2">进行添加。 </font></span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static struct pxa_i2c i2c_pxa = {<br>&nbsp;.lock&nbsp;= SPIN_LOCK_UNLOCKED,<br>&nbsp;.adap&nbsp;= {<br>&nbsp;&nbsp;.owner&nbsp;&nbsp;= THIS_MODULE,<br>&nbsp;&nbsp;.algo&nbsp;&nbsp;= &amp;i2c_pxa_algorithm,<br>&nbsp;&nbsp;.name&nbsp;&nbsp;= "pxa2xx-i2c.0",<br>&nbsp;&nbsp;.retries&nbsp;= 5,<br>&nbsp;},<br>};</td>
        </tr>
    </tbody>
</table>
</span></span></span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;">总的来说，在i2c-pxa中，使用platform驱动模型，完成了i2c的总线两种模块<span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_adapter</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">和</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_algorithm</font></span></span></font></span></p>
<span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"></span></span></font></span></div>
<span style="font-size: 9pt; color: #3b3b3b; font-family: verdana;" lang="EN-US"><span style="font-size: 9pt; color: #3b3b3b; line-height: 200%;"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><font size="2"><span style="font-size: 9pt; color: #3b3b3b; font-family: 宋体;"><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"></span>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">&nbsp;</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">3. I2C device driver</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">I2C只有总线驱动是不够的，必须有设备才能工作。这就是I2C device driver的必要性。I2C的device是有<span style="font-size: 9pt; color: black; font-family: 宋体;">两个模块来描述的，</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_driver</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">和</span><span style="font-size: 9pt; color: black; font-family: ˎ̥;" lang="EN-US"><font face="宋体, MS Song">struct i<st1:chmetcnv unitname="C" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" w:st="on">2c</st1:chmetcnv>_client</font></span><span style="font-size: 9pt; color: black; font-family: 宋体;">。</span></p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">在介绍chips目录下的device driver前有必要介绍一下i2c-dev.c文件。</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font>i2c-dev.c中提供了一个通用的I2C设备的驱动程序，实现了字符类
型设备的访问接口，对设备的具体访问是通过I2C adapter来实现的。构造一个对I2C core层接口的数据结构，通过接口函数向 I2C
Core注册一个I2C设备驱动。同时构造一个对用户层接口的数据结构，并通过接口函数向内核注册为一个主设备号为89的字符类型设备。</p>
<p>
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>
            <p>static struct i2c_driver i2cdev_driver = {<br>&nbsp;.driver = {<br>&nbsp;&nbsp;.name&nbsp;= "dev_driver",<br>&nbsp;},<br>&nbsp;.id&nbsp;&nbsp;= I2C_DRIVERID_I2CDEV,<br>&nbsp;.attach_adapter&nbsp;= i2cdev_attach_adapter,<br>&nbsp;.detach_adapter&nbsp;= i2cdev_detach_adapter,<br>&nbsp;.detach_client&nbsp;= i2cdev_detach_client,<br>};</p>
            <p>struct i2c_dev {<br>&nbsp;struct list_head list;<br>&nbsp;struct i2c_adapter *adap;<br>&nbsp;struct device *dev;<br>};</p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">该
文件提供了用户层对I2C设备的访问，包括open，read，write，ioctl，release等常规文件操作，我们可以通过open函数打开
I2C的设备文件，通过ioctl函数设定要访问从设备的地址，然后就可以通过 read和write函数完成对I2C设备的读写操作。</p>
<p style="margin: 0cm 0cm 0pt; line-height: 200%; text-align: justify;">
<table style="border: 1px solid #999999; font-size: 12px; width: 80%;" align="center">
    <tbody>
        <tr>
            <td>static const struct file_operations i2cdev_fops = {<br>&nbsp;.owner&nbsp;&nbsp;= THIS_MODULE,<br>&nbsp;.llseek&nbsp;&nbsp;= no_llseek,<br>&nbsp;.read&nbsp;&nbsp;= i2cdev_read,<br>&nbsp;.write&nbsp;&nbsp;= i2cdev_write,<br>&nbsp;.ioctl&nbsp;&nbsp;= i2cdev_ioctl,<br>&nbsp;.open&nbsp;&nbsp;= i2cdev_open,<br>&nbsp;.release&nbsp;= i2cdev_release,<br>};</td>
        </tr>
    </tbody>
</table>
</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注：</font>通过I2C
driver提供的通用方法可以访问任何一个I2C的设备，但是其中实现的read，write及ioctl等功能完全是基于一般设备的实现，所有的操作
数据都是基于字节流，没有明确的格式和意义。为了更方便和有效地使用I2C设备，我们可以为一个具体的I2C设备开发特定的I2C设备驱动程序，在驱动中
完成对特定的数据格式的解释以及实现一些专用的功能。</p>
<p>在chips目录下包含着各种device 的driver，完成各种从设备的注册。作为一般的I2C设备，使用i2c-dev.c里的操作足够完成操作了。</p>
<p>当然如果不能完成，则需要独立完成该驱动，这就是chips目录下的代码。
因为i2c-dev.c已经实现了I2C设备的文件操作接口，所以只要实现struct
i2c_driver就可以了。对于某些特殊的操作，可以使用command接口进行控制。 当然，对于i2接口的fm芯片，则将struct
i2c_driver放在i2c的chips目录下，而将另外fm操作相关的代码放在了/media/radio目录下了。在这个目录下需要完成读写接口
的完成，这个大部分使用V4L2架构。</p>
<p>继续分析中&#8230;&#8230;</p>
</span></font></span></span></span><img src ="http://www.cnitblog.com/luofuchong/aggbug/48280.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-08-23 11:01 <a href="http://www.cnitblog.com/luofuchong/archive/2008/08/23/48280.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一点想法</title><link>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sun, 17 Aug 2008 02:48:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/48081.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/48081.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/48081.html</trackback:ping><description><![CDATA[kernel：linux-2.6.22<br><br>发现linux下字符驱动用的越来越少了，感觉就剩key、led、rtc还在用了(内核下都有现成的~_~)，而且都是因为ioctl的缘故而保留的。<br>记得曾经在一本书上看到介绍说ioctl机制不好，在以后的内核中会被逐渐摒弃之类的。<br>如果真是这样的话，那需要用到字符驱动的机会就越来越少了(个人意见，有误的话欢迎指正^_^)<br><br>ioctl机制虽然不好，可是发现新版本的内核下字符驱动有了新的应用，重新焕发出生气来：<br>象spi、i2c这些总线驱动，都会提供一些api接口函数，供设备驱动程序调用以操作总线。<br>按照这种思路，如果要操作spi、i2c总线的话，有且只能通过驱动来实现。<br>也就是说：需要编写相应的设备驱动程序来实现。<br>然而，一些基于spi、i2c的设备驱动具有相当的共通性，所以内核下提供了这么一个通用的spi、i2c字符设备驱动供用户直接调用以操作总线，达到操作设备的目的。<br><br>   <img src ="http://www.cnitblog.com/luofuchong/aggbug/48081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-08-17 10:48 <a href="http://www.cnitblog.com/luofuchong/archive/2008/08/17/48081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【引】Using the initial RAM disk (initrd)</title><link>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Wed, 28 May 2008 03:40:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/44458.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/44458.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/44458.html</trackback:ping><description><![CDATA[Using the initial RAM disk (initrd)<br>===================================<br><br>Written 1996,2000 by Werner Almesberger &lt;werner.almesberger@epfl.ch&gt; and<br>                     Hans Lermen &lt;lermen@fgan.de&gt;<br><br><br>initrd provides the capability to load a RAM disk by the boot loader.<br>This RAM disk can then be mounted as the root file system and programs<br>can be run from it. Afterwards, a new root file system can be mounted<br>from a different device. The previous root (from initrd) is then moved<br>to a directory and can be subsequently unmounted.<br><br>initrd is mainly designed to allow system startup to occur in two phases,<br>where the kernel comes up with a minimum set of compiled-in drivers, and<br>where additional modules are loaded from initrd.<br><br>This document gives a brief overview of the use of initrd. A more detailed<br>discussion of the boot process can be found in [1].<br><br><br>Operation<br>---------<br><br>When using initrd, the system typically boots as follows:<br><br>  1) the boot loader loads the kernel and the initial RAM disk<br>  2) the kernel converts initrd into a "normal" RAM disk and<br>     frees the memory used by initrd<br>  3) if the root device is not /dev/ram0, the old (deprecated)<br>     change_root procedure is followed. see the "Obsolete root change<br>     mechanism" section below.<br>  4) root device is mounted. if it is /dev/ram0, the initrd image is<br>     then mounted as root<br>  5) /sbin/init is executed (this can be any valid executable, including<br>     shell scripts; it is run with uid 0 and can do basically everything<br>     init can do).<br>  6) init mounts the "real" root file system<br>  7) init places the root file system at the root directory using the<br>     pivot_root system call<br>  8) init execs the /sbin/init on the new root filesystem, performing<br>     the usual boot sequence<br>  9) the initrd file system is removed<br><br>Note that changing the root directory does not involve unmounting it.<br>It is therefore possible to leave processes running on initrd during that<br>procedure. Also note that file systems mounted under initrd continue to<br>be accessible.<br><br><br>Boot command-line options<br>-------------------------<br><br>initrd adds the following new options:<br><br>  initrd=&lt;path&gt;    (e.g. LOADLIN)<br><br>    Loads the specified file as the initial RAM disk. When using LILO, you<br>    have to specify the RAM disk image file in /etc/lilo.conf, using the<br>    INITRD configuration variable.<br><br>  noinitrd<br><br>    initrd data is preserved but it is not converted to a RAM disk and<br>    the "normal" root file system is mounted. initrd data can be read<br>    from /dev/initrd. Note that the data in initrd can have any structure<br>    in this case and doesn't necessarily have to be a file system image.<br>    This option is used mainly for debugging.<br><br>    Note: /dev/initrd is read-only and it can only be used once. As soon<br>    as the last process has closed it, all data is freed and /dev/initrd<br>    can't be opened anymore.<br><br>  root=/dev/ram0<br><br>    initrd is mounted as root, and the normal boot procedure is followed,<br>    with the RAM disk mounted as root.<br><br>Compressed cpio images<br>----------------------<br><br>Recent kernels have support for populating a ramdisk from a compressed cpio<br>archive. On such systems, the creation of a ramdisk image doesn't need to<br>involve special block devices or loopbacks; you merely create a directory on<br>disk with the desired initrd content, cd to that directory, and run (as an<br>example):<br><br>find . | cpio --quiet -H newc -o | gzip -9 -n &gt; /boot/imagefile.img<br><br>Examining the contents of an existing image file is just as simple:<br><br>mkdir /tmp/imagefile<br>cd /tmp/imagefile<br>gzip -cd /boot/imagefile.img | cpio -imd --quiet<br><br>Installation<br>------------<br><br>First, a directory for the initrd file system has to be created on the<br>"normal" root file system, e.g.<br><br># mkdir /initrd<br><br>The name is not relevant. More details can be found on the pivot_root(2)<br>man page.<br><br>If the root file system is created during the boot procedure (i.e. if<br>you're building an install floppy), the root file system creation<br>procedure should create the /initrd directory.<br><br>If initrd will not be mounted in some cases, its content is still<br>accessible if the following device has been created:<br><br># mknod /dev/initrd b 1 250 <br># chmod 400 /dev/initrd<br><br>Second, the kernel has to be compiled with RAM disk support and with<br>support for the initial RAM disk enabled. Also, at least all components<br>needed to execute programs from initrd (e.g. executable format and file<br>system) must be compiled into the kernel.<br><br>Third, you have to create the RAM disk image. This is done by creating a<br>file system on a block device, copying files to it as needed, and then<br>copying the content of the block device to the initrd file. With recent<br>kernels, at least three types of devices are suitable for that:<br><br> - a floppy disk (works everywhere but it's painfully slow)<br> - a RAM disk (fast, but allocates physical memory)<br> - a loopback device (the most elegant solution)<br><br>We'll describe the loopback device method:<br><br> 1) make sure loopback block devices are configured into the kernel<br> 2) create an empty file system of the appropriate size, e.g.<br>    # dd if=/dev/zero of=initrd bs=300k count=1<br>    # mke2fs -F -m0 initrd<br>    (if space is critical, you may want to use the Minix FS instead of Ext2)<br> 3) mount the file system, e.g.<br>    # mount -t ext2 -o loop initrd /mnt<br> 4) create the console device:<br>    # mkdir /mnt/dev<br>    # mknod /mnt/dev/console c 5 1<br> 5) copy all the files that are needed to properly use the initrd<br>    environment. Don't forget the most important file, /sbin/init<br>    Note that /sbin/init's permissions must include "x" (execute).<br> 6) correct operation the initrd environment can frequently be tested<br>    even without rebooting with the command<br>    # chroot /mnt /sbin/init<br>    This is of course limited to initrds that do not interfere with the<br>    general system state (e.g. by reconfiguring network interfaces,<br>    overwriting mounted devices, trying to start already running demons,<br>    etc. Note however that it is usually possible to use pivot_root in<br>    such a chroot'ed initrd environment.)<br> 7) unmount the file system<br>    # umount /mnt<br> 8) the initrd is now in the file "initrd". Optionally, it can now be<br>    compressed<br>    # gzip -9 initrd<br><br>For experimenting with initrd, you may want to take a rescue floppy and<br>only add a symbolic link from /sbin/init to /bin/sh. Alternatively, you<br>can try the experimental newlib environment [2] to create a small<br>initrd.<br><br>Finally, you have to boot the kernel and load initrd. Almost all Linux<br>boot loaders support initrd. Since the boot process is still compatible<br>with an older mechanism, the following boot command line parameters<br>have to be given:<br><br>  root=/dev/ram0 rw<br><br>(rw is only necessary if writing to the initrd file system.)<br><br>With LOADLIN, you simply execute<br><br>     LOADLIN &lt;kernel&gt; initrd=&lt;disk_image&gt;<br>e.g. LOADLIN C:\LINUX\BZIMAGE initrd=C:\LINUX\INITRD.GZ root=/dev/ram0 rw<br><br>With LILO, you add the option INITRD=&lt;path&gt; to either the global section<br>or to the section of the respective kernel in /etc/lilo.conf, and pass<br>the options using APPEND, e.g.<br><br>  image = /bzImage<br>    initrd = /boot/initrd.gz<br>    append = "root=/dev/ram0 rw"<br><br>and run /sbin/lilo<br><br>For other boot loaders, please refer to the respective documentation.<br><br>Now you can boot and enjoy using initrd.<br><br><br>Changing the root device<br>------------------------<br><br>When finished with its duties, init typically changes the root device<br>and proceeds with starting the Linux system on the "real" root device.<br><br>The procedure involves the following steps:<br> - mounting the new root file system<br> - turning it into the root file system<br> - removing all accesses to the old (initrd) root file system<br> - unmounting the initrd file system and de-allocating the RAM disk<br><br>Mounting the new root file system is easy: it just needs to be mounted on<br>a directory under the current root. Example:<br><br># mkdir /new-root<br># mount -o ro /dev/hda1 /new-root<br><br>The root change is accomplished with the pivot_root system call, which<br>is also available via the pivot_root utility (see pivot_root(8) man<br>page; pivot_root is distributed with util-linux version 2.10h or higher<br>[3]). pivot_root moves the current root to a directory under the new<br>root, and puts the new root at its place. The directory for the old root<br>must exist before calling pivot_root. Example:<br><br># cd /new-root<br># mkdir initrd<br># pivot_root . initrd<br><br>Now, the init process may still access the old root via its<br>executable, shared libraries, standard input/output/error, and its<br>current root directory. All these references are dropped by the<br>following command:<br><br># exec chroot . what-follows &lt;dev/console &gt;dev/console 2&gt;&amp;1<br><br>Where what-follows is a program under the new root, e.g. /sbin/init<br>If the new root file system will be used with udev and has no valid<br>/dev directory, udev must be initialized before invoking chroot in order<br>to provide /dev/console.<br><br>Note: implementation details of pivot_root may change with time. In order<br>to ensure compatibility, the following points should be observed:<br><br> - before calling pivot_root, the current directory of the invoking<br>   process should point to the new root directory<br> - use . as the first argument, and the _relative_ path of the directory<br>   for the old root as the second argument<br> - a chroot program must be available under the old and the new root<br> - chroot to the new root afterwards<br> - use relative paths for dev/console in the exec command<br><br>Now, the initrd can be unmounted and the memory allocated by the RAM<br>disk can be freed:<br><br># umount /initrd<br># blockdev --flushbufs /dev/ram0<br><br>It is also possible to use initrd with an NFS-mounted root, see the<br>pivot_root(8) man page for details.<br><br><br>Usage scenarios<br>---------------<br><br>The main motivation for implementing initrd was to allow for modular<br>kernel configuration at system installation. The procedure would work<br>as follows:<br><br>  1) system boots from floppy or other media with a minimal kernel<br>     (e.g. support for RAM disks, initrd, a.out, and the Ext2 FS) and<br>     loads initrd<br>  2) /sbin/init determines what is needed to (1) mount the "real" root FS<br>     (i.e. device type, device drivers, file system) and (2) the<br>     distribution media (e.g. CD-ROM, network, tape, ...). This can be<br>     done by asking the user, by auto-probing, or by using a hybrid<br>     approach.<br>  3) /sbin/init loads the necessary kernel modules<br>  4) /sbin/init creates and populates the root file system (this doesn't<br>     have to be a very usable system yet)<br>  5) /sbin/init invokes pivot_root to change the root file system and<br>     execs - via chroot - a program that continues the installation<br>  6) the boot loader is installed<br>  7) the boot loader is configured to load an initrd with the set of<br>     modules that was used to bring up the system (e.g. /initrd can be<br>     modified, then unmounted, and finally, the image is written from<br>     /dev/ram0 or /dev/rd/0 to a file)<br>  8) now the system is bootable and additional installation tasks can be<br>     performed<br><br>The key role of initrd here is to re-use the configuration data during<br>normal system operation without requiring the use of a bloated "generic"<br>kernel or re-compiling or re-linking the kernel.<br><br>A second scenario is for installations where Linux runs on systems with<br>different hardware configurations in a single administrative domain. In<br>such cases, it is desirable to generate only a small set of kernels<br>(ideally only one) and to keep the system-specific part of configuration<br>information as small as possible. In this case, a common initrd could be<br>generated with all the necessary modules. Then, only /sbin/init or a file<br>read by it would have to be different.<br><br>A third scenario is more convenient recovery disks, because information<br>like the location of the root FS partition doesn't have to be provided at<br>boot time, but the system loaded from initrd can invoke a user-friendly<br>dialog and it can also perform some sanity checks (or even some form of<br>auto-detection).<br><br>Last not least, CD-ROM distributors may use it for better installation<br>from CD, e.g. by using a boot floppy and bootstrapping a bigger RAM disk<br>via initrd from CD; or by booting via a loader like LOADLIN or directly<br>from the CD-ROM, and loading the RAM disk from CD without need of<br>floppies. <br><br><br>Obsolete root change mechanism<br>------------------------------<br><br>The following mechanism was used before the introduction of pivot_root.<br>Current kernels still support it, but you should _not_ rely on its<br>continued availability.<br><br>It works by mounting the "real" root device (i.e. the one set with rdev<br>in the kernel image or with root=... at the boot command line) as the<br>root file system when linuxrc exits. The initrd file system is then<br>unmounted, or, if it is still busy, moved to a directory /initrd, if<br>such a directory exists on the new root file system.<br><br>In order to use this mechanism, you do not have to specify the boot<br>command options root, init, or rw. (If specified, they will affect<br>the real root file system, not the initrd environment.)<br>  <br>If /proc is mounted, the "real" root device can be changed from within<br>linuxrc by writing the number of the new root FS device to the special<br>file /proc/sys/kernel/real-root-dev, e.g.<br><br>  # echo 0x301 &gt;/proc/sys/kernel/real-root-dev<br><br>Note that the mechanism is incompatible with NFS and similar file<br>systems.<br><br>This old, deprecated mechanism is commonly called "change_root", while<br>the new, supported mechanism is called "pivot_root".<br><br><br>Mixed change_root and pivot_root mechanism<br>------------------------------------------<br><br>In case you did not want to use root=/dev/ram0 to trigger the pivot_root<br>mechanism, you may create both /linuxrc and /sbin/init in your initrd image.<br><br>/linuxrc would contain only the following:<br><br>#! /bin/sh<br>mount -n -t proc proc /proc<br>echo 0x0100 &gt;/proc/sys/kernel/real-root-dev<br>umount -n /proc<br><br>Once linuxrc exited, the kernel would mount again your initrd as root,<br>this time executing /sbin/init. Again, it would be the duty of this init<br>to build the right environment (maybe using the root= device passed on<br>the cmdline) before the final execution of the real /sbin/init.<br><br><br>Resources<br>---------<br><br>[1] Almesberger, Werner; "Booting Linux: The History and the Future"<br>    <a href="http://www.almesberger.net/cv/papers/ols2k-9.ps.gz" target="_blank">http://www.almesberger.net/cv/papers/ols2k-9.ps.gz</a><br>[2] newlib package (experimental), with initrd example<br>    <a href="http://sources.redhat.com/newlib/" target="_blank">http://sources.redhat.com/newlib/</a><br>[3] Brouwer, Andries; "util-linux: Miscellaneous utilities for Linux"<br>    <a href="ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/" target="_blank">ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/</a> <img src ="http://www.cnitblog.com/luofuchong/aggbug/44458.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-05-28 11:40 <a href="http://www.cnitblog.com/luofuchong/archive/2008/05/28/44458.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>资料收集</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Sat, 26 Apr 2008 18:12:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42805.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42805.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42805.html</trackback:ping><description><![CDATA[prayaya：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 一个非常有意思的可移动linux发行版，很多地方值得去研究：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <a href="http://www.inlsd.org/">http://www.inlsd.org/</a><br><br>shell十三问：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/Files/luofuchong/shell%E5%8D%81%E4%B8%89%E9%97%AE.rar">http://www.cnitblog.com/Files/luofuchong/shell%E5%8D%81%E4%B8%89%E9%97%AE.rar</a><br><br>shell经典教程：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/Files/luofuchong/shell%E6%95%99%E7%A8%8B.rar">http://www.cnitblog.com/Files/luofuchong/shell%E6%95%99%E7%A8%8B.rar</a>
<br><br>yaffs2源代码情景分析:<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  <a href="http://www.cnitblog.com/luofuchong/articles/43334.html">http://www.cnitblog.com/luofuchong/articles/43334.html</a><br><br>基于Video4Linux的USB摄像头图像采集实现：<a style="color: #020000;" href="http://www.cnitblog.com/Files/luofuchong/%E5%9F%BA%E4%BA%8EVideo4Linux%E7%9A%84USB%E6%91%84%E5%83%8F%E5%A4%B4%E5%9B%BE%E5%83%8F%E9%87%87%E9%9B%86%E5%AE%9E%E7%8E%B0.rar"></a><span style="color: #020000;"></span><br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.cnitblog.com/Files/luofuchong/%E5%9F%BA%E4%BA%8EVideo4Linux%E7%9A%84USB%E6%91%84%E5%83%8F%E5%A4%B4%E5%9B%BE%E5%83%8F%E9%87%87%E9%9B%86%E5%AE%9E%E7%8E%B0.rar">http://www.cnitblog.com/Files/luofuchong/%E5%9F%BA%E4%BA%8EVideo4Linux%E7%9A%84USB%E6%91%84%E5%83%8F%E5%A4%B4%E5%9B%BE%E5%83%8F%E9%87%87%E9%9B%86%E5%AE%9E%E7%8E%B0.rar</a><br><span style="text-decoration: underline;"></span>&nbsp;&nbsp; <br>       <img src ="http://www.cnitblog.com/luofuchong/aggbug/42805.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-27 02:12 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/27/42805.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】ping www.baidu.com 及主机名的方法　</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Thu, 24 Apr 2008 09:01:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42694.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42694.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42694.html</trackback:ping><description><![CDATA[注：<br>&nbsp;&nbsp;&nbsp; 今天发现这东西不好找了，还是转一下吧^_^<br><br><font color="#555555">1：文件系统中/lib有</font>
<p><font color="#555555">[root@hjembed /]# ls lib<br>ld-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libm.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv.so<br>ld-linux.so.2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libm.so.6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv.so.2<br>libc-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns-2.3.2.so &nbsp; &nbsp;librt-2.3.2.so<br>libc.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;librt.so<br>libc.so.6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_dns.so.2 &nbsp; &nbsp; &nbsp; &nbsp;librt.so.1<br>libcrypt-2.3.2.so &nbsp; &nbsp; &nbsp;libnss_files-2.3.2.so &nbsp;libstdc++.so<br>libcrypt.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_files.so &nbsp; &nbsp; &nbsp; &nbsp;libstdc++.so.6<br>libcrypt.so.1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libnss_files.so.2 &nbsp; &nbsp; &nbsp;libstdc++.so.6.0.1<br>libdl-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; libpng.a &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libutil-2.3.2.so<br>libdl.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpng.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libutil.so<br>libdl.so.2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpng.so.3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libutil.so.1<br>libgcc_s.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpng.so.3.1.2.15 &nbsp; &nbsp; libuuid.so.1<br>libgcc_s.so.1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpthread-0.10.so &nbsp; &nbsp; libuuid.so.1.2<br>libjpeg.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; libpthread.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libz.so<br>libjpeg.so.62 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libpthread.so.0 &nbsp; &nbsp; &nbsp; &nbsp;libz.so.1<br>libjpeg.so.62.0.0 &nbsp; &nbsp; &nbsp;libpthread.so_orig &nbsp; &nbsp; libz.so.1.2.3<br>libm-2.3.2.so &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;libresolv-2.3.2.so &nbsp; &nbsp;<br>上面与此相关的是libnss* &nbsp;libresolv*</font></p>
<p><font color="#555555">2: 四个文件<br>[root@hjembed /]# cat /etc/hosts<br>127.0.0.1 &nbsp;localhost<br>59.69.74.87 hujunlinux &nbsp; &nbsp; #为我开发的host 机器</font></p>
<p><font color="#555555"> [root@hjembed /]# cat /etc/resolve.conf<br>nameserver &nbsp;XXXXXX &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#设置DNS服务器 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>[root@hjembed /]# cat /etc/host.conf<br>order hosts,bind</font></p>
<p><font color="#555555">还有一个nsswitch.conf , 我是直接从host machine: FC2 &nbsp;下考出来的</font></p>
<p><font color="#555555">[root@hjembed /]# &nbsp;cat /etc/nsswitch.conf<br>#<br># /etc/nsswitch.conf<br>#<br># An example Name Service Switch config file. This file should be<br># sorted with the most-used services at the beginning.<br>#<br># The entry '[NOTFOUND=return]' means that the search for an<br># entry should stop if the search in the previous entry turned<br># up nothing. Note that if the search failed due to some other reason<br># (like no NIS server responding) then the search continues with the<br># next entry.<br>#<br># Legal entries are:<br>#<br># &nbsp; &nbsp; &nbsp; nisplus or nis+ &nbsp; &nbsp; &nbsp; &nbsp; Use NIS+ (NIS version 3)<br># &nbsp; &nbsp; &nbsp; nis or yp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use NIS (NIS version 2), also called YP<br># &nbsp; &nbsp; &nbsp; dns &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use DNS (Domain Name Service)<br># &nbsp; &nbsp; &nbsp; files &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Use the local files<br># &nbsp; &nbsp; &nbsp; db &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use the local database (.db) files<br># &nbsp; &nbsp; &nbsp; compat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use NIS on compat mode<br># &nbsp; &nbsp; &nbsp; hesiod &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Use Hesiod for user lookups<br># &nbsp; &nbsp; &nbsp; [NOTFOUND=return] &nbsp; &nbsp; &nbsp; Stop searching if not found so far<br>#<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br># To use db, put the "db" in front of "files" for entries you want to be<br># looked up first in the databases<br>#<br># Example:<br>#passwd: &nbsp; &nbsp;db files nisplus nis<br>#shadow: &nbsp; &nbsp;db files nisplus nis<br>#group: &nbsp; &nbsp; db files nisplus nis<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>passwd: &nbsp; &nbsp; files<br>shadow: &nbsp; &nbsp; files<br>group: &nbsp; &nbsp; &nbsp;files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>#hosts: &nbsp; &nbsp; db files nisplus nis dns<br>hosts: &nbsp; &nbsp; &nbsp;files dns<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br># Example - obey only what nisplus tells us...<br>#services: &nbsp; nisplus [NOTFOUND=return] files<br>#networks: &nbsp; nisplus [NOTFOUND=return] files<br>#protocols: &nbsp;nisplus [NOTFOUND=return] files<br>#rpc: &nbsp; &nbsp; &nbsp; &nbsp;nisplus [NOTFOUND=return] files<br>#ethers: &nbsp; &nbsp; nisplus [NOTFOUND=return] files<br>#netmasks: &nbsp; nisplus [NOTFOUND=return] files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>bootparams: nisplus [NOTFOUND=return] files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>ethers: &nbsp; &nbsp; files<br>netmasks: &nbsp; files<br>networks: &nbsp; files<br>protocols: &nbsp;files<br>rpc: &nbsp; &nbsp; &nbsp; &nbsp;files<br>services: &nbsp; files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>netgroup: &nbsp; files<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>publickey: &nbsp;nisplus<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>automount: &nbsp;files<br>aliases: &nbsp; &nbsp;files nisplus<br> &nbsp; <br>3:试验： &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </font></p>
<p><font color="#555555">[root@hjembed /]# ping <a  href="http://www.baidu.com/" target="_blank">www.baidu.com</a><br>PING <a  href="http://www.a.shifen.com/" target="_blank">www.a.shifen.com</a> (211.94.144.100): 56 data bytes<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>--- <a  href="http://www.a.shifen.com/" target="_blank">www.a.shifen.com</a> ping statistics ---<br>3 packets transmitted, 0 packets received, 100% packet loss</font></p>
<p><font color="#555555">[root@hjembed /]# ping hujunlinux &nbsp; &nbsp; &nbsp; （主机名）<br>PING hujunlinux (59.69.74.87): 56 data bytes<br>64 bytes from 59.69.74.87: icmp_seq=0 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=1 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=2 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=3 ttl=64 time=0.5 ms<br>64 bytes from 59.69.74.87: icmp_seq=4 ttl=64 time=0.5 ms<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>--- hujunlinux ping statistics ---<br>5 packets transmitted, 5 packets received, 0% packet loss<br>round-trip min/avg/max = 0.5/0.5/0.5 ms</font></p>
<p><font color="#555555"><br>ok!</font></p>
<br><br><img src ="http://www.cnitblog.com/luofuchong/aggbug/42694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-24 17:01 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/24/42694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：《IT人离开IT还能干什么？》</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Wed, 23 Apr 2008 09:24:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42659.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42659.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42659.html</trackback:ping><description><![CDATA[<div class="content">为什么IT人一定要离开IT呢？ <br>
<br>
今天一位同事（已三十多了），被老板叫到他的办公室去。老总对他说，由于效益不好，公司不再和他续订到期的合同！我看到他很落寞地离去。他前年才结婚，还
供着房子，老婆孩子要养，这一下子就失业了，而且又是快过年的时候！我跑去和他道别，他没有说什么，只让我好好干，公司还是大有前途的。 <br>
<br>
他是一个好人，在技术上决不保密。记得三年前我刚进公司的时候，他正是公司的主力，他对我这个应届毕业生十分关照，只要我不懂的，他一定尽力相告。那时公
司的老板也很器重他，可能是正当壮年的时候（还有很多剥削价值）。但自去年开始，公司转向了。NET平台，我们都去研发新技术了，原有的PB老版本程序基
本上都由一些老程序员来维护（可能老板想他们年龄不小了，学新技术有些障碍）。公司产品的升级工作进展很快，PB版本的程序越来越少了，我们晚上经常加
班，而他由于年龄和家庭的缘故，并不经常加班了。我渐渐地从老板对他的态度的变化——从最早的极为欣赏到一般到渐渐地嫌弃。今年公司的效益不太好，也许正
是到了鸟尽弓藏、兔死狗烹的时候了？
上世纪末那会儿，曾有"做IT，35岁就可以退休"的说法，历经沧海这么多年，35岁退休成了童话，35岁的职业坎儿却无法让众多IT人回避。有人说，可
以转为管理，然而管理的一条线就像窄窄的独木桥，又有多少人可以通过呢（据统计平均大约一百个程序员也就只有一两个做管理的机会）？转向传统行业？已经
30多了，能再重新来过？绝大多数平凡IT人的出路又在哪儿呢？ <br>
<br>
35岁对于IT人是个坎儿，过了这个年纪基本技术生涯即告终结，这是IT界多数人认可的。所以，也让IT人着实为35岁后的自己生了不少忧虑：IT人离开IT后能干什么？ <br>
<br>
印象中的IT人都因为职业的缘故而木讷寡言。他们与机器沟通的能力显然优于与人沟通的能力。从机器到人，IT人必须跨过来。 IT业的技术语言过于狭窄。社会却是复杂的。IT人的知识面不够广泛。社会上不需要人人都懂如何设计程序，但IT人却必须要懂社会。 <br>
<br>
IT内的项目，有些人也有些经验，但这些经验性的东西多数是专业性的，个别种类项目的经验能否转化为普遍的社会经验，也确实需要时间。 <br>
<br>
这些劣势，可以说，凡是地球上的IT人大概都知道。除了IT，要重新换个活法一时还真的玩不转。 但IT人毕竟是IT人。IT是高薪行业，IT人从业几年十几年，一般都有了一定的物质基础。这是IT人比其他行业的人具有的优势。 <br>
<br>
有了这样的物质基础，我认为，后IT人的关键是要实现思维方式的转变：从技术性思维到社会性思维，从而开创人生事业的第二高峰。<br>
技术性思维是面向机器的、僵硬的、封闭的、单向性的；社会性思维要求是面向常识和社会的、灵活的、开放的、多向综合的。后IT的人士最需要的是这种思维方式的转变。 <br>
<br>
思维一转天地宽。后IT人会发现社会比IT里面其实更精彩。
后IT人可以走出来干销售。这个工作富于挑战，而且收入与工作业绩直接挂钩。IT人有很强的技术背景，更擅长发掘产品性能的优缺点，对于IT产品的介绍具
有权威性，容易被客户相信。
后IT人可以走出程序迷宫来做培训。IT人在运用某一技术语言上相当精深，另外他们在技术研发中的实战经验，对于学员来说也是相当宝贵的教学资源。
后IT人也可以由直面数字转为面向众人做咨询。成功的咨询师决不会因为年龄而贬值。有过实际项目经验的IT人，解决实际问题的能力非常强，出身IT的人作
为咨询师是其他行业人士无法取代的。还可以做老板，做IT活动策划等等。 <br>
<br>
需要提醒的是，思维方式的转变不是一朝一夕的事。一旦离开IT，IT人所要做的是不断调整自我，保持对社会的参与激情。阅读一些人际沟通技巧之类的书籍是
必要的，还可以参加社会活动，给自己洗洗脑，从以数字中心、个人中心的思维方式转换到以人为中心、社会为中心的模式中。要注意多与人沟通。同时，个人应该
尽早明确自己的发展方向，并根据新的事业来重新积累，不断升级完善自身的"软硬件"。 </div><img src ="http://www.cnitblog.com/luofuchong/aggbug/42659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-23 17:24 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/23/42659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下用上T23的红外接口</title><link>http://www.cnitblog.com/luofuchong/archive/2008/04/09/42146.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Tue, 08 Apr 2008 17:05:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/04/09/42146.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/42146.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/04/09/42146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/42146.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/42146.html</trackback:ping><description><![CDATA[一  <br>&nbsp;&nbsp;&nbsp; BIOS下红外接口默认关闭,而linux-2.6.17前没有pnp处理,需要进入BIOS下手动开始或对内核打补丁,详细请参考:<br>http://www.thinkwiki.org/wiki/How_to_make_use_of_IrDA<br><br>二 <br>&nbsp;&nbsp;&nbsp; 在我使用的FC4上已经安装了irda-util,版本为0.9.16-7,然而系统自带的irda启动脚本不能正常启动irda接口,参考网上资料,采用以下启动脚本:<br><font size="2">http://www.51nb.com/forum/thread-246611-1-1.html<br><br>#!/bin/sh<br>
#Start up the IrDA process and load necessary modules<br>
#<br>
case "$1" in<br>
&nbsp;&nbsp;start)<br>
&nbsp; &nbsp; #Start IRDA<br>
&nbsp; &nbsp; echo -n "Starting up the IR modules"<br>
<br>
&nbsp; &nbsp; modprobe irda<br>
&nbsp; &nbsp; modprobe ircomm<br>
&nbsp; &nbsp; modprobe ircomm-tty<br>
&nbsp; &nbsp; irattach /dev/ttyS1 -s<br>
&nbsp; &nbsp; <br>
&nbsp; &nbsp; echo "Done."<br>
&nbsp; &nbsp; echo ""<br>
&nbsp; &nbsp; ;;<br>
<br>
&nbsp;&nbsp;stop)<br>
&nbsp; &nbsp; #KILL IRDA<br>
&nbsp; &nbsp; echo -n "Stopping IRDA and removing used modules"<br>
<br>
&nbsp; &nbsp; #Kill the irattach process and remove the modules<br>
&nbsp; &nbsp; killall -9 irattach<br>
&nbsp; &nbsp; rmmod ircomm-tty ircomm irda<br>
<br>
&nbsp; &nbsp; echo "Done."<br>
&nbsp; &nbsp; echo ""<br>
&nbsp; &nbsp; ;;<br>
<br>
&nbsp;&nbsp;*)<br>
&nbsp; &nbsp; echo "Usage:irdastart.sh{start|stop}"<br>
&nbsp; &nbsp; echo ""<br>
&nbsp; &nbsp; exit 1<br>
&nbsp; &nbsp; <br>
&nbsp; &nbsp; esac<br>
&nbsp; &nbsp; exit 0<br></font><font size="2">
保存<br>
chmod 755 myirda<br>
chmod 755 /dev/ircomm0<br>
开启：<br>
./myirda start<br>
关闭：<br>
./myirda stop<br>
<br>
测试：<br>
打开手机红外线，对准接收窗口，./myirda start，运行irdadump命令，应该有数据显示，否则红外设置不成功<br><br>正常情况下可以看到类似以下信息:<br>16:59:12.083873 xid:cmd 9044ea60 &gt; ffffffff S=6 s=* localhost hint=4400 [ Computer LAN Access ] (25)<br>16:59:12.082870 xid:rsp 9044ea60 &lt; 0000277b S=6 s=5 Nokia 6020 hint=b125 [ PnP Modem Fax Telephony IrCOMM IrOBEX ] (27)<br></font><br>三<font size="2"><br>&nbsp;&nbsp;&nbsp; 下载openobex<br><br>./configure --enable-apps<br>make<br>make install<br><br><br>使用:<br></font>
Sending from computer:<br>
<pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px; text-align: left;">irobex_palm3 /path/to/file.xxx</pre>
&nbsp;
<br>Recieving to computer:<br>
<pre class="alt2" dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 640px; height: 34px; text-align: left;">irobex_palm3</pre>
<br><font size="2"><br></font><br> 注:<br>&nbsp;&nbsp;&nbsp; 使用ubuntu的朋友可以参考这个贴子:<br>http://ubuntuforums.org/showpost.php?p=504374&amp;postcount=2<br> <img src ="http://www.cnitblog.com/luofuchong/aggbug/42146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-04-09 01:05 <a href="http://www.cnitblog.com/luofuchong/archive/2008/04/09/42146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>备忘：服务器搭建</title><link>http://www.cnitblog.com/luofuchong/archive/2008/03/07/40636.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Fri, 07 Mar 2008 06:43:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/03/07/40636.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/40636.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/03/07/40636.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/40636.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/40636.html</trackback:ping><description><![CDATA[环境：<br>&nbsp;&nbsp;&nbsp; linux-2.6.22<br>&nbsp;&nbsp;&nbsp; busybox-1.4.2<br>&nbsp;&nbsp;&nbsp; udev-115<br>&nbsp;&nbsp;&nbsp; arm-linux-gcc-3.4.5<br>&nbsp;<br>1、telnet服务器搭建：<br><br>&nbsp;&nbsp; 使用busybox自带的telnetd<br><br>&nbsp;&nbsp;&nbsp; 注意事项：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 需要内核支持devpts文件系统，并挂载到/dev/pts目录下(没有这个目录的话，可以在启动脚本里自行创建)<br><br>&nbsp;&nbsp;&nbsp; 启动：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 执行/usr/sbin/telnetd&amp;即可<br><br>&nbsp;&nbsp;&nbsp; 访问：<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;  在pc下执行telnet xxx.xxx.xxx.xxx，按照提示输入用户、密码即可。<br><br><br>2、ftp服务器搭建:<br><br>&nbsp;&nbsp; 这里有一个非常详细的文档介绍,可以参考一下:<br><br>&nbsp;&nbsp; http://www.vsftpdrocks.org/source/<br><br><br><br>  <img src ="http://www.cnitblog.com/luofuchong/aggbug/40636.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-03-07 14:43 <a href="http://www.cnitblog.com/luofuchong/archive/2008/03/07/40636.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]hlist哈希链表</title><link>http://www.cnitblog.com/luofuchong/archive/2008/01/17/38986.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Thu, 17 Jan 2008 09:32:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/01/17/38986.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/38986.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/01/17/38986.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/38986.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/38986.html</trackback:ping><description><![CDATA[近日研究vfs文件系统，继而研究hlist链表，曾经一度给迷惑，好不容易弄明白。本想写个帖子，可是发现已经有很好的贴可供参考了。自问写不出这么好的帖子，还是转一下好了^_^<br>注：<br>&nbsp;&nbsp;&nbsp; 原文出处：http://blog.chinaunix.net/u/12592/showart.php?id=451619
<br><br>王耀(wangyao@cs.hit.edu.cn)
<p>hlist哈希链表是内核中常用的一个数据结构，由于它不同于普通的链表，所以这里对hlist哈希链表进行一下分析，希望对大家有所帮助。<br>
在include/Linux/list.h中有list链表与hlist哈希链表结构的定义，下面都列出它们的定义，可以对比一下：<br>
<code>struct list_head {<br>
struct list_head *next, *prev;<br>
};</code></p>
<p>struct hlist_head {<br>
struct hlist_node *first;<br>
};</p>
<p>struct hlist_node {<br>
struct hlist_node *next, **pprev;<br>
};</p>
<p>双头（next，prev）的双链表对于Hash表来说&#8220;过于浪费&#8221;，因而另行设计了一套Hash表专用的hlist数据结构——单指针表头双循环
链表，hlist的表头仅有一个指向首节点的指针，而没有指向尾节点的指针，这样在可能是海量的Hash表中存储的表头就能减少一半的空间消耗。<br>
pprev因为hlist不是一个完整的循环链表而不得不使用。在list中，表头和节点是同一个数据结构，直接用prev没问题；在hlist中，表头
没有prev，也没有next，只有一个first。为了能统一地修改表头的first指针，即表头的first指针必须修改指向新插入的节点，
hlist就设计了pprev。hlist节点的pprev不再是指向前一个节点的指针，而是指向前一个节点（可能是表头）中的next（对于表头则是
first）指针（struct list_head
**pprev），从而在表头插入的操作可以通过一致的&#8220;*(node-&gt;pprev)&#8221;访问和修改前节点的next（或first）指针。<br>
注：pprev是指向前一个节点中的next指针，next是指向hlist_node的指针，所以pprev是一个指向hlist_node的指针的指针。<br>
</p>
<div align="center"><img src="http://blogimg.chinaunix.net/blog/upfile2/071227211225.jpg" onload="javascript:if(this.width>500)this.width=500;" border="0" width="500"></div>
<p><br>
注意：<br>
pprev可以理解成向list的prev一样，是一个指向hlist_node的指针，又由于hlist_node的第一个元素next是一个指向
hlist_node的指针，pprev也是一个指向next的指针，即pprev是一个指向hlist_node的指针的指针。<br>
<code>struct hlist_node Prev;<br>
struct hlist_node *pprev = (struct hlist_node *) Prev = (struct
hlist_node *) (struct hlist_node * next) = struct hlist_node ** next;</code></p>
<p>下面是hlist中常用的几个宏：<br>
<code>#define HLIST_HEAD_INIT { .first = NULL }<br>
#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }<br>
#define INIT_HLIST_HEAD(ptr) ((ptr)-&gt;first = NULL)<br>
#define INIT_HLIST_NODE(ptr) ((ptr)-&gt;next = NULL, (ptr)-&gt;pprev = NULL)</code></p>
<p>下面只列出hlist_add_before操作函数，其他hlist链表操作函数操作方法类似。这个函数中的参数next不能为空。它在next前面加入了n节点。函数的实现与list中对应函数类似。<br>
<code>static inline void __hlist_del(struct hlist_node *n)<br>
{<br>
struct hlist_node *next = n-&gt;next;<br>
struct hlist_node **pprev = n-&gt;pprev;<br>
*pprev = next;<br>
if (next)<br>
next-&gt;pprev = pprev;<br>
}</code></p>
<p>static inline void hlist_add_before(struct hlist_node *n,struct hlist_node *next)<br>
{<br>
n-&gt;pprev = next-&gt;pprev;<br>
n-&gt;next = next;<br>
next-&gt;pprev = &amp;n-&gt;next;<br>
*(n-&gt;pprev) = n;<br>
}</p>
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)<br>
#define hlist_for_each(pos, head) \<br>
for (pos = (head)-&gt;first; pos &amp;&amp; ({ prefetch(pos-&gt;next); 1; }); \<br>
pos = pos-&gt;next)   <img src ="http://www.cnitblog.com/luofuchong/aggbug/38986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-01-17 17:32 <a href="http://www.cnitblog.com/luofuchong/archive/2008/01/17/38986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Linux  2.4.30 内核文件系统学习 -- 关键数据结构</title><link>http://www.cnitblog.com/luofuchong/archive/2008/01/09/38652.html</link><dc:creator>lfc</dc:creator><author>lfc</author><pubDate>Wed, 09 Jan 2008 07:49:00 GMT</pubDate><guid>http://www.cnitblog.com/luofuchong/archive/2008/01/09/38652.html</guid><wfw:comment>http://www.cnitblog.com/luofuchong/comments/38652.html</wfw:comment><comments>http://www.cnitblog.com/luofuchong/archive/2008/01/09/38652.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/luofuchong/comments/commentRss/38652.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/luofuchong/services/trackbacks/38652.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 注：&nbsp;&nbsp;&nbsp; 写得实在太好了！&nbsp;&nbsp;&nbsp; 原文出处：http://blog.csdn.net/rstevens/archive/2007/10/14/1824785.aspx1.&nbsp;&nbsp; 概述&nbsp;根据以前学习内核源码的经验，在学习文件系统实现之前，我大概定了个目标：1、&nbsp; 建立一个清晰的...&nbsp;&nbsp;<a href='http://www.cnitblog.com/luofuchong/archive/2008/01/09/38652.html'>阅读全文</a><img src ="http://www.cnitblog.com/luofuchong/aggbug/38652.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/luofuchong/" target="_blank">lfc</a> 2008-01-09 15:49 <a href="http://www.cnitblog.com/luofuchong/archive/2008/01/09/38652.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>