启动分析
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板子上,只初始化了bank6和bank7,其他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是当前程序运行的地址