加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 18:20:11 所属栏目:百科 来源:网络整理
导读:一、????支持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 gene

一、????支持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

修改配置文件includeconfigstq2440.h,给u-boot分配512KB

#define CONFIG_SYS_TEXT_BASE 0x33f80000

增加文件boardtq2440nand_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);

? }

}

修改archarmcpuarm920tstart.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,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,LSR #4???????? /* r1 <- symbol index in .dynsym */

?????? add?????? r1,r1??????? /* r1 <- address of symbol in table*/

?????? ldr? r1,[r1,#4]????????????? /* r1 <- symbol value */

?????? add?????? r1,r9?????????? /* r1 <- relocated sym addr */

?????? b???? fixnext

fixrel:

?????? /* relative fix: increase location by offset */

?????? ldr? r1,[r0]

?????? add?????? r1,r9

fixnext:

?????? str? r1,[r0]

?????? add?????? 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,r4

?????? add?????? r1,r4

?????? mov????? r2,#0x00000000???????? /* clear???????????????????? ??? */

?

clbss_l:str? r2,[r0]????????????? /*clear loop...????????????? ??? */

?????? add?????? r0,#4

?????? cmp????? r0,r1

?????? bne?????? clbss_l

?

?????? bl coloured_LED_init

?????? bl red_led_on

#endif

#endif

修改archarmlibboard.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);

修改链接脚本archarmcpuu-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,具体代码如下archarmlibboard.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,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 #

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读