嵌入式系统中引导加载程序和启动代码的基本意义是什么?有什么区别?
这些放在哪里??并概述了从上电复位到应用程序启动的流程。一般考虑任何平台。
所有处理器都有一些特定于处理器的启动方式。通常在处理器地址空间中有一些地址,例如 0xFFFF0000,处理器读取该内存的位置。它找到的值用作编码地址并开始在该地址执行代码。
硬件芯片或电路板设计人员会做的是确保将闪存或某种其他形式的非易失性存储器 (ROM) 映射到该地址空间,以便处理器的引导代码和该地址映射到该特殊位置的引导代码地址,将在打开电源并释放复位时供处理器读取(RAM 易失性,关闭电源会丢失数据,重新打开电源会得到一些随机数据,直到RAM是用别的东西写的)。
所以处理器运行的第一个代码通常称为引导加载程序,有些人可能会争论说加载程序这个词的后半部分意味着这段代码既可以“引导”操作系统或任何要运行的应用程序,也可以作为第二个函数为开发人员提供“加载器”功能。如果您曾经使用过U-Boot甚至GRUB或许多其他引导加载程序,您可能会明白,如果您不碰任何东西,它将引导默认的任何东西,嵌入式应用程序或操作系统,等等。
但是,如果您中断启动过程,并且中断该过程是非常特定于平台和软件的,有时您必须按下按钮或将两个引脚短接或在串行/ UART端口上发送转义或其他字符等.,然后它进入加载程序模式,您可以更改它的引导和/或引导加载程序而不是从闪存/ROM加载默认程序,它可能让您使用XMODEM或ZMODEM或以太网端口和协议将测试程序加载到 RAM 中,然后让您运行该程序而不是默认程序。
有些人将引导软件称为引导加载程序,即使它不允许您中断进程并加载一些备用程序,因为该引导代码可能会将应用程序从非易失性存储“加载”到 RAM 中。
并非所有引导加载程序都需要将应用程序从非易失性存储(闪存/ROM、硬盘、CD-ROM 等)复制到 RAM。一些系统和一些应用程序从闪存/ROM 运行。以 PC 为例:PC 中真正的引导加载程序是 BIOS,它是一个存在于闪存/ROM 中并从其运行的程序。对于像 PC 这样的具有DRAM的系统,无论如何您都必须启动 DRAM 系统。配置硬件以使 DRAM 工作需要大量代码,有时您可以在 PC 启动时在显示器上看到一些状态。如果您的系统中有SRAM,那么它可能还需要一些初始化,但通常不像 DRAM 那样复杂,而且通常它可以立即启动并准备好使用很少或没有配置,不同的处理器和不同的系统......不同.
所以处理器没有复位,以某种方式硬编码在处理器硬件中。它找到了引导代码的入口点并开始执行该代码。然后,该代码通常需要启动并运行外围设备和 RAM,然后运行主应用程序。或者在启动该应用程序之前至少需要同样多的硬件。
在嵌入式系统中加载 Linux 可以像启动 RAM 一样简单,然后将内核从 ROM 复制到 RAM,可能准备一些寄存器并可能填充内核查看的一些内存位置,可能是内存大小和备用命令行例如,然后分支到内核的开头。您不必在某些系统上复制内核;您可以分支到它所在的ROM。然后 Linux 将启动系统的其余部分。在 PC 上,BIOS 做了很多事情,比如调出视频、DRAM、枚举PCI(e) 总线外设,启动硬盘或其他文件系统类似设备,然后使用用户在 BIOS 硬盘或类似外设(USB 拇指驱动器或 CD-ROM 等)中定义的。文件系统的开头将包含某种如何根据 BIOS 代码规则引导操作系统的内容。这可能是另一个引导加载程序(GRUB、U-Boot 等),它最终将内核或操作系统启动代码复制到 RAM,然后分支到它……
术语引导加载程序和启动代码可以互换使用。有些人可能会对它们不同或细微的差异感到挑剔,但这通常与复杂性有关,像 U-Boot 这样具有以太网驱动程序和文件系统驱动程序等的引导加载程序在某种程度上是其中的操作系统自我,无论哪种方式,U-Boot 都非常复杂。
例如,微控制器的启动代码可能很简单,只需几行代码、设置堆栈指针并跳转到 main。启动代码/引导加载程序可以是介于两者之间的任何复杂程度。如前所述,一些嵌入式系统从 ROM 启动并运行它们的应用程序,因此不需要复制和运行。其他人需要复制并运行主应用程序。
有时会涉及到硬件或其他一些方案。例如,许多基于FPGA的解决方案是可能的,其中硬件在上电时从 ROM 读取内容并复制它。然后,当处理器或其他逻辑被释放时,您的程序或其他数据就神奇地存在于 RAM 中,随时可以使用。即使电源关闭时,它也存在于您通常不会触摸的 ROM 中。Raspberry Pi还有另一种解决方案。该芯片有两个处理器,一个是ARM,一个是GPU,图形处理器,完全不同的指令集,专为数学运算等而设计。有以某种形式烧入芯片(可能是芯片上的 ROM)中的小型引导加载程序,足以启动和读取 SD 卡。这是 GPU 顺便说一句;ARM 处于复位状态。然后 GPU 从 SD 卡读取其第一个引导加载程序文件,将其复制到 RAM 并运行它。
该引导加载程序做了更多的事情,比如启动 DRAM,然后将更复杂的第二(第三?)阶段引导加载程序从 SD 卡复制到 DRAM,然后运行它。该代码可能包含用于为系统执行屏幕/显示功能的 GPU 应用程序。它还,一旦视频和一切准备就绪,再次读取 SD 卡并将 ARM 应用程序从 SD 卡复制到 DRAM,填充 RAM 中的一些项目(异常表中的引导向量(内核分支))以及 Linux 内核引导代码需要的已知位置的其他一些项目。然后它释放 ARM 上的复位。此时 ARM 唤醒了它的应用程序,内核,神奇地在 RAM 中......