sbl1启动代码分析

本文详细分析了SBL1(Secondary Boot Loader 1)的启动代码,从汇编启动文件sbl1.s到C语言启动文件sbl1_mc.c,涵盖了设置中断向量表、关闭watchdog、硬件初始化、执行配置表中的入口程序等多个步骤。SBL1在L2 cache中运行,通过初始化串口输出log,并在DDR初始化后重定位log存储。文章还介绍了TZ、RPM、WDT和APPSBL等相关操作,以及在启动过程中涉及的内存管理、中断处理和硬件配置等关键环节。
摘要由CSDN通过智能技术生成

1. sbl1.s -- 汇编启动文件

sbl1程序的入口点在0xF800_C000,从memory map可以看出此地址位于L2 cache中,所以sbl1实际上是运行在L2 cache上的;

 

1)设置中断向量表

  中断向量表位于0xFE80_5FC0(OCIMEM),覆盖PBL的中断向量表

  AREA   SBL1_INDIRECT_VECTOR_TABLE, CODE, READWRITE

  CODE32

unused_reset_vector

  DCD    0x00000000

undefined_instruction_vector

  DCD    sbl1_undefined_instruction_nested_handler

swi_vector

  DCD     boot_swi_c_handler

prefetch_abort_vector

  DCD    sbl1_prefetch_abort_nested_handler

data_abort_vector

  DCD    sbl1_data_abort_nested_handler

reserved_vector

 DCD    boot_reserved_c_handler

irq_vector

  DCD    boot_irq_c_handler

fiq_vector

  DCD    boot_fiq_c_handler

 

2)代码入口点 -- SBL1_ENTRY

  sbl1的汇编代码入口点在0xF800_C000,即L2 cache中;

  AREA SBL1_ENTRY, CODE, READONLY, ALIGN=4

  CODE32

  ENTRY

 

sbl1_entry

  ; 进入SVC模式

  msr    CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

 

  ; 保存PBL传递进来的参数r0->r7

  mov         r7, r0

 

  ; 设置堆栈指针

  ldr         r0, =SCL_SBL1_STACK_BASE

  mov         r13, r0

 

; und modeabt mode设置堆栈指针

  msr    CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit

  mov    r13, r0

 

  msr    CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit

  mov    r13, r0

 

  ; 返回到svc模式

  msr    CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit

 

  ; 恢复PBL参数r7->r0

  mov    r0, r7

 

  ; 跳转到C语言程序入口点sbl1_main_ctl

  ldr   r5, =sbl1_main_ctl

  blx   r5

2. sbl1_mc.c -- C语言启动文件

sbl1_main_ctl()是C语言程序的入口函数,在此以后我们就可以开始C语言之旅了。

 

1)sbl1_main_ctl() -- C语言程序入口点

a)初始化串口,并输出log

sbl1_boot_logger_init(&boot_log_data,pbl_shared);

boot_log_message("scatterload_region&& ram_init, Start");

 

b)重定位中断向量表和数据段

result =boot_scatterload_region(&sbl1_scatterload_data);

result =boot_ram_init(&sbl1_ram_init_data);

 

c)关闭watchdog

pm_pon_wdog_enable(0,PM_OFF); 

 

d)重定位并初始化SHARED IMEM – 其基地址位于0xFE805000

sbl1_update_shared_imem_base();

boot_shared_imem_init(&bl_shared_data);

 

e)硬件初始化

sbl1_hw_init();

 

f)初始化TZ, RPM, WDT,最后跳转到APPSBL即lk

boot_config_process_bl(&bl_shared_data, SBL1_IMG,sbl1_config_table);

 

2)boot_config_process_bl()

遍历config table,并进入相应的子系统执行代码;

/* For every entry inthe boot configuration table */

for(curr_entry =boot_config_table; curr_entry->host_img_id != NONE_IMG; curr_entry++)

{

    /* Process entries sequentially only forthe specific host_img */

    if(curr_entry->host_img_id == host_img)

    {

      boot_config_process_entry(bl_shared_data,curr_entry);

}

}

3)boot_config_process_entry()

// 执行Pre- Procedures函数列表

boot_do_procedures(bl_shared_data,boot_config_entry->pre_procs);

 

// 加载并校验image

 

// 跳转到image的入口点,并开始执行

(boot_config_entry->exec_func)(bl_shared_data);

 

// 执行Post- Procedures函数列表

boot_do_procedures(bl_shared_data,boot_config_entry->post_procs);

 

// 跳转到image入口点执行程序,并且不再返回

(boot_config_entry->jump_func)(bl_shared_data);

3. 输出log

 sbl1可以把log保存在ram中,或者直接输出到串口。Log格式可以是显示启动时间,或者是显示delta时间。Log最初是保存在L2 cache中,在DDR初始化完毕后,将会重定位到DDR中;

 

1)log存储位置

boot_log_data数据结构定义了log和meta info存储地址(a)

staticboot_log_init_data boot_log_data =

{

  (void *)SBL1_LOG_BUF_START,                      // 0xF80599B0

  SBL1_LOG_BUF_SIZE,                                    // 0x5C0

  (void *)SBL1_LOG_META_INFO_START,         // 0xF8059970

  SBL1_LOG_META_INFO_SIZE,                       // 0x40

  NULL

};

 

#define SBL1_LOG_BUF_START   (&Image$$SBL1_LOG_BUF_SECTION$$Base)  

#defineSBL1_LOG_BUF_SIZE     1472

 

#defineSBL1_LOG_META_INFO_START    (&Image$$SBL1_LOG_META_INFO_SECTION$$Base)

#defineSBL1_LOG_META_INFO_SIZE       64

 

在DDR初始化完成后,上述地址将会被重定位到DDR中(b)

static voidsbl1_move_boot_log_to_ddr()

{

  /* Relocate boot logger buffer to DDR andcontinue to save log in DDR */

  boot_log_relocate((void*)SCL_DDR_BOOT_LOG_META_INFO_BASE,

                    (void *)SCL_SBL1_DDR_BOOT_LOG_BUF_BASE,

                   SCL_SBL1_DDR_BOOT_LOG_BUF_SIZE, 

                    (void*)SBL1_LOG_META_INFO_START,

                    (void *)SBL1_LOG_BUF_START,

                    SBL1_LOG_BUF_SIZE);

 

  boot_log_data.log_buffer_start = (void *)SCL_SBL1_DDR_BOOT_LOG_BUF_BASE;

  boot_log_data.log_buffer_size =SCL_SBL1_DDR_BOOT_LOG_BUF_SIZE;

  boot_log_data.meta_info_start = (void *)SCL_DDR_BOOT_LOG_META_INFO_BASE;

}

 

上述用到的几个地址需要查看相应的scl文件获得(c),Log在L2 Cache中的存储地址如下:

// Reserve space for theboot logger's meta info data. -- meta log预留内存空间

SBL1_LOG_META_INFO_SECTION +0x0  EMPTY  64

 

// Reserve buffer spacefor the boot logger's log messages -- log预留内存空间

SBL1_LOG_BUF_SECTION  +0x0  EMPTY 1472

 

Log在DDR中的存储地址如下:

SBL1_DDR_LOG_META_INFO_SECTION\

  (((0x0FE00000 + 0x0088000) + 0x0008000) \

  + (0x0100000 - 0x0088000 - 0x0008000 - 64 - 1984))EMPTY 64

 

SBL1_DDR_LOG_BUF_SECTION\

((((0x0FE00000 +0x0088000) + 0x0008000) \

+ (0x0100000 - 0x0088000- 0x0008000 - 64 - 1984)) + 64) EMPTY 1984

 

我们大概算一下,Meta Info的起始地址在FEFF800的位置,而Log的起始地址在FEFF840,注意这两个地址在kernel中是不

  • 13
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值