作者:付汉杰,hankf@xilinx.com,文章转载自:赛灵思中文社区论坛
MPSoC A53执行的第一条代码定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\asm_vectors.S里。
去掉Xen相关代码后,简化如下:
.org 0 .section .vectors, "a" _vector_table: .set VBAR, _vector_table .org VBAR b _boot .org (VBAR + 0x200) b SynchronousInterruptHandler .org (VBAR + 0x280) b IRQInterruptHandler .org (VBAR + 0x300) b FIQInterruptHandler .org (VBAR + 0x380) b SErrorInterruptHandler
上述代码的地址,由《ARM® Architecture Reference Manual,ARMv8, for ARMv8-A architecture profile》(ARM DDI 0487C)定义,可以参考Table D1-7 Vector offsets from vector table base address。
EL0的Synchronous offset是0x0。其他EL级别,Synchronous offset是0x200,IRQ or vIRQ offset是0x280, FIQ or vFIQ offset是0x300, SError or vSError offset是0x380,
MPSoC A53启动后,在EL0,执行的第一条代码是“b _boot”。
符号_boot的定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\boot.S里。简化后的代码如下。
/* this initializes the various processor modes */ _prestart: _boot: mov x0, #0 ... ... mov x30, #0 #if 0 //dont put other a53 cpus in wfi //Which core am I // ---------------- mrs x0, MPIDR_EL1 and x0, x0, #0xFF //Mask off to leave Aff0 cbz x0, OKToRun //If core 0, run the primary init code EndlessLoop0: wfi b EndlessLoop0 #endif OKToRun: mrs x0, currentEL cmp x0, #0xC beq InitEL3 cmp x0, #0x4 beq InitEL1 b error // go to error if current exception level is neither EL3 nor EL1
InitEL3/InitEL1会设置reset vector address,Invalidate cache,设置stack pointer。
执行上述代码后,会执行“bl _startup”。
符号_startup的定义在BSP工程的目录\psu_cortexa53_0\libsrc\standalone_v7_0\src\xil-crt0.S里。符号_startup先清除SBSS和BSS段,然后运行global constructors,再跳到C语言的定义在文件xfsbl_main.c里的入口函数main。
FSBL的main()里的调用关系是XFsbl_Initialize()->XFsbl_SystemInit()->XFsbl_HookPsuInit()->psu_init().。
psu_init由Vivado导出,含有芯片的管脚、pll、DDR初始化,主要代码如下。
psu_init(void) { status &= psu_mio_init_data(); status &= psu_pll_init_data(); status &= psu_clock_init_data(); status &= psu_ddr_init_data(); status &= psu_ddr_phybringup_data(); status &= psu_peripherals_init_data(); status &= init_serdes(); init_peripheral(); status &= psu_peripherals_powerdwn_data(); status &= psu_afi_config(); }
上述流程,可以在SDK里双击应用程序的ELF文件,查看应用程序的反汇编文件确认。