AM335x裸機<二>:StartWare的分析
阿新 • • 發佈:2017-09-09
ron asm 中斷向量 des copy lec start 內容 第一個
這篇接著上一篇,來分析上一篇程序裏面的MLO和app文件啟動過程,基本涵蓋到整個am335x的大部分操作,包括:時鐘初始化、代碼搬移、中斷向量的重定位、中斷的處理等。要分析程序,首先分析makefile和連接腳本lds文件,然後順藤摸瓜,當同名函數太多時,可以考慮反匯編elf文件,進行對比判斷。
0.添加Source Insight工程
創建新工程,添加所有文件,註意Source Insight添加對asm和makefile文件支持,更有利於分析
1.bootloader分析
查看build/armv7a/gcc/am335x/sbc8600/bootloader目錄makefile和lds文件可知(*bl_init.o),第一個文件為bootloader/src/armv7a/gcc/bl_init.S
#bootloader/src/armv7a/gcc/bl_init.S
Entry:
bl_start
#bootloader/src/bl_main.c
/* 各種初始化 */
DeviceConfig()
#bootloader/src/bl_am335x.c
// 關看門狗
HWREG(SOC_WDT_1_REGS + WDT_WSPR) = 0xAAAAu;
while(HWREG(SOC_WDT_1_REGS + WDT_WWPS) != 0x00);
HWREG(SOC_WDT_1_REGS + WDT_WSPR) = 0x5555u;
while(HWREG(SOC_WDT_1_REGS + WDT_WWPS) != 0x00);
// 初始化時鐘
PLLInit();
// 使能控制模塊
HWREG(SOC_CM_WKUP_REGS + CM_WKUP_CONTROL_CLKCTRL) =
CM_WKUP_CONTROL_CLKCTRL_MODULEMODE_ENABLE;
// 初始化內存
EMIFInit();
DDR3Init();
// 初始化串口
UARTSetup();
/* 打印啟動信息 */
UARTPuts("StarterWare ", -1);
/* 將app從mmc復制到ram */
ImageCopy();
#bootloader/src/bl_copy.c
MMCSDBootCopy();
#bootloader/src/bl_hsmmcsd.c
// 初始化控制器
HSMMCSDInit();
// 復制mmc內容到ram
HSMMCSDImageCopy();
// 設置app入口地址
entryPoint = imageHdr.load_addr;
/* 跳轉到app執行 */
appEntry = (void (*)(void)) entryPoint;
UARTPuts("Jumping to StarterWare Application...\r\n\n", -1);
(*appEntry)( );
2.app分析
查看build/armv7a/gcc/am335x/sbc8600/bootloader目錄makefile和lds文件可知(*init.o),第一個文件為system_config/armv7a/gcc/init.S
#system_config/armv7a/gcc/init.S
Entry:
start_boot
#system_config/armv7a/am335x/startup.c
/* 中斷向量重定位 */
CopyVectorTable();
CP15VectorBaseAddrSet(AM335X_VECTOR_BASE);
#system_config/armv7a/gcc/cp15.S
CP15VectorBaseAddrSet:
dest[count] = src[count];
static unsigned int const vecTbl[14]=
(unsigned int)IRQHandler,
#system_config/armv7a/am335x/gcc/exceptionhandler.S
IRQHandler:
/* 保存現場 */
...
/* 處理中斷 */
LDR r0, =fnRAMVectors
/* 恢復現場 */
...
/* 調用main函數 */
main();
#examples/sbc8600/uart/uartEcho.c
/* 打開時鐘 */
UART0ModuleClkConfig();
/* 串口初始化 */
UartFIFOConfigure();
......
/* 配置中斷 */
UartInterruptEnable();
UART0AINTCConfigure();
IntRegister(SYS_INT_UART0INT, UARTIsr);
#system_config/armv7a/am335x/interrupt.c
void IntRegister(unsigned int intrNum, void (*fnHandler)(void))
fnRAMVectors[intrNum] = fnHandler;
void (*fnRAMVectors[NUM_INTERRUPTS])(void);
/* 死循環 */
while(1);
整個uart裸機程序分為兩部分:MLO、app,其中MLO用於完成基本初始化,然後跳轉到app入口,app負責完成中斷向量(interrupt vector)重定位,並負責實現中斷的處理,當uart發生收發中斷時,會暫時停止當前工作,跳轉到異常入口中斷,進行對數據的處理,當處理完中斷後,返回前面位置繼續運行。
最後總結一下,分析要點:
makefile、lds、反匯編
AM335x裸機<二>:StartWare的分析