初始化启动过程分析_第1页
初始化启动过程分析_第2页
初始化启动过程分析_第3页
初始化启动过程分析_第4页
初始化启动过程分析_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、今天我们讨论一下PXA255芯片的bootloader的初始化过程,也就是start_xscale.S的汇编文件中包含的内容。E1开发板的硬件配置是这样的,400M Turbo模式运行的PXA255处理器,32M Flash和64M SDRAM。start_xscale.S包含的主要内容是系统上电后的初始化过程,依次为:屏蔽硬件中断、初始化GPIO引脚、初始化Flash和SDRAM、拷贝bootloader代码到SDRAM中、拷贝内核代码到SDRAM中、最后跳转到bootloader的main程序中去执行。关于PXA255芯片的详细信息请参阅PXA255 Developers Manual。&

2、#160;1 屏蔽硬件中断ldr     r12, =INTERRUPT_CONTROL_BASE        ldr     r0, =0x00000000        str     r0, r12, #ICMR        str  &#

3、160;  r0, r12, #ICLR这一部分的代码很简单,即使将中断屏蔽寄存器ICMR置0,屏蔽所有硬件中断。 2 初始化GPIO引脚gpio_init:ldr     r12, =GPIO_BASE    ldr     r0, =GAFR0L_VALUE    str     r0, r12, #GAFR0_L    ldr   

4、  r0, =GAFR0U_VALUE    str     r0, r12, #GAFR0_U     ldr     r0, =GAFR1L_VALUE    str     r0, r12, #GAFR1_L    ldr     r0, =GAFR1U_VALUE  &#

5、160; str     r0, r12, #GAFR1_U     ldr     r0, =GAFR2L_VALUE    str     r0, r12, #GAFR2_L    ldr     r0, =GAFR2U_VALUE    str     r0, r

6、12, #GAFR2_U     ldr     r0, =GPSR0_VALUE    str     r0, r12, #GPSR0    ldr     r0, =GPSR1_VALUE    str     r0, r12, #GPSR1    ldr 

7、0;   r0, =GPSR2_VALUE    str     r0, r12, #GPSR2     ldr     r0, =GPCR0_VALUE    str     r0, r12, #GPCR0    ldr     r0, =GPCR1_VALUE  &

8、#160; str     r0, r12, #GPCR1    ldr     r0, =GPCR2_VALUE    str     r0, r12, #GPCR2     ldr     r0, =GPDR0_VALUE    str     r0, r12, #

9、GPDR0    ldr     r0, =GPDR1_VALUE    str     r0, r12, #GPDR1    ldr     r0, =GPDR2_VALUE    str     r0, r12, #GPDR2 / Clear the peripheral control register

10、 bits, so that we can use gpio as configured above   ldr     r1, =PSSR   ldr     r2, =(PSSR_RDH | PSSR_PH)   str     r2, r1           mov     pc,

11、 lr 这里我们着重讨论关于GPIO的功能寄存器的设置,也就是GAFR寄存器,有几个问题要注意:1 静态存储器空间nCS0的片选信号没有与GPIO脚复用,这是因为由于芯片当复位时自动跳转到地址0运行,因此对这一块地址需要专用的片选信号。其它静态存储器空间(nCS1:5)的片选信号都与GPIO脚复用,即也可用做一般功能的GPIO,当系统有外部设备需要访问时(如FLASH、具有FIFO的专用芯片等),可以将该块地址的片选用对应GPIO引脚来代替。2 GPIO18被设置为RDY信号输入,如果芯片外接VLIO设备的话,需要用到该信号。 该段代码最后通过向PSSR寄存器的RDH和PH

12、位写1来清零该位,这时候GPIO才可以按照上面的配置进行工作。 3初始化存储器3.1 下面我们开始讨论Flash和SDRAM的初始化,在配置这二者之前,首先要做一些系统时钟方面的处理。init_sdram:mov    r10, lr     ldr     r12, =CLOCK_MANAGER_BASE     ldr     r0, =CKEN_VALUE   

13、 str     r0, r12, #CKEN    ldr     r0, =OSCC_VALUE /The 32.768k oscillator clocks the RTC and PM.    str     r0, r12, #OSCC上面的代码首先配置CKEN寄存器,屏蔽除了FFUART之外所有设备的时钟信号,FFUART之所以被使能是因为现在需要串口工作。接着代码配置OSCC寄存器,选择32.

14、768K的晶振作为RTC和Power_Manager的同步信号。 3.2#if 1    ldr r0, =CCCR_VALUE    str r0, r12, #CCCR    mov r1, #3    mcr p14, 0, r1, c6, c0, 0 /Enter Frequency Change Sequence, turbo mode is set at the same time /set O

15、S count value to 0ldr r1, =OSCR         ldr r0, =0    str r0, r1     ldr r0, =0x300      /wait for 0x300 OS countswait_for_clock:    ldr r2, r1    cmp

16、 r0, r2    bne wait_for_clock#endif代码接着配置CCCR寄存器,也就是设置我们常说的L,M,N值,分别设置为27,2,2,这样配置完毕后的各频率值为:内存频率 = 3.6864 x 27 = 100MHz运行模式频率 = 内存频率 x 2 = 200MHzTurbo模式频率 = 运行模式频率 x 2 =400MHz接下来通过设置协处理器14的寄存器6CCLKCFG,将处理器模式设置为Turob模式,然后进入频率改变时序,最后等待0x300个OS记数直到频率设置成功。 3.3/Step 1 in Int

17、el's code    ldr     r12, =MEM_CTL_BASE     ldr     r0, =MSC0_VALUE    str     r0, r12, #MSC0     ldr     r0, =MSC1_VALUE    str

18、60;    r0, r12, #MSC1    ldr     r0, r12, #MSC1     ldr     r0, =MSC2_VALUE    str     r0, r12, #MSC2    ldr     r0, r12, #MSC2  &

19、#160;  ldr     r0, =MECR_VALUE    str     r0, r12, #MECR     ldr     r0, =MCMEM0_VALUE    str     r0, r12, #MCMEM0     ldr    

20、; r0, =MCMEM1_VALUE    str     r0, r12, #MCMEM1     ldr     r0, =MCATT0_VALUE    str     r0, r12, #MCATT0     ldr     r0, =MCATT1_VALUE  

21、60; str     r0, r12, #MCATT1     ldr     r0, =MCIO0_VALUE    str     r0, r12, #MCIO0     ldr     r0, =MCIO1_VALUEstr     r0, r12, #MCIO1接下来代码配置Fl

22、ash和16位PC Card接口参数,其中的MSC0:2寄存器包含Flash的配置参数,剩下的寄存器配置16位PC Card。其中对Flash的配置设计到几个关键的参数,分别是: 通过查看CPU外接的Flash类型的具体资料,配置以上参数。 3.4 下面的代码主要配置SDRAM的参数,也是bootloader中比较复杂的地方。ldr     r0, =MDREFR_VALUEldr     r3, r12, #MDREFR    ldr  

23、60;  r1, =0xFFF    and     r0, r0, r1    / Make the DRI we read from MDREFR what MDREFR_VALUE says it is.   / We also Free KXFREE the free running bits.    bic     r3, r3, r1    bic

24、0;   r3, r3, #0x03800000    orr     r3, r3, r0         /Write it backstr     r3, r12, #MDREFR首先从MDREFR寄存器中得到当前值,在此基础上设置DRI(SDRAM刷新间隔)值,关于DRI值的计算在PXA255 Develops Manual中是这样的:(Refresh time / rows)

25、x Memory clock frequency / 32.目前公认的标准是,存储体中电容的数据有效保存期上限是64ms,也就是说每一行刷新的循环周期是64ms。这样刷新速度就是:64ms/行数量。由于行地址有13位(在MDCNFG寄存器的DRAC01:0中设置,需要与硬件一致),所以每行的的刷新时间为64ms/21364ms/8192 = 7.8125s,那么7.8125s x 100MHz / 32 = 0x018,这样就得到了系统的DRI值。然后代码将MDREFR:KxFree位清零。 ldr r0, =MDREFR_VALUE    l

26、dr r1, =0xF6000 / Mask of SDCLK's settings minus EXPIN    and r0, r0, r1    bic r3, r3, r1    orr r3, r3, r0     str r3, r12, #MDREFR    ldr r3, r12, #MDREFR由于板子上没有使用同步SRAM,因此不需要配置SXCNFG

27、寄存器。这段代码设置MDREFR寄存器的KxRUN和KxDB2位,禁用SDCLK0,SDCLK2,只使能SDCLK1,这是因为参照PXA255 Developers Manual文档说明,SDCLK0被分配给SRAM,SDCKL1和SDCLK2分别被SDRAM区域的Bank0,1和Bank2,3使用,由于我们的PXA255板子上面使用异步Flash,同时SDRAM区域只有Bank0上贴了64M,所以只需要使能SDCLK1信号。接着代码将SDCLK1的频率设置为1/2内存频率。 bic     r3, r3, #0x00400000str

28、0;    r3, r12, #MDREFR禁止自刷新模式(Self-Refresh)。这里我们讨论一下SDRAM的刷新。刷新操作分为两种:自动刷新(Auto Refresh,简称AR)与自刷新(Self Refresh,简称SR)。不论是何种刷新方式,都不需要外部提供行地址信息,因为这是一个内部的自动操作。SR则主要用于休眠模式低功耗状态下的数据保存,这方面最著名的应用就是STR(Suspend to RAM,休眠挂起于内存)。在发出AR命令时,将CKE置于无效状态,就进入了SR模式,此时不再依靠系统时钟工作,而是根据内部的时钟进行刷新操作。在SR期间除了CKE

29、之外的所有外部信号都是无效的(无需外部提供刷新指令),只有重新使CKE有效才能退出自刷新模式并进入正常操作状态。 ldr  r0, =MDREFR_VALUE    ldr  r1, =0x03809000    and  r0, r0, r1    orr  r3, r3, r0    str    r3, r12, #MDREFR  

30、  nopnop将SDCKE0禁用,将SDCKE1使能,原因与上面讨论的SDCLKx设置一样。 ldr     r0, =MDCNFG_VALUE     /disable all sdram banks    bic     r0, r0, #0x00000003    bic     r0, r0, #0x00030000  

31、0;  /program banks 0/1 for 32 bit bus width    bic     r0, r0, #0x00000004    / test with 16 bit bus width/ orr r0, r0, #0x00000004     /write MDCNFG, without enabling SDRAM banks    str   &

32、#160; r0, r12, #MDCNFG     /Step 5 in Intel's code    ldr     r0, =OSCRmov r1, #0    str r1, r0     /pause for approx 200 usecs    ldr     r4, =0x300sdram_dly:&#

33、160;   ldr     r1, r0    cmp     r4, r1bgt     sdram_dly上面的代码配置MDCNFG内容,首先将SDRAM的4个分区(Bank)屏蔽,数据宽度为32位。另外配置了外接SDRAM芯片的与CAS潜伏期有关的参数,这些参数包括:CL:在选定列地址(CAS有效)后,就已经确定了具体的存储单元,剩下的事情就是数据通过数据I/O通道(DQ)输出到内存总线上了。但是在CAS发出之后,仍要

34、经过一定的时间才能有数据输出,从CAS与读取命令发出到第一笔数据输出的这段时间,被定义为CL(CAS Latency,CAS潜伏期)。由于CL只在读取时出现,所以CL又被称为读取潜伏期(RL,Read Latency)。tRP: 在发出预充电命令之后,要经过一段时间才能允许发送RAS行有效命令打开新的工作行,这个间隔被称为tRP(Precharge command Period,预充电有效周期)。tRCD: 在发送列读写命令时必须要与行有效命令有一个间隔,这个间隔被定义为tRCD,即RAS to CAS Delay(RAS至CAS延迟),也可以理解为行选通周期。tRAS: (Active to

35、 Precharge Command,行有效至预充电命令间隔周期)。tRC: 包括行单元开启和行单元刷新在内的整个过程所需要的时间,(Row Cycle Time,SDRAM行周期时间) 。以上各参数单位为内存时钟周期数。 /turn everything off    mov     r0, #0x78    mcr     p15, 0, r0, c1, c0, 0    /Access me

36、mory that has not been enabled for CBR refresh cycles (8)Ldr    r0, =SDRAM_BASE    str     r0, r0    str     r0, r0    str     r0, r0    str    

37、r0, r0    str     r0, r0    str     r0, r0    str     r0, r0    str     r0, r0这段代码首先将通过协处理器15,将片内数据缓冲禁用,同时禁用burst模式读写数据。禁用缓冲主要是为了使下面数据的写操作可以按顺序依次执行。接着代码进行8次数据的写

38、操作,这导致8次芯片的CBR刷新,即上面提到的AR刷新。接着,用户可以自己的需要再将数据缓冲使能,这里我们没有进行该使能操作。 ldr     r0, r12, #MDCNFG     /enable bank 0 (what about bank 1?)    orr     r0, r0, #0x00000001    str     r0, r12, #MDCN

39、FG     /write MDMRS again    ldr     r0, =MDMRS_VALUEstr     r0, r12, #MDMRS接着代码使能SDRAM的Bank0,然后配置MDMRS寄存器。在SDRAM芯片内部还有一个逻辑控制单元,并且有一个模式寄存器为其提供控制参数。因此,每次开机时SDRAM都要先对这个控制逻辑核心进行初始化,也就是配置MDMRS寄存器。寄存器的信息由地址线来提供。在设置到模式寄存器之后,芯片就开始了进

40、入正常的工作状态, ldr     r0, r12, #MDREFR    ldr    r11, =0xFFEFFFFFand     r0, r0, r11str     r0, r12, #MDREFRmov     pc, r10清空APD位。 至此,完成CPU的存储器接口的配置工作。 4 bootloader从Flash到SDRAM的拷贝

41、copy_to_ram:mov r8, lr ldr    r0, =0    ldr    r1, =_ld_text_start    ldr    r2, =_ld_text_and_data_size copy_loop:ldr    r3, r0    str    r3, r1    a

42、dd    r0, r0, #4    add    r1, r1, #4    subs    r2, r2, #4    bne    copy_loop     mov     pc, r8上面的代码完成将Bootloader程序从Flash到SDRAM的拷贝工作,之所以要进行该拷贝,是因为SDRAM的运行速度要

43、远远高于Flash,因此加快了bootloader的运行速度。这里要注意的是ld_text_start和ld_text_and_data_size两个变量的含义,要理解这两个变量,我们首先要看看ld-xscale文件的内容和作用。内核可执行文件由许多链接在一起的对象文件组成。对象文件有许多节,如文本、数据、init数据、bss等等。这些对象文件都是由一个称为链接器脚本的文件链接并装入的。这个链接器脚本的功能是将输入对象文件的各节映射到输出文件中;换句话说,它将所有输入对象文件都链接到单一的可执行文件中,将该可执行文件的各节装入到指定地址处。ld-xscale就是bootloader的链接器脚本

44、,它负责链接bootloader可执行程序的各个节并将它们装入内存中特定偏移量处。好了,了解了ld-xscale文件的作用之后,我们来看看其中和上面的代码有关的内容。.text 0xA4000000 - 0x80000:          _ld_text_start = .;      *(.text)      *(.got)      *(.got.pld)      *(.rodata)      _ld_text_end = .;   。_ld_text_and_data_size = SIZEOF(.text) + SIZEOF(.data);这里代表的是bootloader可执行文件的代码段(text)的链接信息,很明显,_ld_text_and_data_size代表的是bootlo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论