【启动】芯片启动过程全解析

本文详细介绍了芯片启动过程中的BootLoader作用,包括其在不同架构(如X86和ARM)芯片中的启动步骤,以及BootRom和Bootloader的区别和功能。文章还探讨了MCU和运行Linux的SOC启动流程的差异,以及Bootloader在其中的关键角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hi!早,今天来和你一起聊聊芯片启动过程发生了什么。

内容基本来自文末推荐视频


当你按下电源开关的那一瞬间,第一行代码如何在芯片上运行起来的呢?

嵌入式软件代码需要一定的方式烧录到芯片中才能运行,除了物理刻蚀,无论是通讯端口的传输或者调试端口的烧录,都需要驱动程序的支持。

所以说是程序烧录了程序,软件启动了软件。

这就像自己提着自己的鞋带,把自己拎起来。

靴子(Boot),鞋带(Strap),提鞋带(Loader)。

这就是Boot Strap Loader的命名来源。通常称BootLoader,中文翻译为自举。

BootLoader是芯片最初运行的代码吗?

当然不是,其实每一块芯片在出厂时都在其内部的ROM中,烧录了它最基础的软件。

CPU 搬运并运行的第一条代码的默认位置,就在ROM的地址空间。所以一切的起始都在硬件上。

以 X86 架构的鼻祖 8086 芯片为例,按下开关的一瞬间,芯片 Reset 引脚接收到了电平跳变,在一连串电路的作用下,代码段寄存器CS恢复成0XFFFF,指令指针寄存器IP恢复成0X0000,他们组合成 20 位的地址正好等于 ROM 中存放第一条代码的位置。

所以,一个Soc真正的启动过程,在BootRom之前,其实逻辑进行了很多的动作,如果开了安全模式,那干的工作就更多额。但是作为嵌入式工程师,对于这部分涉及的机会实在是太少了。

之后取出这里的指令在跳转到别处。

ARM 架构的芯片也是类似的过程,对于 32 位的芯片,通电后,PC指针寄存器复位至零地址随后从中断向量表表头的 reset 向量处获取下一个跳转的地址。

这时候的代码已经以二进制形式存储,处理器可以直接搬到自身缓存中运行。

有了这部分代码,就能跳转到存放有更多更复杂的代码的地址。

执行硬件自检,基本的初始化操作,提供基础的输入输出支持。

之后可以将操作系统从外部的存储空间加载到内部。

代码就这样接力式的流转起来。


所以我们把出厂就写在ROM里,负责启动后续用户软件的软件,称为Boot ROM或者ROM Code。

现在不一定是用只读存储器(Read Only Memory),但是至少是一块掉电不易失的存储器,现在主要用EEPROM,NOR Flash

我们一般没有权限修改它,但是它也不完全是黑盒,大部分芯片都会有外部启动配置引脚,通常是以拨码开关的形式。

对于 PC 机来说,Boot ROM就是我们常说的BIOS,它也有启动配置途径。而且提供了交互界面,用于配置部分功能和选择后续的引导设备。

那是不是BootRom是绝对安全的呢?

答案是NO,详情参见认识Glitch到攻击BootROM



除了芯片自带的Boot ROM,还需要再给自己实际的应用程序,写一个二次引导代码或者 N 次引导代码,用作操作系统,文件系统加载等等。

我们所说的Bootloader时,其实大多数就是这样的二次引导代码。

这些事其实Boot ROM它也能做,但是Boot ROM实现的功能和配置方法不灵活,但是Bootloader是开发人员可以而完全控制的引导代码。

还有两点:

  • 1、BootRom的存储介质成本很高,一般降成本会考虑缩小BootRom的大小,因此BootRom的代码尽量缩小
  • 2、BootRom我们刚刚知道是不能修改的,所以代码越大,出问题的风险越大。因此一般BootRom都是放的必要内容。

在设计Bootloader时,MCU的引导步骤就开始和嵌入式 Linux 或者 PC 有所不同。

这一定程度与芯片架构所采用的的存储方案有关。

先来说MCU,与SOC相比MCU的主要特征是:

  • 单核和或多核同构的微处理器,
  • 单核或多核同构,
  • 主频 < 1GHz,
  • 没有MMU内存管理单元,
  • 只能运行实时操作系统。

常见MCU内核:


程序的主要运行介质为NOR Flash,因为和RAM一样有分离的地址线和数据线。

并且可以以字节长度精确寻址,所以程序不需要拷贝到RAM中运行的。

以英飞凌家的 TC27x 系列 MCU 为例,上电后的默认取址位置是0x8FFF 8000,这就是他的Boot ROM在NorFlash中的地址。并且这块Boot Rom分为SSW,BSL,TF。


SSW 每次上电必须运行,他会根据写在program flash,PFO地址的前 32byte 中的配置字,来决定SSW执行完的跳转地址。

我们可以选择一个合适的跳转地址,比如0x80000020,放上自己写的Bootloader。

也可以选择不跳转,运行厂家提供的Bootloader(BSL)。

MCU下的Bootloader主要完成的事情有以下:

  • 关闭看门狗,初始化中断和 trap 向量表,进行时钟和外设初始化,让芯片正常运行起来。

  • 提供CAN,UART, ETH等用于通讯功能的驱动,能够接收外部数据传输请求。

  • 提供FLASH的读写与擦除驱动,设计服务来对通讯端口接收到的更新代码进行校验、存储,以及跳转操作系统或后续应用程序代码。

  • 如有必要,还会开发一些基础诊断服务,串口交互程序等等。

那么运行 Linux 的SOC和 PC 的这一过程有何不同呢。

还是先看存储方案,运行嵌入式 Linux 的 SoC。

一般将它的操作系统,文件系统和他的应用程序放在nand flash中。

运行代码前,需要将代码搬运到SRAM中,相比MCU多了一道步骤。

对于SOC的Boot ROM 和 PC 的BIOS而言,他们结束运行前的最终任务,是将某些代码从nand flash搬运到SRAM中,其中最重要的内容就是Boot Loader。

而一般SOC的Bootloader,又分为SPL(Secondary Program Loader)和uBOOT两个阶段。

SPL的 Secondary 就是相对于BootROM而言,他就像是接力赛中的第二棒选手。

SPL会初始化更大空间的外部DRAM,再把uBoot搬运到外部DRAM中去运行。

uBoot作为第三棒选手,开始运行它的初始化程序。

之后再根据系统环境变量,将 OS 内核搬运到外部DRAM中去运行。

OS 再完成根文件系统的加载等等等等。


相关阅读推荐:


参考资料


推荐观看视频:

### LlamaIndex 多模态 RAG 实现 LlamaIndex 支持多种数据类型的接入与处理,这使得它成为构建多模态检索增强生成(RAG)系统的理想选择[^1]。为了实现这一目标,LlamaIndex 结合了不同种类的数据连接器、索引机制以及强大的查询引擎。 #### 数据连接器支持多样化输入源 对于多模态数据的支持始于数据收集阶段。LlamaIndex 的数据连接器可以从多个异构资源中提取信息,包括但不限于APIs、PDF文档、SQL数据库等。这意味着无论是文本还是多媒体文件中的内容都可以被纳入到后续的分析流程之中。 #### 统一化的中间表示形式 一旦获取到了原始资料之后,下一步就是创建统一而高效的内部表达方式——即所谓的“中间表示”。这种转换不仅简化了下游任务的操作难度,同时也提高了整个系统的性能表现。尤其当面对复杂场景下的混合型数据集时,良好的设计尤为关键。 #### 查询引擎助力跨媒体理解能力 借助于内置的强大搜索引擎组件,用户可以通过自然语言提问的形式轻松获得所需答案;而对于更复杂的交互需求,则提供了专门定制版聊天机器人服务作为补充选项之一。更重要的是,在这里实现了真正的语义级关联匹配逻辑,从而让计算机具备了一定程度上的‘认知’功能去理解和回应人类意图背后所蕴含的意义所在。 #### 应用实例展示 考虑到实际应用场景的需求多样性,下面给出一段Python代码示例来说明如何利用LlamaIndex搭建一个多模态RAG系统: ```python from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader, LLMPredictor, PromptHelper, ServiceContext from langchain.llms.base import BaseLLM import os def create_multi_modal_rag_system(): documents = SimpleDirectoryReader(input_dir='./data').load_data() llm_predictor = LLMPredictor(llm=BaseLLM()) # 假设已经定义好了具体的大型预训练模型 service_context = ServiceContext.from_defaults( chunk_size_limit=None, prompt_helper=PromptHelper(max_input_size=-1), llm_predictor=llm_predictor ) index = GPTSimpleVectorIndex(documents, service_context=service_context) query_engine = index.as_query_engine(similarity_top_k=2) response = query_engine.query("请描述一下图片里的人物表情特征") print(response) ``` 此段脚本展示了从加载本地目录下各类格式文件开始直到最终完成一次基于相似度排序后的top-k条目返回过程。值得注意的是,“query”方法接收字符串参数代表使用者想要询问的内容,而在后台则会自动调用相应的解析模块并结合先前准备好的知识库来进行推理计算得出结论。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TrustZone_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值