barebox分析

本文详细分析了Barebox的启动过程,从入口函数barebox_arm_head()开始,经过reset函数,到board_init_lowlevel()的板级初始化,包括关闭看门狗、PLL初始化、SDRAM设置等。接着,通过board_init_lowlevel_return()进行代码重定位和bss段清零,最终执行start_barebox(),运行初始化函数并启动命令循环。在/env/bin/init中,处理环境变量和执行默认脚本,实现系统的进一步配置和启动。
摘要由CSDN通过智能技术生成

启动分析

arch\arm\目录下是对应构架的目录

Makefile文件

lds-$(CONFIG_GENERIC_LINKER_SCRIPT)    :=arch/arm/lib/barebox.lds

lds-$(CONFIG_BOARD_LINKER_SCRIPT)  := $(BOARD)/barebox.lds

配置时使用arch/arm/lib/barebox.lds链接脚本。

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

OUTPUT_ARCH(arm)

ENTRY(start)

SECTIONS

{

  . = TEXT_BASE;

arch/arm/Makefile:143:TEXT_BASE = $(CONFIG_TEXT_BASE)

CONFIG_TEXT_BASE是在配置文件中配置的

TEXT_BASE

  PRE_IMAGE

 

  . = ALIGN(4);

  .text      :

  {

     _stext = .;

     _text = .;

     *(.text_entry*)

      __ll_return = .;

     *(.text_ll_return*)

#ifdef CONFIG_ARCH_EP93XX

     /* the EP93xx expects to find the pattern 'CRUS' at 0x1000 */

    . = 0x1000;

    LONG(0x53555243) /* 'CRUS' */

#endif

     __bare_init_start = .;

     *(.text_bare_init*)

     __bare_init_end = .;

      __exceptions_start = .;

     KEEP(*(.text_exceptions*))

     __exceptions_stop = .;

     *(.text*)

  }

  BAREBOX_BARE_INIT_SIZE

 

  . = ALIGN(4);

  .rodata : { *(.rodata*) }

 

#ifdef CONFIG_ARM_UNWIND

  /*

   * Stack unwinding tables

   */

  . = ALIGN(8);

  .ARM.unwind_idx : {

     __start_unwind_idx = .;

     *(.ARM.exidx*)

     __stop_unwind_idx = .;

  }

  .ARM.unwind_tab : {

     __start_unwind_tab = .;

     *(.ARM.extab*)

     __stop_unwind_tab = .;

  }

#endif

  _etext = .;          /* End of text and rodata section */

 

  . = ALIGN(4);

  .data : { *(.data*) }

 

  . = ALIGN(4);

  .got : { *(.got*) }

 

  . = .;

  __barebox_cmd_start = .;

  .barebox_cmd : { BAREBOX_CMDS }

  __barebox_cmd_end = .;

 

  __barebox_magicvar_start = .;

  .barebox_magicvar : { BAREBOX_MAGICVARS }

  __barebox_magicvar_end = .;

 

  __barebox_initcalls_start = .;

  .barebox_initcalls : { INITCALLS }

  __barebox_initcalls_end = .;

 

  __usymtab_start = .;

  __usymtab : { BAREBOX_SYMS }

  __usymtab_end = .;

 

  . = ALIGN(4);

  __bss_start = .;

  .bss : { *(.bss*) }

  __bss_stop = .;

  _end = .;

  _barebox_image_size = __bss_start - TEXT_BASE;

}

 

刚开始时.text_entry,

void __naked__section(.text_entry) start(void)

{

    barebox_arm_head();

}

    进入的函数是barebox_arm_head(),是跳转函数。

staticinlinevoid barebox_arm_head(void)

{

    __asm__ __volatile__ (

       "b reset\n"

       "1: b 1b\n"

       "1: b 1b\n"

       "1: b 1b\n"

       "1: b 1b\n"

       "1: b 1b\n"

       "1: b 1b\n"

       "1: b 1b\n"

       ".word 0x65726162\n"        /* 'bare' */

       ".word 0x00786f62\n"        /* 'box' */

       ".word _text\n"             /* text base. If copied there,

                          * barebox can skip relocation

                          */

       ".word_barebox_image_size\n"      /* image size tocopy */

    );

}

    这个函数就是一些列跳转函数,正常情况下调转到reset函数。

       Reset函数修饰用

#define __bare_init          __section(.text_bare_init.text)

              __bare_init_start= .;

              *(.text_bare_init*)

              __bare_init_end= .;

Lds链接脚本有对此的修饰。

 

void __naked__bare_init reset(void)

{

 

    /* set the cpu to SVC32 mode */

#ifdef CONFIG_ARCH_HAS_LOWLEVEL_INIT

    arch_init_lowlevel();

#endif

    /* disable MMU stuff and caches */

#ifdef CONFIG_MACH_DO_LOWLEVEL_INIT

    board_init_lowlevel(); 这个是特定板子的文件

#endif

    board_init_lowlevel_return();

}

lowlevel_init.S (arch\arm\boards\tq2440)  中

.section ".text_bare_init.board_init_lowlevel","ax"

 

/* ------------------------------------------------------------------------*/

 

.globl board_init_lowlevel

board_init_lowlevel:

 

    mov r10, lr       /* save the link register */

 

    bl s3c24x0_disable_wd

 

    /* skip everything here if we are alreadyrunning from SDRAM */

    cmp pc, #S3C_SDRAM_BASE

    blo 1f

    cmp pc, #S3C_SDRAM_END

    bhs 1f

 

    mov pc, r10

 

/* we are running from NOR or NAND/SRAM memory. Do further initialisation*/

1:

    bl s3c24x0_pll_init

 

    bl s3c24x0_sdram_init

 

#ifdef CONFIG_S3C24XX_NAND_BOOT

    mov lr, r10       /* restore the linkregister */

/* up to here we are running from the internal SRAM area */

    b s3c24x0_nand_boot  /* does return directly to our caller into SDRAM */

#else

    mov pc, r10

#endif

       执行完函数board_init_lowlevel后,执行board_init_lowlevel_return

       函数board_init_lowlevel

s3c24x0_disable_wd关闭看门狗

s3c24x0_pll_init PLL初始化

s3c24x0_sdram_init SDRAM初始化,在2440板子上,只初始化了bank6bank7,其他bank的配置保留。

s3c24x0_nand_boot:如果配置了从nand启动,会将代码从nand中拷贝到SDRAM中的TEXT_BASE地址处。

 

void __naked__section(.text_ll_return)board_init_lowlevel_return(void)

{

    uint32_t r, addr;

 

    /*

     * Get runtime address of this function. Do not

     * put any code above this.

     */

    __asm__ __volatile__("1: adr %0,1b":"=r"(addr));

Adr是当前程序运行的地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值