【BES2500x系列 -- RTX5操作系统】系统执行流程 -- 引导程序(boot loader)--(十)

请添加图片描述

  • 💌 所属专栏:【BES2500x系列】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩

请添加图片描述

文章目录

  • 前言
  • 1 引导程序(boot loader)
      • 1.1 启动文件
        • 1.1.1 启动加载程序
        • 1.1.2 设置堆栈指针
        • 1.1.3 数据段初始化
        • 1.1.4 调用 main 函数
  • 总结


<<【系列文章索引】>>

前言

  大家好,又见面了,我是夜阑的狗🐶,本文是专栏【BES2500x系列】专栏的第10篇文章;
  今天开始学习BES2500x系列的一天💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
  专栏地址:【BES2500x系列】, 此专栏是我是夜阑的狗对BES2500x系列开发过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。
  如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。


1 引导程序(boot loader)

  前面学习了嵌入式系统启动的基本流程,可以分为 引导程序 和 系统初始化程序 这两部分,也对一些概念进行了讲解。接下来就来 引导程序 是怎么跑的吧,也就是 boot loader。话不多说,让我们原文再续,书接上回吧。

请添加图片描述

1.1 启动文件

  从上一篇文章中可以知道,引导程序一般都是以 汇编语言编写,所以其文件后缀为 .s 文件,在 platform/main 就能看到有这么一个文件:startup_main.S,如下图所示:

在这里插入图片描述

  很明显这个就是 boot loader 的启动文件里,接下来就让我们来看里面具体都干了什么吧,启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:

  Step 1、配置汇编启动文件
  Step 2、初始化堆栈指针 SP(__initial_sp);
  Step 3、初始化 PC 指针(Reset_Handler);
  Step 4、初始化中断向量表(__Vectors);
  Step 5、配置系统时钟(SystemInit);
  Step 6、数据段初始化;
  Step 7、一般情况是调用C库函数_main来初始化用户堆栈,从而最终调用main函数去到C的世界;

1.1.1 启动加载程序
  • 代码

  在讲解启动代码的时候,会涉及到 ARM 的汇编指令和 Cortex 内核的指令

    .syntax    unified.section .boot_loader, "ax", %progbits.thumb.thumb_func.align  2.globl  Boot_Loader.type   Boot_Loader, %function
  • 参数/函数讲解

  这段代码是用 ARM 汇编语言编写的启动加载程序(boot loader)。让我们来逐行解释:

序号参数/函数说明
1.syntax unified这是汇编器指示使用统一语法格式的指令
2.section .boot_loader, “ax”, %progbits这条指令定义了一个名为 .boot_loader 的段,属性为可执行(a)和可读(x),内容类型为程序代码(%progbits)
3.thumb该指令告诉汇编器使用Thumb指令集,Thumb是ARM处理器的一种指令集,它可以使得代码更加紧凑
4.thumb_func同上
5.align 2这是对齐指令,确保后续指令在内存中按2字节对齐
6.globl Boot_Loader这是一个全局符号定义指令,声明了一个名为 Boot_Loader 的全局符号,使得它可以在其他文件中访问
7.type Boot_Loader, %function这是类型定义指令,将 Boot_Loader 标记为一个函数
1.1.2 设置堆栈指针
  • 代码

  这段代码的作用是设置堆栈指针,为程序的执行做准备。接下来是函数的实现:

Boot_Loader:ldr     r0, =__StackTopmsr     msp, r0
/* Always use MSP and set privileged mode */movs    r0, #0msr     control, r0isb#ifndef NO_NVIC_INITbl      NVIC_InitVectors
#endif#ifndef NO_BOOT_INITbl      BootInit
#endif#ifndef NO_SYSTEM_INITbl      SystemInit
#endif
  • 参数/函数讲解

  这段代码的作用是在设置好堆栈指针后,进行一些系统的初始化工作,包括设置特权级别、执行启动前初始化钩子、初始化中断向量表、执行启动初始化和系统初始化。条件编译部分根据预定义的宏来选择是否执行相应的初始化操作。

序号参数/函数说明
1ldr r0, =__StackTop这条指令将栈顶地址 __StackTop 的值加载到寄存器 r0 中
2msr msp, r0这条指令将寄存器 r0 中的值(即栈顶地址)写入主堆栈指针寄存器 msp 中,从而设置了栈顶地址
3movs r0, #0这条指令将常数0移动到寄存器 r0 中
4msr control, r0这条指令将寄存器 r0 中的值(即常数0)写入到控制寄存器 control 中,用于设置特权级别。并且决定使用哪一个堆栈指针
5isb这是指令同步栅栏指令,确保在修改特权级别后立即执行。

  接下来是一些条件编译的部分:

序号参数/函数说明
1#ifndef NO_NVIC_INIT这是另一个预处理器指令,用于检查是否没有定义 NO_NVIC_INIT 宏。如果没有定义,那么会调用 NVIC_InitVectors 函数,用于初始化中断向量表。
2#ifndef NO_BOOT_INIT同样是预处理器指令,用于检查是否没有定义 NO_BOOT_INIT 宏。如果没有定义,那么会调用 BootInit 函数,用于执行启动初始化,配置系统时钟
3#ifndef NO_SYSTEM_INIT同样是预处理器指令,用于检查是否没有定义 NO_SYSTEM_INIT 宏。如果没有定义,那么会调用 SystemInit 函数,用于执行系统初始化
1.1.3 数据段初始化
  • 代码
    ldr    r1, =__etextldr    r2, =__data_start__ldr    r3, =__data_end__.L_loop1:cmp    r2, r3ittt    ltldrlt    r0, [r1], #4strlt    r0, [r2], #4blt    .L_loop1
  • 参数/函数讲解

  这部分代码执行了数据段的初始化,将程序的只读数据段(.text 段)中的数据复制到RAM中的数据段(.data 段)中。

序号参数/函数说明
1ldr r1, =__etext将只读数据段的结束地址 __etext 加载到寄存器 r1 中
2ldr r2, =__data_start__将RAM中数据段的起始地址 __data_start__ 加载到寄存器 r2 中
3ldr r3, =__data_end__将RAM中数据段的结束地址 __data_end__ 加载到寄存器 r3 中

  然后,使用一个循环(标签 .L_loop1)来逐个复制数据:

序号参数/函数说明
1cmp r2, r3比较寄存器 r2 和 r3 中的值,检查是否到达数据段的结束地址
2ittt lt这是一个条件执行指令,当 lt(小于)条件成立时,执行后续的指令
3ldrlt r0, [r1], #4如果 r2 小于 r3,则从只读数据段中加载一个32位数据到寄存器 r0 中,并递增只读数据段的地址
4strlt r0, [r2], #4如果 r2 小于 r3,则从只读数据段中加载一个32位数据到寄存器 r0 中,并递增只读数据段的地址
5blt .L_loop1如果 r2 小于 r3,则继续循环,否则跳出循环

  这段代码的作用是将只读数据段中的初始化数据复制到 RAM 中的数据段中,以便程序运行时可以修改这些数据。

1.1.4 调用 main 函数
  • 代码
#if defined(__ARMCC_VERSION) && !defined(NOSTD) || defined(NUTTX_BUILD)bl    __rt_entry
#elsebl    _start
#endif.pool.size    Boot_Loader, . - Boot_Loader.end
  • 参数/函数讲解

  这段代码根据条件调用不同的函数作为程序的入口点:如果使用的是 ARMCC 编译器且未定义 NOSTD 宏,或者是 NuttX 构建环境,那么将调用 __rt_entry 函数。否则,将调用 _start 函数。基本到这里上 bootloader 算是完成它的工作了。 然后,使用 .pool 指令和 .size 指令对 Boot_Loader 函数进行处理。

序号参数/函数说明
1.pool这个指令用于池区,是一种链接指令,用于优化分支指令。它的存在告诉链接器将后续的分支指令(例如 bl)尽可能地放在一起
2.size这个指令指定了 Boot_Loader 函数的大小,用于告诉链接器该函数的长度。. Boot_Loader 表示从当前位置到 Boot_Loader 标签之间的距离,即函数的长度。
3.end指明了汇编文件的结束

<<【系列文章索引】>>

请添加图片描述


总结

  感谢观看,这里就是 boot loader 引导程序的讲解,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

  也欢迎你,关注我。👍 👍 👍

  原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉

更多专栏订阅:

  • 😀 【LeetCode题解(持续更新中)】

  • 🥇 【恒玄BES】

  • 🌼 【鸿蒙系统】

  • 💎 【蓝牙协议栈】

  • 🎃 【死机分析】

  • 👑 【Python脚本笔记】

  • 🚝 【Java Web项目构建过程】

  • 💛 【微信小程序开发教程】

  • 【JavaScript随手笔记】

  • 🤩 【大数据学习笔记(华为云)】

  • 🦄 【程序错误解决方法(建议收藏)】

  • 🔐 【Git 学习笔记】

  • 🚀 【软件安装教程】



订阅更多,你们将会看到更多的优质内容!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/386596.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

地球磁场的形成、变迁、特点

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

Unity多客户端位置同步信息

书接上文&#xff0c;有了一个基本的网络同步消息的服务器&#xff0c;客户端这边其实要做的工作就简单许多。 如果对位置信息的保密程度没那么高的话&#xff0c;可以放在客户端处理这部分的逻辑。 即一个客户端移动的时候&#xff0c;另一个客户端跟着移动&#xff0c;基本…

【电控笔记-xuan】各种估测器扰动估计性能比较

各种扰动观测器观测结果 蓝色: 扰动值 隆博戈估测器扰动补偿 论文53disturb扰动补偿 2order eso 观测

LabVIEW学习-LabVIEW处理带分隔符的字符串从而获取数据

带分隔符的字符串很好处理&#xff0c;只需要使用"分隔符字符串至一维字符串数组"函数或者"一维字符串数组至分隔符字符串"函数就可以很轻松地处理带分隔符地字符串。 这两个函数所在的位置为&#xff1a; 函数选板->字符串->附加字符串函数->分…

APT 安装软件详细教程

文章目录 APT 安装软件详细教程APT 概述APT 的基本命令APT 命令详解安装软件包更新和升级软件包删除软件包搜索和查找软件包管理软件包依赖清理软件包缓存APT 配置软件源配置自定义软件源常见问题及解决方案解决软件包依赖问题处理软件源错误其他常见问题使用 APT 的最佳实践总…

在Postman中引用JS库

前言 在做接口测试时&#xff0c;出于安全因素&#xff0c;请求参数需要做加密或者加上签名才能正常请求&#xff0c;例如&#xff1a;根据填写的请求参数进行hash计算进行签名。postman作为主流的接口调试工具也是支持请求预处理的&#xff0c;即在请求前使用JavaScript脚本对…

昇思MindSpore学习入门-自动混合精度

混合精度&#xff08;Mix Precision&#xff09;训练是指在训练时&#xff0c;对神经网络不同的运算采用不同的数值精度的运算策略。在神经网络运算中&#xff0c;部分运算对数值精度不敏感&#xff0c;此时使用较低精度可以达到明显的加速效果&#xff08;如conv、matmul等&am…

OSI七层模型详解

OSI七层模型 OSI&#xff08;Open System Interconnect&#xff09;&#xff0c;即开放式系统互连。 一般都叫OSI参考模型&#xff0c;是ISO组织在1985年研究的网络互连模型。该体系结构标准定义了网络互连的七层框架&#xff08;物理层、数据链路层、网络层、传输层、会话层、…

[玄机]流量特征分析-常见攻击事件 tomcat

[玄机]流量特征分析-常见攻击事件 tomcat 题目做法及思路解析&#xff08;个人分享&#xff09; Tomcat是一个开源的Java Servlet容器&#xff0c;它实现了Java Servlet和JavaServer Pages (JSP) 技术&#xff0c;提供了一个运行这些应用程序的Web服务器环境。Tomcat由A…

go程序在windows服务中优雅开启和关闭

本篇主要是讲述一个go程序&#xff0c;如何在windows服务中优雅开启和关闭&#xff0c;废话不多说&#xff0c;开搞&#xff01;&#xff01;&#xff01;   使用方式&#xff1a;go程序 net服务启动 Ⅰ 开篇不利 Windows go进程编译后&#xff0c;为一个.exe文件,直接执行即…

语言转文字

因为工作原因需要将语音转化为文字&#xff0c;经常搜索终于找到一个免费的好用工具&#xff0c;记录下使用方法 安装Whisper 搜索Colaboratory 右上方链接服务 执行 !pip install githttps://github.com/openai/whisper.git !sudo apt update && sudo apt install f…

NSSRound#4 Team

[NSSRound#4 SWPU]1zweb 考察&#xff1a;phar的反序列化 1.打开环境&#xff0c;审计代码 1.非预期解 直接用file伪协议读取flag,或直接读取flag file:///flag /flag 2.正常解法 用读取文件读取index.php,upload.php的源码 index.php: <?php class LoveNss{publi…

hadoop学习(一)

一.hadoop概述 1.1hadoop优势 1&#xff09;高可靠性&#xff1a;Hadoop底层维护多个数据副本&#xff0c;即使Hadoop某个计算元素或存储出现故障&#xff0c;也不会导致数据的丢失。 2&#xff09;高扩展性&#xff1a;在集群间分配任务数据&#xff0c;可方便扩展数以千计…

c++ 内存管理(newdeletedelete[])

因为在c里面新增了类&#xff0c;所以我们在有时候会用malloc来创建类&#xff0c;但是这种创建只是单纯的开辟空间&#xff0c;没有什么默认构造的。同时free也是free的表面&#xff0c;如果类里面带有指针指向堆区的成员变量就会free不干净。 所以我们c增加了new delete和de…

Python --Pandas库基础方法(2)

文章目录 Pandas 变量类型的转换查看各列数据类型改变数据类型 重置索引删除行索引和切片seriesDataFrame取列按行列索引选择loc与iloc获取 isin()选择query()的使用排序用索引排序使用变量值排序 修改替换变量值对应数值的替换 数据分组基于拆分进行筛选 分组汇总引用自定义函…

springcloud RocketMQ 客户端是怎么走到消费业务逻辑的 - debug step by step

springcloud RocketMQ &#xff0c;一个mq消息发送后&#xff0c;客户端是怎么一步步拿到消息去消费的&#xff1f;我们要从代码层面探究这个问题。 找的流程图&#xff0c;有待考究。 以下我们开始debug&#xff1a; 拉取数据的线程&#xff1a; PullMessageService.java 本…

126M全球手机基站SHP数据分享

数据是GIS的血液&#xff01; 我们在《2.8亿东亚五国建筑数据分享》一文中&#xff0c;为你分享过东亚五国建筑数据。 现在再为你分享全球手机基站SHP数据&#xff0c;你可以在文末查看该数据的领取方法。 全球手机基站SHP数据 全球手机基站数据是OpenCelliD团队创建由社区…

【Spring Cloud】Sleuth +Zinkin 实现链路追踪并持久化的解决方案

文章目录 前言链路追踪介绍Sleuth入门Sleuth介绍TraceSpanAnnotation Sleuth入门1、引入依赖2、修改配置文件3、网关路由配置4、演示 Zipkin的集成ZipKin介绍ZipKin服务端安装Zipkin客户端集成1、添加依赖2、添加配置3、访问微服务4、演示 Zipkin数据持久化使用mysql实现数据持…

现代Java开发:使用jjwt实现JWT认证

前言 jjwt 库 是一个流行的 Java 库&#xff0c;用于创建和解析 JWT。我在学习spring security 的过程中看到了很多关于jwt的教程&#xff0c;其中最流行的就是使用jjwt实现jwt认证&#xff0c;但是教程之中依然使用的旧版的jjwt库&#xff0c;许多的类与方法已经标记弃用或者…

多家隧道代理价格:阿布云、快代理、小象代理、熊猫代理和亿牛云……

随着奥运的热度攀升&#xff0c;各大品牌也在抓紧时机赶上这波奥运热潮&#xff0c;随之而来的大量数据信息收集和分析工作也接踵而至&#xff0c;在这一数据采集过程中&#xff0c;HTTP代理的质量和价格对企业的效率和成本调控重要性不言而喻。我们大部分人在日常购买产品的时…