亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1192 | 回復(fù): 0
打印 上一主題 下一主題

移植nand支持到uboot, 使用nand.c ,linux mtd 架構(gòu) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-12-23 03:25 |只看該作者 |倒序瀏覽
u-boot-1.1.6與1.1.4相比,兩者有較大的不同,1.1.6 更像是復(fù)制了 kernel 的方法來實現(xiàn)。

下面對nand flash的初始化代碼nand_init()進(jìn)行分析:


1.如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)沒定義(CFG_NAND_LEGACY) 則start_armboot()調(diào)用driver/nand/nand.c中的nand_init(),否則如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)并且有定義了CFG_NAND_LEGACY,則調(diào)用自己定義的nand_init(),F(xiàn)在使用 driver/nand/nand.c中的nand_init()。
2.nand_init()調(diào)用本文件中的nand_init_chip()對nand進(jìn)行初始化。
3.nand_init_chip()首先調(diào)用board_nand_init()。
4.board_nand_init()是需要自己添加的函數(shù),這個函數(shù)的主要功能是對struct nand_chip結(jié)構(gòu)體的函數(shù)指針賦值,讓它們指向自己為nand驅(qū)動編寫的一些函數(shù),對未賦值的指針,uboot會在后面為其賦上通用nand驅(qū)動函數(shù)指針。此函數(shù)可放到自己板子目錄的文件下。
5.nand_init_chip()接著調(diào)用nand_scan().
6.nand_scan()定義在drivers/nand/nand_base.c文件中。它首先對struct nand_chip結(jié)構(gòu)體中在board_nand_init()函數(shù)中未賦值的指針賦上通用nand驅(qū)動函數(shù)指針。
7.nand_scan()->select_chip = nand_select_chip;

此函數(shù)用于打開或關(guān)閉nand芯片,0為打開,1為關(guān)閉。在這個函數(shù)中會調(diào)用nand_chip結(jié)構(gòu)體中的 hwcontrol函數(shù)指針。 hwcontrol在board_nand_init()函數(shù)中被賦值。主要作用是向 nand flash發(fā)送一些nand flash開啟與關(guān)閉命令。
8.nand_scan()剩余部分初始化nand_chip和mtd_info結(jié)構(gòu)體。
9.nand_scan()最后在返回時調(diào)用drivers/nand/nand_bbt.c文件中的nand_default_bbt()。
nand_default_bbt()選擇一個壞塊描述表,返回時調(diào)用本文件中的nand_scan_bbt()(尋找建立一個壞塊描述表)
10.最后返回到nand_init(),這樣nand驅(qū)動的初始化完成了。

通過上述步驟我們可以知道,移植nand主要按如下步驟:

1、在board/xxx下建立c文件

2、在此文件上添加函數(shù)board_nand_init(),實現(xiàn)nand_chip的初始化功能

3、添加初始化的函數(shù)

4、在include/configs/xxx.h中定義相關(guān)宏,比如#define CFG_MAX_CHIPS

完成上述移植后,實際上啟動后的uboot中的nand命令是通過include/nand.h實現(xiàn)的,例如nand erase調(diào)用了:

static inline int nand_erase(nand_info_t *info, ulong off, ulong size)

看看人家怎么做的:

//----------------------------------------------------------------------------------------------------

為了讓uboot支持自己QT板子的nand flash而進(jìn)行修改的部分 
1.前面的移植請參考我寫的一篇《U-Boot的編譯與移植到QT-S3C44B0X開發(fā)板上》,現(xiàn)在在board/51EDA/QT/目錄下建立nand.c文件。
2.在nand.c中添加自己的board_nand_init()函數(shù)。設(shè)定nand_chip結(jié)構(gòu)中的hwcontrol和dev_ready指針指向自己的函數(shù)QT_hwcontrol和QT_device_ready。并建立自己的QT_hwcontrol和QT_device_ready函數(shù)。
3.由于自己板子的nand flash的命令發(fā)送方式與uboot提供的通用nand flash命令發(fā)送方式不同,所以在nand.c文件中建立自己的命令發(fā)送函數(shù)QT_nand_command(),并在 board_nand_init()函數(shù)中將nand_chip結(jié)構(gòu)中的cmdfunc指針指向QT_nand_command()函數(shù),使其使用自己定義的發(fā)送命令函數(shù)。
4.在include/configs/QT.h中定義CFG_NAND_BASE用于指定自己板子nand flash的I/O地址。
5.在CONFIG_COMMANDS中打開CFG_CMD_NAND選項。
6.在include/configs/QT.h中定義NAND_MAX_CHIPS指定自己板子的nand flash芯片數(shù)。
7.在include/configs/QT.h中定義CFG_MAX_NAND_DEVICE指定想要支持的nand flash設(shè)備數(shù)。

//這是比較深入的分析:

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

U-BOOT Nand命令支持
u-boot1.1.6 nand_legacy驅(qū)動提供了u-boot對nand相關(guān)命令的一個輕量級的實現(xiàn),但好象可擴(kuò)展性不足。本文主要分析u-boot 1.16/drivers/nand文檔夾下的源程式。
一.關(guān)鍵數(shù)據(jù)結(jié)構(gòu)
1.struct mtd_info
該結(jié)構(gòu)在include\linux\mtd\Mtd.h中定義,字段比較多,有很多還是函數(shù)指針,他是MTD設(shè)備操作的通用接口,這個結(jié)構(gòu)中有一個比較重要的成員 void *priv,priv被聲明成void指針,在下文的分析中會知道priv實際上指向了nand_chip結(jié)構(gòu)。
2.struct nand_chip
   該結(jié)構(gòu)在include\linux\mtd\Nand.h中定義,從名字上看就知道u-boot用他來描述Nand Flash芯片的結(jié)構(gòu),比如他定義了頁地址的偏移,頁地址的位掩碼等。struct nand_chip不用我們手動的初始化,而是由另外一個結(jié)構(gòu),struct nand_flash_dev在程式中動態(tài)的初始化。
3.struct nand_flash_dev
    該結(jié)構(gòu)的定義有兩處地方分別是
①include/linux/mtd/nand_legacy.h 由nand_legacy模塊使用
②include/linux/mtd/nand.h       由u-boot通用nand架構(gòu)使用
特別是在移植的時候要小心把兩者混淆。我們先來看看改結(jié)構(gòu)的定義
struct nand_flash_dev {
       char *name;            
       int id;
       unsigned long pagesize;
       unsigned long chipsize;
       unsigned long erasesize;
       unsigned long options;
};
name : Nand Flash名稱
id : u-boot內(nèi)部id編號???
chipsize : 以MB為單位的芯片大小,比如64(M)
erasesize : 擦除塊的大小,比如0x4000(16K)
options : 一些選項,比較重要的是Flash的數(shù)據(jù)位寬,假如您的Nand Flash是16位寬的,則必須包含NAND_BUSWIDTH_16選項。我們必須根據(jù)所使用的Nand Flash來填充里面的字段。
4.關(guān)鍵數(shù)據(jù)結(jié)構(gòu)在程式中的使用
struct nand_info_t nand_info[ CFG_MAX_NAND_DEVICE ];
在 drivers\nand\nand.c中定義。CFG_MAX_NAND_DEVICE是板子的Nand Flash芯片的數(shù)量必須在板子的配置文檔中定義(比如 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驅(qū)動模塊使用的。兩者不能混淆!!!。在nand_flash_ids的定義中我找到了適合我的Nand Flash的結(jié)構(gòu)描述:
{"NAND 64MiB 3,3V 8-bit",        0x76, 512, 64, 0x4000, 0}
設(shè)備ID為0x76,頁大小為512Byte,總的容量為64M,擦除塊為0x4000(16K),數(shù)據(jù)位寬8Bit。假如您的Nand Flash沒有合適的描述,需要自己在該數(shù)組中添加相應(yīng)的定義。

二.Nand Flash初始化

1.nand_init( drivers\nand\nand.c )
nand_init函數(shù)在lib_xxx/Board.c的start_armboot中調(diào)用。是u-boot Nand的主函數(shù)。nand_init的主要功能是對CFG_MAX_NAND_DEVICE個Nand設(shè)備進(jìn)行初始化(調(diào)用 nand_init_chip),累加Nand Flash的總大小。在nand_init結(jié)束時,能夠配置是否執(zhí)行board_nand_select_device,選擇Nand芯片。
2.nand_init_chip( drivers\nand\nand.c )
static void nand_init_chip( struct mtd_info *mtd, struct nand_chip *nand, ulong base_addr )調(diào)用各個研發(fā)板提供的 board_nand_init 函數(shù)( board\\.c )讓研發(fā)板獲得初始化Nand Flash芯片的機(jī)會。調(diào)用 nand_scan。
3.nand_scan ( drivers\nand\nand_base.c )
int nand_scan( struct mtd_info *mtd, int maxchips )
這是u-boot初始化nand設(shè)備的核心函數(shù)。他主要完成以下工作

1)初始化nand_chip的函數(shù)指針,這些函數(shù)一般在 board\\.c中定義。

struct nand_chip *this = mtd->priv
....
if( this-> cmdfunc == NULL )
       this->cmdfunc = nand_command;

上面是初始化nand_chip中cmdfunc指針的代碼,假如在board_init_nand中研發(fā)板沒有提供自己的nand_command函數(shù),u-boot 將使用默認(rèn)的nand_command函數(shù)(我覺得u-boot提供的這些默認(rèn)的函數(shù)都不適合特定的硬件,所以很多都要自己重新寫)。

2)使用上面注冊的函數(shù)指針,讀取Nand Flash的設(shè)備,并且在上文提到的nand_flash_ids[]中找是否有匹配項,若找到匹配的項,則初始化 nand_chip 和 mtd_info,他們的初始化代碼老長的一段,一般沒什么問題。

三. Nand Flash 操作
1. Read
函數(shù)調(diào)用層次:(如下圖)。 
[轉(zhuǎn)載]s3c2410移植nand支持到uboot, 使用nand.c ,linux mtd 架構(gòu) 【2】 - lanmanck的專欄 - CSDN博客 - deshunfan - 電子屋 
以common/env_nand.c里面讀取Nand Flash中的環(huán)境變量為例
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的別名)數(shù)組。此處的nand_read是個inline函數(shù),下面是他的實現(xiàn):

include/nand.h
static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf)
{
       return info->read(info, ofs, *len, (size_t*)len, buf);
}

能夠看出nand_read實際上調(diào)用的是nand_info的read方法。nand_info的read方法是在2.3中講到的nand_scan中初始化
drivers/nand/nand_base.c
int nand_scan(struct mtd_info *mtd, int machips)
{
       …
       mtd->read = nand_read;
       …
}
此處又一個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)
{
       return nand_read_ecc( mtd, from, len, retlen, buf, NULL, NULL );
}

又一層包裝!!!

drivers/nand/nand_base.c
static int nand_read_ecc(…)
{
       …
}
終于到達(dá)最后一層了,nand_read_ecc通過調(diào)用nand_chip里面提供的函數(shù)對nand flash完成讀的操作。具體能夠看看代碼,老長的一段

您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP