原帖地址:http://wogoyixikexie.blog.163.com/blog/static/88778624200872525040175/
一、首先,第一眼看到的就是头文件,这个非常关键,因为这些头文件通常都包含着非常重要的信息。我们要做的就是把这些头文件都打开,否则就像我先前一样闹出笑话——对一些莫名奇妙的指令不知道从何而来,其实是在头文件中做了定义的。
I NCLUDE kxarm.h ;C:\WINCE500\PUBLIC\COMMON\SDK\INC
TEXTAREA就是在里面的一个宏定义 INCLUDE armmacros.s ;C:\WINCE500\PUBLIC\COMMON\SDK\INC\armmacros.s 代码较短,就是贴出来来吧 ;***********************************************************************/ IF Interworking :LOR: Thumbing;这是什么意思? MACRO CALL $Fn ldr r12, =$Fn mov lr, pc bx r12 MEND MACRO CALLEQ $Fn ldreq r12, =$Fn moveq lr, pc bxeq r12 MEND MACRO RETURN bx lr MEND MACRO RETURN_EQ bxeq lr MEND MACRO RETURN_NE bxne lr MEND ELSE MACRO CALL $Fn bl $Fn MEND MACRO CALLEQ $Fn bleq $Fn MEND MACRO RETURN mov pc, lr MEND MACRO RETURN_EQ moveq pc, lr MEND MACRO RETURN_NE movne pc, lr MEND ENDIF END INCLUDE s3c2410x.inc;C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\INC /////////////////////////一些2410硬件相关的一些定义 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 先从kxarm.h分析 GBLS VBar ---------------------GBLS 伪指令用于定义一个全局的字符串变量,并初始化为空; VBar SETS "|"-------------------将该变量赋值为"|" GBLL HaveExceptHandler-----GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为 F (假); GBLS AreaName GBLS FuncName GBLS PrologName GBLS FuncEndName GBLS ExceptHandler GBLS ExceptData AreaName SETS "|.text|"---------将该变量赋值为"|.text|" HaveExceptHandler SETL {FALSE}---------------将该变量赋值为假 //---------------------------------一些重要的宏定义--------------------------------------// MACRO TEXTAREA AREA |.text|,ALIGN=2,CODE,READONLY AreaName SETS "|.text|" MEND MACRO THUMBAREA AREA |.text|,ALIGN=2,CODE,READONLY,THUMB AreaName SETS "|.text|" MEND MACRO STARTUPTEXT AREA |.astart|,ALIGN=2,CODE AreaName SETS "|.astart|" MEND ///////////////////////////////////////////////////////////////////////////////////////////////// 1、 AREA 语法格式: AREA 段名 属性 1 ,属性 2 ,…… AREA 伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用 “ | ” 括起来,如 |1_test| 。 属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下: — CODE 属性:用于定义代码段,默认为 READONLY 。 — DATA 属性:用于定义数据段,默认为 READWRITE 。 — READONLY 属性:指定本段为只读,代码段默认为 READONLY 。 — READWRITE 属性:指定本段为可读可写,数据段的默认属性为 READWRITE 。 — ALIGN 属性:使用方式为 ALIGN 表达式。在默认时, ELF (可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为 0 ~ 31 ,相应的对齐方式为 2 表达式次方。 — COMMON 属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的 COMMON 段共享同一段存储单元。 一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。 使用示例: AREA Init , CODE , READONLY 该伪指令定义了一个代码段,段名为 Init ,属性为只读 2、 ALIGN 语法格式: ALIGN { 表达式 { ,偏移量 }} ALIGN 伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式 | 。其中,表达式的值用于指定对齐方式,可能的取值为 2 的幂,如 1 、 2 、 4 、 8 、 16 等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为: 2 的表达式次幂+偏移量。 使用示例: AREA Init , CODE , READONLY , ALIEN = 3 ;指定后面的指令为 8 字节对齐。 指令序列 END ;---------------------------------------再次对startup.s的疑惑---------------------------- ; Copy boot loader to memory ands r9, pc, #0xFF000000 ; see if we are in flash or in ram bne %f20 ; go ahead if we are already in ram ; This is the loop that perform copying. ldr r0, = 0x38000 ; offset into the RAM add r0, r0, #PHYBASE ; add physical base mov r1, r0 ; (r1) copy destination ldr r2, =0x0 ; (r2) flash started at physical address 0 ldr r3, =0x10000 ; counter (0x40000/4) 10 ldr r4, [r2], #4 str r4, [r1], #4 subs r3, r3, #1 bne %b10 ; Restart from the RAM position after copying. mov pc, r0 ;r0= 0x38000+#PHYBASE=0X30038000修改了PC相当于改变了存储指令地址,实现跳转 nop ;疑惑:既然已经跳转到内存中执行,但是为什么后面还会执行到20 标号下的东西呢 nop ;难道在内存中的函数使ARM再回来执行这个startup.s这个函数?但是就算回来,但是 nop ;感觉也没有这个必要啊 ----------------------------下面两句说明了在执行内存中的代码的时候有执行了startup.s这个汇编代码 ands r9, pc, #0xFF000000 ; see if we are in flash or in ram bne %f20 ; go ahead if we are already in ram ---------怎么会这样呢?麻烦指教一下。也许是我钻进了死胡同 引用 10 楼 freasy 的回复: 你的看法没错 ldr r0, = 0x38000 ; offset into the RAM add r0, r0, #PHYBASE ; add physical base 拷贝之前,这里先把拷贝后的目标地址先保存在r0里面,也就是说R0保存的是拷贝到内存之后的EBOOT首地址 拷贝完成之后 ; Restart from the RAM position after copying. mov pc, r0 这就跳转到内存当中的EBOOT入口再进来。 这样它的代码写起来简单一点。 当然,不同的EBOOT启… -----------------感觉是这样,谢谢前辈的回复。 -----------------在这里我想问个更加弱智的问题:就是为什么eboot启动2410/2440等ARM一上电就会执行startup.s这个汇编代码?这是由什么决定的?还是在哪里可以设置的?在哪里设置的?据我所知如果从Nandflash启动,一上电,ARM自动拷贝Nandflash前4K代码到内部SDRAM执行的。 /////////////////////////////////////////////////////// startup.s里有一个entry指示编译器把那里放最前面,使得CPU上电后能够直接执行到EBoot中的startup.s里面的那句话(这是对于NorFlash),或者是被Nand Flash跳转到(使用Nand Flash)
文章评论(0条评论)
登录后参与讨论