移植uboot2017.01(四)

接着上一节的继续分析和实验


    bl  gpio_out
    bl  led1_on

    /* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl  cpu_init_cp15
#ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY
    bl  cpu_init_crit        /* 上一节分析到这里,面的lowlevel_init,我们初始化了ddr */
#endif
#endif

    /* 同时开发吧制锁和K都打印出来了,说明下一步要执行_main */
    /* 开发板制锁*/
    ldr r0, = 0xe010e81c
    ldr r1, = 0x301
    str r1, [r0]

    ldr     r1, =0xe2900020
    ldr     r2, =0x4b
    str     r2, [r1]
    
    bl  _main

上一节分析了跳转到打印出了K就死掉了,首先我们判断_main子程序是否在16K以内。

打开u-boot.map查看_main的地址,发现0xce0小于16k,所以在16k以内,所以继续分析。

调到_main中继续分析,_main 要做的事

 arch/arm/lib/crt0.S 

/*
 * entry point of crt0 sequence
 */

ENTRY(_main)

/*
 * Set up initial C runtime environment and call board_init_f(0).
 */

#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)  /* 我们没定义这个 */
	ldr	sp, =(CONFIG_SPL_STACK)
#else
    /* 在s5pv210.h中定义,见下面分析,0x33000000 */
	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)        
#endif
#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, sp 8字节对齐 */
#endif
	mov	r0, sp      /* 把上面的0x33000000,作为参数传给下面c函数 */   
	bl	board_init_f_alloc_reserve
	mov	sp, r0      /* c函数的返回值又给sp */ 
	/* set up gd here, outside any C code */
	mov	r9, r0      /* r0即当前sp给r9,  r9是gd全局变量的指针,同时作为参数传递给下面函数 */
	bl	board_init_f_init_reserve

	mov	r0, #0
	bl	board_init_f    /* 把参数0,传给下面函数,并调用它 */

上面用到的宏

/* DRAM Base 我们的ddr_base就是这里,所以不用改*/
#define CONFIG_SYS_SDRAM_BASE		0x30000000

/* 0x34000000 */
#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x4000000)

/* 0x33000000 */
#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_LOAD_ADDR - 0x1000000)

_main的前半部分的大体功能知道了,现在要确定到底有没有执行。

即调用的三个C函数都有没有在16k以内。

搜索u-boot.map,里面发现第一个函数就超出了16K(0xa8c8)。

所以我们要在执行这个之前把整个uboot搬移到ddr,并完成绝对跳转。

根据手册applicate_note给出的说明,编写代码。

在board/samsung/smdkv210/下增加mmc_relocate.c 文件,并添加搬移代码

typedef int _bool;

typedef _bool (*copy_sd_to_mem)(unsigned int,unsigned int, unsigned short, unsigned int*,_bool);


void mmc_relocate(void)
{
    copy_sd_to_mem uboot_copy = (copy_sd_to_mem)(*(unsigned int*)(0xd0037f98));

    unsigned int ch = *(volatile unsigned int*)(0xd0037488);

    if(ch == 0xeb000000)
    {   

    }   
    else if(ch == 0xeb200000)
    {   
        /* 只要大于33号扇区就都可以,我搬移了400k */
        uboot_copy(2, 49, 800,(unsigned int*) 0x34800000, 0); 
    }   
}

在Makefile中增加

 obj-y   := smdkv210.o mmc_relocate.o

添加到lowlevel_init里面的ddr初始化后面

    
    bl  mem_ctrl_asm_init


    bl  mmc_relocate

    /* 打印出搬移完的uboot的前四个字节数据 */
    ldr r0, =0x34800000
    bl  uart_print_hex

为了今后方便烧写和测试,编写如下脚本

#! /bin/bash

./make-16k u-boot.bin u-boot-16k.bin

sudo dd iflag=dsync oflag=dsync if=u-boot-16k.bin of=/dev/sdb seek=1
sudo dd iflag=dsync oflag=dsync if=u-boot.bin of=/dev/sdb seek=49

                                                          

使用如下命令查看uboot.bin的数据

hexdump -C u-boot.bin |less

发现和u-boot.bin一致,证明uboot搬移成功。

下面就是从16k的IRAM跳转到DDR运行了。


    /* 开发板制锁*/
    ldr r0, = 0xe010e81c
    ldr r1, = 0x301
    str r1, [r0]

    ldr     r1, =0xe2900020
    ldr     r2, =0x4b
    str     r2, [r1]
    bl led3_on

    /* 使用绝对跳转指令,跳转到_main的链接地址去运行 */
    ldr pc, =jump_ddr
jump_ddr:
    
    bl  _main

还是打印的和之前的一样,没有增加什么。

理论上是要打印一些信息的,因为接下来的一段代码都是和硬件无关的。

后来查看了好久发现,人家用的是串口2打印的,虽然我在smdkv210.h中该了串口号,但新的uboot是用设备树进行设备管理的,这个串口2的地址写死了,不能通过smdkv210.h配置了。因为我设备树还没怎么学,所以就先不改了,继续用原来配置的串口2调试。将来学习了设备树,再修改串口号。

下面是打印出来的信息。

可以看到我的板子没oneNand,但却打印出来信息,说明最后应该是在oneNand这里又跑飞了。

猜你喜欢

转载自blog.csdn.net/qq_16777851/article/details/81677050