u-boot1.1.6 nand_legacy
驅動提供了
u-boot
對nand
相關命令的乙個輕量級的實現,但好象可擴充套件性不足。本文主要分析
u-boot 1.16/drivers/nand
資料夾下的源程式。
該結構在
include/linux/mtd/mtd.h
中定義,字段比較多,有很多還是函式指標,它是
mtd裝置操作的通用介面,這個結構中有乙個比較重要的成員
void *priv
,priv
被宣告成
void
指標,在下文的分析中會知道
priv
實際上指向了
nand_chip
結構。該結構在
include/linux/mtd/nand.h
中定義,從名字上看就知道
u-boot
用它來描述
nand flash
晶元的結構,比如它定義了頁位址的偏移,頁位址的位掩碼等。
struct nand_chip
不用我們手動的初始化,而是由另外乙個結構,
struct nand_flash_dev
在程式中動態的初始化。
該結構的定義有兩處地方分別是
①include/linux/mtd/nand_legacy.h
由nand_legacy
模組使用
②include/linux/mtd/nand.h
由u-boot
通用nand
架構使用
特別是在移植的時候要小心把兩者混淆。我們先來看看改結構的定義
struct nand_flash_dev ;
name : nand flash
名稱id : u-boot
內部id
編號???
chipsize : 以mb
為單位的晶元大小,比如64(
m)erasesize :
擦除塊的大小,比如
0x4000
(16k
)options :
一些選項,比較重要的是
flash
的資料位寬,如果你的
nand flash是16
位寬的,則必須包含
nand_buswidth_16
選項。我們必須根據所使用的
nand flash
來填充裡面的字段。
struct nand_info_t nand_info[ cfg_max_nand_device ];
在drivers/nand/nand.c
中定義。
cfg_max_nand_device
是板子的
nand flash
晶元的數量必須在板子的配置檔案中定義(比如
include/configs/smdk2410.h
)。static struct nand_chip nand_chip[cfg_max_nand_device];
在drivers/nand/nand.c
中定義。
cfg_max_nand_device
的定義同上。
struct nand_flash_dev nand_flash_ids = ;
在drivers/nand/nand_ids.c
中定義。這裡要注意一點,在
include/linux/mtd/nand_ids.h
裡面也nand_flash_ids
的定義,那是由
nand legacy
驅動模組使用的。兩者不能混淆
!!!。在
nand_flash_ids
的定義中我找到了適合我的
nand flash
的結構描述:
裝置id為
0x76
,頁大小為
512byte
,總的容量為
64m,擦除塊為
0x4000
(16k
),資料位寬
8bit
。如果你的
nand flash
沒有合適的描述,需要自己在該陣列中新增相應的定義。
nand_init
函式在lib_***/board.c
的start_armboot
中呼叫。是
u-boot nand
的主函式。
nand_init
的主要功能是對
cfg_max_nand_device
個nand
裝置進行初始化(呼叫
nand_init_chip),
累加nand flash
的總大小。在
nand_init
結束時,可以配置是否執行
board_nand_select_device,
選擇nand
晶元。static void nand_init_chip
(struct mtd_info *mtd, struct nand_chip *nand, ulong base_addr
)呼叫各個開發板提供的
board_nand_init
函式(board//.c
)讓開發板獲得初始化
nand flash
晶元的機會。呼叫
nand_scan
。int nand_scan( struct mtd_info *mtd, int maxchips )
這是u-boot
初始化nand
裝置的核心函式。它主要完成以下工作
1)初始化
nand_chip
的函式指標,這些函式一般在
board//.c
中定義。
…struct nand_chip *this = mtd->priv
....
if( this-> cmdfunc == null )
this->cmdfunc = nand_command;
…上面是初始化
nand_chip
中cmdfunc
指標的**,如果在
board_init_nand
中開發板沒有提供自己的
nand_command
函式,u-boot
將使用預設的
nand_command
函式(我覺得
u-boot
提供的這些預設的函式都不適合特定的硬體,所以很多都要自己重新寫)。
2)使用上面註冊的函式指標,讀取
nand flash
的裝置,並且在上文提到的
nand_flash_ids
中找是否有匹配項,若找到匹配的項,則初始化
nand_chip
和mtd_info
,它們的初始化**老長的一段,一般沒什麼問題。
函式呼叫層次
:(如下圖)。
以common/env_nand.c
裡面讀取
nand flash
中的環境變數為例
common/env_nand.c
ret = nand_read( &nand_info[0], cfg_env_offset, &total, (u_char*)env_ptr );
nand_info
就是我們在
1.4講到的
nand_info_t
(mtd_info
的別名)陣列。此處的
nand_read
是個inline
函式,下面是它的實現:
include/nand.h
static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf)
可以看出
nand_read
實際上呼叫的是
nand_info
的read
方法。nand_info
的read
方法是在
2.3中講到的
nand_scan
中初始化
drivers/nand/nand_base.c
int nand_scan(struct mtd_info *mtd, int machips)
此處又乙個
nand_read
!!!drivers/nand/nand_base.c
static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
又一層包裝
!!!
drivers/nand/nand_base.c
static int nand_read_ecc(…)
終於到達最後一層了,
nand_read_ecc
通過呼叫
nand_chip
裡面提供的函式對
nand flash
完成讀的操作。具體可以看看**,老長的一段。
debian支援ll命令
debian支援ll命令 ll bash ll command not found 沒有ll這個命令,雖然也知道ll其實 是ls l 這個命令的別名,但是總感覺不是很習慣,因為之前一直用centos的。如果想讓debian也支援 ll 命令的話則需要修改使用者目錄下面的.bashrc 配置檔案 cd...
debian支援ll命令
debian支援ll命令 ll bash ll command not found 沒有ll這個命令,雖然也知道ll其實 是ls l 這個命令的別名,但是總感覺不是很習慣,因為之前一直用centos的。如果想讓debian也支援 ll 命令的話則需要修改使用者目錄下面的.bashrc 配置檔案 cd...
windows git支援arc命令
本文整理了在windows系統上安裝 審查工具arcanist的過程。目的是配合phabricator進行 review。配置成功後可使用arc diff命令來發起code review。1.安裝php環 在命令列中輸入 php i 命令檢視環境是否配置成功 開啟exe程式進行安裝即可 3.安裝ar...