新闻中心

EEPW首页>嵌入式系统>设计应用> ARM-Linux驱动--MTD驱动分析(一)

ARM-Linux驱动--MTD驱动分析(一)

作者: 时间:2016-11-20 来源:网络 收藏
主机:Gentoo Linux 11.2 with linux kernel 3.0.6

硬件平台:FL2440(S3C2440)with linux kernel 2.6.35

本文引用地址://m.amcfsurvey.com/article/201611/319012.htm

MTD(memory technology device内存技术设备) 在硬件和文件系统层之间的提供了一个抽象的接口,MTD是用来访问内存设备(如:ROM、flash)的中间层,它将内存设备的共有特性抽取出来,从而使增加新的内存设备驱动程序变得更简单。MTD的源代码都在/drivers/mtd目录中。

MTD中间层细分为四层,按从上到下依次为:设备节点、MTD设备层、MTD原始设备层和硬件驱动层。MTD中间层层次结构图如下:

从上图可以看出,原始设备是MTD字符设备和MTD块设备的抽象。

MTD设备层、MTD原始设备层和Flash硬件驱动层之间的接口关系如下图:

下面首先分析下MTD原始层设备

1、mtd_info数据结构

  1. structmtd_info{
  2. u_chartype;//内存技术类型,例如MTD_RAM,MTD_ROM,MTD_NORFLASH,MTD_NAND_FLASH,MTD_PEROM等
  3. uint32_tflags;//标志位
  4. uint64_tsize;//TotalsizeoftheMTD//MTD设备的大小
  5. /*"Major"erasesizeforthedevice.Naïveusersmaytakethis
  6. *tobetheonlyerasesizeavailable,ormayusethemoredetailed
  7. *informationbelowiftheydesire
  8. */
  9. uint32_terasesize;//最小的擦除块大小
  10. /*Minimalwritableflashunitsize.IncaseofNORflashitis1(even
  11. *thoughindividualbitscanbecleared),incaseofNANDflashitis
  12. *oneNANDpage(orhalf,orone-fourthsofit),incaseofECC-edNOR
  13. *itisofECCblocksize,etc.Itisillegaltohavewritesize=0.
  14. *Anydriverregisteringastructmtd_infomustensureawritesizeof
  15. *1orlarger.
  16. */
  17. uint32_twritesize;//编程块大小
  18. uint32_toobsize;//AmountofOOBdataperblock(e.g.16)//oob(Outofband)块大小
  19. uint32_toobavail;//AvailableOOBbytesperblock//每块的可用的oob字节
  20. /*
  21. *Iferasesizeisapowerof2thentheshiftisstoredin
  22. *erasesize_shiftotherwiseerasesize_shiftiszero.Dittowritesize.
  23. */
  24. unsignedinterasesize_shift;
  25. unsignedintwritesize_shift;
  26. /*Masksbasedonerasesize_shiftandwritesize_shift*/
  27. unsignedinterasesize_mask;
  28. unsignedintwritesize_mask;
  29. //Kernel-onlystuffstartshere.
  30. constchar*name;
  31. intindex;
  32. /*ecclayoutstructurepointer-readonly!*/
  33. structnand_ecclayout*ecclayout;//eec布局结构
  34. /*Dataforvariableeraseregions.Ifnumeraseregionsiszero,
  35. *itmeansthatthewholedevicehaserasesizeasgivenabove.
  36. */
  37. intnumeraseregions;//擦除区域个数,通常为1
  38. structmtd_erase_region_info*eraseregions;//擦除区域的区域信息地址
  39. /*
  40. *Eraseisanasynchronousoperation.Devicedriversaresupposed
  41. *tocallinstr->callback()whenevertheoperationcompletes,even
  42. *ifitcompleteswithafailure.
  43. *Callersaresupposedtopassacallbackfunctionandwaitforit
  44. *tobecalledbeforewritingtotheblock.
  45. */
  46. int(*erase)(structmtd_info*mtd,structerase_info*instr);//函数指针,erase函数的功能是将一个erase_info加入擦除队列
  47. /*ThisstuffforeXecute-In-Place*/
  48. /*physisoptionalandmaybesettoNULL*/
  49. int(*point)(structmtd_info*mtd,loff_tfrom,size_tlen,
  50. size_t*retlen,void**virt,resource_size_t*phys);//point函数功能是允许片内执行(XIP)
  51. /*WeprobablyshouldntallowXIPiftheunpointisntaNULL*/
  52. void(*unpoint)(structmtd_info*mtd,loff_tfrom,size_tlen);//unpoint函数与point函数相反,是禁止片内执行(XIP)
  53. /*AllowNOMMUmmap()todirectlymapthedevice(ifnotNULL)
  54. *-returntheaddresstowhichtheoffsetmaps
  55. *-return-ENOSYStoindicaterefusaltodothemapping
  56. */
  57. //如果不是NULL,则允许无MMU单元的地址映射,返回偏移地址
  58. unsignedlong(*get_unmapped_area)(structmtd_info*mtd,
  59. unsignedlonglen,
  60. unsignedlongoffset,
  61. unsignedlongflags);
  62. /*Backingdevicecapabilitiesforthisdevice
  63. *-providesmmapcapabilities
  64. */
  65. structbacking_dev_info*backing_dev_info;
  66. //MTD设备的读写函数
  67. int(*read)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
  68. int(*write)(structmtd_info*mtd,loff_tto,size_tlen,size_t*retlen,constu_char*buf);
  69. /*Inblackboxflightrecorderlikescenarioswewanttomakesuccessful
  70. writesininterruptcontext.panic_write()isonlyintendedtobe
  71. calledwhenitsknownthekernelisabouttopanicandweneedthe
  72. writetosucceed.Sincethekernelisnotgoingtoberunningformuch
  73. longer,thisfunctioncanbreaklocksanddelaytoensurethewrite
  74. succeeds(butnotsleep).*/
  75. int(*panic_write)(structmtd_info*mtd,loff_tto,size_tlen,size_t*retlen,constu_char*buf);
  76. //用于MTD设备的OBB数据读写
  77. int(*read_oob)(structmtd_info*mtd,loff_tfrom,
  78. structmtd_oob_ops*ops);
  79. int(*write_oob)(structmtd_info*mtd,loff_tto,
  80. structmtd_oob_ops*ops);
  81. /*
  82. *Methodstoaccesstheprotectionregisterarea,presentinsome
  83. *flashdevices.Theuserdataisonetimeprogrammablebutthe
  84. *factorydataisreadonly.
  85. */
  86. int(*get_fact_prot_info)(structmtd_info*mtd,structotp_info*buf,size_tlen);
  87. int(*read_fact_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
  88. int(*get_user_prot_info)(structmtd_info*mtd,structotp_info*buf,size_tlen);
  89. int(*read_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
  90. int(*write_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen,size_t*retlen,u_char*buf);
  91. int(*lock_user_prot_reg)(structmtd_info*mtd,loff_tfrom,size_tlen);
  92. /*kvec-basedread/writemethods.
  93. NB:Thecountparameteristhenumberof_vectors_,eachof
  94. whichcontainsan(ofs,len)tuple.
  95. */
  96. int(*writev)(structmtd_info*mtd,conststructkvec*vecs,unsignedlongcount,loff_tto,size_t*retlen);
  97. /*Sync*/
  98. //MTD设备的同步函数
  99. void(*sync)(structmtd_info*mtd);
  100. /*Chip-supporteddevicelocking*/
  101. //芯片的加锁和解锁
  102. int(*lock)(structmtd_info*mtd,loff_tofs,uint64_tlen);
  103. int(*unlock)(structmtd_info*mtd,loff_tofs,uint64_tlen);
  104. /*PowerManagementfunctions*/
  105. //支持电源管理函数
  106. int(*suspend)(structmtd_info*mtd);
  107. void(*resume)(structmtd_info*mtd);
  108. /*Badblockmanagementfunctions*/
  109. //坏块管理函数
  110. int(*block_isbad)(structmtd_info*mtd,loff_tofs);
  111. int(*block_markbad)(structmtd_info*mtd,loff_tofs);
  112. structnotifier_blockreboot_notifier;/*defaultmodebeforereboot*/
  113. /*ECCstatusinformation*/
  114. structmtd_ecc_statsecc_stats;//ECC状态信息
  115. /*Subpageshift(NAND)*/
  116. intsubpage_sft;
  117. void*priv;//私有数据指针
  118. structmodule*owner;
  119. structdevicedev;
  120. intusecount;//记录用户的个数
  121. /*Ifthedriverissomethingsmart,likeUBI,itmayneedtomaintain
  122. *itsownreferencecounting.Thebelowfunctionsareonlyfordriver.
  123. *Thedrivermayregisteritscallbacks.Thesecallbacksarenot
  124. *supposedtobecalledbyMTDusers*/
  125. //驱动回调函数
  126. int(*get_device)(structmtd_info*mtd);
  127. void(*put_device)(structmtd_info*mtd);
  128. };

2、mtd_part结构体信息

  1. /*Ourpartitionlinkedlist*/
  2. staticLIST_HEAD(mtd_partitions);//分区链表
  1. /*Ourpartitionnodestructure*/
  2. //分区结构信息
  3. structmtd_part{
  4. structmtd_infomtd;//mtd_info数据结构,会被加入mtd_table中
  5. structmtd_info*master;//该分区的主分区
  6. uint64_toffset;//该分区的偏移地址
  7. structlist_headlist;//分区链表
  8. };

3、mtd_partition描述mtd具体分区结构

  1. /*
  2. *Partitiondefinitionstructure:
  3. *
  4. *AnarrayofstructpartitionispassedalongwithaMTDobjectto
  5. *add_mtd_partitions()tocreatethem.
  6. *
  7. *Foreachpartition,thesefieldsareavailable:
  8. *name:stringthatwillbeusedtolabelthepartitionsMTDdevice.
  9. *size:thepartitionsize;ifdefinedasMTDPART_SIZ_FULL,thepartition
  10. *willextendtotheendofthemasterMTDdevice.
  11. *offset:absolutestartingpositionwithinthemasterMTDdevice;if
  12. *definedasMTDPART_OFS_APPEND,thepartitionwillstartwherethe
  13. *previousoneended;ifMTDPART_OFS_NXTBLK,atthenexteraseblock.
  14. *mask_flags:containsflagsthathavetobemasked(removed)fromthe
  15. *masterMTDflagsetforthecorrespondingMTDpartition.
  16. *Forexample,toforcearead-onlypartition,simplyadding
  17. *MTD_WRITEABLEtothemask_flagswilldothetrick.
  18. *
  19. *Note:writeablepartitionsrequiretheirsizeandoffsetbe
  20. *erasesizealigned(e.g.useMTDPART_OFS_NEXTBLK).
  21. */
  22. structmtd_partition{
  23. char*name;/*identifierstring分区名*/
  24. uint64_tsize;/*partitionsize分区大小*/
  25. uint64_toffset;/*offsetwithinthemasterMTDspace偏移地址*/
  26. uint32_tmask_flags;/*masterMTDflagstomaskoutforthispartition*/
  27. structnand_ecclayout*ecclayout;/*outofbandlayoutforthispartition(NANDonly)*/
  28. };



评论


相关推荐

技术专区

关闭