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

来源:互联网 发布:红蜘蛛 软件 编辑:程序博客网 时间:2024/06/01 22:44

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

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

   ldr pc, =CONFIG_SYS_TEXT_BASE

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

--------------------0x30000000 + 64Mu-boot.bin--------------------0x30008000..(not use)
--------------------0x30001000global data --------------------0x30001000 - 176GD 
--------------------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
原创粉丝点击