【原】s3c2410 u-boot-1.3.3移植記錄
|
發(fā)布時間:2009-06-26 15:37:01 |
技術(shù)類別:ARM
|
|
將u-boot-1.3.3.tar.bz2解壓,得到文件夾u-boot-1.3.3 ================================================================ 第 1 階段 ================================================================
1)、在u-boot-1.3.3/board下找個與2410相似的開發(fā)板,這里smdk2410為例。 2)、將u-boot-1.3.3/board/smdk2410目錄復(fù)制到當(dāng)前目錄下,并改名為edukit2410。 3)、把smdk2410.c改名為edukit2410.c,修改Makefile中的 COBJS := edukit2410.o pcmcia.o,保存。 4)、將u-boot-1.3.3/include/configs/smdk2410.h,復(fù)制到當(dāng)前目錄,并改名為edukit2410.h。 5)、修改u-boot-1.3.3/Makefile的內(nèi)容 ifeq ($(ARCH),arm) CROSS_COMPILE = /usr/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux-(交叉編譯工具安裝目錄)
6)、在u-boot-1.3.3/Makefile中添加 edukit2410_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t edukit2410 NULL s3c24x0 7)、打開超級終端,切換到u-boot-1.3.3目錄,敲入命令 # make edukit2410_config Configuring for edukit2410 board... 8)、之后就可以# make了。
================================================================ 第 2 階段 ================================================================
為了方便在linux下進(jìn)行u-boot的修改和燒寫,其實u-boot可通過一些命令和串口傳輸(使用ckermit)傳輸來實現(xiàn)自已燒寫自已。下面是步驟: 1)、#protect off all 去保護(hù) 2)、#erase 00000 1ffff 擦除 00000H ~ 1ffffH的內(nèi)容。 3)、#loadb 4)、用ckermit發(fā)送文件的方法: 按下ctrl + \,再按c切換到kermit輸入命令 send /.../u-boot.bin,等待發(fā)送完畢。 5)、#cp.b 33000000 00000 200000 等待燒寫完畢。
================================================================ 第 3 階段 ================================================================
1)、將u-boot-1.3.3/include/configs/edukit2410.h中的 #define CFG_PROMPT "SMDK2410 # " /* Monitor Command Prompt */ 改為 #define CFG_PROMPT "EDUKIT2410 # " /* Monitor Command Prompt */ 這是u-boot命令前面的提示符 2)、將u-boot-1.3.3/include/configs/edukit2410.h中的 #define PHYS_FLASH_SIZE 0x00080000 /* 512KB */ #define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */ #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000) /* addr of environment */ 改為 #define PHYS_FLASH_SIZE 0x00200000 /* 2MB */ #define CFG_MAX_FLASH_SECT (35) /* max number of sectors on one chip */ #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x1F0000) /* addr of environment */ 3)、將將u-boot-1.3.3/include/configs/edukit2410.h中的 /*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */ #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 10.0.0.110 #define CONFIG_SERVERIP 10.0.0.1 改為 #define CONFIG_ETHADDR 08:00:3e:26:0a:5b #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.2.201 #define CONFIG_SERVERIP 192.168.2.80 將同一文件中的關(guān)于CS8900的內(nèi)容更改為:(這些內(nèi)容可從其它帶有DM9000的開發(fā)板中查找,然后修改內(nèi)容,主要是片選和CMD片選) /* * Davicom DM9000 Network Card */ #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_BASE 0x20000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+0x100000) #define CONFIG_DM9000_USE_16BIT 1 #define CONFIG_NET_RETRY_COUNT 10 然后將ping命令加入,即在同一文件中加入以下定義 #define CONFIG_CMD_PING 重新編譯,然后設(shè)置相關(guān)的環(huán)境變量,如IP地址,物理地址等,保存。即可用ping 命令來測試網(wǎng)絡(luò)是否通了。 4)、由于驅(qū)動里用的是dm9000x,開發(fā)板上用的是dm9000A,有所不同,如果直接用uboot自帶的驅(qū)動ping不能。 需要將/root/Desktop/linux2410/SRC/u-boot-1.3.3/drivers/net/dm9000x.c的內(nèi)容 /* Check packet ready or not */ DM9000_ior(DM9000_MRCMDX); /* Dummy read */ rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */ 在前面需要加兩句: /* Check packet ready or not */ DM9000_ior(DM9000_MRRH); /* The follow code is special in DM9000A */ DM9000_ior(DM9000_MRRL); DM9000_ior(DM9000_MRCMDX); /* Dummy read */ rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */ 保存重新編譯即可ping通。 5)、“could not establish link” 提示和慢響應(yīng)的解決方法: 將/root/Desktop/linux2410/SRC/u-boot-1.3.3/drivers/net/dm9000x.c內(nèi)容中 i = 0; while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */ udelay(1000); i++; if (i == 10000) { printf("could not establish link\n"); return 0; } } /* see what we've got */ lnk = phy_read(17) >> 12; printf("operating at "); switch (lnk) { case 1: printf("10M half duplex "); break; case 2: printf("10M full duplex "); break; case 4: printf("100M half duplex "); break; case 8: printf("100M full duplex "); break; default: printf("unknown: %d ", lnk); break; } printf("mode\n"); 屏蔽掉。即在頭和尾加上 #if 0 ... #endif ================================================================ 第 4 階段 ================================================================ 1)、經(jīng)過上面的修改,以太網(wǎng)已通,在PC上建立tftp服務(wù),具體在FC7下如何安裝和設(shè)置tftp服務(wù),可查看郵箱的記載。在建立tftp服務(wù)之后 可通過u-boot的tftp命令下載內(nèi)核鏡象或者u-boot.bin來更新自已了。(這里PC的tftp服務(wù)根目錄為/tftpboot/,內(nèi)核文件名為zImage.img) 2)、在u-boot下通過命令已經(jīng)可以下載內(nèi)核或u-boot.bin了。但是發(fā)現(xiàn)在u-boot啟動的時候沒有出現(xiàn) Hit any key to stop autoboot: 3 也就是說直接進(jìn)入命令行,而不能自動引導(dǎo)。這個問題困攏了一天,后面通過看源代碼,發(fā)現(xiàn)是由于環(huán)境變量的問題。環(huán)境變量中必須存在變量bootcmd, 否則不會等 待,直接進(jìn)入命令行。u-boot啟動時環(huán)境變量的初始化是先從flash中讀取,如果flash中為空,則使用程序中的默認(rèn)環(huán)境變量。 3)、我的u-boot是由smdk2410移植 過來的,smdk2410里/u-boot-1.3.3/include/configs/smdk2410.h里關(guān)于bootcmd等的環(huán)境變量已注 釋掉: #define CONFIG_BOOTDELAY 3 /*#define CONFIG_BOOTARGS "root=ramfs devfs="mount" console="ttySA0",9600" */ /*#define CONFIG_ETHADDR 08:00:3e:26:0a:5b */ #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 10.0.0.110 #define CONFIG_SERVERIP 10.0.0.1 /*#define CONFIG_BOOTFILE "elinos-lart" */ /*#define CONFIG_BOOTCOMMAND "tftp; bootm" */ 其中CONFIG_BOOTARGS---對應(yīng)環(huán)境變量---bootargs CONFIG_BOOTFILE---對應(yīng)環(huán)境變量---bootfile CONFIG_BOOTCOMMAND---對應(yīng)環(huán)境變量---bootcmd 4)、在上面的那三個相關(guān)的注釋都去掉之后,重新編譯鏈接,將u-boot更新。為什么一進(jìn)u-boot還是進(jìn)入命令行呢,是由于u-boot啟動時環(huán)境變量 的初始化是先從flash中讀取,如果flash中為空,則使用程序中的默認(rèn)環(huán)境變量。由于我以前曾經(jīng)把環(huán)境變量寫到flash中(2M Nor Flash的最后 一個扇區(qū),第35個扇區(qū))。即使u-boot已更新,但是環(huán)境變量毫無變化,這樣導(dǎo)致u-boot啟動時的環(huán)境變量不是代碼中的環(huán)境變量,而是以前燒在Flash 的舊環(huán)境變量。而這些舊環(huán)境變量中沒有bootcmd項,所以u-boot啟動之后直接進(jìn)入命令行了。所以,為了使用程序中最新的環(huán)境變量,可將最后一塊flash 擦掉。當(dāng)然也可新增bootcmd變量,然后再saveenv。下次啟動時會有等 待時間,并能進(jìn)入自動引導(dǎo)模式。個人建議先不要把環(huán)境變量寫入flash,等最后 確定之后,再寫入不遲。當(dāng)然沒有寫入flash時,會有提示*** Warning - bad CRC, using default environment。這是沒關(guān)系的。使用程序中的 環(huán)境變量更有助于我們調(diào)試。 5)、將/u-boot-1.3.3/include/configs/edukit2410.h中已注釋的地方 /*#define CONFIG_BOOTFILE "elinos-lart" */ /*#define CONFIG_BOOTCOMMAND "tftp; bootm" */ 修改為 #define CONFIG_BOOTFILE "zImage.img" #define CONFIG_BOOTCOMMAND "tftp 30008000 zImage.img; bootm 30008000" 保存并重新編譯鏈接。并更新開發(fā)板上的u-boot。這樣在u-boot啟動時可自動將linux內(nèi)核從pc上下載到SDRAM上運行。 ================================================================ 第 5 階段 nand驅(qū)動 ================================================================ 1)、在u-boot-1.3.3/include/configs/edukit2410.h的 #ifndef __CONFIG_H #define __CONFIG_H 前面增加以下定義
/* add by xionggang.run on embest edukit iv board. nand flash:K9F1208U0B,refer to web file "移植U-Boot.1.3.1到S3C244和S3C2410" */ #define oNFCONF 0x00 #define oNFCMD 0x04 #define oNFADDR 0x08 #define oNFDATA 0x0c #define oNFSTAT 0x10 #define oNFECC 0x14 #define rNFCONF (*(volatile unsigned int *)0x4e000000) #define rNFCMD (*(volatile unsigned char *)0x4e000004) #define rNFADDR (*(volatile unsigned char *)0x4e000008) #define rNFDATA (*(volatile unsigned char *)0x4e00000c) #define rNFSTAT (*(volatile unsigned int *)0x4e000010) #define rNFECC (*(volatile unsigned int *)0x4e000014) #define rNFECC0 (*(volatile unsigned char *)0x4e000014) #define rNFECC1 (*(volatile unsigned char *)0x4e000015) #define rNFECC2 (*(volatile unsigned char *)0x4e000016) 2)、在u-boot-1.3.3/include/configs/edukit2410.h的最后面加上,注意要放在最后一條語句 #endif /* __CONFIG_H */ 之前 /*----------------------------------------------------------------------- * NAND flash settings add by xionggang.refer to web file "移植U-Boot.1.3.1到S3C244和S3C2410" */
#if defined(CONFIG_CMD_NAND) #define CFG_NAND_BASE 0x4E000000 /* NandFlash控制器在SFR區(qū)起始寄存器地址 */ #define CFG_MAX_NAND_DEVICE 1 /* 支持的最在Nand Flash數(shù)據(jù) */ #define SECTORSIZE 512 /* 1頁的大小 */ #define NAND_SECTOR_SIZE SECTORSIZE #define NAND_BLOCK_MASK 511 /* 頁掩碼 */ #define ADDR_COLUMN 1 /* 一個字節(jié)的Column地址 */ #define ADDR_PAGE 3 /* 3字節(jié)的頁塊地址*/ #define ADDR_COLUMN_PAGE 4 /* 總共4字節(jié)的頁塊地址*/ #define NAND_ChipID_UNKNOWN 0x00 /* 未知芯片的ID號 */ #define NAND_MAX_FLOORS 1 #define NAND_MAX_CHIPS 1 /* Nand Flash命令層底層接口函數(shù) */ #define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;} #define WRITE_NAND(d, adr) {rNFDATA = d;} #define READ_NAND(adr) (rNFDATA) #define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));} #define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;} #define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);} #define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr) #define NAND_CTL_SETALE(nandptr) #define NAND_CTL_CLRCLE(nandptr) #define NAND_CTL_SETCLE(nandptr) /* 允許Nand Flash寫校驗 */ #define CONFIG_MTD_NAND_VERIFY_WRITE 1 #endif /* CONFIG_CMD_NAND */ 3)、在u-boot-1.3.3/board/edukit2410/edukit2410.c文件的末尾添加對Nand Flash 的初始化函數(shù)(在后面Nand Flash的操作都要用到) u-
boot運行至第二階段進(jìn)入start_armboot()函數(shù)。其中nand_init()函數(shù)是對nand
flash的最初初始化函數(shù)。Nand_init()函數(shù)在兩個文件中實現(xiàn)。其調(diào)用與CFG_NAND_LEGACY宏有關(guān),如果沒有定義這個宏,系統(tǒng)調(diào)
用
drivers/nand/nand.c中的nand_init();否則調(diào)用自己在u-boot-1.3.3/board/edukit2410
/edukit2410.c中的nand_init()函數(shù)。這里我選擇第二種方式。 在u-boot-1.3.3/board/edukit2410/edukit2410.h的內(nèi)容 #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */ 后加上以下宏: #define CFG_NAND_LEGACY
然后在u-boot-1.3.3/board/edukit2410/edukit2410.c的最后添加下內(nèi)容: /* add by xionggang.run on embest edukit iv board. nand flash:K9F1208U0B refer to "vcma9.h" */ #if defined(CONFIG_CMD_NAND) typedef enum { NFCE_LOW, NFCE_HIGH } NFCE_STATE;
static inline void NF_Conf(u16 conf)/* 控制寄存器設(shè)置 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf; }
static inline void NF_Cmd(u8 cmd) /* 命令寄存器傳遞命令 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd; }
static inline void NF_CmdW(u8 cmd) /* 命令寄存器寫操作 */ { NF_Cmd(cmd); udelay(1); }
static inline void NF_Addr(u8 addr) /* 地址寄存器設(shè)置 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr; }
static inline void NF_SetCE(NFCE_STATE s) /* 設(shè)置nand flash的片選信號 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) { case NFCE_LOW: nand->NFCONF &= ~(1<<11); break;
case NFCE_HIGH: nand->NFCONF |= (1<<11); break; } }
static inline void NF_WaitRB(void) /* 等待 nand flash處于 Ready狀態(tài) */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
while (!(nand->NFSTAT & (1<<0))); }
static inline void NF_Write(u8 data) /* 寫數(shù)據(jù)操作 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFDATA = data; }
static inline u8 NF_Read(void) /* 讀數(shù)據(jù)操作 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA); }
static inline void NF_Init_ECC(void) /* 初始化ECC */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1<<12); }
static inline u32 NF_Read_ECC(void) /* 讀取ECC值 */ { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFECC); }
/* add by xionggang.refer to "sbc2410x.c" */
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void) { int i;
NF_SetCE(NFCE_LOW); NF_Cmd(0xFF); /* reset command */ for(i = 0; i < 10; i++); /* tWB = 100ns. */ NF_WaitRB(); /* wait 200~500us; */ NF_SetCE(NFCE_HIGH); }
static inline void NF_Init(void) { #if 1 #define TACLS 0 #define TWRPH0 3 #define TWRPH1 0 #else #define TACLS 0 #define TWRPH0 4 #define TWRPH1 2 #endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0)); /*nand->NFCONF
=
(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
*/ /* 1 1 1 1, 1 xxx, r xxx, r xxx */ /* En 512B 4step ECCR nFCE="H" tACLS tWRPH0 tWRPH1 */
NF_Reset(); }
void nand_init(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
NF_Init(); #ifdef DEBUG printf("NAND flash probing at 0x%.8lX\n", (ulong)nand); #endif printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20); } #endif 4)、u-boot-1.3.3/include/linux/mtd/nand_ids.h的結(jié)構(gòu)體nand_flash_ids加入 static struct nand_flash_dev nand_flash_ids[] = { ... {"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0}, // add by xionggang {NULL,} }; 5)、最后記得在u-boot-1.3.3/board/edukit2410/edukit2410.h的 #include <config_cmd_default.h> #define CONFIG_CMD_PING 后加上flash命令: #define CONFIG_CMD_NAND 最后保存#make,將生成的u-boot.bin下載到SRAM然后更新。上電運行。 u-boot啟動后,可鍵入命令nand erase clean將整塊nand flash擦除。 為了測試nand flash的驅(qū)動,可將u-boot.bin先下到33000000。然后通過u-boot命令nand write 33000000 0000 20000 將u-boot.bin燒寫到nand flash。完成以后,再上電運u-boot。通過u-boot命令nand read 32000000 0000 20000 將u-boot.bin拷貝到32000000,然后go 32000000。如果u-boot能正常啟動則說明nand的讀寫完好。
注:在添加了nand flash驅(qū)動之后,可能會編譯通不過,主要是由于以下兩個宏的定義所導(dǎo)致的: #if defined(CONFIG_CMD_NAND) #if !defined(CFG_NAND_LEGACY) ... #else // #error "U-Boot legacy NAND support not available for S3C2410" // by xionggang #endif #endif 解決辦法是將 #error "U-Boot legacy NAND support not available for S3C2410" 注釋掉。 ================================================================ 第 6 階段 根據(jù)需從nor啟動改為nand啟動。 注:經(jīng)過以上步驟編譯成的u-boot.bin燒寫到norflash的前面,設(shè)置成從nor啟動,可以正常啟動運行。 下面將實現(xiàn)從nand啟動,只需將編譯生成的bin燒寫到nandflash的前面,設(shè)置成nand啟動即可引導(dǎo)u-boot,在功能上與norflash啟動的完全一樣。 ================================================================ 1)、修改/cpu/arm920t/start.S 在 #ifndef CONFIG_AT91RM9200
#ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup
ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */
copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ #endif 將#ifndef CONFIG_AT91RM9200改為#ifdef CONFIG_AT91RM9200,目的是啟動時不執(zhí)行relocate。以從nand啟動。 并在其后加上: // add by xionggang,start #ifdef CONFIG_S3C2410_NAND_BOOT @ one half leds off ldr r0,=0x21180000 ldr r1,=0xA strb r1,[r0] @ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =0xf830 @ initial value str r2, [r1, #oNFCONF] ldr r2, [r1, #oNFCONF] bic r2, r2, #0x800 @ enable chip str r2, [r1, #oNFCONF] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait nand1: add r3, r3, #0x1 cmp r3, #0xa blt nand1
nand2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x1 beq nand2
ldr r2, [r1, #oNFCONF] orr r2, r2, #0x800 @ disable chip str r2, [r1, #oNFCONF]
@ get read to call C functions (for nand_read()) ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp="0"
@ copy U-Boot to RAM ldr r0, =TEXT_BASE mov r1, #0x0 mov r2, #0x20000 bl nand_read_ll tst r0, #0x0 beq ok_nand_read
bad_nand_read: loop2: b loop2 @ infinite loop
ok_nand_read: @ the other half leds on ldr r0,=0x21180000 ldr r1,=0x5 strb r1,[r0] @ verify mov r0, #0 ldr r1, =TEXT_BASE mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq stack_setup bne go_next
notmatch: loop3: b loop3 @ infinite loop
#endif @ CONFIG_S3C2410_NAND_BOOT // add by xionggang,end 2)、在 _start_armboot: .word start_armboot 后加上: // add by xionggang .align 2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 3)、在board/edukit2410/下添加NAND Flash讀函數(shù)文件nand_read.c,內(nèi)容如下:(參考vivi中nand_read.c) /* add by xionggang */ #include <config.h>
#define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) #define NF_BASE 0x4e000000
#if defined(CONFIG_S3C2410)
#define NFCONF __REGi(NF_BASE + 0x0) #define NFCMD __REGb(NF_BASE + 0x4) #define NFADDR __REGb(NF_BASE + 0x8) #define NFDATA __REGb(NF_BASE + 0xc) #define NFSTAT __REGb(NF_BASE + 0x10) #define BUSY 1
inline void wait_idle(void) { int i; while(!(NFSTAT & BUSY)) for(i=0; i<10; i++); } /* low level nand read function ,refer to vivi*/ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j, t;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) { return -1; /* invalid alignment */ }
/* chip Enable */ NFCONF &= ~0x800; for (t = 0; t < 100; t++);
for(i=start_addr; i < (start_addr + size);) { /* READ0 */ NFCMD = 0;
/* Write Address */ NFADDR = i & 0xff; NFADDR = (i >> 9) & 0xff; NFADDR = (i >> 17) & 0xff; NFADDR = (i >> 25) & 0xff;
//for (t = 0; t < 1500; t++); /* add by thisway, if not, will not work at some case */ wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) { *buf = (NFDATA & 0xff); buf++; } }
/* chip Disable */ NFCONF |= 0x800; /* chip disable */
return 0; } # endif 4)、修改board/edukit2410/Makefile文件
...... OBJS := tekkaman2440.o nand_read.o flash.o ...... 5)、修改include/configs/edukit2410.h,添加如下內(nèi)容: /* * add by xionggang ,In order to Nandflash Boot */ #define STACK_BASE 0x33f00000 #define STACK_SIZE 0x8000 #define CONFIG_S3C2410_NAND_BOOT
/* NAND Flash Controller */ #define NAND_CTL_BASE 0x4E000000 #define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb)) 6)、如果按照u-boot.1.3.3以前的版本,如果u-boot.1.3.1,經(jīng)過以上步聚編譯之后燒寫到nandflash應(yīng)該可以正常運行。 同樣的步聚在1.3.1可以正常運行,但是在1.3.3上不能正常運行。后來經(jīng)過對比System.map文件中函數(shù)地址發(fā)現(xiàn)了原因。 在1.3.1中默認(rèn)鏈接下,start.o放在最前面,后面緊接著nand_read.o和lowlevel_init.o。并且這三部分加起來大小小于4K。 在1.3.3中默認(rèn)鏈接下,start.o放在最前面,后面不是緊跟nand_read.o和lowlevel_init.o。中間有許多其它函數(shù)。而且 nand_read.o和lowlevel_init.o與start.o的距離遠(yuǎn)大于4K。當(dāng)從nand啟動時,只將最開始的4K搬到SRAM中,而這4K中不包 括nand_read.o和lowlevel_init.o,但是要能正常啟動,必須在前4k里調(diào)用該兩個文件中的函數(shù)!因此在默認(rèn)情況下是不能 正常運行的。需要手動改改鏈接腳本。 修改board/edukit2410/u-boot.lds文件,在 cpu/arm920t/start.o (.text)后加上 board/edukit2410/lowlevel_init.o (.text) board/edukit2410/nand_read.o (.text) 這樣指定start.o、nand_read.o、lowlevel_init.o放在最前面4K中。重新編譯運行就可以正常從nand啟動了?。。?br>================================================================ 第 7 階段 將環(huán)境變量從保存到nor flash改成保存到nand flash。 ================================================================ 1)、將include/configs/edukit2410.h中的 #define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */ 改為: //#define CFG_ENV_IS_IN_FLASH 1 #define CFG_ENV_IS_IN_NAND 1 /* add by xionggang,save env to nand flash */ #define CFG_ENV_OFFSET 0X20000 /* add by xionggang */ #define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */ 2)、修改common/env_nand.c 在 int nand_legacy_rw (struct nand_chip* nand, int cmd, size_t start, size_t len, size_t * retlen, u_char * buf); 后面添加 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; /* add by xionggang */ extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean); /* add by xionggang */ 將 extern nand_info_t nand_info[]; 修改為: extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; 3)、在當(dāng)前文件中修改#else /* ! CFG_ENV_OFFSET_REDUND */后的saveenv函數(shù): 將if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) 替換成: if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0)) 將ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr); 替換成: ret = nand_legacy_rw(nand_dev_desc + 0,0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,&total,(u_char*)env_ptr);
修改#else /* ! CFG_ENV_OFFSET_REDUND */后的env_relocate_spec函數(shù): 將ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr); 替換成: ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr); 重新編譯運行,即可將環(huán)境變量保存到nand flash而非nor flash了。
注:在用u-boot來給linux內(nèi)核傳遞參數(shù)里需要增加對以下宏的定義: #define CONFIG_SETUP_MEMORY_TAGS 1 #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
注:四型箱的Mini2410子板上也有一個DM9000A的網(wǎng)卡芯片,以上的驅(qū)動針對主板上的DM9000A,如果需要使用子板上的DM9000A, 只需將include/configs/edukit2410.h中的 /* * Davicom DM9000 Network Card * 使用EduKit IV主板上的網(wǎng)卡 */ #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_BASE 0x20000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE+0x100000) #define CONFIG_DM9000_USE_16BIT 1 #define CONFIG_NET_RETRY_COUNT 10 修改為: #define CONFIG_DRIVER_DM9000 1 #define CONFIG_DM9000_BASE 0x10000000 #define DM9000_IO (CONFIG_DM9000_BASE) #define DM9000_DATA (CONFIG_DM9000_BASE+2) #define CONFIG_DM9000_USE_16BIT 1 #define CONFIG_NET_RETRY_COUNT 10 重新編譯更新即可。
|