今天解決了乙個小問題,如何在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)
原理遍歷mtd裝置表,匹配mtd號./**
* 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;
}
其中的第乙個引數可以是null。
方法2:根據mtd name, 也就是分割槽名
struct mtd_info *get_mtd_device_nm(const char *name)
這是遍歷mtd裝置表,匹配分割槽名字。/**
* 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);
}
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);
具體的實現**如下:
從0x0偏移位置開始讀取mtd中的值, 度的大小是mbr_size, buffer的位址是mbrp.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");
}
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...