WinCE6.0学习之EBoot源码分析----startup.s
2015-06-04 16:40
323 查看
<div class="MsoNormal" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px;"> startup.s文件是S3C6410引导程序EBoot的原始入口处,该文件的内容是以汇编形式编写的,本人花了几天的时间对startup.s进行了详细的研究,翻阅了大量的书籍和网络博客。网络上有一些大牛在其博客中对源码已经进行了分析,但本人感觉里面的有些部分对初学者还是不够清楚,谁让人家是大牛呢,直接在一定高度上讲,O(∩_∩)O,不过仍然非常感谢这些牛人无私的奉献出那些知识。<div
class="MsoNormal" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: 21pt;">本人是WinCE的入门选手,将沿着自己的菜鸟学习之路,将自己的一些学习心得在这里记录下来,如果能够帮到以后的人,不胜荣幸。如果有什么分析的不正确的地方,欢迎拍砖,大家讨论才能更加进步。<div
class="MsoNormal" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: 21pt;">大家都知道startup.s是用来完成硬件的初始化的,具体工作如下:<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">1、 设置CPU模式,使得可以无限制的访问内存和硬件,一般会设置为管理模式或者系统模式;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">2、 关闭所有的CPU中断;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">3、 关闭内存管理单元MMU和TLB;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">4、 关闭写缓冲和Cache,使得Write
Buffer和Cache无效;<div class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height:
28px; text-indent: -36pt;">5、 初始化内存控制器;<div class="MsoListParagraph" <=""
body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">6、 设置CPU的PLL,设置时钟;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">7、 创建堆栈;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">8、 设置并打开MMU进行地址映射,打开Cache;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">9、 如果需要,拷贝Eboot从Flash到RAM中;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">10、 跳转到C语言的main函数。<div
<="" body="" style="padding: 0px; margin: 0px;">
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的管脚上,由GPNDAT三个寄存器控制,具体功能参看一下手册吧,这三个寄存器的定义在MACRO来定义了一段代码的宏,
;------------------------------------------------------------------------------
;
; 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标示程序段的结束。首先就跳转到
ResetHandler
LED_ON 0x1
宏,点亮<span calibri','sans-serif';="" font-size:="" 10.5pt;="" mso-ascii-theme-font:="" minor-latin;="" mso-fareast-font-family:="" 宋体;="" mso-fareast-theme-font:=""
minor-fareast;="" mso-hansi-theme-font:="" mso-bidi-font-size:="" 11.0pt;="" mso-bidi-font-family:="" 'times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:=""
ar-sa"="" lang="EN-US" style="padding: 0px; margin: 0px;">LED<span times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa"="" style="padding: 0px; margin:
0px; font-size: 10.5pt;">指示灯。
本文出自 “飞雪待剑” 博客,请务必保留此出处/article/4603913.html
class="MsoNormal" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: 21pt;">本人是WinCE的入门选手,将沿着自己的菜鸟学习之路,将自己的一些学习心得在这里记录下来,如果能够帮到以后的人,不胜荣幸。如果有什么分析的不正确的地方,欢迎拍砖,大家讨论才能更加进步。<div
class="MsoNormal" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: 21pt;">大家都知道startup.s是用来完成硬件的初始化的,具体工作如下:<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">1、 设置CPU模式,使得可以无限制的访问内存和硬件,一般会设置为管理模式或者系统模式;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">2、 关闭所有的CPU中断;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">3、 关闭内存管理单元MMU和TLB;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">4、 关闭写缓冲和Cache,使得Write
Buffer和Cache无效;<div class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height:
28px; text-indent: -36pt;">5、 初始化内存控制器;<div class="MsoListParagraph" <=""
body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">6、 设置CPU的PLL,设置时钟;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">7、 创建堆栈;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">8、 设置并打开MMU进行地址映射,打开Cache;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">9、 如果需要,拷贝Eboot从Flash到RAM中;<div
class="MsoListParagraph" <="" body="" style="padding: 0px; margin: 0cm 0cm 0pt 57pt; color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 14px; line-height: 28px; text-indent: -36pt;">10、 跳转到C语言的main函数。<div
<="" body="" style="padding: 0px; margin: 0px;">
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的管脚上,由GPNDAT三个寄存器控制,具体功能参看一下手册吧,这三个寄存器的定义在MACRO来定义了一段代码的宏,
;------------------------------------------------------------------------------
;
; 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标示程序段的结束。首先就跳转到
ResetHandler
LED_ON 0x1
宏,点亮<span calibri','sans-serif';="" font-size:="" 10.5pt;="" mso-ascii-theme-font:="" minor-latin;="" mso-fareast-font-family:="" 宋体;="" mso-fareast-theme-font:=""
minor-fareast;="" mso-hansi-theme-font:="" mso-bidi-font-size:="" 11.0pt;="" mso-bidi-font-family:="" 'times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:=""
ar-sa"="" lang="EN-US" style="padding: 0px; margin: 0px;">LED<span times="" new="" roman';="" mso-bidi-theme-font:="" minor-bidi;="" mso-ansi-language:="" en-us;="" mso-fareast-language:="" zh-cn;="" mso-bidi-language:="" ar-sa"="" style="padding: 0px; margin:
0px; font-size: 10.5pt;">指示灯。
本文出自 “飞雪待剑” 博客,请务必保留此出处/article/4603913.html
相关文章推荐
- 一封来自知乎的手机拍摄要领
- 第14周-输入输出流,文本文件-项目0-课后实践·程序阅读5
- C语言的不完整类型(incomplete type)和前置声明
- 使用Spark+Cassandra打造高性能数据分析平台
- 神话电视剧配乐
- Centos编译安装 LAMP (apache-2.4.7 + mysql-5.5.35 + php 5.5.8)+ Redis
- js操作cookie方法
- OK335xS-Android mkmmc-android-ubifs.sh hacking
- 在Linux下使用Prips打印指定范围内的IP地址的方法
- 新版FFmpeg音频编解码处理
- IOS开发系列--GCD详解介绍
- Firefly3288—Lubuntu显示0-4串口设备
- POJ2752KMP逆序处理
- 关于Class.getResource和ClassLoader.getResource的路径问题
- ecshop的订单状态
- linux下tomcat开机启动配置
- 周记:适配心得
- poj2987最大权闭包(输出最少建塔个数)
- UIAlertView以及UIAlertController
- JS网站右下角悬浮视窗可关闭广告