u-boot-2016.05移植:(2)、修改时钟 初始化sdram 重定位u-boot 配置smdk2440.h 修改u-boot.lds

来源:互联网 发布:淘宝账号怎么找回来 编辑:程序博客网 时间:2024/06/06 17:56

1、修改时钟:
在u-boot-2016.05\arch\arm\cpu\arm920t\start.S中将

    /*      * 设置时钟       */    /* FCLK:HCLK:PCLK = 1:2:4 */    /* default FCLK is 120 MHz ! */    ldr r0, =CLKDIVN    mov r1, #3    str r1, [r0]

替换为:

    /*      * 设置时钟       */    ldr r0, =0x4c000014    mov r1, #0x05;            // FCLK:HCLK:PCLK=1:4:8    str r1, [r0]    /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */    mrc p15, 0, r1, c1, c0, 0       /* 读出控制寄存器 */     orr r1, r1, #0xc0000000         /* 设置为“asynchronous bus mode” */    mcr p15, 0, r1, c1, c0, 0       /* 写入控制寄存器 */#define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))    /* MPLLCON = S3C2440_MPLL_200MHZ */    ldr r0, =0x4c000004    ldr r1, =S3C2440_MPLL_400MHZ    str r1, [r0]    /* 启动ICACHE */    mrc p15, 0, r0, c1, c0, 0   @ read control reg    orr r0, r0, #(1<<12)    mcr p15, 0, r0, c1, c0, 0   @ write it back

在u-boot-2016.05\board\samsung\smdk2440\smdk2440.c的board_early_init_f函数中将原来的时钟设置删掉:

    /* to reduce PLL lock time, adjust the LOCKTIME register */    writel(0xFFFFFF, &clk_power->locktime);    /* configure MPLL */    writel((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV,&clk_power->mpllcon);

2、初始化sdram:
将u-boot-2016.05\board\samsung\smdk2440\lowlevel_init.S中原来的配置sdram的初始化数据

SMRDATA:    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)    .word 0x32    .word 0x30    .word 0x30

替换为我们自己的:

SMRDATA:    .long 0x22011110     //BWSCON    .long 0x00000700     //BANKCON0    .long 0x00000700     //BANKCON1    .long 0x00000700     //BANKCON2    .long 0x00000700     //BANKCON3      .long 0x00000740     //BANKCON4    .long 0x00000700     //BANKCON5    .long 0x00018005     //BANKCON6    .long 0x00018005     //BANKCON7    .long 0x008C04F4     //REFRESH    .long 0x000000B1     //BANKSIZE    .long 0x00000030     //MRSRB6    .long 0x00000030     //MRSRB7

3、重定位u-boot:
①、将init.c文件添加到u-boot-2016.05\board\samsung\smdk2440文件夹中,并在该文件夹下的Makefile中末尾添上

obj-y += init.o

②、在u-boot-2016.05\arch\arm\lib\crt0.S中将

    mov r0, sp    bl  board_init_f_alloc_reserve    mov sp, r0    /* set up gd here, outside any C code */    mov r9, r0    bl  board_init_f_init_reserve    mov r0, #0    bl  board_init_f

替换为

        bl nand_init_ll        mov r0, #0        ldr r1,= CONFIG_SYS_TEXT_BASE        ldr r2,= 0x80000        bl copy_code_to_sdram        bl clear_bss        ldr pc, =call_board_init_fcall_board_init_f:        mov     r0, sp        bl      board_init_f_alloc_reserve        mov     sp, r0        /* set up gd here, outside any C code */        mov     r9, r0        bl      board_init_f_init_reserve        mov     r0, #0        bl      board_init_f

注意:其中

        mov r0, #0        ldr r1,=CONFIG_SYS_TEXT_BASE        ldr r2,=0x4b000

分别是uboot重定位时的源、目的、长度。uboot的长度本想像修改u-boot-2012.04.01一样通过定义:

        .globl _bss_start_ofs_bss_start_ofs:        .word __bss_start - _start

来求得,但是失败了,具体原因还未找到,所以长度就先用稍微大于u-boot的数值。
4、配置smdk2440.h:
在u-boot-2016.05\include\configs\smdk2440.h中,
①、添加

#define DEBUG

以能够输出DEBUG信息。
②、注释掉

#define CONFIG_S3C2410      /* specifically a SAMSUNG S3C2410 SoC */#define CONFIG_SMDK2410     /* on a SAMSUNG SMDK2410 Board */

添加

#define CONFIG_S3C2440#define CONFIG_SMDK2440

③、修改CONFIG_SYS_TEXT_BASE的值为:

#define CONFIG_SYS_TEXT_BASE    0x33f00000

CONFIG_SYS_TEXT_BASE的值根据uboot的大小而定。
④、注释掉以下暂时用不到的各项

#define CONFIG_USB_KEYBOARD#define CONFIG_USB_STORAGE#define CONFIG_DOS_PARTITION
#define CONFIG_RTC_S3C24X0
#define CONFIG_BOOTP_BOOTFILESIZE#define CONFIG_BOOTP_BOOTPATH#define CONFIG_BOOTP_GATEWAY#define CONFIG_BOOTP_HOSTNAME
#define CONFIG_CMD_DATE
#define CONFIG_CMD_UBI#define CONFIG_CMD_UBIFS#define CONFIG_CMD_MTDPARTS#define CONFIG_MTD_DEVICE#define CONFIG_MTD_PARTITIONS#define CONFIG_YAFFS2#define CONFIG_RBTREE

特别提示:CONFIG_ARM在自动配置文件include/config/auto.conf中设置为y:

CONFIG_ARM=y

编译u-boot时将自动配置,所以,CONFIG_ARM是宏定义了的。
5、修改u-boot.lds的代码段,使board/samsung/smdk2440和arch/arm/lib两个文件夹中的文件链接到靠前的位置

    .text :    {        *(.__image_copy_start)        *(.vectors)        CPUDIR/start.o (.text*)        board/samsung/smdk2440/built-in.o (.text*)        arch/arm/lib/built-in.o (.text*)        *(.text*)    }

6、现在,编译并烧到开发板nand flash就应该有如下面的输出

U-Boot 2016.05 (Aug 15 2016 - 16:00:34 +0800)CPUID: 32440001FCLK:      400 MHzHCLK:      100 MHzPCLK:       50 MHzDRAM:  0 Bytes

但是我们看到DRAM大小没有识别出来,现在来解决DRAM大小识别的问题,一步一步按照启动流程阅读代码,可发现

DRAM:  0 Bytes

的显示是在初始化函数序列init_sequence_f中的show_dram_config函数中,DRAM的大小输出的是gd->bd->bi_dram[i].size 的值,而gd->bd->bi_dram[i].size 是在同为初始化函数序列中的setup_dram_config中赋值的,如下:

__weak void dram_init_banksize(void){#if defined(CONFIG_NR_DRAM_BANKS) && defined(CONFIG_SYS_SDRAM_BASE)    gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;    gd->bd->bi_dram[0].size = get_effective_memsize();#endif}

再看dram_init_banksize的反汇编代码:

33f0ab84 <dram_init_banksize>:33f0ab84:   e5992000    ldr r2, [r9]33f0ab88:   e3a03203    mov r3, #805306368  ; 0x3000000033f0ab8c:   e92d4010    push    {r4, lr}33f0ab90:   e5823048    str r3, [r2, #72]33f0ab94:   e5994000    ldr r4, [r9]33f0ab98:   eb001a42    bl  33f114a8 <get_effective_memsize>33f0ab9c:   e584004c    str r0, [r4, #76]33f0aba0:   e8bd8010    pop {r4, pc}

r9=gd=全局数据结构体的地址,经过JTAG调试发现赋值号右边的值没错,而问题是在gd->bd指针的值上,它的值并没有在sdram的地址范围内,是个无效地址,所以才没有赋值成功,gd->bd->bi_dram[i].size 总是0,gd->bd初始值是在初始化函数序列init_sequence_f中的reserve_board函数中和gd->start_addr_sp联系在一起的

static int reserve_board(void){    if (!gd->bd) {        ...        gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));        memset(gd->bd, '\0', sizeof(bd_t));        ...    }    return 0;}

而gd->start_addr_sp初始值是在初始化函数序列init_sequence_f中的reserve_uboot函数中被赋以gd->relocaddr,所以去修改gd->relocaddr的值,在
u-boot-2016.05\common\board_f.c:reserve_uboot函数中用

    gd->relocaddr = CONFIG_SYS_TEXT_BASE;

替换

    gd->relocaddr -= gd->mon_len;    gd->relocaddr &= ~(4096 - 1);

然后编译并烧写到nand flash就可以显示DRAM的大小了。
7、board_init_r函数运行参数的准备:
①、在u-boot-2016.05\common\board_f.c:board_init_f函数中添加变量定义

extern unsigned int new_gd;

去掉

#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \        !defined(CONFIG_EFI_APP)    /* NOTREACHED - jump_to_copy() does not return */    hang();#endif

并在函数结尾添加

new_gd = (unsigned int)(gd->new_gd);

其中 gd->new_gd 是在初始化函数序列init_sequence_f中的setup_reloc中赋值的,如下:

static int setup_reloc(void){    ...    memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));    ...}

②、在u-boot-2016.05/arch/arm/lib/crt0.S中入口声明ENTRY(_main) 前面添加定义:

.globl new_gdnew_gd:    .long 0

在下面这段代码中

/* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return * 'here' but relocated. */    ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */#if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */    mov r3, sp    bic r3, r3, #7    mov sp, r3#else    bic sp, sp, #7  /* 8-byte alignment for ABI compliance */#endif    ldr r9, [r9, #GD_BD]        /* r9 = gd->bd */    sub r9, r9, #GD_SIZE        /* new GD is below bd */    adr lr, here    ldr r0, [r9, #GD_RELOC_OFF]     /* r0 = gd->reloc_off */    add lr, lr, r0#if defined(CONFIG_CPU_V7M)    orr lr, #1              /* As required by Thumb-only */#endif    ldr r0, [r9, #GD_RELOCADDR]     /* r0 = gd->relocaddr */    b   relocate_code

分别去掉

ldr r9, [r9, #GD_BD]
sub r9, r9, #GD_SIZE
ldr r0, [r9, #GD_RELOCADDR]
b   relocate_code

然后,在下面这段代码中

/* call board_init_r(gd_t *id, ulong dest_addr) */    mov     r0, r9                  /* gd_t */    ldr r1, [r9, #GD_RELOCADDR] /* dest_addr */

去掉

mov     r0, r9                  /* gd_t */

添加

ldr r0, new_gd

特别注意:不要认为下面这段代码不重要,可以删掉,在尝试删掉之后出现了c文件中某些变量地址分配出现了错误,所以下面这段代码不能删除,必须保留。

here:/* * now relocate vectors */    bl  relocate_vectors/* Set up final (full) environment */    bl  c_runtime_cpu_setup /* we still call old routine here */

8、将u-boot-2016.05\common\board_r:board_init_r函数中

#if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)    gd = new_gd;#endif

gd = new_gd 语句外的条件编译去掉。
9、去掉编译中的-pie参数
在u-boot-2016.05/arch/arm/config.mk中去掉

LDFLAGS_u-boot += -pie

此时编译u-boot会提示错误:

Makefile:1385: recipe for target 'checkarmreloc' failed

参考“recipe for target ‘checkarmreloc’ failed解决办法”去解决。之后编译烧写到nand flash就会正常输出了:

U-Boot 2016.05 (Aug 22 2016 - 02:00:09 +0800)initcall: 33f0aa6cU-Boot code: 33F00000 -> 33F480E8  BSS: -> 33F92BE0initcall: 33f0113cCPUID: 32440001FCLK:      400 MHzHCLK:      100 MHzPCLK:       50 MHzinitcall: 33f0ad18DRAM:  initcall: 33f004fcinitcall: 33f0abd0Monitor len: 00092BE0Ram size: 04000000Ram top: 34000000initcall: 33f0a84cinitcall: 33f0aa14TLB table from 33ff0000 to 33ff4000initcall: 33f0a864initcall: 33f0a9dcReserving 586k for U-Boot at: 33f00000initcall: 33f0a9b0Reserving 4160k for malloc() at: 33af0000initcall: 33f0acccReserving 80 Bytes for Board Info at: 33aeffb0initcall: 33f0a86cinitcall: 33f0a97cReserving 168 Bytes for Global Data at: 33aeff08initcall: 33f0a904initcall: 33f0a8a0initcall: 33f0a874initcall: 33f0ac70Ram size: 04000000gd->bd->bi_dram[0].start: 30000000gd->bd->bi_dram[0].size: 04000000get_effective_memsize: 04000000initcall: 33f0ab48RAM Configuration:Bank #0: 30000000 64 MiBDRAM:  64 MiBinitcall: 33f0a8e8New Stack Pointer is: 33aefee0initcall: 33f0ab0cinitcall: 33f0aa9cRelocation Offset is: 00000000Relocating to 33f00000, new gd at 33aeff08, sp at 33aefee0initcall: 33f0ad94initcall: 33f0aeacRelocating to 33f00000, new gd at 33aeff08, sp at 33aefee0initcall: 33f0af9c (relocated to 33f0af9c)WARNING: Caches not enabledinitcall: 33f0ad9c (relocated to 33f0ad9c)initcall: 33f0adc4 (relocated to 33f0adc4)initcall: 33f0af80 (relocated to 33f0af80)using memory 0x33af0000-0x33f00000 for malloc()initcall: 33f0adcc (relocated to 33f0adcc)initcall: 33f0ad70 (relocated to 33f0ad70)initcall: 33f0af6c (relocated to 33f0af6c)initcall: 33f0053c (relocated to 33f0053c)dram_bank_mmu_setup: bank: 0initcall: 33f115a8 (relocated to 33f115a8)initcall: 33f0af5c (relocated to 33f0af5c)initcall: 33f0ae90 (relocated to 33f0ae90)Now running in RAM - U-Boot at: 33f00000initcall: 33f0add4 (relocated to 33f0add4)initcall: 33f0aee0 (relocated to 33f0aee0)Flash: fwc addr 00000000 cmd f0 00f0 16bit x 16 bitfwc addr 0000aaaa cmd aa 00aa 16bit x 16 bitfwc addr 00005554 cmd 55 0055 16bit x 16 bitfwc addr 0000aaaa cmd 90 0090 16bit x 16 bitfwc addr 00000000 cmd f0 00f0 16bit x 16 bitJEDEC PROBE: ID f0 ea00 0fwc addr 00000000 cmd ff 00ff 16bit x 16 bitfwc addr 00000000 cmd 90 0090 16bit x 16 bitfwc addr 00000000 cmd ff 00ff 16bit x 16 bitJEDEC PROBE: ID 90 ea00 00 Bytesinitcall: 33f0ae74 (relocated to 33f0ae74)NAND:  board_nand_init()end of nand_initdev_readydev_readydev_readydev_ready0 MiBinitcall: 33f0ae44 (relocated to 33f0ae44)*** Warning - bad CRC, using default environmentDestroy Hash Table: 33f42c20 table = 00000000Create Hash Table: N=75INSERT: table 33f42c20, filled 1/79 rv 33af50b8 ==> name="bootdelay" value="5"INSERT: table 33f42c20, filled 2/79 rv 33af4f78 ==> name="baudrate" value="115200"INSERT: table 33f42c20, filled 3/79 rv 33af4f28 ==> name="ipaddr" value="10.0.0.110"INSERT: table 33f42c20, filled 4/79 rv 33af50e0 ==> name="serverip" value="10.0.0.1"INSERT: table 33f42c20, filled 5/79 rv 33af5374 ==> name="netmask" value="255.255.255.0"INSERT: free(data = 33af4e88)INSERT: doneinitcall: 33f0ad84 (relocated to 33f0ad84)initcall: 33f11668 (relocated to 33f11668)initcall: 33f0ae34 (relocated to 33f0ae34)initcall: 33f0f334 (relocated to 33f0f334)In:    serialOut:   serialErr:   serialInitial value for argc=3Final value for argc=3Initial value for argc=3Final value for argc=3Initial value for argc=3Final value for argc=3initcall: 33f00c6c (relocated to 33f00c6c)initcall: 33f0ae24 (relocated to 33f0ae24)initcall: 33f0ae04 (relocated to 33f0ae04)initcall: 33f0ade8 (relocated to 33f0ade8)Net:   Initial value for argc=3Final value for argc=3CS8900-0Error: CS8900-0 address not set.initcall: 33f0addc (relocated to 33f0addc)### main_loop entered: bootdelay=5### main_loop: bootcmd="<UNDEFINED>"SMDK2440 # 
0 0