Linux mtd子系統專欄分析之三 MTD層相關接口說明(註冊與註銷等)

       原文再續,書接上回。在上篇文章中,我們介紹了mtd層相關數據結構以及接口的關聯,並簡要說明了mtd層與vfs、文件系統層、閃存芯片驅動層的關聯,本篇文章主要介紹mtd層相關的接口,這些接口用於實現這些數據結構的關聯與解綁。

 

本篇文章的主要內容如下:

 

  1. mtd設備相關的註冊與註銷接口說明
  2. Mtd info master與slave的區別
  3. 如何進行分區設置操作
  4. 如何實現將一個閃存芯片註冊至mtd子系統中。

 

 

一、mtd設備相關的註冊與註銷接口

按照上一篇文章的分析,針對mtd設備相關的註冊,主要包括如下幾個方面:

  1. 提供mtd設備註冊的接口,完成mtd info設備註冊至設備驅動模型子系統中,並完成mtd字符設備與mtd塊設備的創建(從而完成mtd info與設備驅動子系統、vfs子系統的關聯);
  2. 若閃存設備支持分區,則提供分區註冊接口,主要完成每一個分區對應的mtd_info設備註冊至設備驅動模型子系統中;並將每一個分區對應的mtd_part類型的變量註冊至鏈表mtd_partitions中;

 

基本上也就以上兩個功能,而在mtd子系統中,針對註冊的接口即爲mtd_device_parse_register,而在

該接口中,則根據是否進行分區,分別調用add_mtd_partitions、add_mtd_device的註冊。

 

mtd_device_parse_register接口分析

      該接口主要實現將mtd_info設備註冊到mtd子系統中。由於閃存設備可以選擇分區,也可以選擇不分區,因此該接口包括這兩個功能。該接口的實現如下,還包括parse_mtd_partitions接口,該接口主要是解析分區信息的配置。該接口實現較簡單,不再細說。

 

 

     若一個閃存芯片,在註冊至mtd子系統中時,不需要進行分區,則只需要使用接口add_mtd_device即可,下面我們對該接口進行分析。

 

add_mtd_device接口

該接口的處理流程如下圖所示(省略了異常處理),其主要實現如下功能:

  1. 設置mtd_info相關的信息,包括writesize_shift等;另外針對設置了可寫信息且上電時鎖定芯片的mtd設備,需要執行unlock操作(在某些場景下,我們做flash的設計時,可以讓硬件設計人員將wp引腳默認爲有效,用於保證系統上電時可能導致的寫異常。然後在驅動中再將wp引腳關閉即可,而mtd子系統支持該功能,只需要實現mtd_info中_unlock成員函數指針即可);
  2. 設置該mtd_info所包含的device類型成員的信息,主要設置其所屬的class以及其device_type信息

關於device、class相關的關聯我們在之前的設備驅動模型系列文章中已經說明;而在mtd_devtype中則主要定義了mtd_info設備的註銷信息。如下爲device_ktype中的release和device_type的release接口的關係,當mtd_info的引用計數爲0時,則會調用device_ktype的release接口,最終則調用mtd_release進行釋放操作。

 

 

 

  1. 調用device_register,進行mtd_info對應device類型變量的設備註冊,而在註冊中會嚮應用層發送uevent信息(藉助netlink),然後應用層的mdev/udev程序接收到uevent信息,根據設備號會進行字符設備與塊設備對應inode節點的創建(調用mknod),至此即完成該mtd_info對應的字符設備與塊設備文件的創建;

 

 

add_mtd_partitions

該接口主要針對需要對註冊設備進行分區的情況,該接口主要實現兩個功能:

  1. 針對每一個分區,均創建一個mtd_part類型的變量,該變量包括master mtd_info以及該分區對應的mtd_info,並初始化該分區對應slave mtd_info,而針對slave mtd_info,其上層接口主要爲分區相關的接口,該接口主要會調用master mtd_info對應的接口。針對master mtd_info、slave mtd_info的關聯,在下面分析。
  2. 針對每一個分區,將其mtd_part中的slave mtd_info調用add_mtd_device,將其註冊至mtd子系統中。

該接口的代碼實現如下,邏輯流程簡單,不再贅述。

 

 

       Mtd_info的註銷接口爲mtd_device_unregister,該接口主要是實現mtd_info的註銷操作,其實主要就是調用device_unregister進行mtd_info對應device類型設備的註銷,同時若爲分區設備,則將其從mtd_partitions鏈表上刪除等。

 

 

Mtd info master與slaver的區別

在上一篇文件介紹mtd_info與上下層子系統的關聯時,沒有詳細說明master 與slaver mtd_info的關聯,下面具體說明下。主要包括如下幾點:

  1. 一個master mtd_info對應一個閃存設備;
  2. 一個slaver mtd_info對應一個閃存設備的邏輯分區(若沒有邏輯分區,則不存在該變量)
  3. 若一個閃存設備沒有進行邏輯分區,則會將該master mtd_info註冊至mtd子系統中,並創建一個master mtd_info對應的字符設備、塊設備;
  4. 若一個閃存設備進行邏輯分區,則每一個邏輯分區對應的slaver mtd_info均註冊至mtd子系統中,並創建該slaver mtd_info對應的字符設備與塊設備,而master mtd_info不註冊至mtd子系統中;此時slaver mtd_info並沒有實現對芯片驅動的訪問接口,而對下層閃存芯片驅動的訪問接口還是由master mtd_info中的接口實現訪問操作;而slaver mtd_info中的接口主要即是對master mtd_info的簡單封裝而已。還需要將每一個邏輯分區對應的mtd_part變量註冊至mtd_partitions鏈表中。

如下圖是邏輯關聯圖,當沒有邏輯分區時,則mtd接口層通過黃色箭頭調用master mtd_info中的接口完成對下層閃存芯片的訪問;當存在邏輯分區時,則mtd接口層通過藍色接口藉助slaver mtd_info,間接調用master mtd_info的接口完成對下層閃存芯片的訪問。

 

 

 

如何進行分區設置操作

針對閃存芯片邏輯分區的設置,主要包括兩種:

  1. 若linux內核不支持設備樹,則定義struct mtd_partition類型的變量即可(可以在板級文件中定義,並將其作爲platform 的device的參數傳遞,然後在閃存芯片或閃存芯片控制器的驅動接口中解析該參數即可);
  2. 若linux內核支持設備樹,則只需要在設備樹文件中,增加分區信息即可;

當我們進行邏輯分區時,可設置分區屬性爲只讀,這樣在linux內核下則不會修改該分區(這只是邏輯實現只讀屬性,若想決定只讀則可使用wp引腳設置寫保護)

 

如何實現將一個閃存芯片註冊至mtd子系統中

  1. 在閃存對應驅動的probe接口中,完成針對master mtd_info變量的初始化,包括參數以及接口的設置,並完成設置master mtd_info的priv成員指針指向該芯片驅動對應的結構體變量(包含了針對該閃存芯片參數及訪問接口等信息);
  2. 調用mtd_device_parse_register接口,完成對該芯片邏輯分區註冊至mtd子系統中。

針對系統中nor flash驅動、nandflash驅動、spi flash驅動(如m25p80驅動)等驅動模型,均是通過這兩步完成註冊的。

 

 

本篇文章主要說明mtd子系統的註冊與註銷以及一些概念的說明,下一篇文章說明nandflash框架。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章