RTOS的引导是指将操作系统装入内存并开始执行的过程。
时间限制主要包括:系统要求快速启动和系统启动后要求程序能实时运行。
空间限制主要包括:Flash等非易失性存储空间限制和RAM等易失性存储空间限制。
通常不可能同时满足两种要求,需根据具体情况进行折中处理,由此,RTOS的引导分为如下两种模式。
BootLoader是在RTOS内核运行之前执行的一段小程序,它将RTOS内核从外部存储介质复制到内存中,并让PC跳转到刚复制到内存的内核的首条指令。
在嵌入式系统中,BootLoader依赖于硬件,几乎不可能建立一个通用的BootLoader。不同的CPU体系结构都有不同的BootLoader,另外,BootLoader还依赖于具体的嵌入式板级设备的配置。
对于采用高性能RAM的系统,出于成本因素,RAM空间有一定限制,此时一般采用Bootloader引导方式:由Loader程序把RTOS内核中的数据段复制到RAM中,代码段在Flash中运行。
因为代码段在低速的Flash中运行,该方式在节省空间的同时,牺牲了时间。这种引导方式适合于硬件成本低、运行速度相对较慢的嵌入式系统,但是启动时间却较快。
如果RAM空间没有限制,足够程序运行时,由Loader程序把RTOS内核从非易失性存储介质全部复制到RAM中,对于某些压缩的内核,复制后还需要解压。此时,不能满足对启动速度要求特别高的系统,但是系统的运行速度却能得到保障。
对于实时性要求较高的系统,通常要求系统能够快速启动。由于将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可以拆分成两部分:一个是Boot,另一个是Loader。
从上面可以看出,在PC上,BIOS满足上面的特性,因为PC启动时就是从BIOS的地址处启动的,然后BIOS的代码读取硬盘的第一扇区的数据,即引导程序,然后将控制权交给引导程序,再由引导程序加载操作系统内核代码运行。
而在嵌入式系统中,Vivi、Uboot等就是BootLoader,这些程序都是开机时就启动,启动后,会从NAND Flash或SD卡等存储设备中奖RTOS内核程序代码复制到SDRAM中,然后执行内核代码。
aCoral的BootLoader就是start.s,代码很少。
Vivi,Uboot代码量大的原因主要是:它们都支持多种嵌入式平台,都可以看成是一个通用的BootLoader,除了提供上面启动、RTOS加载两个功能外,它们还支持更多功能,如支持各种命令,这些命令主要分为以下两大类:
有些BootLoader,如ARM公司的Bootmonitor还支持文件系统,能以文件系统的方式管理NANDFlash、SDCARD上的数据。
有了上面两大类操作的支持后,BootLoader不再是纯粹的BootLoader了,它已具备了一些操作系统的功能,只是不支持操作系统支持的任务管理、调度、切换等功能。
其实像Vivi,Uboot这些BootLoader在电子产品很少用到,因为电子产品强调性能、成本,且不愿意用户有太大的修改权利,且Vivi,Uboot尺寸很大,启动时间长,严重影响系统的性能和成本,因此商用后,BootLoader肯定越小越好。
真正在商用产品中,BootLoader这部分代码直接写到操作系统,这个简单的BootLoader是和内核一起编译,并且通过链接器链接在一起的。
为什么会出现这么多种类呢?这是价格和用户需求平衡的结果。
例如,大家知道程序最后运行必须要有随机可读写存储器来存储变量,且速度要快,这导致了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都是需要控制器才能访问数据的,控制器又需要驱动程序,那如何做到从这些地方启动呢?
其实,解决方法和上面讨论的一样,就是必须有一个复制过程,该复制过程可以有三种方式,硬件方式、软件方式、内存映射。
RTOS这类操作系统一般比较小,存储介质选择余地有很多,可以放在ROM中,也可以放在NAND Flash中,无论放在哪里,只要BootLoader能找到RTOS映像文件,再将其复制到SDRAM就可以了。所以关键是看BootLoader是否强大,对于强大的BootLoader,其实RTOS都可以放在主机上,然后BootLoader可以通过网络将RTOS下载到SDRAM上,再从SDRAM上启动。
对于BootLoader和内核链在一起的RTOS,操作系统内核是跟BootLoader一起存储在一种存储介质中的。