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

U-boot-2014.04移植到MINI2440(9) nor flash启动和nand flash

发布时间:2020-12-15 07:20:48 所属栏目:百科 来源:网络整理
导读:在mini2440上,nor flash启动和nand flash启动可以满足不同的需要,这里进行移植,nor的启动移植比较简单,因为不需要进行代码的重定向,nand的启动相对复杂,这里先从nor开始,进入正题: ?????? ?????? 一 . 修改支持 nor flash 启动 ?????? 第一步:修改

在mini2440上,nor flash启动和nand flash启动可以满足不同的需要,这里进行移植,nor的启动移植比较简单,因为不需要进行代码的重定向,nand的启动相对复杂,这里先从nor开始,进入正题:

??????

?????? .修改支持nor flash启动

?????? 第一步:修改mini2440.h

?????? 在第27行:

?????? #define CONFIG_SYS_TEXT_BASE?????? 0x30008000

?????? 这里将这个值改为0x0,因为从nor flash启动,直接在0地址执行就可以,不需要再拷贝到sdram中。修改为:

?????? #define CONFIG_SYS_TEXT_BASE?????? 0x0

?????? 之前我的帖子分析的start.s启动过程等等,都是对应的没有做代码重定向,没有从nand启动,因为那时候只在sdram里执行u-boot,在第37行:

?????? //#define CONFIG_SKIP_LOWLEVEL_INIT

?????? 将其注释掉,这样程序执行:

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

?????? bl??? cpu_init_crit

#endif

?????? 因为我们没有定义CONFIG_SKIP_LOWLEVEL_INIT,所以程序就会跳转到cpu_init_crit里面,在cpu_init_crit里面,程序进一步跳转到????

mov?????? ip,lr

?????? bl??? lowlevel_init

?????? mov?????? lr,ip

?????? 进入lowlevel_init以后,就会执行这一段代码:

?????? ldr????r0,=SMRDATA

?????? ldr?? r1,=CONFIG_SYS_TEXT_BASE

?????? sub? r0,r0,r1

?????? 因为TEXT_BASE现在被我们设置为了0,SMRDATA就会从相对0地址的地方开始,这样我们就可以从nor flash启动。

??????

第二步:修改lowlevel_init.s

?????? 第113行:

?????? #define REFCNT??????????????????? 1113??????

?????? 这个REFCNT其实是位宽和刷新频率的设置,这里需要做一个修改,改为如下:

?????? #define REFCNT??????????????????? 0x4f4

??????

第三步:编译测试

?????? 这里我编译没有问题,下载进去在执行erase的时候,无法擦除我的nor flash,这可能是我原来的u-boot对nor flash的第一个块进行了保护,即使protectoff all也没用,但是可以擦除别的块,所以这里我借助了j-link来下载我移植的u-boot到nor flash。具体的下载步骤不懂得可以上网查下,下载进去之后启动,输出如下信息:

U-Boot 2014.04 (Sep 02 2015 - 15:09:02)

?

CPUID: 32440001

FCLK:?????400 MHz

HCLK:?????100 MHz

PCLK:??????50 MHz

DRAM:?64 MiB

WARNING: Caches not enabled

Flash: 2 MiB

NAND:?256 MiB

*** Warning - bad CRC,using defaultenvironment

?

In:???serial

Out:??serial

Err:??serial

Net:??dm9000

MINI2440 Deep_l_zh #

说明我们是可以从nor启动了,下面进入nand的移植,我们一般nor只是用来调试和学习,所以掌握从nand启动是很重要的。

??????

?????? .nand flash启动移植

?????? 第一步:去除-pie选项

?????? 在arch/arm/config.mk中,第82行,修改如下:

?????? # needed for relocation

#LDFLAGS_u-boot += -pie

?????? 这里是为了避免重定向后新的地址比较复杂,所以还是采用老的办法进行修改。

?????? 第二步:修改mini2440.h

?????? 重新将TEXT_BASE制定为0x33f80000

?????? #define CONFIG_SYS_TEXT_BASE?????? 0x33f80000

?????? 第三步:添加nand_read_b.c文件并修改makefile

?????? 在/board/mini2440/mini2440下,修改Makefile,将其编译进去,修改部分如下:

obj-y????? :=mini2440.o

obj-y????? += nand_read_b.o

obj-y????? +=lowlevel_init.o

?????? 接着再该目录下创建nand_read_b.c文件,该文件所有内容如下:

#define NFCONF(*((volatile unsigned long*)0x4E000000))

#define NFCONT(*((volatileunsigned long *)0x4E000004))

#define NFCMMD(*((volatileunsigned char *)0x4E000008))

#define NFADDR(*((volatileunsigned char *)0x4E00000C))

#define NFDATA(*((volatileunsigned char *)0x4E000010))

#define NFSTAT(*((volatileunsigned char *)0x4E000020))

?

?

?

static void nand_read_b(unsignedint addr,unsigned char *buf,unsigned int len);

?

static intisBootFromNorFlash(void)

{

?????? volatileint *p = (volatile int *)0;

?????? intval;

?????? val= *p;

?????? *p= 0x12345678;

?????? if(*p == 0x12345678)

?????? {

?????? /*写成功, nand 启动 */

?????? *p= val;

?????? return0;

?????? }????

?????? else

????????????? {

???????????????????? /*NOR 不能像内存一样写 */

???????????????????? return1;

???????????????????? }

}

?

void nand_init_b(void)

{

????????????? #defineTACLS 3

????????????? #defineTWRPH0 3

????????????? #defineTWRPH1 2

????????????? /*设置时序 */

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

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

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

}

?

void copy_code_to_sdram(unsignedchar *src,unsigned char *dest,unsigned int len)

{

int i = 0;

/* 如果是 NOR 启动 */

?????? if(isBootFromNorFlash())

?????? {

?????? while(i < len)

????????????? {

???????????????????? dest[i]= src[i];

????????????? i++;

????????????? }

?????? }

else

?????? {

?????? nand_init_b();

?????? nand_read_b((unsignedint)src,dest,len);

?????? }

}

?

void clear_bss(void)

{

?????? externint __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(unsignedchar cmd)

{

?????? volatileint i;

?????? NFCMMD= cmd;

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

}

?

static void nand_addr(unsignedint addr)

{

?????? unsignedint col = addr % 2048;

?????? unsignedint page = addr / 2048;

?????? volatileint 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 charnand_data(void)

{

??return NFDATA;

}

?

static void nand_read_b(unsignedint addr,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();

}

?

第四步:修改crt0.S

?????? 在arch/arm/lib/crt0.S文件中,修改如下:

?????? ENTRY(_main)

?

/*

?* Set up initial C runtime environment andcall board_init_f(0).

?*/

?

#ifdefined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)

?????? ldr?? sp,=(CONFIG_SPL_STACK)

#else

?????? ldr?? sp,=(CONFIG_SYS_INIT_SP_ADDR)

#endif

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

?????? sub? sp,#GD_SIZE???? /* allocate one GD aboveSP */

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

?????? mov?????? r9,sp??????????? /* GD is above SP */

??????

?????? #if 1

?????? __TEXT_BASE:

?????? .word CONFIG_SYS_TEXT_BASE

?????? mov r0,#0

?????? ldr r1,__TEXT_BASE

?????? ldr r2,__TEXT_BASE

?????? ldr r3,=__bss_end

?????? sub r2,r3,r2

?????? bl copy_code_to_sdram

?????? bl clear_bss

?????? ldr pc,=call_board_init_f

?????? call_board_init_f:

?????? mov r0,#0

?????? bl board_init_f

?????? ldr sp,[r9,#GD_START_ADDR_SP] /* sp =gd->start_addr_sp */

?????? bic sp,#7 /* 8-byte alignment forABI compliance */

?????? ldr r9,#GD_BD] /* r9 = gd->bd */

?????? subr9,r9,#GD_SIZE /* new GD is below bd*/

?????? ldr r1,__TEXT_BASE

?????? bl board_init_r

?????? #else

?????? mov?????? r0,#0

?????? bl??? board_init_f

?

#if !defined(CONFIG_SPL_BUILD)

?

/*

?* Set up intermediate environment (new sp andgd) and call

?* relocate_code(addr_moni). Trick here is thatwe'll return

?* 'here' but relocated.

?*/

?

?????? ldr?? sp,#GD_START_ADDR_SP] /* sp =gd->start_addr_sp */

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

?????? ldr?? r9,#GD_BD]???????????? /* r9 = gd->bd*/

?????? sub? r9,#GD_SIZE???????????? /* new GD isbelow bd */

?

?????? adr? lr,here

?????? ldr?? r0,#GD_RELOC_OFF]????????? /* r0 =gd->reloc_off */

?????? add lr,lr,r0

?????? ldr?? r0,#GD_RELOCADDR]??????? /* r0 =gd->relocaddr */

?????? b???? relocate_code

here:

?

/* Set up final(full) environment */

?

?????? bl??? c_runtime_cpu_setup /* we still call old routine here */

?

?????? ldr?? r0,=__bss_start?? /* this is auto-relocated!*/

?????? ldr?? r1,=__bss_end?????????? /* this isauto-relocated! */

?

?????? mov?????? r2,#0x00000000??????? /* prepare zero toclear BSS */

?

clbss_l:cmp?? r0,r1??????????????????? /*while not at end of BSS */

?????? strlo?????? r2,[r0]????????? /* clear 32-bit BSS word */

?????? addlo???? r0,#4????????????? /* move to next */

?????? blo? clbss_l

?

?????? bl coloured_LED_init

?????? bl red_led_on

?

?????? /* call board_init_r(gd_t *id,ulongdest_addr) */

?????? mov????r0,r9????????????????? /* gd_t */

?????? ldr?? r1,#GD_RELOCADDR] /* dest_addr */

?????? /* call board_init_r */

?????? ldr?? pc,=board_init_r?????? /* this isauto-relocated! */

?

?????? /* we should not return here. */

#endif

#endif

?

ENDPROC(_main)

?

?????? 第五步:修改board_init_f函数

?????? 在arch/arm/lib/board.c中,第265行,修改为:

?????? unsigned intboard_init_f(ulong bootflag)

{

bd_t *bd;

?????? init_fnc_t **init_fnc_ptr;

?????? gd_t *id;

?????? 注释掉372的addr,添加新的addr:

?????? //addr -= gd->mon_len;

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

addr=CONFIG_SYS_TEXT_BASE;

在结尾461行添加:

?????? memcpy(id,(void *)gd,sizeof(gd_t));

?????? return (unsignedint)id;

}

?

?????? 第六步:修改common.h

?????? 在/include下,common.h第298行,修改为:

?????? unsigned int board_init_f(ulong);

??????

第七步:修改链接脚本u-boot.lds

?????? 在arch/arm/cpu/下,u-boot.lds,第20行:

*(.__image_copy_start)

?????? CPUDIR/start.o (.text*)

?????? board/mini2440/mini2440/lowlevel_init.o(.text*)

?????? board/mini2440/mini2440/nand_read_b.o(.text*)

?????? *(.text*)

?????? 同时需要修改/board/mini2440/mini2440下的Makefile,修改如下:

? ? ? ? obj-y????? :=mini2440.o

extra-y?? :=nand_read_b.o

extra-y?? +=lowlevel_init.o

??????

?????? 第八步:修改顶层/arch/arm/config.mk

?????? 注释掉checkarmreloc这部分,否则编译会出错

在第105行:

?????? #ALL-y += checkarmreloc

??????

?????? 第九步:编译测试

?????? 从nor启动,然后下载到nand之后,关闭电源,s2开关打到nand处启动,出现如下信息:

?U-Boot 2014.04 (Sep 02 2015 - 18:54:01)

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 ###

?????? 因为这时候从nand启动,检测不到nor flash的信息,但是使用友善的u-boot从nand启动是可以读到nor的信息的,并且可以使用nor的命令对其进行操作,看来这个地址空间还有很多文章,这里能够从nand启动进行内核引导的是我们的目的。所以,屏蔽这个错误,这个错误在我们移植nor flash读写的时候就探讨过了,这里进去arch/arm/lib/board.c,第577行:

?????? # endif /* CONFIG_SYS_FLASH_CHECKSUM */

?????? } else {

????????????? puts(failed);

?????? //???? hang();

?????? }

?????? 把这个hang()函数注释掉。

?????? 再次编译下载。

?U-Boot 2014.04 (Sep 02 2015 - 19:06:04)

CPUID: 32440001

FCLK:?????400 MHz

HCLK:?????100 MHz

PCLK:??????50 MHz

DRAM:?64 MiB

WARNING: Caches not enabled

Flash: *** failed ***

NAND:?256 MiB

*** Warning - bad CRC,using defaultenvironment

?

In:???serial

Out:??serial

Err:??serial

Net:??dm9000

MINI2440 Deep_l_zh #

?????? 可以看到成功了,不得不说,移植过程参照网上大神移植到tq2440的帖子,但是期间遇到了很多小问题,这里没有一一写下来,对自己还是收获不少,如有不正确,还请指出,大家共同进步!

(编辑:李大同)

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

    推荐文章
      热点阅读