u-boot移植(三)---修改前工作:代码流程分析2

发布时间:2023-07-03  

一、vectors.S

1.1 代码地址

  vectors.S (archarmlib) 

1.2 流程跳转

    

  跳转符号 B 为 start.S 中的 reset 执行代码,暂且先不看,先看看 vector.S 中的执行。

1.3 代码分析

  ldr{条件}   目的寄存器     

 1 _start:

 2 

 3 #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG

 4     .word    CONFIG_SYS_DV_NOR_BOOT_CFG

 5 #endif

 6     /* LDR{条件}   目的寄存器      */

 7     /* 当异常发生的时候,由硬件机制处理器自动的跳到一个固定地址去执行相关异常处理程序,而这个固定地址就是所谓的异常向量。 */

 8     b    reset                        /* 跳转到reset执行 0x00000000 复位异常*/

 9     ldr    pc, _undefined_instruction    /* 0x00000004 未定义指令异常 */

10     ldr    pc, _software_interrupt        /* 0x00000008 软中断异常 */

11     ldr    pc, _prefetch_abort            /* 0x0000000c 预取异常 */

12     ldr    pc, _data_abort                /* 0x00000010 数据异常 */

13     ldr    pc, _not_used                /* 0x00000014 未使用异常,多余的指令 */

14     ldr    pc, _irq                    /* 0x00000018 外部中断异常 */

15     ldr    pc, _fiq                    /* 0x0000001c 快速中断异常 */


  这里的代码全部都是异常向量表的定义,第一段代码中,执行 b   reset ,跳转到reset执行。

  reset 我们的 start.S 代码中。

二、start.S

2.1 跳转流程

    

2.2 代码流程

  

 

2.3 代码分析 

  start.S (archarmcpuarm920t) 

2.3.1 指令介绍

  • .global symbol .global 使得链接程序(ld)能够识别 symbol,声明symbol是全局可见的

  • ARM模式切换指令:

    • mrs(Move to Register from State register):指令可以对状态寄存器CPSR和SPSR进行读操作。通过读CPSR可以获得当前处理器的工作状态。读SPSR寄存器可以获得进入异常前的处理器状态(因为只有异常模式下有SPSR寄存器)。

    • msr:MSR指令可以对状态寄存器CPSR和SPSR进行写操作。

  • bic:(位清除)指令对 Rn 中的值 和 Operand2 值的反码按位进行逻辑“与”运算。BIC 是 逻辑”与非” 指令, 实现的 Bit Clear的功能。

  • orr:用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。

    • ORR{条件}{S} 目的寄存器,操作数 1,操作数 2

  • 数据传输指令:LDR,STR。LDR和STR的第一操作数是目标寄存器,第二操作数是内存地址。

    • 立即数:内存的物理地址,前面加个#

    • 寄存器:加个[],如[r1]

    • 寄存器加偏移:[r1,r2]  [r2, #4] , [r2, LSL, #4]等,把寄存器里的数当成地址  

    • LDR  内存--->寄存器

    • STR 寄存器--->内存

    • 内存的表示方式有:立即数,寄存器,或寄存器加偏移

    • mvn指令:与mov指令相似,唯一的区别是赋值的时候先按位取反 

  • 协处理器指令:MCR,MRC

    • MCR{} p15, 0, , , {,}

    • MCR2 p15, 0, , , {,}

    • 为指令执行的条件码。当忽略时指令为无条件执行。MCR2中,为Ob1111,指令为无条件执行指令。 

    • MCR:将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。指令的语法格式:

    • MRC:将协处理器的寄存器中数值传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。        

2.3.2 代码分析

2.3.2.1 u-boot.dis分析

  u-boot.dis分析

  代码跳转到reset,reset的地址为 2e8:

  

  在2e8处执行reset的代码,此段代码是对CPSR寄存器进行操作

  

  CPSR寄存器主要是用来CPU切换用户模式和系统模式,寄存器的定义如下:

  

  • 中断禁止位I、F:置1时,禁止IRQ中断和FIQ中断。

  • T标志位:该位反映处理器的运行状态。当该位为1时,程序运行于THUMB状态,否则运行于ARM状态。该信号反映在外部引脚TBIT上。在程序中不得修改CPSR中的TBIT位,否则处理器工作状态不能确定。


image.png

 

  CPSR寄存器的M4~M0位为模式位,所以将CPSR的值放入R0寄存器中后,就是将R0的值的低5位进行清零,然后与 1101 0011进行相互,则进入管理模式。

  关闭看门狗:

  

  看门狗寄存器

  

 

  屏蔽中断,代码中并没有234行和236行的执行,这里是跳转到 地址位 35c 去执行打印,暂且先不管这两行,只要知道都是中断屏蔽的代码,留待后续分析:

  

  

  

  中断屏蔽寄存器:

  

 

  设置启动参数:时钟

   

   时钟分频寄存器

  

 

  紧接着跳转到地址 328 去执行 cpu_init_crit,执行DRAM的初始化:

  

  

  这里涉及到CP15寄存器,CP15是用于系统存储管理的协处理器,操作指令为: 

  MCR{cond}     coproc,opcode1,Rd,CRn,CRm,opcode2  MRC {cond}    coproc,opcode1,Rd,CRn,CRm,opcode2 

  • coproc         指令操作的协处理器名.标准名为pn,n,为0~15 

  • opcode1      协处理器的特定操作码. 对于CP15寄存器来说,opcode1永远为0,不为0时,操作结果不可预知

  • CRd             作为源寄存器的ARM寄存器,其值被传送到协处理器寄存器中。CRd不能为PC,当其为PC时,指令操作结果不可预知。

  • CRn             存放第1个操作数的协处理器寄存器。作为目标寄存器的协处理器寄存器,其编号可能为C0,C1....C15。

  • CRm            存放第2个操作数的协处理器寄存器. (用来区分同一个编号的不同物理寄存器,当不需要提供附加信息时,指定为C0)

  • opcode2       提供附加信息,可选的协处理器特定操作码. (用来区分同一个编号的不同物理寄存器,当不需要提供附加信息时,指定为0)

   cpu_init_crit 涉及到的协处理器的寄存器有C0,C1,C7,C8:

  【1】C0寄存器

  

  

  

  

  

  

  【2】C1寄存器

  

  

  

C1中的控制位 含义
M(bit[0])

0 :禁止 MMU 或者 PU 

1 :使能 MMU 或者 PU

如果系统中没有MMU及PU,读取时该位返回0,写入时忽略该位

A(bit[1])

0 :禁止地址对齐检查

1 :使能地址对齐检查

C(bit[2])

当数据cache和指令cache分开时,本控制位禁止/使能数据cache。当数据cache和指令cache统一时,该控制位禁止/使能整个cache。

0 :禁止数据 / 整个 cache 

1 :使能数据 / 整个 cache

如果系统中不含cache,读取时该位返回0.写入时忽略

当系统中不能禁止cache 时,读取时返回1.写入时忽略

W(bit[3])

0 :禁止写缓冲

1 :使能写缓冲

如果系统中不含写缓冲时,读取时该位返回0.写入时忽略

当系统中不能禁止写缓冲时,读取时返回1.写入时忽略

P(bit[4])

对于向前兼容26位地址的ARM处理器,本控制位控制PROG32控制信号

0 :异常中断处理程序进入 32 位地址模式

1 :异常中断处理程序进入26 位地址模式

如果本系统中不支持向前兼容26位地址,读取该位时返回1,写入时忽略

D(bit[5]

对于向前兼容26位地址的ARM处理器,本控制位控制DATA32控制信号

0 :禁止 26 位地址异常检查

1 :使能 26 位地址异常检查

如果本系统中不支持向前兼容26位地址,读取该位时返回1,写入时忽略

L(bit[6]

对于ARMv3及以前的版本,本控制位可以控制处理器的中止模型

0 :选择早期中止模型

1 :选择后期中止模型

B(bit[7])

对于存储系统同时支持big-endian和little-endian的ARM系统,本控制位配置系统的存储模式

0 : little endian  

1 : big endian

对于只支持little-endian的系统,读取时该位返回0,写入时忽略

对于只支持big-endian的系统,读取时该位返回1,写入时忽略

S(bit[8]) 在基于 MMU 的存储系统中,本位用作系统保护
R(bit[9]) 在基于 MMU 的存储系统中,本位用作 ROM 保护
F(bit[10]) 由生产商定义
Z(bit[11])

对于支持跳转预测的ARM系统,本控制位禁止/使能跳转预测功能

0 :禁止跳转预测功能 

1 :使能跳转预测功能

对于不支持跳转预测的ARM系统,读取该位时返回0,写入时忽略

I(bit[12])

当数据cache和指令cache是分开的,本控制位禁止/使能指令cache

0 :禁止指令 cache  

1 :使能指令 cache

如果系统中使用统一的指令cache和数据cache或者系统中不含cache,读取该位时返回0,写入时忽略。当系统中的指令cache不能禁止时,读取时该位返回1,写入时忽略

V(bit[13]

对于支持高端异常向量表的系统,本控制位控制向量表的位置

0 :选择低端异常中断向量 0x0~0x1c 

1 :选择高端异常中断向量0xffff0000~ 0xffff001c

对于不支持高端异常向量表的系统,读取时该位返回0,写入时忽略

PR(bit[14])

如果系统中的cache的淘汰算法可以选择的话,本控制位选择淘汰算法

0 :常规的 cache 淘汰算法,如随机淘汰 

1 :预测性淘汰算法,如round-robin 淘汰算法

如果系统中cache的淘汰算法不可选择,写入该位时忽略。读取该位时,根据其淘汰算法是否可以比较简单地预测最坏情况返回0或者1

L4(bit[15])

对于ARM版本5及以上的版本,本控制位可以提供兼容以前的ARM版本的功能

0 :保持 ARMv5 以上版本的正常功能

1 :将 ARMv5 以上版本与以前版本处理器 兼容,不根据跳转地址的 bit[0] 进行 ARM 指令和 Thumb 状态切换: bit[0] 等于 0 表示 ARM 指令,等于 1 表示 Thumb 指令

Bits[31:16]) 这些位保留将来使用,应为UNP/SBZP

 

 

 

 

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  【3】C7寄存器

  

  

  【4】C8寄存器

  

  

  执行完cache和MMU的设置后,则跳转到lowlevel_init(lowlevel_init.S (archarmcpuarm920tep93xx) )中执行。

   

  执行完内存初始化后,则执行_main()函数。

2.3.2.2 代码执行

  start.S

  1     .globl    reset

  2 

  3 reset:

  4     /*

  5      * set the cpu to SVC32 mode

  6      * 设置 CPU 为管理员模式

  7      */

  8     mrs    r0, cpsr            /* 将CPSR状态寄存器读取保存在r0中 */

  9     bic    r0, r0, #0x1f        /* 清除r0中数据的低5位,然后存放在r0中 */

 10     orr    r0, r0, #0xd3        /* r0的数据与 1101 0011 相或,然后存放在r0中 */

 11     msr    cpsr, r0            /* 将r0中的数据存放在cpsr寄存器中 */

 12 

 13 

 14     /* 定义控制寄存器地址 */

 15 #  define pWTCON    0x53000000    /* 看门狗地寄存器地址 */

 16 #  define INTMSK    0x4A000008    /* Interrupt-Controller base addresses */

 17 #  define INTSUBMSK    0x4A00001C    /* 中断掩码 */

 18 #  define CLKDIVN    0x4C000014    /* clock divisor register */

 19 

 20     /* 关闭看门狗 */

 21     ldr    r0, =pWTCON                /* r0中存放看门狗寄存器地址 */

 22     mov    r1, #0x0                /* 将立即数0存放到r1中,r1 = 0x0 */

 23     str    r1, [r0]                /* 将r1中的值存放到以r0中的值为地址的存储单元中,即 pwTCON = 0 */

 24 

 25     /*

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

 27      * 屏蔽中断

 28      */

 29     mov    r1, #0xffffffff            /* 将立即数 0xffffffff 存放到r1中*/

 30     ldr    r0, =INTMSK             /* r0中存放中断控制寄存器基地址 */

 31     str    r1, [r0]                /* 将r1中的值存放到以r0中的值为地址的存储单元中,即 INTMSK = 0xffffffff */

 32 

 33     /* FCLK:HCLK:PCLK = 1:2:4 */

 34     /* default FCLK is 120 MHz ! */

 35     /* 设置启动参数:时钟 */

 36     ldr    r0, =CLKDIVN            /* r0中存放时钟寄存器地址 */

 37     mov    r1, #3                    /* 将立即数0存放到r1中,r1 = 0x3 */

 38     str    r1, [r0]                /* 将r1中的值存放到以r0中的值为地址的存储单元中,即 CLKDIVN = 0 */

 39 

 40     /*

 41      * we do sys-critical inits only at reboot,

 42      * not when booting from ram!

 43      */

 44 #ifndef CONFIG_SKIP_LOWLEVEL_INIT

 45     /*  执行CPU初始化,完成DRAM初始化操作,跳转到 cpu_init_crit 执行 */

 46     bl    cpu_init_crit

 47 #endif

 48 

 49     bl    _main

 50 

 51 

 52 /*------------------------------------------------------------------------------*/

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    区域中第一个位的指针,其中该区域内的位将被置位。对于跨区域间接寄存器寻址,必须以双字格式指定该指针。 N Input INT I、Q、M、D、L、P 或常数 要置位的位数 示例 以下示例说明了该指令......
    种是硬件复位方式。 在空闲模式下,若任何一个允许的中断请求被响应时,IDL位被片内硬件自动清0,从而退出空闲模式。当执行完中断服务程序返回时,将从设置空闲模式指令的下一条指令(断点处)开始......
    可避免的”,这要归功于它可以创造的开放商业模式和开放芯片设计浪潮,而且它正在很难反驳这一点。虽然该节目主要是关于 RISC-V 的优势,但我想补充一点,RISC-V 似乎不可避免的最大原因是当前的 CPU......
    端设有LED照明灯以及相应的控制按键,4个AC输出插座和AC模块开关键。盖板内部设有太阳能/直流输入接口、AC充电切换键、轻音模式指示灯、快充模式指示灯、过流保护开关、AC充电接口。   国民......
    Note 5创下了京东史上新品首发日销量最高纪录,同时还创造了品牌日最快21秒销量破万台。此外,魅族手机夺得销量、销售额单日双料冠军。 据悉,12月10日,起魅蓝Note5将于魅族专卖店,苏宁......
    译的时候生成的,所以如果要修改u-boot.lds 需要找到正确的地方。   u-boot.lds 分析:  1 #include   2 /* 指定输出可执行文件是elf格式,32位ARM指令,小端模式......
    指示灯、燃油不足警告灯、动力蓄电池故障指示灯 运动模式指示灯、车距警告灯、遥控......
    意法半导体推出STeID Java Card 可信电子身份证和电子政务解决方案;安全智能卡操作系统和小程序安全存放多个电子身份证件意法半导体推出了 STeID Java Card™ 智能卡平台,以满......
    入FX3U-485-BD通信模块。 1)基本格式 其中m(发生数据的个数)和n(接收数据的个数)需要根据外部设备的报文格式指令,不能随便设置。 2)示例 X0: RS指令触发条件,当X0位ON时......
    一个库,用于处理 opcodes——处理器指令的 '可读文本' 版本;用于编制 objdump 这样的工具。 nlmconv 将可重定位的目标文件转换成 NetWare 可加载模块(NetWare......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>