结合VxWorks自己的romInit.s,分析一下:
(1)首先添加相应的头文件,学过C和GNU汇编的都知道, 添加一些本程序可能用到的东西
#define _ASMLANGUAGE /* 定义汇编宏 */
#include <vxWorks.h> /* 工程项目组件, 内核项目组件,指令调整 */
#include <sysLib.h> /* 定义工程所需的头函数声明和全局变量 */
#include <asm.h> /* ARM汇编相关定义 */
#include <regs.h> /* ARM 寄存器定义 */
#include <config.h> /* 硬件BSP配置参数头文件,注意不是configAll.h 那个是做全局和默认值*/
#include <arch/arm/mmuArmLib.h> /* MMU 相关头文件*/
(2)相关函数和数据声明
.globl FUNC(romInit) /* start of system code */
/* #define FUNC(a) a */ /* global 使符号symbol对连接器ld可见。 */
.globl VAR(sdata) /* start of data */
/* #define VAR(name) name */
.globl _sdata
.globl VAR(integratorMemSize) /* actual memory size */
/* .extern可以在源程序中使用--以便兼容其他的汇编器-但会被忽略。as将所有未定义的符号都当作外部符号处理。 */
/* externals */
.extern FUNC(romStart) /* system initialization routine */
(3)编译伪指令
.data
_sdata:
VAR_LABEL(sdata)
/*#define VAR_LABEL(name) name:*/
.asciz "start of data"
/*.asciz “<string>”把string当成数据插入汇编中, 但在每个字符串后面跟一个零字节"/0". */
.balign 4 /* 对齐地址到4 字节 */
/* variables */
VAR_LABEL(integratorMemSize) /*integratorMemSize: 0L*/
.long 0 /* .long is the same as ‘.int’*/
/* .int expressions 可以不带参数或带多个expressions,参数之间由逗号分隔。每个expressions都生成一个数字,这个数字等于表达式在目标机器运行时的值。字节顺序和数字的位数视汇编的目标机器而定。 */
.text
/* 通知as把后续语句汇编到编号为subsection的正文子段的末尾,subsection是一个纯粹的表达式。如果省略了参数subsection,则使用编号为0的子段。 */
.balign 4 /* 增加位置计数器(在当前子段)使它指向规定的存储边界。 */
(4)romInit函数具体实现
函数声明:
_ARM_FUNCTION(romInit) /*#define _ARM_FUNCTION(a) .code 32 ; .balign 4 ; a: ARM指令,4字节对齐*/
_romInit:
cold:
热启动和冷启动有点区别
MOV r0, #BOOT_COLD /* fall through to warm boot entry */
/* #define BOOT_CLEAR 0x02 clear memory if set */
warm:
B start
/* copyright notice appears at beginning of ROM (in TEXT segment) */
.ascii "Copyright 1999-2001 ARM Limited" /*.ascii “<string>”把string当成数据插入汇编中 */
.ascii "/nCopyright 1999-2007 Wind River Systems, Inc."
.balign 4 /* 对齐地址到4 字节 */
此处为了规避问题,有时候冷启动需要多次循环。
设置CP15的工作模式:兼容26位地址数据,设置终止模式,ROM保护等(此时Cache等还是无效的)
LDR r1, =MMU_INIT_VALUE /* Defined in mmuArmLib.h */
/*#define MMU_INIT_VALUE (MMUCR_PROG32 | MMUCR_DATA32 | MMUCR_L_ENABLE | /
MMUCR_MODE | MMUCR_926E_SBO)*/
/*Values to be used when the MMU Control Register is initialised from within romInit.s or sysALib.s (before the MMU is enabled). */
#endif /* defined(CPU_920T/920T_T/1020E/1022E/1136JF) */
MCR CP_MMU, 0, r1, c1, c0, 0 /* Write to MMU CR *//*MCR: ARM register r1 to coperation register c1/c0 */
有时需要循环等待
清空写缓冲区
MOV r1, #0 /* data SBZ */
MCR CP_MMU, 0, r1, c7, c10, 4 /* drain write-buffer */ /* 控制cache和写缓冲区,清空写缓存*/
无效整个Cache
MCR CP_MMU, 0, r1, c7, c7, 0 /* R1 = 0 from above, data SBZ*/ /* 无效Cache*/
条件使能Cache
#if defined(INTEGRATOR_EARLY_I_CACHE_ENABLE)
MRC CP_MMU, 0, r1, c1, c0, 0
ORR r1, r1, #MMUCR_I_ENABLE /* conditionally enable Icache*/
MCR CP_MMU, 0, r1, c1, c0, 0 /* Write to MMU CR */
#endif /* defined(INTEGRATOR_EARLY_I_CACHE_ENABLE) */
没看懂
LDR r1, L$_sysCacheUncachedAdrs /* R1 -> uncached area */
LDR r1, [r1] /* drain write-buffer */
/* Flush (invalidate) both caches */
MOV r1, #0 /* data SBZ */ C7用于控制cache和写缓冲
MCR CP_MMU, 0, r1, c7, c5, 0 /* Flush (inval) all I-cache */ 无效指令Cache
MCR CP_MMU, 0, r1, c7, c6, 0 /* Flush (inval) all D-cache */ 无效数据Cache