当前位置: 首页 > news >正文

U-Boot ARMv8 平台异常处理机制解析

入口点:arch/arm/cpu/armv8/start.S

1. 判断是否定义了钩子,如有则执行,否则往下走。执行save_boot_params,本质就是保存一些寄存器的值。

2. 对齐修复位置无关码的偏移

      假设U-Boot链接时基址为0x10000,但实际加载到0x20000:

      基址偏移 x9 = 0x20000 - 0x10000 = 0x10000。

      若某个重定位项的r_offset = 0x11000(链接时地址),r_addend = 0x200:

      运行时r_offset 修正为0x11000 + 0x10000 = 0x21000。

3. 若定义了CONFIG_SYS_RESET_SCTRL,则执行reset_sctrl,也是一个钩子函数,复位操作相关。

4. 异常向量表配置及EL3常规配置

     a. 异常向量表地址(即vector)存到x0

     b. 判断当前EL几,然后执行对应的分支,以EL3举例

       1)把x0的值,写到vbar_el3。

       2)配置scr_el3 的低4位,包括安全位的设置,以及配置“物理IRQ中断会不会被路由到EL3”“物理 FIQ 中断会不会被路由到EL3”“external aborts和SError中断会不会被路由到EL3”,以上全部配置为“会”。

       3)使能浮点计算;使能单指令多数据。

       4)初始cntfrq_el的值。这个变量是咱们用的定时器的那个频率。在Uboot中,不是测量出来的,是直接写死的。

 5. 配置sctlr,使能指令cache

      c. CR_I,一个宏定义,表示指令cache在sctlr中的bit位。

      d. 通过switch_el宏指令,判断当前是EL几,然后进入相应分支。以el3举例。

      e. 把CR_I写入sctlr,即,使能指令cache。这个指令cache,是EL0和EL1的使能位。

 6. 使能多核之间的数据一致性

      f. 先是isb指令,流水线同步操作。

      g. 然后操作cpuectlr寄存器,bit6使能,即保证多核数据一致性。

 7. 截至这里,cache、TLB都是无效的。执行lowlevel_init

      h. 执行bl lowlevel_init时,bl指令,会把bl后边的指令的地址,存在LR中,以便执行完lowlevel_init的ret时返回。但是由于lowlevel_init中,也会调用bl,导致lr会被覆盖,所以在lowlevel_init中,先存一下LR的值。可以看到,上图最后3行,在执行ret 时,先把x29的值,恢复到lr中,在执行ret。

      i. 如果IRQ被设置为y,则进行中断控制器的配置:branch_if_slave可以判断是否是主核,若是主核,则执行ldr x0, = GICD_BASE 和bl gic_init_secure,然后跳转;若不是主核,则直接跳转。

       1)若是主核,x0存储了中断控制器寄存器基地址。

       2)x0作为参数,调用gic_init_secure:arch/arm/lib/gic_64.S。

       3)上图代码走GICV2分支。先是gicd_ctlr的bit0和bit1置1,表示使能Grp0和Grp1的中断上送。

       4)读取GICD_TYPER中的ITLinesNumber。

         需要了解的是,当ITLinesNumber = 0时,表示最大中断数为32 * (0 + 1) = 32,即 ID 为0 ~ 31。但只有32个中断,就意味着没有SPI(共享中断),如下图,SPI的编号,从32开始。

         所以,cbz w10 1f 指令的含义,是当没有SPI中断时,跳转到1:处,直接返回。

       5)通过循环,将所有中断都划到group1中。

       6)gic_init_secure结束,返回上一层。跳转到gic_ini_secure_percpu去,同时传进去的参数分别是GIC distributor寄存器组的基地址和cpu interface组的基地址。把SGI 和PPI划分到group1(其实在上一个函数里,已经做过一遍了)。使能SGI(多核通信要用);使能通过interface上报中断。

      j. 从核等待主核SGI0中断唤醒。

8. 最后进入_main

异常触发时,根据异常的类型(SE同步异常、irq中断、fiq快速中断等),硬件会跳转到vector 的偏移。比如,IRQ跳转到vector+0x80*5,其实就是,vector中的条目,每个条目按128字节对齐(align 7),所以就是,每个条目最多128字节。

相关文章:

  • 力扣经典算法篇-13-接雨水(较难,动态规划,加法转减法优化,双指针法)
  • PID - 模拟
  • 3D草图绘制管道
  • 从零搭建上门做饭平台:高并发订单系统设计
  • Deep Evidential Regression
  • doucker 挂载卷
  • 零基础设计模式——结构型模式 - 装饰器模式
  • ubuntu 制作 ssl 证书
  • 通过ansible playbook创建azure 资源
  • 电子邮箱设置SSL:构建邮件传输的加密护城河
  • 解决Qt 打包的软件缺少dll问题
  • UDP 传输时间(延迟)
  • 记录:训练过程中可训练参数出现nan和inf造成loss为nan
  • 2025年6月亲测可用 | 剪映免SVIP版本 | 支持数字人
  • 8.安卓逆向2-frida hook技术-frida环境安装
  • 利用亮数据实现大规模数据自动抓取
  • 如何验证 AXI5 原子操作
  • Linux 进阶命令篇
  • (自用)Java学习-5.19(地址管理,三级联动,预支付)
  • WSL连接网络
  • 网站建设的方案计划/seo营销技巧
  • 北京公司电话大全黄页/河北百度推广seo
  • ui设计师是做网站吗/怎么自己制作网站
  • 微官网免费制作平台/商丘seo教程
  • 网站首页轮播图怎么换/图片外链生成
  • 2b网站推广怎么做/品牌推广方案