u-boot2010.03 移植篇(三)-----进一步修改start.S,smdk6410.h,支持nand启动及配置DM9000网卡

发布者:EnchantedHeart最新更新时间:2024-11-07 来源: cnblogs关键字:u-boot  start  nand启动 手机看文章 扫描二维码
随时随地手机看文章

----------------------------------------------------------
使用环境
PC:     Centos5.4

kernel: 3.0.1

corss:  arm-linux-gcc 4.4.1

arm:    s3c6410
uboot:  uboot-2010-03
----------------------------------------------------------

第一处修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#ifndef CONFIG_NAND_SPL
/*
 * flush v4 I/D caches
 */
mov r0, #0
mcr p15, 0, r0, c7, c7, 0/* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0/* flush v4 TLB */
/*
 * disable MMU stuff and caches////////////////////////////////////////////////
 */
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0//从后面拷贝过来的
///////////////////////////////以下的注释掉
  
/* Prepare to disable the MMU */
//adr r1, mmu_disable_phys
/* We presume we're within the first 1024 bytes */
//and r1, r1, #0x3fc
//ldr r2, _TEXT_PHY_BASE
//ldr r3, =0xfff00000
//and r2, r2, r3
//orr r2, r2, r1
//b mmu_disable
//.align 5
/* Run in a single cache-line */
//mmu_disable:
// mcr p15, 0, r0, c1, c0, 0
// nop
// nop
// mov pc, r2
////////////////////////////////////////////////////////////////////

第二处修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bl lowlevel_init  /* go setup pll,mux,memory */  之后
  
  
/* when we already run in ram, we don't need to relocate U-Boot.////////////////////////////////////////////////////////////////////
* and actually, memory controller must be configured before U-Boot
* is running in ram.
*/
 ldr r0, =0xff000fff
 bic r1, pc, r0 /* r0 <- current base addr of code */
 ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */
 bic r2, r2, r0 /* r0 <- current base addr of code */
 cmp     r1, r2                 /* compare r0, r1                  */
 beq      after_copy /* r0 == r1 then skip flash copy   */
#ifdef CONFIG_BOOT_NAND
  mov r0, #0x1000
 bl copy_from_nand
#endif 
after_copy:////////////////////////////////////////////////////////
#ifdef CONFIG_ENABLE_MMU

上面的修改是判断到底是从Nand Flash启动还是RAM启动;

1.如果是从nandflash中启动,那么PC的值一定在4K之内。那么执行完bicr1,pc,r0 之后,r1为0。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么不相等,则不跳转,下面应该就是copy_from_nand。
2.如果是从ram中启动,那么PC的值为0xx7e00000。那么执行完bicr1,pc,r0 之后,r1为0x00e00000。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么相等,跳转到after_copy,也就是不需要copy。承接上面分析,如果没有完成copy,则接下来就是copy_from_nand。

第三处修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#ifndef CONFIG_NAND_SPL
/*
 * we assume that cache operation is done before. (eg. cleanup_before_linux())
 * actually, we don't need to do anything about cache if not use d-cache in
 * U-Boot. So, in this function we clean only MMU. by scsuh
 *
 * void theLastJump(void *kernel, int arch_num, uint boot_params);
 */
#ifdef CONFIG_ENABLE_MMU
 .globl theLastJump
theLastJump:  
之前加上以下语句
  
/*
 * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
 * r0: size to be compared
 * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
 *////////////////////////////////////////////////////////////////////////////////
.globl copy_from_nand
  
copy_from_nand:
  mov r10, lr /* save return address */
  
  mov r9, r0
 /* get ready to call C functions */  
  
  
ldr sp, _TEXT_PHY_BASE/* setup temp stack pointer */
 sub sp, sp, #12
 mov fp, #0  /* no previous frame, so fp=0 */
 mov r9, #0x1000
 bl copy_uboot_to_ram          //此函数需要添加,稍后说明。
3: tst  r0, #0x0
  bne copy_failed
  ldr r0, =0x0c000000
  ldr r1, _TEXT_PHY_BASE
1: ldr r3, [r0], #4
  ldr r4, [r1], #4
 teq r3, r4
 bne compare_failed/* not matched */
 subs r9, r9, #4
 bne 1b
4: mov lr, r10   /* all is OK */
  mov pc, lr
copy_failed:
  nop  /* copy from nand failed */
     
b copy_failed
compare_failed:
 nop  /* compare failed */
 b compare_failed

      接着进入u-boot-2010.03/include/configs编辑smdk6410.h,添加下面的宏定义;

1.

1
#definevirt_to_phys(x) virt_to_phy_smdk6410(x)

2.

1
#defineCONFIG_SYS_PROMPT 'SMDK6410#' /*MonitorCommandPrompt */
1
这里的”SMDK6410”可以自己修改,这就是你进入uboot的命令模式的#前面的文字。
1

1
2
//#definePHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
#definePHYS_SDRAM_1_SIZE 0x10000000 /*256MBinBank#1 */

1
修改SDRAM内存为256M的。
1

1
2
3
4
/*NANDconfiguration*/
#defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
#defineNAND_ENABLE_CE()(NFCONT_REG&=~(1<<1))
#defineNF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
1
这里的定义是后面写nand_cp.c要用到的宏定义
1

1
2
3
4
5
/*
*Architecturemagicandmachinetype
*/
//#define MACH_TYPE 1270/*smdk6400ID*/
#defineMACH_TYPE 1626/*smdk6410ID*/
1
6410的ID号;
1

1
2
3
4
5
6
/*
*Sizeofmalloc()pool
*/
//#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+1024*1024)
#defineCONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+512*1024)
#defineCONFIG_SYS_GBL_DATA_SIZE 128 /*sizeinbytesforinitialdata*/
1
修改内存大小;
1

1
#defineCONFIG_BOOTDELAY 3
1
修改bootdelay延迟时间
1

1
2
3
4
//#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x7e00000)
/*126MBinDRAM*/
#defineCONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x9e00000)
/*256MBinDRAM*/
1
修改SDROM大小;
1

1
2
3
4
/*the PWMTImer4usesacounterof15625for10ms,soweneed*/
/*ittowrap100times (total1562500)toget1sec.*/
//#define CONFIG_SYS_HZ 1000 //atPCLK50MHz
#defineCONFIG_SYS_HZ 1562500
1
时钟修改;
1
10.
1
2
//#define CONFIG_STACKSIZE 0x40000 /*regularstack256KB*/
#defineCONFIG_STACKSIZE 0x80000 /*regularstack512KB*/
1
堆栈大小修改;
1
11.
1
2
//#define PHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */
#definePHYS_SDRAM_1_SIZE0x10000000 /*256MBinBank#1 */
1
Nand Flash每块大小修改;
1
12.
1
2
//#define CONFIG_ENV_SIZE 0x4000 /*TotalSizeofEnvironmentSector*/
#defineCONFIG_ENV_SIZE 0x80000 /*TotalSizeofEnvironmentSector*/
1
Total Size of Environment Sector修改;
1
13.
1
2
3
4
//#define CONFIG_BOOTCOMMAND 'nand read 0x50018000 0x60000 0x1c0000;'
//'bootm0x50018000'
#define CONFIG_BOOTCOMMAND 'nand read 0x50018000 0x100000 0x500000;'
'bootm0x50018000'
1
CONFIG_BOOTCOMMAND修改
1
14.
1
#defineCONFIG_ENV_OFFSET 0x0080000
1
CONFIG_ENV_OFFSET修改
1
15.
1
2
//#define CONFIG_SYS_NAND_PAGE_SIZE 2048
#defineCONFIG_SYS_NAND_PAGE_SIZE 4096
1
Nand Flash每一页大小的修改
1
16.
1
2
3
/*NANDchipblocksize */
//#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024)
#defineCONFIG_SYS_NAND_BLOCK_SIZE (512*1024)
1
Nand Flash每一块大小的修改
1
17.
1
2
3
/*NANDchippageperblockcount */
//#define CONFIG_SYS_NAND_PAGE_COUNT 64
#defineCONFIG_SYS_NAND_PAGE_COUNT 128
1
校验位修改
1
并将里面的所有6400除了(#define CONFIG_S3C6400          1)替换为6410
1

1
接下来在u-boot-2010.03/cpu/arm1176/下面新建一个nand_cp.c文件,代码如下:
1
2
3
4
#include
#ifdefCONFIG_S3C64XX
#include
#include
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include
staticintnandll_read_page(uchar*buf,ulongaddr,intlarge_block)
{
inti;
intpage_size=512;
/* 2K */
if(large_block==1)
page_size=2048;
/* 4K */
if(large_block==2)
page_size=4096;
NAND_ENABLE_CE();
NFCMD_REG=NAND_CMD_READ0;
/*WriteAddress*/
NFADDR_REG=0;
if(large_block)
NFADDR_REG=0;
1
2
3
4
5
6
7
8
9
10
NFADDR_REG=(addr)&0xff;
NFADDR_REG=(addr>>8)&0xff;
NFADDR_REG=(addr>>16)&0xff;
/*
#defineNFCMD_REG
__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFCMMD_OFFSET 0x08
NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
NFCMMD 0x70200008 NANDFlash命令设置寄存器0
1
2
3
4
5
6
7
8
9
10
11
12
13
#define NAND_CMD_READSTART 0x30
*/
if(large_block)
NFCMD_REG=NAND_CMD_READSTART;
/*
define NF_TRANSRnB()
do{ while( !( NFSTAT_REG&(1<<0) ) ); }while(0)
#define NFSTAT_REG
__REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
NFSTAT_REG=(*( (volatileu32*) (0x70200028) ))
NFSTAT 0x70200028 NANDFlash操作状态寄存器
*/
NF_TRANSRnB();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*forcompatibility(2460).u32cannotbeused.byscsuh*/
for(i=0;i
{
*buf++=NFDATA8_REG;
}
/*
#defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1))
#defineNFCONT_REG
__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
#define__REG(x) (*((volatileu32*)(x)))
#defineELFIN_NAND_BASE 0x70200000
#defineNFCONT_OFFSET 0x04
*/
NAND_DISABLE_CE();
return0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
staticintnandll_read_blocks(ulongdst_addr,ulongsize,int large_block)
{
uchar*buf=(uchar*)dst_addr;
inti;
uintpage_shift=9;
if(large_block==1)
page_shift=11;
/*Readpages*/
if(large_block==2)
page_shift=12;
if(large_block==2)
{
/*Readpages*/
for(i=0;i<4;i++,buf+=(1<<(page_shift-1)))
{
nandll_read_page(buf,i,large_block);
}
/*Readpages*/
/* 0x3c000 = 111100000000000000 */
1
2
3
4
5
6
7
8
9
10
11
12
13
for(i=4;i<(0x3c000>>page_shift);i++,buf+=(1<
{
nandll_read_page(buf,i,large_block);
}
}
else
{
for(i=0;i<(0x3c000>>page_shift);i++,buf+=(1<
{
nandll_read_page(buf,i,large_block);
}
}
return0;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
}
intcopy_uboot_to_ram(void)
{
intlarge_block =0;
inti;
vu_charid;
/*
#defineNAND_ENABLE_CE() (NFCONT_REG&=~(1<<1))
#defineNFCONT_REG
__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
#define__REG(x) (*((volatileu32*)(x)))
#defineELFIN_NAND_BASE 0x70200000
#defineNFCONT_OFFSET 0x04
NFCONT_REG=(*( (volatileu32*) (0x70200004) ))
NFCONT0x70200004 读/写NANDFlash控制寄存器
[0]1:NANDFlash控制器使能
*/
NAND_ENABLE_CE();
1
2
3
4
5
6
7
8
/*
#defineNFCMD_REG
__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFCMMD_OFFSET 0x08
NFCMD_REG=(*( (volatileu32*) (0x70200008) ))
NFCMMD 0x70200008 NANDFlash命令设置寄存器0
#defineNAND_CMD_READID 0x90
1
2
3
4
5
6
7
8
9
10
11
*/
NFCMD_REG=NAND_CMD_READID;
*
#defineNFADDR_REG
__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
#defineELFIN_NAND_BASE 0x70200000
#defineNFADDR_OFFSET 0x0C
NFADDR_REG =(*( (volatileu32*) (0x7020000C) ))
NFADDR0x7020000C NANDFlash地址设置寄存器
*/
NFADDR_REG= 0x00;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
#define NFDATA8_REG
__REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
#define__REGb(x) (*(vu_char*)(x))
NFDATA8_REG = (*( (vu_char*) (0x70200010) ))
NFDATA0x70200010 读/写NANDFlash数据寄存器
NANDFlash 读/烧写数据值用于I/O
*/
/*waitforawhile*/
for(i=0;i<200;i++);
id=NFDATA8_REG;
id=NFDATA8_REG;
if(id>0x80)
large_block=1;
if(id ==0xd5)
large_block=2;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*readNANDBlock.
*128KB->240KBbecauseofU-Bootsizeincrease.byscsuh
*So,read0x3c000bytesnot0x20000(128KB).
*/
/*
#define CONFIG_SYS_PHY_UBOOT_BASE
(CONFIG_SYS_SDRAM_BASE+0x07e00000)
#define CONFIG_SYS_SDRAM_BASE 0x50000000
CONFIG_SYS_PHY_UBOOT_BASE= 0x57e00000
0x3c000 = 1M
*/
returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,0x3c000,large_block);
}
#endif
1

1
修改u-boot-2010.03/cpu/arm1176/Makefile,在COBJS = cpu.o后面加nand_cp.o
1
COBJS   = cpu.o nand_cp.o
1
修改u-boot-2010.03/board/samsung/smdk6410/u-boot-nand.lds,添加nand_cp.o 如下:
1
2
3
4
5
6
7
8
{
cpu/arm1176/start.o (.text)
cpu/arm1176/s3c64xx/cpu_init.o (.text)
board/samsung/smdk6410/lowlevel_init.o (.text)
cpu/arm1176/nand_cp.o(.text)
lib_arm/board.o (.text)
*(.text)
}

[1] [2] [3]
关键字:u-boot  start  nand启动 引用地址:u-boot2010.03 移植篇(三)-----进一步修改start.S,smdk6410.h,支持nand启动及配置DM9000网卡

上一篇:u-boot2010.03 移植篇(二)-----修改start.S,支持nand启动
下一篇:u-boot2010.03 配置编译目标分析

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved