首页 理论教育 常见嵌入式操作系统加载方式

常见嵌入式操作系统加载方式

时间:2023-10-21 理论教育 版权反馈
【摘要】:本节对嵌入式操作系统的加载方式进行简单的描述。之所以对嵌入式操作系统的加载方式进行描述,是为了让读者更好地了解常见的嵌入式系统的启动过程,以便根据实际需要,把Hello China移植到特定的目标系统上。上述功能完成之后,嵌入式系统的执行环境已经准备完毕,进入操作系统初始化阶段。但这种方式需要嵌入式系统配置较多的RAM存储器,因为操作系统和应用程序的代码直接在RAM中执行。

常见嵌入式操作系统加载方式

本节对嵌入式操作系统的加载方式进行简单的描述。之所以对嵌入式操作系统的加载方式进行描述,是为了让读者更好地了解常见的嵌入式系统的启动过程,以便根据实际需要,把Hello China移植到特定的目标系统上。下面介绍三种方式。

1.从Flash直接加载

这种加载方式下,嵌入式操作系统映像和应用程序映像,都存放在Flash当中。在编译的时候,操作系统和应用程序映像的二进制模块被编译器分成了不同的节,包括TEXT节、DATA节、BSS节等。不同的节存放的内容不同,TEXT节存放了可执行代码,DATA节存放了已经初始化的全局变量,而BSS节是一个预留节,存放了未经初始化的全局变量等。

在这种加载方式下,嵌入式系统的启动过程如图3-2所示。

978-7-111-41444-5-Chapter03-14.jpg

图3-2 从Flash直接加载嵌入式系统

详细步骤为(每个步骤对应图中的一个数字标号):

(1)CPU复位完成,执行启动向量所在的第一条指令(位于Boot ROM内),这条指令往往是一条跳转指令,跳转到Boot ROM内的硬件初始化代码位置,执行必需的硬件初始化工作。

(2)硬件初始化代码完成CPU的初始化,比如设置CPU的段寄存器、堆栈指针等,以及其他硬件的初始化。

(3)完成硬件的初始化功能后,会通过一条跳转指令(或函数调用指令),跳转到Flash存储器的特定位置开始执行。这个位置,一定是代码段(TEXT段)中的一个特定位置。

(4)把Flash中DATA节代码复制到RAM中。

(5)完成DATA节的复制后,Flash中的代码会根据BSS节的大小,在RAM中预留相应的内存空间,留给未初始化变量使用。

上述功能完成之后,嵌入式系统的执行环境已经准备完毕,进入操作系统初始化阶段。

需要注意的是,DATA节的搬迁和BSS节的预留工作也可能由Boot ROM完成,即Boot ROM中的硬件初始化代码执行完后,会通过一些内存搬移指令,把Flash中的DATA节搬移到RAM中,然后再根据BSS节的大小,预留BSS空间。这些工作完成之后,就可通过一条跳转指令,跳转到TEXT节的某个位置(一般是操作系统的入口函数)开始执行。这种情况下,Boot ROM中的代码需要知道DATA节和BSS节的详细信息(大小、起始地址等)。

在这种加载方式下,所有的执行指令都是从Flash中读取的,RAM中只是存放了数据和堆栈。这种启动方式可以节约物理内存空间,因为不需要专门为代码预留内存空间,一般应用在内存数量受到限制的系统中。这种加载方式有以下缺点。

(1)由于代码直接在Flash中执行,一般情况下对Flash的访问速度会比对RAM的访问要慢很多,因此性能会受到影响。若CPU本身携带了较大数量的代码Cache,则这个问题会得到一定程度的缓解。

(2)代码直接从Flash中运行,而一般情况下,Flash是只读的,因此无法实现代码的自我修改功能(即动态修改代码),这样不利于代码级的调试。

(3)在对操作系统核心和应用程序代码进行编译的时候,必须指定TEXT节、DATA节和BSS节的起始地址,这个地址应该与它在Flash和RAM中的最终位置相同。因此,会给开发带来一定的困难。

总之,这种加载方式在一些性能要求不是太关键、硬件配置受到限制的系统中,被大量地采用。Internet发展初期的一些低端路由器经常采用这种方式。

2.从RAM中加载

与从Flash直接加载方式不同的是,这种方式下,代码和数据都被加载到RAM中,从RAM中运行。这样从Flash直接运行的一些弊端就可以消除了。这种方式下,加载过程如图3-3所示。

详细步骤为(每个步骤对应图中的一个数字标号):

(1)CPU复位完成,执行启动向量所在的第一条指令(位于Boot ROM内)。这条指令往往是一条跳转指令,跳转到Boot ROM内的硬件初始化代码位置,执行必需的硬件初始化工作。

978-7-111-41444-5-Chapter03-15.jpg(www.xing528.com)

图3-3 RAM加载过程

(2)硬件初始化代码完成CPU的初始化,比如设置CPU的段寄存器、堆栈指针等,以及其他硬件的初始化。

(3)位于Boot ROM中的代码,把位于Flash中的操作系统和应用程序的TEXT节(代码节)从Flash中搬移到RAM中。这个过程,需要Boot ROM内的搬移代码预先知道TEXT节的起始地址和大小,这可以通过在操作系统映像的开始处(该位置往往是固定的)设置一个数据结构,来指明这些节的大小和起始位置,以及目标位置等。这样在搬移的时候,Boot ROM中的代码就可以先从这个固定位置获得节的信息,然后根据这些信息来完成搬移工作。

(4)与第三步类似,Boot ROM中的代码把操作系统和应用程序映像的DATA节搬移到RAM中。

(5)Boot ROM中的启动代码完成BSS节的RAM空间预留。

(6)完成上述所有动作之后,Boot ROM中的代码通过一条跳转指令跳转到RAM中操作系统的入口点,正式启动操作系统。

这种启动方式是一种比较常见的启动方式,简便易行,而且克服了直接从Flash中运行代码的一些弊端。但这种方式需要嵌入式系统配置较多的RAM存储器,因为操作系统和应用程序的代码直接在RAM中执行。

3.从文件系统加载运行

在上面介绍的两种启动方式中,操作系统和应用程序的二进制映像存放在Flash当中,而Flash直接映射到CPU的可寻址空间,因此在加载的时候,直接通过访存指令就可以完成,无需额外的设备驱动程序。但这种方式需要系统配置较多的Flash存储器,这在操作系统映像很大的情况下,矛盾尤其突出。而下面介绍的方式是从外部存储器加载操作系统和应用程序映像的,可以解决该问题。

这种方式与从Flash加载方式的区别是,操作系统映像和应用程序映像是存放在外部存储器(如IDE接口硬盘)中的。而对于外部存储器的访问所需要的驱动程序,则存放在Boot ROM中。这种方式的加载过程如图3-4所示。

978-7-111-41444-5-Chapter03-16.jpg

图3-4 从文件系统加载运行过程

详细步骤为(每个步骤对应图中的一个数字标号):

(1)CPU复位完成,执行启动向量所在的第一条指令(位于Boot ROM内),这条指令往往是一条跳转指令,跳转到Boot ROM内的硬件初始化代码位置,执行必需的硬件初始化工作。

(2)硬件初始化代码完成CPU的初始化,比如设置CPU的段寄存器、堆栈指针等,以及其他硬件的初始化。

(3)Boot ROM中的引导代码通过外部设备的驱动程序读取外部存储器,把操作系统和应用程序的映像加载到内存(RAM)中。这个过程中,可以不区分TEXT节和DATA节,而作为统一的二进制映像进行加载。

(4)完成二进制映像的加载后,Boot ROM中的启动代码需要进一步为操作系统预留BSS空间。

(5)上述一切动作完成、操作系统运行的环境就绪后,Boot ROM中的代码通过一条转移指令(跳转或CALL),跳转到操作系统的入口点,这样后续系统的运行就完全在操作系统的控制下进行了。

这种加载方式把操作系统和应用程序的映像都搬移到了外部存储介质上,不但可以节约Flash存储器,而且可以适应大容量的操作系统映像的情况。另外,由于引入了外部存储介质,嵌入式系统运行过程中产生的一些状态数据,比如告警、日志等信息,就可以存储在大容量的外部存储介质上,这样十分便于问题的定位。

但这种方式实现起来相对复杂,需要额外的存储介质访问接口电路(如IDE接口电路),而且需要软件实现针对这些外部存储介质的驱动程序,可能会大大延长开发周期。这种模型,一般应用到一些大型的嵌入式系统设计上,比如,位于Internet核心位置的核心路由器(GSR或TSR),就可能需要采用这种方式进行设计。

这种设计方式的另一个优点就是可以在线升级(系统运行过程中,对操作系统和应用程序软件进行升级)。实际上,从RAM中运行代码的方式也可以实现在线升级,但采用外部存储介质的在线升级,会更完善,更利于使用。比如,有的情况下,可能为不同的应用定制不同的软件和嵌入式操作系统,并编译成不同的模块,这些模块都存放在外部存储器上。在嵌入式设备安装完成后,可以根据需要,选择一种特定的功能进行加载,这时候,就可以通过修改位于外部存储器上的系统配置文件来告诉系统,默认情况下加载哪个模块(或版本)。

实际上,PC上的操作系统就是这样一种系统。PC使用的操作系统,一般位于外部存储介质,比如软盘或硬盘上,PC启动的时候,从这些外部存储介质上加载操作系统。从这点上来说,PC本身就是一个复杂的嵌入式系统,而且很有典型意义,在嵌入式开发过程中遇到的普遍问题,都可以在PC上模拟。因此,对于嵌入式开发入门者来说,在PC上模拟嵌入式开发环境,以达到学习的目的,是十分可行的。但在嵌入式开发中遇到的一些专业问题,比如特定硬件芯片(如网络处理器等)的初始化和应用等,则在PC上可能无法模拟。但有了嵌入式开发的基本概念和技能,转而从事这类更专业的开发,所需要的仅仅是一个很短的学习周期而已。

除了上述几种加载方式,在嵌入式开发领域中,还有另外的一些加载方式,比如从串口(COM接口)加载、从以太网接口(Ethernet接口)加载等,这些加载方式与从外部存储设备加载类似,无非需要Boot ROM额外实现一个驱动程序来完成这些设备数据的读取,在此不进行详细描述。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈