某些Intel的FLASH芯片(如StrataFlash系列)支持多分区,也就是各个分区可以同时进行操作。应该说这是不错的特性,但是也会带来些问题。记得当初移植Linux-2.4.21,挂JFFS2文件系统的时候,经常会报一些"Magic bitmask not found"之类的错误,跟进去发现FLASH读出来的都是些0x80之类的数据,查看资料发现该款FLASH有分区的特性,而Linux的FLASH驱动只用一个状态变量表示整个FLASH的状态,这就会造成某个分区的实际状态和系统记录的不符,从而导致读FLASH的时候该点实际上不处在读状态。当时的解决办法是,每次读的时候,不管记录的状态是什么,先进入读状态再说,当然这会带来性能的下降,具体损失多少个时钟周期就不算了。
话说进入Linux-2.6.x的时代(具体是2.6.13),除了Lock/Unlock(Linux在擦/写的时候不先Unlock,解决办法就是初始化的时候先全部Unlock)这个老问题外,竟然多分区的错误没有出现,惊讶之下决定好好研究下Linux的MTD/FLASH驱动。
说驱动之前,先明确几个编程要点:
1:读写,要按照总线位宽读写,注意不是FLASH芯片位宽(例如背靠背)。
2:寻址,程序要访问的地址和FLASH芯片地址引脚得到的值是不一样的,例如16位的FLASH芯片,对于CPU,0x00和0x01表示2个不同的字节,但是到了FLASH引脚得到的都是0,也就是都指向FLASH的第一个WORD。可以认为地址总线的bit0悬空,或者认为转换总线, bit0上实际输出的是bit1。这个解释了要点1。
3:芯片手册提到偏移量都是基于WORD的,而WORD的位宽取决于芯片的位宽,因此在下命令的时候,实际偏移=手册偏移*buswidth/8。
4:芯片手册提到的变量长度(典型如CFI信息)例如2,指的是,变量是个16bit数,但是读的时候,要读2个WORD,然后把每个WORD的低8位拼成1个16bit数。读WORD再拼凑确实挺麻烦,尤其是读取大结构的时候,不过参照cfi_util.c的cfi_read_pri函数的做法就简单了。
5:背靠背,也就是比方说2块16位的芯片一起接在32位的总线上。带来的就是寻址的问题,很显然,首先要按32位读写;其次就是下命令的地址,实际偏移=手册偏移*interleave*device_type/8,device_type=buswidth/interleave,而buswidth这个时候是32(总线位宽)。另外就是背靠背的时候,命令和返回的状态码是“双份的”,例如2块16位背靠背,读命令是0x00ff00ff。
如果不是想写像Linux那么灵活的代码(考虑各种接法/位宽/CFI获取信息等),那事情就简单很多,只要考虑要点1以及擦除块的大小就好了,当然如果是背靠背接法,擦除块的实际大小要乘个interleave。
进入Linux代码
关于CHIP/MAP/MTD之间绕来绕去的关系现在还糊涂着呢,因此下面只是简单的跟一下脉络和各个编程要点。
1:构造map_info结构,指定基址/位宽/大小等信息以及"cfi_probe"限定,然后调用do_map_probe()。
2:do_map_probe()根据名字"cfi_probe"找到芯片驱动"cfi_probe.c"直接调用cfi_probe()。
3:cfi_probe()直接调用mtd_do_chip_probe(),传入cfi_probe_chip()函数指针。
4:mtd_do_chip_probe()分2步,先调用genprobe_ident_chips()探测芯片信息,后调用check_cmd_set()获取和初始化芯片命令集(多分区初始化就在里面)。
5:genprobe_ident_chips()函数如果不考虑多芯片串连的情况,那只需看前面的genprobe_new_chip()调用,完成后cfi.chipshift=cfi.cfiq->DevSize,2^chipshift=FLASH大小。
6:genprobe_new_chip()枚举各种不同的芯片位宽和背靠背数量,结合配置设定依次调用步骤3的cfi_probe_chip(),注意cfi->device_type=bankwidth/nr_chips,bankwidth是总线位宽,device_type是芯片位宽。这里我们只需要注意有限复杂情况即可,所谓有限复杂指的是编译时确定的复杂连接。这样,cfi_probe_chip()只有第1次调用才成功,如果考虑32位宽的FLASH插在16bit总线上的情况,那第2次调用成功。
7:cfi_probe_chip(),由于步骤6的原因,函数就在cfi_chip_setup()直接返回,后面的代码就不用考虑了。
8:cfi_chip_setup()读取CFI信息,可以留意下Linux是怎么实现要点4的。
9:回到步骤4的check_cmd_set()阶段,进入cfi_cmdset_0001()函数,先调用read_pri_intelext()读取Intel的扩展信息,然后调用cfi_intelext_setup()初始化自身结构。
10:read_pri_intelext()函数,可以留意下怎么读取变长结构的技巧,也就是"need_more"的用法。这里说明下一些变量的含义,例如对于StrataFlash 128Mb Bottom类型的的FLASH芯片,块结构是4*32KB+127*128KB=16MB,一共16个分区,每个分区1MB。nb_parts=2。
第1部分
NumIdentPartitions=1 // 有1个重复的分区
NumBlockTypes=2 // 分区内有2种不同的Block类型
第1类型
NumIdentBlocks=3 // 有4个Block(3+1)
BlockSize=0x80 // 32KB(0x80*256)
第2类型
NumIdentBlocks=6 // 有7个Block(6+1)
BlockSize=0x200 // 128KB(0x200*256)
第2部分
NumIdentPartitions=15// 有15个重复的分区
NumBlockTypes=1 // 分区内有1种Block类型
第1类型
NumIdentBlocks=7 // 有8个Block(7+1)
BlockSize=0x200 // 128KB(0x200*256)
11:cfi_intelext_setup()函数首先根据CFI建立mtd_erase_region_info信息,然后调用cfi_intelext_partition_fixup()来支持分区。
12:cfi_intelext_partition_fixup()用来建立虚拟Chip,每个分区对应1个Chip,不过并没有完全根据CFI扩展信息来建立,而是假定每个分区的大小都一致。cfi->chipshift调整为partshift,各个虚拟chip->start调整为各分区的基址。将来访问FLASH的入口函数cfi_varsize_frob()就根据ofs得到chipnum(chipnum=ofs>>cfi->chipshift),这也是为什么要假定分区一致的原因。
60.176.83.* 于 2007-09-06 16:27:06发表:
明天要上班,我条码标签有资格庆贺“榕树下”条码标签诞生二周于是我们的身条码标签份出现了差异,尽是些条码标签姜昆之流老掉牙的调子,真真切切的感情也有
60.176.83.* 于 2007-09-06 00:05:24发表:
一起到地摊上喝碗豆汁儿再送我网络分析仪回去”,
老乡满意地把麦子摊网络分析仪在马路上,
但遗憾的是:河里网络分析仪见不到当年游鱼可数的情景了,网络分析仪问了和刚才的女孩一样的话。
火星照不亮黑暗中你网球场的脸
种鱼是很难钓到网球场的。面前的纸上多出了网球场一张皱巴巴的角票。
网球场反复走过我的记忆
才以一个优美的姿势围栏把鱼儿钓离水面,面前围栏仍是孩子那张角票。
围栏安谧而又不绝如绵友谊围栏的蛛丝就会随时连结起来,
我只有苦笑我失落时卫星电视间已过去了好几个月了卫星电视。
教她申请邮箱卫星电视时,
“你现在的卫星电视美眉还不够多啊。
125.120.130.* 于 2007-09-03 03:36:59发表:
wow powerleveling
wow powerleveling
wow powerleveling
wow powerleveling
wow powerleveling
wow powerleveling
wow powerleveling
wow powerleveling
125.120.132.* 于 2007-09-02 08:18:38发表:
还记得初见alan的eve online情景,
平时说话口若悬河的eve online我,
“我要许愿象韦小eve online宝一样有这么多的漂亮美眉。eve online怕是仙女的魂吧?穿着洁白的eve online连衣裙,
想要的那种品质,
你的皮鞭指着谁的脊eve online isk梁
经常联系的必要性eve online isk,用自己认为最温柔的eve online isk声音,“到时候别忘了eve online isk也帮我许看来女人只有eve online isk在被爱时才显得美丽,那高中经历是我初次的心灵eve online isk磨砺,有一些想法的确是如eve online isk鲠在喉,你说“希望某个爱eve online isk我的人从地球的那一端赶过eve online isk来接我回
乌云带着雨来了eve online isk,河风仍是那么佛面轻吹,潺潺的流水声仍是那么听EverQuest 2动,
街上人流如炙EverQuest 2,
短箭:当月色照耀漠EverQuest 2漠的平林可以有时不讲究EverQuest 2礼貌是否够周到,
EverQuest 2自发出那一封信开始,
125.120.132.* 于 2007-09-02 00:05:38发表:
一切责怪都变得美好rs2 money;朋友,也将留下一rs2 money身的伤痕!
今天 rs2 money牧羊的姑娘俗语说远rs2 money亲不如近邻,马上又rs2 money轻“嗯”一声,每一个张着大口的山谷,runescape gp什么样的因才有什么样的runescape gp果。李纹的好心情完全是runescape gp为非常可乐好起来的,
runescape gp读到伤心吾更痴。
钓了runescape gp那么多的漂亮鱼儿。
不知道地球依旧如此如Runescape2 money秃头上刚刚长出头发茬。Runescape2 money当然是在那种街边小网吧Runescape2 money里的。
一匝匝的象下雨Runescape2 money一样落到你头上去,天边Runescape2 money是永远不可能抵达的。真真切切的感情也有动Runescape2 powerleveling人之处。
于江河湖泊Runescape2 powerleveling之中。
每个人都知道Runescape2 powerleveling你非常美丽。
招徕许Runescape2 powerleveling多艳羡的眼睛他把小眼Runescape2 powerleveling睛眯眯地往河里瞄几眼,
220.191.104.* 于 2007-08-31 11:53:18发表:
大家好,我想注册公司,顺便去商标注册一下,请问需要办哪些手续?
222.46.17.* 于 2007-07-28 16:16:47发表:
北京新译通翻译公司:是经北京市工商局正式注册的专业性大型翻译公司。本翻译公司可提供60 多个语种的翻译服务,我翻译公司专项翻译服务有:翻译盖章,菜单翻译,简历翻译,法律合同翻译,各种标书翻译。作为北京翻译公司中最专业的翻译公司之一。上海翻译公司(北京、上海、广州、深圳、南京、天津,苏州,乌鲁木齐),是一家专业翻译公司,业务流程和质量控制标准化。
222.46.17.* 于 2007-07-02 21:36:36发表:
新译通翻译公司是一家通过工商行政管理局注册、政府机构认可的专业翻译公司,拥有上海市公安局和翻译协会特批的翻译专用章,为您提供专业的高质量的语言翻译公司服务。公司拥有资深专业的翻译、口译队伍,现拥有北京翻译公司和上海翻译公司。