WinCE6.0学习之EBoot源码分析----startup.s

简介:
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255);">     startup.s文件是S3C6410引导程序EBoot的原始入口处,该文件的内容是以汇编形式编写的,本人花了几天的时间对startup.s进行了详细的研究,翻阅了大量的书籍和网络博客。网络上有一些大牛在其博客中对源码已经进行了分析,但本人感觉里面的有些部分对初学者还是不够清楚,谁让人家是大牛呢,直接在一定高度上讲,O(_)O,不过仍然非常感谢这些牛人无私的奉献出那些知识。
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: 21pt;"> 本人是WinCE的入门选手,将沿着自己的菜鸟学习之路,将自己的一些学习心得在这里记录下来,如果能够帮到以后的人,不胜荣幸。如果有什么分析的不正确的地方,欢迎拍砖,大家讨论才能更加进步。
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: 21pt;"> 大家都知道startup.s是用来完成硬件的初始化的,具体工作如下:
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 1、               设置CPU模式,使得可以无限制的访问内存和硬件,一般会设置为管理模式或者系统模式;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 2、               关闭所有的CPU中断;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 3、               关闭内存管理单元MMUTLB
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 4、               关闭写缓冲和Cache,使得Write BufferCache无效;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 5、               初始化内存控制器;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 6、               设置CPUPLL,设置时钟;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 7、               创建堆栈;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 8、               设置并打开MMU进行地址映射,打开Cache
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 9、               如果需要,拷贝EbootFlashRAM中;
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0cm 0cm 0pt 57pt; padding: 0px; max-width: 100%; font-size: 16px; color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); text-indent: -36pt;"> 10、           跳转到C语言的main函数。
<="" body="" style="font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; margin: 0px; padding: 0px; max-width: 100%;">
                INCLUDE         kxarm.h 
                INCLUDE         s3c6410.inc 
                INCLUDE         image_cfg.inc 
 
                IMPORT            OALClearUTLB 
                IMPORT            OALFlushICache 
                IMPORT            OALFlushDCache 
 
                IMPORT            System_DisableVIC 
                IMPORT            System_EnableIRQ 
                IMPORT            System_SetSyncMode 
                IMPORT            System_SetAsyncMode 
                IMPORT            System_EnableICache 
 
                EXPORT            StartUp
    首先是函数引用声明, IMPORT 伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,这些引用的标号在下面用到时会进行简要介绍, EXPORT  伪指令用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。
;------------------------------------------------------------------------------- 
;         Definition  for MMU table initialization 
;------------------------------------------------------------------------------- 
 
PT_1ST_BASE                 EQU         (DRAM_BASE_PA_START+0x10000)                ; 1st level Page Table Base Address (PHYBASE + 0x10000) save room  for interrupt vectors 
PT_1ST_ENTRY_CNB        EQU         (DRAM_BASE_PA_START+0x40E)                    ; Cached Area Page Table Entry (Cache/Unbuffer/RW), PA  base = 0x50000000 
PT_1ST_ENTRY_NCNB     EQU         (DRAM_BASE_PA_START+0x402)                    ; Uncached Area Page Table Entry (Uncache/Unbuffer/RW), PA  base = 0x50000000 
PTR_1ST_PTE                 EQU         ((DRAM_BASE_PA_START>>16)/4)                ; Ptr to 1st PTE  for 0x50000000 
BANK_SHIFT                    EQU         (20)
此部分用来声明一些变量,在 MMU 初始化时使用。 DRAM_BASE_PA_START PLATFORM\SMDK6410\SRC\INC\image_cfg.inc 中定义,这个是 DRAM 的基地址,与硬件相关, S3C2410 0x30000000 S3C6410 0x50000000
PT_1ST_BASE 是一级页表的基地址,一般都选在 DDR 开始地址 + 偏移值( offset )处, WinCe offset=64K Linux 也是,有资料 ARM 的页表基地址必须是 64K 对齐的,貌似在此处比较吻合,但是不知道为什么,有待进一步考证),所以此处在 DRAM_BASE_START 基础上加上了 0x10000 ,正好 64K
PT_1ST_ENTRY_CNB PT_1ST_ENTRY_NCNB 用来设置页表项的对应的虚拟内存页的访问权限和缓冲读写属性,下面用到时再进一步解释。
PTR_1ST_PTE BANK_SHIFT 下面用到时,自然就明白什么用处了。
;------------------------------------------------------------------------------ 

;         Macro  for LED on SMDK Board (GPN[15:12]) 

;         LED_ON  for physical address domain 
;         VLED_ON  for  virtual address domain 

;------------------------------------------------------------------------------ 
 
        MACRO 
 
                LED_ON         $data 
 
                ldr                    r10, =GPNPUD 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xFF000000         ; Pull-Up-Down Disable 
                str                    r11, [r10] 
 
                ldr                    r10, =GPNDAT 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xF000 
                ldr                    r12, =$data 
                mov                    r12, r12, lsl #12         ; [15:12] 
                orr                    r11, r11, r12 
                str                    r11, [r10] 
 
                ldr                    r10, =GPNCON 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xFF000000 
                orr                    r11, r11, #0x55000000         ; GPN[15:12] Output . 
                str                    r11, [r10] 
 
        MEND 
 
 
        MACRO 
 
                VLED_ON         $data 
 
                ldr                    r10, =vGPNPUD 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xFF000000         ; Pull-Up-Down Disable 
                str                    r11, [r10] 
 
                ldr                    r10, =vGPNDAT 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xF000 
                ldr                    r12, =$data 
                mov                    r12, r12, lsl #12         ; [15:12] 
                orr                    r11, r11, r12 
                str                    r11, [r10] 
 
                ldr                    r10, =vGPNCON 
                ldr                    r11, [r10] 
                bic                    r11, r11, #0xFF000000 
                orr                    r11, r11, #0x55000000         ; GPN[15:12] Output . 
                str                    r11, [r10] 
 
        MEND
    这部分是用来点亮 LED 灯的,在 Eboot 中可有可无,不过在这里也顺便分析一下。这里 LED 灯是接在 GPN 的管脚上,由 GPNPUD GPNDAT GPNCON 三个寄存器控制,具体功能参看一下手册吧,这三个寄存器的定义在 PLATFORM\COMMON\SRC\SOC\S3C6410_SEC_V1\OAL\INC\s3c6410.inc 文件中。此处用 MACRO MEND 来定义了一段代码的宏, $data 是宏的参数。
;------------------------------------------------------------------------------ 

;         StartUp Entry 

;         Main entry point  for CPU initialization. 

;------------------------------------------------------------------------------ 
        LEAF_ENTRY            StartUp 
 
                b                    ResetHandler 
                b                    .                                        ; HandlerUndef 
                b                    .                                        ; HandlerSWI 
                b                    .                                        ; HandlerPabort 
                b                    .                                        ; HandlerDabort 
                b                    .                                        ; HandlerReserved 
                b                    .                                        ; HandlerIRQ 
                b                    .                                        ; HandlerFIQ
    上面是 startup.s 的入口部分,由 LEAF_ENTRY 宏进行标示,进入到程序段 StartUp 中,由 ENTRY_END 标示程序段的结束。首先就跳转到 ResetHandler 处执行,这也是复位以后的位置,下面的跳转语句不应该进入(不过不知道为什么还要写?)。
ResetHandler 
 
                LED_ON 0x1
     这条语句就是应用上面定义的 LED_ON 宏,点亮 LED 指示灯。


本文转自jazka 51CTO博客,原文链接:http://blog.51cto.com/jazka/572602,如需转载请自行联系原作者
相关文章
|
Java jvm-sandbox Perl
Jvm-Sandbox源码分析--启动简析
1.工作原因,使用jvm-sandbox比较多,遂进行源码分析,做到知己知彼,个人能力有限,如有错误,欢迎指正。 2.关于jvm-sandbox 是什么,如何安装相关环境,可移步官方文档 3.源码分析基于jvm-sandbox 最新的master代码,tag-1.2.1。
8037 0
Jvm-Sandbox源码分析--启动简析
|
Linux
Linux驱动学习-----最简单的Hello程序
Linux驱动学习-----最简单的Hello程序
180 0
|
Web App开发 JavaScript API
Chrome操作指南——入门篇(十五)monitor
Chrome操作指南——入门篇(十五)monitor
Chrome操作指南——入门篇(十五)monitor