<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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

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

          本文引用地址:http://www.ex-cimer.com/article/201611/319012.htm

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

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

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

          MTD設(shè)備層、MTD原始設(shè)備層和Flash硬件驅(qū)動層之間的接口關(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ū)域個數(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ù)的功能是將一個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函數(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,則允許無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;//記錄用戶的個數(shù)
          121. /*Ifthedriverissomethingsmart,likeUBI,itmayneedtomaintain
          122. *itsownreferencecounting.Thebelowfunctionsareonlyfordriver.
          123. *Thedrivermayregisteritscallbacks.Thesecallbacksarenot
          124. *supposedtobecalledbyMTDusers*/
          125. //驅(qū)動回調(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),會被加入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. };



          評論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();