亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 服務器 > Linux服務器 > 正文

高手進階 Linux系統下MTD/CFI驅動介紹

2024-09-05 23:01:36
字體:
來源:轉載
供稿:網友

因為前不久作了些關于FLASH編程方面的東西,加上看了Linux下MTD/CFI代碼,感覺收獲不小,就準備記個筆記,沒想到竟然花了半天時間才寫好。

  某些Intel的FLASH芯片(如StrataFlash系列)支持多分區,也就是各個分區可以同時進行操作。應該說這是不錯的特性,但是也會帶來些問題。記得當初移植Linux-2.4.21,掛JFFS2文件系統的時候,經常會報一些"Magic bitmask not found"之類的錯誤,跟進去發現FLASH讀出來的都是些0x80之類的數據,查看資料發現該款FLASH有分區的特性,而Linux的FLASH驅動只用一個狀態變量表示整個FLASH的狀態,這就會造成某個分區的實際狀態和系統記錄的不符,從而導致讀FLASH的時候該點實際上不處在讀狀態。當時的解決辦法是,每次讀的時候,不管記錄的狀態是什么,先進入讀狀態再說,當然這會帶來性能的下降,具體損失多少個時鐘周期就不算了。

   話說進入Linux-2.6.x的時代(具體是2.6.13),除了Lock/Unlock(Linux在擦/寫的時候不先Unlock,解決辦法就是初始化的時候先全部Unlock)這個老問題外,竟然多分區的錯誤沒有出現,驚訝之下決定好好研究下Linux的MTD/FLASH驅動。

  說驅動之前,先明確幾個編程要點:

  1:讀寫,要按照總線位寬讀寫,注意不是FLASH芯片位寬(例如背靠背)。

  2:尋址,程序要訪問的地址和FLASH芯片地址引腳得到的值是不一樣的,例如16位的FLASH芯片,對于CPU,0x00和0x01表示2個不同的字節,但是到了FLASH引腳得到的都是0,也就是都指向FLASH的第一個WORD??梢哉J為地址總線的bit0懸空,或者認為轉換總線, bit0上實際輸出的是bit1。這個解釋了要點1。

  3:芯片手冊提到偏移量都是基于WORD的,而WORD的位寬取決于芯片的位寬,因此在下命令的時候,實際偏移=手冊偏移*buswidth/8。

  4:芯片手冊提到的變量長度(典型如CFI信息)例如2,指的是,變量是個16bit數,但是讀的時候,要讀2個WORD,然后把每個WORD的低8位拼成1個16bit數。讀WORD再拼湊確實挺麻煩,尤其是讀取大結構的時候,不過參照cfi_util.c的cfi_read_pri函數的做法就簡單了。

  5:背靠背,也就是比方說2塊16位的芯片一起接在32位的總線上。帶來的就是尋址的問題,很顯然,首先要按32位讀寫;其次就是下命令的地址,實際偏移=手冊偏移*interleave*device_type/8,device_type=buswidth/interleave,而buswidth這個時候是32(總線位寬)。另外就是背靠背的時候,命令和返回的狀態碼是“雙份的”,例如2塊16位背靠背,讀命令是0x00ff00ff。

  如果不是想寫像Linux那么靈活的代碼(考慮各種接法/位寬/CFI獲取信息等),那事情就簡單很多,只要考慮要點1以及擦除塊的大小就好了,當然如果是背靠背接法,擦除塊的實際大小要乘個interleave。

  下面就進入Linux代碼,不過關于CHIP/MAP/MTD之間繞來繞去的關系現在還糊涂著呢,因此下面只是簡單的跟一下脈絡和各個編程要點。

  1:構造map_info結構,指定基址/位寬/大小等信息以及"cfi_probe"限定,然后調用do_map_probe()。

  2:do_map_probe()根據名字"cfi_probe"找到芯片驅動"cfi_probe.c"直接調用cfi_probe()。

  3:cfi_probe()直接調用mtd_do_chip_probe(),傳入cfi_probe_chip()函數指針。

  4:mtd_do_chip_probe()分2步,先調用genprobe_ident_chips()探測芯片信息,后調用check_cmd_set()獲取和初始化芯片命令集(多分區初始化就在里面)。

  5:genprobe_ident_chips()函數如果不考慮多芯片串連的情況,那只需看前面的genprobe_new_chip()調用,完成后cfi.chipshift=cfi.cfiq->DevSize,2^chipshift=FLASH大小。

  6:genprobe_new_chip()枚舉各種不同的芯片位寬和背靠背數量,結合配置設定依次調用步驟3的cfi_probe_chip(),注意cfi->device_type=bankwidth/nr_chips,bankwidth是總線位寬,device_type是芯片位寬。這里我們只需要注意有限復雜情況即可,所謂有限復雜指的是編譯時確定的復雜連接。這樣,cfi_probe_chip()只有第1次調用才成功,如果考慮32位寬的FLASH插在16bit總線上的情況,那第2次調用成功。

  7:cfi_probe_chip(),由于步驟6的原因,函數就在cfi_chip_setup()直接返回,后面的代碼就不用考慮了。

  8:cfi_chip_setup()讀取CFI信息,可以留意下Linux是怎么實現要點4的。

  9:回到步驟4的check_cmd_set()階段,進入cfi_cmdset_0001()函數,先調用read_pri_intelext()讀取Intel的擴展信息,然后調用cfi_intelext_setup()初始化自身結構。

  10:read_pri_intelext()函數,可以留意下怎么讀取變長結構的技巧,也就是"need_more"的用法。這里說明下一些變量的含義,例如對于StrataFlash 128Mb Bottom類型的的FLASH芯片,塊結構是4*32KB+127*128KB=16MB,一共16個分區,每個分區1MB。nb_parts=2。

  第1部分

  NumIdentPartitions=1 // 有1個重復的分區

  NumBlockTypes=2      // 分區內有2種不同的Block類型

  第1類型

  NumIdentBlocks=3   // 有4個Block(3+1)

  BlockSize=0x80     // 32KB(0x80*256)

  第2類型

  NumIdentBlocks=6   // 有7個Block(6+1)

  BlockSize=0x200    // 128KB(0x200*256)

  第2部分

  NumIdentPartitions=15// 有15個重復的分區
  NumBlockTypes=1      // 分區內有1種Block類型

  第1類型

  NumIdentBlocks=7   // 有8個Block(7+1)

  BlockSize=0x200    // 128KB(0x200*256)

  11:cfi_intelext_setup()函數首先根據CFI建立mtd_erase_region_info信息,然后調用cfi_intelext_partition_fixup()來支持分區。

  12:cfi_intelext_partition_fixup()用來建立虛擬Chip,每個分區對應1個Chip,不過并沒有完全根據CFI擴展信息來建立,而是假定每個分區的大小都一致。cfi->chipshift調整為partshift,各個虛擬chip->start調整為各分區的基址。將來訪問FLASH的入口函數cfi_varsize_frob()就根據ofs得到chipnum(chipnum=ofs>>cfi->chipshift),這也是為什么要假定分區一致的原因。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91av网站在线播放| 26uuu另类亚洲欧美日本老年| 中文字幕日韩免费视频| 在线精品视频视频中文字幕| 91久久久亚洲精品| 日韩在线观看免费高清| 国产欧美日韩精品丝袜高跟鞋| 欧美激情综合亚洲一二区| 亚洲天堂av图片| 成人乱色短篇合集| 久久久亚洲精选| 欧美巨大黑人极品精男| 亚洲三级免费看| 97久久精品人人澡人人爽缅北| 国产一区二区精品丝袜| 国产91色在线免费| 国产精品99久久久久久久久久久久| 91视频免费网站| 日韩精品视频免费在线观看| 国内精品久久久久久| 亚洲精品自产拍| 日本中文字幕久久看| 亚洲激情自拍图| 亚洲成**性毛茸茸| 国产精品久久久久77777| 国产香蕉一区二区三区在线视频| 欧美成人自拍视频| xxx成人少妇69| 国产精品极品美女粉嫩高清在线| www高清在线视频日韩欧美| 久久久亚洲网站| 国产成人av网址| 91亚洲精品一区| 欧美亚洲在线观看| 国产欧美一区二区| 最近日韩中文字幕中文| 亚洲欧美日韩一区在线| 欧美一区二三区| 久久99视频免费| 国产成人小视频在线观看| 欧美黑人一级爽快片淫片高清| 亚洲电影天堂av| 国产精品永久免费在线| 欧洲午夜精品久久久| 中文字幕日韩av综合精品| 欧美大人香蕉在线| 亚洲欧美日韩在线高清直播| 久久久午夜视频| 视频在线观看一区二区| 日韩欧美极品在线观看| 狠狠色噜噜狠狠狠狠97| 亚洲综合精品伊人久久| 欧美另类xxx| 亚洲国产成人精品久久久国产成人一区| 理论片在线不卡免费观看| 日韩欧美一区二区三区久久| 精品国产一区二区三区久久久狼| 欧洲美女7788成人免费视频| 亚洲精品97久久| 国产97人人超碰caoprom| 在线观看精品自拍私拍| 久久久久久这里只有精品| 91精品国产成人www| 亚洲第一精品夜夜躁人人躁| 成人国产精品av| 欧美噜噜久久久xxx| 亚洲人精选亚洲人成在线| 国产日韩欧美日韩| 亚洲精品美女视频| 亚洲成人国产精品| 日韩精品视频在线免费观看| 日韩av中文字幕在线播放| 日韩成人中文字幕| 久久夜精品va视频免费观看| 欧美一级片在线播放| 日韩av一卡二卡| www国产亚洲精品久久网站| 精品激情国产视频| 欧美激情第三页| 国产欧美va欧美va香蕉在| 国产成人aa精品一区在线播放| 欧美华人在线视频| 欧美日韩视频在线| 国产亚洲欧美日韩一区二区| 国产成人精品电影| 成人免费自拍视频| 欧美亚洲激情在线| 精品一区二区电影| 欧美精品午夜视频| 国产精品91久久久久久| 欧美福利视频在线观看| 91成人福利在线| 亚洲色图偷窥自拍| 91麻豆国产语对白在线观看| 日韩va亚洲va欧洲va国产| 欧美一级大胆视频| 日韩在线观看高清| 欧美在线视频一区二区| 欧美二区在线播放| 久久精品一偷一偷国产| 成人两性免费视频| 在线看国产精品| 九九精品视频在线观看| 丝袜情趣国产精品| 国产精品999999| 国产成人综合亚洲| 国产精品白嫩初高中害羞小美女| 国产精品av免费在线观看| 亚洲社区在线观看| 91日本视频在线| 91精品国产乱码久久久久久久久| 国产精品久久一区主播| 久久久精品视频成人| 国产精品一区二区久久精品| 97色在线观看免费视频| 国产成人av在线| 亚洲欧美色图片| 亚洲天堂免费视频| 亚洲激情免费观看| 欧美一区深夜视频| 色综合久久精品亚洲国产| 欧美成人免费在线观看| 欧美特黄级在线| 色婷婷综合成人av| 中文字幕精品在线| 欧美精品18videos性欧| 欧美激情高清视频| 日韩中文字幕视频在线| 国产精品久久久久久久久免费看| 国产精品第100页| 欧美日韩一区免费| 欧美裸身视频免费观看| 亚洲精品一区二区网址| 国产精品视频精品视频| 国产999精品久久久影片官网| 欧美性猛交xxxx偷拍洗澡| 九九热99久久久国产盗摄| 日韩高清电影免费观看完整| 欧美一区二区三区免费视| 国产不卡在线观看| 九九久久综合网站| 欧美另类在线播放| 777精品视频| 久久久久久91| 亚洲欧美中文在线视频| 国产精品www| 91精品久久久久久久久青青| 中文字幕精品国产| 国产成人精品国内自产拍免费看| 国产大片精品免费永久看nba| 欧美亚洲免费电影| 精品日韩视频在线观看| 亚洲а∨天堂久久精品9966| 国产精品一区二区三区久久久| 国产精品91久久久| 3344国产精品免费看| 97在线看免费观看视频在线观看| 久久精品一偷一偷国产| 国产精品久久久久久久久粉嫩av| 久久久久久久久久久免费精品| 最近2019年中文视频免费在线观看| 欧美日韩在线一区| 久久韩剧网电视剧| 91久久久精品|