主机:Gentoo Linux 11.2 with linux kernel 3.0.6
硬件渠道:FL2440(S3C2440)with linux kernel 2.6.35
MTD(memory technology device内存技能设备) 在硬件和文件体系层之间的供给了一个笼统的接口,MTD是用来拜访内存设备(如:ROM、flash)的中间层,它将内存设备的共有特性抽取出来,从而使添加新的内存设备驱动程序变得更简略。MTD的源代码都在/drivers/mtd目录中。
MTD中间层细分为四层,按从上到下依次为:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。MTD中间层层次结构图如下:
从上图能够看出,原始设备是MTD字符设备和MTD块设备的笼统。
MTD设备层、MTD原始设备层和Flash硬件驱动层之间的接口联系如下图:
下面首要剖析下MTD原始层设备
1、mtd_info数据结构
- structmtd_info{
- u_chartype;//内存技能类型,例如MTD_RAM,MTD_ROM,MTD_NORFLASH,MTD_NAND_FLASH,MTD_PEROM等
- uint32_tflags;//标志位
- uint64_tsize;//TotalsizeoftheMTD//MTD设备的巨细
- /*”Major”erasesizeforthedevice.Naïveusersmaytakethis
- *tobetheonlyerasesizeavailable,ormayusethemoredetailed
- *informationbelowiftheydesire
- */
- uint32_terasesize;//最小的擦除块巨细
- /*Minimalwritableflashunitsize.IncaseofNORflashitis1(even
- *thoughindividualbitscanbecleared),incaseofNANDflashitis
- *oneNANDpage(orhalf,orone-fourthsofit),incaseofECC-edNOR
- *itisofECCblocksize,etc.Itisillegaltohavewritesize=0.
- *Anydriverregisteringastructmtd_infomustensureawritesizeof
- *1orlarger.
- */
- uint32_twritesize;//编程块巨细
- uint32_toobsize;//AmountofOOBdataperblock(e.g.16)//oob(Outofband)块巨细
- uint32_toobavail;//AvailableOOBbytesperblock//每块的可用的oob字节
- /*
- *Iferasesizeisapowerof2thentheshiftisstoredin
- *erasesize_shiftotherwiseerasesize_shiftiszero.Dittowritesize.
- */
- unsignedinterasesize_shift;
- unsignedintwritesize_shift;
- /*Masksbasedonerasesize_shiftandwritesize_shift*/
- unsignedinterasesize_mask;
- unsignedintwritesize_mask;
- //Kernel-onlystuffstartshere.
- constchar*name;
- intindex;
- /*ecclayoutstructurepointer-readonly!*/
- structnand_ecclayout*ecclayout;//eec布局结构
- /*Dataforvariableeraseregions.Ifnumeraseregionsiszero,
- *itmeansthatthewholedevicehaserasesizeasgivenabove.
- */
- intnumeraseregions;//擦除区域个数,一般为1
- structmtd_erase_region_info*eraseregions;//擦除区域的区域信息地址
- /*
- *Eraseisanasynchronousoperation.Devicedriversaresupposed
- *tocallinstr->callback()whenevertheoperationcompletes,even
- *ifitcompleteswithafailure.
- *Callersaresupposedtopassacallbackfunctionandwaitforit
- *tobecalledbeforewritingtotheblock.
- */
- int(*erase)(structmtd_info*mtd,structerase_info*instr);//函数指针,erase函数的功用是将一个erase_info参加擦除行列
- /*ThisstuffforeXecute-In-Place*/
- /*physisoptionalandmaybesettoNULL*/
- int(*point)(structmtd_info*mtd,loff_tfrom,size_tlen,
- size_t*retlen,void**virt,resource_size_t*phys);//point函数功用是答应片内碑文(XIP)
- /*WeprobablyshouldntallowXIPiftheunpointisntaNULL*/
- void(*unpoint)(structmtd_info*mtd,loff_tfrom,size_tlen);//unpoint函数与point函数相反,是制止片内碑文(XIP)
- /*AllowNOMMUmmap()todirectlymapthedevice(ifnotNULL)
- *-returntheaddresstowhichtheoffsetmaps
- *-return-ENOSYStoindicaterefusaltodothemapping
- */
- //假如不是NULL,则答应无MMU单元的地址映射,回来偏移地址
- unsignedlong(*get_unmapped_area)(structmtd_info*mtd,
- unsignedlonglen,
- unsignedlongoffset,
- unsignedlongflags);
- /*Backingdevicecapabilitiesforthisdevice
- *-providesmmapcapabilities
- */
- structbacking_dev_info*backing_dev_info;
- //MTD设备的读写函数
- int(*read)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
- int(*write)(structmtd_info*mtd,loff_tto,size_tlen,size_t*retlen,constu_char*buf);
- /*Inblackboxflightrecorderlikescenarioswewanttomakesuccessful
- writesininterruptcontext.panic_write()isonlyintendedtobe
- calledwhenitsknownthekernelisabouttopanicandweneedthe
- writetosucceed.Sincethekernelisnotgoingtoberunningformuch
- longer,thisfunctioncanbreaklocksanddelaytoensurethewrite
- succeeds(butnotsleep).*/
- int(*panic_write)(structmtd_info*mtd,loff_tto,size_tlen,size_t*retlen,constu_char*buf);
- //用于MTD设备的OBB数据读写
- int(*read_oob)(structmtd_info*mtd,loff_tfrom,
- structmtd_oob_ops*ops);
- int(*write_oob)(structmtd_info*mtd,loff_tto,
- structmtd_oob_ops*ops);
- /*
- *Methodstoaccesstheprotectionregisterarea,presentinsome
- *flashdevices.Theuserdataisonetimeprogrammablebutthe
- *factorydataisreadonly.
- */
- int(*get_fact_prot_info)(structmtd_info*mtd,structotp_info*buf,size_tlen);
- int(*read_fact_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
- int(*get_user_prot_info)(structmtd_info*mtd,structotp_info*buf,size_tlen);
- int(*read_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
- int(*write_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
- int(*lock_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen);
- /*kvec-basedread/writemethods.
- NB:Thecountparameteristhenumberof_vectors_,eachof
- whichcontainsan(ofs,len)tuple.
- */
- int(*writev)(structmtd_info*mtd,conststructkvec*vecs,unsignedlongcount,loff_tto,size_t*retlen);
- /*Sync*/
- //MTD设备的同步函数
- void(*sync)(structmtd_info*mtd);
- /*Chip-supporteddevicelocking*/
- //芯片的加锁和解锁
- int(*lock)(structmtd_info*mtd,loff_tofs,uint64_tlen);
- int(*unlock)(structmtd_info*mtd,loff_tofs,uint64_tlen);
- /*PowerManagementfunctions*/
- //支撑电源办理函数
- int(*suspend)(structmtd_info*mtd);
- void(*resume)(structmtd_info*mtd);
- /*Badblockmanagementfunctions*/
- //坏块办理函数
- int(*block_isbad)(structmtd_info*mtd,loff_tofs);
- int(*block_markbad)(structmtd_info*mtd,loff_tofs);
- structnotifier_blockreboot_notifier;/*defaultmodebeforereboot*/
- /*ECCstatusinformation*/
- structmtd_ecc_statsecc_stats;//ECC状况信息
- /*Subpageshift(NAND)*/
- intsubpage_sft;
- void*priv;//私有数据指针
- structmodule*owner;
- structdevicedev;
- intusecount;//记载用户的个数
- /*Ifthedriverissomethingsmart,likeUBI,itmayneedtomaintain
- *itsownreferencecounting.Thebelowfunctionsareonlyfordriver.
- *Thedrivermayregisteritscallbacks.Thesecallbacksarenot
- *supposedtobecalledbyMTDusers*/
- //驱动回调函数
- int(*get_device)(structmtd_info*mtd);
- void(*put_device)(structmtd_info*mtd);
- };
2、mtd_part结构体信息
- /*Ourpartitionlinkedlist*/
- staticLIST_HEAD(mtd_partitions);//分区链表
- /*Ourpartitionnodestructure*/
- //分区结构信息
- structmtd_part{
- structmtd_infomtd;//mtd_info数据结构,会被参加mtd_table中
- structmtd_info*master;//该分区的主分区
- uint64_toffset;//该分区的偏移地址
- structlist_headlist;//分区链表
- };
3、mtd_partition描绘mtd详细分区结构
- /*
- *Partitiondefinitionstructure:
- *
- *AnarrayofstructpartitionispassedalongwithaMTDobjectto
- *add_mtd_partitions()tocreatethem.
- *
- *Foreachpartition,thesefieldsareavailable:
- *name:stringthatwillbeusedtolabelthepartitionsMTDdevice.
- *size:thepartitionsize;ifdefinedasMTDPART_SIZ_FULL,thepartition
- *willextendtotheendofthemasterMTDdevice.
- *offset:absolutestartingpositionwithinthemasterMTDdevice;if
- *definedasMTDPART_OFS_APPEND,thepartitionwillstartwherethe
- *previousoneended;ifMTDPART_OFS_NXTBLK,atthenexteraseblock.
- *mask_flags:containsflagsthathavetobemasked(removed)fromthe
- *masterMTDflagsetforthecorrespondingMTDpartition.
- *Forexample,toforcearead-onlypartition,simplyadding
- *MTD_WRITEABLEtothemask_flagswilldothetrick.
- *
- *Note:writeablepartitionsrequiretheirsizeandoffsetbe
- *erasesizealigned(e.g.useMTDPART_OFS_NEXTBLK).
- */
- structmtd_partition{
- char*name;/*identifierstring分区名*/
- uint64_tsize;/*partitionsize分区巨细*/
- uint64_toffset;/*offsetwithinthemasterMTDspace偏移地址*/
- uint32_tmask_flags;/*masterMTDflagstomaskoutforthispartition*/
- structnand_ecclayout*ecclayout;/*outofbandlayoutforthispartition(NANDonly)*/
- };