在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

flash存儲的內容和代碼實現

Linux閱碼場 ? 來源: Linux閱碼場 ? 作者:尹忠凱 ? 2021-05-10 14:14 ? 次閱讀

文章目錄

UBI簡介

flash存儲的內容

代碼實現

將flash數據讀到內存

組織數據結構

volume & EBA子系統初始化

wear-leveling子系統初始化

UBI層操作

舉個例子

擦寫均衡

擦寫時機

擦寫條件

03 正文

UBI簡介

f8dd2160-b03c-11eb-bf61-12bb97331649.png

UBI全稱是Unsorted Block Images,上圖為UBI在系統中的層次結構,最下面是flash層(包括flash控制器,各個flash驅動代碼,spi-mem層等);MTD層是對flash層的抽象,一個flash可能被劃分成不同的分區,每一個分區都會對應一個MTD設備;UBI層是基于MTD層之上的更高層,UBI層抽象出一個個邏輯擦寫塊,每個邏輯擦寫塊都有一個物理擦寫塊與之前對應,有了這個映射,我們就可以加一些軟件算法,達到擦寫均衡的目的,從而提高flash的使用壽命;再往上是基于UBI層實現和各種文件系統,比如UBIFS。

flash存儲的內容

首先介紹幾個概念:

PEB:physical eraseblocks 也就是對應flash上的一個擦寫塊

LEB:logical eraseblocks 軟件上的概念

Volume:卷

f8eb8f34-b03c-11eb-bf61-12bb97331649.png

如上圖為flash中(或者說flash一個分區中)數據組織結構:

ubi層對flash的管理是以擦寫塊為單位的,LEB對應軟件上的概念,PEB對應flash上一個實實在在的擦寫塊,每一個LEB對應一個PEB。

往上看多個LEB可以組成一個volume,也就是說,可以根據不同的功能,將LEB劃分到不同的卷中;其中valume-layout是一個ubi內部使用的卷,用來存放該MTD設備上所劃分的各個卷的信息,其包含兩個LEB,它們存儲的內容是一樣,互為備份。

往下看每個PEB的內容包含3部分ech(erase counter header),vidh(volume identifier header),data。下面會介紹具體含義。

代碼實現

linux對UBI層的代碼實現大致可以總結為3個方面:

首先數據是存儲在flash中的,因此需要將flash中的相關信息讀到內存中,同時也可以檢查出flash中的壞塊

數據讀到內存后,需要按照內部的邏輯關系組織起來(比如將正在使用的PEB放到紅黑樹上管理起來,空閑的PEB也放到紅黑樹上管理起來)

在內存中有了這些數據的關系后,就可以對其進行操作(比如讀寫操作,volume增加,刪除,擴容等操作,擦寫均衡操作)

將flash數據讀到內存

f8fbcf8e-b03c-11eb-bf61-12bb97331649.png

UBI初始化時代碼調用流程如上圖,最終會調用scan_all() 函數, scan_all() 函數會遍歷該MTD設備

中的每一個PEB,從中讀出ech和vidh,它們的定義如下。

f915eff4-b03c-11eb-bf61-12bb97331649.png

ech的定義如上,其中:

ec:表示該PEB被擦寫的次數,借助該字段我們就能夠找出被擦寫次數最少的PEB,從而達到擦寫均衡的目的

vid_hdr_offset:表示vidh在該PEB中的偏移位置

data_offset:表示實際數據在該PEB中的偏移位置

f921ab00-b03c-11eb-bf61-12bb97331649.png

vidh的定義如上,其中:

vol_id:表示該PEB屬于那一個volume

lmun:表示LEB在volume中的編號,該字段與PEB在MTD設備中的編號形成映射關系通過對MTD設備的每個PEB進行遍歷,可以得知各個PEB的情況,或是被使用的,或是空閑狀態,或者已經損壞,這些信息會被臨時記錄在struct ubi_attach_info 結構中,遍歷過程中的具體細節,可以參考scan_all() 函數。

組織數據結構

遍歷PEB后,會將flash信息保存在臨時的結構struct ubi_attach_info 中,接下來會將struct ubi_attach_info 中的臨時信息保存到全局結構struct ubi_device *ubi_devices 中,代碼如下:

f9304db8-b03c-11eb-bf61-12bb97331649.png

分為三個步驟,分別是對volume的初始化,對wear-leveling子系統的初始化,對eba(Eraseblock Association)子系統的初始化;下面我們分別看下。

volume & EBA子系統初始化

f939f3e0-b03c-11eb-bf61-12bb97331649.png

前面有介紹到volume-layout是UBI內部使用的一個卷,其包含兩個LEB(互為備份),對應PEB中的數據內容如上圖,data(灰色)部分是一個struct ubi_vtbl_record 結構數組,記錄了當前UBI設備所有卷的信息, ubi_read_volume_table() 函數先遍歷臨時結構struct ubi_attach_info 找出volumelayout所在PEB,然后 讀出struct ubi_vtbl_record 結構數組并保存到內存中,也就是struct ubi_device 的struct ubi_volume *volumes[] 字段中,初始化后的數組結構如下圖,其中struct ubi_volume *volumes[] 是一個指針數組,數組中的每一個元素都是struct ubi_volume 結構(詳細過程見ubi_read_volume_table() 函數)。

f9442d42-b03c-11eb-bf61-12bb97331649.png

在struct ubi_volume 結構體中,有一個比較重要的字段struct ubi_eba_table *eba_tbl ,該字段記錄了當前volume中所有LEB與PEB的映射關系,其中struct ubi_eba_entry *entries 是一個數組結構,每一個元素對應一個struct ubi_eba_table 結構體, struct ubi_eba_entry *entries 數

組的下標對應于LEB的編號,數組元素的內容對應EB的編號,這樣就將LEB與PEB關聯起來了(詳細過程見ubi_eba_init() 函數)。

wear-leveling子系統初始化

在UBI中將PEB分為4種情況,正在使用、空閑狀態、需要擦除、已經損壞,各個狀態的PEB被放到不同的紅黑樹中管理。在ubi_eba_init() 函數中,會先分配一個struct ubi_wl_entry 指針數組并存儲在sruct ubi_wl_entry **lookuptbl 字段中,數組下標為PEB的編號,數組內容記錄了PEB的擦寫次

數與編號信息,每一個PEB都有一個這樣的結構與之對應如下圖。

f94dd1a8-b03c-11eb-bf61-12bb97331649.png

另外各個PEB還根據狀態放到不同的紅黑樹管理起來,上圖畫出了used, free, scrub三種狀態的紅黑樹,其中紅黑樹是以擦寫次數為順序排列的,最小的擦寫次數排列在最左邊,如果擦寫次數相同,則比較PEB的編號,編號小的排在樹的左邊,而對應的值為struct ubi_wl_entry 指針數組中的一個元素。

調用ubi_eba_init() 函數后,wear-leveling子系統也就初始化完畢,在內存中會形成上圖中的數組關系。

UBI層操作

經過前面的初始化,各個數據的結構關系已經保存在內存中了,因此UBI層的操作其實就是對內存中這些數據的操作。

f95e8890-b03c-11eb-bf61-12bb97331649.png

從用戶空間角度看,UBI初始化后會對應三類字符設備,分別為/dev/ubi_ctrl 、/dev/ubix (x = 0, 1, 2.。.), /dev/ubix_y (x = 0, 1, 2.。., y = 0, 1, 2),它們對應的操作函數如下代碼。

f96bacd2-b03c-11eb-bf61-12bb97331649.png

f979907c-b03c-11eb-bf61-12bb97331649.png

ubi_vol_cdev_operations:是針對某個volume(/dev/ubi1_0等)來操作的,從volume的角度只能看到其中包含的PEB,因此它的操作也是圍繞PEB進行的。

ubi_cdev_operations:是針對UBI設備(/deb/ubi0等)進行操作的,從UBI設備的角度可以看到不同的volume,因此可以對volume進行創建,刪除,擴容等操作。

ubi_ctrl_cdev_operations:是針對UBI層(/dev/ubi_ctrl)的操作,從該角度可以看到UBI設備,因此可以對UBI設備進行創建,刪除操作。

舉個例子

需求:假如我們想要對/dev/ubi1_0 這個volume進行擴容,我們應用怎樣操作?

用戶空間將volume_id,size兩個參數傳遞到內核空間

在內核空間我們根據volume_id在struct ubi_volume *volumes[] 數組中找到volume的handler

因為需要擴容(要分配更多的LEB),所以要重新分配struct ubi_eba_table *eba_tbl 數組,并將舊數組中的數據拷貝到新數組中

對于新增的LEB,我們需要從free樹上申請,建立LEB到PEB的映射關系并保存到struct ubi_eba_table *eba_tbl 數組,另外還需要更新PEB中ech和vidh,表明該PEB屬于那個volume

上面這一系列操作是我自己的想法,并非kernel實現代碼(具體實現可以參數ubi_cdev_ioctl() 函數)。這里想表達的意思是,在UBI初始化完成后,在內存中已經存在了各個volume,各個LEB/PEB之間的關系,因此對于UBI的操作,理論上我們是都可以完成的,所差的只是代碼實現;程序=算法+數組結構,這里的數組結構已經有了,而算法就是UBI層的各種操作,這里的代碼其實每個人都可以實現的,只不過有好有壞,所幸kernel已經幫我們實現了,我們可以參考學習。其實別人寫的文章只能提供個大概,真正的細節只有在源碼中才能獲得。

擦寫均衡

flash的擦寫塊都是有壽命限制的,如果頻繁的擦寫flash的某一個PEB,很快這個PEB就會損壞,而擦寫均衡的目的就是將擦除操作平均分配到整個flash,這樣就能提高flash的使用壽命。那怎樣將擦除操作平均分配到整個flash呢,要達到這個條件還是有些難度的,因此我們退一步,將條件修改為PEB的最大擦寫次數與最小次數的的差值小于某個值。

f9d86a52-b03c-11eb-bf61-12bb97331649.png

比如flash中包含20個PEB,其中數字表示該PEB被擦寫的次數,我們約定擦寫次數的差值最大為15,現在flash中PEB的最小與最大擦寫次數分別為10、39,由于超過門限值,因此需要我們想一些方法,增加擦寫次數為10的PEB被擦寫的機會,減少擦寫次數為39的PEB被擦寫的機會,從而使整個flash的擦寫次數趨于平均。具體的實現后面會介紹。

擦寫時機

linux kernel會在下面兩個位置調用擦寫均衡:

wear-leveling子系統初始化完成時會檢查一次是否需要擦寫均衡,此時是一個初始狀態,是檢查的一個時機。

當要擦除某個PEB的時候,此時擦寫次數會增加,有可能達到擦寫均衡的要求,此時也是一個檢查的時機。

擦寫條件

除了上面的調用時機,擦寫均衡還有一些其它的條件限制,如下圖為擦寫均衡的流程圖:

f9f1deba-b03c-11eb-bf61-12bb97331649.png

當scrub紅黑樹上有節點時,一定需要進行擦寫均衡。在遍歷flash的每個PEB時,如果發現在從flash中讀出的數據有位翻轉的情況,就會加上scrub標志,并放到scrub紅黑樹上維護起來,表示該PEB需要被擦寫;在擦寫均衡時,先取出scrub樹最左邊節點e1,再從free樹中找一個合適的節點e2,然后讀取e1對應PEB的數據,如果讀取的數據還有問題,就會結束本次擦寫;如果沒有問題就會把e1數據copy到e2位置,并擦除e1數據完成本次擦寫均衡操作。

當scrub樹上沒有節點時,會從used樹上取出最左邊節點e1,并從free樹上找一個合適的節點e2,然后檢查e2與e1的PEB擦寫次數的差值是否大于門限值,如果大于,則將e1數據copy到e2位置并擦除e1數據完成本次擦寫。為什么這樣做,原因是used樹中的節點已經被初始化過(先整個擦除,然后寫入ech和vidh,后面再寫入數據也不需要擦寫)所以不會有擦除操作,在free樹上的節點,在被使用前需要擦除一次,所以把擦寫次數大的PEB放到used樹上減少被擦寫的機會,把擦寫次數小的節點放到free樹上增加被擦寫的機會,這樣就達到了擦寫均衡的目的。

另外在free樹上選擇一個合適的節點,什么是適合和節點?最簡單的方法就是從free樹的最右邊拿一上節點(擦寫次數最大的節點),然后與used樹上取下的最左邊的節點比較,看看差值是否超過門限值。但實際情況可能會更復雜些,如下代碼29行,是kernel中在free樹上選擇節點的方法,其限制了最大擦寫次數為free樹最左側節點 + WL_FREE_MAX_DIFF,看上面的注釋說在某些情況下會出現不斷擦寫某一個或幾個PEB的情況,所以作了這樣一個限制。(沒有想道是什么情況)

fa1d997e-b03c-11eb-bf61-12bb97331649.png

fa2f68ac-b03c-11eb-bf61-12bb97331649.png

原文標題:尹忠凱: 針對Flash的Linux UBI子系統代碼深度分析

文章出處:【微信公眾號:Linuxer】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FlaSh
    +關注

    關注

    10

    文章

    1672

    瀏覽量

    151219
  • 存儲
    +關注

    關注

    13

    文章

    4510

    瀏覽量

    87188

原文標題:尹忠凱: 針對Flash的Linux UBI子系統代碼深度分析

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦
    熱點推薦

    第二十九章 讀寫內部FLASH

    本文介紹了W55MH32內部FLASH,其含主存儲、系統存儲等,可存儲代碼及掉電保存數據。讀寫需解鎖、擦除頁等步驟,標準庫提供相關函數。還展
    的頭像 發表于 06-20 14:09 ?376次閱讀
    第二十九章 讀寫內部<b class='flag-5'>FLASH</b>

    MCU片上Flash

    ? ? MCU片上Flash是微控制器內部集成的非易失性存儲器,主要用于存儲程序代碼、常量數據及系統配置信息。其核心特性與功能如下: 一、定義與類型? 片上
    的頭像 發表于 05-06 14:26 ?246次閱讀

    調試時Memory窗口中Flash內容不更新的原因和解決辦法

    調試時在代碼中對Flash進行寫操作時(比如Bootloader對Code Flash進行升級操作,Application對Data Flash進行寫操作),Memory窗口中
    的頭像 發表于 04-01 09:18 ?414次閱讀
    調試時Memory窗口中<b class='flag-5'>Flash</b><b class='flag-5'>內容</b>不更新的原因和解決辦法

    存儲技術探秘 NAND Flash vs NOR Flash:藏在芯片里的&quot;門道之爭&quot;

    門電路玄機 NOR Flash:Intel 1988 年革命性突破,終結 EPROM/EEPROM 壟斷時代 NAND Flash:東芝 1989 年發布,開創 "低成本比特" 存儲新紀元 共性特征
    的頭像 發表于 03-18 12:06 ?440次閱讀

    NAND Flash與SD NAND的存儲扇區架構差異

    NAND Flash?和?SD卡(SD NAND)的存儲扇區分配表都是用于管理存儲設備中扇區的分配信息。它們記錄了哪些扇區已被使用、哪些是空閑的,以及文件或數據與扇區的對應關系,以便實現
    的頭像 發表于 03-13 15:20 ?1049次閱讀
    NAND <b class='flag-5'>Flash</b>與SD NAND的<b class='flag-5'>存儲</b>扇區架構差異

    stm32f407的flash內容沒有做任何事情,但是它的內容改變了,為什么?

    我的一個程序使用IAP。該應用程序從0x8020000開始。在應用程序正常工作一段時間后,應用程序將無法運行。我查看了不正常運行時FLASH內容,并將其與正常運行時FLASH內容
    發表于 03-07 07:52

    【半導體存儲】關于NAND Flash的一些小知識

    保存代碼及數據,分為閃型存儲器 (Flash Memory)與只讀存儲器(Read-OnlyMemory),其中閃型存儲器是主流,而閃型
    發表于 12-17 17:34

    Flash語音芯片相比OTP語音芯片的優勢

    ?。 1?.可重復擦寫?:Flash語音芯片的最大特點是支持多次編程和擦除,這意味著用戶可以根據需要隨時更新語音內容,實現定制化和靈活的語音交互。相比之下,OTP語音芯片只能編程一次,無法更改
    的頭像 發表于 12-16 15:44 ?469次閱讀

    基于NXP MCXA153 MCU實現RT-Thread的MTD NOR Flash驅動

    在嵌入式系統中,片上Flash存儲器是一個關鍵組件,用于存儲程序代碼和關鍵數據。本文將詳細介紹如何在NXPMCXA153 MCU上實現RT-
    的頭像 發表于 11-09 14:00 ?1090次閱讀
    基于NXP MCXA153 MCU<b class='flag-5'>實現</b>RT-Thread的MTD NOR <b class='flag-5'>Flash</b>驅動

    鐵電存儲器和Flash的區別

    鐵電存儲器(Ferroelectric RAM, FRAM)與閃存(Flash)是兩種不同類型的非易失性存儲器,它們在工作原理、性能特點、應用場景等方面存在顯著的差異。
    的頭像 發表于 09-29 15:25 ?3054次閱讀

    物聯網行業存儲方案詳解_SPI NOR Flash

    SPI NOR FLASH存儲器在初始響應和啟動時提供高可靠性,并具有低時延。這一特性對于物聯網設備至關重要,因為物聯網設備通常需要快速啟動并穩定運行,以確保數據的實時傳輸和處理。 2、直接執行代碼的能力 SPI NOR
    的頭像 發表于 09-24 14:39 ?1027次閱讀
    物聯網行業<b class='flag-5'>存儲</b>方案詳解_SPI NOR <b class='flag-5'>Flash</b>

    NAND Flash與其他類型存儲器的區別

    NAND Flash作為一種基于NAND技術的非易失性存儲器,具有多個顯著優點,這些優點使其在數據存儲領域得到了廣泛應用。以下是對NAND Flash優點的詳細闡述,并簡要探討與其他類
    的頭像 發表于 08-20 10:24 ?1264次閱讀

    NAND Flash與NOR Flash:壞塊管理需求的差異解析

    NOR Flash和NAND Flash是兩種不同類型的閃存技術,它們在存儲單元的連接方式、耐用性、壞塊管理等方面存在差異。
    的頭像 發表于 07-10 14:25 ?3197次閱讀
    NAND <b class='flag-5'>Flash</b>與NOR <b class='flag-5'>Flash</b>:壞塊管理需求的差異解析

    云安全服務加密存儲代碼怎么查

    云安全服務加密存儲代碼的查詢與實現是一個復雜的過程,涉及到多個方面,包括數據加密、密鑰管理、訪問控制等。 1. 引言 隨著云計算的快速發展,越來越多的企業和個人將數據存儲在云端。然而,
    的頭像 發表于 07-02 09:28 ?691次閱讀

    加速科技Flash存儲測試解決方案 全面保障數據存儲可靠性

    Flash存儲芯片? 現代電子設備的核心數據存儲守護者 Flash存儲芯片是一種關鍵的非易失性存儲
    的頭像 發表于 06-26 18:25 ?1238次閱讀
    加速科技<b class='flag-5'>Flash</b><b class='flag-5'>存儲</b>測試解決方案 全面保障數據<b class='flag-5'>存儲</b>可靠性
    主站蜘蛛池模板: 黄色网址在线免费观看 | 波多野结衣在线观看一区 | 欧美精彩狠狠色丁香婷婷 | 2021国产精品自在拍在线播放 | 日本黄色免费在线观看 | 狠色网 | 在线你懂得 | 欧美一区二区视频三区 | 人人操天天射 | 午夜视频网址 | 日本人zzzwww色视频 | 欧美伊人久久大香线蕉综合69 | 狂野欧美激情性xxxx | 国产三级日本三级韩国三级在线观看 | 国产最好的精华液网站 | 韩国床戏合集三小时hd中字 | 午夜精品一区二区三区在线观看 | 女bbbbxxxx另类亚洲 | 成人在线观看网站 | 日韩在线三级视频 | 国产香蕉精品视频在 | 亚洲qingse中文在线 | 韩国中文字幕在线观看 | 性欧美视频videos6一9 | 欧美黑人巨大日本人又爽又色 | 国产性夜夜春夜夜爽 | dy888午夜秋霞影院不卡 | 伊人久久大香线蕉综合影 | 奇米狠狠干 | aaa一级最新毛片 | 欧美成人鲁丝片在线观看 | h视频在线观看网站 | 夜夜爽夜夜爽 | 欧美色香蕉 | 亚洲国产精品久久久久婷婷软件 | 国产精品毛片一区二区三区 | 人人做人人爽国产视 | 磁力bt种子搜索在线 | 色老头久久久久久久久久 | 美女很黄很黄是免费的·无遮挡网站 | www.四虎|