- 浏览: 1818611 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
yeying12:
强大
HTTP协议详解,你所不知道的 -
夏雪纷纷:
据我所知,9月12日有个对于DXperience 2013新功 ...
DXperience 9.1.3 -
Emy:
现在面临第一个坎。。
IT高薪者所具备的人格魅力 -
yangxiutian:
很详细,楼主很会总结。
IE下 z-index 的各种坑 -
idleone:
真心求指教,全选怎么实现
Android开发之ListView,加入CheckBox(复选框),实现选择列表
嵌入式Linux之我行——S3C2440上Flash驱动实例开发讲解
<div>
<span style="">嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</span>
</div>
<ul>
<li>
<span style="">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong><span style="">一、Linux中Flash硬件知识</span>
</strong>
</p>
<ol>
<li>
<span style="font-size: x-small;">Flash用途和分类:<br><br>
在嵌入式系统开发设计中,存储模块是不可缺少的重要部分,而
Flash是目前市场上主要的非易失闪存技术,他主要分为:Nor Flash和Nand Flash两种。那么他们有什么区别呢?简单的讲:Nor
Flash容量小,价格高,写速度慢但随机读速度快,所以较适合存储少量的程序代码,比如u-boot启动代码;而Nand
Flash则容量大,价格低,写速度快但读速度慢,所以他相当于PC上的硬盘用于存储大量的数据。Nor Flash与Nand
Flash更详细区别如下表:<br><img src="http://blog.chinaunix.net/photo/101649_100629103038.png" alt=""><br></span>
</li>
<li>
<span style="font-size: x-small;">Flash在硬件设计中的应用:<br><br>
以Mini2440开发板为例:该开发板上带有一块2M的Nor Flash和一块64M的Nand Flash。下面先看看他们是怎样被应用于嵌入式Linux的。Nor Flash和Nand Flash电路原理图分别如下:(由mini2440提供)<br><img src="http://blog.chinaunix.net/photo/101649_100629104856.png" alt=""><br><br>
从
原理图上可以看到,Nor Flash内部提供的是有类似于DRam之类的地址总线,可以直接与CPU相连,CPU可以直接通过地址总线对Nor
Flash进行访问;而Nand Flash没有这类的总线,其内部只提供IO接口,因此只能通过IO接口发送命令和地址,对Nand
Flash内部数据进行访问。这可以说是二者最大的区别了,也说明了二者读写速度不同的所在。因此,各有各的优点,Nor Flash访问快,Nand
Flash简化了电路。注意:电路原理图中字母上面有一横杠的表示该引脚是低电平有效,没有的是默认的高电平。</span>
</li>
</ol>
<div>
<strong><span style="">二、Linux中Flash软件知识</span>
</strong>
</div>
<ol>
<li>
<span style="">Linux MTD子系统:<br><br>
在Linux系统中,提供了MTD(内存技术设备)子系统来建立Flash针对Linux的统一、抽象的接口。MTD子系统将上层文件系统与底层
Flash硬件进行了隔离,使Flash驱动开发者无需再关心Flash作为字符设备或者块设备与Linux内核的接口。MTD将Linux系统
Flash设备驱动及接口分成了4个层次,如图所示,从上往下分别为:设备节点、MTD设备层、MTD原始设备层和Flash硬件驱动层。<br><img src="http://blog.chinaunix.net/photo/101649_100629160140.png" alt=""><br><br><strong>设备节点:</strong>
用户在/dev目录下使用mknod命令建立MTD字符设备节点(主设备号为90),或者MTD块设备节点(主设备号为31),使用该设备节点即可访问MTD设备。<br><br><strong>MTD设备层:</strong>
基于MTD原始设备层,系统将MTD设备可以定义为MTD字符设备(在/mtd/mtdchar.c中实现)和MTD块设备(在/mtd/mtdblock.c中实现)。<br><br><strong>MTD原始设备层:</strong>
MTD原始设备层由两个部分组成,分别是MTD原始设备的通用代码和各个特定的Flash的数据,如分区信息。<br><br><strong>Flash硬件驱动层:</strong>
Flash硬件驱动层负责对Flash硬件的读、写和擦除操作。MTD设备的Nor Flash芯片驱动一般位于drivers/mtd/chips/子目录下,Nand Flash芯片的驱动则位于drivers/mtd/nand/子目录下。<br><br>
综
合上述我们可知,MTD子系统已经对Flash设备对于上层的应用进行了封装,我们在写硬件驱动的时候直接调用MTD原始设备层提供的接口函数做相应的操
作即可。那么,对于MTD设备层,MTD原始设备层提供了哪些接口呢?对于Flash硬件驱动层,MTD原始设备层又提供了哪些接口呢?下面开始了解。<br><br></span>
</li>
<li>
<span style="font-size: x-small;">MTD子系统接口:<br><br>
在MTD子系统中,MTD设备层、MTD原始设备层和Flash硬件驱动层之间的接口关系如下图所示:<br><img src="http://blog.chinaunix.net/photo/101649_100701145306.png" alt=""><br>
从上图可知,MTD设备层是通过原始设备层提供的接口来注册MTD字符设备或MTD块设备的,同样,驱动工程师要编写的Flash硬件驱动也是通过原始设备层提供的接口来添加MTD设备和MTD分区的,分别如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9933;">//使用这两个接口函数进行添加和删除MTD设备</span>
<br><span style="color: #0000ff;">int</span>
add_mtd_device<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
del_mtd_device<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"></span>
</span>
</code>
</p>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9933;">//使用这两个接口函数进行添加和删除MTD分区</span>
<br><span style="color: #0000ff;">int</span>
add_mtd_partitions<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*<span style="color: #000000;">master</span>
, struct <span style="color: #000000;">mtd_partition</span>
*<span style="color: #000000;">parts</span>
, int <span style="color: #000000;">nbparts</span>
</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
del_mtd_partitions<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*<span style="color: #000000;">master</span>
</span>
<span style="color: #0000cc;">)</span>
</span>
</span>
</code>
</p>
</span>
</span>
</span>
</code>
</td>
</tr></tbody></table>
<br><br>
在
MTD中,一个MTD原始设备用mtd_info结构体来表示,定义在include/linux/mtd/mtd.h中;一个MTD原始设备分区用
mtd_part结构体来表示,定义在drivers/mtd/mtdpart.c中。其中每个分区也被认为是一个mtd_info,比如:有一个MTD
原始设备,上面有3个分区,那么将共有3个mtd_info,而这3个mtd_info的指针将被存放在mtd_table的数组中进行管理,定义在
drivers/mtd/mtdcore.h中,如下所示:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">extern</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd_table<span style="color: #0000cc;">[</span>
MAX_MTD_DEVICES<span style="color: #0000cc;">]</span>
<span style="color: #0000cc;">;<span style="color: #ff9933;">//最多有MAX_MTD_DEVICES(默认定义为32)个设备</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><br></span>
</li>
<li>
<span style="font-size: x-small;">MTD子系统中重要的一些数据结构:<br><table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">struct</span>
mtd_info <br><span style="color: #0000cc;">{</span>
<br><span style="color: #ff9900;">//硬件设备的类型,如:MTD_RAM,MTD_ROM,MTD_NORFlash,MTD_NANDFlash,MTD_PEROM等</span>
<br>
u_char type<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//设备支持的选项,如:MTD_ERASEABLE(可擦除),MTD_WRITEB_WRITEALBE(可编程),</span>
<br><span style="color: #ff9900;">//MTD_XIP(可片内执行),MTD_OOB(NAND额外数据),MTD_ECC(支持自动ECC)等</span>
<br><span style="color: #ff0000;">uint32_t</span>
flags<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff0000;">uint64_t</span>
size<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//MTD设备的大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
erasesize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//主要的擦除块大小(注意:同一个MTD设备可能有几种不同的erasesize)</span>
<br><span style="color: #ff0000;">uint32_t</span>
writesize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//编程块大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
oobsize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//OOB数据大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
oobavail<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
erasesize_shift<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
writesize_shift<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
erasesize_mask<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
writesize_mask<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">const</span>
<span style="color: #0000ff;">char</span>
<span style="color: #0000cc;">*</span>
name<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
index<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">struct</span>
nand_ecclayout <span style="color: #0000cc;">*</span>
ecclayout<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//ECC布局结构</span>
<br><br><span style="color: #0000ff;">int</span>
numeraseregions<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//擦除区域的个数,通常为1</span>
<br><span style="color: #0000ff;">struct</span>
mtd_erase_region_info <span style="color: #0000cc;">*</span>
eraseregions<span style="color: #0000cc;">;</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//擦除区域的指针<br></span>
<br><span style="color: #ff9900;">//此方法将一个erase_info结构放入擦除队列中</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
erase<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
erase_info <span style="color: #0000cc;">*</span>
instr<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//point和unpoint方法分别用于允许和禁止芯片内执行(eXecute-In-Place,简称XIP),如果unpoint为NULL,则表示禁止XIP</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
point<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">*</span>
virt<span style="color: #0000cc;">,</span>
resource_size_t <span style="color: #0000cc;">*</span>
phys<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
unpoint<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//如果不为NULL,则表示允许无MMU单元的虚拟地址映射</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_unmapped_area<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
offset<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
flags<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">struct</span>
backing_dev_info <span style="color: #0000cc;">*</span>
backing_dev_info<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//read和write分别用于MTD设备的读和写</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
<span style="color: #ff0000;">read</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
<span style="color: #ff0000;">write</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
panic_write<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//read_oob和write_oob分别用于读写MTD设备的OOB数据</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_oob<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
mtd_oob_ops <span style="color: #0000cc;">*</span>
ops<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
write_oob<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
mtd_oob_ops <span style="color: #0000cc;">*</span>
ops<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//一下几个方法是用于实现访问一些受保护的寄存器(一般这只是出现在某些特定的Flash设备上)</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_fact_prot_info<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
otp_info <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_fact_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_user_prot_info<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
otp_info <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
write_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
lock_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//基于kvec的形式写</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
writev<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
<span style="color: #0000ff;">struct</span>
kvec <span style="color: #0000cc;">*</span>
vecs<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
<span style="color: #ff0000;">count</span>
<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现MTD设备的同步操作</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
sync<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现特定芯片的加锁和解锁</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
lock<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">uint64_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
unlock<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">uint64_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现支持电源管理</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
suspend<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
resume<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//坏块管理功能</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
block_isbad<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
block_markbad<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//默认重启的MTD设备工作模式</span>
<br><span style="color: #0000ff;">struct</span>
notifier_block reboot_notifier<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//用于记录ECC状态的信息</span>
<br><span style="color: #0000ff;">struct</span>
mtd_ecc_stats ecc_stats<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">/* Subpage shift (NAND) */</span>
<br><span style="color: #0000ff;">int</span>
subpage_sft<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//私有数据,注意是void类型的指针</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">*</span>
priv<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">struct</span>
module <span style="color: #0000cc;">*</span>
owner<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">struct</span>
device dev<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
usecount<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//记录用户的个数</span>
<br><br><span style="color: #ff9900;">//这两个方法用于设备驱动的回调,可以根据具体需要来决定是否实现他们</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_device<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
put_device<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000cc;">;</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">struct</span>
mtd_part <br><span style="color: #0000cc;">{</span>
<br><span style="color: #0000ff;">struct</span>
mtd_info mtd<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//本分区信息(会被加入到mtd_table中,其大部分成员由其master决定)</span>
<br><span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
master<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区的主分区(不作为一个mtd_info加入到mtd_table。这也解释了上面的一个比喻,1个原始设备上有3个分区,最后将只有3个mtd_info加入到mtd_table而不是4个)</span>
<br><span style="color: #ff0000;">uint64_t</span>
offset<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区的偏移地址</span>
<br><span style="color: #0000ff;">int</span>
index<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区号</span>
<br><span style="color: #0000ff;">struct</span>
list_head <span style="color: #ff0000;">list</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
registered<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000cc;">;</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</li>
</ol>
<div>
<strong><span style="">三、Linux中的Nor Flash驱动</span>
</strong>
</div>
<p></p>
<div>未完,待续。。。。。。</div>
<span style="">嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。</span>
</div>
<ul>
<li>
<span style="">共享资源,欢迎转载:</span>
<a href="http://hbhuanggang.cublog.cn/"><span style="">http://hbhuanggang.cublog.cn</span>
</a>
</li>
</ul>
<p><strong><span style="">一、Linux中Flash硬件知识</span>
</strong>
</p>
<ol>
<li>
<span style="font-size: x-small;">Flash用途和分类:<br><br>
在嵌入式系统开发设计中,存储模块是不可缺少的重要部分,而
Flash是目前市场上主要的非易失闪存技术,他主要分为:Nor Flash和Nand Flash两种。那么他们有什么区别呢?简单的讲:Nor
Flash容量小,价格高,写速度慢但随机读速度快,所以较适合存储少量的程序代码,比如u-boot启动代码;而Nand
Flash则容量大,价格低,写速度快但读速度慢,所以他相当于PC上的硬盘用于存储大量的数据。Nor Flash与Nand
Flash更详细区别如下表:<br><img src="http://blog.chinaunix.net/photo/101649_100629103038.png" alt=""><br></span>
</li>
<li>
<span style="font-size: x-small;">Flash在硬件设计中的应用:<br><br>
以Mini2440开发板为例:该开发板上带有一块2M的Nor Flash和一块64M的Nand Flash。下面先看看他们是怎样被应用于嵌入式Linux的。Nor Flash和Nand Flash电路原理图分别如下:(由mini2440提供)<br><img src="http://blog.chinaunix.net/photo/101649_100629104856.png" alt=""><br><br>
从
原理图上可以看到,Nor Flash内部提供的是有类似于DRam之类的地址总线,可以直接与CPU相连,CPU可以直接通过地址总线对Nor
Flash进行访问;而Nand Flash没有这类的总线,其内部只提供IO接口,因此只能通过IO接口发送命令和地址,对Nand
Flash内部数据进行访问。这可以说是二者最大的区别了,也说明了二者读写速度不同的所在。因此,各有各的优点,Nor Flash访问快,Nand
Flash简化了电路。注意:电路原理图中字母上面有一横杠的表示该引脚是低电平有效,没有的是默认的高电平。</span>
</li>
</ol>
<div>
<strong><span style="">二、Linux中Flash软件知识</span>
</strong>
</div>
<ol>
<li>
<span style="">Linux MTD子系统:<br><br>
在Linux系统中,提供了MTD(内存技术设备)子系统来建立Flash针对Linux的统一、抽象的接口。MTD子系统将上层文件系统与底层
Flash硬件进行了隔离,使Flash驱动开发者无需再关心Flash作为字符设备或者块设备与Linux内核的接口。MTD将Linux系统
Flash设备驱动及接口分成了4个层次,如图所示,从上往下分别为:设备节点、MTD设备层、MTD原始设备层和Flash硬件驱动层。<br><img src="http://blog.chinaunix.net/photo/101649_100629160140.png" alt=""><br><br><strong>设备节点:</strong>
用户在/dev目录下使用mknod命令建立MTD字符设备节点(主设备号为90),或者MTD块设备节点(主设备号为31),使用该设备节点即可访问MTD设备。<br><br><strong>MTD设备层:</strong>
基于MTD原始设备层,系统将MTD设备可以定义为MTD字符设备(在/mtd/mtdchar.c中实现)和MTD块设备(在/mtd/mtdblock.c中实现)。<br><br><strong>MTD原始设备层:</strong>
MTD原始设备层由两个部分组成,分别是MTD原始设备的通用代码和各个特定的Flash的数据,如分区信息。<br><br><strong>Flash硬件驱动层:</strong>
Flash硬件驱动层负责对Flash硬件的读、写和擦除操作。MTD设备的Nor Flash芯片驱动一般位于drivers/mtd/chips/子目录下,Nand Flash芯片的驱动则位于drivers/mtd/nand/子目录下。<br><br>
综
合上述我们可知,MTD子系统已经对Flash设备对于上层的应用进行了封装,我们在写硬件驱动的时候直接调用MTD原始设备层提供的接口函数做相应的操
作即可。那么,对于MTD设备层,MTD原始设备层提供了哪些接口呢?对于Flash硬件驱动层,MTD原始设备层又提供了哪些接口呢?下面开始了解。<br><br></span>
</li>
<li>
<span style="font-size: x-small;">MTD子系统接口:<br><br>
在MTD子系统中,MTD设备层、MTD原始设备层和Flash硬件驱动层之间的接口关系如下图所示:<br><img src="http://blog.chinaunix.net/photo/101649_100701145306.png" alt=""><br>
从上图可知,MTD设备层是通过原始设备层提供的接口来注册MTD字符设备或MTD块设备的,同样,驱动工程师要编写的Flash硬件驱动也是通过原始设备层提供的接口来添加MTD设备和MTD分区的,分别如下:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9933;">//使用这两个接口函数进行添加和删除MTD设备</span>
<br><span style="color: #0000ff;">int</span>
add_mtd_device<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
del_mtd_device<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
</span>
</span>
</code>
</p>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"></span>
</span>
</code>
</p>
<code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000cc;">
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #ff9933;">//使用这两个接口函数进行添加和删除MTD分区</span>
<br><span style="color: #0000ff;">int</span>
add_mtd_partitions<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*<span style="color: #000000;">master</span>
, struct <span style="color: #000000;">mtd_partition</span>
*<span style="color: #000000;">parts</span>
, int <span style="color: #000000;">nbparts</span>
</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
del_mtd_partitions<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*<span style="color: #000000;">master</span>
</span>
<span style="color: #0000cc;">)</span>
</span>
</span>
</code>
</p>
</span>
</span>
</span>
</code>
</td>
</tr></tbody></table>
<br><br>
在
MTD中,一个MTD原始设备用mtd_info结构体来表示,定义在include/linux/mtd/mtd.h中;一个MTD原始设备分区用
mtd_part结构体来表示,定义在drivers/mtd/mtdpart.c中。其中每个分区也被认为是一个mtd_info,比如:有一个MTD
原始设备,上面有3个分区,那么将共有3个mtd_info,而这3个mtd_info的指针将被存放在mtd_table的数组中进行管理,定义在
drivers/mtd/mtdcore.h中,如下所示:
<table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">extern</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd_table<span style="color: #0000cc;">[</span>
MAX_MTD_DEVICES<span style="color: #0000cc;">]</span>
<span style="color: #0000cc;">;<span style="color: #ff9933;">//最多有MAX_MTD_DEVICES(默认定义为32)个设备</span>
</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><br></span>
</li>
<li>
<span style="font-size: x-small;">MTD子系统中重要的一些数据结构:<br><table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">struct</span>
mtd_info <br><span style="color: #0000cc;">{</span>
<br><span style="color: #ff9900;">//硬件设备的类型,如:MTD_RAM,MTD_ROM,MTD_NORFlash,MTD_NANDFlash,MTD_PEROM等</span>
<br>
u_char type<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//设备支持的选项,如:MTD_ERASEABLE(可擦除),MTD_WRITEB_WRITEALBE(可编程),</span>
<br><span style="color: #ff9900;">//MTD_XIP(可片内执行),MTD_OOB(NAND额外数据),MTD_ECC(支持自动ECC)等</span>
<br><span style="color: #ff0000;">uint32_t</span>
flags<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff0000;">uint64_t</span>
size<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//MTD设备的大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
erasesize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//主要的擦除块大小(注意:同一个MTD设备可能有几种不同的erasesize)</span>
<br><span style="color: #ff0000;">uint32_t</span>
writesize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//编程块大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
oobsize<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//OOB数据大小</span>
<br><span style="color: #ff0000;">uint32_t</span>
oobavail<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
erasesize_shift<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
writesize_shift<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
erasesize_mask<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">int</span>
writesize_mask<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">const</span>
<span style="color: #0000ff;">char</span>
<span style="color: #0000cc;">*</span>
name<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
index<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">struct</span>
nand_ecclayout <span style="color: #0000cc;">*</span>
ecclayout<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//ECC布局结构</span>
<br><br><span style="color: #0000ff;">int</span>
numeraseregions<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//擦除区域的个数,通常为1</span>
<br><span style="color: #0000ff;">struct</span>
mtd_erase_region_info <span style="color: #0000cc;">*</span>
eraseregions<span style="color: #0000cc;">;</span>
</span>
<span style="font-family: NSimsun;"><span style="color: #ff9900;">//擦除区域的指针<br></span>
<br><span style="color: #ff9900;">//此方法将一个erase_info结构放入擦除队列中</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
erase<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
erase_info <span style="color: #0000cc;">*</span>
instr<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//point和unpoint方法分别用于允许和禁止芯片内执行(eXecute-In-Place,简称XIP),如果unpoint为NULL,则表示禁止XIP</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
point<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">*</span>
<span style="color: #0000cc;">*</span>
virt<span style="color: #0000cc;">,</span>
resource_size_t <span style="color: #0000cc;">*</span>
phys<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
unpoint<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//如果不为NULL,则表示允许无MMU单元的虚拟地址映射</span>
<br><span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_unmapped_area<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
offset<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
flags<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">struct</span>
backing_dev_info <span style="color: #0000cc;">*</span>
backing_dev_info<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//read和write分别用于MTD设备的读和写</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
<span style="color: #ff0000;">read</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
<span style="color: #ff0000;">write</span>
<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
panic_write<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//read_oob和write_oob分别用于读写MTD设备的OOB数据</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_oob<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
mtd_oob_ops <span style="color: #0000cc;">*</span>
ops<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
write_oob<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
mtd_oob_ops <span style="color: #0000cc;">*</span>
ops<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//一下几个方法是用于实现访问一些受保护的寄存器(一般这只是出现在某些特定的Flash设备上)</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_fact_prot_info<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
otp_info <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_fact_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_user_prot_info<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">struct</span>
otp_info <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
read_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
write_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">,</span>
u_char <span style="color: #0000cc;">*</span>
buf<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
lock_user_prot_reg<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t from<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//基于kvec的形式写</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
writev<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">const</span>
<span style="color: #0000ff;">struct</span>
kvec <span style="color: #0000cc;">*</span>
vecs<span style="color: #0000cc;">,</span>
<span style="color: #0000ff;">unsigned</span>
<span style="color: #0000ff;">long</span>
<span style="color: #ff0000;">count</span>
<span style="color: #0000cc;">,</span>
loff_t to<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">size_t</span>
<span style="color: #0000cc;">*</span>
retlen<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现MTD设备的同步操作</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
sync<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现特定芯片的加锁和解锁</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
lock<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">uint64_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
unlock<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">,</span>
<span style="color: #ff0000;">uint64_t</span>
len<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//实现支持电源管理</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
suspend<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
resume<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//坏块管理功能</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
block_isbad<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
block_markbad<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">,</span>
loff_t ofs<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//默认重启的MTD设备工作模式</span>
<br><span style="color: #0000ff;">struct</span>
notifier_block reboot_notifier<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//用于记录ECC状态的信息</span>
<br><span style="color: #0000ff;">struct</span>
mtd_ecc_stats ecc_stats<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">/* Subpage shift (NAND) */</span>
<br><span style="color: #0000ff;">int</span>
subpage_sft<span style="color: #0000cc;">;</span>
<br><br><span style="color: #ff9900;">//私有数据,注意是void类型的指针</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">*</span>
priv<span style="color: #0000cc;">;</span>
<br><br><span style="color: #0000ff;">struct</span>
module <span style="color: #0000cc;">*</span>
owner<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">struct</span>
device dev<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
usecount<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//记录用户的个数</span>
<br><br><span style="color: #ff9900;">//这两个方法用于设备驱动的回调,可以根据具体需要来决定是否实现他们</span>
<br><span style="color: #0000ff;">int</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
get_device<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">void</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000cc;">*</span>
put_device<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">(</span>
<span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
mtd<span style="color: #0000cc;">)</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000cc;">;</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table>
<br><table style="border-collapse: collapse; width: 95%;" border="1" cellspacing="0" cellpadding="0"><tbody><tr>
<td>
<p style="margin: 5px; line-height: 150%;"><code><span style="color: #000000;"><span style="font-family: NSimsun;"><span style="color: #0000ff;">struct</span>
mtd_part <br><span style="color: #0000cc;">{</span>
<br><span style="color: #0000ff;">struct</span>
mtd_info mtd<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//本分区信息(会被加入到mtd_table中,其大部分成员由其master决定)</span>
<br><span style="color: #0000ff;">struct</span>
mtd_info <span style="color: #0000cc;">*</span>
master<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区的主分区(不作为一个mtd_info加入到mtd_table。这也解释了上面的一个比喻,1个原始设备上有3个分区,最后将只有3个mtd_info加入到mtd_table而不是4个)</span>
<br><span style="color: #ff0000;">uint64_t</span>
offset<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区的偏移地址</span>
<br><span style="color: #0000ff;">int</span>
index<span style="color: #0000cc;">;</span>
<span style="color: #ff9900;">//该分区号</span>
<br><span style="color: #0000ff;">struct</span>
list_head <span style="color: #ff0000;">list</span>
<span style="color: #0000cc;">;</span>
<br><span style="color: #0000ff;">int</span>
registered<span style="color: #0000cc;">;</span>
<br><span style="color: #0000cc;">}</span>
<span style="color: #0000cc;">;</span>
</span>
</span>
</code>
</p>
</td>
</tr></tbody></table></span>
</li>
</ol>
<div>
<strong><span style="">三、Linux中的Nor Flash驱动</span>
</strong>
</div>
<p></p>
<div>未完,待续。。。。。。</div>
相关推荐
本书是根据相关的博客做的PDF格式的电子书,欢迎到原作者的博客去看看。 这个是目录: ·嵌入式Linux之我行——虚拟机中安装Linux ·嵌入式Linux之我行...·嵌入式Linux之我行——S3C2440上Flash驱动实例开发讲解(一)
嵌入式Linux之我行——S3C2440上LCD驱动(FrameBuffer)实例开发讲解(一)
嵌入式Linux之我行——S3C2440上LCD驱动(FrameBuffer)实例开发讲解(二)
嵌入式Linux之我行——内核通知链机制的原理及实现.pdf嵌入式Linux之我行——内核通知链机制的原理及实现.pdf
基于S3C2440的嵌入式Linux开发实例教程书籍;arm9系列书籍
基于S3C2440的嵌入式Linux开发实例
嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解.doc
S3C2440上LCD驱动(FrameBuffer)实例开发讲解
[野火]《嵌入式Linux驱动开发实战指南——基于i.MX6ULL系列》
嵌入式学习——s3c2440全套中文手册(无水印版)
嵌入式linux S3C2440 上 MMC / SD 卡 驱动实例开发讲解
3.1 嵌入式Linux的开发环境 3.2 Cygwin 3.3 虚拟机 3.4 交叉编译的预备知识 3.4.1 Make命令和Makefile文件 3.4.2 binutils工具包 3.4.3 gcc编译器 3.4.4 Glibc库 3.4.5 GDB 3.5 交叉编译 3.5.1 创建编译...
基于S3C2440的嵌入式Linux开发实例.pdf
嵌入式Linux攀上枝头——2006年嵌入式Linux市场调查.pdf
S3C2440上ADC驱动实例开发讲解
嵌入式Linux在S3C2440上的移植 (1).pdf
扫描完整版 ARM嵌入式Linux设备驱动实例开发 ARM嵌入式Linux设备驱动实例开发
基于ARM9 S3C2440的MINI2440开发板,深圳迅通程式嵌入式培训中心开发的精选20个基于嵌入式linux平台的ARM开发板经典实验项目,每个实验项目包括详细的实验原理、目的和步骤;主要内容涵盖嵌入式Linux平台开发环境...
嵌入式linux设备驱动开发详解 嵌入式开发资料
本书特色:本书系统地介绍了嵌入式Linux设备驱动开发的相关知识和实例,主要包括: 数码管驱动程序;键盘驱动程序;...实例丰富、讲解细致、代码分析详尽,嵌入式Linux设备驱动开发的理想参考用书。