TE2440II開發板使用的Norflash是INTEL的JS28F320J3D75,4M,32個block,每個128KB。本文添加對Norflash的支持,使Uboot可以燒錄到Norflash,從Norflash啟動,并執行Norflash下的命令。 這樣需要注釋掉 /include/configs/TE2440II.h中的 #define CONFIG_SKIP_LOWLEVEL_INIT 1 //#define CONFIG_SKIP_RELOCATE_UBOOT 1 把include/configs/TE2440II.h的Physical Memory Map和FLASH and environment organization修改為,這里添加了/board/cmi/flash.c中部份變量的宏定義。FLASH and environment organization這里的sector指的是手冊中的bank,所以大小是128KB,為32塊。#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x40000),這個偏移是自己定的,是放環境變量的,只要不在uboot的代碼區就可以。 CONFIG_SYS_FLASH_ERASE_TOUT和CONFIG_SYS_FLASH_WRITE_TOUT是超時的時間,如果小了,自己改大些。cpu/arm920t/s3c24x0/timer.c中講述了怎么獲得時間的。 /*----------------------------------------------------------------------- * Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */ #define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */ #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */ #define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1 #define FLASH_BASE0_PRELIM PHYS_FLASH_1 #define CONFIG_SYS_MONITOR_BASE TEXT_BASE /*----------------------------------------------------------------------- * FLASH and environment organization */ #define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CONFIG_INTEL_JS28F320 1 #define PHYS_FLASH_SIZE 0x400000 /* 4M */ #define CONFIG_SYS_MAX_FLASH_SECT 32 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x40000) /* timeout values are in ticks */ #define CONFIG_SYS_FLASH_ERASE_TOUT (2*CONFIG_SYS_HZ) /* Timeout for Flash Erase */ #define CONFIG_SYS_FLASH_WRITE_TOUT (2*CONFIG_SYS_HZ) /* Timeout for Flash Write */ #define CONFIG_ENV_IS_IN_FLASH 1 #define CONFIG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */ #endif /* __CONFIG_H */ 用board/cmi/下的flash.c文件替換board/samsung/TE2440II/下的flash.c,因為cmi目錄下的正好是JS28F320J3D75的驅動文件。刪除這個write_short函數的申明和定 義、刪除write_buff函數。替換成下面的兩個函數: /****************************************************************************************************** * Copy memory to flash. */ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) { ulong cp, wp; ushort data; int l; int i, rc; wp = (addr & "1); /* get lower word aligned address */ /* * handle unaligned start bytes */ if ((l = addr - wp) != 0) { data = 0; for (i=0, cp=wp; i<l; ++i, ++cp) { data = (data >> 8) | (*(uchar *)cp << 8); } for (; i<2 && cnt>0; ++i) { data = (data >> 8) | (*src++ << 8); --cnt; ++cp; } for (; cnt==0 && i<2; ++i, ++cp) { data = (data >> 8) | (*(uchar *)cp << 8); } if ((rc = write_word(info, wp, data)) != 0) { return (rc); } wp += 2; } /* * handle word aligned part */ while (cnt >= 2) { data = *((vu_short*)src); if ((rc = write_word(info, wp, data)) != 0) { return (rc); } src += 2; wp += 2; cnt -= 2; } if (cnt == 0) { return ERR_OK; } /* * handle unaligned tail bytes */ data = 0; for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) { data = (data >> 8) | (*src++ << 8); --cnt; } for (; i<2; ++i, ++cp) { data = (data >> 8) | (*(uchar *)cp << 8); } return write_word(info, wp, data); } /****************************************************************************************************** * Copy memory to flash. */ static int write_word (flash_info_t *info, ulong dest, ushort data) { vu_short *addr = (vu_short *)dest, val; int rc = ERR_OK; int flag; /* Check if Flash is (sufficiently) erased , fix by kavin*/ if ((*addr & data) != data) return ERR_NOT_ERASED; /* * Disable interrupts which might cause a timeout * here. Remember that our exception vectors are * at address 0 in the flash, and we don't want a * (ticker) exception to happen while the flash * chip is in programming mode. */ flag = disable_interrupts(); /* clear status register command */ *addr = 0x50; /* program set-up command */ *addr = 0x40; /* latch address/data */ *addr = data; /* arm simple, non interrupt dependent timer */ reset_timer_masked(); /* wait while polling the status register */ while(((val = *addr) & 0x80) != 0x80) { if (get_timer_masked() > CONFIG_SYS_FLASH_WRITE_TOUT) { rc = ERR_TIMOUT; /* suspend program command */ *addr = 0xB0; goto outahere; } } if(val & 0x1A) { /* check for error */ printf("\nFlash write error %02x at address %08lx\n", (int)val, (unsigned long)dest); if(val & (1<<3)) { printf("Voltage range error.\n"); rc = ERR_PROG_ERROR; goto outahere; } if(val & (1<<1)) { printf("Device protect error.\n"); rc = ERR_PROTECTED; goto outahere; } if(val & (1<<4)) { printf("Programming error.\n"); rc = ERR_PROG_ERROR; goto outahere; } rc = ERR_PROG_ERROR; goto outahere; } outahere: /* read array command */ *addr = 0xFF; if (flag) enable_interrupts(); return rc; } 修改flash.c文件中的一個宏定義: 把: #define FLASH_BLOCK_SIZE 0x00010000 改為: #define FLASH_BLOCK_SIZE 0x00020000 修改開發板目錄下的lowlevel_init.S文件中SDARM刷新參數為: #define REFCNT 1258 /* period=7.8125us, HCLK=405/4 Mhz, (2048+1-7.8125*405/4) */ Lowlevel_init.S中對SDRAM進行了初始化,因為我們要把第二階段的代碼搬運到SDRAM中,REFCNT是刷新計數器,這個在移植的時候是一定要修改的。手冊上有公式:Refresh period = (2^11-refresh_count+1)/HCLK,我使用的這款芯片在datasheet寫著8192Refresh cycle/64ms,所以一個刷新周期為64ms/8192=7.8125us。目前公認的標準是,存儲體中電容中數據有效保存期上限是64ms,也就是說每一行刷新的循環周期是64ms,這樣刷新的速度就是:行數量/64ms。我的理解是CPU并不知道你用的SDRAM的刷新速度是多少,特殊功能寄存器也沒有直接傳遞刷新速度的位,但是有一個刷新計數器,可以通過刷新計數器間接獲得刷新速度,所以要設定刷新計數器。 然后就可以燒錄Norflash了。 李萬鵬 |