嵌入式实时操作系统的设计与开发 (启动内核学习)

RTOS的引导模式

RTOS的引导是指将操作系统装入内存并开始执行的过程。

时间限制主要包括:系统要求快速启动系统启动后要求程序能实时运行。

空间限制主要包括:Flash等非易失性存储空间限制RAM等易失性存储空间限制。

通常不可能同时满足两种要求,需根据具体情况进行折中处理,由此,RTOS的引导分为如下两种模式。

需要BootLoader的引导模式

BootLoader是在RTOS内核运行之前执行的一段小程序,它将RTOS内核从外部存储介质复制到内存中,并让PC跳转到刚复制到内存的内核的首条指令。

在嵌入式系统中,BootLoader依赖于硬件,几乎不可能建立一个通用的BootLoader。不同的CPU体系结构都有不同的BootLoader,另外,BootLoader还依赖于具体的嵌入式板级设备的配置。

对于采用高性能RAM的系统,出于成本因素,RAM空间有一定限制,此时一般采用Bootloader引导方式:由Loader程序把RTOS内核中的数据段复制到RAM中,代码段在Flash中运行。

因为代码段在低速的Flash中运行,该方式在节省空间的同时,牺牲了时间。这种引导方式适合于硬件成本低、运行速度相对较慢的嵌入式系统,但是启动时间却较快。

如果RAM空间没有限制,足够程序运行时,由Loader程序把RTOS内核从非易失性存储介质全部复制到RAM中,对于某些压缩的内核,复制后还需要解压。此时,不能满足对启动速度要求特别高的系统,但是系统的运行速度却能得到保障。

不需要BootLoader的引导模式

对于实时性要求较高的系统,通常要求系统能够快速启动。由于将Flash中的代码复制到RAM中的操作会带来一定的时间开销,因此,对于此类系统启动时无须BootLoader,而直接在NorFlash或ROM等可以做主存的非易失性存储介质中运行,以达到较快的启动速度。但这种引导模式不能满足运行速度的要求,因为Flash的访存时间与RAM的访存时间存在数量级上的差距。

通常,除了上述两种引导模式中考虑时间、空间效率以外,出于空间效率的要求,需要对RTOS内核使用压缩工具进行压缩,在RTOS引导时,采用逆向解压缩算法解压。

同时,出于实时性的考虑,压缩算法不能过于复杂,否则压缩、解压过程消耗大量时间将与启动时间限制发生严重冲突。

采用压缩策略并不一定会增加系统启动时间,因为压缩、解压过程虽然消耗了一定的时间,但是由于内核体积小,由Flash复制到RAM中的时间相应减少,有可能反而减少了时间消耗。

以VxWorks操作系统为例,VxWorks Image分为在ROM中运行和RAM中运行两种,而且在ROM中运行的VxWorks Image是非压缩的,不需要解压;但在RAM中运行的VxWorks Image是压缩的,引导时需要解压COPY所有的text和data到RAM中。

BootLoader

BootLoader可以拆分成两部分:一个是Boot,另一个是Loader。

  1. Boot:Boot意味着系统启动时会从这里启动,具体一定就是当大家按下开机键时,CPU执行的第一条指令就是Boot的代码,也就是说Boot的代码要存储在CPU第一条指令的地址处。
  2. Loader:加载代码程序,这个程序就是内核映像。

从上面可以看出,在PC上,BIOS满足上面的特性,因为PC启动时就是从BIOS的地址处启动的,然后BIOS的代码读取硬盘的第一扇区的数据,即引导程序,然后将控制权交给引导程序,再由引导程序加载操作系统内核代码运行。

而在嵌入式系统中,Vivi、Uboot等就是BootLoader,这些程序都是开机时就启动,启动后,会从NAND Flash或SD卡等存储设备中奖RTOS内核程序代码复制到SDRAM中,然后执行内核代码。

aCoral的BootLoader就是start.s,代码很少。

Vivi,Uboot代码量大的原因主要是:它们都支持多种嵌入式平台,都可以看成是一个通用的BootLoader,除了提供上面启动、RTOS加载两个功能外,它们还支持更多功能,如支持各种命令,这些命令主要分为以下两大类:

  1. 操作设备类:支持板载设备的操作,如操作Flash等。
  2. 数据相关类(通信和管理):支持FTP、NFS等网络协议,支持USB下载等。

有些BootLoader,如ARM公司的Bootmonitor还支持文件系统,能以文件系统的方式管理NANDFlash、SDCARD上的数据。

有了上面两大类操作的支持后,BootLoader不再是纯粹的BootLoader了,它已具备了一些操作系统的功能,只是不支持操作系统支持的任务管理、调度、切换等功能。

其实像Vivi,Uboot这些BootLoader在电子产品很少用到,因为电子产品强调性能、成本,且不愿意用户有太大的修改权利,且Vivi,Uboot尺寸很大,启动时间长,严重影响系统的性能和成本,因此商用后,BootLoader肯定越小越好。

真正在商用产品中,BootLoader这部分代码直接写到操作系统,这个简单的BootLoader是和内核一起编译,并且通过链接器链接在一起的。

存储介质的划分方法

  1. 按存储介质分类。作为存储介质的基本要求,必须具备能够显示两个有明显区别的物理状态的性质,分别用来表示二进制码的0和1。另一方面,存储器的存取速度又取决于该物理状态的改变速度。目前主要是半导体器件和磁性材料,用半导体器件组成的存储器称为半导体存储。
  2. 按存取方式分类。如果存储器中任何存储单元的内容都能被随机存取,且存取时间和存储单元的物理位置无关,这种存储器称为随机存储器。半导体存储器和磁芯存储器都是随机存储器。如果存储器只能按某种顺序来存取,也就是说存取时间和存储单元的物理位置有关,这种存储器称为顺序存储器。例如,磁带存储器就是顺序存储器。一般来说,顺序存储器的存取周期较长,磁盘存储器是半顺序存储器。
  3. 按存储器的读写功能分类。有些半导体存储器存储的内容是固定不变的,即只能读出而不能写入,因此这种半导体存储器称为只读存储器(ROM)。既能读出又能写入的半导体存储器,称为随机存储器(RAM)。
  4. 按信息的可保存性分类。断电后信息即消失的存储器,称为非永久记忆的存储器。断电后仍能保存信息的存储器,称为永久性记忆的存储器。磁性材料做成的存储器是永久性存储器,半导体读写存储器RAM是非永久性存储器。
  5. 按串、并行存取方式分类。目前使用的半导体存储器大多为并行存取方式,但也有以串行存取方式工作的存储器,如电耦合器件(CCD)、串行移位寄存器和镍延迟线构成的存储器等。

为什么会出现这么多种类呢?这是价格和用户需求平衡的结果。

例如,大家知道程序最后运行必须要有随机可读写存储器来存储变量,且速度要快,这导致了RAM的产生,但是RAM价格昂贵,于是又导致了SDRAM的产生,SDRAM和RAM的区别就是它是靠电容的值来保存0,1信息,时间一长就会丢失数据,故需要周期性刷新,这个在SDRAM控制器芯片的控制下能很好解决,且不太影响性能,但是它的速度比RAM低一些,复杂一些,但是价格低很多,容量可以做到很大,故是一种很好的存储器,因此目前无论是嵌入式还是PC设备都广泛使用到了SDRAM。

虽然SDRAM解决了可读写和速度问题。但是它们都是非永久记忆的存储器,断电后信息即消失,明显不能满足用户永久保存代码和数据的需求,因为用户总不至于每次启动计算机都要下载一次程序吧,于是就产生了NAND Flash、硬盘等永久记忆的存储器(硬盘容量很大,但是很少用在嵌入式系统中)。

这些存储器是永久记忆的,且能做到很大容量,但是速度慢,不过某种程序上还是可以承受的,因为有办法可以解决这个问题。
在启动阶段,Boot的工作完成后,Loader程序将系统程序和用户程序从这些存储介质上复制到SDRAM中,这样程序真正运行时,代码和数据就是从SDRAM中读取的了,也就没有速度问题。

有了NANDFlash、硬盘等永久记忆的存储器还不够,因为它们是按块访问的,而不是按地址访问,这种块模式访问往往需要有硬件控制器,而硬件控制器又需要有程序来控制,那这个控制器的驱动从何而来?这就是鸡生蛋、蛋生鸡的问题,正因如此,又出现了一种存储器ROM,如NorFlash等只读存储器。

NORFlash这种存储器也是永久记忆的存储器,但它和NANDFlash等不一样,它是按地址随机访问的,也就是说不需要驱动,和SDRAM的访问方式一样,可以很简单地访问数据,这就解决了这个问题,但是这种按地址访问的永久记忆的存储器相比有点贵,做不到很大容量。其实也没有必要过多使用这种存储器,因为它是只读的,没法修改,不会过多使用,所以只要能够容纳BootLoader程序就可以了,其它的代码交给廉价的可读写的NANDFlash。

BootLoader所选用的存储器肯定得是按地址随机存取的永久性记忆的存储器,当然对于支持NANDFlash启动的SOC,这可以存储在NANDFlash。

刚才不是说NANDFlash、SDCARD都是需要控制器才能访问数据的,控制器又需要驱动程序,那如何做到从这些地方启动呢?

其实,解决方法和上面讨论的一样,就是必须有一个复制过程,该复制过程可以有三种方式,硬件方式、软件方式、内存映射。

  1. 硬件方式。就是硬件实现对存储设备控制器的控制,读取指定大小的数据,它没法做的控制器的驱动程序那样,可以随机读取任意大小的数据,但是只要能够复制指定地址,指定大小的数据就已经够了,硬件可以看成是简化版的驱动。
  2. 软件方式。这种方式就更简单了,芯片自带一个ROM,往往是片内ROM,里面装有驱动程序,这个驱动程序负责将BootLoader从NAND Flash等存储器复制到RAM中,然后跳转到BootLoader中运行。这样方式其实和我们把BootLoader存储在ROM中是一样的,只不过板子自带了一个BootLoader,实现小量数据复制。
  3. 内存映射。当用户使用跳线选择启动方式后,硬件自动开启了内存映射,将其它地址映射到CPU启动地址
    如ARM11的PB11MPCore,CPU的启动地址是0x0,如果配置为NOR Flash启动,则可将NORFlash的原本地址0x400000000x43FFFFFF映射到0x00x3FFFFFFF,这样就相当于从NORFlash启动,这种方式是经常用的方式。
    由于NOR Flash原本内存空间映射到地址0x0了,导致地址0x0对应的内存没法使用,因此启动后需将映射取消,这就是取消地址映射。需要有按地址随机存储器的支持,即将存储启动代码的存储器的地址映射到启动地址。

RTOS映像文件的存储介质

RTOS这类操作系统一般比较小,存储介质选择余地有很多,可以放在ROM中,也可以放在NAND Flash中,无论放在哪里,只要BootLoader能找到RTOS映像文件,再将其复制到SDRAM就可以了。所以关键是看BootLoader是否强大,对于强大的BootLoader,其实RTOS都可以放在主机上,然后BootLoader可以通过网络将RTOS下载到SDRAM上,再从SDRAM上启动。

对于BootLoader和内核链在一起的RTOS,操作系统内核是跟BootLoader一起存储在一种存储介质中的。

相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习