Chinaunix首页 | 论坛 | 博客
  • 博客访问: 470260
  • 博文数量: 105
  • 博客积分: 2258
  • 博客等级: 大尉
  • 技术积分: 922
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-23 13:21
文章分类

全部博文(105)

文章存档

2013年(1)

2012年(10)

2011年(94)

分类: Delphi

2011-09-20 10:25:00

startup.s
 
;---------------------------------------------------------------------
;设计名称  : MicroOS 
;描述   : 运行于ARM920T的微型操作系统
;版本   : 0.0.1
;运行于   : ARM920T
;起始设计时间 : 2009.5.7 ----->
;作者   : 孙文中
;Email   :

;
;   版权声明
;你可以随意使用,修改本设计的源码
;但是你同样要向其他学习者开放本设
;计的源码和你对本设计修改后的源码!
;--------------------------------------------------------------------- 
 
;---------------------------------------------------------------------
;startup.s
;系统启动代码
;起始时间 : 2009.5.7 ----->2009.5.11
;---------------------------------------------------------------------
 
;---------------------------------------------------------------------
 GET  ./Include/s3c2440.inc ;寄存器地址信息
 GET  ./Include/memcfg.inc ;内存控制器配置信息
 
;处理器模式
USERMODE  EQU  0x10
FIQMODE   EQU  0x11
IRQMODE   EQU  0x12
SVCMODE   EQU  0x13
ABORTMODE  EQU  0x17
UNDEFMODE  EQU  0x1b
SYSMODE   EQU  0x1f
;相关掩码
MODEMASK     EQU  0x1f
NOINT   EQU  0xc0
;各个处理器模式下堆栈设置
_STACK_BASEADDRESS EQU 0x33ff8000  ;BANK6 64MB顶部
UserStack  EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack  EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack  EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack  EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack  EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack  EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;导入操作系统入口函数
 IMPORT OSEntry
 
;导入外部C语言编写的异常与中断处理函数
 IMPORT vectorUNDEF
 IMPORT vectorSWI
 IMPORT vectorPABT
 IMPORT vectorDABT
 IMPORT vectorIRQ
 IMPORT vectorFIQ
;导入镜像装载域段起始地址
 IMPORT  |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
 IMPORT  |Image$$RW$$Base|   ; Base of RAM to initialise
 IMPORT  |Image$$ZI$$Base|   ; Base and limit of area
 IMPORT  |Image$$ZI$$Limit|  ; to zero initialise
;--------------------------------------------------------------------

;------------------------------------------------------
 AREA startup, CODE, READONLY
 
 ENTRY
;系统向量表
  b vectorRESET ;复位向量
  b vectorUNDEF ;未定义指令
  b vectorSWI ;软中断
  b vectorPABT ;预取指终止
  b vectorDABT ;数据终止
  b .   ;系统保留
  b vectorIRQ ;外部中断
  b vectorFIQ ;快速中断
;-------------------------------------------------------
;--------------------------------------------------------------------------
;复位向量
;复位向量是ARM处理器上电后第一个被执行的异常
;此时系统处理管理(SVC)模式
vectorRESET 
;复位向量有以下六件事要做
;第一步 : 关闭看门狗定时器屏蔽所有中断
;第二步 : 配置系统时钟
;第三步 : 配置内存控制器
;第四步 : 配置每种处理器模式下堆栈指针
;第五步 : 初始化镜像运行域
;第六步 : 跳转到操作系统入口

 ;------------------------------------------
 ;第一步 : 关闭看门狗定时器
 ;具体内容请参看s3c2440a数据手册的第18章
  ldr r0, =WTCON
  ldr  r1, =0x0
  str  r1, [r0, #0x0]
  
 ;屏蔽所有中断
  ldr r0, =INTMSK 
  ldr r1, =0xffffffff 
  str r1, [r0]
 ;------------------------------------------
 
 
 
 ;------------------------------------------
 ;第二步 : 配置系统时钟
 ;具体内容请看手册第7章
 
  ;先减少锁相环锁定时间,s3c2440a要求PLL
  ;锁定时间>300us,在上电时s3c2440a预设值
  ;mpll为晶体频率,我用的晶体频率为12MHz
  ;300us*12M = 3600设置LOCKTIME = 0xfff
  ;足够了
  ldr r0, =LOCKTIME
  ldr r1, =0xfff0fff0 ;高16为对应UPLL
       ;低16为对应MPLL
  str r1, [r0, #0x0]
  
  ;根据器件手册我们还有以下几个事要做
  ;step1.配置UPLL
  ;step2.配置MPLL
   ;注:手册要求先配置UPLL后MPLL
   ; 且之间要间隔7NOP
   ; 详请看手册第7-21.
  ;step3.配置分频系数
  
   ;step1:
   ldr r0, =UPLLCON
   ldr r1, =((56<<12) + (2<<4) + 2)
   ldr r1, [r0]
   
   ;按手册要求插入7个NOP
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   
   ;step2:
   ldr r0, =MPLLCON
   ldr r1, =((127<<12) + (2<<4) + 1)
   ldr r1, [r0]
   
   ;step3:
   ldr r0, =CLKDIVN
   ldr r1, =((0<<3) + (2 << 2) + 1)
   ldr r1, [r0]
 ;------------------------------------------
 
 
 
 ;------------------------------------------
 ;第三步 : 配置内存控制器
 ;内存控制内的寄存器器地址是连续分布的
 ;从0x4800_0000 -- 0x4800_0030,所以可以
 ;通过一个循环依次填入各个寄存器的内容
 
  ldr r0, =SMRDATA ;装入配置值的地址
  ldr r1, =BWSCON  ;装入起始寄存器地址
  add r2, r0, #0x34 ;计算结束地址
  
  ;下面是用于向内存控制器
  ;装入配置信息的循环
0  
  ldr r3, [r0], #4 ;装入配置值到r3,后变址
  str r3, [r1], #4  ;把r3内包含的配置值写入
       ;内存控制器的寄存器
  cmp r2, r0   ;结束否?
  bne %B0    ;没结束则继续
 ;------------------------------------------
 
 
 
 ;------------------------------------------
 ;第四步 : 配置每种处理器模式下堆栈指针
 ;方法与原则:
  ;1: 通过CPSR寄存器切换处理器模式
  ;2: 对CPSR的操作方式为 读-修改-写回
  ;3: 绝对不要跳到用户模式,跳过去容易
  ; 回来就难了
  ;4: 切到新处理器模式后要屏蔽IRQ和FIQ
  ; 防止在未设置好堆栈前进入中断处理
  ; 程序,但是在启动代码的最先我们已
  ; 经屏蔽了所有的32个中断源,所以感
  ; 觉是否屏蔽都可以
  
   ;step1: 先把程序状态寄存器读到r0
   mrs r0, cpsr  
   
   ;step2: 清除处理器模式位(最前面5位)
   bic r0, r0, #MODEMASK
   
   ;step3: 设置未定义状态下的堆栈指针
   orr r1, r0, #UNDEFMODE|NOINT
   msr cpsr_cxsf, r1  ;UndefMode
   ldr sp, =UndefStack  ;UndefStack=0x33FF_5C00
   
   ;step4: 设置终止状态下的堆栈指针
   orr r1, r0, #ABORTMODE|NOINT
   msr cpsr_cxsf, r1  ;AbortMode
   ldr sp, =AbortStack  ;AbortStack=0x33FF_6000
   
   ;step5: 设置中断模式下的堆栈指针
   orr r1, r0, #IRQMODE|NOINT
   msr cpsr_cxsf, r1  ;IRQMode
   ldr sp, =IRQStack  ;IRQStack=0x33FF_7000
   
   ;step6: 设置快速中断模式下的堆栈指针
   orr r1, r0, #FIQMODE|NOINT
   msr cpsr_cxsf, r1  ;FIQMode
   ldr sp, =FIQStack  ;FIQStack=0x33FF_8000
   
   ;step7: 设置管理模式下的堆栈指针
   orr r1, r0, #SVCMODE|NOINT
   msr cpsr_cxsf, r1  ;SVCMode
   ldr sp, =SVCStack  ;SVCStack=0x33FF_5800
   
   ;step8: 因为管理模式与用户模式共用
   ;  堆栈指针,所以借着系统模式
   ;  来设置用户模式的堆栈指针
   orr r1, r0, #SYSMODE|NOINT
   msr cpsr_cxsf, r1  ;SYSMode
   ldr sp, =UserStack  ;SVCStack & USERMode=0x33ff4800
   
   ;现在处理器处于系统模式
 ;------------------------------------------
   
   
   
 ;------------------------------------------
 ;第五步 : 初始化镜像运行域
 ;复制RW段和ZI段到SDRAM指定地址
 
  LDR     r0, =|Image$$RO$$Limit| ; 装入RO段结束地址
  LDR     r1, =|Image$$RW$$Base|  ; 装入RW段起始地址
  LDR     r3, =|Image$$ZI$$Base|  ; 装入ZI段起始地址
 
  
  ;|Image$$RO$$Limit| == |Image$$RW$$Base| ? 跳过RW段复制 : 复制RW段
  CMP     r0, r1    
  BEQ     %F2
  
  ;复制RW段
1      
  CMP     r1, r3 
  LDRCC   r2, [r0], #4    
  STRCC   r2, [r1], #4
  BCC     %B1
2      
  LDR     r1, =|Image$$ZI$$Limit|
  MOV     r2, #0
  
  ;构造ZI段
3      
  CMP     r3, r1    
  STRCC   r2, [r3], #4
  BCC     %B3
 
 ;------------------------------------------  
 
 
 
 ;------------------------------------------
 ;第六步 : 跳转到操作系统入口
 
  b OSEntry  ;不要使用main,因为如果使用main
      ;ads还会调用_main()初始化RW和ZI
      ;段,但是那里的数据和本程序不同
      
  b .
  
 ;------------------------------------------
 
;---------------------------------------------------------------------------
 
SMRDATA DATA
 ;这里是内存控制器的配置数据
 ;配置数据需要根据你使用的存储器修改
 ;在第三步时会将以下数据写入
 ;内存控制器的相关寄存器中
 ;共13个寄存器的配置值
 
 DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
 DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))   ;GCS0
 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   ;GCS1
 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   ;GCS2
 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   ;GCS3
 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   ;GCS4
 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   ;GCS5
 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))    ;GCS6
 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))    ;GCS7
 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
 DCD 0x32     ;SCLK power saving mode, BANKSIZE 128M/128M
 DCD 0x30     ;MRSR6 CL=3clk
 DCD 0x30     ;MRSR7 CL=3clk
 ALIGN  ;数据边界对齐
 
 END
/**********************************************************************************************/
以下是:asmlib.s
/**********************************************************************************************/
 AREA asmlib, CODE, READONLY
 
 END
/**********************************************************************************************/
以下是:kernel.c
/**********************************************************************************************/
#include "./Include/s3c2440.h"
void OSEntry()
{
 int data;
 int i;
 rGPBCON = 0x155555;
  
  
    data = 0x06;
    while(1)
    {
     
     rGPBDAT = (data<<5);
     for(i = 0; i < 0xffffff; i++)
      continue;
     data =~data;
 }
}
void vectorUNDEF()
{
}
void vectorSWI()
{
}
void vectorPABT()
{
}
void vectorDABT()
{
}
void vectorIRQ()
{
}
void vectorFIQ()
{
}
 
 
 
 
 
 
阅读(750) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~