keil下的s3c2440启动代码分析

由于片面问题,所以可能会看起来不太美观,可以看附件中的内容。

ARM启动代码相当于我们电脑的BIOS,也就是ARM启动时对处理器的一些初始化及嵌入式系统硬件的一些初始化。

由于它直接面对处理器内核和硬件控制器进行编程,一般都是用汇编语言。

一般包括:中断向量表,初始化存储器系统,初始化堆栈,初始化有特殊要求的断口,设备初始化,变量初始化等。

这几天对着RealView MDK-ARM中自带的启动代码研究了一下,遇到问题又对着数据手册和指令表看了一下,总算对S3C2440A的硬件有了一个大致的了解。

学习嵌入式系统重在系统,学习ARM只是为学习嵌入式系统铺路,懒猫比较笨可能在上系统之前要裸奔几天以强化以下对S3C2440A内部结构的了解。

把MDK自带的S3C2440A.S文件的注释发一下,这些是懒猫结合数据手册与ARM指令表理解了,可能会有错误,放在这里只是引导一下像我一样还没有入门的兄弟们,希望你们不要害怕ARM害怕嵌入式,老毛他老人家说的对,世上无难事,只怕有心人,ARM指令就那么多,看一遍不会就多看几遍,还有一定要学习看软件自带的帮助文件.;/*****************************************************************************/;/* S3C2440.S: Startup file for Samsung S3C440 */;/*****************************************************************************/;/* <<< Use Configuration Wizard in Context Menu >>> */ ;/*****************************************************************************/;/* This file is part of the uVision/ARM development tools. */ ;/* Copyright (c) 2005-2008 Keil Software. All rights reserved. */ ;/* This software may only be used under the terms of a valid, current, */;/* end user licence from KEIL for a compatible version of KEIL softwar e */;/* development tools. Nothing else gives you the right to use this softwa re. */;/*****************************************************************************/;下面这些参数是与CPSR状态寄存器有关;参数的由来:这里各个模式的参数是由寄存器CPSR的模式位设置M[4:0]得来的,;比如这里的用户模式,CPSR的M[4:0]设置为10000就是0x10。

;;Mode_USR -- 用户模式,正常程序执行模式,用于应用程序;Mode_FIQ -- 快速中断模式,用于高速数据传输和通道处理。

;Mode_IRQ -- 外部中断模式,用于通用的中断处理。

;Mode_SVC -- 管理模式,使用的一种保护模式。

;Mode_ABT -- 数据访问中止模式,用于虚拟存储用存储保护;Mode_UND -- 未定义指令中止模式,当未定义指令执行时进入此模式。

;Mode_SYS -- 系统模式,用于特权级的操作系统任务。

;I_Bit -- 如果I位被置1,则外部中断被禁止(IRQ is disabled);F_Bit -- 如果F位被置1,则快速中断被禁止(FIQ is disabled);;----------------------------------------------------------------------Mode_USR EQU 0x10Mode_FIQ EQU 0x11Mode_IRQ EQU 0x12Mode_SVC EQU 0x13Mode_ABT EQU 0x17Mode_UND EQU 0x1BMode_SYS EQU 0x1FI_Bit EQU 0x80 ; when I bit is set, IRQ is disabledF_Bit EQU 0x40 ; when F bit is set, FIQ is disabled;-----------------------------栈初始化定义-----------------------------------;下面这些主要是栈配置,系统的栈空间设定;;UND_Stack_Size -- 未定义模式的栈大小;SVC_Stack_Size -- 超级用户模式的栈大小;ABT_Stack_Size -- 数据访问终止模式的栈大小;FIQ_Stack_Size -- 快速中断模式的栈大小;IRQ_Stack_Size -- 外部中断模式的栈大小;USR_Stack_Size -- 用户模式的栈大小;ISR_Stack_Size -- 总堆栈的大小,也就是也有模式下堆栈相加;;-----------------------------------------------------------------------UND_Stack_Size EQU 0x00000000SVC_Stack_Size EQU 0x00000008ABT_Stack_Size EQU 0x00000000FIQ_Stack_Size EQU 0x00000000IRQ_Stack_Size EQU 0x00000080USR_Stack_Size EQU 0x00000400ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_St ack_Size + \FIQ_Stack_Size + IRQ_Stack_Size);-----------------------------------------------------------------------;AREA -- 是一个伪指令,用于段定义。

ARM的汇编程序由段组成,段是相对独立; 的指令或数据单位,每个段由AREA伪指令定义,并定义段的属性。

; STACK -- AREA指令的一个参数,定义段名称; NOINIT -- AREA指令的一个参数,指定本数据段仅仅保留了内在单元,而; 将句初始值写入内存单元,也即将内存单元值初始化为0; READWRITE -- 指定本段为可读可写,数据段默认为READWRITE。

; READWRITE(读写)、READONLY(只读);ALIGN -- 也是一个伪指令,指定对齐方式。

ALIGN n 指令的对齐值有两种方案; 即n 或2^n,这里采用第二种方案即指定后面的指令8字节对齐。

;;下面这句话的意思是:;开辟一个堆栈段,段名字为STACK,定义为可读可写,将内存单元初始化为0, ;-----------------------------------------------------------------------AREA STACK, NOINIT, READWRITE, ALIGN=3;-----------------------------------------------------------------------;SPACE -- 伪指令,用于分配一块内存单元,并用0初始化,与%同义;其指令格式为:; {lable} SPACE expr;lable -- 内存起始地址标号expr -- 所要分配的内存字节数;-----------------------------------------------------------------------Stack_Mem SPACE USR_Stack_Size ;堆栈内存起始地址标号__initial_sp SPACE ISR_Stack_Size ;汇编代码的地址标号Stack_Top ;堆栈段内容结束,在这里放个标号,用来获得堆栈顶部地址Heap_Size EQU 0x00000000 ;定义堆大小设置;开辟一个名字为HEAP可读可写,不初始化内存单的内存单元。

AREA HEAP, NOINIT, READWRITE, ALIGN=3__heap_base ;堆的基址Heap_Mem SPACE Heap_Size ;堆内存起始地址标号__heap_limit ;堆结束;----------------------------内存初始化定义-----------------------------;在一些应用系统中除了扩展Flash,RAM挂接在外部存储器接口上外,可能还有其它;的外设挂接在外部存储器接口上,不同外设的操作时序什么的都是不一样的,所以;在使用这些外设之前必须初始化连接这些外设存储器接口。

这里因为没扩展,所以;只定义一个片上内存基地址。

;-----------------------------------------------------------------------IRAM_BASE EQU 0x40000000 ;片上SRAM的基地址,即内存基地址;-------------------------看门狗初始化定义------------------------------;看门狗在防止程序跑飞,进入无限死循环时起着重要作用。

有些应用可能用不上;看门狗功能,也可能有些应用会用到外部看门狗。

在这个时候内部看门狗必须禁;止,所以有时候会在初始化时将内部看门狗禁止,当以后应用用到时再开启它。

;看门狗定时器包括三个寄存器:;WTCON -- 看门狗控制寄存器,设定看门狗定时器模式;WTDAT -- 看门狗数据寄存器,用于设定超时宽度;WTCNT -- 看门狗计数寄存器,里面存放的是看门狗定时器当前值;;WT_BASE -- 看门狗定时器基地址;WTCON_OFS -- 看门狗控制寄存器偏移地址,相对于基址;WTDAT_OFS -- 看门狗数据寄存器偏移地址,相对于基址;WTCNT_OFS -- 看门狗计数寄存器偏移地址,相对于基址;WT_SETUP -- 看门狗设置;WTCON_Val -- 看门狗控制寄存器设置,关闭看门狗;WTDAT_Val -- 看门狗数据寄存器设置,初始值即为0x8000;-----------------------------------------------------------------------WT_BASE EQU 0x53000000 ; Watchdog Timer Base Address WTCON_OFS EQU 0x00 ; Watchdog Timer Control Register Offse tWTDAT_OFS EQU 0x04 ; Watchdog Timer Data Register Offs etWTCNT_OFS EQU 0x08 ; Watchdog Timer Count Register Offs etWT_SETUP EQU 0WTCON_Val EQU 0x00000000WTDAT_Val EQU 0x00008000;----------------------------时钟与电源管理定义-------------------------;S3C2440A中的时钟控制逻辑可以产生必须的时钟信号,包括CPU的FCLK,A HB总线的;HCLK 以及APB总线外设的PCLK 3C2440A内部有两个锁相环(PLL):一个提供FCLK,;HCLK及PCLK,另一个专用于USB模块(48MHz).;;CLOCK_BASE -- 时钟基地址;LOCKTIME_OFS -- 锁相环锁定时间计数寄存器偏移地址,相对于基址;MPLLCON_OFS -- MPLL配置寄存器偏移地址,相对于基址,主时钟源PLL ;UPLLCON_OFS -- UPLL配置寄存器偏移地址,相对于基址,USB时钟源P LL;CLKCON_OFS -- 时钟控制寄存器偏移地址,相对于基址;CLKSLOW_OFS -- 时钟减慢控制寄存器偏移地址,相对于基址;CLKDIVN_OFS -- 时钟分频器控制寄存器偏移地址,相对于基址;CAMDIVN_OFS -- 摄像头时钟分频器控制寄存器偏移地址,相对于基址,UP LL提供;;CLOCK_SETUP -- 时钟设置;LOCKTIME_Val -- PLL锁定时间计数器值;MPLLCON_Val -- MPLL配置寄存器值;UPLLCON_Val -- UPLL配置寄存器值;CLKCON_Val -- 时钟配置寄存器值;CLKSLOW_Val -- 时钟减慢控制寄存器值;CLKDIVN_Val -- 时钟分频控制寄存器值;CAMDIVN_Val -- 摄像头分频控制寄存器值;-----------------------------------------------------------------------CLOCK_BASE EQU 0x4C000000 ; Clock Base Address LOCKTIME_OFS EQU 0x00 ; PLL Lock Time Count Register Offs etMPLLCON_OFS EQU 0x04 ; MPLL Configuration Register Offset UPLLCON_OFS EQU 0x08 ; UPLL Configuration Register Offset CLKCON_OFS EQU 0x0C ; Clock Generator Control Reg Offse tCLKSLOW_OFS EQU 0x10 ; Clock Slow Control Register Offset CLKDIVN_OFS EQU 0x14 ; Clock Divider Control Register Offse tCAMDIVN_OFS EQU 0x18 ; Camera Clock Divider Register Offs etCLOCK_SETUP EQU 0LOCKTIME_Val EQU 0x0FFF0FFFMPLLCON_Val EQU 0x00043011UPLLCON_Val EQU 0x00038021CLKCON_Val EQU 0x001FFFF0CLKSLOW_Val EQU 0x00000004CLKDIVN_Val EQU 0x0000000FCAMDIVN_Val EQU 0x00000000;--------------------存储控制器设置定义---------------------------------;下面这些都是一些关于存储控制器的地址宏定义;;MC_BASE -- 存储控制器基地址;BWSCON_OFS -- 总线宽度和等待控制寄存器偏移地址;BANKCON0_OFS -- BANK1控制寄存器偏移地址; .; .;BANKCON7_OFS -- BANK7控制寄存器偏移地址;REFRESH_OFS -- DRAM/SDRAM刷新控制寄存器偏移地址;BANKSIZE_OFS -- 可调的bank大小寄存器偏移地址;MRSRB6_OFS -- bank6模式控制寄存器偏移地址;MRSRB7_OFS -- bank7模式控制寄存器偏移地址;;MC_SETUP -- 存储器控制寄存器设置;BWSCON_Val -- 写入总线宽度和等待控制寄存值;BANKCON0_Val -- 写入Blank0的值; .; .;BANKCON7_Val -- 写入BANK7 的值;REFRESH_Val -- 写入DRAM/SDRAM刷新控制寄存的值;BANKSIZE_Val -- 写入可调的bank大小寄存的值;MRSRB6_Val -- 写入bank6模式控制寄存器的值;MRSRB7_Val -- 写入bank7模式控制寄存器的值;-----------------------------------------------------------------------MC_BASE EQU 0x48000000 ; Memory Controller Base Addres sBWSCON_OFS EQU 0x00 ; Bus Width and Wait Status Ctrl Offs etBANKCON0_OFS EQU 0x04 ; Bank 0 Control Register Offset BANKCON1_OFS EQU 0x08 ; Bank 1 Control Register Offset BANKCON2_OFS EQU 0x0C ; Bank 2 Control Register Offset BANKCON3_OFS EQU 0x10 ; Bank 3 Control Register Offset BANKCON4_OFS EQU 0x14 ; Bank 4 Control Register Offset BANKCON5_OFS EQU 0x18 ; Bank 5 Control Register Offset BANKCON6_OFS EQU 0x1C ; Bank 6 Control Register Offs etBANKCON7_OFS EQU 0x20 ; Bank 7 Control Register Offs etREFRESH_OFS EQU 0x24 ; SDRAM Refresh Control Register OffsetBANKSIZE_OFS EQU 0x28 ; Flexible Bank Size Register Off setMRSRB6_OFS EQU 0x2C ; Bank 6 Mode Register Offs etMRSRB7_OFS EQU 0x30 ; Bank 7 Mode Register Offs etMC_SETUP EQU 1BWSCON_Val EQU 0x22000000BANKCON0_Val EQU 0x00000700BANKCON1_Val EQU 0x00000700BANKCON2_Val EQU 0x00000700BANKCON3_Val EQU 0x00000700BANKCON4_Val EQU 0x00000700BANKCON5_Val EQU 0x00000700BANKCON6_Val EQU 0x00018005BANKCON7_Val EQU 0x00018005REFRESH_Val EQU 0x008404F3BANKSIZE_Val EQU 0x00000032MRSRB6_Val EQU 0x00000020MRSRB7_Val EQU 0x00000020;---------------------I/O端口宏定义--------------------------------------;GPA_BASE -- 端口A基地址; .;GPJ_BASE -- 端口J基地址;GPCON_OFS -- 端口配置寄存器偏移地址;GPDAT_OFS -- 端口数据寄存器偏移地址;GPUP_OFS -- 端口上拉寄存器偏移地址;GP_SETUP -- 端口设置;GPA_SETUP -- 端口A配置;GPACON_Val -- 写入端口A配置寄存器的值; .; .;GPJ_SETUP -- 端口J配置;GPJCON_Val -- 写入端口J配置寄存器的值;GPJUP_Val -- 写入端口J上拉寄存器的值;-----------------------------------------------------------------------GPA_BASE EQU 0x56000000 ; GPA Base AddressGPB_BASE EQU 0x56000010 ; GPB Base AddressGPC_BASE EQU 0x56000020 ; GPC Base AddressGPD_BASE EQU 0x56000030 ; GPD Base AddressGPE_BASE EQU 0x56000040 ; GPE Base AddressGPF_BASE EQU 0x56000050 ; GPF Base AddressGPG_BASE EQU 0x56000060 ; GPG Base AddressGPH_BASE EQU 0x56000070 ; GPH Base AddressGPJ_BASE EQU 0x560000D0 ; GPJ Base Address GPCON_OFS EQU 0x00 ; Control Register Offset GPDAT_OFS EQU 0x04 ; Data Register OffsetGPUP_OFS EQU 0x08 ; Pull-up Disable Register Offset GP_SETUP EQU 1;-----------------------------------------------------------------------;端口A配置;----------------------------------------------------------------------- GPA_SETUP EQU 0GPACON_Val EQU 0x000003FF;----------------------------------------------------------------------- ;端口B配置;----------------------------------------------------------------------- GPB_SETUP EQU 0GPBCON_Val EQU 0x00000000GPBUP_Val EQU 0x00000000;----------------------------------------------------------------------- ;端口C配置;----------------------------------------------------------------------- GPC_SETUP EQU 0GPCCON_Val EQU 0x00000000GPCUP_Val EQU 0x00000000;----------------------------------------------------------------------- ;端口D配置;----------------------------------------------------------------------- GPD_SETUP EQU 0GPDCON_Val EQU 0x00000000GPDUP_Val EQU 0x00000000;----------------------------------------------------------------------- ;端口E配置;----------------------------------------------------------------------- GPE_SETUP EQU 0GPECON_Val EQU 0x00000000GPEUP_Val EQU 0x00000000;----------------------------------------------------------------------- ;端口F配置;----------------------------------------------------------------------- GPF_SETUP EQU 0GPFCON_Val EQU 0x00000000GPFUP_Val EQU 0x00000000;----------------------------------------------------------------------- ;端口G配置;----------------------------------------------------------------------- GPG_SETUP EQU 0GPGCON_Val EQU 0x00000000GPGUP_Val EQU 0x00000000;-----------------------------------------------------------------------;端口H配置;-----------------------------------------------------------------------GPH_SETUP EQU 0GPHCON_Val EQU 0x00000000GPHUP_Val EQU 0x00000000;-----------------------------------------------------------------------;端口J配置;-----------------------------------------------------------------------GPJ_SETUP EQU 0GPJCON_Val EQU 0x00000000GPJUP_Val EQU 0x00000000;-----------------------------------------------------------------------;PRESERVE8 -- 伪指令,指示当前文件请求堆栈为8字节对齐。

合集下载

s3c2410ARM9启动代码分析

s3c2410ARM9启动代码分析

ADS下C语言的入口方式和ROM镜像文件的生成这部分介绍下ADS下如何生成可以运行的ROM镜像文件,我们知道当程序下载到flash中运行的时候,对于RW、ZI数据就存在着两个环境,一个load环境,一个是exec环境,有时候由于速度的需要RO数据也要重新加载,那么对RO数据也是有两个环境。

编译器产生ROM镜像文件时候,这三块数据的存放依次为RO、RW、ZI,并且地址空间时连续的。

但是到了运行的时候,RW数据必须被拷贝到SDRAM(SRAM)中以支持读写,这就是我们所谓的运行环境。

那么就要有一段代码去完成这个任务,在本章中我们介绍如何生成这段代码。

玩过2410的朋友都知道2410初始化代码中有一段搬运RW和ZI初始化的代码,没错,它确实能够在一定程度上完成上面所说的任务,只要我们在生成二进制可执行代码的时候在编译器链接项的地方填写正确的RO&RW地址,(比如RO = 0, RW = 0x30000000), 那么将程序下到NOR flash的零地址并从nor flash启动,启动代码会将RW&ZI数据弄到0x30000000,程序就能跑起来了。

但是各位有没有想过,怎么把RO代码弄到SDRAM中(有时候这是必须的,比方后面我将提到用nor flash的bootloader烧写nor flash)?如果直接设RO=0x30000000,那么这段代码下载到0地址肯定跑不起来,除非是ROPI,这个要求就高了。

这里我们有必要从介绍ADS 中规定的C语言入口开始,ADS中从初始化汇编代码跳到main函数有两种方式,main和__main:1,在__main入口的模式下,汇编代码的指令为b __main, 编译器在跳转到main之前还要作一系列的工作,这其中就包括对运行环境的初始化,在<ADS COMPILE GUIDE>中提到:copies nonroot(RO&RW) execution regions from load addr to exec addr, and Zeros ZI region. 借助编译器,我们就可以定义更为复杂的运行环境,这里要用到scatter文件(.scf),比如我们要的目标运行环境是:将启动代码以外的所有代码都拷贝到SDRAM的初始地址中运行,比且把RW段设在0x30800000,那么对应的scf文件如下:FLASH 0x0 0x200000{EXEC1 0x0 0x200000{2410init.o(Init, +First)__main.o(+RO) ; copy code* (Region$$Table) ; RO/RW addresses to copy* (ZISection$$Table) ; ZI addresses to zero}EXEC2 0x30000000 0x00800000{*(+RO)}SDRAM 0x30800000 0x00800000{*(+RW,+ZI)}};Sections named Region$$Table and ZISection$$Table which contain the addresses of the code/data to be copied.当然,在这种模式下,有些入口函数必须自己重定义,比如__user_initial_stackheap,具体参见ADS文档。

s3c2240按键分析程序

s3c2240按键分析程序

s3c2240按键分析程序这里分析了4个按键,还有ENIT8和EINT19没有,不过原理一样的。

4个按键,分别是EINT11/GPG3EINT13/GPG5EINT14/GPG6EINT15/GPG7外部上拉电阻。

EINT8-23共用一个IRQ向量。

初始化步骤1,设置IO的功能,00输入01输出02第二功能P292设置的方法是rGPGCON&=~(3<<3*2|3<<5*2|3<<6*2|3<<7*2);rGPGCON|=(2<<3*2|2<<5*2|2<<6*2|2<<7*2);2,设置EXTINT系列寄存器,设定中断触发的类型P301其中这次用到的EINT1113-15是分布在EXTINT1中触发类型000低电平001高电平01x下降弦10x上升弦11x边缘触发rEXTINT1&=~(7<<12|7<<20|7<<24|7<<28);rEXTINT1|=(2<<12|2<<20|2<<24|2<<28);3,设置EINTPEND,P306如果发生中断,该寄存器对应的位置一,没有中断则为0清零的办法比较特殊,对对应位置一的话表示清零。

所以这里要这样做:rEINTPEND|=(1<<11)|(1<<13)|(1<<14)|(1<<15);4,设置EINTMASK寄存器,P3050表示允许对应位中断,1表示禁止对应位中断,默认是禁止的rEINTMASK&=~((1<<11)|(1<<13)|(1<<14)|(1<<15));5,先清一下IRQ中断作为初始化,需要先清一下,注意,刚才EINTPEND是清次中断,EXTINT8-23都递属于IRQ的中断号5,所以这里清的是主IRQ中断ClearPending(BIT_EINT8_23);其中ClearPending();是一个内联函数,原型在2440addr.h由于在头文件里面不适宜放函数的实现,所以这次移植将函数体放到2440lib.c里面,而2440addr.h保留函数的定义__inline void ClearPending(int bit){register i;rSRCPND=bit;rINTPND=bit;i=rINTPND;}函数很简单,跟前面一样,在INTPND对应位置1就能清除该位的中断标志了。

s3c2440 启动代码

s3c2440 启动代码

;******************************************************** ;S3C2440启动代码startup.s;******************************************************** PRESERVE8AREA START, CODE, READONL YENTRYCODE32GET 2440addr.incIMPORT InitPLLIMPORT InitBankIMPORT InitStackIMPORT InitRORWZIIMPORT IRQ_DispatchIMPORT Main;异常向量表LDR PC, =HANDLE_ResetInit ;复位异常LDR PC, =HandlerUndef ;未定义指令异常LDR PC, =HandlerSWI ;软中断异常LDR PC, =HandlerPabort ;取指中止异常LDR PC, =HandlerDabort ;数据中止异常LDR PC, . ;保留LDR PC, =HandlerIRQ ;IRQ中断异常LDR PC, =HandlerFIQ ;FIQ中断异常;******************************************************** ;复位异常处理函数;处理系统的复位异常,初始化硬件系统环境,并调到c语言;******************************************************** HANDLE_ResetInit;关闭看门狗LDR R0, =WTCONLDR R1, =0X0STR R1, [R0];屏蔽IRQ和FIQ中断位MRS R0, CPSRORR R0, R0, #0xc0MSR CPSR_c, R0BL InitPLL ;配置MPLL和UPLL时钟BL InitBank ;配置bank的参数BL InitStack ;配置各种模式下的堆栈BL InitRORWZI ;RW和ZI段的初始化;开启IRQ和FIQ中断位MRS R0, CPSRAND R0, R0, #0x1FMSR CPSR_c, R0B MainHandlerUndef;未定义指令异常处理函数(未实现) HandlerSWI;软中断处理函数(未实现) HandlerPabort ;指令终止异常处理函数(未实现) HandlerDabort;数据终止异常处理函数(未实现) HandlerIRQ;终端异常处理函数(未实现) SUB LR, LR, #4STMFD SP!, {R0-R12, LR}LDR LR, =RETURN_ADDRLDR PC, =IRQ_DispatchRETURN_ADDRLDMFD SP!, {R0-R12, PC}^;SPSR复制到CPSR中;是把R0到R7及其PC等十三个寄存器的值都恢复HandlerFIQ;快速中断异常处理函数(未实现) END;************************************;MPLL和UPLL参数配置;***********************************AREA PLL, CODE, READONL YENTRYCODE32GET 2440addr.incEXPORT InitPLL;UPLL时钟配置,UPLL只能48MHz或48MHzUPLL_MDIV_V AL EQU 0X38UPLL_PDIV_V AL EQU 0X2UPLL_SDIV_V AL EQU 0X2UPLL_MDIV EQU (UPLL_MDIV_V AL << 12)UPLL_PDIV EQU (UPLL_PDIV_V AL << 4)UPLL_SDIV EQU (UPLL_SDIV_V AL << 0)DIVN_UPLL EQU 0;MPLL时钟配置,MPLL在200MHz-600MHzMPLL_MDIV_V AL EQU 0X44MPLL_PDIV_V AL EQU 1MPLL_SDIV_V AL EQU 1MPLL_MDIV EQU (MPLL_MDIV_V AL << 12)MPLL_PDIV EQU (MPLL_PDIV_V AL << 4)MPLL_SDIV EQU (MPLL_SDIV_V AL << 0)HDIVN EQU 3PDIVN EQU 1UPLL_V AL EQU (UPLL_MDIV | UPLL_PDIV | UPLL_SDIV) MPLL_V AL EQU (MPLL_MDIV | MPLL_PDIV | MPLL_SDIV) CLKDIVN_V AL EQU ((DIVN_UPLL << 3) | (HDIVN << 1) | (PDIVN << 0)) ;以上配置产生的MPLL时钟频率如下;FCLK EQU 304;HCLK EQU 101;PCLK EQU 50 ;系统时钟MPLL和UPLL配置InitPLLLDR R0, =LOCKTIME ;配置PLL的稳定周期时间LDR R1, =0xFFFFFFFFSTR R1, [R0]LDR R0, =CLKDIVN ;配置CLKDIVN时钟分频器LDR R1, =CLKDIVN_V ALSTR R1, [R0]mrc p15, 0, r0, c1, c0, 0 ;/*read ctrl register tekkaman*/ orr r0, r0, #0xc0000000 ;/*Asynchronous tekkaman*/ mcr p15, 0, r0, c1, c0, 0 ;/*write ctrl register tekkaman*/LDR R0, =UPLLCON ;配置UPLLLDR R1, =UPLL_VALSTR R1, [R0]NOPNOP;……(需要大于7个NOP的缓冲)NOPLDR R0, =MPLLCON ;配置MPLLLDR R1, =MPLL_V ALSTR R1, [R0]BX LR;MOV PC, LR ;(这种方式比较不好)END;************************************ ;BANK参数配置;*********************************** AREA BANK, CODE, READONL YENTRYCODE32GET 2440addr.incEXPORT InitBank;BWSCONDW8 EQU (0X0)DW16 EQU (0X1)DW32 EQU (0X2)WAIT EQU (0X1 << 2)UBLB EQU (0X1 << 3)B0_BWS EQU (DW16 << 1)B1_BWS EQU (DW32 << 4)B2_BWS EQU (DW16 << 8)B3_BWS EQU (DW16 << 12)B4_BWS EQU (DW16 << 16)B5_BWS EQU (DW16 << 20)B6_BWS EQU (DW32 << 24)B7_BWS EQU (DW32 << 28);BANK0配置参数B0_Tacs EQU (0X0 << 13)B0_Tcos EQU (0X0 << 11)B0_Tacc EQU (0X7 << 8)B0_tcoh EQU (0X0 << 6) B0_tah EQU (0X0 << 4)B0_tacp EQU (0X0 << 2) B0_tPMC EQU (0X0 << 0);BANK1配置参数B1_Tacs EQU (0X0 << 13) B1_Tcos EQU (0X0 << 11) B1_Tacc EQU (0X7 << 8)B1_tcoh EQU (0X0 << 6)B1_tah EQU (0X0 << 4)B1_tacp EQU (0X0 << 2)B1_tPMC EQU (0X0 << 0);BANK2配置参数B2_Tacs EQU (0X0 << 13) B2_Tcos EQU (0X0 << 11) B2_Tacc EQU (0X7 << 8)B2_tcoh EQU (0X0 << 6)B2_tah EQU (0X0 << 4)B2_tacp EQU (0X0 << 2)B2_tPMC EQU (0X0 << 0);BANK3配置参数B3_Tacs EQU (0X0 << 13) B3_Tcos EQU (0X0 << 11) B3_Tacc EQU (0X7 << 8)B3_tcoh EQU (0X0 << 6)B3_tah EQU (0X0 << 4)B3_tacp EQU (0X0 << 2)B3_tPMC EQU (0X0 << 0);BANK4配置参数B4_Tacs EQU (0X0 << 13)B4_Tcos EQU (0X0 << 11)B4_Tacc EQU (0X7 << 8)B4_tcoh EQU (0X0 << 6)B4_tah EQU (0X0 << 4)B4_tacp EQU (0X0 << 2)B4_tPMC EQU (0X0 << 0);BANK5配置参数B5_Tacs EQU (0X0 << 13)B5_Tcos EQU (0X0 << 11)B5_Tacc EQU (0X7 << 8)B5_tcoh EQU (0X0 << 6)B5_tah EQU (0X0 << 4)B5_tacp EQU (0X0 << 2)B5_tPMC EQU (0X0 << 0);BANK6配置参数B6_MT EQU (0X3 << 15) B6_Trcd EQU (0X1 << 2) B6_SCAN EQU (0X1 << 0);BANK7配置参数B7_MT EQU (0X3 << 15) B7_Trcd EQU (0X1 << 2) B7_SCAN EQU (0X1 << 0);REFRESH参数REFEN EQU (0X1 << 23) TREFMD EQU (0X0 << 22) Trp EQU (0X2 << 20)Trc EQU (0X2 << 18)Tchr EQU (0X2 << 16)REFCET EQU (1653 << 0);参数配置组合BWSCON_V AL EQU (B0_BWS|B1_BWS| B2_BWS | B3_BWS| B4_BWS | B5_BWS | B6_BWS | B7_BWS)BANKCON0_V AL EQU (B0_Tacs | B0_Tcos | B0_Tacc | B0_tcoh | B0_tah | B0_tacp | B0_tPMC)BANKCON1_V AL EQU (B1_Tacs | B1_Tcos | B1_Tacc | B1_tcoh | B1_tah | B1_tacp | B1_tPMC)BANKCON2_V AL EQU (B2_Tacs | B2_Tcos | B2_Tacc | B2_tcoh | B2_tah | B2_tacp | B2_tPMC)BANKCON3_V AL EQU (B3_Tacs | B3_Tcos | B3_Tacc | B3_tcoh | B3_tah | B3_tacp | B3_tPMC)BANKCON4_V AL EQU (B4_Tacs | B4_Tcos | B4_Tacc | B4_tcoh | B4_tah | B4_tacp | B4_tPMC)BANKCON5_V AL EQU (B5_Tacs | B5_Tcos | B5_Tacc | B5_tcoh | B5_tah | B5_tacp | B5_tPMC)BANKCON6_V AL EQU (B6_MT | B6_Trcd | B6_SCAN)BANKCON7_V AL EQU (B7_MT | B7_Trcd | B7_SCAN)REFRESH_V AL EQU (REFEN| TREFMD | Trp | Trc | Tchr | REFCET)BANKSIZE_VAL EQU (0X32)MRSRB6_V AL EQU (0X30)MRSRB7_V AL EQU (0X30);配置bank的参数InitBank;Set memory control registersLDR R0,=L_BANK_CONFLDR R1,=BWSCON ;BWSCON AddressADD R2, R0, #52 ;End address of SMRDATALDR R3, [R0], #4STR R3, [R1], #4CMP R2, R0BNE %B0BX LR;声明一个文字池的开始,文字池一般放置在一个代码段的最后面,或者一个文件的END前面。

基于S3C2440的U-boot启动分析

基于S3C2440的U-boot启动分析
o t 动 分析 3 24 昀 b o启
中北 大学信 息与 通信 工程 学院 洪永 学 余 红英
[ 要] 摘 在嵌入 式的世界 中 , 通常没有像 B O 那样 的固件程序 , IS 因此整 个嵌入式 系统的加栽就完全 由B o od r o t ae 来完成, l 所以B o— o t la e是嵌入 式京 统中不可缺 少的重要部分 , 文结合 u b o一 ..部分源代码详细地分析 U— o 启动过程 , o dr 本 — o t 116 Bo t 主要是对 U— o 启 Bo t 动的关键 环节进行较 为详 细的解析 , 其对 U— o t 目 B o在 标板 ¥ C 40 3 2 4 移植分析具有一定的借鉴价值。 [ 关键 词] o t ae U— 0 启动 移植 B ol dr o Bo t 给 内 核 , 代 码 如 下 : g 一 b 一 b a h n m e : d>d >i r — u br _c U B o, — ot全称 为 U iesl ot o dr 即通 用的 B ood r是遵循 MACH TYP S D 2 1 ; 始 化 串 口 函数 只要 是 sr l n , 置 了 nvra B o a e, L ot ae , l E M K4 0初 e a it i— i设 GL P 条款 的开发代码 , 的名字“ 它 通用” 具有两层含义 : 以引导 多种操 U T控制器 , c uam9 0 sc4 Osf .中实现 。 可 AR 在 p / 2f 32 x/e a c r i 1 作 系统 、 支持 多种架构 的 C U P 。它支持如 下操作 系统 :iu 、 e S 、 Lnx N t D B () 2 检测系统 内存映射( e o a ) m m r m p y V Wo s Q X R T S A T S , 持 如 下 C U架 构 : o e C x r 、 N 、 E M 、 RO 等 支 k P Pw r 、 P 对于特定 的开发板 , 内存 的分 布是明确 的, 以可 以直接设 置 , 其 所 o d m k 4 0 m k4 0 rs s e r it m n 函数指定 了开发板 的内存起 M P 、 8 、 R N I 等 。U B o支 持大 多数 C U, 以烧 写 E T 、 b a / d 2 1/ d2 1 .中的da _ i IS x6 A M、 O S — ot P 可 X 2 Y E S 文件系统 映像 , E F2 支持 串口下 载 , 网络下载 , 提供大量 的命令 , 始地址 , 并 代码如下 : it rm i t o ) n a d 相 对于 M z 司的V v, 的使用更复杂 , i公 i i 它 i 但是可 以用来更方便地 调试 n ( i iv d 、 程序 。本文针对 A M架构 中的 s d 2 1 开发板的 U B o启动进行详 R m k4 0 — ot { g > d >b da 0.at HY _ D AM一 ; d- b 一 i rm[]t =P S S R 细分析。 sr 1 g > d >b d m[ .z d一 b - i r O s e=P S S A 2U— o t 动 过 程 分 析 . B o启 a ]i HY _ DR M— — IE lSZ ; 通常 , ot ae 是 严重 地依 赖于硬 件 而实 现的 , 多数 的 B o B l dr o 大 ot — rtr : e u n0 l dr o e启动 过程 分为两个阶段 , a 本文 以开发板 s d 2 1 为例 , U B o m k 40 其 — ot ) 属于两阶段 的B o od r 一阶段 的文件为 cu r 9 0 s r 和 ba / ot ae , l 第 p / m 2 tt . o r a /aS d () 3 获取 U B o操作命 令 — ot s mdk 41  ̄o e e. 2 0 wlv 1 S。 启 动 U B o 后 可 以在 串 口看 到 一 些 打 印 信 号 , 后 会 出 现 — ot 随 2 — ot 一阶段分析 .U B o 1 第 ”MD 4 0#” S K20 字符等待用户输人命令来启动 内核 , 因此 U B o启动内 — ot () 1硬件设备初始化 核 的主要 核心是通 过 U B o命令来 实现 , — ot 在函数 s r a bo 中进行 t _r ot a m t 依次完 成如下设 置 : C U的工作模式设 置为管理 模式 (v ) 关 相 应 的 f s_ i 0 nn — i 等 函数 后 , 入 m i l p0 过 s 将 P sc , l h i t 和 ad i t a n n0 进 a _ o 通 no = 闭 看 门狗 ( T HD G) 设置 P L , L ,C K的 比例 , 闭 MMU gt v Iot d) WA C O , C KHC KF L 关 , en ( om ” e t c 获取U B o命令 , b — ot 然后通过 rn cm a d s0 u_ o m n ( ) , 执行命 cc A HE等 等 。 令, 最终启动内核 。U B o 中的每个命令都通过 u B O M 宏来定 — ot _O TC D 义, 格式如下 : () 2 为加载 B ood r ot ae 的第二段代码 到 R M空间 l A U BOOT C 所 谓 R M空 间 , 是 初始 化 内存芯 片 , 它能 够使 用 。通过 在 A 就 使 MDn m , xrs eetbecm n , sg””e ” (a emaag, p aal, ma d” ae , l ) r o u hp 各项参数的意义 如下 : s rS t t 中调用 l l e i t a. o e l n 函数来设置控制器 , 得外接 S R M。 w v_ i 使 D A L wl v l i t o e e n 部分函数代码 如下 : i ① nm : a e 命令 的名字 , 注意 , 它不是 一个字符 串( 不要 用双引号 括

【总结】S3C2440PLL设置详解总结

【总结】S3C2440PLL设置详解总结

S3C2440 PLL设置详解CPU上电几毫秒后,晶振输出稳定,FCLK=Fin(晶振频率),CPU开始执行指令。

但实际上,FCLK可以高于Fin,为了提高系统时钟,需要用软件来启用PLL。

这就需要设置CLKDIVN,MPLLCON,UPLLCON这3个寄存器。

CLKDIVN寄存器用于设置FCLK,HCLK,PCLK三者的比例,MPLLCON用于设置主频FCLK,UPLLCON用于设置USB时钟UCLK。

S3C2440APLL源有两个,一个是MPLL,另一个是UPLL. MPLL用于CPU用外设,UPLL只用于USB.,包括CPU的FCLK,AHB总线外设的HCLK以及APB总线外设的PCLK。

S3C2440A包含两个锁相环(PLL):MPLL提供给FCLK、HCLK和PCLK,UPLL 专用于USB模块(48MHz)。

时钟控制逻辑可以不使用PLL来减慢时钟,并且可以由软件连接或断开各外设模块的时钟,以降低功耗。

S3C2440A的主时钟源由外部时钟(EXTCLK)或者外部晶振(XTIPll)提供,输入时钟源由模式控制引脚OM3和OM2控制选择,在复位信号的上升沿参考OM3和OM2的引脚将OM[3:2]的状态在内部锁定,如图1所示图1 引导启动时的时钟源选择选择不同输入时钟源时连接方式如图2所示:图2 时钟连接参考通过在片内集成的2个锁相环:MPLL和UPLL,可对输入的Fin=12MHz的晶振频率进行倍频。

S3C2440使用了三个倍频因子MDIV、PDIV和SDIV来设置倍频,通过寄存器MPLLCON和UPLLCON可分别设置各自的倍频因子。

其中MPLLCON寄存器用于设置处理器内核时钟主频FCLK,其输入输出频率间的关系为FCLK=MPLL=(2*m*Fin)/(p*2^s)其中m=(MDIV+8), p=(PDIV+2), s=SDIV。

其中UPLLCON寄存器用于产生48MHz或96MHz,提供USB时钟(UCLK),其输入输出频率间的关系为UCLK=UPLL=(m * Fin) / (p * 2^s)其中m=(MDIV+8), p=(PDIV+2), s=SDIV。

s3c2440的一些解释

s3c2440的一些解释
str r1,[r0] ;为什么UPLL的等待时间要少一些呢?
[ PLL_ON_START
; Added for confirm clock divide. for 2440.
; Setting value Fclk:Hclk:Pclk
读出boot的基本参数
<7> misc() (没找到)
init_builtin_cmds() vivi/lib/command.c中
(注册用户的基本命令,包括boot, bon, load, help 等等)
<8> boot_or_vivi() 就在main.c中,等待用户输入,有输入进入vivi_shell,没有输入,超时后启动linux
; 这里设置的 Fclk:Hclk:Pclk = 1:3:6,因为 CLKDIV_VAL = 7
ldr r0,=CLKDIVN
ldr r1,=CLKDIV_VAL ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.
9、判断是否是从睡眠状态唤醒的,如果是,则做出相应处理(具体处理还没看)
10、初始化存储设备、包括外存,内存等(BWSCON,BANKCONn,BANKSIZE,MRSRB6,MRSRB7)
11、初始化处理器各模式的堆栈(还没看懂)
12、Setup IRQ handler(也没咋看懂,似乎是对IRQ终端进行处理)
(主要做了clear memory的工作)
<2> board_init() (没找到)
<3> mem_map_init() vivi/arch/mmu.c中

S3C2440启动代码经验总结

1、引言2、汇编基础2.1、伪操作GET 伪操作类似于C 语言里面的include,是将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。

IMPORT伪操作相当于C 语言中的extern 声明,它告诉编译器当前的符号不再本源文件中定义,而是在其他源文件中定义,在本源文件中可能引用该符号。

AERA 伪操作用于定义一个代码或者数据段。

ASSERT在汇编编译器对汇编程序的扫描中,如果ASSERT 中条件不成立,ASSERT 伪操作将报告错误信息。

2.2、汇编指令LDR伪指令将一个32 位的常数或者一个地址值读取到寄存器中。

BL跳转指令,L 决定是否保存返回地址。

MRS用于将状态寄存器的内容传送到通用寄存器中。

MSR用于将通用寄存器的内容或一个立即数传送到状态寄存器中。

LDM和STM分别为批量Load/Store内存访问指令。

FD为满递减数据栈。

3、启动代码功能模块分解启动代码主要是在主程序运行之前初始化系统硬件及软件的运行环境,它的主要功能包括以下的几个方面:* 建立中断向量表* 初始化系统堆栈* 应用程序执行环境初始化* 跳转至主函数3.1、系统堆栈初始化ARM有7种模式:* 用户模式* 快速中断模式* 中断模式* 管理模式* 中止模式* 未定义模式* 系统模式系统堆栈的初始化主要是给各个处理器模式分配堆栈空间。

堆栈是为中断或程序跳转服务的,当发生中断或程序跳转时,需要将当前处理器的状态及一些参数保持在堆栈中,当中断处理完毕以后或程序执行完后返回时,再将堆栈保存的现场数据进行恢复,以保证原来的程序正确运行。

USERMODE EQU 0x10 ;用户模式FIQMODE EQU 0x11 ;快速中断模式IRQMODE EQU 0x12 ;中断模式SVCMODE EQU 0x13 ;监管模式ABORTMODE EQU 0x17 ;异常中断模式UNDEFMODE EQU 0x1b ;未定义模式MODEMASK EQU 0x1f ;模式掩码NOINT EQU 0xc0 ;取消中断;设置工作模式的堆栈的起始地址;在option.inc 中定义了_STACK_BASEADDRESS EQU 0x33ff8000 UserStack EQU (_STACK_BASEADDRESS-0x3800) ;堆栈空间0x33ff4800 SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;堆栈空间0x33ff5800 UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;堆栈空间0x33ff5c00AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;堆栈空间0x33ff6000IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;堆栈空间0x33ff7000 FIQStack EQU (_STACK_BASEADDRESS-0x0) ;堆栈空间0x33ff8000堆栈初始化的顺序决定系统最后运行在哪种处理器模式,最后初始化哪种模式的堆栈,系统就运行在哪种模式。

s3c2440a启动过程详解

s3c2440a启动过程详解1:s3c2440是32位的,所以可以寻址4GB空间,内存(SDRAM)和端口(特殊寄存器),还有ROM都映射到同一个4G空间里。

2:开发板上一般都用SDRAM做内存flash(nor、nand)来当做ROM。

其中nand flash没有地址线,一次至少要读一页(512B).其他两个有地址线(飞凌2440开发板使用大页nandflash,每页2Kb)。

飞凌的全线2440开发板采用的是2片SDRAM(单片为32M,最大可扩展到单片为64M)。

3:nandflash不能用来运行代码,只用来存储代码,NORflash,SDRAM 可以直接运行代码。

4:s3c2440总共有8个内存banks,6个内存bank可以当作ROM或者SRAM来使用,留下的2个bank除了当作ROM 或者SRAM,还可以用SDRAM(各种内存的读写方式不一样),7个bank的起始地址是固定的。

还有一个灵活的bank的内存地址,并且bank大小也可以改变。

5:s3c2440支持两种启动模式:NAND和非NAND(这里是nor flash)。

具体采用的方式取决于s3c2440的OM0、OM1两个引脚OM[1:0]所决定的启动方式:OM[1:0]=00时,处理器从NAND Flash启动;OM[1:0]=01时,处理器从16位宽度的ROM启动;OM[1:0]=10时,处理器从32位宽度的ROM启动;OM[1:0]=11时,处理器从Test Mode启动。

当从NAND启动时,cpu会自动从NAND flash中读取前4KB的数据放置在片内SRAM里(s3c2440是soc),同时把这段片内SRAM映射到nGCS0片选的空间(即0x00000000)。

cpu是从0x00000000开始执行,也就是NAND flash里的前4KB内容。

因为NAND FLASH连地址线都没有,不能直接把NAND映射到0x00000000,只好使用片内SRAM做一个载体。

第三讲 S3C2440上Bootloader代码分析


Stage1
通常包括以下步骤(以执行的先后顺序):
硬件设备初始化。 为加载Boot Loader 的stage2 准备RAM 空间。 拷贝Boot Loader 的stage2 到RAM 空间中。 设置好堆栈。 跳转到stage2 的C 入口点。
硬件设备初始化
屏蔽所有的中断
为中断提供服务通常是 OS 设备驱动程序的责任,因此在 Boot Loader 的执行全过程中可以不必响应任何中断。中断屏蔽可以通 过写 CPU 的中断屏蔽寄存器或状态寄存器(比如 ARM 的 CPSR 寄存器)来完成。
无法通过main() 函数传递函数参数; 无法处理 main() 函数返回的情况
解决- Main()的入口
trampoline(弹簧床) : trampoline小程序 来作为 main() 函数的外部包裹(external wrapper) 用汇编语言写一段trampoline 小程序,并 将这段 trampoline 小程序来作为 stage2 可执行映象的执行入口点。 在 trampoline 汇编小程序中用 CPU 跳转 指令跳入 main() 函数中去执行; 当 main() 函数返回时,CPU 执行路径显 然再次回到我们的 trampoline 程序。
大多数Boot Loader 都分为stage1 和 stage2 两大部分。依赖于CPU 体系结构的 代码,比如设备初始化代码等,通常都放 在stage1 中,而且通常都用汇编语言来实 现,以达到短小精悍的目的。而stage2 则 通常用C语言来实现,这样可以实现给复杂 的功能,而且代码会具有更好的可读性和 可移植性。
拷贝 stage2 到 RAM 中
需要考虑:
stage2 的可执行映象在固态存储设备的存放起 始地址和终止地址; RAM 空间的起始地址。

凌阳s3c2440开发板烧写程序说明


执行 “load yaffs root x”指令,将“rootfs26_noGUI.yaffs 或 ” "rootfs26_GUI.yaffs" 入开发板: 烧 vivi>: load yaffs root x 发送文件配置: 文件名(F):
rootfs26_noGUI.yaffs
发送文件配置: 文件名(F):
超级终端工具配置: 连接端口: COM1 每秒位数: 115200 数据位: a 奇偶校验: 无 停止位: 1 数据流控制 无 注:连接端口不一定是 COM1,也可能是其他的COM口。
3.开发板文件烧写 : 单击2440开发板启动键 ,同时快速按键盘的空格键 。超级终端会进入如下界面 :
VIVI version 0.1.4 (root@SunplusAPP) (gcc version 2.95.3 20010315 (release)) #0. 1.4 2010骞?01鏈?19鏃?鏄熸湡浜 ?10:46:52 CST MMU table base address = 0x33DFC000 Succeed memory mapping. NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) Could not found stored vivi parameters. Use default vivi parameters. Press Return to start the LINUX now, any other key for vivi type "help" for help.
嵌入式开发板烧写程序说明
1.双击LSJF24X0图标,进入并口烧写对话框 :
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档