1. 程式人生 > >AM335x裸機<二>:StartWare的分析

AM335x裸機<二>:StartWare的分析

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的分析