您的位置:首页 > 其它

TQ2440 u-boot-2012.04.01移植二支持NAND启动

2013-05-02 21:18 573 查看
继 u-boot-2012.04.01移植一串口正常输出,继续修改代码支持单板NAND启动。最后直接用NOR Flash里的u-boot烧写自己移植的u-boot到NAND,方便电脑没有并口或手上没有openjtag,照样能移植u-boot,当然有openjtag更方便。
开发环境:

系统:ubuntu 10.04.4

单板:tq2440

NAND FLASH:K9F1216U0A 256MB

NOR Flash:EN29LV160AB 2MB

SDRAM:HY57V561620 x2 64MB

NET:DM9000AEP

编译器:arm-linux-gcc-4.3.2

搭建开发环境详见ubuntu 10.04.4开发环境配置。

目标:

1.支持NOR Flash启动,串口正常输出

2.支持NAND启动

3.支持DM9000网卡

4.添加u-boot菜单

5.裁剪u-boot及制作补丁

NOR Flash是内存接口,能直接运行程序,但是NAND Flash地址线都没有,是不能直接跑程序的。熟悉三星片子的人都知道s3c2440 NAND启动时,CPU会自动从NAND Flash读取前4KB到SRAM,同时把这段片内SRAM映射到nGCS0片选空间即0x0000 0000。而ARM架构的CPU第一条指令是从0地址开始执行的。相当于片内SRAM充当一个载体,把NAND前4KB映射到0地址,CPU开始执行NAND前4KB内容。

change@change:~$ cd Si/TQ2440/u-boot-2012.04.01/

change@change:~/Si/TQ2440/u-boot-2012.04.01$ ls u-boot.bin -l

-rw-r--r-- 1 change change 364712 2013-05-02 20:00 u-boot.bin


看到生成的u-boot.bin有360KB左右,这个放在NOR Flash里能直接启动,但是不利于NAND启动。u-boot运行后,不管是NNAD还是NOR Flash启动,都会进行重定位,即把代码拷到内存运行,就像PC机一样程序都是在内存运行的。那么支持NAND启动的u-boot,重定位之前代码必须小于4KB,才能跑起来。分析现在较新的u-boot源码(以后在另外文章分析),代码连接时加-pie选项,重定位成位置无关代码,搞的很高级,不利于像S3C2440这样片内SRAM十分有限的SOC跑。这里修改重定位代码,支持NAND启动。

1.去掉-pie选项,不需要附加“*(.rel*)”、“*(.dynsm)”等信息

change@change:~/Si/TQ2440/u-boot-2012.04.01$ grep "\-pie" * -nR

arch/x86/config.mk:43:LDFLAGS_FINAL += --gc-sections -pie

arch/arm/config.mk:75:LDFLAGS_u-boot += -pie

doc/README.arm-relocation:3:At arch level: add linker flag -pie

change@change:~/Si/TQ2440/u-boot-2012.04.01$ vim arch/arm/config.mk
去掉75行LDFLAGS_u-boot += -pie

2.参考以前update写的start.S init.c修改代码

在arch/arm/cpu/arm920t/start.S112:增加

.globl base_sp

base_sp:

.long 0

在arch/arm/cpu/arm920t/start.S:205行增加如下代码

ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)/*sp =30000f80*/
bic	sp, sp, #7 /* 8-byte alignment for ABI compliance */

bl nand_init_ll
mov r0, #0
//ldr r1, =_start
ldr r1, _TEXT_BASE
//dr r2, =__bss_start
//sub r2, r2, r1
ldr r2, _bss_start_ofs
bl copy_code_to_sdram
bl clear_bss

ldr pc, =call_board_init_f


arch/arm/cpu/arm920t/start.S221:注释掉下面2行

//ldr
sp, =(CONFIG_SYS_INIT_SP_ADDR)

//bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

在arch/arm/cpu/arm920t/start.S:226行增加如下代码

/*unsigned int id */

ldr r1, _TEXT_BASE//*link addres

ldr sp, base_sp

bl board_init_r//*the second step

用自己的重定位代码,去掉u-boot自带的arch/arm/cpu/arm920t/start.S 231:

/*------------------------------------------------------------------------------*/

/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* This "function" does not return, instead it continues in RAM
* after relocating the monitor code.
*
*/
.globl	relocate_code
relocate_code:
mov	r4, r0	/* save addr_sp */
mov	r5, r1	/* save addr of gd */
mov	r6, r2	/* save addr of destination */

/* Set up the stack						    */
stack_setup:
mov	sp, r4

adr	r0, _start
cmp	r0, r6
moveq	r9, #0		/* no relocation. relocation offset(r9) = 0 */
beq	clear_bss		/* skip relocation */
mov	r1, r6			/* r1 <- scratch for copy_loop */
ldr	r3, _bss_start_ofs
add	r2, r0, r3		/* r2 <- source end address	    */

copy_loop:
ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
stmia	r1!, {r9-r10}		/* copy to   target address [r1]    */
cmp	r0, r2			/* until source end address [r2]    */
blo	copy_loop

#ifndef CONFIG_SPL_BUILD
/*
* fix .rel.dyn relocations
*/
ldr	r0, _TEXT_BASE		/* r0 <- Text base */
sub	r9, r6, r0		/* r9 <- relocation offset */
ldr	r10, _dynsym_start_ofs	/* r10 <- sym table ofs */
add	r10, r10, r0		/* r10 <- sym table in FLASH */
ldr	r2, _rel_dyn_start_ofs	/* r2 <- rel dyn start ofs */
add	r2, r2, r0		/* r2 <- rel dyn start in FLASH */
ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
fixloop:
ldr	r0, [r2]		/* r0 <- location to fix up, IN FLASH! */
add	r0, r0, r9		/* r0 <- location to fix up in RAM */
ldr	r1, [r2, #4]
and	r7, r1, #0xff
cmp	r7, #23			/* relative fixup? */
beq	fixrel
cmp	r7, #2			/* absolute fixup? */
beq	fixabs
/* ignore unknown type of fixup */
b	fixnext
fixabs:
/* absolute fix: set location to (offset) symbol value */
mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
add	r1, r10, r1		/* r1 <- address of symbol in table */
ldr	r1, [r1, #4]		/* r1 <- symbol value */
add	r1, r1, r9		/* r1 <- relocated sym addr */
b	fixnext
fixrel:
/* relative fix: increase location by offset */
ldr	r1, [r0]
add	r1, r1, r9
fixnext:
str	r1, [r0]
add	r2, r2, #8		/* each rel.dyn entry is 8 bytes */
cmp	r2, r3
blo	fixloop
#endif

clear_bss:
#ifndef CONFIG_SPL_BUILD
ldr	r0, _bss_start_ofs
ldr	r1, _bss_end_ofs
mov	r4, r6			/* reloc addr */
add	r0, r0, r4
add	r1, r1, r4
mov	r2, #0x00000000		/* clear			    */

clbss_l:cmp	r0, r1			/* clear loop... */
bhs	clbss_e			/* if reached end of bss, exit */
str	r2, [r0]
add	r0, r0, #4
b	clbss_l
clbss_e:

bl coloured_LED_init
bl red_led_on
#endif
以上代码全部去掉,在之前已重定位

接着在board/samsung/TQ2440/目录下增加init.c文件,board/samsung/TQ2440/init.c:

/* NAND FLASH控制器 */
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))

/* GPIO */
#define GPHCON              (*(volatile unsigned long *)0x56000070)
#define GPHUP               (*(volatile unsigned long *)0x56000078)

/* UART registers*/
#define ULCON0              (*(volatile unsigned long *)0x50000000)
#define UCON0               (*(volatile unsigned long *)0x50000004)
#define UFCON0              (*(volatile unsigned long *)0x50000008)
#define UMCON0              (*(volatile unsigned long *)0x5000000c)
#define UTRSTAT0            (*(volatile unsigned long *)0x50000010)
#define UTXH0               (*(volatile unsigned char *)0x50000020)
#define URXH0               (*(volatile unsigned char *)0x50000024)
#define UBRDIV0             (*(volatile unsigned long *)0x50000028)

#define TXD0READY   (1<<2)

void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len);

static int isBootFromNorFlash(void)
{
volatile int *p = (volatile int *)0;
int val;

val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/* 写成功, 是nand启动 */
*p = val;
return 0;
}
else
{
/* NOR不能像内存一样写 */
return 1;
}
}

void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
int i = 0;

/* 如果是NOR启动 */
if (isBootFromNorFlash())
{
while (i < len)
{
dest[i] = src[i];
i++;
}
}
else
{
//nand_init();
nand_read_ll((unsigned int)src, dest, len);
}
}

void clear_bss(void)
{
extern int __bss_start, __bss_end__;
int *p = &__bss_start;

for (; p < &__bss_end__; p++)
*p = 0;
}

void nand_init_ll(void)
{
#define TACLS   0
#define TWRPH0  1
#define TWRPH1  0
/* 设置时序 */
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
NFCONT = (1<<4)|(1<<1)|(1<<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)
{
unsigned int col  = addr % 2048;
unsigned int page = addr / 2048;
volatile int i;

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;
}

void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
int col = addr % 2048;
int i = 0;

/* 1. 选中 */
nand_select();

while (i < len)
{
/* 2. 发出读命令00h */
nand_cmd(0x00);

/* 3. 发出地址(分5步发出) */
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();
}
同时修改该目录下的在Makfile,board/samsung/TQ2440/Makefile:
28: COBJS:= TQ2440.o init.o

其中lowlevel_init.S定义_TEXT_BASE: .word
CONFIG_SYS_TEXT_BASE,是u-boot的重定位地址,搜索定义在TQ2440.h42:

//#define CONFIG_SYS_TEXT_BASE 0x0

#define CONFIG_SYS_TEXT_BASE 0x33f80000

arch/arm/lib/board.c265:将void board_init_f(ulong bootflag)修改unsigned int board_init_f(ulong bootflag)

同时修改include/common.h 276:

void board_init_f (ulong) __attribute__ ((noreturn));

改为unsigned int board_init_f (ulong);

arch/arm/lib/board.c265:增加extern ulong base_sp;//**add

arch/arm/lib/board.c373:修改如下

//addr -= gd->mon_len;

//addr &= ~(4096 - 1);

addr = _TEXT_BASE;//**add return sp to start.s

arch/arm/lib/board.c439:修改如下

base_sp = addr_sp;//**add

//relocate_code(addr_sp, id, addr);

return (unsigned int) id;// add it

代码部分修改的差不多了,接下来还要修改链接脚本,确保重定位之前的代码编译在最前面

在arch/arm/cpu/u-boot.lds 38:增加如下

board/samsung/TQ2440/libTQ2440.o(.text)

3.重新配置、编译

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make distclean

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make TQ2440_config

Configuring for TQ2440 board...

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make

ok编译通过,看看现在的u-boot.bin多大

change@change:~/Si/TQ2440/u-boot-2012.04.01$ ls u-boot.bin -l

-rwxr-xr-x 1 change change 337656 2013-05-02 20:40 u-boot.bin

change@change:~/Si/TQ2440/u-boot-2012.04.01$ cp u-boot.bin /home/change/work/tftpboot/

4.烧写、测试

记住这里是烧到NAND,我用NOR Flash里的u-boot烧写,拨到NOR Flash启动,设置串口 115200 8 n 1

U-Boot 2012.04.01 (Oct 25 2012 - 22:47:25)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: 0 KB

NAND: 256 MiB

*** Warning - bad CRC, using default environment

In: serial

Out: serial

Err: serial

Net: dm9000

Hit any key to stop autoboot: 0

SMDK2410 # set ipaddr 172.16.1.111

SMDK2410 # set gatewayip 172.16.1.1

SMDK2410 # set serverip 172.16.1.132

SMDK2410 # tftp 0x32000000 u-boot.bin

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 00:0c:29:4d:e4:f4

could not establish link

Using dm9000 device

TFTP from server 172.16.1.132; our IP address is 172.16.1.111

Filename 'u-boot.bin'.

Load address: 0x32000000

Loading: ########################

done

Bytes transferred = 337656 (526f8 hex)

SMDK2410 # nand erase 0 0x80000

NAND erase: device 0 offset 0x0, size 0x80000

Erasing at 0x60000 -- 100% complete.

OK

SMDK2410 # nand write 0x32000000 0 0x80000

NAND write: device 0 offset 0x0, size 0x80000

524288 bytes written: OK

SMDK2410 #

单板断电,拨到NAND启动,上电串口输出:

U-Boot 2012.04.01 (May 02 2013 - 20:37:59)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: *** failed ***

### ERROR ### Please RESET the board ###

启动了,但卡在NOR Flash,NAND启动没检测到NOR Flash 就hang()这是正常的。这里修改一下不然它卡住,直接输出0

arch/arm/lib/board.c530:修改如下:

puts("0 KB\n\r");

//puts(failed);

//hang();

修改后再次编译,应该就没问题了。发现还会卡在NET,暂时不支持网卡,先这样屏蔽arch/arm/lib/board.c:619//eth_initialize(gd->bd);同时将TQ2440.h131:

#define CONFIG_SYS_PROMPT "SMDK2410 # "改为#define CONFIG_SYS_PROMPT "TQ2440 # "

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make distclean

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make TQ2440_config

Configuring for TQ2440 board...

change@change:~/Si/TQ2440/u-boot-2012.04.01$ make

change@change:~/Si/TQ2440/u-boot-2012.04.01$ cp u-boot.bin /home/change/work/tftpboot/

change@change:~/Si/TQ2440/u-boot-2012.04.01$

OK编译通过,单板拨到NOR Flash启动,串口设置115200 8 n 1上电

U-Boot 2012.04.01 (Oct 25 2012 - 22:47:25)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: 0 KB

NAND: 256 MiB

*** Warning - bad CRC, using default environment

In: serial

Out: serial

Err: serial

Net: dm9000

Hit any key to stop autoboot: 0

SMDK2410 # set ipaddr 172.16.1.111

SMDK2410 # set gatewayip 172.16.1.1

SMDK2410 # set serverip 172.16.1.132

SMDK2410 # tftp 0x32000000 u-boot.bin

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 00:0c:29:4d:e4:f4

could not establish link

Using dm9000 device

TFTP from server 172.16.1.132; our IP address is 172.16.1.111

Filename 'u-boot.bin'.

Load address: 0x32000000

Loading: ########################

done

Bytes transferred = 337648 (526f0 hex)

SMDK2410 # nand erase 0 0x80000

NAND erase: device 0 offset 0x0, size 0x80000

Erasing at 0x60000 -- 100% complete.

OK

SMDK2410 # nand write 0x32000000 0 0x80000

NAND write: device 0 offset 0x0, size 0x80000

524288 bytes written: OK

SMDK2410 #

烧写刚刚移植的u-boot.bin到NAND,现在单板断电,拨到NAND启动,串口115200 8 n 1上电

U-Boot 2012.04.01 (May 02 2013 - 21:14:02)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: 0 KB

*** Warning - bad CRC, using default environment

In: serial

Out: serial

Err: serial

Net: no support

TQ2440 #

TQ2440 #

这样NAND启动基本正常了,还需要完善,支持更多的功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: