Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 移植u-boot2012.04.1 -》2440 (二)norflash 識別

移植u-boot2012.04.1 -》2440 (二)norflash 識別

編輯:關於Android編程

在上一篇文章中,我們實現了新建單板,時鐘 sdram 等一系列初始化工作,串口已經能正確輸出打印信息,但是有錯誤信息。

\

現在,我們就來解決問題。搜索“Flash:”,或者往下看一下代碼,不難發現arch\arm\lib\board.c -》board_init_r 函數中有一句。

 

#if !defined(CONFIG_SYS_NO_FLASH)
	puts("Flash: ");

	flash_size = flash_init();
flash_init 就是 norflash 的初始化函數了,下面來簡單分析一下 flash_init 函數 norflash 的識別過程。

 

drivers\mtd\cfi_flash.c ->flash_init

 

if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))
			flash_get_size(cfi_flash_bank_addr(i), i);
board_flash_get_legacy(base, banknum, info)
	portwidth = FLASH_CFI_16BIT;
	chipwidth = FLASH_CFI_BY16;
	interface = FLASH_CFI_X16;
if (board_flash_get_legacy(base, banknum, info)) {
		// 如果 info 中沒有指定廠商,我們假設它是下面兩種之一,分別進行嘗試
		if (!info->vendor) {
			int modes[] = {
				CFI_CMDSET_AMD_STANDARD,
				CFI_CMDSET_INTEL_STANDARD
			};
			int i;
                        // 嘗試兩種廠商,循環兩次,第一次是 CFI_CMDSET_AMD_STANDARD
			for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
				info->vendor = modes[i];
				info->start[0] =
					(ulong)map_physmem(base,
							   info->portwidth,
							   MAP_NOCACHE);
				if (info->portwidth == FLASH_CFI_8BIT
					&& info->interface == FLASH_CFI_X8X16) {
					info->addr_unlock1 = 0x2AAA;
					info->addr_unlock2 = 0x5555;
				} else {  // 執行這個分支,norflash 位寬16bit
					info->addr_unlock1 = 0x5555;
					info->addr_unlock2 = 0x2AAA;
				}
				flash_read_jedec_ids(info);// 讀芯片ID
				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])) //匹配flash芯片
					break;
				else
					unmap_physmem((void *)info->start[0],
						      MAP_NOCACHE);
			}
		}
                ...
	}
首先引起我注意的是 info->addr_unlock1 和info->addr_unlock1 ,因為它和我們 norflash 芯片手冊中的兩個值很相似。

 

\ 如果沒猜錯的話,unlock1 就對應於Cycles 1 、3、5 ,unlock2 對應於 Cycles 2、4、6,由於我們的norflash位寬是16bit->word,那麼我們這裡應該分別修改為info->addr_unlock1 = 0x555;info->addr_unlock2 = 0x2AA; 在flash_read_jedec_ids(info);執行完之後,下面會debug出它讀取出的信息. 根據上圖芯片手冊,正確的話我們的廠家 ID = 01 ,device id = 0x22C4 . 由於 debug 默認是不開啟的,我們需要修改宏,配置輸出 debug 信息,在include\common.h
增加 #define DEBUG 開啟 debug 輸出,然後 make 燒寫! \
  我們可以看到,已經能夠正確識別出我們的 norflash id ,有些同學可能會奇怪下面又一次識別的是啥,那個好像不對,還記得前邊 for 循環麼?默認的第一個廠家識別匹配不成功的話,會嘗試第二次識別匹配,我們識別是成功了,但是還不知道匹配行不行呢,解決了匹配問題,第二次識別就不會執行了。
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;
}
這個函數的功能能一目了然,取出 jecec_table 數組中的每一項,和我們識別出來的廠家ID 設備ID 進行比較,如果比較成功,將 jecec_table 中的信息填充到 info 中去,那麼我們未匹配成功十有八九就是 jecec_table中沒有我們 norflash 的信息咯。 打開 jecec_table 確實沒有與我們匹配的項目,因此照葫蘆畫瓢添加一個。drivers\mtd\Jedec_flash.c
	{	//增加
		.mfr_id		= (u16)0x01,
		.dev_id		= 0x2249,
		.name		= "S29AL016J",
		.uaddr		= {
			[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
		},
		.DevSize		= SIZE_2MiB,
		.CmdSet			= CFI_CMDSET_AMD_LEGACY,
		.NumEraseRegions	= 4,
		.regions		= {
			ERASEINFO(0x04000, 1),
			ERASEINFO(0x02000, 2),
			ERASEINFO(0x08000, 1),
			ERASEINFO(0x10000, 31),
		}
	},
uaddr :和我們前邊修改的保持一致,先發0x555後發0x2AA cmdset:不清楚什麼意思,但是數據中的值大多都是這一個 0xfff0,先試試不行再說 NumEraseRegions:幾種不同的 sector ,與.regions 對應 \ 我這款 norflash : sector0 :16 * 1024 bytes (0x4000) 1個 sector1-sector2 : 8 *1024 bytes (0x2000) 2個 sector3 :32 * 1024 bytes (0x8000) 1個 sector4-sector34 :64 * 1024 bytes (0x8000)31個 .regions 顯然就是上邊的信息了,ok添加完畢 make 燒寫。 \
  已經能夠正確識別 norflash 並且成功進入控制台了,print 能夠正確打印環境變量,有一個nor的錯誤信息,

 

ERROR:too many flash sectors ,搜索too many flash sectors

include\configs\smdk2440.h 中定義了

#define CONFIG_SYS_MAX_FLASH_SECT (19)

修改為#define CONFIG_SYS_MAX_FLASH_SECT (35) //我的sector是35個

修改完成之後,norflash 部分算是沒有問題了,nandflash 的問題在下一篇文章中解決。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved