u-boot之ARM920T的start.S分析

发布者:RadiantEyes最新更新时间:2024-08-29 来源: cnblogs关键字:u-boot  ARM920T  start 手机看文章 扫描二维码
随时随地手机看文章

cpu/arm920t/start.S程序步骤大致有以下几个


1、设置中断向量表


2、设置CPU模式为SVC32 mode并且关闭IRQ与FIQ中断


3、关闭看门狗


4、屏蔽所有中断


5、判断程序是否在RAM中运行如果不是的话则先关闭MMU再则需要初始化RAM。


6、设置堆栈准备在C函数中运行了


7、 跳转到C函数clock_init初始化系统时钟


8、跳转到C函数CopyCode2Ram将代码拷贝到RAM中


9、清零BSS段


10、跳转到_start_armboot运行,此时代码已经在RAM中运行了


11、IRQ中断与FIQ中断发生后的上下文处理


1、cpu/arm920t/start.S文件中存放着S3C2440芯片(内核是ARM920T)的异常向量表(即异常入口地址),从S3C2440芯片手册得知每当板子重新上电即芯片复位后pc的值总是指向0,所以在链接时存放在最前面的文件肯定是cpu/arm920t/start.S。


.globl _start

_start:    b       reset                                   //复位异常地址

    ldr    pc, _undefined_instruction             //未定义异常地址

    ldr    pc, _software_interrupt                 //软件中断异常地址

    ldr    pc, _prefetch_abort                      //预取指异常地址

    ldr    pc, _data_abort                           //数据异常地址

    ldr    pc, _not_used                             //保留

    ldr    pc, _irq                                      //IRQ中断异常地址

    ldr    pc, _fiq                         //FIQ快速中断异常地址


_undefined_instruction:    .word undefined_instruction//0x20地址处存放着未定义异常跳转地址

_software_interrupt:    .word software_interrupt

_prefetch_abort:    .word prefetch_abort

_data_abort:        .word data_abort

_not_used:        .word not_used

_irq:            .word irq

_fiq:            .word fiq


    .balignl 16,0xdeadbeef                               //0x3c地址存放一个固定的标志表明前面的数据为中断向量表占用


2、当复位异常出现后,程序执行b reset后设置CPU模式为SVC32 mode并且关闭IRQ与FIQ中断,b指令为位置无关码,它的寻址方式是先找到reset程序段所在地址然后计算出当前程序地址与reset段地址的偏移然后根据偏移值跳转,这么做的目的是因为:假设开发板通过nand启动的,那么一上电后硬件自动将nand内的前4K程序拷贝到s3c2440内部的ram中运行程序,这段程序的地址与链接地址不一致,当程序运行地址与链接地址不一致时只能使用位置无关码进行跳转


reset:

    /*

     * set the cpu to SVC32 mode //设置cpsr寄存器使CPU进入系统模式,并且关闭FIQ与IRQ

     */

    mrs    r0,cpsr

    bic    r0,r0,#0x1f

    orr    r0,r0,#0xd3

    msr    cpsr,r0



3、关闭看门狗


#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

    ldr     r0, =pWTCON//pWTCON为看门狗寄存器地址,全部清0即关闭看门狗

    mov     r1, #0x0

    str     r1, [r0]//关闭看门狗

 


4、屏蔽所有中断,S3C2440的中断控制器可以控制多个中断源,可以设置中断优先级。通过选出优先级最高的中断源送到ARM920T的IRQ或FIQ异常,最后通过IRQ或FIQ异常响应相应的中断源


    /*

     * mask all IRQs by setting all bits in the INTMR - default

     */

    mov    r1, #0xffffffff

    ldr    r0, =INTMSK               //INTMSK为中断控制寄存器

    str    r1, [r0]                      //屏蔽所有without sub中断源

# if defined(CONFIG_S3C2410)

    ldr    r1, =0x3ff

    ldr    r0, =INTSUBMSK        //INTSUBMSK为中断控制寄存器

    str    r1, [r0]                     //屏蔽所有with sub中断源 

# endif


5、判断程序是否在RAM中运行如果不是的话则先关闭MMU再则需要初始化RAM。下面代码注释引自博客http://www.cnblogs.com/lifexy/p/7309791.html


#ifndef CONFIG_SKIP_LOWLEVEL_INIT   //这个在100ask24x0里未定义

    adr    r0, _start        /* r0 <- current position of code   */

    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */

    cmp     r0, r1                  /* don't reloc during debug         */

    blne    cpu_init_crit            //未在ram中运行,所以要初始化ram


cpu_init_crit:


mov    r0, #0

mcr    p15, 0, r0, c7, c7, 0    //关闭ICaches(指令缓存,关闭是为了降低MMU查表带来的开销)和DCaches(数据缓存,DCaches使用的是虚拟地址,开启MMU之前必须关闭)

mcr    p15, 0, r0, c8, c7, 0    //使无效整个数据TLB和指令TLB(TLB就是负责将虚拟内存地址翻译成实际的物理内存地址)


mrc    p15, 0, r0, c1, c0, 0

bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS) //bit8:系统不保护,bit9:ROM不保护,bit13:设置中断向量表的位置为0x0~0x1c,即异常模式基地址为0X0

bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM) //bit0~2:禁止MMU,禁止地址对齐检查,禁止数据Cache.bit7:设为小端模式

orr    r0, r0, #0x00000002    @ set bit 2 (A) Align //bit2:开启数据Cache

orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache //bit12:开启指令Cache

mcr    p15, 0, r0, c1, c0, 0

/*

mcr/mrc:

Caches:是一种高速缓存存储器,用于保存CPU频繁使用的数据。在使用Cache技术的处理器上,当一条指令要访问内存的数据时,

首先查询cache缓存中是否有数据以及数据是否过期,如果数据未过期则从cache读出数据。处理器会定期回写cache中的数据到内存。

根据程序的局部性原理,使用cache后可以大大加快处理器访问内存数据的速度。

其中DCaches和ICaches分别用来存放数据和执行这些数据的指令


TLB:就是负责将虚拟内存地址翻译成实际的物理内存地址,TLB中存放了一些页表文件,文件中记录了虚拟地址和物理地址的映射关系。

当应用程序访问一个虚拟地址的时候,会从TLB中查询出对应的物理地址,然后访问物理地址。TLB通常是一个分层结构,

使用与Cache类似的原理。处理器使用一定的算法把最常用的页表放在最先访问的层次。

这里禁用MMU,是方便后面直接使用物理地址来设置控制寄存器

*/

mov    ip, lr //临时保存当前子程序返回地址,因为接下来执行bl会覆盖当前返回地址.

bl    lowlevel_init //跳转到lowlevel_init(位于u-boot-1.1.6/board/100ask24x0/lowlevel_init.S)

mov    lr, ip //恢复当前返回地址

mov    pc, lr //退出


.globl lowlevel_init

lowlevel_init://配置存储控制器  by andy

    /* memory control configuration */

    /* make r0 relative the current location so that it */

    /* reads SMRDATA out of FLASH rather than memory ! */

    ldr     r0, =SMRDATA

    ldr    r1, _TEXT_BASE

    sub    r0, r0, r1 //求出SMRDATA实际位于的地址,nand启动的话起始是位于0地址的,而不是链接地址

    ldr    r1, =BWSCON    /* Bus Width Status Controller */

    add     r2, r0, #13*4

0:

    ldr     r3, [r0], #4

    str     r3, [r1], #4

    cmp     r2, r0

    bne     0b


    /* everything is fine now */

    mov    pc, lr


    .ltorg

/* the literal pools origin */


SMRDATA:

    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) 

    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))

    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))

    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))

    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))

    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))

    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))

    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))

    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))

    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

    .word 0xb1

    .word 0x30

    .word 0x30


6、设置堆栈准备在C函数中运行了。在SDRAM中,代码段位于0x3f80000以上,sp=_TEXT_BASE-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-CONFIG_STACKSIZE_IRQ-CONFIG_STACKSIZE_FIQ-12


    /* Set up the stack       */ //设置堆栈需要放到前面,因为clock_init是C函数

stack_setup:

    ldr    r0, _TEXT_BASE        /* upper 128 KiB: relocated uboot   *///_TEXT_BASE之前为代码段

    sub    r0, r0, #CFG_MALLOC_LEN    /* malloc area                      *///减去堆区

    sub    r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        *///减去全局变量区

#endif


#ifdef CONFIG_USE_IRQ

    sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)//减去IRQ与FIQ占用的栈区

#endif

    sub    sp, r0, #12        /* leave 3 words for abort-stack    *///再预留12字节sp为堆栈寄存器,堆栈为向下增长

7、跳转到C函数clock_init初始化系统时钟bl   clock_init,clock_init具体代码如下:代码注释引自博客http://www.cnblogs.com/lifexy/p/7309791.html


void clock_init(void)

{

//时钟的寄存器地址只能在函数内部定义,因为代码还不在链接地址处运行

S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000; //定义一个S3C24X0_CLOCK_POWER型结构体指针,clk_power->LOCKTIME=0x4C000000


if (isS3C2410) //isS3C2410为0,执行else

{... ...}

else

{

/* FCLK:HCLK:PCLK = 1:4:8 */

clk_power->CLKDIVN = S3C2440_CLKDIV; //S3C2440_CLKDIV=0X05


/* change to asynchronous bus mod *///C语言内嵌汇编

__asm__( 'mrc p15, 0, r1, c1, c0, 0n' /* read ctrl register */ 

'orr r1, r1, #0xc0000000n' //使其从快总线模式改变为异步总线模式,在2440手册上看到

'mcr p15, 0, r1, c1, c0, 0n' /* write ctrl register */ 

:::'r1' //

);


/* to reduce PLL lock time, adjust the LOCKTIME register */

clk_power->LOCKTIME = 0xFFFFFFFF; //PLL 锁定时间计数寄存器


/* configure UPLL */

clk_power->UPLLCON = S3C2440_UPLL_48MHZ; //UCLK=48Mhz


/* some delay between MPLL and UPLL */

[1] [2]
关键字:u-boot  ARM920T  start 引用地址:u-boot之ARM920T的start.S分析

上一篇:u-boot之make _config执行过程分析
下一篇:s3c2440的IIC控制

推荐阅读最新更新时间:2024-11-24 18:00

如何利用AT89S51单片机实现家庭语音报警系统设计
引 言 现代化居住格局使家庭生活的安全问题显得尤为重要。当前,安全的防范及报警系统是确保住宅、住户安全的重要保障。防盗的最好方法就是在不法分子有入侵企图时就发出语音警告,增加其心理压力,使其主动离开。本系统就是基于这种思想,采用了Atmel公司的AT89S51单片机作为控制核心,以美国ISD公司的ISD1420作为语音芯片的一种新型家庭语音报警系统。 系统工作原理 本系统的工作原理框图如图1所示。不法分子在所防范区域内移动时会引起红外辐射变化。当其所辐射的红外线通过菲涅尔透镜被聚焦在热释电红外传感器PIS-209S的探测元上时,热释电红外传感器将输出电压信号,然后经信号放大电路放大后送入信号采集与处理电路,经处理后向单片机输出
[单片机]
如何利用AT89<font color='red'>S</font>51单片机实现家庭语音报警系统设计
S3C2440A智能小车可移动视频监控系统
  本文介绍的智能小车可移动视频监控系统,以“飞思卡尔杯”智能小车竞赛提供的车模装置为基础,利用ARM芯片S3C2440A控制图像采集、网络传输、速度采集干扰小的模块,利用FPGA芯片控制电机驱动、舵机控制、电量采集干扰大的模块,当上位机通过Internet访问智能小车服务器时,在监控界面上点击按钮来控制小车的运行、图像拍摄、速度采集。    1 系统总体设计   该系统采用三星公司的ARM芯片S3C2440A作为主控制芯片及Altera公司的FPGA芯片EP2C5T144C8作为辅助控制芯片,ARM上装有Windows CE5.0操作系统。S3C2440A内置丰富的外设资源包括中断控制器、GPIO、I2C、相机接口等接口电路
[单片机]
vivo Y55s通过认证 配置类似将推出的iQOO Z5X
近日,三款型号为V2009A、V2115A和V2156A的新vivo手机获得了工信部的认证。其中,工信部列出了V2156A智能手机的主要规格和图片。 早在8月份,这款V2156A手机就在IMEI数据库中被发现,名字是vivo Y76S。然而,微博用户@WHYLAB爆料声称,这款智能手机将在市场上发布,名字为vivo Y55s。 V2156A手机尺寸为163.85 x 75 x 7.79 mm,重175克。它拥有6.58英寸的TFT显示屏,提供1080x2408像素的Full HD+分辨率。由4005mAh额定电池供电。 V2156A的背板拥有5000万像素+200万像素的双摄像头系统。它有一个800万像素的前置摄像头。
[手机便携]
ARM9_S3C2440学习(七)SDRAM学习总结
1.SDRAM的burst mode SDRAM是一种命令型动作的设备,就算读写资料只有一个也要先下命令才可以用,为了增加工作效率,就产生了一种传送一个命令,写多个数据的模式,这就是burst mode。 burst mode是一种利用内部列地址发生器来工作的高速读写模式,只要设置最开始的列地址,后面的地址就可以通过内部的列地址发生器来自动生成。 2.为什么要做precharge动作? 关闭正在作用的SDRAM bank,算是一种结束命令,后面可以下新的命令。我想这是和SDRAM内部管理有关。(这是从网上查到的,感觉不够详细,也不太理解) 3.自动刷新功能? 动态存储器(Dynamic RAM)都存在刷新问题。这里主要
[单片机]
基于S3C2440A芯片实现RFID读写器系统的设计
随着现代信息技术和超大规模集成电路的发展,RFID技术在服务领域、货物销售与后勤分配、商业部门、生产企业和材料流通领域得到了越来越广泛的应用。射频识别技术的基本原理是利用射频信号和空间耦合(电感耦合或电磁耦合)或雷达反射的传输特性,实现对被识别物体的自动识别。 RFID系统不局限于视线,识别距离远。射频识别卡具有可读写能力,可携带大量数据,可工作在潮湿、干燥等恶劣环境下,同时具有难以伪造和智能性较高等优点。与此同时,不同的射频标签编码规则、不同的空中接口协议、大量而复杂的RFID数据如何处理等问题严重阻碍了RFID技术发挥其巨大作用。基于这种现状,本文结合防碰撞算法提出了嵌入式平台下的RFID读写器设计方案。 1 、RFI
[单片机]
基于<font color='red'>S</font>3C2440A芯片实现RFID读写器系统的设计
国外用户曝光三星Galaxy S10/S10+真机上手视频
集微网消息,近日有外国用户提前公开了一段较为详细的三星S10高清上手体验视频,从视频中可以看到,三星S10拥有一块6.1英寸曲面显示屏,一颗1000万像素自拍镜头,屏内打孔设计;S10+为6.4寸,前置双摄,采用1000万+800万像素的摄像头组合。 另外,S10的背部采用了水平三摄像头的设计,包括一颗可拍摄超广角照片的广角镜头,一颗支持两倍光学变焦的长焦镜头。
[手机便携]
国外用户曝光三星Galaxy <font color='red'>S</font>10/<font color='red'>S</font>10+真机上手视频
stm8s开发(七) SPI的使用:SPI主机通信!
前几篇介绍过UART串口,地址: http://blog.csdn.net/devintt/article/details/52512457 这次讲解一下另一个常用的串口:SPI通信 科普SPI:是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,分别是:SCK(时钟)、MOSI(主机发送数据)、MISO(主机接收数据)、NSS(片选),其中NSS的片选信号,大部分情况下我们使用的是软件NSS,即为使用一个GPIO进行软件控制片选。值得注意的是,其中SPI有4中模式:分别是空闲时SCLK的电平高\低、MISO采样时第1\2个变化沿。 stm8s的SPI结构如下图, 如果用形象的比喻的话:SCK像一个发条
[单片机]
stm8<font color='red'>s</font>开发(七) SPI的使用:SPI主机通信!
把摄像头藏起来,三星 Galaxy S10 曝光
在今年的旗舰手机发布已经进入尾声之际,很多“一年双旗舰”手机厂商年初发布的旗舰产品消息已经开始纷纷涌现。近日,三星 Galaxy S10 就被曝出一张疑似渲染图。 据悉此前的消息称,三星 Galaxy S10 将会有三个版本,其中标准版的代号为“Beyond”。而从那张疑似渲染图中可以看到,三星 Galaxy S10 配备的是圆角曲面屏,机身尺寸和前代大致相投,上下边框比起前代进一步收窄,所以屏占比也会较前代更高。 而为了尽可能地提高屏占比,三星 Galaxy S10 更是将前置摄像头设计在屏幕底下,这对于如今手机厂商想尽办法提高屏占比的趋势来说,绝对是一个创新性设计。 此外,还有
[手机便携]
把摄像头藏起来,三星 Galaxy <font color='red'>S</font>10 曝光
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved