新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM-Linux驅(qū)動(dòng)--MTD驅(qū)動(dòng)分析(一)

ARM-Linux驅(qū)動(dòng)--MTD驅(qū)動(dòng)分析(一)

作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò) 收藏
主機(jī):Gentoo Linux 11.2 with linux kernel 3.0.6

硬件平臺(tái):FL2440(S3C2440)with linux kernel 2.6.35

本文引用地址:http://butianyuan.cn/article/201611/319012.htm

MTD(memory technology device內(nèi)存技術(shù)設(shè)備) 在硬件和文件系統(tǒng)層之間的提供了一個(gè)抽象的接口,MTD是用來(lái)訪問(wèn)內(nèi)存設(shè)備(如:ROM、flash)的中間層,它將內(nèi)存設(shè)備的共有特性抽取出來(lái),從而使增加新的內(nèi)存設(shè)備驅(qū)動(dòng)程序變得更簡(jiǎn)單。MTD的源代碼都在/drivers/mtd目錄中。

MTD中間層細(xì)分為四層,按從上到下依次為:設(shè)備節(jié)點(diǎn)、MTD設(shè)備層、MTD原始設(shè)備層和硬件驅(qū)動(dòng)層。MTD中間層層次結(jié)構(gòu)圖如下:

從上圖可以看出,原始設(shè)備是MTD字符設(shè)備和MTD塊設(shè)備的抽象。

MTD設(shè)備層、MTD原始設(shè)備層和Flash硬件驅(qū)動(dòng)層之間的接口關(guān)系如下圖:

下面首先分析下MTD原始層設(shè)備

1、mtd_info數(shù)據(jù)結(jié)構(gòu)

  1. structmtd_info{
  2. u_chartype;//內(nèi)存技術(shù)類型,例如MTD_RAM,MTD_ROM,MTD_NORFLASH,MTD_NAND_FLASH,MTD_PEROM等
  3. uint32_tflags;//標(biāo)志位
  4. uint64_tsize;//TotalsizeoftheMTD//MTD設(shè)備的大小
  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字節(jié)
  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布局結(jié)構(gòu)
  34. /*Dataforvariableeraseregions.Ifnumeraseregionsiszero,
  35. *itmeansthatthewholedevicehaserasesizeasgivenabove.
  36. */
  37. intnumeraseregions;//擦除區(qū)域個(gè)數(shù),通常為1
  38. structmtd_erase_region_info*eraseregions;//擦除區(qū)域的區(qū)域信息地址
  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);//函數(shù)指針,erase函數(shù)的功能是將一個(gè)erase_info加入擦除隊(duì)列
  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函數(shù)功能是允許片內(nèi)執(zhí)行(XIP)
  51. /*WeprobablyshouldntallowXIPiftheunpointisntaNULL*/
  52. void(*unpoint)(structmtd_info*mtd,loff_tfrom,size_tlen);//unpoint函數(shù)與point函數(shù)相反,是禁止片內(nèi)執(zhí)行(XIP)
  53. /*AllowNOMMUmmap()todirectlymapthedevice(ifnotNULL)
  54. *-returntheaddresstowhichtheoffsetmaps
  55. *-return-ENOSYStoindicaterefusaltodothemapping
  56. */
  57. //如果不是NULL,則允許無(wú)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設(shè)備的讀寫函數(shù)
  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設(shè)備的OBB數(shù)據(jù)讀寫
  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設(shè)備的同步函數(shù)
  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. //支持電源管理函數(shù)
  106. int(*suspend)(structmtd_info*mtd);
  107. void(*resume)(structmtd_info*mtd);
  108. /*Badblockmanagementfunctions*/
  109. //壞塊管理函數(shù)
  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狀態(tài)信息
  115. /*Subpageshift(NAND)*/
  116. intsubpage_sft;
  117. void*priv;//私有數(shù)據(jù)指針
  118. structmodule*owner;
  119. structdevicedev;
  120. intusecount;//記錄用戶的個(gè)數(shù)
  121. /*Ifthedriverissomethingsmart,likeUBI,itmayneedtomaintain
  122. *itsownreferencecounting.Thebelowfunctionsareonlyfordriver.
  123. *Thedrivermayregisteritscallbacks.Thesecallbacksarenot
  124. *supposedtobecalledbyMTDusers*/
  125. //驅(qū)動(dòng)回調(diào)函數(shù)
  126. int(*get_device)(structmtd_info*mtd);
  127. void(*put_device)(structmtd_info*mtd);
  128. };

2、mtd_part結(jié)構(gòu)體信息

  1. /*Ourpartitionlinkedlist*/
  2. staticLIST_HEAD(mtd_partitions);//分區(qū)鏈表
  1. /*Ourpartitionnodestructure*/
  2. //分區(qū)結(jié)構(gòu)信息
  3. structmtd_part{
  4. structmtd_infomtd;//mtd_info數(shù)據(jù)結(jié)構(gòu),會(huì)被加入mtd_table中
  5. structmtd_info*master;//該分區(qū)的主分區(qū)
  6. uint64_toffset;//該分區(qū)的偏移地址
  7. structlist_headlist;//分區(qū)鏈表
  8. };

3、mtd_partition描述mtd具體分區(qū)結(jié)構(gòu)

  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分區(qū)名*/
  24. uint64_tsize;/*partitionsize分區(qū)大小*/
  25. uint64_toffset;/*offsetwithinthemasterMTDspace偏移地址*/
  26. uint32_tmask_flags;/*masterMTDflagstomaskoutforthispartition*/
  27. structnand_ecclayout*ecclayout;/*outofbandlayoutforthispartition(NANDonly)*/
  28. };



評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉