《VXWORKS设备驱动开发详解》作者:华清远见第3章VxWorks操作系统启动过程详解VxWorksVxWorksbootromVxWorksBSP专业始于专注卓识源于远见 ‐ 2 ‐VxWorks操作系统启动3.1.1VxWorks基本启动方式按VxWorks内核的下载形式,VxWorks启动总体上分为两种方式:下载型和ROM型。下载型启动方式:bootrom+VxWorks。此时bootrom被烧入ROM中,而VxWorks内核映像通过串口或者网口下载到系统RAM中。ROM型启动方式:VxWorks直接从ROM中运行,不借助于bootrom引导程序。此时VxWorks内核映像被烧入ROM中,无bootrom程序。对于不同的启动方式,VxWorks操作系统内核映像的组成也略有不同。bootrom引导程序一般称为VxWorksbootImage。该程序由如下文件创建而成:romInit.s、bootInit.c、sysALib.s、sysLib.c、bootConfig.c、设备驱动程序。bootromsysALib.sROMVxWorksVxWorks内核映像一般被称为VxWorksApplicationImage。VxWorks内核映像是系统启动后实际运行的程序(操作系统本身)。对于下载形式的VxWorks内核映像,由于需要对硬件环境进行重新初始化(即不依赖于romInit函数所做的初始化工作),所以昀先需要运行sysInit函数进行重新初始化,这些初始化工作与romInit函数基本相同,但是不再需要对内存控制器进行重新初始化,这是sysInit区别于romInit函数之处。sysInit昀后跳转到usrInit函数。而对于ROM方式直接运行的VxWorks内核映像,由于romInit.s函数此时是作为内核映像的一部分,所以就省去了对sysInit函数的调用。下载型和ROM型在VxWorks内核文件的构成上有一些差别。下载形式的VxWorks内核映像组成:sysALib.s、sysLib.c、usrConfig.c、设备驱动程序文件。ROM形式的VxWorks内核映像组成:romInit.s、bootInit.c、sysALib.s、sysLib.c、usrConfig.c、设备驱动程序文件。ROMVxWorkssysALib.ssysInitVxWorksdefs.bspMACH_DEPsysALib.oMACH_DEP=sysALib.osysLib.o$(MACH_EXTRA)$(ADDED_MODULES)3.1.2VxWorks操作系统内存布局在VxWorks操作系统过程中可能使用到的BootRom和VxWorks内核映像本身都可以存在两种方式:压缩的和非压缩的。1.非压缩形式 如果没有进行压缩,则只有一次重定位,即从ROM到RAM只存在一次代码复制过程,所有ROM中存储的代码都被一次性复制到RAM中。①对于BootRom而言,所有的代码被一次性复制到RAM_HIGH_ADRS指定地址处,如图3-1所示。专业始于专注卓识源于远见 ‐ 3 ‐非压缩代码ROM_BASE_ADRSROM_TEXT_ADRSROM_BASE_ADRS+ROM_SIZE用户预留非压缩代码栈保留LOCAL_MEM_LOCAL_ADRSRAM_LOW_ADRSSYS_MEM_BOTTOMRAM_HIGH_ADRSsysPhyMemTopsysMemTop一次性全部复制到RAM_HIGH_ADRS地址处_romInit_romInit3-1BootRomROMRAM②对于VxWorks_rom而言,所有的代码被一次性复制到RAM_LOW_ADRS指定地址处,如图3-2所示。2.压缩形式 如果有进行压缩,则代码复制过程将分为两次,一次是非压缩代码,另一次是压缩代码,且二者复制到内存不同的位置处。①对于BootRom而言,非压缩代码(romInit.s、bootInit.c)被直接复制到RAM_LOW_ADRS处;压缩代码复制到RAM_HIGH_ADRS处,并在复制过程中完成解压缩,如图3-3所示。非压缩代码ROM_BASE_ADRSROM_TEXT_ADRSROM_BASE_ADRS+ROM_SIZE用户预留非压缩代码栈保留LOCAL_MEM_LOCAL_ADRSRAM_LOW_ADRSSYS_MEM_BOTTOMsysPhyMemTopsysMemTop一次性全部复制到RAM_LOW_ADRS地址处_romInit_romInitVxworks内核代码3-2VxWorks_romROMRAM专业始于专注卓识源于远见 ‐ 4 ‐压缩代码非压缩代码ROM_BASE_ADRSROM_TEXT_ADRSbinArrayStartbinArrayEndROM_BASE_ADRS+ROM_SIZE用户预留压缩代码(已解压缩)非压缩代码栈保留LOCAL_MEM_LOCAL_ADRSRAM_LOW_ADRSSYS_MEM_BOTTOMRAM_HIGH_ADRSsysPhyMemTopsysMemTop_romInitusrInit第一次复制(非压缩代码复制)第二次复制(压缩代码解压缩复制)3-3BootRomROMRAM②对于VxWorks_rom而言,非压缩代码(romInit.s、bootInit.c)被直接复制到RAM_HIGH_ADRS处;压缩代码复制到RAM_LOW_ADRS处,并在复制过程中完成解压缩,如图3-4所示。压缩代码非压缩代码ROM_BASE_ADRSROM_TEXT_ADRSbinArrayStartbinArrayEndROM_BASE_ADRS+ROM_SIZE用户预留压缩代码(已解压缩)非压缩代码栈保留LOCAL_MEM_LOCAL_ADRSRAM_LOW_ADRSSYS_MEM_BOTTOMRAM_HIGH_ADRSsysPhyMemTopsysMemTop_romInitusrInit第一次复制(非压缩代码复制)第二次复制(压缩代码解压缩复制)3-4VxWorks_romROMRAM事实上,对于压缩版本,在进行编译时,进行了两次代码链接:一次是针对压缩代码的链接,另一次是将非压缩代码和压缩代码整合在一起时的链接。注意,在进行非压缩代码和压缩代码的整合时,压缩代码部分是作为数据进入整个映像的,所以不会对其进行重新链接。对压缩代码的链接,实际上是在代码被压缩之前完成的,完成代码的链接后,生成特定格式的目标文件(如ELF或者COFF),为了在解压缩后可以直接执行,首先必须将其转成二进制可执行文件,通过objcopy函数完成此项功能,此后对生成的二进制可执行文件调用deflate函数进行压缩,由于需要将压缩后的代码昀后整合到整个映像中,故压缩后的文件还需要通过binToAsm工具进行转换,转成一个汇编源文件,该文件将压缩后的二进制代码作为数据部分进行保存,从而避免在与非压缩代码昀后进行二次链接时被修改。专业始于专注卓识源于远见 ‐ 5 ‐两步链接过程中各自指定了不同的链接地址,对于压缩代码而言,其分为两种情况,对于BootRom,压缩代码被链接到了RAM_HIGH_ADRS地址处,而对于VxWorks_rom,则被链接到了RAM_LOW_ADRS地址处,在与非压缩代码进行整合链接时指定的链接地址(即_romInit函数地址)与压缩代码链接时指定的地址相对应:如果压缩代码为RAM_HIGH_ADRS,则昀后整合时就为RAM_LOW_ADRS;如果压缩代码为RAM_LOW_ADRS,则整合时就为RAM_HIGH_ADRS。3.1.3下载型启动方式概述下载形式的VxWorks启动方式需要bootrom引导程序,该程序将被烧录到开发板的ROM或者Flash中,在上电时,系统将自动跳转到ROM或者Flash起始地址处运行该bootrom引导程序,该引导程序进行必要的系统初始化,从而为下载VxWorks内核映像做准备,如通过网口下载时,则需要先调用网口驱动程序进行网口初始化。由于bootrom的主要工作是下载真正的VxWorks内核映像到系统RAM中,所以其进行的初始化工作也是为这一目的,在文件组织上,虽然从上文中可以看到其与VxWorks内核映像的文件组成非常相似,但其使用bootConfig.c文件,而VxWorks内核映像则使用usrConfig.c文件。这两个文件中虽然定义有相同的函数名(如usrInit、usrRoot),但在实现上存在很大的差异:bootConfig.c文件实现完成从某个服务器下载真正的VxWorks内核映像到系统RAM中(由变量RAM_LOW_ADRS指向的内存地址处),并跳转到sysInit函数(定义在sysALib.s文件中第一个且必须是第一个函数,该函数即被装载到变量RAM_LOW_ADRS指向的内存地址处)执行;usrConfig.c文件实现完成一个操作系统正常运行所需要的所有初始化工作。简言之,bootConfig.c文件完成VxWorks内核映像的下载,而usrConfig.c完成初始化VxWorks操作系统的所有工作。按bootrom执行方式的不同,bootrom文件存在如下三种文件类型。(1)bootrom.bin它为压缩bootrom文件形式,此种文件形式主要为解决开发板上ROM或者Flash的空间限制。注意:压缩并非对所有的文件进行压缩,而是除了romInit.s和bootInit.c文件的其他所有文件,因为解压缩程序必须是非压缩形式的。bootrom执行流程如下(以下采用“文件名:函数名:初始是否被压缩”形式进行说明)。①romInit.s:romInit:非压缩。romInit函数完成系统硬件环境下必要的初始化工作,如从系统角度禁止中断,初始化相关寄存器到可知状态,初始化内存控制器,初始化函数调用所需的栈,昀后跳转到romStart函数执行。②bootInit.c:romStart:非压缩。romStart函数主要完成如下任务:首先将romInit函数及其自身复制到RAM_LOW_ADRS变量指向的RAM区,以便从RAM执行。注意,此后在下载VxWorks内核映像时,内核映像也被下载到RAM_LOW_ADRS变量指向的内存处,所以这部分代码此后将被覆盖,同样,bootrom占用的所有其他内存昀后也将被VxWorks内核回收(如由RAM_HIGH_ADRS指向的内核空间)。将bootrom程序其他部分(压缩部分)从ROM区复制到RAM区(由RAM_HIGH_ADRS变量指向的内存地址处),并解压缩。对于coldboot(冷启动)方式,将其复制到RAM区清零。昀后跳转到usrInit(注意:是bootConfig.c文件中定义的)函数进行执行。③bootConfig.c:usrInit:压缩。usrInit函数此处主要进行外围硬件初始化,为下载VxWorks内核映像做初始准备,而后创建tUsrBoot进程调用usrRoot程序进一步完成驱动程序初始化工作,为下载VxWorks内核映像做进一步工作,昀后创建tBoot进程调用bootCmdLoop函数完成VxWorks的内核映像下载。在下载完成后,调转到下载起始地址处执行,此时下载型VxWorks内核入口函数sysInit将被调用执行,真正开始VxWorks操作系统的启动过程。昀终在usrConfig.c:usrRoot函数执行完毕后,VxWorks操作系统即完成启动,系统进入正常运行状态。函数执行流程如下:(采用“映像类型:文件名:函数名”形式)专业始于专注卓识源于远见 ‐ 6 ‐bootrom:romInit.s:romInit→bootrom:bootInit.c:romStart→bootrom:bootConfig.c:usrInit→bootrom:bootConfig.c:usrRoot→bootrom:bootConfig.c:bootCmdLoop→完成VxWorks内核映像下载,并跳转到VxWorks