新聞中心

        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

        本文引用地址:http://www.104case.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. };



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 调兵山市| 惠来县| 那曲县| 霍林郭勒市| 文化| 青冈县| 改则县| 体育| 东城区| 镇江市| 林口县| 星子县| 登封市| 南召县| 蓝山县| 博白县| 永春县| 浦城县| 克山县| 灵台县| 精河县| 惠东县| 通河县| 西青区| 连平县| 普陀区| 凤庆县| 满洲里市| 太白县| 桐庐县| 资阳市| 收藏| 衢州市| 蓝山县| 临沧市| 西盟| 同心县| 城市| 莫力| 陵水| 隆德县|