u-boot-2014.10移植第27天----nand flash启动(五)
硬件平台:tq2440 开发环境:Ubuntu-3.11 u-boot版本:2014.10 本文允许转载,请注明出处:http://blog.csdn.net/fulinus 为实现nand flash启动,最好的方法是使用u-boot自身提供的SPL方式,就是借助另一个相对独立的u-boot-spl.bin执行文件,将u-boot.bin拷贝到SDRAM中去,再运行u-boot.bin。这样一来u-boot就可以再次重定向。我们这里首先尝试用一个老方法。 1、首先关闭“位置无关”的编译选项,在arch/arm/config.mk文件中,注释“pie”:
# needed for relocation # LDFLAGS_u-boot += -pie 2、修改基地址,在include/configs/tq2440.h配置文件中,修改CONFIG_SYS_TEXT_BASE: #define CONFIG_SYS_TEXT_BASE 0x33F80000 3、在board/samsung/tq2440目录下添加nand_read_ll.c文件,nand_read_ll.c文件内容如下: /* NAND FLASH控制器 */ #define NFCONF (*((volatile unsigned long *)0x4E000000)) #define NFCONT (*((volatile unsigned long *)0x4E000004)) #define NFCMMD (*((volatile unsigned long *)0x4E000008)) #define NFADDR (*((volatile unsigned long *)0x4E00000C)) #define NFDATA (*((volatile unsigned long *)0x4E000010)) #define NFSTAT (*((volatile unsigned long *)0x4E000020)) static int is_boot_from_norflash(void) { int val; volatile int *p = (volatile int *)0; val = *p; *p = 0x12345678; if(*p == 0x12345678){ /* 写成功,是nand flash启动 */ *p = val; return 0; }else{ /* Nor flash 不能像内存一样写 */ return 1; } } void nand_init_ll(void) { #define TACLS 0 #define TWRPH0 1 #define TWRPH1 0 /* 设置时序 */ NFCONT = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* 使能Nand flash 控制器,初始化ECC,禁止片选 */ NFCONT = (1<<4)|(1<<1)|(1<<0); } void clear_bss(void) { extern int __bss_start,__bss_end; int *p = &__bss_start; for(; p < &__bss_end; p++){ *p = 0; } } static void nand_select(void) { NFCONT &= ~(1<<1); } static void nand_deselect(void) { NFCONT |= (1<<1); } static void nand_cmd(unsigned char cmd) { volatile int i; NFCMMD = cmd; for(i = 0; i < 10; i++); } static void nand_addr(unsigned int addr) { volatile int i; unsigned int col = addr % 2048; unsigned int page = addr / 2048; NFADDR = col & 0xFF; for(i = 0; i < 10; i++); NFADDR = (col >> 8) & 0xFF; for(i = 0; i < 10; i++); NFADDR = page & 0xFF; for(i = 0; i < 10; i++); NFADDR = (page >> 8) & 0xFF; for(i = 0; i < 10; i++); NFADDR = (page >> 16) & 0xFF; for(i = 0; i < 10; i++); } static void nand_wait_ready(void) { while(!(NFSTAT & 1)); } static unsigned char nand_data(void) { return NFDATA; } static void nand_read_ll(unsigned int addr,unsigned char *buf,unsigned int len) { int i = 0; int col = addr % 2048; /* 1.选中 */ nand_select(); while(i < len) { /* 2.发出读命令:00h */ nand_cmd(0x00); /* 3.发出地址指令 */ nand_addr(addr); /* 4.发出读命令:30h */ nand_cmd(0x30); /* 5.判断状态 */ nand_wait_ready(); /* 6.读数据 */ for(; (col < 2048) && (i < len); col++){ buf[i] = nand_data(); i++; addr++; } col = 0; } /* 7.取消选中 */ nand_deselect(); } void copy_code_to_sdram(unsigned char *src,unsigned char *dest,unsigned int len) { int i = 0; /* 如果是Nor flash 启动 */ if(is_boot_from_norflash()){ while(i < len){ dest[i] = src[i]; i++; } }else{ nand_init_ll(); nand_read_ll((unsigned int)src,dest,len); } } 4、修改board/samsung/tq2440目录下的Makefile文件: obj-y := tq2440.o + obj-y += nand_read_ll.o obj-y += lowlevel_init.o ENTRY(_main) 6、修改arch/arm/lib/board.c 文件中的board_init_f函数: //void board_init_f(ulong bootflag) ? ? //addr -= gd->mon_len; 。。。 ? ? memcpy(id,(void *)gd,sizeof(gd_t));
7、同时修改include/common.h头文件中board_init_f函数的声明: //void ?board_init_f(ulong); 8、修改连接脚本arch/arm/cpu/u-boot.lds文件,将nand_read_ll.c文件放在前4K字节中: ? ? .text : 9、修改arch/arm/config.mk文件,将checkarmreloc功能注释掉: # ALL-y += checkarmreloc 10、编译 不成功,感觉这个方法很牵强,换一种; 明天继续; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |