u-boot移植第三弹——移植2013.10u-boot到RealARM210 cortex-A8开发板(支持moviNAND_Fusing_Tool_v2.0)

来源:互联网 发布:opengl 平移矩阵 编辑:程序博客网 时间:2024/06/11 10:02

在移植2012.10过程中遇到个麻烦的问题,到写这篇文章的时候还是没找原因在哪,导致无法正常运行。我遇到的问题如下:__bss_start和__bss_end__这两个地址无法正确得到地址,也就是bss段清除的时候失败,程序死掉。使用前两篇文件介绍的bl1,且没有开启重定位功能的情况下board_init_f这个函数中的addr -= gd->mon_len;这句一定要修改成你的u-boot基址,也就是CONFIG_SYS_TEXT_BASE的值,否则会很痛苦的。

如果哪位朋友知道__bss_start和__bss_end__这个不能正确得到地址的原因,还麻烦指点指点,呵呵。


由于上面说到的原因,一直也不知道是哪里的问题,所以就放弃了这个2012.10版本u-boot的移植,进而使用了2013.10版本的u-boot。前两篇分别记录了独立的bl1和2012.10版本u-boot配合这个bl1实现的启动。这篇相对于前两篇的移植记录有些区别,最大的区别就是(不是版本问题哈,呵呵)该篇文章记录的是使u-boot-2013.10这个版本u-boot支持moviNAND_Fusing_Tool_v2.0.exe这个软件,也就是说,编译生成的u-boot.bin可以使用moviNAND_Fusing_Tool_v2.0.exe这个软件直接下载到SD卡中,并不需要在linux系统下输入命令去烧写,当然,在linux下输入命令也是可以烧写的。为什么要这么做呢,我的情况是这样的,ubuntu在多次插拔SD卡后会出现不识别SD卡的现象,必须重启虚拟机才可以识别,相当的郁闷,导致非常没有效率。windows下就没这种情况啦,比较好用,而且下载还快。


我移植的u-boot-2013.10这个版本实际上是按照三星的1.3.4版本的u-boot启动方式来的。

可以看这个博文普及一下先,我就不贴在这里了,地址是http://blog.csdn.net/zsy2020314/article/details/9824035

对于代码我不做详细的解释,我这里说一下移植中可能比较重要的东西。

在移植中主要修改的文件有两类,板级类和CPU相关类。

板级类请参考我上传的源码v1.0-u-boot-2013.10中的board目录

CPU相关类请参考我上传的源码v1.0-u-boot-2013.10中的arch目录

v1.0-u-boot-2013.10中include目录是相关的配置头文件,boards.cfg和Makefile也是必须的。除此之外其他的文件或者文件夹不是移植中必须的,只是为了调试或者工具之类,可不必纠结在这些文件。由于本次u-boot.bin的下载是在windows下使用moviNAND_Fusing_Tool_v2.0.exe软件完成,所以linux下的sd_fusing工具也可以不用了。

源码地址在后边有贴出

如果想急着看运行效果可以直接拷贝我上传的源码到u-boot-2013.10版本官方源码中,使用合并替换功能即可。然后再终端输入make real210_config和make即可完成编译生成u-boot.bin文件,把u-boot.bin文件拷贝到windows中(具体怎么拷贝我就不多说了,方法很多种,使用觉得方便的即可),使用moviNAND_Fusing_Tool_v2.0.exe软件烧写到SD即可。启动即可看到如下所示的界面


下面介绍一下移植过程:

首先要理清代码的启动顺序,启动是以start.S为开始,那么就从这个文件开始走。全部代码如下:

/* * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core * * Copyright (c) 2004Texas Instruments <r-woodruff2@ti.com> * * Copyright (c) 2001Marius Gröger <mag@sysgo.de> * Copyright (c) 2002Alex Züpke <azu@sysgo.de> * Copyright (c) 2002Gary Jennejohn <garyj@denx.de> * Copyright (c) 2003Richard Woodruff <r-woodruff2@ti.com> * Copyright (c) 2003Kshitij <kshitij@ti.com> * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com> * * SPDX-License-Identifier:GPL-2.0+ */#include <asm-offsets.h>#include <config.h>#include <version.h>#include <asm/system.h>#include <linux/linkage.h>#include <configs/real210.h>#include <s5pc110.h>#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED).word 0x2000.word 0x0.word 0x0.word 0x0#endif.globl _start_start: bresetldrpc, _undefined_instructionldrpc, _software_interruptldrpc, _prefetch_abortldrpc, _data_abortldrpc, _not_usedldrpc, _irqldrpc, _fiq#ifdef CONFIG_SPL_BUILD_undefined_instruction: .word _undefined_instruction_software_interrupt:.word _software_interrupt_prefetch_abort:.word _prefetch_abort_data_abort:.word _data_abort_not_used:.word _not_used_irq:.word _irq_fiq:.word _fiq_pad:.word 0x12345678 /* now 16*4=64 */#else_undefined_instruction: .word undefined_instruction_software_interrupt:.word software_interrupt_prefetch_abort:.word prefetch_abort_data_abort:.word data_abort_not_used:.word not_used_irq:.word irq_fiq:.word fiq_pad:.word 0x12345678 /* now 16*4=64 */#endif/* CONFIG_SPL_BUILD */.global _end_vect_end_vect:.balignl 16,0xdeadbeef/************************************************************************* * * Startup Code (reset vector) * * do important init only if we don't start from memory! * setup Memory and board specific bits prior to relocation. * relocate armboot to ram * setup stack * *************************************************************************/.globl _TEXT_BASE_TEXT_BASE:#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE).wordCONFIG_SPL_TEXT_BASE#else.wordCONFIG_SYS_TEXT_BASE#endif/* * These are defined in the board-specific linker script. */.globl _bss_start_ofs_bss_start_ofs:.word __bss_start - _start.globl _bss_end_ofs_bss_end_ofs:.word __bss_end - _start.globl _end_ofs_end_ofs:.word _end - _start#ifdef CONFIG_USE_IRQ/* IRQ stack memory (calculated at run-time) */.globl IRQ_STACK_STARTIRQ_STACK_START:.word0x0badc0de/* IRQ stack memory (calculated at run-time) */.globl FIQ_STACK_STARTFIQ_STACK_START:.word 0x0badc0de#endif/* IRQ stack memory (calculated at run-time) + 8 bytes */.globl IRQ_STACK_START_INIRQ_STACK_START_IN:.word0x0badc0de/* * the actual reset code */reset:blsave_boot_params/* * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, * except if in HYP mode already */mrsr0, cpsrandr1, r0, #0x1f@ mask mode bitsteqr1, #0x1a@ test for HYP modebicner0, r0, #0x1f@ clear all mode bitsorrner0, r0, #0x13@ set SVC modeorrr0, r0, #0xc0@ disable FIQ and IRQmsrcpsr,r0/* * Setup vector: * (OMAP4 spl TEXT_BASE is not 32 byte aligned. * Continue to use ROM code vector only in OMAP4 spl) */#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */mrcp15, 0, r0, c1, c0, 0@ Read CP15 SCTRL Registerbicr0, #CR_V@ V = 0mcrp15, 0, r0, c1, c0, 0@ Write CP15 SCTRL Register/* Set vector address in CP15 VBAR register */ldrr0, =_startmcrp15, 0, r0, c12, c0, 0@Set VBAR#endif#ifndef CONFIG_EVT1bldisable_l2cachemovr0, #0x0@movr1, #0x0@ imovr3, #0x0movr4, #0x0lp1:movr2, #0x0@ jlp2:movr3, r1, LSL #29@ r3 = r1(i) <<29movr4, r2, LSL #6@ r4 = r2(j) <<6orrr4, r4, #0x2@ r3 = (i<<29)|(j<<6)|(1<<1)orrr3, r3, r4movr0, r3@ r0 = r3blCoInvalidateDCacheIndexaddr2, #0x1@ r2(j)++cmpr2, #1024@ r2 < 1024bnelp2@ jump to lp2addr1, #0x1@ r1(i)++cmpr1, #8@ r1(i) < 8bnelp1@ jump to lp1blset_l2cache_auxctrlblenable_l2cache#endifbldisable_l2cacheblset_l2cache_auxctrl_cycleblenable_l2cache/* the mask ROM code should have PLL and others stable */#ifndef CONFIG_SKIP_LOWLEVEL_INITblcpu_init_cp15blcpu_init_crit#endif/* 读取启动模式信息 */ldrr0, =PRO_ID_BASEldrr1, [r0,#OMR_OFFSET]bicr2, r1, #0xffffffc1/* NAND BOOT */cmpr2, #0x0@ 512B 4-cyclemoveqr3, #BOOT_NANDcmpr2, #0x2@ 2KB 5-cyclemoveqr3, #BOOT_NANDcmpr2, #0x4@ 4KB 5-cycle8-bit ECCmoveqr3, #BOOT_NANDcmpr2, #0x6@ 4KB 5-cycle16-bit ECCmoveqr3, #BOOT_NANDcmpr2, #0x8@ OneNAND Muxmoveqr3, #BOOT_ONENAND/* SD/MMC BOOT */cmp     r2, #0xcmoveq   r3, #BOOT_MMCSD/* NOR BOOT */cmp     r2, #0x14moveq   r3, #BOOT_NOR/* Uart BOOTONG failed */cmpr2, #(0x1<<4)moveqr3, #BOOT_SEC_DEVldrr0, =INF_REG_BASEstrr3, [r0, #INF_REG3_OFFSET]ldrr0, =0xE010E81C  /* PS_HOLD_CONTROL register */ldrr1, =0x00005301 /* PS_HOLD output high*/strr1, [r0]/* 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. */#if 0ldrsp, =(CONFIG_SYS_INIT_SP_ADDR)bicsp, sp, #7 /* 8-byte alignment for ABI compliance */ldrr0,=0x00000000#endifldrr1, =0xff000fffbicr2, pc, r1/* r0 <- current base addr of code */ldrr3, _TEXT_BASE/* r1 <- original base addr in ram */bicr3, r3, r1/* r0 <- current base addr of code */cmp r2, r3                  /* compare r0, r1     */beq run_in_ram/* r0 == r1 then skip sdram init   */#if defined(CONFIG_EVT1)/* If BL1 was copied from SD/MMC CH2 */ldrr0, =0xD0037488ldrr1, [r0]ldrr2, =0xEB200000cmpr1, r2beqmmcsd_boot#endifldrr0, =INF_REG_BASEldrr1, [r0, #INF_REG3_OFFSET]cmpr1, #BOOT_NAND/* 0x0 => boot device is nand */beqnand_bootcmpr1, #BOOT_ONENAND/* 0x1 => boot device is onenand */beqonenand_bootcmpr1, #BOOT_MMCSDbeqmmcsd_bootcmpr1, #BOOT_NORbeqnor_bootcmpr1, #BOOT_SEC_DEVbeqmmcsd_bootnand_boot:/*bl  ledon_1*/mmcsd_boot:/*bl  ledon_2*/blcopy_uboot_to_ramblrun_in_ramnor_boot:/*bl  ledon*/onenand_boot:/*bl  ledon*/run_in_ram:#if defined(CONFIG_ENABLE_MMU)enable_mmu:/* enable domain access */ldrr5, =0x0000ffffmcrp15, 0, r5, c3, c0, 0@load domain access register/* Set the TTB register */ldrr0, _mmu_table_baseldrr1, =CONFIG_PHY_UBOOT_BASEldrr2, =0xfff00000bicr0, r0, r2orrr1, r0, r1mcrp15, 0, r1, c2, c0, 0/* Enable the MMU */mmu_on:mrcp15, 0, r0, c1, c0, 0orrr0, r0, #1mcrp15, 0, r0, c1, c0, 0nopnopnopnop#endifbl  ledoffbl_main/*------------------------------------------------------------------------------*/ENTRY(c_runtime_cpu_setup)/* * If I-cache is enabled invalidate it */#ifndef CONFIG_SYS_ICACHE_OFFmcrp15, 0, r0, c7, c5, 0@ invalidate icachemcr     p15, 0, r0, c7, c10, 4@ DSBmcr     p15, 0, r0, c7, c5, 4@ ISB#endif/* * Move vector table *//* Set vector address in CP15 VBAR register */ldr     r0, =_startmcr     p15, 0, r0, c12, c0, 0  @Set VBARbxlrENDPROC(c_runtime_cpu_setup)/************************************************************************* * * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3) *__attribute__((weak)); * * Stack pointer is not yet initialized at this moment * Don't save anything to stack even if compiled with -O0 * *************************************************************************/ENTRY(save_boot_params)bxlr@ back to my callerENDPROC(save_boot_params).weaksave_boot_params/************************************************************************* * * cpu_init_cp15 * * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless * CONFIG_SYS_ICACHE_OFF is defined. * *************************************************************************/ENTRY(cpu_init_cp15)/* * Invalidate L1 I/D */movr0, #0@ set up for MCRmcrp15, 0, r0, c8, c7, 0@ invalidate TLBsmcrp15, 0, r0, c7, c5, 0@ invalidate icachemcrp15, 0, r0, c7, c5, 6@ invalidate BP arraymcr     p15, 0, r0, c7, c10, 4@ DSBmcr     p15, 0, r0, c7, c5, 4@ ISB/* * disable MMU stuff and caches */mrcp15, 0, r0, c1, c0, 0bicr0, r0, #0x00002000@ clear bits 13 (--V-)bicr0, r0, #0x00000007@ clear bits 2:0 (-CAM)orrr0, r0, #0x00000002@ set bit 1 (--A-) Alignorrr0, r0, #0x00000800@ set bit 11 (Z---) BTB#ifdef CONFIG_SYS_ICACHE_OFFbicr0, r0, #0x00001000@ clear bit 12 (I) I-cache#elseorrr0, r0, #0x00001000@ set bit 12 (I) I-cache#endifmcrp15, 0, r0, c1, c0, 0#ifdef CONFIG_ARM_ERRATA_716044mrcp15, 0, r0, c1, c0, 0@ read system control registerorrr0, r0, #1 << 11@ set bit #11mcrp15, 0, r0, c1, c0, 0@ write system control register#endif#ifdef CONFIG_ARM_ERRATA_742230mrcp15, 0, r0, c15, c0, 1@ read diagnostic registerorrr0, r0, #1 << 4@ set bit #4mcrp15, 0, r0, c15, c0, 1@ write diagnostic register#endif#ifdef CONFIG_ARM_ERRATA_743622mrcp15, 0, r0, c15, c0, 1@ read diagnostic registerorrr0, r0, #1 << 6@ set bit #6mcrp15, 0, r0, c15, c0, 1@ write diagnostic register#endif#ifdef CONFIG_ARM_ERRATA_751472mrcp15, 0, r0, c15, c0, 1@ read diagnostic registerorrr0, r0, #1 << 11@ set bit #11mcrp15, 0, r0, c15, c0, 1@ write diagnostic register#endifmovpc, lr@ back to my callerENDPROC(cpu_init_cp15)#ifndef CONFIG_SKIP_LOWLEVEL_INIT/************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * *************************************************************************/ENTRY(cpu_init_crit)/* * Jump to board specific initialization... * The Mask ROM will have already initialized * basic memory. Go here to bump up clock rate and handle * wake up conditions. */blowlevel_init@ go setup pll,mux,memoryENDPROC(cpu_init_crit)#endif#ifndef CONFIG_SPL_BUILD/* ************************************************************************* * * Interrupt handling * ************************************************************************* */@@ IRQ stack frame.@#define S_FRAME_SIZE72#define S_OLD_R068#define S_PSR64#define S_PC60#define S_LR56#define S_SP52#define S_IP48#define S_FP44#define S_R1040#define S_R936#define S_R832#define S_R728#define S_R624#define S_R520#define S_R416#define S_R312#define S_R28#define S_R14#define S_R00#define MODE_SVC 0x13#define I_BIT 0x80/* * use bad_save_user_regs for abort/prefetch/undef/swi ... * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling */.macrobad_save_user_regssubsp, sp, #S_FRAME_SIZE@ carve out a frame on current@ user stackstmiasp, {r0 - r12}@ Save user registers (now in@ svc mode) r0-r12ldrr2, IRQ_STACK_START_IN@ set base 2 words into abort@ stackldmiar2, {r2 - r3}@ get values for "aborted" pc@ and cpsr (into parm regs)addr0, sp, #S_FRAME_SIZE@ grab pointer to old stackaddr5, sp, #S_SPmovr1, lrstmiar5, {r0 - r3}@ save sp_SVC, lr_SVC, pc, cpsrmovr0, sp@ save current stack into r0@ (param register).endm.macroirq_save_user_regssubsp, sp, #S_FRAME_SIZEstmiasp, {r0 - r12}@ Calling r0-r12addr8, sp, #S_PC@ !! R8 NEEDS to be saved !!@ a reserved stack spot would@ be good.stmdbr8, {sp, lr}^@ Calling SP, LRstrlr, [r8, #0]@ Save calling PCmrsr6, spsrstrr6, [r8, #4]@ Save CPSRstrr0, [r8, #8]@ Save OLD_R0movr0, sp.endm.macroirq_restore_user_regsldmiasp, {r0 - lr}^@ Calling r0 - lrmovr0, r0ldrlr, [sp, #S_PC]@ Get PCaddsp, sp, #S_FRAME_SIZEsubspc, lr, #4@ return & move spsr_svc into@ cpsr.endm.macro get_bad_stackldrr13, IRQ_STACK_START_IN@ setup our mode stack (enter@ in banked mode)strlr, [r13]@ save caller lr in position 0@ of saved stackmrslr, spsr@ get the spsrstrlr, [r13, #4]@ save spsr in position 1 of@ saved stackmovr13, #MODE_SVC@ prepare SVC-Mode@ msrspsr_c, r13msrspsr, r13@ switch modes, make sure@ moves will executemovlr, pc@ capture return pcmovspc, lr@ jump to next instruction &@ switch modes..endm.macro get_bad_stack_swisubr13, r13, #4@ space on current stack for@ scratch reg.strr0, [r13]@ save R0's value.ldrr0, IRQ_STACK_START_IN@ get data regions start@ spots for abort stackstrlr, [r0]@ save caller lr in position 0@ of saved stackmrslr, spsr@ get the spsrstrlr, [r0, #4]@ save spsr in position 1 of@ saved stackldrlr, [r0]@ restore lrldrr0, [r13]@ restore r0addr13, r13, #4@ pop stack entry.endm.macro get_irq_stack@ setup IRQ stackldrsp, IRQ_STACK_START.endm.macro get_fiq_stack@ setup FIQ stackldrsp, FIQ_STACK_START.endm/* * exception handlers */.align5undefined_instruction:get_bad_stackbad_save_user_regsbldo_undefined_instruction.align5software_interrupt:get_bad_stack_swibad_save_user_regsbldo_software_interrupt.align5prefetch_abort:get_bad_stackbad_save_user_regsbldo_prefetch_abort.align5data_abort:get_bad_stackbad_save_user_regsbldo_data_abort.align5not_used:get_bad_stackbad_save_user_regsbldo_not_used#ifdef CONFIG_USE_IRQ.align5irq:get_irq_stackirq_save_user_regsbldo_irqirq_restore_user_regs.align5fiq:get_fiq_stack/* someone ought to write a more effective fiq_save_user_regs */irq_save_user_regsbldo_fiqirq_restore_user_regs#else.align5irq:get_bad_stackbad_save_user_regsbldo_irq.align5fiq:get_bad_stackbad_save_user_regsbldo_fiq#endif /* CONFIG_USE_IRQ */#endif 
可把下图所示的流程对着上面的代码仔细看看,这里不多说。所调用的函数位置在http://blog.csdn.net/zsy2020314/article/details/9824035这个博文中都有说明,我也不多说了。当然我的start.S与其他人的可能有所不同,为了支持windows下软件可下载,这个start.S最开始的地方有如下代码:

#if defined(CONFIG_EVT1) && !defined(CONFIG_FUSED).word 0x2000.word 0x0.word 0x0.word 0x0#endif

这个是必须要有的,具体原因不详,可能是软件的要求,去掉是无法启动的。
下面这个是对板子的前期初始化,主要是时钟、内存、串口的初始化:

#ifndef CONFIG_SKIP_LOWLEVEL_INITblcpu_init_cp15blcpu_init_crit#endif
最终调用的是lowlevel_init这个函数对板子的前期初始化。lowlevel_init函数在板级目录下文件lowlevel_init.S中,请看源码我不贴出了。主要进行的是时钟、内存、串口等的初始化工作。mem_setup.S文件就是内存的初始化。mmc_boot.c文件是从SD卡拷贝代码到ram的函数。

ENTRY(cpu_init_crit)/* * Jump to board specific initialization... * The Mask ROM will have already initialized * basic memory. Go here to bump up clock rate and handle * wake up conditions. */blowlevel_init@ go setup pll,mux,memoryENDPROC(cpu_init_crit)

下面是代码的拷贝部分,在初始化板子之后会有一个启动判断,以及决定去哪个地方拷贝代码到内存,代码是下面的部分:

/* 读取启动模式信息 */ldrr0, =PRO_ID_BASEldrr1, [r0,#OMR_OFFSET]bicr2, r1, #0xffffffc1/* NAND BOOT */cmpr2, #0x0@ 512B 4-cyclemoveqr3, #BOOT_NANDcmpr2, #0x2@ 2KB 5-cyclemoveqr3, #BOOT_NANDcmpr2, #0x4@ 4KB 5-cycle8-bit ECCmoveqr3, #BOOT_NANDcmpr2, #0x6@ 4KB 5-cycle16-bit ECCmoveqr3, #BOOT_NANDcmpr2, #0x8@ OneNAND Muxmoveqr3, #BOOT_ONENAND/* SD/MMC BOOT */cmp     r2, #0xcmoveq   r3, #BOOT_MMCSD/* NOR BOOT */cmp     r2, #0x14moveq   r3, #BOOT_NOR/* Uart BOOTONG failed */cmpr2, #(0x1<<4)moveqr3, #BOOT_SEC_DEVldrr0, =INF_REG_BASEstrr3, [r0, #INF_REG3_OFFSET]ldrr0, =0xE010E81C  /* PS_HOLD_CONTROL register */ldrr1, =0x00005301 /* PS_HOLD output high*/strr1, [r0]/* 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. */#if 0ldrsp, =(CONFIG_SYS_INIT_SP_ADDR)bicsp, sp, #7 /* 8-byte alignment for ABI compliance */ldrr0,=0x00000000#endifldrr1, =0xff000fffbicr2, pc, r1/* r0 <- current base addr of code */ldrr3, _TEXT_BASE/* r1 <- original base addr in ram */bicr3, r3, r1/* r0 <- current base addr of code */cmp r2, r3                  /* compare r0, r1     */beq run_in_ram/* r0 == r1 then skip sdram init   */#if defined(CONFIG_EVT1)/* If BL1 was copied from SD/MMC CH2 */ldrr0, =0xD0037488ldrr1, [r0]ldrr2, =0xEB200000cmpr1, r2beqmmcsd_boot#endifldrr0, =INF_REG_BASEldrr1, [r0, #INF_REG3_OFFSET]cmpr1, #BOOT_NAND/* 0x0 => boot device is nand */beqnand_bootcmpr1, #BOOT_ONENAND/* 0x1 => boot device is onenand */beqonenand_bootcmpr1, #BOOT_MMCSDbeqmmcsd_bootcmpr1, #BOOT_NORbeqnor_bootcmpr1, #BOOT_SEC_DEVbeqmmcsd_bootnand_boot:/*bl  ledon_1*/mmcsd_boot:/*bl  ledon_2*/blcopy_uboot_to_ramblrun_in_ramnor_boot:/*bl  ledon*/onenand_boot:
判断的结果当然是从SD卡启动了,这时会调用copy_uboot_to_ram函数进行代码的搬移,也就是拷贝bl2,然后就直接跳到内存中运行了,blrun_in_ram这句代码不必关心。

跳到内存后当然又是从reset处开始运行了,不过这次得运行于刚启动时运行的不同,跳到内存运行后是不会再对时钟和内存做初始化了,尤其是内存不能做初始化,因为已经在内存中运行了,再初始化,肯定会当掉,所以在跳转到内存后这部分的初始化会跳过的。
另外下面这部分代码也会做判断,判断程序是否在内存中运行,如果是就直接跳转到run_in_ram处继续执行,不再进行bl2的搬运了

ldrr1, =0xff000fffbicr2, pc, r1/* r0 <- current base addr of code */ldrr3, _TEXT_BASE/* r1 <- original base addr in ram */bicr3, r3, r1/* r0 <- current base addr of code */cmp r2, r3                  /* compare r0, r1     */beq run_in_ram/* r0 == r1 then skip sdram init   */

run_in_ram这部分做的是什么呢,代码如下:

run_in_ram:#if defined(CONFIG_ENABLE_MMU)enable_mmu:/* enable domain access */ldrr5, =0x0000ffffmcrp15, 0, r5, c3, c0, 0@load domain access register/* Set the TTB register */ldrr0, _mmu_table_baseldrr1, =CONFIG_PHY_UBOOT_BASEldrr2, =0xfff00000bicr0, r0, r2orrr1, r0, r1mcrp15, 0, r1, c2, c0, 0/* Enable the MMU */mmu_on:mrcp15, 0, r0, c1, c0, 0orrr0, r0, #1mcrp15, 0, r0, c1, c0, 0nopnopnopnop#endifbl  ledoffbl_main

可以看到最后跳转到了_main函数运行,这个函数在crt0.S中定义,上面部分有个mmu的条件编译,如果定义了CONFIG_ENABLE_MMU宏就开启内存映射功能,否则就不开启。

在_main函数中前后会调用board_init_f和board_init_r,最后进入u-boot控制台。


修改的源码下载地址http://download.csdn.net/detail/u010406724/6924075(我没有下载资源分了,所以本资源我设置了2个下载分,以后会取消下载分的)


需要对u-boot.lds的链接做个说明,也就是指定某个文件的函数放在u-boot的前8K之中,因为bl1用了8K,如果调用的函数在这之外,那么bl1肯定是失败的。可以的话大家可以自行测试一下,我就不贴出我自己的测试了。

这里贴出我的这个文件代码:

/* * Copyright (c) 2004-2008 Texas Instruments * * (C) Copyright 2002 * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> * * SPDX-License-Identifier:GPL-2.0+ */OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{. = 0x00000000;. = ALIGN(4);.text :{*(.__image_copy_start)CPUDIR/start.o (.text*)board/samsung/real210/real210_board.o(.text)/*用户添加*/*(.text*)}. = ALIGN(4);.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }. = ALIGN(4);.data : {*(.data*)}. = ALIGN(4);. = .;. = ALIGN(4);.u_boot_list : {KEEP(*(SORT(.u_boot_list*)));}. = ALIGN(4);.image_copy_end :{*(.__image_copy_end)}.rel_dyn_start :{*(.__rel_dyn_start)}.rel.dyn : {*(.rel*)}.rel_dyn_end :{*(.__rel_dyn_end)}_end = .;/* * Deprecated: this MMU section is used by pxa at present but * should not be used by new boards/CPUs. */. = ALIGN(4096);.mmutable : {*(.mmutable)}/* * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c * __bss_base and __bss_limit are for linker only (overlay ordering) */.bss_start __rel_dyn_start (OVERLAY) : {KEEP(*(.__bss_start));__bss_base = .;}.bss __bss_base (OVERLAY) : {*(.bss*) . = ALIGN(4); __bss_limit = .;}.bss_end __bss_limit (OVERLAY) : {KEEP(*(.__bss_end));}/DISCARD/ : { *(.dynsym) }/DISCARD/ : { *(.dynstr*) }/DISCARD/ : { *(.dynamic*) }/DISCARD/ : { *(.plt*) }/DISCARD/ : { *(.interp*) }/DISCARD/ : { *(.gnu*) }/DISCARD/ : { *(.ARM.exidx*) }/DISCARD/ : { *(.gnu.linkonce.armexidx

由上可以知道我添加的是
board/samsung/real210/real210_board.o(.text)/*用户添加*/

这一行代码,也就是把real210_board.o文件链接进来。这个文件在哪里呢,这个文件是在编译时产生的,位置在board/samsung/real210这个目录。real210_board.o又是由哪些文件生成的呢,这就需要看makefile了。

这里说明一下,u-boot-2013.10版本u-boot与1.3.4版本u-boot的连接可能不太一样,不是只要把连接的目标添加到u-boot.lds就可以的,还需要修改makefile才行,否则就会报重定义的错误。我的makefile文件代码如下:

## (C) Copyright 2000, 2001, 2002# Wolfgang Denk, DENX Software Engineering, wd@denx.de.## (C) Copyright 2008# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>## See file CREDITS for list of people who contributed to this# project.## This program is free software; you can redistribute it and/or# modify it under the terms of the GNU General Public License as# published by the Free Software Foundation; either version 2 of# the License, or (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston,# MA 02111-1307 USA#include $(TOPDIR)/config.mk#下面为用户添加,功能是把lowlevel_init.o mem_setup.o mmc_boot.o这三个目标独立出来,生成real210_board.o,用于在u-boot.lds中做链接#这样做的目的是,为了在增加该目录下代码量时,不影响生成u-boot.bin前8K的BL1LIBReal= $(obj)real210_board.oREAL210_board := lowlevel_init.o mem_setup.o mmc_boot.oSRCS    := $(REAL210_board:.o=.S) REAL210_board := $(addprefix $(obj),$(REAL210_board))#上面为用户添加LIB= $(obj)lib$(BOARD).oCOBJS-y:= real210.o#COBJS-$(CONFIG_SAMSUNG_ONENAND)+= onenand.oSOBJS:= SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)OBJS:= $(addprefix $(obj),$(COBJS-y))SOBJS:= $(addprefix $(obj),$(SOBJS))#下面为用户添加,下面的ALL一定不能少,它的意思是告诉编译器后面的两个LIB全部都要编译,不加只会编译前面的一个,后面的不会编译ALL:$(LIB) $(LIBReal) $(LIBReal):$(obj).depend $(REAL210_board) $(call cmd_link_o_target, $(REAL210_board))#上面为用户添加$(LIB) :$(obj).depend $(SOBJS) $(OBJS)$(call cmd_link_o_target, $(SOBJS) $(OBJS))########################################################################## defines $(obj).depend targetinclude $(SRCTREE)/rules.mksinclude $(obj).depend#########################################################################

注释已经很详细了,我不多解释了。


好了本篇到此告一段落。下一篇是加入DM9000的网络支持。


还有个栈的问题未弄明白,还得再看看。也就是CONFIG_SYS_INIT_SP_ADDR这个宏的值是多少的问题,以后还得看看,或者谁了解告知我,感激不尽。


copy_uboot_to_ram这个函数的问题请参考我的另一篇博客http://blog.csdn.net/wang_shuai_ww/article/details/19235833。










1 0
原创粉丝点击