移植uboot之修改代码支持NorFlash记录
學(xué)習交流加
- 個人qq:
1126137994 - 個人微信:
liu1126137994 - 學(xué)習交流資源分享qq群:
962535112
今天我們的任務(wù)是修改uboot源碼支持NorFlash。
上兩篇關(guān)于uboot移植的文章,我們修改了uboot源代碼,支持了串口的輸出,以及nand啟動(點擊連接可以查看上兩面文章的相關(guān)內(nèi)容移植uboot支持串口輸出,移植uboot支持NAND啟動)
同時分享一個很好的書:Linux設(shè)備驅(qū)動開發(fā)詳解-宋寶華
(注:寫到后面發(fā)現(xiàn)沒有告訴大家用的flash芯片的型號,我們用的flash芯片的型號是:MX29LV160DB,芯片手冊大家可以自行到網(wǎng)上下載,從中可以查看芯片的廠家ID和設(shè)備ID等信息)
我們移植uboot,都是一步一步調(diào)試而來,所以會比較繁瑣,但是我覺得記錄這些,是一件很有意義的事,雖然很麻煩,但是對將來,會有莫大的影響!!!
上次移植支持NAND后,串口啟動界面如下:
我們在source insight中搜索“Flash:”這個字符串出現(xiàn)在哪里,在Board.c中的board_init_r函數(shù)中,有這樣幾行代碼:
課件代碼是執(zhí)行到了這兩行:
puts(failed);hang();查看hang()這個函數(shù)為:
void hang(void)
{
puts("### ERROR ### Please RESET the board ###\n");
for (;?;
}
很明顯,代碼進入了一個死循環(huán),所以無法啟動uboot了。
回過頭看上面的board_init_r函數(shù)里的flash_size = flash_init();,應(yīng)該是flash的一個初始化,初始化后成功后才執(zhí)行下面的if語句,很明顯我們這里沒有初始化成功。進入flash_init。查看代碼如下(在drivers/mtd/Cfi_flash.c中):
里面有一個if判斷語句:
if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))flash_get_size(cfi_flash_bank_addr(i), i);從字面意思看出flash_detect_legacy為舊的檢測flash,flash_get_size就應(yīng)該為新的檢測flash機制,先看一下舊的,沒看出什么,再看flash_get_size,發(fā)現(xiàn)有很多debug調(diào)試信息,有這么多調(diào)試信息,那就應(yīng)該用起來:
在flash_get_size中的debug信息
搜索debug 查到:
在include/common.h中有下面的代碼
很明顯應(yīng)該是用的_DEBUG,搜索_DEBUG,有:
#ifdef DEBUG #define _DEBUG 1 #else #define _DEBUG 0 #endif好,那么我們就把#define _DEBUG 1給加上,在Cfi_flash.c中定義如下兩行:
#define DEBUG 1 (不確定是哪個就都定義,反正也不會出錯) #define _DEBUG 1重新編譯uboot燒寫啟動看一下:
打印的這句話:JEDEC PROBE: ID c2 2249 0
告訴我們讀到的廠家ID,設(shè)備ID,我們查看datasheet,發(fā)現(xiàn)這個讀到的ID是沒有錯的,廠家ID是c2,設(shè)備ID是2249,
根據(jù)打印信息,在源碼中搜索字符串“JEDEC PROBE:”在Cfi_flash.c中的flash_detect_legacy函數(shù)中有如下代碼片段:
debug("JEDEC PROBE: ID %x %x %x\n",info->manufacturer_id,info->device_id,info->device_id2);if (jedec_flash_match(info, info->start[0]))break;elseunmap_physmem((void *)info->start[0],MAP_NOCACHE);看出設(shè)備ID時如何打印的,下面的jedec_flash_match還需要進行一下匹配,我們?nèi)edec_flash_match函數(shù)里看看是實現(xiàn)的什么內(nèi)容(在drivers/mtd/jeder_flash.c中):
/*-----------------------------------------------------------------------* match jedec ids against table. If a match is found, fill flash_info entry*/ int jedec_flash_match(flash_info_t *info, ulong base) {int ret = 0;int i;ulong mask = 0xFFFF;if (info->chipwidth == 1)mask = 0xFF;for (i = 0; i < ARRAY_SIZE(jedec_table); i++) {if ((jedec_table[i].mfr_id & mask) == (info->manufacturer_id & mask) &&(jedec_table[i].dev_id & mask) == (info->device_id & mask)) {fill_info(info, &jedec_table[i], base);ret = 1;break;}}return ret; }發(fā)現(xiàn)一個數(shù)組jedec_table,匹配設(shè)備的ID用的應(yīng)該就是這個數(shù)組里的內(nèi)容了,查看數(shù)組如下:
static const struct amd_flash_info jedec_table[] = { #ifdef CONFIG_SYS_FLASH_LEGACY_256Kx8{.mfr_id = (u16)SST_MANUFACT,.dev_id = SST39LF020,.name = "SST 39LF020",.uaddr = {[0] = MTD_UADDR_0x5555_0x2AAA /* x8 */},.DevSize = SIZE_256KiB,.CmdSet = P_ID_AMD_STD,.NumEraseRegions= 1,.regions = {ERASEINFO(0x01000,64),}},。。。。。。。。。。(還有很多跟上面相同的類型的內(nèi)容,我這里給省略了)這個結(jié)構(gòu)體里的內(nèi)容,定義了許多類型的flash,每一個定義就是一個flash芯片。我們在里面自己定義我們的芯片結(jié)構(gòu)項。
/* jz2440使用的是MX29LV160DB芯片 */{.mfr_id = (u16)MX_MANUFACT, /*廠家ID*/.dev_id = 0x2249, /*設(shè)備ID*/.name = "MXIC MX29LV160DB",.uaddr = { /*NOR FLASH看到的解鎖地址*/[0] = MTD_UADDR_0x0555_0x02AA /* x16 */},.DevSize = SIZE_2MiB, /* 總大小 */.CmdSet = P_ID_AMD_STD,.NumEraseRegions= 4, /* 擦除區(qū)域的數(shù)目 */.regions = { /* 這些內(nèi)容涉及芯片手冊的閱讀,之后的文章會單獨寫關(guān)于硬件的操作 */ERASEINFO(16*1024, 1), ERASEINFO(8*1024, 2),ERASEINFO(32*1024, 1),ERASEINFO(64*1024, 31),}},里面涉及到 的硬件操作,我會在之后的講解NOR FLASH 驅(qū)動時,講解如何操作這個芯片里面涉及到,在這里,我們移植uboot,只需要這樣做就可以,暫時不需要追根究底(無底洞啊!!!)。
然后就是最開始忘記了一件事,就是把board.中的board_init_r中的兩行代碼(自己回頭看上面的代碼)屏蔽掉:
//puts(failed);//hang();然后重新編譯uboot,燒寫啟動運行:
哈哈哈!!!!先慶祝一下,終于啟動進去了,雖然還沒有完善,但是得一步一步來嘛!
顯示有錯誤:ERROR: too many flash sectors,在源碼中搜索這個錯誤找到(Cfi_flash.c中):
跳轉(zhuǎn)到CONFIG_SYS_MAX_FLASH_SECT這個定義(在smdk2440.h中),有:
#define CONFIG_SYS_MAX_FLASH_SECT (19)將19改為128吧:
#define CONFIG_SYS_MAX_FLASH_SECT (128)然后再把我們之前加的Debug調(diào)試信息去掉,因為我們已經(jīng)不需要那些打印信息了,去掉的話會看起來簡潔一些,去掉下面的兩個宏定義:
//#define DEBUG 1 //#define _DEBUG 1重新編譯燒寫,看啟動界面:
這次啟動界面比較簡潔,而且上面出現(xiàn)的錯誤也沒有了!!!
那我們現(xiàn)在來測試一下NORFLASH能否擦除與讀寫。
串口中輸入:protect off all,先解除寫保護
輸入:flinfo,打印輸出正常:
輸入:erase 80000 8ffff
輸入:cp.b 30000000 80000 10000 (把內(nèi)存中30000000位置的內(nèi)容拷貝到flash80000地址)
到了這里,出現(xiàn)了一些問題,無法將內(nèi)存的代碼拷貝過來,無法寫flash。。。。。。。。。啊,天哪,感覺又得花時間去看了!!!
放到下一篇博客吧,這篇已經(jīng)寫了很多了!!!
想獲得各種學(xué)習資源以及交流學(xué)習的加我:
qq:1126137994
微信:liu1126137994
可以共同交流關(guān)于嵌入式,操作系統(tǒng),C++語言,C語言,數(shù)據(jù)結(jié)構(gòu)等技術(shù)問題!
總結(jié)
以上是生活随笔為你收集整理的移植uboot之修改代码支持NorFlash记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Face Alignment by 30
- 下一篇: Java中常用的设计模式【模板模式】