驅動中訪問mtd裝置

2021-06-16 16:40:23 字數 3452 閱讀 9514

今天解決了乙個小問題,如何在linux驅動中訪問mtd裝置。

正常的訪問,都是使用者空間通過,open( /dev/mtd*, )  read(), write(), close() 來訪問的。

這次由於在驅動中需要讀取/dev/mtd4的乙個sector, 這個sector是之前用來備份sd 卡的mbr的。

1. 訪問的第一步是獲得mtd裝置,這有兩種方法:

方法1:根據mtd number, 也就是分割槽號,

函式如下:

struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)

/**

* get_mtd_device - obtain a validated handle for an mtd device

* @mtd: last known address of the required mtd device

* @num: internal device number of the required mtd device

* * given a number and null address, return the num'th entry in the device

* table, if any. given an address and num == -1, search the device table

* for a device with that address and return if it's still present. given

* both, return the num'th driver only if its address matches. return

* error code if not.

*/struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)

}} else if (num >= 0)

if (!ret)

err = __get_mtd_device(ret);

if (err)

ret = err_ptr(err);

out:

mutex_unlock(&mtd_table_mutex);

return ret;

}

原理遍歷mtd裝置表,匹配mtd號.

其中的第乙個引數可以是null。

方法2:根據mtd name, 也就是分割槽名

struct mtd_info *get_mtd_device_nm(const char *name)

/**

* get_mtd_device_nm - obtain a validated handle for an mtd device by

* device name

* @name: mtd device name to open

* * this function returns mtd device description structure in case of

* success and an error code in case of failure.

*/struct mtd_info *get_mtd_device_nm(const char *name)

}if (!mtd)

goto out_unlock;

if (!try_module_get(mtd->owner))

goto out_unlock;

if (mtd->get_device)

mtd->usecount++;

mutex_unlock(&mtd_table_mutex);

return mtd;

out_put:

module_put(mtd->owner);

out_unlock:

mutex_unlock(&mtd_table_mutex);

return err_ptr(err);

}

這是遍歷mtd裝置表,匹配分割槽名字。

2. 讀mtd分割槽操作:

根據第一部得到 mtd_info 表示的mtd裝置結構體後,可以根據這個結構體zhong的read() 函式進行讀操作:

int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);

int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);

具體的實現**如下:

unsigned char * mbrp = null;

unsigned char tmpbuf[512];

int ret;

size_t retlen;

struct mtd_info *mtd_mbr;

mbrp = tmpbuf;

mtd_mbr = get_mtd_device(null, mtd_num_mbr);

ret = mtd_mbr->read(mtd_mbr, 0x0, mbr_size, &retlen, mbrp);

if((ret != 0) || (retlen != mbr_size))

if(!msdos_magic_present(data + 510)) else

printk("and there is no backup in spi-flash, just panic now!!!\n");

}

從0x0偏移位置開始讀取mtd中的值, 度的大小是mbr_size, buffer的位址是mbrp.

ret返回值,如果讀成功返回0,讀失敗非0。

retlen是讀了多少個位元組,讀成功則返回mbr_size 個位元組,否則失敗。

這個mtd_info->read() 函式,是個函式指標,最終會呼叫到mtd晶元硬體驅動層的讀函式, 如m25p_read() 等。

msdos_magic_present() 是用來監測 mbrp[510], mbrp[511]位置上是不是 0x55, 0xaa, 這時mbr的特性決定的:

#define msdos_label_magic1      0x55

#define msdos_label_magic2 0xaa

static inline int

msdos_magic_present(unsigned char *p)

記憶體技術裝置,MTD

mtd,是linux的儲存裝置中的乙個子系統。其設計此系統的目的是,對於記憶體類的裝置,提供乙個抽象層,乙個介面,使得對於硬體驅動設計者來說,可以盡量少的去關心儲存格式,比如ftl,ffs2等,而只需要去提供最簡單的底層硬體裝置的讀 寫 擦除函式就可以了。而資料對於上層使用者來說是如何表示的,硬體驅...

linux驅動子系統 MTD

mtd是各種型別儲存裝置的抽象,是介於高層抽象和底層物理硬體之間的橋梁,它遮蔽了底層硬體的技術細節,對上層模組提供無差別的訪問控制。分析mtd部分的 就不難發現,mtd採用3層設計思路,最上面一層用於和塊裝置層對接 中間層是mtd實現,最底層是硬體驅動層。mtd下層註冊介面為mtd device r...

mtd裝置操作 jffs2

安裝mtd相關命令 手動安裝mtd utils,根據系統自行選擇 mtd交叉編譯 系統flash操作命令 cat proc mtd dev size erasesize name mtd0 00080000 00020000 boot mtd1 00100000 00020000 kernel mt...