• AM335x裸机<二>:StartWare的分析


    这篇接着上一篇,来分析上一篇程序里面的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...
    
    ", -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、反汇编

  • 相关阅读:
    操作系统
    MarkDown语法实操
    mac 添加环境变量
    在django中建立mysql数据表时发生的低级错误
    models.Book.object.get()与models.Book.object.filter()区别
    django中数据库操作时distinct的用法
    ‘,’逗号并不是字符串的拼接方式
    django单表操作中update_or_create不能更新多于一个数据的信息
    在python中terminal中建立mysql数据库,无法再models.py 文件中建立数据库信息
    booleanfield()和booleanfield(default=True)在数据库的表中无法插入
  • 原文地址:https://www.cnblogs.com/Ethan-Gao/p/7498875.html
Copyright © 2020-2023  润新知