亮仔移植u-boot系列之-- S3c2440在最新版本U-boot-2015.10移植(支持SPL模式启动) -- 3

   这章讲解BL2阶段的代码重定位和串口功能的实现.

   在BL1阶段执行最后一句代码:

   ldr pc, =CONFIG_SYS_TEXT_BASE

  此时PC指针重新指向b reset命令,第二阶段无需重新做cpu,时钟之类的初始化,直接执行BL _main命令设置BL2模式下的sp.我将BL2模式下DDR的分布设置如下:

--------------------0x30000000 + 64M
u-boot.bin
--------------------0x30008000
.
.(not use)
--------------------0x30001000
global data 
--------------------0x30001000 - 176
GD 
--------------------0x30001000 - 176 - GD_SIZE
.SP.
.
---------------------0x30000000</span>

    设置完堆栈后执行

    BL  board_init_r,下面是详细分析这段函数的相关代码和注释:

gd->mon_len = (ulong)&__bss_end - (ulong)_start;//记录代码段起始地址到bss_end总大小
↓
↓
init_baud_rate();//设置串口波特率为115200
↓
↓
serial_init();   //设置uart时钟,新版的u-boot支持2440的时钟配置,只需将CONFIG_S3C2440 = 1;不用像u-boot-1.1.6那样重新写代码
       ↓
       ↓
       get_current()->start();//相当于调用了serial_init_dev(0);函数,下面有分析
           ↓
           ↓
            dev = default_serial_console();//我们需要调用serial_s3c24x0.c中的函数,查看MakeFile发现obj-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o
                                           //<strong>因此需要在yl2440.h中定义CONFIG_S3C24X0_SERIAL</strong>
                     ↓
                return &s3c24xx_serial0_device;//我们默认使用serial0,因此需要在yl2440.h中<strong>#define CONFIG_SERIAL1 1</strong>
                而struct serial_device s3c24xx_serial0_device = INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0"); 将  INIT_S3C_SERIAL_STRUCTURE展开即
                struct serial_device s3c24xx_serial0_device = 
                {
	            .name	= "s3ser0",			\
	            .start	= s3serial0_init,		\
	            .stop	= NULL,				\
	            .setbrg	= s3serial0_setbrg,		\
	            .getc	= s3serial0_getc,		\
	            .tstc	= s3serial0_tstc,		\
	            .putc	= s3serial0_putc,		\
	            .puts	= s3serial0_puts,		\ /* printf()--->>> dev->puts() */
                } 
↓
↓               
gd->ram_size = PHYS_SDRAM_1_SIZE; //在yl2440.h中定义成64M
↓
↓
setup_dest_addr(); //首先将gd->relocaddr设置为0x30000000+0x4000000(64M)
     ↓
     ↓
     gd->relocaddr = 0x30000000+0x4000000;
↓
↓    
reserve_uboot
     ↓
     ↓
     gd->relocaddr -= gd->mon_len; //relocaddr指向代码重定位的地址
     gd->start_addr_sp = gd->relocaddr;
↓
↓     
 reserve_malloc()     
     ↓
     ↓
     gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;
↓
↓
reserve_board
     ↓
     ↓
     gd->start_addr_sp -= sizeof(bd_t);
     gd->bd = gd->start_addr_sp;
     将bd区域清0
↓
↓
reserve_global_data()
     ↓
     ↓
     gd->start_addr_sp -= sizeof(gd_t);
     gd->new_gd = gd->start_addr_sp ;
↓
↓
reserve_stacks()
     ↓
     ↓
     gd->start_addr_sp -= 16;
     gd->start_addr_sp &= ~0xf; 
↓
↓
setup_reloc();
     ↓
     ↓
     gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;//gd->reloc_off = gd->relocaddr - 0x30008000; 
     memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));//  0x30001000-176-GD_SIAZE ---->>>> gd->new_gd搬移

     需要说明的是在该函数调用的board_early_init_f()中将设置PLL相关部分全部注释掉,因为之前的时钟设置已经在BL1阶段设置好了.

     board_init_r退出重新设置新的sp指针:LDR SP [r9 #GD_START_ADDR_SP] /* sp = gd->start_addr_sp这个值已经之前设置好了 */

     从新的gd地址找到新的gd->relocaddr即代码重定位的地址,调用b  relocate_code后,此时新的DDR分布如下:

-------------0x304000000 sdram end(64M)
.
.
<strong>u-boot.bin + 动态链接库(不是很清楚,估计和相对地址有关)</strong>
.
-------------gd->relocaddr  0x304000000 - (gd->mon_len)
malloc lenth
-------------0x304000000 - (gd->mon_len + malloc_lenth)
bd(记录板子的信息,如bd->baudrate)
-------------0x304000000 - (gd->mon_len + malloc_lenth + bd)
gd(记录初始化参数,如gd->start_addr_sp)
-------------0x304000000 - (gd->mon_len + malloc_lenth + bd + gd)
16Byte
-------------gd->start_addr_sp 0x304000000 - (gd->mon_len + malloc_lenth + bd + gd + 16)
sp
-------------
.
.(not use)
-------------
kernel(2M)
-------------0x30800000
.
.boot param
-------------0x30000100
(not use)
-------------0x30000000

    由于在4K IRAM内的中断向量表是BL1阶段的向量表,因而需要执行搬移BL2的向量表到4K IRAM内

    bl relocate_vectors

    最后执行

    ldr pc, =board_init_r

    进入板子的第二阶段初始化工作,此时在串口已经可以显示U-BOOT2015.10的信息了.串口功能调试完毕.

    总结:

    U-Boot第二阶段(BL2)最开始将位于用户定义的代码链接地址从0x30008000重定位到SDRAM顶端,并生成了一个动态链接库rel_dyn_start到rel_dyn_end.并重新设置sp,拷贝就得bd数据到新的bd区域,重定位向量表,最终执行第二阶段的板卡初始化.

    这个阶段代码重定位完毕,串口已经可以跑起来了.

    我们知道U-boot终极目的是引导内核,因此我们还需要以下功能:

    功能1:u-boot支持tftp下载内核到DDR中,因此需要配置DM9000网卡

    功能2:u-boot需要支持Nand读写,将内核及环境变量写到Nand Flash的相关位置,上电后将镜像读到DDR

    功能3:u-boot能将位于DDR的内核进行引导,最终U-boot寿命结束,控制权交给内核


    本章结束,下一章将介绍如何配置DM9000,实现网卡的下载功能.


    遗留问题:动态链接库、中断重定位的细节




     



  

    



    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值