Android OrangePi 4G IOT(三) - MTK preloader分析

一、代码目录结构

二、preloader简介

1: preloader实在LK启动前一阶段的对系统进行初始化的代码,在bootroom后加载的。

2: 对硬件进行必要的一些准备和初始化(Timer,PLL,UART,GPIO,PMIC Wrapper,I2C,PMIC,Mem/Storage初始化,Memory自检)

3:检测商店原因(RTC,WDT,Powerkey,USB),然后检查是否关闭BB的power

4:启动模式检测,检测来自tools的启动模式(Flashtool,Metatool,Factory tool)以及队友的Normal,Meta和Factory启动模式

5:第二阶段LK启动的检测和加载,检查和加载LK从启动介质(Nand和eMMC)到RAM,在preloader最后阶段跳转到LK

source build/envsetup.sh
lunch
make -j4 pl 2>&1 | tee pl_build.log

三、启动流程

1:总体系统启动流程

 

2:PL启动流程 

A:/home/ubuntu/Mediatek/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/link_descriptor.ld

OUTPUT_ARCH(arm)

ENTRY(_start)

romBase = 0x00201000;
ramBase = 0x00102180;

MEMORY {
    ram : ORIGIN = ramBase, LENGTH = 0xBA80
    rom : ORIGIN = romBase, LENGTH = 0x1F000
}

SECTIONS {

    . = romBase;
    .start ALIGN(4) : {	
        *(.text.start)
    } >rom
    
    . = romBase + 0x01FC;
    .rom_info ALIGN(4) : {	    	    	    	     
    	*(.data.rom_info)
    } >rom 

    .text ALIGN(4) : {
        *(.text)
        *(.text.*)        
    } >rom

    .rodata ALIGN(4) : {
        *(.rodata)
        *(.rodata.*)        
    } >rom

    .data ALIGN(4) : {
        *(.data)
        *(.data.*)        
    } >rom

    .got ALIGN(4) : {
        *(.got)
        *(.got.*)        
    } >rom

    __boot_end = .;

    . = ramBase;
    .bss ALIGN(16) : {
        _bss_start = .;
        *(.bss)
        *(.bss.*)
        *(COMMON)
        /* make _bss_end as 4 bytes alignment */
        . = ALIGN(4);
        _bss_end = .;
    } >ram
	.secbuf ALIGN(4) : {
		_secbuf_start = .;
		*(.secbuf)
		_secbuf_end = .;
	} >ram

}

B:/home/ubuntu/Mediatek/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/init/init.s

.section .text.start

.equ MODE_USR       ,0x10
.equ MODE_FIQ       ,0x11
.equ MODE_IRQ       ,0x12
.equ MODE_SVC       ,0x13
.equ MODE_MON       ,0x16
.equ MODE_ABT       ,0x17
.equ MODE_UNDEF     ,0x1B
.equ MODE_SYS       ,0x1F
.equ I_BIT          ,0x80
.equ F_BIT          ,0x40
.equ INT_BIT        ,0xC0

/* .equ RVBADDRESS_CPU0 ,0x10200038 */
.extern sys_stack
.extern sys_stack_sz
.extern bl31_base_addr
.extern rst_vector_base_addr

/* bldr argument address */
.globl bldr_args_addr
bldr_args_addr:
    .word 0x0

.globl _start
_start:
    b resethandler
bss_start:
    .word _bss_start
bss_end:
    .word _bss_end
stack:
    .long sys_stack
stacksz:
    .long sys_stack_sz

resethandler:
    LDR r6, =bldr_args_addr
    STR r4, [r6]
    MOV r0, #0
    MOV r1, #0
    MOV r2, #0
    MOV r3, #0
    MOV r4, #0
    MOV r5, #0
    MOV r6, #0
    MOV r7, #0
    MOV r8, #0
    MOV r9, #0
    MOV r10, #0
    MOV r11, #0
    MOV r12, #0
    MOV sp, #0
    MOV lr, #0

    /* CONFIG_ARM_ERRATA_826319 */
    mrc p15, 0, r8, c1, c0, 0    @ Read System Control Register into Rt
    bic r8, r8, #0x4             @ disable D-Cache
    bic r8, r8, #0x1000          @ clear I-Cache
    mcr p15, 0, r8, c1, c0, 0    @ Write Rt to System Control Register
    
    mrc p15, 1, r8, c15, c0, 0  @ Read L2ACTLR into Rt
    orr r8, r8, #0x8            @ Set Bit[3]=1, disable eviction transaction
    bic r8, r8, #0x1 << 14      @ Set Bit[14]]0
    mcr p15, 1, r8, c15, c0, 0  @ Write Rt to L2ACTLR
    isb

    /* CONFIG_ARM_ERRATA_836870 */
    /** CONFIG_ARM_ERRATA_836870=y (for 6595/6752/6735, prior to r0p4)
	  * Prog CatC,
	  * Non-allocating reads might prevent a store exclusive from passing
	  * worksround: set the CPUACTLR.DTAH bit.
	  * The CPU Auxiliary Control Register can be written only when the system 
	  * is idle. ARM recommends that you write to this register after a powerup 
	  * reset, before the MMU is enabled, and before any ACE or ACP traffic 
	  * begins.
	  **/
    mrrc p15, 0, r8, r9, c15	@ Read CPUACTLR into Rt, Rt2
    orr r8, r8, #0x1 << 24      @ Set Bit[24]=1, set the CPUACTLR.DTAH bit.
    mcrr p15, 0, r8, r9, c15    @ Write Rt, Rt2 to CPUACTLR
    isb

    /* set the cpu to SVC32 mode */
    MRS	r0,cpsr
    BIC	r0,r0,#0x1f
    ORR	r0,r0,#0xd3
    MSR	cpsr,r0

    /* disable interrupt */
    MRS r0, cpsr
    MOV r1, #INT_BIT
    ORR r0, r0, r1
    MSR cpsr_cxsf, r0

    /* enable I+Z+SMP bits and disable D bit */
    MRC p15, 0, ip, c1, c0, 0
    ORR ip, ip, #0x1840   /* I+Z+SMP bits */
    BIC ip, ip, #0x4      /* C bit */
    MCR p15, 0, ip, c1, c0, 0

clear_bss :
    LDR r0, bss_start  /* find start of bss segment */
    LDR r1, bss_end    /* stop here */
    MOV r2, #0x00000000 /* clear */

    CMP r0, r1
    BEQ setup_stk

    /*  clear loop... */
clbss_l :
    STR r2, [r0]
    ADD r0, r0, #4
    CMP r0, r1
    BNE clbss_l

setup_stk :
    /* setup stack */
    LDR r0, stack
    LDR r1, stacksz

    /* buffer overflow detect pattern */
    LDR r2, =0xDEADBEFF
    STR r2, [r0]

    LDR r1, [r1]
    SUB r1, r1, #0x04
    ADD r1, r0, r1

    MOV sp, r1

entry :
    LDR r0, =bldr_args_addr
    B   main

.globl jump
jump:
    MOV r4, r1   /* r4 argument */
    MOV r5, r2   /* r5 argument */
    MOV pc, r0    /* jump to addr */

.globl apmcu_icache_invalidate
apmcu_icache_invalidate:
    MOV r0, #0
    MCR p15, 0, r0, c7, c5, 0  /* CHECKME: c5 or c1 */
    BX  lr

.globl apmcu_isb
apmcu_isb:
    ISB
    BX  lr

.globl apmcu_disable_icache
apmcu_disable_icache:
    MOV r0,#0
    MCR p15,0,r0,c7,c5,6   /* Flush entire branch target cache */
    MRC p15,0,r0,c1,c0,0
    BIC r0,r0,#0x1800      /* I+Z bits */
    MCR p15,0,r0,c1,c0,0
    BX  lr

.globl apmcu_disable_smp
apmcu_disable_smp:
    MRC p15,0,r0,c1,c0,1
    BIC r0,r0,#0x040       /* SMP bit */
    MCR p15,0,r0,c1,c0,1
    BX  lr

.section .text.arch64
.globl jumparch64
jumparch64:
    MOV r4, r1   /* r4 argument */
    MOV r5, r2   /* r5 argument */
    MOV r6, r0   /* keep LK jump addr */

    MOV r7, r3   /* r3 = TEE boot entry, relocate to r7 */

    /* setup the reset vector base address after warm reset to Aarch64 */
    LDR r0, =bl31_base_addr
    LDR r0,[r0]

    LDR r1, =rst_vector_base_addr
    LDR r1,[r1]
    str r0,[r1]

    /* setup the excution state after warm reset: 1:Aarch64, 0:Aarch32 */
    MRC p15,0,r0,c12,c0,2
    orr r0, r0, #1
    MCR p15,0,r0,c12,c0,2
    DSB
    ISB

    /* do warm reset:reset request */
    MRC p15,0,r0,c12,c0,2
    orr r0, r0, #2
    MCR p15,0,r0,c12,c0,2
    DSB
    ISB

    /* set r0 as 0xC000_0000 for ATF OP code check */
    MOV r0, #0xC0000000

.globl WFI_LOOP
WFI_LOOP:
    /* enter WFI to request a warm reset */
    WFI
    B WFI_LOOP

.globl jumparch64_slt
jumparch64_slt:
    /* setup the reset vector base address after warm reset to Aarch64 */
    /* ldr r1,=RVBADDRESS_CPU0 */
    /* ldr r1,[r1] */
    /* LDR r0, =0x40000000 */
    LDR r0, =0x40000000
    LDR r1, =0x10200038
    str r0,[r1]

    /* setup the excution state after warm reset: 1:Aarch64, 0:Aarch32 */
    MRC p15,0,r0,c12,c0,2
    orr r0, r0, #1
    MCR p15,0,r0,c12,c0,2
    DSB
    ISB

    /* do warm reset:reset request */
    MRC p15,0,r0,c12,c0,2
    orr r0, r0, #2
    MCR p15,0,r0,c12,c0,2
    DSB
    ISB

    /* set r0 as 0x40000300 for dtb */
    ldr r0, =0x40000300

1:
    /* enter WFI to request a warm reset */
    WFI
    B 1b

C:/home/ubuntu/Mediatek/code/vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6735/src/core/main.c

void main(u32 *arg)
{
    struct bldr_command_handler handler;
    u32 jump_addr, jump_arg;

    /* get the bldr argument */
    bldr_param = (bl_param_t *)*arg;

    mtk_uart_init(UART_SRC_CLK_FRQ, CFG_LOG_BAUDRATE);
    bldr_pre_process();

    #ifdef HW_INIT_ONLY
    bldr_wait_forever();
    #endif

    handler.priv = NULL;
    handler.attr = 0;
    handler.cb   = bldr_cmd_handler;

	BOOTING_TIME_PROFILING_LOG("before bldr_handshake");
    bldr_handshake(&handler);
	BOOTING_TIME_PROFILING_LOG("bldr_handshake");
    ......
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值