<div id="art" style="margin: 15px;">
<div>
<p style="margin: 0pt;"><span style="">但是由于物理制程</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">制造方面的原因,导致</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nor </span>
</span>
<span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand</span>
</span>
<span style="">在一些具体操作方面的特性不同:</span>
</p>
<table style="border: medium none; width: 608px; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0"><tbody>
<tr style="height: 16.1pt;">
<td style="padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong></strong>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt;" lang="EN-US">NOR </span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt;" lang="EN-US">NAND </span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><strong><span style="">(备注)</span>
</strong>
<strong></strong>
</p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">接口</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">总线</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">I/O</span>
</span>
<span style="">接口</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">这个两者最大的区别</span>
</p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">cell</span>
</span>
</strong>
<strong><span style="">大小</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">大</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">小</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 15.45pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 15.45pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Cell</span>
</span>
</strong>
<strong><span style="">成本</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 15.45pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">高</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">低</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">读耗时</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单字节的编程时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 15.45pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 15.45pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">多字节的编程时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 15.45pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">擦除时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">功耗</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">高</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">低,但是需要额外的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">RAM</span>
</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 63.7pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 63.7pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">是否可以执行代码</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 63.7pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">是</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 63.7pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">不行</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">, </span>
</span>
<span style="">但是一些新的芯片,可以在第一页之外执行一些小的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">loader</span>
</span>
<span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 63.7pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">即是否允许,芯片内执行</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(XIP, eXecute In Place) (2)</span>
</span>
</p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">位反转</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(Bit twiddling/bit flip)</span>
</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">几乎无限制</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">1-4</span>
</span>
<span style="">次,也称作</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">“部分页编程限制”</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">也就是数据错误,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">0->1</span>
</span>
<span style="">或</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1->0</span>
</span>
</p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">在芯片出厂时候是否允许坏块</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">不允许</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">允许</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
</tbody></table>
<p style="margin: 0pt; text-align: center;" align="center"><strong><span style="">表</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">3 Nand Flash </span>
</span>
</strong>
<strong><span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> Nor Flash</span>
</span>
</strong>
<strong><span style="">的区别</span>
</strong>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">理论上是可以的,而且也是有人验证过可以的,只不过由于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的物理特性,不能完全保证所读取的数据</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">代码是正确的,实际上,很少这么用而已。因为,如果真是要用到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">XIP</span>
</span>
<span style="">,那么除了读出速度慢之外,还要保证有数据的校验,以保证读出来的,将要执行的代码</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">数据,是正确的。否则,系统很容易就跑飞了。。。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<strong><span lang="EN-US"><a href="http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html"><span style="color: #0072ae;"><span style="" lang="EN-US"><span lang="EN-US">芯片内执行</span>
</span>
<span style="font-family: Times New Roman;">(XIP, eXecute In Place)</span>
</span>
</a>
</span>
</strong>
<span lang="EN-US"><span style="font-family: Times New Roman;">:</span>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html"><span style="font-family: Times New Roman; color: #0072ae;">http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html</span>
</a>
</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">的种类】</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">具体再分,又可以分为</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">1)Bare NAND chips</span>
</span>
<span style="">:裸片,单独的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
<span style="">芯片</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">2)SmartMediaCards</span>
</span>
<span style="">:</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> =</span>
</span>
<span style="">裸片</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">一层薄塑料,常用于数码相机和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MP3</span>
</span>
<span style="">播放器中。之所以称</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">,是由于其软件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">,而不是硬件本身有啥</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">之处。</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">^_^</span>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">3)DiskOnChip</span>
</span>
<span style="">:裸片</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+glue logic</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">glue logic=</span>
</span>
<span style="">硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">产生器</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">用于静态的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
<span style="">芯片控制的寄存器</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">直接访问一小片地址窗口,那块地址中包含了引导代码的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">stub</span>
</span>
<span style="">桩,其可以从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">中拷贝真正的引导代码。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">spare area/oob</span>
</span>
</strong>
<strong><span style="">】</span>
</strong>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">Nand</span>
</span>
<span style="">由于最初硬件设计时候考虑到,额外的错误校验等需要空间,专门对应每个页,额外设计了叫做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">spare area</span>
</span>
<span style="">空区域,在其他地方,比如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">jffs2</span>
</span>
<span style="">文件系统中,也叫做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">out of band</span>
</span>
<span style="">)数据。</span>
</p>
<p style="margin: 0pt;"><span style="">其具体用途,总结起来有:</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">标记是否是坏快</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">存储</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数据</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">3.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">存储一些和文件系统相关的数据,如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">jffs2</span>
</span>
<span style="">就会用到这些空间存储一些特定信息,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">yaffs2</span>
</span>
<span style="">文件系统,会在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">中,存放很多和自己文件系统相关的信息。</span>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">软件方面</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">如果想要在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下编写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">驱动,那么就先要搞清楚</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下,关于此部分的整个框架。弄明白,系统是如何管理你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的,以及,系统都帮你做了那些准备工作,而剩下的,驱动底层实现部分,你要去实现哪些功能,才能使得硬件正常工作起来。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="">【内存技术设备,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
</strong>
<strong><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Memory Technology Device</span>
</span>
</strong>
<strong><span style="">)】</span>
</strong>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">的存储设备中的一个子系统。其设计此系统的目的是,对于内存类的设备,提供一个抽象层,一个接口,使得对于硬件驱动设计者来说,可以尽量少的去关心存储格式,比如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FTL</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FFS2</span>
</span>
<span style="">等,而只需要去提供最简单的底层硬件设备的读</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">擦除函数就可以了。而对于数据对于上层使用者来说是如何表示的,硬件驱动设计者可以不关心,而</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">存储设备子系统都帮你做好了。</span>
</p>
<p style="margin: 0pt;"><span style="">对于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">字系统的好处,简单解释就是,他帮助你实现了,很多对于以前或者其他系统来说,本来也是你驱动设计者要去实现的很多功能。换句话说,有了</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,使得你设计</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的驱动,所要做的事情,要少很多很多,因为大部分工作,都由</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">帮你做好了。</span>
</p>
<p style="margin: 0pt;"><span style="">当然,这个好处的一个“副作用”就是,使得我们不了解的人去理解整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">驱动架构,以及</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,变得更加复杂。但是,总的说,觉得是利远远大于弊,否则,就不仅需要你理解,而且还是做更多的工作,实现更多的功能了。</span>
</p>
<p style="margin: 0pt;"><span style="">此外,还有一个重要的原因,那就是,前面提到的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">和普通硬盘等设备的特殊性:</span>
</p>
<p style="margin: 0pt;"><span style="">有限的通过出复用来实现输入输出命令和地址</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">数据等的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">IO</span>
</span>
<span style="">接口,最小单位是页而不是常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">bit</span>
</span>
<span style="">,写前需擦除等,导致了这类设备,不能像平常对待硬盘等操作一样去操作,只能采取一些特殊方法,这就诞生了</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">设备的统一抽象层。</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,将</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nor flash</span>
</span>
<span style="">和其他类型的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">flash</span>
</span>
<span style="">等设备,统一抽象成</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">设备来管理,根据这些设备的特点,上层实现了常见的操作函数封装,底层具体的内部实现,就需要驱动设计者自己来实现了。具体的内部硬件设备的读</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">擦除函数,那就是你必须实现的了。</span>
</p>
<table style="border: medium none; width: 568px; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td style="padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt; color: blue;" lang="EN-US">HARD drives</span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt; color: blue;" lang="EN-US">MTD device</span>
</strong>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">连续的扇区</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">连续的可擦除块</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">扇区都很小</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(512B,1024B)</span>
</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">可擦除块比较大</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> (32KB,128KB)</span>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">主要通过两个操作对其维护操作:读扇区,写扇区</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">主要通过三个操作对其维护操作:从擦除块中读,写入擦除块,<strong>擦写可擦除块</strong>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">坏快被重新映射,并且被硬件隐藏起来了(至少是在如今常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">LBA</span>
</span>
<span style="">硬盘设备中是如此)</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">坏的可擦除块没有被隐藏,软件中要处理对应的坏块问题。</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">HDD</span>
</span>
<span style="">扇区没有擦写寿命超出的问题。</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">可擦除块是有擦除次数限制的,大概是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">10<sup>4</sup>
-10<sup>5</sup></span>
</span>
<span style="">次</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">.</span>
</span>
</p>
</td>
</tr>
</tbody></table>
<p style="margin: 0pt; text-align: center;" align="center"><strong><span style="">表</span>
</strong>
<strong><span lang="EN-US"><span style="font-family: Times New Roman;">4.MTD</span>
</span>
</strong>
<strong><span style="">设备和硬盘设备之间的区别</span>
</strong>
<strong></strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">多说一句,关于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">更多的内容,感兴趣的,去附录中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">的主页去看。</span>
</p>
<p style="margin: 0pt;"><span style="">关于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">mtd</span>
</span>
<span style="">设备驱动,感兴趣的可以去参考</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://www.cnitblog.com/luofuchong/archive/2007/08/31/32682.html"><span style="color: #0072ae;"><strong><span style="font-family: Times New Roman;">MTD</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">原始设备与</span>
</span>
<span style="font-family: Times New Roman;">FLASH</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">硬件驱动的对话</span>
</span>
</strong>
</span>
</a>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://www.cnitblog.com/luofuchong/archive/2007/09/04/32939.html"><span style="color: #0072ae;"><strong><span style="font-family: Times New Roman;">MTD</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">原始设备与</span>
</span>
<span style="font-family: Times New Roman;">FLASH</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">硬件驱动的对话</span>
</span>
<span style="font-family: Times New Roman;">-</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">续</span>
</span>
</strong>
</span>
</a>
</span>
</p>
<p style="margin: 0pt;"><span style="">那里,算是比较详细地介绍了整个流程,方便大家理解整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">mtd</span>
</span>
<span style="">框架和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand flash</span>
</span>
</strong>
<strong><span style="">驱动工作原理】</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">在介绍具体如何写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动之前,我们先要了解,大概的,整个系统,和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">相关的部分的驱动工作流程,这样,对于后面的驱动实现,才能更加清楚机制,才更容易实现,否则就是,即使写完了代码,也还是没搞懂系统是如何工作的了。</span>
</p>
<p style="margin: 0pt;"><span style="">让我们以最常见的,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">内核中已经有的三星的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动,来解释</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动具体流程和原理。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">此处是参考</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2.6.29</span>
</span>
<span style="">版本的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">源码中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/drivers/mtd/nand/s3c2410.c</span>
</span>
<span style="">,以</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2410</span>
</span>
<span style="">为例。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动加载后,第一步,就是去调用对应的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">init</span>
</span>
<span style="">函数,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_init,</span>
</span>
<span style="">去将在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动注册到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">驱动框架中。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">驱动本身,真正开始,是从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">函数,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_probe->s3c24xx_nand_probe,</span>
</span>
</p>
<p style="margin: 0pt;"><span style="">在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">过程中,去用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">clk_enable</span>
</span>
<span style="">打开</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">控制器的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">clock</span>
</span>
<span style="">时钟,用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">request_mem_region</span>
</span>
<span style="">去申请驱动所需要的一些内存等相关资源。然后,在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_inithw</span>
</span>
<span style="">中,去初始化硬件相关的部分,主要是关于时钟频率的计算,以及启用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">控制器,使得硬件初始化好了,后面才能正常工作。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">3.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">需要多解释一下的,是这部分代码:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
for (setno = 0; setno < nr_sets; setno++, nmtd++) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
pr_debug("initialising set %d (%p, info %p)/n", setno, nmtd, info);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* </span>
</span>
</strong>
<strong><span style="">调用</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">init chip</span>
</span>
</strong>
<strong><span style="">去挂载你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
</strong>
<strong><span style="">驱动的底层函数到</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的结构体中,以及设置对应的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc mode</span>
</span>
</strong>
<strong><span style="">,挂载</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">相关的函数</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
s3c2410_nand_init_chip(info, nmtd, sets);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* scan_ident</span>
</span>
</strong>
<strong><span style="">,扫描</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
</strong>
<strong><span style="">设备,设置</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的默认函数,获得物理设备的具体型号以及对应各个特性参数,这部分算出来的一些值,对于</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">来说,是最主要的参数,比如</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand falsh</span>
</span>
</strong>
<strong><span style="">的芯片的大小,块大小,页大小等。</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->scan_res = nand_scan_ident(&nmtd->mtd,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span></span>
(sets) ? sets->nr_chips : 1);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (nmtd->scan_res == 0) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
s3c2410_nand_update_chip(info, nmtd);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* scan tail</span>
</span>
</strong>
<strong><span style="">,从名字就可以看出来,是扫描的后一阶段,此时,经过前面的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">scan_ident</span>
</span>
</strong>
<strong><span style="">,我们已经获得对应</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的硬件的各个参数,然后就可以在</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">scan tail</span>
</span>
</strong>
<strong><span style="">中,根据这些参数,去设置其他一些重要参数,尤其是</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">layout</span>
</span>
</strong>
<strong><span style="">,即</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">是如何在</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
</strong>
<strong><span style="">中摆放的,最后,再去进行一些初始化操作,主要是根据你的驱动,如果没有实现一些函数的话,那么就用系统默认的。</span>
<span style="color: blue;"><span style="font-family: Times New Roman;"> <span lang="EN-US">*/</span>
</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nand_scan_tail(&nmtd->mtd);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* add partion</span>
</span>
</strong>
<strong><span style="">,根据你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的分区设置,去分区</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
s3c2410_nand_add_partition(info, nmtd, sets);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (sets != NULL)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
sets++;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">4.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">等所有的参数都计算好了,函数都挂载完毕,系统就可以正常工作了。</span>
</p>
<p style="margin: 0pt;"><span style="">上层访问你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand falsh</span>
</span>
<span style="">中的数据的时候,通过</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">层,一层层调用,最后调用到你所实现的那些底层访问硬件数据</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">缓存的函数中。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
</strong>
<strong><span style="font-size: 14pt;" lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下</span>
</strong>
<strong><span style="font-size: 14pt;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">驱动编写步骤简介】</span>
</strong>
<strong></strong>
</p>
<p style="margin: 0pt;"><span style="">关于上面提到的,在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand_scan_tail</span>
</span>
<span style="">的时候,系统会根据你的驱动,如果没有实现一些函数的话,那么就用系统默认的。如果实现了自己的函数,就用你的。</span>
</p>
<p style="margin: 0pt;"><span style="">估计很多人就会问了,那么到底我要实现哪些函数呢,而又有哪些是可以不实现,用系统默认的就可以了呢。</span>
</p>
<p style="margin: 0pt;"><span style="">此问题的,就是我们下面要介绍的,也就是,你要实现的,你的驱动最少要做哪些工作,才能使整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">工作起来。</span>
</p>
<p style="margin: 0pt;"></p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">对于驱动框架部分</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">其实,要了解,关于驱动框架部分,你所要做的事情的话,只要看看三星的整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动中的这个结构体,就差不多了:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">static struct platform_driver s3c2410_nand_driver = {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.probe<span> </span>
= s3c2410_nand_probe,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.remove<span> </span>
= s3c2410_nand_remove,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.suspend<span> </span>
= s3c24xx_nand_suspend,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.resume<span> </span>
= s3c24xx_nand_resume,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.driver<span> </span>
= {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.name<span> </span>
= "s3c2410-nand",</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.owner<span> </span>
= THIS_MODULE,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
},</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">};</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">对于上面这个结构体,没多少要解释的。从名字,就能看出来:</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">就是系统“探测”,就是前面解释的整个过程,这个过程中的多数步骤,都是和你自己的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">相关的,尤其是那些硬件初始化部分,是你必须要自己实现的。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">remove</span>
</span>
<span style="">,就是和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">对应的,“反初始化”相关的动作。主要是释放系统相关资源和关闭硬件的时钟等常见操作了。</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">(3)suspend</span>
</span>
<span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">resume</span>
</span>
<span style="">,对于很多没用到电源管理的情况下,至少对于我们刚开始写基本的驱动的时候,可以不用关心,放个空函数即可。</span>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">对于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">底层操作实现部分</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">而对于底层硬件操作的有些函数,总体上说,都可以在上面提到的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_init_chip</span>
</span>
<span style="">中找到:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
struct s3c2410_nand_mtd *nmtd,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
struct s3c2410_nand_set *set)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">{</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
struct nand_chip *chip = &nmtd->chip;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
void __iomem *regs = info->regs;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->write_buf<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_write_buf</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->read_buf<span> </span>
=</span>
<span style="color: red;" lang="EN-US"> s3c2410_nand_read_buf</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->select_chip<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_select_chip</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->chip_delay<span> </span>
= 50;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->priv<span> </span>
<span> </span>
= nmtd;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->options<span> </span>
<span> </span>
= 0;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->controller<span> </span>
= &info->controller;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
switch (info->cpu_type) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
case TYPE_S3C2410:</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* nand flash</span>
</span>
</strong>
<strong><span style="">控制器中,一般都有对应的数据寄存器,用于给你往里面写数据,表示将要读取或写入多少个字节</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">(byte,u8)/</span>
</span>
</strong>
<strong><span style="">字</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">(word,u32) </span>
</span>
</strong>
<strong><span style="">,所以,此处,你要给出地址,以便后面的操作所使用</span>
<span style="color: blue;"><span style="font-family: Times New Roman;"> <span lang="EN-US">*/</span>
</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->IO_ADDR_W = regs + S3C2410_NFDATA;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
info->sel_reg<span> </span>
= regs + S3C2410_NFCONF;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
info->sel_bit<span> </span>
= S3C2410_NFCONF_nFCE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->cmd_ctrl<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_hwcontrol</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->dev_ready =</span>
<span style="color: blue;" lang="EN-US"> </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_devready</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
break;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">。。。。。。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->IO_ADDR_R = chip->IO_ADDR_W;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->info<span> </span>
<span> </span>
= info;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->mtd.priv<span> </span>
<span> </span>
= chip;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->mtd.owner<span> </span>
= THIS_MODULE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->set<span> </span>
<span> </span>
= set;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (hardware_ecc) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.calculate = </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_calculate_ecc</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.correct<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_correct_data</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* </span>
</span>
</strong>
<strong><span style="">此处,多数情况下,你所用的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">的控制器,都是支持硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的,所以,此处设置硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC(HW_ECC) </span>
</span>
</strong>
<strong><span style="">,也是充分利用硬件的特性,而如果此处不用硬件去做的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的话,那么下面也会去设置成</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">NAND_ECC_SOFT</span>
</span>
</strong>
<strong><span style="">,系统会用默认的软件去做</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">校验,相比之下,比硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的效率就低很多,而你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的读写,也会相应地要慢不少</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">*/</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
<span> </span>
= NAND_ECC_HW;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
switch (info->cpu_type) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
case TYPE_S3C2410:</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.hwctl<span> </span>
<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_enable_hwecc</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.calculate = s3c2410_nand_calculate_ecc;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
break;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">。。。。。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
} else {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
<span> </span>
= NAND_ECC_SOFT;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (set->ecc_layout != NULL)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.layout = set->ecc_layout;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (set->disable_ecc)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
= NAND_ECC_NONE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">而我们要实现的底层函数,也就是上面蓝色标出来的一些函数而已:</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_write_buf </span>
</span>
<span style="">和</span>
<span style="font-family: Times New Roman;"> <span lang="EN-US">s3c2410_nand_read_buf</span>
</span>
<span style="">:这是两个最基本的操作函数,其功能,就是往你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的控制器中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">读写数据。一般情况下,是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">上层的操作,比如要读取一页的数据,那么在发送完相关的读命令和等待时间之后,就会调用到你底层的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">read_buf</span>
</span>
<span style="">,去</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand Flash</span>
</span>
<span style="">的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">中,一点点把我们要的数据,读取出来,放到我们制定的内存的缓存中去。写操作也是类似,将我们内存中的数据,写到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">中去。具体的数据流向,参考上面的图</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">4</span>
</span>
<span style="">。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_select_chip </span>
</span>
<span style="">:</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">实现</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的片选。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">3</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_hwcontrol</span>
</span>
<span style="">:给底层发送命令或地址,或者设置具体操作的模式,都是通过此函数。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">4</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_devready</span>
</span>
<span style="">:</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的
一些操作,比如读一页数据,写入(编程)一页数据,擦除一个块,都是需要一定时间的,在命发送完成后,就是硬件开始忙着工作的时候了,而硬件什么时候完成
这些操作,什么时候不忙了,变就绪了,就是通过这个函数去检查状态的。一般具体实现都是去读硬件的一个状态寄存器,其中某一位是否是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">,对应着是出于“就绪</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">不忙”还是“忙”的状态。这个寄存器,也就是我们前面分析时序图中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">R/B#</span>
</span>
<span style="">。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">5</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_enable_hwecc</span>
</span>
<span style="">:</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">在硬件支持的前提下,前面设置了硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">的话,要实现这个函数,用于每次在读写操作前,通过设置对应的硬件寄存器的某些位,使得启用硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">,这样在读写操作完成后,就可以去读取硬件校验产生出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数值了。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">6</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_calculate_ecc</span>
</span>
<span style="">:如果是上面提到的硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">的话,就不用我们用软件去实现校验算法了,而是直接去读取硬件产生的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数值就可以了。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">7</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_correct_data</span>
</span>
<span style="">:当实际操作过程中,读取出来的数据所对应的硬件或软件计算出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">,和从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">中读出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">不一样的时候,就是说明数据有误了,就需要调用此函数去纠正错误。对于现在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">SLC</span>
</span>
<span style="">常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">算法来说,可以发现</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">位,纠正</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位。如果错误大于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位,那么就无法纠正回来了。一般情况下,出错超过</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位的,好像几率不大。至少我看到的不是很大。更复杂的情况和更加注重数据安全的情况下,一般是需要另外实现更高效和检错和纠错能力更强的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">算法的。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">当然,除了这些你必须实现的函数之外,在你更加熟悉整个框架之后,你可以根据你自己的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的特点,去实现其他一些原先用系统默认但是效率不高的函数,而用自己的更高效率的函数替代他们,以提升你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的整体性能和效率。</span>
</p>
</div>
</div>
<div>
<p style="margin: 0pt;"><span style="">但是由于物理制程</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">制造方面的原因,导致</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nor </span>
</span>
<span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand</span>
</span>
<span style="">在一些具体操作方面的特性不同:</span>
</p>
<table style="border: medium none; width: 608px; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0"><tbody>
<tr style="height: 16.1pt;">
<td style="padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong></strong>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt;" lang="EN-US">NOR </span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt;" lang="EN-US">NAND </span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><strong><span style="">(备注)</span>
</strong>
<strong></strong>
</p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">接口</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">总线</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">I/O</span>
</span>
<span style="">接口</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">这个两者最大的区别</span>
</p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">cell</span>
</span>
</strong>
<strong><span style="">大小</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">大</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">小</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 15.45pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 15.45pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Cell</span>
</span>
</strong>
<strong><span style="">成本</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 15.45pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">高</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">低</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">读耗时</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">单字节的编程时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 15.45pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 15.45pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">多字节的编程时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 15.45pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 15.45pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 16.1pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 16.1pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">擦除时间</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 16.1pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">慢</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">快</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 16.1pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">功耗</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">高</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">低,但是需要额外的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">RAM</span>
</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
<tr style="height: 63.7pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 63.7pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">是否可以执行代码</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 63.7pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">是</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 63.7pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">不行</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">, </span>
</span>
<span style="">但是一些新的芯片,可以在第一页之外执行一些小的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">loader</span>
</span>
<span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 63.7pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">即是否允许,芯片内执行</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(XIP, eXecute In Place) (2)</span>
</span>
</p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">位反转</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(Bit twiddling/bit flip)</span>
</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">几乎无限制</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">1-4</span>
</span>
<span style="">次,也称作</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">“部分页编程限制”</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"><span style="">也就是数据错误,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">0->1</span>
</span>
<span style="">或</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1->0</span>
</span>
</p>
</td>
</tr>
<tr style="height: 32.15pt;">
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 158.4pt; height: 32.15pt; background-color: transparent;" width="211">
<p style="margin: 0pt;"><strong><span style="">在芯片出厂时候是否允许坏块</span>
</strong>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 69.5pt; height: 32.15pt; background-color: transparent;" width="93">
<p style="margin: 0pt;"><span style="">不允许</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152">
<p style="margin: 0pt;"><span style="">允许</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 114pt; height: 32.15pt; background-color: transparent;" width="152" valign="top">
<p style="margin: 0pt;"></p>
</td>
</tr>
</tbody></table>
<p style="margin: 0pt; text-align: center;" align="center"><strong><span style="">表</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">3 Nand Flash </span>
</span>
</strong>
<strong><span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> Nor Flash</span>
</span>
</strong>
<strong><span style="">的区别</span>
</strong>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">理论上是可以的,而且也是有人验证过可以的,只不过由于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的物理特性,不能完全保证所读取的数据</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">代码是正确的,实际上,很少这么用而已。因为,如果真是要用到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">XIP</span>
</span>
<span style="">,那么除了读出速度慢之外,还要保证有数据的校验,以保证读出来的,将要执行的代码</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">数据,是正确的。否则,系统很容易就跑飞了。。。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<strong><span lang="EN-US"><a href="http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html"><span style="color: #0072ae;"><span style="" lang="EN-US"><span lang="EN-US">芯片内执行</span>
</span>
<span style="font-family: Times New Roman;">(XIP, eXecute In Place)</span>
</span>
</a>
</span>
</strong>
<span lang="EN-US"><span style="font-family: Times New Roman;">:</span>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html"><span style="font-family: Times New Roman; color: #0072ae;">http://hi.baidu.com/serial_story/blog/item/adb20a2a3f8ffe3c5243c1df.html</span>
</a>
</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">的种类】</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">具体再分,又可以分为</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">1)Bare NAND chips</span>
</span>
<span style="">:裸片,单独的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
<span style="">芯片</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">2)SmartMediaCards</span>
</span>
<span style="">:</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> =</span>
</span>
<span style="">裸片</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">一层薄塑料,常用于数码相机和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MP3</span>
</span>
<span style="">播放器中。之所以称</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">,是由于其软件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">,而不是硬件本身有啥</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">smart</span>
</span>
<span style="">之处。</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">^_^</span>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">3)DiskOnChip</span>
</span>
<span style="">:裸片</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+glue logic</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">glue logic=</span>
</span>
<span style="">硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">产生器</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">用于静态的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
<span style="">芯片控制的寄存器</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">+</span>
</span>
<span style="">直接访问一小片地址窗口,那块地址中包含了引导代码的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">stub</span>
</span>
<span style="">桩,其可以从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">中拷贝真正的引导代码。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">spare area/oob</span>
</span>
</strong>
<strong><span style="">】</span>
</strong>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">Nand</span>
</span>
<span style="">由于最初硬件设计时候考虑到,额外的错误校验等需要空间,专门对应每个页,额外设计了叫做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">spare area</span>
</span>
<span style="">空区域,在其他地方,比如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">jffs2</span>
</span>
<span style="">文件系统中,也叫做</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">out of band</span>
</span>
<span style="">)数据。</span>
</p>
<p style="margin: 0pt;"><span style="">其具体用途,总结起来有:</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">标记是否是坏快</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">存储</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数据</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">3.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">存储一些和文件系统相关的数据,如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">jffs2</span>
</span>
<span style="">就会用到这些空间存储一些特定信息,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">yaffs2</span>
</span>
<span style="">文件系统,会在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">中,存放很多和自己文件系统相关的信息。</span>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">软件方面</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">如果想要在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下编写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">驱动,那么就先要搞清楚</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下,关于此部分的整个框架。弄明白,系统是如何管理你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的,以及,系统都帮你做了那些准备工作,而剩下的,驱动底层实现部分,你要去实现哪些功能,才能使得硬件正常工作起来。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="">【内存技术设备,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
</strong>
<strong><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Memory Technology Device</span>
</span>
</strong>
<strong><span style="">)】</span>
</strong>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">的存储设备中的一个子系统。其设计此系统的目的是,对于内存类的设备,提供一个抽象层,一个接口,使得对于硬件驱动设计者来说,可以尽量少的去关心存储格式,比如</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FTL</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FFS2</span>
</span>
<span style="">等,而只需要去提供最简单的底层硬件设备的读</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">擦除函数就可以了。而对于数据对于上层使用者来说是如何表示的,硬件驱动设计者可以不关心,而</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">存储设备子系统都帮你做好了。</span>
</p>
<p style="margin: 0pt;"><span style="">对于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">字系统的好处,简单解释就是,他帮助你实现了,很多对于以前或者其他系统来说,本来也是你驱动设计者要去实现的很多功能。换句话说,有了</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,使得你设计</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的驱动,所要做的事情,要少很多很多,因为大部分工作,都由</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">帮你做好了。</span>
</p>
<p style="margin: 0pt;"><span style="">当然,这个好处的一个“副作用”就是,使得我们不了解的人去理解整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">驱动架构,以及</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,变得更加复杂。但是,总的说,觉得是利远远大于弊,否则,就不仅需要你理解,而且还是做更多的工作,实现更多的功能了。</span>
</p>
<p style="margin: 0pt;"><span style="">此外,还有一个重要的原因,那就是,前面提到的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">和普通硬盘等设备的特殊性:</span>
</p>
<p style="margin: 0pt;"><span style="">有限的通过出复用来实现输入输出命令和地址</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">数据等的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">IO</span>
</span>
<span style="">接口,最小单位是页而不是常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">bit</span>
</span>
<span style="">,写前需擦除等,导致了这类设备,不能像平常对待硬盘等操作一样去操作,只能采取一些特殊方法,这就诞生了</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">设备的统一抽象层。</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">,将</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nor flash</span>
</span>
<span style="">和其他类型的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">flash</span>
</span>
<span style="">等设备,统一抽象成</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">设备来管理,根据这些设备的特点,上层实现了常见的操作函数封装,底层具体的内部实现,就需要驱动设计者自己来实现了。具体的内部硬件设备的读</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">擦除函数,那就是你必须实现的了。</span>
</p>
<table style="border: medium none; width: 568px; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0"><tbody>
<tr>
<td style="padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt; color: blue;" lang="EN-US">HARD drives</span>
</strong>
</span>
</p>
</td>
<td style="border-color: windowtext windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="font-family: Times New Roman;"><strong><span style="font-size: 12pt; color: blue;" lang="EN-US">MTD device</span>
</strong>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">连续的扇区</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">连续的可擦除块</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">扇区都很小</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">(512B,1024B)</span>
</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">可擦除块比较大</span>
<span lang="EN-US"><span style="font-family: Times New Roman;"> (32KB,128KB)</span>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">主要通过两个操作对其维护操作:读扇区,写扇区</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">主要通过三个操作对其维护操作:从擦除块中读,写入擦除块,<strong>擦写可擦除块</strong>
</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">坏快被重新映射,并且被硬件隐藏起来了(至少是在如今常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">LBA</span>
</span>
<span style="">硬盘设备中是如此)</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">坏的可擦除块没有被隐藏,软件中要处理对应的坏块问题。</span>
</p>
</td>
</tr>
<tr>
<td style="border-color: #ffffff windowtext windowtext; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">HDD</span>
</span>
<span style="">扇区没有擦写寿命超出的问题。</span>
</p>
</td>
<td style="border-color: #ffffff windowtext windowtext #ffffff; padding: 0pt 5.4pt; width: 213.05pt; background-color: transparent;" width="284">
<p style="margin: 0pt;"><span style="">可擦除块是有擦除次数限制的,大概是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">10<sup>4</sup>
-10<sup>5</sup></span>
</span>
<span style="">次</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">.</span>
</span>
</p>
</td>
</tr>
</tbody></table>
<p style="margin: 0pt; text-align: center;" align="center"><strong><span style="">表</span>
</strong>
<strong><span lang="EN-US"><span style="font-family: Times New Roman;">4.MTD</span>
</span>
</strong>
<strong><span style="">设备和硬盘设备之间的区别</span>
</strong>
<strong></strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">多说一句,关于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">更多的内容,感兴趣的,去附录中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">的主页去看。</span>
</p>
<p style="margin: 0pt;"><span style="">关于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">mtd</span>
</span>
<span style="">设备驱动,感兴趣的可以去参考</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://www.cnitblog.com/luofuchong/archive/2007/08/31/32682.html"><span style="color: #0072ae;"><strong><span style="font-family: Times New Roman;">MTD</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">原始设备与</span>
</span>
<span style="font-family: Times New Roman;">FLASH</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">硬件驱动的对话</span>
</span>
</strong>
</span>
</a>
</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><a href="http://www.cnitblog.com/luofuchong/archive/2007/09/04/32939.html"><span style="color: #0072ae;"><strong><span style="font-family: Times New Roman;">MTD</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">原始设备与</span>
</span>
<span style="font-family: Times New Roman;">FLASH</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">硬件驱动的对话</span>
</span>
<span style="font-family: Times New Roman;">-</span>
</strong>
<strong><span style="" lang="EN-US"><span lang="EN-US">续</span>
</span>
</strong>
</span>
</a>
</span>
</p>
<p style="margin: 0pt;"><span style="">那里,算是比较详细地介绍了整个流程,方便大家理解整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">mtd</span>
</span>
<span style="">框架和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand flash</span>
</span>
</strong>
<strong><span style="">驱动工作原理】</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">在介绍具体如何写</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动之前,我们先要了解,大概的,整个系统,和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">相关的部分的驱动工作流程,这样,对于后面的驱动实现,才能更加清楚机制,才更容易实现,否则就是,即使写完了代码,也还是没搞懂系统是如何工作的了。</span>
</p>
<p style="margin: 0pt;"><span style="">让我们以最常见的,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">内核中已经有的三星的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动,来解释</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">驱动具体流程和原理。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">此处是参考</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2.6.29</span>
</span>
<span style="">版本的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">源码中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/drivers/mtd/nand/s3c2410.c</span>
</span>
<span style="">,以</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2410</span>
</span>
<span style="">为例。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动加载后,第一步,就是去调用对应的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">init</span>
</span>
<span style="">函数,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_init,</span>
</span>
<span style="">去将在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动注册到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
<span style="">驱动框架中。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">驱动本身,真正开始,是从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">函数,</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_probe->s3c24xx_nand_probe,</span>
</span>
</p>
<p style="margin: 0pt;"><span style="">在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">过程中,去用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">clk_enable</span>
</span>
<span style="">打开</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">控制器的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">clock</span>
</span>
<span style="">时钟,用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">request_mem_region</span>
</span>
<span style="">去申请驱动所需要的一些内存等相关资源。然后,在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_inithw</span>
</span>
<span style="">中,去初始化硬件相关的部分,主要是关于时钟频率的计算,以及启用</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">控制器,使得硬件初始化好了,后面才能正常工作。</span>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">3.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">需要多解释一下的,是这部分代码:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
for (setno = 0; setno < nr_sets; setno++, nmtd++) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
pr_debug("initialising set %d (%p, info %p)/n", setno, nmtd, info);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* </span>
</span>
</strong>
<strong><span style="">调用</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">init chip</span>
</span>
</strong>
<strong><span style="">去挂载你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
</strong>
<strong><span style="">驱动的底层函数到</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的结构体中,以及设置对应的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc mode</span>
</span>
</strong>
<strong><span style="">,挂载</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">相关的函数</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
s3c2410_nand_init_chip(info, nmtd, sets);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* scan_ident</span>
</span>
</strong>
<strong><span style="">,扫描</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand </span>
</span>
</strong>
<strong><span style="">设备,设置</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的默认函数,获得物理设备的具体型号以及对应各个特性参数,这部分算出来的一些值,对于</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">来说,是最主要的参数,比如</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand falsh</span>
</span>
</strong>
<strong><span style="">的芯片的大小,块大小,页大小等。</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->scan_res = nand_scan_ident(&nmtd->mtd,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span></span>
(sets) ? sets->nr_chips : 1);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (nmtd->scan_res == 0) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
s3c2410_nand_update_chip(info, nmtd);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* scan tail</span>
</span>
</strong>
<strong><span style="">,从名字就可以看出来,是扫描的后一阶段,此时,经过前面的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">scan_ident</span>
</span>
</strong>
<strong><span style="">,我们已经获得对应</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的硬件的各个参数,然后就可以在</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">scan tail</span>
</span>
</strong>
<strong><span style="">中,根据这些参数,去设置其他一些重要参数,尤其是</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">layout</span>
</span>
</strong>
<strong><span style="">,即</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ecc</span>
</span>
</strong>
<strong><span style="">是如何在</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
</strong>
<strong><span style="">中摆放的,最后,再去进行一些初始化操作,主要是根据你的驱动,如果没有实现一些函数的话,那么就用系统默认的。</span>
<span style="color: blue;"><span style="font-family: Times New Roman;"> <span lang="EN-US">*/</span>
</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nand_scan_tail(&nmtd->mtd);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* add partion</span>
</span>
</strong>
<strong><span style="">,根据你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的分区设置,去分区</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;"> */</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
s3c2410_nand_add_partition(info, nmtd, sets);</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (sets != NULL)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
sets++;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style=""><span lang="EN-US"><span><span style="font-family: Times New Roman;">4.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
<span style="">等所有的参数都计算好了,函数都挂载完毕,系统就可以正常工作了。</span>
</p>
<p style="margin: 0pt;"><span style="">上层访问你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand falsh</span>
</span>
<span style="">中的数据的时候,通过</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">层,一层层调用,最后调用到你所实现的那些底层访问硬件数据</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">缓存的函数中。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><strong><span style="">【</span>
</strong>
<strong><span style="font-size: 14pt;" lang="EN-US"><span style="font-family: Times New Roman;">Linux</span>
</span>
</strong>
<strong><span style="">下</span>
</strong>
<strong><span style="font-size: 14pt;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">驱动编写步骤简介】</span>
</strong>
<strong></strong>
</p>
<p style="margin: 0pt;"><span style="">关于上面提到的,在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand_scan_tail</span>
</span>
<span style="">的时候,系统会根据你的驱动,如果没有实现一些函数的话,那么就用系统默认的。如果实现了自己的函数,就用你的。</span>
</p>
<p style="margin: 0pt;"><span style="">估计很多人就会问了,那么到底我要实现哪些函数呢,而又有哪些是可以不实现,用系统默认的就可以了呢。</span>
</p>
<p style="margin: 0pt;"><span style="">此问题的,就是我们下面要介绍的,也就是,你要实现的,你的驱动最少要做哪些工作,才能使整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">工作起来。</span>
</p>
<p style="margin: 0pt;"></p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">1.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">对于驱动框架部分</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">其实,要了解,关于驱动框架部分,你所要做的事情的话,只要看看三星的整个</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">驱动中的这个结构体,就差不多了:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">static struct platform_driver s3c2410_nand_driver = {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.probe<span> </span>
= s3c2410_nand_probe,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.remove<span> </span>
= s3c2410_nand_remove,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.suspend<span> </span>
= s3c24xx_nand_suspend,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.resume<span> </span>
= s3c24xx_nand_resume,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.driver<span> </span>
= {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.name<span> </span>
= "s3c2410-nand",</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
.owner<span> </span>
= THIS_MODULE,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
},</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">};</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">对于上面这个结构体,没多少要解释的。从名字,就能看出来:</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">就是系统“探测”,就是前面解释的整个过程,这个过程中的多数步骤,都是和你自己的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">相关的,尤其是那些硬件初始化部分,是你必须要自己实现的。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">remove</span>
</span>
<span style="">,就是和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">probe</span>
</span>
<span style="">对应的,“反初始化”相关的动作。主要是释放系统相关资源和关闭硬件的时钟等常见操作了。</span>
</p>
<p style="margin: 0pt;"><span lang="EN-US"><span style="font-family: Times New Roman;">(3)suspend</span>
</span>
<span style="">和</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">resume</span>
</span>
<span style="">,对于很多没用到电源管理的情况下,至少对于我们刚开始写基本的驱动的时候,可以不用关心,放个空函数即可。</span>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style=""><strong><span lang="EN-US"><span><span style="font-family: Times New Roman;">2.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal;"> </span>
</span>
</span>
</span>
</strong>
<strong><span style="">对于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">底层操作实现部分</span>
</strong>
</p>
<p style="margin: 0pt;"><span style="">而对于底层硬件操作的有些函数,总体上说,都可以在上面提到的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_init_chip</span>
</span>
<span style="">中找到:</span>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
struct s3c2410_nand_mtd *nmtd,</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
struct s3c2410_nand_set *set)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">{</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
struct nand_chip *chip = &nmtd->chip;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
void __iomem *regs = info->regs;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->write_buf<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_write_buf</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->read_buf<span> </span>
=</span>
<span style="color: red;" lang="EN-US"> s3c2410_nand_read_buf</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->select_chip<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_select_chip</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->chip_delay<span> </span>
= 50;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->priv<span> </span>
<span> </span>
= nmtd;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->options<span> </span>
<span> </span>
= 0;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->controller<span> </span>
= &info->controller;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
switch (info->cpu_type) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
case TYPE_S3C2410:</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* nand flash</span>
</span>
</strong>
<strong><span style="">控制器中,一般都有对应的数据寄存器,用于给你往里面写数据,表示将要读取或写入多少个字节</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">(byte,u8)/</span>
</span>
</strong>
<strong><span style="">字</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">(word,u32) </span>
</span>
</strong>
<strong><span style="">,所以,此处,你要给出地址,以便后面的操作所使用</span>
<span style="color: blue;"><span style="font-family: Times New Roman;"> <span lang="EN-US">*/</span>
</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->IO_ADDR_W = regs + S3C2410_NFDATA;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
info->sel_reg<span> </span>
= regs + S3C2410_NFCONF;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
info->sel_bit<span> </span>
= S3C2410_NFCONF_nFCE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->cmd_ctrl<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_hwcontrol</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->dev_ready =</span>
<span style="color: blue;" lang="EN-US"> </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_devready</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
break;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">。。。。。。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
<span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->IO_ADDR_R = chip->IO_ADDR_W;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->info<span> </span>
<span> </span>
= info;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->mtd.priv<span> </span>
<span> </span>
= chip;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->mtd.owner<span> </span>
= THIS_MODULE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
nmtd->set<span> </span>
<span> </span>
= set;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (hardware_ecc) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.calculate = </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_calculate_ecc</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.correct<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_correct_data</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">/* </span>
</span>
</strong>
<strong><span style="">此处,多数情况下,你所用的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
</strong>
<strong><span style="">的控制器,都是支持硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的,所以,此处设置硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC(HW_ECC) </span>
</span>
</strong>
<strong><span style="">,也是充分利用硬件的特性,而如果此处不用硬件去做的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的话,那么下面也会去设置成</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">NAND_ECC_SOFT</span>
</span>
</strong>
<strong><span style="">,系统会用默认的软件去做</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">校验,相比之下,比硬件</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
</strong>
<strong><span style="">的效率就低很多,而你的</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
</strong>
<strong><span style="">的读写,也会相应地要慢不少</span>
<span style="color: blue;" lang="EN-US"><span style="font-family: Times New Roman;">*/</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
<span> </span>
= NAND_ECC_HW;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
switch (info->cpu_type) {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
case TYPE_S3C2410:</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="font-family: Times New Roman;"><span style="color: green;" lang="EN-US"><span> </span>
chip->ecc.hwctl<span> </span>
<span> </span>
= </span>
<span style="color: red;" lang="EN-US">s3c2410_nand_enable_hwecc</span>
<span style="color: green;" lang="EN-US">;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.calculate = s3c2410_nand_calculate_ecc;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
break;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="">。。。。。</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
} else {</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
<span> </span>
= NAND_ECC_SOFT;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (set->ecc_layout != NULL)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.layout = set->ecc_layout;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong></strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
if (set->disable_ecc)</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;"><span> </span>
chip->ecc.mode<span> </span>
= NAND_ECC_NONE;</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"><strong><span style="color: green;" lang="EN-US"><span style="font-family: Times New Roman;">}</span>
</span>
</strong>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">而我们要实现的底层函数,也就是上面蓝色标出来的一些函数而已:</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_write_buf </span>
</span>
<span style="">和</span>
<span style="font-family: Times New Roman;"> <span lang="EN-US">s3c2410_nand_read_buf</span>
</span>
<span style="">:这是两个最基本的操作函数,其功能,就是往你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的控制器中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">读写数据。一般情况下,是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">MTD</span>
</span>
<span style="">上层的操作,比如要读取一页的数据,那么在发送完相关的读命令和等待时间之后,就会调用到你底层的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">read_buf</span>
</span>
<span style="">,去</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand Flash</span>
</span>
<span style="">的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">中,一点点把我们要的数据,读取出来,放到我们制定的内存的缓存中去。写操作也是类似,将我们内存中的数据,写到</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">FIFO</span>
</span>
<span style="">中去。具体的数据流向,参考上面的图</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">4</span>
</span>
<span style="">。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_select_chip </span>
</span>
<span style="">:</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">实现</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的片选。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">3</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_hwcontrol</span>
</span>
<span style="">:给底层发送命令或地址,或者设置具体操作的模式,都是通过此函数。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">4</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_devready</span>
</span>
<span style="">:</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">Nand Flash</span>
</span>
<span style="">的
一些操作,比如读一页数据,写入(编程)一页数据,擦除一个块,都是需要一定时间的,在命发送完成后,就是硬件开始忙着工作的时候了,而硬件什么时候完成
这些操作,什么时候不忙了,变就绪了,就是通过这个函数去检查状态的。一般具体实现都是去读硬件的一个状态寄存器,其中某一位是否是</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">,对应着是出于“就绪</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">/</span>
</span>
<span style="">不忙”还是“忙”的状态。这个寄存器,也就是我们前面分析时序图中的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">R/B#</span>
</span>
<span style="">。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">5</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_enable_hwecc</span>
</span>
<span style="">:</span>
<span style="font-family: Times New Roman;"> </span>
<span style="">在硬件支持的前提下,前面设置了硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">的话,要实现这个函数,用于每次在读写操作前,通过设置对应的硬件寄存器的某些位,使得启用硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">,这样在读写操作完成后,就可以去读取硬件校验产生出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数值了。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">6</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_calculate_ecc</span>
</span>
<span style="">:如果是上面提到的硬件</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">的话,就不用我们用软件去实现校验算法了,而是直接去读取硬件产生的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">数值就可以了。</span>
</p>
<p style="margin: 0pt;"><span style="">(</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">7</span>
</span>
<span style="">)</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">s3c2410_nand_correct_data</span>
</span>
<span style="">:当实际操作过程中,读取出来的数据所对应的硬件或软件计算出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">,和从</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">oob</span>
</span>
<span style="">中读出来的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">不一样的时候,就是说明数据有误了,就需要调用此函数去纠正错误。对于现在</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">SLC</span>
</span>
<span style="">常见的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">算法来说,可以发现</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">2</span>
</span>
<span style="">位,纠正</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位。如果错误大于</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位,那么就无法纠正回来了。一般情况下,出错超过</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">1</span>
</span>
<span style="">位的,好像几率不大。至少我看到的不是很大。更复杂的情况和更加注重数据安全的情况下,一般是需要另外实现更高效和检错和纠错能力更强的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">ECC</span>
</span>
<span style="">算法的。</span>
</p>
<p style="margin: 0pt;"></p>
<p style="margin: 0pt;"><span style="">当然,除了这些你必须实现的函数之外,在你更加熟悉整个框架之后,你可以根据你自己的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的特点,去实现其他一些原先用系统默认但是效率不高的函数,而用自己的更高效率的函数替代他们,以提升你的</span>
<span lang="EN-US"><span style="font-family: Times New Roman;">nand flash</span>
</span>
<span style="">的整体性能和效率。</span>
</p>
</div>
</div>