u-boot走读 -- start.S

来源:互联网 发布:简述sem和seo的区别 编辑:程序博客网 时间:2024/05/16 00:27

最近要接触到u-boot,看看网上的文章,看看代码,随便写点记录,。

 

貌似ARM架构的代码,都是从start.S这个汇编代码开始的,我也从这个文件入手,我不是以注释的方式来描述,而是以面向流程的方式来描述,最后把带注释的代码一贴完事儿。

 

>第一部分:

#include <config.h>#include <version.h>

注意,代码中有很多个config.h,不少于十个,不过这里包含的应该是 ./include/config.h 这一个,简单的说这个start.S需要用到很多配置头文件的宏,定义这个宏的头文件只被 ./include/config.h 包含,具体原因以后分析。

 

>第二部分:

.globl _start_start: bresetldrpc, _undefined_instructionldrpc, _software_interruptldrpc, _prefetch_abortldrpc, _data_abortldrpc, _not_usedldrpc, _irqldrpc, _fiq_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 */.global _end_vect_end_vect:

 

好像和单片机差不多,程序开头部分都是中断向量表,这里先不说其它中断,直接说第一个reset,power on其实和reset是一样的,都是从无到有的一个过程,直接看reset的代码:

reset:/* * set the cpu to SVC32 mode */mrsr0, cpsrbicr0, r0, #0x1forrr0, r0, #0xd3msrcpsr,r0

设置CPU进入SVC32模式,超级模式。

#if (CONFIG_OMAP34XX)/* Copy vectors to mask ROM indirect addr */adrr0, _start@ r0 <- current position of codeaddr0, r0, #4@ skip reset vectormovr2, #64@ r2 <- size to copyaddr2, r0, r2@ r2 <- source end addressmovr1, #SRAM_OFFSET0@ build vect addrmovr3, #SRAM_OFFSET1addr1, r1, r3movr3, #SRAM_OFFSET2addr1, r1, r3next:ldmiar0!, {r3 - r10}@ copy from source address [r0]stmiar1!, {r3 - r10}@ copy to   target address [r1]cmpr0, r2@ until source end address [r2]bnenext@ loop until equal */#if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)/* No need to copy/exec the clock code - DPLL adjust already done * in NAND/oneNAND Boot. */blcpy_clk_code@ put dpll adjust code behind vectors#endif /* NAND Boot */#endif

 

这段代码并不是每种cpu都是必须的,为啥呢? 看看内容和注释,其实就是把中断向量表的内容copy到SRAM中去了,另外如果没有定义NAND或者ONENAND的boot,就调用 cpy_clk_code 这个代码,好像是将clock的代码(定时中断?)copy到中断向量表后面了。

接下来:

/* the mask ROM code should have PLL and others stable */#ifndef CONFIG_SKIP_LOWLEVEL_INITblcpu_init_crit#endif

 

cpu的初始化,代码如下:

 

/************************************************************************* * * CPU_init_critical registers * * setup important registers * setup memory timing * *************************************************************************/cpu_init_crit:/* * Invalidate L1 I/D */movr0, #0@ set up for MCRmcrp15, 0, r0, c8, c7, 0@ invalidate TLBsmcrp15, 0, r0, c7, c5, 0@ invalidate icache/* * 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 12 (Z---) BTBmcrp15, 0, r0, c1, c0, 0/* * 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. */movip, lr@ persevere link reg across callbllowlevel_init@ go setup pll,mux,memorymovlr, ip@ restore linkmovpc, lr@ back to my caller


具体没仔细看了,还调用了 lowlevel_init.S 中的 lowlevel_init 代码。

 

>第三部分:

#ifndef CONFIG_SKIP_RELOCATE_UBOOTrelocate:@ relocate U-Boot to RAMadrr0, _start@ r0 <- current position of codeldrr1, _TEXT_BASE@ test if we run from flash or RAMcmpr0, r1@ don't reloc during debugbeqstack_setupldrr2, _armboot_startldrr3, _bss_startsubr2, r3, r2@ r2 <- size of armbootaddr2, r0, r2@ r2 <- source end addresscopy_loop:@ copy 32 bytes at a timeldmiar0!, {r3 - r10}@ copy from source address [r0]stmiar1!, {r3 - r10}@ copy to   target address [r1]cmpr0, r2@ until source end addreee [r2]blecopy_loop#endif/* CONFIG_SKIP_RELOCATE_UBOOT */


从名字看一下,就知道,是把u-boot的代码搬到RAM中而已。

 

>第四部分:设置堆栈

/* Set up the stack */stack_setup:ldrr0, _TEXT_BASE@ upper 128 KiB: relocated ubootsubr0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc areasubr0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo#ifdef CONFIG_USE_IRQsubr0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)#endifsubsp, r0, #12@ leave 3 words for abort-stackandsp, sp, #~7@ 8 byte alinged for (ldr/str)d


>第五部分:清除BSS

/* Clear BSS (if any). Is below tx (watch load addr - need space) */clear_bss:ldrr0, _bss_start@ find start of bss segmentldrr1, _bss_end@ stop heremovr2, #0x00000000@ clear valueclbss_l:strr2, [r0]@ clear BSS locationcmpr0, r1@ are we at the end yetaddr0, r0, #4@ increment clear index pointerbneclbss_l@ keep clearing till at end


>最后:跳转到C代码执行。

ldrpc, _start_armboot@ jump to C code_start_armboot: .word start_armboot



(慢慢再看再补充吧,我的目的不是S,而是整体架构,补充驱动,呵呵)