`
844604778
  • 浏览: 544754 次
文章分类
社区版块
存档分类
最新评论

u-boot-2012.04.01移植到TQ2440(六):支持NAND FLASH启动

 
阅读更多

一、支持NAND FLASH启动

新版u-boot在链接时加了“-pie”选项

-pie

Produce a position independentexecutable on targets which support it.For predictable results, you must also specify the same set of optionsthat were used to generate code (-fpie, -fPIE, or model suboptions) when youspecify this option.

产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意

位置,都可以正确的执行。

最终u-boot.bin中多了这些段

.rel.dyn : {

__rel_dyn_start = .;

*(.rel*)

__rel_dyn_end = .;

}

.dynsym : {

__dynsym_start = .;

*(.dynsym)

}

从NOR FLASH把代码复制到SDRAM,程序的链接地址是0,访问全局变量、静态变量、调用函数时是使用基于0地址编译得到的地址,现在把程序复制到了SDRAM(0x3000000),需要修改代码,把原来的地址改为新地址。这样太复杂了,我还是使用老版本的方法。

去掉“-pie”选项,在u-boot源码搜索“-pie”

root@zjh:/home/work/u-boot-2012.04.01#grep "\-pie" . -nR

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

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

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

去除arch/arm/config.mk:75:LDFLAGS_u-boot += -pie中的“-pie”

# needed for relocation

ifndef CONFIG_NAND_SPL

#LDFLAGS_u-boot +=-pie

endif

修改配置文件include\configs\tq2440.h,给u-boot分配512KB

#define CONFIG_SYS_TEXT_BASE 0x33f80000

增加文件board\tq2440\nand_read_ll.c并修改相应的Makefile

COBJS := tq2440.onand_read_ll.o

Nand_read_ll.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))

static intisBootFromNorFlash(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;

}

}

voidclear_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

#defineTWRPH0 1

#defineTWRPH1 0

/* 设置时序 */

NFCONF =(TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

/* 使能NAND Flash控制器,初始化ECC, 禁止片选 */

NFCONT =(1<<4)|(1<<1)|(1<<0);

}

static voidnand_select(void)

{

NFCONT &= ~(1<<1);

}

static voidnand_deselect(void)

{

NFCONT |= (1<<1);

}

static voidnand_cmd(unsigned char cmd)

{

volatile int i;

NFCMMD = cmd;

for (i = 0; i < 10; i++);

}

static voidnand_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 voidnand_wait_ready(void)

{

while (!(NFSTAT & 1));

}

static unsignedchar nand_data(void)

{

return NFDATA;

}

voidnand_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();

}

voidcopy_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_ll();

nand_read_ll((unsigned int)src, dest,len);

}

}

修改arch\arm\cpu\arm920t\start.S

call_board_init_f:

ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)

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

ldr r0,=0x00000000

ldr r1, _TEXT_BASE

ldr r2, _bss_start_ofs

bl copy_code_to_sdram

bl clear_bss

ldr pc, = board_init_f /* 跳转到SDRAM */

.globl second

second:

/* 调用第2阶段的代码 */

bl board_init_r

注释掉以下代码

#if 0

.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

beq clear_bss /* skip relocation */

mov r1, r6 /* r1 <- scratch forcopy_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.dynrelocations

*/

ldr r0, _TEXT_BASE /* r0 <- Text base */

sub r9, r6, r0 /* r9 <- relocation offset */

ldr r10,_dynsym_start_ofs /* r10 <- sym tableofs */

add r10, r10, r0 /* r10 <- sym table in FLASH */

ldr r2,_rel_dyn_start_ofs /* r2 <- reldyn 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, INFLASH! */

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:str r2, [r0] /*clear loop... */

add r0, r0, #4

cmp r0, r1

bne clbss_l

bl coloured_LED_init

bl red_led_on

#endif

#endif

修改arch\arm\lib\board.c中的函数board_init_f

//addr -=gd->mon_len;

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

addr =CONFIG_SYS_TEXT_BASE;

注视最后的重定位,并跳转到刚才定义的second

//relocate_code(addr_sp,id, addr);

second(id, addr);

修改链接脚本arch\arm\cpu\u-boot.lds把start.o、nand_read_ll.o、lowlevel_init.o编译到前面4k

CPUDIR/start.o (.text)

board/tq2440/libtq2440.o(.text)

重新编译,烧到NAND FLASH

TQ2440 # nand erase 040000;tftp 32000000 u-boot.bin;nand write 32000000 0 40000

NAND erase: device 0 offset0x0, size 0x40000

Erasing at 0x20000 -- 100%complete.

OK

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

DM9000: running in 16 bitmode

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

Using dm9000 device

TFTP from server172.28.12.60; our IP address is 172.28.12.10

Filename 'u-boot.bin'.

Load address: 0x32000000

Loading: T ###############

done

Bytes transferred = 208508(32e7c hex)

NAND write: device 0 offset0x0, size 0x40000

262144 bytes written: OK

TQ2440 #

从NAND FLASH启动

U-Boot 2012.04.01 (Dec 312012 - 11:57:16)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: *** failed ***

### ERROR ### Please RESETthe board ###

由于从NAND启动,CPU检测不到NOR FLASH,具体代码如下arch\arm\lib\board.c

#if!defined(CONFIG_SYS_NO_FLASH)

puts("Flash: ");

flash_size = flash_init();

if (flash_size > 0) {

# ifdefCONFIG_SYS_FLASH_CHECKSUM

char *s = getenv("flashchecksum");

print_size(flash_size, "");

/*

* Compute and printflash CRC if flashchecksum is set to 'y'

*

* NOTE: Maybe weshould add some WATCHDOG_RESET()? XXX

*/

if (s && (*s == 'y')) {

printf("CRC: %08X", crc32(0,

(const unsigned char *) CONFIG_SYS_FLASH_BASE,

flash_size));

}

putc('\n');

# else /* !CONFIG_SYS_FLASH_CHECKSUM */

print_size(flash_size, "\n");

# endif /*CONFIG_SYS_FLASH_CHECKSUM */

} else {

puts(failed);

hang();

}

#endif

void hang(void)

{

puts("### ERROR ### Please RESET the board ###\n");

for (;;);

}

我们直接注释掉上面的hang();

# endif /*CONFIG_SYS_FLASH_CHECKSUM */

} else {

puts(failed);

//hang();

}

#endif

重新编译,烧到NAND FLASH,从NAND启动

U-Boot 2012.04.01 (Dec 31 2012- 12:27:20)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: *** failed ***

NAND: 256 MiB

卡在这里,检查后发现修改start.S的时候调用第二阶段代码没有重新设置栈指针,做如下修改

board.c中的board_init_f函数

//relocate_code(addr_sp, id,addr);

second(id, addr, addr_sp);

start.S

second:

mov sp, r2 /*重新设置栈指针 */

/* 调用第2阶段的代码 */

bl board_init_r

重新编译,烧到NAND,从NAND启动

U-Boot 2012.04.01 (Dec 312012 - 12:31:58)

CPUID: 32440001

FCLK: 400 MHz

HCLK: 100 MHz

PCLK: 50 MHz

DRAM: 64 MiB

WARNING: Caches not enabled

Flash: *** failed ***

NAND: 256 MiB

In: serial

Out: serial

Err: serial

Net: dm9000

TQ2440 #

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics