分类:
2008-09-09 12:37:54
摘要 提出一种适用于系统的模块动态加载技术,设计实现简单,占用资源少,开销小,并且成功运用于DeltaOS.可提高系统的灵活性和扩属性.介招加载与动态链接的原理和应用情况,解释相关术语,描述基本设计思路:详细说明该技术的核心。即模块声明、调用库、两级重定位表,最后给出结论。
关键词 模块 动态加栽 系统DeltaOS
引 言
随着电子技术的飞速发展,嵌人式设备应用越来越广泛,复杂度也越来越高。这使得硬件和软件设计比例发生了很大变化,软件开发的比重越来越大。然而传统嵌入式开发过程中需要将应用与操作系统编译链接成一个整体,然后到目标机上运行。如果在调试过程中发现问题,需要重新编链接然后重复运行的过程。这样的开发流程周期长而且繁琐,已经越来越不适应快速市场化的需要。
为了适应多样化的嵌入式应用和加快嵌入式系统的开发过程,除了需要可靠的基础平台软件的支持,如带有文件系统、网络栈的RTOS和配套的集成开发环境,更重要的是需要可以动态扩展的系统平台。近年来,新一代的嵌入式操作系统已经开始使用动态扩展技术:将基本系统(包括操作系统以及其他共享功能调用库)和应用程序开发分开处理,支持模块更新和动态加载技术。很多主流的传统嵌入式操作系统厂商,如windRiver、Green HilIs、Lynxworks,都推出了面向航空航天、基础通信设备等领域的高可靠、高性能的RTOS版本,支持应用和系统组件的动态加载和更新;而在消费电子领域,相关的操作系统厂商,如symbian、Palm、Microsoft,更是积极推出了具有相应功能的操作系统,在新一代移动设备上得到了广泛应用。
为了成为可动态扩展系统平台,大部分嵌入式操作系统需要使用动态加载技术。总的来说,动态加载是指应用或者系统在运行过程中需要使用某模块的服务,于是通过一系列预定的动作将指定模块加载到系统中,让调用者继续顺利工作。它实现的关键就是加载与动态链接技术。因为加载和动态链接互相依赖,关系紧密,所以将两者放在一起进行讨论。
1 加载与动态链接机制
加载主要负责将模块程序从二级设备(比如硬盘或者Flash)搬移到指定内存空间,并且将模块交由系统加载器统一管理。
程序链接分为静态链接、加载时链接和运行时链接。静态链接就是将程序和它运行所需的全部库链接成一个执行文件。它的优点是可以独立运行、速度快,但是它链接生成的代码尺寸比较大。加载时链接是指程序在编译链接时不会把它用到的库链接到执行程序中,而是在它被加载器加载时才解析执行文件,依次把用到的库装载到系统中让其运行。它的优点是程序本身代码量减小,但运行时程序占的内存并没有减小,同时增加了加载器的工作量。动态链接是加载时链接的进一步发展,它是指将库的加载过程延迟到程序运行时执行。这种方式不会给程序引入额外的代码,也不会增加加载器的开销,只有当应用真正使用某库时才会加载该库,减少了不必要的空间占用。它的缺点是可能会有一些运行开销。
嵌入式系统中动态加载和普通的动态链接概念类似,但是嵌入式系统中的加载链接器有其自身的特点:它是交叉加载,主机端做一部分工作,比如程序的重定位,执行文件的解析等等;而目标机端相对简单,主要做模块搜索定位和空间分配,以及指定物理地址或者映射虚拟地址让其运行。一部分嵌入式系统不支持虚拟内存,应用和内核共享空间。当系统加载了多个应用到系统中时,一般需要使用overlap技术来解决内存空间有限的问题,即是当多个应用的运行地址空间冲突时,加载器会冻结当前暂时不运行的应用,让新加载的应用使用指定的地址空间,PairnOS中就采用了这样的设计。对于支持虚拟内存的嵌入式系统,加载器的工作被大大简化,每个应用都有可以运行在同样的虚拟的空间,不需要加载器为其重定位或使用overlap技术,因此提高了工作效率。Vxworks6.O,WinCE都使用了这种设计。两种方式在不同的领域都有比较多的应用。
文中提出的模块动态加载技术是基于支持MMU(Memory Management Unit)的32位嵌入式操作系统,采用了加载与动态链接技术。使用该技术构建的嵌人式系统面向高端市场,特别是对系统可靠性、性要求很高的领域。在DeltaOS新一代高可靠的版本HAR(High Available Reliable system)的研发过程中,即成功地实现了基于该设计的加载器LambdaLoader,达到了预期的性
能要求。
2 模块动态加载的设计
2.1 设计思路
首先定义一些概念:模块、目标程序、接口函数地址表和调用库(call Library)。
①模块,主要是指加载器加载的一个单位,并且这里模块的概念主要是强调它是为应用或者系统提供一系列服务的提供者。
②目标程序,是指模块的使用者。它可以是应用,也可以是另一个模块。
③接口函数地址表(文中也称之为模块重定位表),指在模块中有一个数组表,该数组表的内容是该模块对外提供的函数接口的地址。
④调用库,是供模块调用者链接使用的专有库。它与相关模块一一对应,将封装了的模块接口供目标程序使用。除此以外,它还有一个运行时才确定的模块重定位表地址指针和模块动态查找定位的代码。
如果在系统中要实现动态加载,首先需要一种模块定位机制,使得调用者能够在系统中动态定位需要的模块,其次是要能让模块与目标程序动态的关联在一起,协调工作。为了解决这些问题,需要一系列相关的设计:规定模块的声明方式;简化目标机端模块地址空间定位的工作;重定位表的机制等等。基于这样的设计,系统可以比较顺利地实现动态加载。模块动态加载的工作流程如图l所示。这里描述的主要是目标机端的工作。
2.2 模块的声明
模块首先要定义它的相关属性。这里使用模块声明文件来完成这个工作。模块声明文件中需要定义:模块名字、版本、对外提供的API接口。在系统编译模块程序后,会调用一系列的script代码。这些script会根据模块名字查找模块对应的模块声明文件,并根据该文件生成供模块调用者使用的调用库和与模块一起链接的附加库。
附加库包含系统后台通过调用script生成的接口函数地址表和模块注册函数。在每个模块的初始化函数中,会调用一个模块的注册函数(该函数主要工作是向系统注册模块的名字和接口函数地址表地址)。当模块被加载时,初始化函数会被系统调用,向系统注册模块信息,此后模块交由加载器统一管理。
[1]