1 VxWorks映象的组成
VxWorks映象由文本段(.text/.code),数据段(.data)和BSS段(.bss)组成。文本段相当于代码段,是由一些指令组成的;数据段就是由一些初始化过的全局和静态变量组成;BSS段也是由全局变量和静态变量组成,只不过他们都没有经过初始化。
2 VxWorks映象的类型(1).VxWorks(Loadable binary VxWorks image)
RAM based VxWorks image, linked to RAM_LOW_ADRS. It is loaded into RAM via some external program such as abootROM.This is the default development image.
(2).vxWorks_rom(Uncompressed ROMable binary VxWorks image)
RAM based image that starts in ROM. The ROM startup code copies the entireimage to RAM and then jumps to it. This image generally has a slower startup time, but faster execution time, than vxWorks_romResident.
(3).vxWorks_romCompress(compressed ROMable binary VxWorks image)
Compressed RAM based image thatstartsin ROM. This image can fit almost twice the code as other ROM images.But it has the slowest boot time, since the image must be uncompressed. The run-time speed is the same as
for vxWorks_rom.
(4).vxWorks_romResident(ROM-resident version binary VxWorks image)
ROM resident image. The program textremains in ROM, only the data iscopied to RAM. This image has the fastest boot time and uses the least amount of RAM, but runsslower on boards with slow
ROM access.
相关后缀的含义同bootrom。
我们可将VxWorks Image的文件类型划分为两类三种:
A.加载型映象(VxWorks类型)
(1)Loadable Image是包含用户程序的VxWorks操作系统映象,其不具备引导功能,需要借助bootloader引导程序通过网口或串口下载到RAM中。bootloader在此扮演了“搬运工”的角 {MOD}。
B.可引导型映象
可引导型(Bootable)映象包含含有用户程序的VxWorks操作系统映象,并包括完整的引导代码,可以在系统上电后自动完成自身的引导。我们在前面已经分析过,该类映像往往由bootstrap program(romInit.s+romStart.c)和紧随其后的为vxWorks映像(可能被压缩)组成。
(2)ROM-based Image(压缩/没有压缩):即将Image直接烧入ROM/flash,运行时将Image拷入(如果压缩则需解压)RAM中运行。
(3)ROM-resident Image:Image的指令部分驻留在ROM中运行,仅将数据段部分拷入RAM。
注意,以上三种映象都是包含完整VxWorks操作系统的映象,其中后两种可以直接启动并运行起来,但是第一种不行,它必须借助另一个叫做Boot Image的映象(可以在Tornado中的build->build bootrom中生成)才能运行起来,也就是利用Boot Image引导起来后通过网口或串口下载真正包含VxWorks的Loadable Image,然后才能运行起来。也即Boot Image往往和Loadable Image结合起来使用。
现在看来一共有四种映象文件,让我们看看它们的组成:
(1)Boot Image:包含一段起始引导程序(BootStrap Program)和一段ROM引导程序(ROM Boot Program)。
(2)Loadable Image:由操作系统VxWorks和应用组成的映象。
(3)ROM-based Image(压缩/没有压缩):包含一段叫做BootStrap Program的程序+Loadable Image(即有操作系统VxWorks和应用组成的映象)。
(4)ROM-Resident Image:同上。
通过上面我们可以看出,ROM-based Image,ROM-Resident Image,Boot Image三种映象都包含一段叫做BootStrap Program的程序,可以把ROM引导程序的代码段和数据段拷贝到RAM中。同时,它具有启动功能。
上一节主要是从映象的分类和各种映象的大致加载流程上看VxWorks的启动过程,这一节让我们从函数级看一下VxWorks的启动过程。
1 BootImage+LoadableImage
VxWorks借鉴了传统PC操作系统的引导原理,其将整个引导过程分为两个阶段:
1.1 BOOTROM启动
起始引导程序(BootStrap Program)驻留在ROM中,主要包含:
(1)汇编级的硬件初始化程序romInit.s,用于系统的基本初始化,设置一些重要寄存器的初始值,进行存储器的映射
(2)搬移程序bootInit.c,将ROM引导程序拷贝至RAM的高端地址RAM_HIGH_ADRS,然后跳转到此处执行ROM引导程序。
ROM引导程序运行,将可加载的VxWorks映象下载到内存的指定地址RAM_LOW_ADRS处。
1.2 启动VxWorks内核
下面是具体的流程图:
图五
其中第一阶段的执行流程使用的是上图的左边的源文件中的那些函数(romInit->romStart->usrInit->sysHwinit->usrKernelinit->usrRoot);第二阶段执行流程使用的是上图中右边源文件中的那些函数(sysInit->usrInit->sysHwinit->usrKernelinit->usrRoot->usrAppInit)。下面具体解释:
Stage 1:
(1)romInit.s : romInit() /*entry point for VxWorks in ROM*/
系统上电之后,首先调用的函数就是romInit(),其主要完成两个操作:将CPU设置为正确的工作状态,包括各个寄存器的值以及CPU的工作模式;初始化系统内存并建立堆栈。由于需要设置CPU模式,所以这里的代码必须由汇编代码完成,并且汇编也是建立堆栈的唯一选择。
• 禁止中断,避免陷入不确定混乱状态。
• 清除cache。
• 初始化CPU基本寄存器,调用SDRAM初始化函数初始化UPM。
• 初始化系统堆栈,在内存中建立起堆栈后,系统就具备了高级语言的执行条件。后面的代码可以用C实现。
• 把启动类型(冷启动/热启动)放在堆栈上。
• 直接跳转到bootInit.c : romStart()
(2)bootInit.c : romStart()/*generic ROM initialization*/
这是VxWorks中所执行的第一段C语言代码,但仍在ROM中执行。
• 把ROMBoot Program的代码段和数据段从ROM复制到RAM中。
• 完成程序映象的解压缩(如果映象是压缩版本的)。
• 跳转到bootConfig.c: usrInit()开始执行ROM引导程序。
从这里开始,可引导型映象和加载型映象走上了相同的初始化道路。
(3)bootConfig.c : usrInit()
对于bootrom_uncmp和bootrom_res,在romStart()中直接跳转到usrInit()。对于压缩的bootrom,romStart()跳转到解压缩点,而bootConfig.c中的第一个函数为compressedEntry(),故压缩型bootrom解压后将跳转到compressedEntry()入口处,紧接着调用usrInit()。至于为什么压缩的bootrom需要compressedEntry这个桩函数(Stub
Routine),详情参考后文《VxWorks/MIPS运行期的gp重定位》。 /* compressedEntry - compressed entry point after decompression。
* This routine is the entry point after the bootroms decompress, if
* compression is utilized. This routine must be the first item of the
* text segment of this file.*/
• VxWorks中第一个在RAM中执行的函数。执行操作系统内核所必须的初始化程序。
• Cache程序库的初始化。
• 清零系统的BSS段。
• 初始化中断向量表。
• 使硬件工作在一个“安静”的状态,尽量不产生各种中断或者异常。
• 调用sysHwInit()初始化硬件。
• 调用usrKernelInit()初始化内核的必要组件。
• 调用KernelInit(),初始化VxWorks内核并产生usrRoot根任务。
• 在usrRoot根任务中解析Bootline,产生bootCmdLoop任务,用于启动、加载VxWorks映象。
此时,调试超级终端会有如下打印信息(printBootLogo()):
VxWorks System BootCopyright 1984-1998 Wind River Systems, Inc.CPU: MPC860Version: 5.4BSP version: 1.2/0Creation date: Aug 22002, 09:19:47Press any key to stopauto-boot... 3
接着,将调用自动引导程序autoboot(timeout),在指定时间timeout内,按任意键可停止自动启动,修改启动行参数(read and execute the ROM commands)。下一步将调用bootload()将指定主机目录下的VxWorks映象下载到目标板的RAM地址RAM_LOW_ADRS处,并跳转(go)到此处执行指令代码,启动VxWorks操作系统。
[VxWorks Boot]: pboot device : cpmunit number : 0processor number : 0host name : Michelfile name : c:/ftpRoot/vxWorksinet on ethernet (e) :168.2.7.27:ffffff00host inet (h) : 168.2.7.10user (u) : targetPasswd(pw) : targetflags (f) : 0x0―――――――――――――――――――――――――――[VxWorks Boot]: @boot device : cpmunit number : 0processor number : 0host name : Michelfile name : c:/ftpRoot/vxWorksinet on ethernet (e) :168.2.7.27:ffffff00host inet (h) : 168.2.7.10user (u) : targetPasswd(pw) : targetflags (f) : 0x0Attached TCP/IPinterface to cpm0.Attaching networkinterface lo0... done.Stage 2:
(1)bootConfig.c :bootLoad()
加载VxWorks映象,并跳转到它的加载地址,具体流程如下。
usrBootLineInit()中strcpy (BOOT_LINE_ADRS,DEFAULT_BOOT_LINE);从FLASH中读出DEFAULT_BOOT_LINE配置的引导方式及映象文件。
bootload()->usrBootLineCrack (BOOT_LINE_ADRS,¶ms)获取BOOT_PARAMS,通过params.bootDev类型来决定从硬盘、软盘、闪存加载或通过网口、串口下载VxWorks映象。
bootLoad (BOOT_LINE_ADRS, &entry);
{
scsiLoad();/* loada vxWorks image from a local SCSI disk */fdLoad(); /* loada vxWorks image from a local floppy disk */ideLoad();/* loada vxWorks image from a local IDE disk */ataLoad();/* loada vxWorks image from a local ATA disk */pcmciaLoad();/* loada vxWorks image from a PCMCIA disk device */tffsLoad();/* loada vxWorks image from a TFFS Flash disk */tsfsLoad();/* loada vxWorks image from a Target Server File System (TSFS) */netLoad();/*downLoad a file from a remote machine via the network */bootLoadModule();/*bootstrap load an object module into memory */