ZYNQ7000FSBL加载启动代码详解
参考资料:
SDK版本:2017.4
写在前⾯:
该⽂档不⾜以使你清楚FSBL启动的寄存器级的操作细节,但可以让你看明⽩整个ZYNQ7000 FSBL代码执⾏的主要流程。
1. ZYNQ7000加载启动流程
(1)BootRom阶段为ARM上电后最早加载的代码,根据MIO引脚配置确认加载⽅式,初始化相应的启动介质,加载FSBL到OCM中,把控制权交给FSBL
(2)FSBL阶段完成PS的初始化,加载PL bit流⽂件,加载SSBL引导程序或者ARM的裸机程序
(3)SSBL阶段分两种情况:①裸机程序直接在DDR中执⾏②uboot引导加载kernel的过程
2. FSBL代码分析
(1)在⽂件FSBL_bsp/standalone_v6_5/src/asm_ventors.S中,声明了⼀个代码段,位于地址0处。开机后PS⾃动执⾏地址0处的指令,其中第⼀⾏代码为⼀个跳转:B _boot
0
.text
.globl _vector_table
.ction .vectors
_vector_table:
B _boot
B Undefined
B SVCHandler
B PrefetchAbortHandler
B DataAbortHandler
NOP /* Placeholder for address exception vector*/
B IRQHandler
B FIQHandler
before的用法
(2)在同⽬录下找到⽂件boot.S中可以看到_boot标号下的代码,_boot会对系统做⼀系列的初始化,包括DDR,中断,MMU,cache 等,执⾏完成后PS将具有执⾏C代码的能⼒。
朗文英语可以看到在_boot代码最后⼜执⾏了⼀次跳转:b _start
b _start /* jump to C startup code */
and r0, r0, r0 /* no op */
(3)在同⽬录下找到⽂件xil-crt0.S中可以看到_start标号下的代码,可以看到_start⾸先执⾏跳转:bl __cpu_init去执⾏CPU初始化操作
_start:fetish
bl __cpu_init /* Initialize the CPU first (BSP provides this) */
mov r0, #0
/* clear sbss */
ldr r1,.Lsbss_start /* calculate beginning of the SBSS */
ldr r2,.Lsbss_end /* calculate end of the SBSS */
(4)在_start标号代码的末尾可以看到bsp完成了所有的初始化⼯作,将跳转到main函数开始执⾏。
/* make sure argc and argv are valid */
mov r0, #0
mov r1, #0
/* Let her rip */
bl main
(5)回到FSBL⼯程,在⽬录FSBL/src/main.c中找到main函数,可以看到第⼀步就是调⽤了ps7_init()函数。
ps7_init()函数位于ps7_init.c⽂件中,这个C⽂件是由XPS根据⽤户的配置⾃动⽣成的。
查看ps7_init()函数,根据代码可以很明显可以看出该函数其实就是根据PS版本执⾏了MIO,PLL,CLK,DDR和其他外设的初始化。
int main(void)
{
u32 BootModeRegister = 0;
u32 HandoffAddress = 0;
u32 Status = XST_SUCCESS;
/*
* PCW initialization for MIO,PLL,CLK and DDR
*/
Status = ps7_init();
if (Status != FSBL_PS7_INIT_SUCCESS) {
fsbl_printf(DEBUG_GENERAL,"PS7_INIT_FAIL : %s\r\n", getPS7MessageInfo(Status));
OutputStatus(PS7_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
}
ps7_init()
{
// Get the PS_VERSION on run time
unsigned long si_ver = ps7GetSiliconVersion ();
工程管理专业学什么
int ret;
//int pcw_ver = 0;
if (si_ver == PCW_SILICON_VERSION_1) {
ps7_mio_init_data = ps7_mio_init_data_1_0;
ps7_pll_init_data = ps7_pll_init_data_1_0;
ps7_clock_init_data = ps7_clock_init_data_1_0;
ps7_ddr_init_data = ps7_ddr_init_data_1_0;
ps7_peripherals_init_data = ps7_peripherals_init_data_1_0; //pcw_ver = 1;
} el if (si_ver == PCW_SILICON_VERSION_2) {
ps7_mio_init_data = ps7_mio_init_data_2_0;
ps7_pll_init_data = ps7_pll_init_data_2_0;
ps7_clock_init_data = ps7_clock_init_data_2_0;
ps7_ddr_init_data = ps7_ddr_init_data_2_0;
ps7_peripherals_init_data = ps7_peripherals_init_data_2_0; //pcw_ver = 2;
} el {
ps7_mio_init_data = ps7_mio_init_data_3_0;
ps7_pll_init_data = ps7_pll_init_data_3_0;
ps7_clock_init_data = ps7_clock_init_data_3_0;
ps7_ddr_init_data = ps7_ddr_init_data_3_0;
ps7_peripherals_init_data = ps7_peripherals_init_data_3_0; //pcw_ver = 3;
}
// MIO init
ret = ps7_config (ps7_mio_init_data);
if (ret != PS7_INIT_SUCCESS) return ret;
// PLL init
ret = ps7_config (ps7_pll_init_data);
桃子的英文if (ret != PS7_INIT_SUCCESS) return ret;
// Clock init
ret = ps7_config (ps7_clock_init_data);
if (ret != PS7_INIT_SUCCESS) return ret;
// DDR init
ret = ps7_config (ps7_ddr_init_data);
if (ret != PS7_INIT_SUCCESS) return ret;
/
/ Peripherals init
ret = ps7_config (ps7_peripherals_init_data);
if (ret != PS7_INIT_SUCCESS) return ret;
//xil_printf ("\n PCW Silicon Version : %d.0", pcw_ver);
return PS7_INIT_SUCCESS;
}
(6)System Software Ret,使能系统软件复位功能
* Unlock SLCR for SLCR register write
*/
SlcrUnlock();
(7)关闭cache功能
/
*
* Flush the Caches
*/
Xil_DCacheFlush();
/*
* Disable Data Cache
*/
Xil_DCacheDisable();
(8)注册异常中断
/*
* Register the Exception handlers
*/
RegisterHandlers();
注册税务师报考条件这⾥相当于异常处理函数全部指向0地址。
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_UNDEFINED_INT,
(Xil_ExceptionHandler)Undef_Handler,丑女贝蒂
(void *) 0);
survivalofthefittest
XExc_VectorTable[Exception_id].Handler = Handler;
XExc_VectorTable[Exception_id].Data = Data;
(9)DDR读写测试,在DDR不同地址段进⾏读写⽐对
/*
* DDR Read/write test
*/
Status = DDRInitCheck();
if (Status == XST_FAILURE) {
fsbl_printf(DEBUG_GENERAL,"DDR_INIT_FAIL \r\n");
/* Error Handling here */
OutputStatus(DDR_INIT_FAIL);
/*
* Calling FsblHookFallback instead of Fallback四级 时间
* since, devcfg driver is not yet initialized
*/
FsblHookFallback();
contents
}
(10)Processor Configuration Access Port即处理器配置接⼝,连接软件和硬件的桥梁。