处理软件镜像并产生差异文件的制作方法

文档序号:6569315阅读:240来源:国知局
专利名称:处理软件镜像并产生差异文件的制作方法
相关申请
本申请要求2005年9月23日提交的美国临时专利申请第60/720,264号的优先权。
本申请是2003年6月20日提交的美国专利申请第10/600,978号的部分继续申请。
背景技术
在处理器、微处理器和/或处理单元上运行以提供特定功能的软件经常随着时间发生变化。这些变化可能是由于例如校正软件文件中的缺陷(bug)或错误、适应技术的发展、或者增加新的特征等的需要而产生的。特别是,在例如移动无线设备的移动处理设备上驻留的嵌入式软件组件经常包括需要校正的大量软件缺陷。软件包括人可读的美国信息交换标准码(ASCII,American Standard Code for Information Interchange)纯文本文件或者二进制代码形式的一个或多个文件。可以将软件文件划分为更小的单元,通常将其称为模块或者组件。
例如移动处理设备的基于便携式处理器的设备一般包括实时操作系统(RTOS,real-time operating system),其中将设备的所有软件组件链接为大的单个文件。此外,在这些移动无线设备中一般不设置文件系统支持。另外,需要使用例如无线电、红外或者串行链路的慢通信链路将该大的单个文件预先加载或者嵌入到设备中。
经由慢通信链路更新移动处理设备的大文件的障碍包括与对设备分发更新后的文件相关联的时间、带宽和成本。对移动处理设备分发大文件的问题的一个现有解决方案包括使用压缩。然而,虽然通常使用多个现有压缩算法,但是经常是即使压缩后的文件对于经由慢、昂贵、窄带通信链路下载到设备中也太大。
用于更新文件的另一个典型解决方案使用差异程序来产生修订后的文件如何与原始文件不同的描述。存在生成这种差异数据的可用差异程序。然而,与使用压缩类似,使用这些差异程序生成的差异文件有时候对于经由相关联的通信协议进行传送也太大。通过引用包含 在本说明书中提及的每一个出版物、专利和/或专利申请的全部内容通过引用包含于此,就像具体并且独立地指出每一个独立出版物和/或专利申请通过引用包含于此一样。



图1是示出根据实施例的文件求差和更新的框图。
图2是根据图1的实施例产生△(delta)文件的流程图。
图3是示出可执行文件的原始版本和新版本的框图。
图4是根据图1和图2的实施例对电子文件的差异版本进行预处理的流程图。
图5是根据图4的实施例对电子文件的差异版本的代码(文本)部分进行预处理的流程图。
图6是根据图5的实施例产生电子文件的原始版本的代码(文本)部分的新目标地址值的流程图。
图7是根据实施例的文件的原始版本和新版本的框图,其示出参考电子文件的原始版本的代码(文本)部分的新目标地址值的产生所描述的差异地址(和相应的记号)。
图8是根据图4的实施例对电子文件的原始版本和新版本的数据部分进行预处理的流程图。
图9是根据图8的实施例产生电子文件的原始版本的数据部分的新数据指针值的流程图。
图10是根据实施例的文件的原始版本和新版本的框图,其示出在产生电子文件的原始版本的新数据指针值时所使用的差异地址(和相应的记号)。
图11是根据图4的实施例的公共函数单元的线索(hint)合并的流程图。
图12是根据图4的实施例的公共数据单元的线索合并的流程图。
图13示出根据实施例的对产生一个或多个新代码块的预处理数据的后处理。
图14示出根据实施例的对增大一个或多个先前识别的公共代码块的大小同时还产生至少一个新代码块的预处理数据的后处理。
图15A~15F示出提供预处理和后处理方法的示例结果的图形表示。

具体实施例方式 本发明提供一种系统和方法,用于对文件的原始版本和新版本进行预处理,作为原始文件版本和新文件版本之间的差异文件产生的一部分。该预处理支持差异文件的大小的进一步减小。文件版本之间的软件/可执行变化包括被定义为源代码变化的初级变化/逻辑变化和次级变化。次级变化通常由初级变化引起,并且是由软件编译器/连接器所产生的。次级变化包括由初级变化引起并由软件编译器/连接器产生的地址变化、指针目标地址变化和地址偏移的变化。提供的预处理系统和方法在文件版本之间使用近似规则,以去除/减小次级变化并对相应的差异文件的信息中与这些变化的去除有关的信息进行编码。
这里,详细描述用于产生电子文件的两个版本之间的差异文件、这里称为文件求差的系统和方法。图1是示出根据实施例所提供的文件求差和更新的框图。文件求差和更新包括求差组件和更新组件。求差组件,这里称为文件差异产生器,根据电子文件的原始版本和新版本在第一基于处理器的系统或者计算机系统中产生差异文件。更新组件,这里称为更新产生器,使用差异文件和所保存的原始文件的拷贝在第二基于处理器的系统或者计算机系统上产生新文件的拷贝。
在下面的描述中,引入大量具体细节提供对本发明的实施例的全面理解以及对本发明的实施例的详细描述。然而,本领域技术人员将认识到可以不使用这些具体细节中的一个或多个或者使用其它组件、系统等等来实现本发明。另外,没有示出或者没有详细描述公知结构或者操作以避免混淆本发明的各个方面。
参考图1,第一计算机系统102和第二计算机系统104经由通信路径106进行通信。如在本领域中已知的,这些计算机系统102和104包括计算组件和设备操作的任意集合。计算机系统102和104还可以是更大的计算机系统或者网络内的组件或者子系统。
通信路径106包括用来在计算机系统102和104之间传递或者传送文件的任意介质。因此,该路径106包括无线连接、有线连接和混合无线/有线连接。通信路径106还包括到网络的耦合或者连接,网络包括局域网(LAN,local area network)、城域网(MAN,metropolitan area network)、广域网(WAN,wide area network)、专线网络(proprietary network)、局间(interoffice)网络或者后端(backend)网络、以及因特网。此外,通信路径106包括例如软盘、硬盘驱动和CD-ROM盘的可去除固定介质以及电话线、总线和电子邮件消息等。
第一通信系统102接收电子文件的原始或者旧版本110和新版本112。新文件112通常是原始文件110的更新后或者修订后的版本,但是不限于此。电子文件110和112包括包括动态链接库文件的软件文件、共享对象文件、嵌入式软件组件(EBSC,embedded software component)、固件文件、可执行文件、包括十六进制数据文件的数据文件、系统配置文件和包括个人使用数据的文件,但是不限于此。由于可以将任意类型的文件视为字节流,因此下文中根据上下文可能将文件描述为字节流。
如下面所描述的,文件差异产生器114的组件接收新文件112,将其与原始文件110相比较,并计算所比较的文件之间的差异。这些差异包括所比较的文件之间的字节级别的差异,但是不限于此。在比较过程中,文件差异产生器114产生差异文件116,这里称为△文件116。
实施例的文件差异产生器114耦合在主计算机系统102的组件之间,这些组件包括处理器、至少一个控制器、至少一个存储设备和至少一个总线中的至少一个,但是不限于此。实施例的文件差异产生器114的组件包括至少一个预处理子系统124和至少一个求差子系统134。预处理子系统124,也称为预处理器124,包括在至少一个预处理算法、程序或者例程的控制下运行的至少一个处理器。类似地,求差子系统134包括在至少一个求差算法、程序或者例程的控制下运行的至少一个处理器。
△文件116的内容提供新文件112和原始文件110之间的差异的有效表示。如在2002年5月13日提交的申请号为10/146,545、发明名称为“Byte-Level File Differencing and Updating Algorithms”的美国专利申请中所描述的,△文件116包括与表示相关联的文件的新或当前版本和文件的在前版本之间的差异的替换和/或插入操作的实际数据一起的元数据(meta-data)。文件差异产生器114在△文件116中用最少数量的字节和预先定义的格式或者协议提供始文件110和新文件112之间的任何差异,从而提供在空间上最优化的△文件。
经由通信路径106将△文件116传送或者发送到另一个处理系统104。在传送之前,可以使用本领域已知的压缩技术对△文件116进行压缩,但是不限于此。驻留在接收系统104上的更新产生器118使用△文件116与所保存的原始文件110H产生或者创建新文件112C的拷贝。然后,使用该新文件112C的拷贝来更新在客户设备上保持的作为修订或者更新目标的原始文件110H。在完成该更新处理时,现在存储在第二计算机系统上的新文件与在第一计算机系统102中接收到的新文件112是相同的。
原始文件和新文件之间的差异一般小于新文件,因此如果代替整个新文件发送并存储这些差异将节省相当的存储和发送。这对于经由例如无线或者蜂窝式连接的一般可能慢且昂贵的连接来进行更新的移动电子设备(客户设备)驻留程序尤其重要。减小了大小的△文件提供了大量改进,其中之一包括将△文件发送到客户设备所需的带宽减小;越小的文件意味着传送需要越小的带宽。此外,越小的文件需要越短的发送时间,因此降低了文件传送被中断的可能性,同时减少了接收文件中的发送错误。另外,经由非安全连接发送△文件比发送新软件镜像(image)更安全。所有这些改进提高了客户满意度。
图2是根据图1的实施例的△文件的产生的流程图。在块204,当在第一处理或者计算机系统中接收到新文件和原始文件时,操作开始。还接收到了与新文件和原始文件相对应的映射文件。映射文件是高级别的文本文件,其包括软件镜像的每一个符号的起始地址和大小,符号的示例包括函数变量和全局变量。编译器/连接器输出映射文件,还已知映射文件是日志文件、符号文件和/或列表文件。
在块206,在新文件和原始文件的内容之间进行预处理操作,以识别两个文件的内容中的公共片段和简单模式。通常,预处理使用识别出的公共片段和模式来减少/去除新文件和原始文件之间的次级变化。如下面所描述的,实施例的预处理包括减少和/或去除由与逻辑变化相关联的地址偏移所引起的原始文件和新文件之间的变化,但是不限于此。因此,该预处理减小了包括次级变化的文件的公共片段之间的差异,从而提高了差异计算的效率。
在预处理之后,在块208,计算新文件和修正后的原始文件之间的字节级别差异。对算出的差异进行编码和合并,在块210,通过遵循预先定义的编码格式来产生△文件。然后,在块212,如果可能,如在本领域中已知的对△文件进行优化以进一步减小文件大小,在块214,提供优化后的△文件作为输出。
如上所述,在新文件和原始文件的内容之间进行预处理操作,以识别两个文件的内容中的公共片段和简单模式。公共片段和简单模式的确认用于减小/去除次级变化,从而产生总体性能增益。
如上所述,系统和客户设备之间的电子文件的发送或者软件更新可能花费大量时间,尤其在经由低带宽信道进行时。一个示例是蜂窝式电话软件更新。通过蜂窝式无线耦合发送新软件版本和原始软件版本之间的字节级别的文件差异或者变化已成为典型的实践。因为可执行文件的新版本和原始版本之间的差异比其相应的源文件之间的差异更复杂,所以产生了相当长的传送时间。
出现新文件版本和原始文件版本之间的这些复杂的差异,部分是因为源文件的小的变化经常引起整个可执行文件的大幅度变化。作为示例,可执行文件中引入的变化包括两种主要类型的变化初级变化和次级变化。初级变化也称为逻辑变化,是由从原始文件中删除源代码行、向新文件中增加源代码行以及源代码行修正引起的源代码的变化。定义次级变化包括但不限于地址变化、指针目标地址变化和由初级变化引起的并且由软件编译器/连接器产生的地址偏移的变化。下面描述的预处理例程去除/减小了次级变化,并且对相应的△文件的信息中与这些变化的去除有关的信息进行编码。
对在可执行文件中引入的次级变化的分析从假设可执行文件包括代码(文本)部分和数据部分开始。图3是示出可执行文件的原始版本V1和新版本V2的框图300。原始版本V1和新版本V2二者包括代码(文本)部分310和320以及数据部分312和322。新版本V2与原始版本V1的不同之处在于新版本V2包括大小为0x500的附加新代码块302。新代码块302的存在引入了两种类型的次级变化。
第一种类型的次级变化出现在新版本V2的代码(文本)部分320中,并且产生具有不同分支偏移的分支指令BRANCH,也称为相对地址或者分支偏移,这是由在分支指令BRANCH的地址和目标指令地址TARGET之间增加了新代码块302引起的。在该示例中,目标指令地址是0x1000,分支指令地址是0x3000,在原始版本中产生0x2000(0x3000-0x1000)的分支偏移。在分支指令地址和目标指令地址之间增加新代码块(大小为0x500)使分支指令地址改变为0x3500(0x3000+0x500)。因此,新版本V2中的分支偏移改变为0x2500(0x3500-0x1000)。
第二种类型的次级变化出现在新版本V2的数据部分322,并且引起存储在数据指针POINTER中的值的变化或者存储相应的数据区域的绝对地址的数据指针值的变化。数据指针值的变化是由在代码(文本)部分中新代码302的增加引起的。在原始版本中的数据部分322之前的点处插入新代码302。因此,在原始版本中是0x8000的数据指针值改变为新版本中的0x8500(0x8000+0x500)。
随着软件开发变得越来越复杂,次级变化遍布在可执行文件中,在字节级别的文件求差的情况下考虑时,甚至到了次级变化在数量上超过初级变化的程度。下面描述的预处理例程使用文件的原始版本和新版本之间的关系来减少在△文件中进行编码的关于与次级变化有关的差异的信息的量。当进行字节级别求差和重建时,使用最少的信息可以达到级联计算的效果,从而减小了△文件的大小。
通常,实施例的预处理例程包括在使△文件的大小最小化时使用的至少一个近似例程和至少一个合并例程。根据文本(代码)和数据模型假设,近似例程用来减小/去除次级变化。合并例程也称为线索合并例程,在针对接收新版本的设备传送的最小成本级别对模型信息进行编码。如上所述,在设备中恢复新版本时使用模型信息,但是不限于此。
图4是根据图1和图2的实施例用于对电子版本的差异版本进行预处理的流程图206。在收到文件的新版本和原始版本时,在块402,从相关联的映射文件中提取公共函数单元和公共数据单元。如下面将参考图11详细描述的,在块404,合并公共函数单元以形成公共函数块。类似地,如下面将参考图12详细描述的,在块406,合并公共数据单元以形成公共数据块。然后,如下面将参考图5、6和7描述的,在块408,预处理系统的预处理例程对新文件和原始文件的代码(文本)部分进行预处理。如下面将参考图8、9和10描述的,在块410,预处理例程相继或者同时对新文件和原始文件的数据部分进行预处理。在块412,对公共函数块和公共数据块进行编码,输出原始文件修正后的版本,用于在进行字节级别文件求差时使用。
图5是根据图4的实施例用于对电子文件的差异版本的代码(文本)部分进行预处理的流程图408。通常,文件的代码(文本)部分由一个或多个函数单元或者块构成。实施例的对代码(文本)部分的预处理从块502开始识别原始文件和新文件的每一个函数单元的起始地址和结束地址,这里将原始文件的函数单元称为“原始函数单元”,将新文件的函数单元称为“新函数单元”。使用映射文件来识别函数单元的起始地址和结束地址,但是不限于此。
接下来,在块504,预处理器对每一个唯一函数单元分配唯一索引或者索引值。这种对唯一函数单元的索引值的分配支持对原始文件版本和新文件版本两者公共的函数单元的识别。因此,当在文件的原始版本和新版本中找到相同的函数单元时,对该函数分配公共索引值,但是本实施例不限于此。
作为示例,考虑包括原始函数单元F1、F2、F3和F4的原始文件版本和包括新函数单元F1、F2、F3和F5的新文件版本。如果预处理器使用索引值1、2、3、4和5分别对函数单元F1、F2、F3、F4和F5编写索引,则对于原始文件版本组成下面的表 索引startAddressV1endAddressV1 1 0x80400x8062 2 0x80620x8080 3 0x80860x809e 4 0x90560x90a8 类似地,对于新文件版本组成下面的表 索引 startAddressV1endAddressV1 1 0x80600x8082 2 0x80820x80a0 3 0x80a60x80be 5 0x90e60x9138 在这两个表中,通常将“startAddress”定义为相应的函数单元的起始地址;因此,“startAddressV1”是原始文件的函数单元的起始地址,“startAddressV2”是新文件的函数单元的起始地址。此外,通过将函数单元的大小加到函数单元的起始地址来产生endAddress(结束地址),因此 endAddress=startAddress+函数单元的大小, 但是本实施例不限于此。因此,将endAddressV1定义为原始文件的函数单元的结束地址,而将endAddressV2定义为新文件的函数单元的结束地址。这里,还将结束地址的这种定义应用于数据单元,但是不限于此。
然后,在块506,预处理器使用来自上述表的索引值、起始地址和结束地址的信息产生公共函数单元的HintTable(线索表)。HintTable包括组成在一个表中的公共函数单元的信息,包括原始文件版本(V1)的原始函数单元的索引值、起始地址和结束地址以及新文件版本(V2)的新函数单元的起始地址和结束地址。使用本领域已知的任意技术来排列HintTable的信息。使用上述信息,产生如下的实施例的HintTable 索引 startAddV1 endAddV1 startAddV2 endAddV2 1 0x8040 0x80620x8060 0x8082 2 0x8062 0x80800x8082 0x80a0 3 0x8086 0x809e0x80a6 0x80be 在块508,预处理器继续针对包括目标地址的原始函数单元的指令产生新目标地址值。图6是根据图5的实施例用于产生电子文件的原始版本的代码(文本)部分的新目标地址值的流程图508。
在描述新目标地址值的产生时,使用如下特定记号来描述与函数单元相关联的各种地址。这里,通常使用记号“addr”称谓指令地址;因此,“addrV1”是指原始函数单元中的指令地址,而“addrV2”是指新函数单元中的指令地址。这里,通常使用记号“targetAddr”称谓目标地址;因此,“targetAddrV1”是指原始函数单元中的目标地址,而“targetAddrV2”是指新函数单元中相应的目标地址。此外,这里使用记号“targetStartAddrV1”称谓包括targetAddrV1的原始函数单元的起始地址,“targetStartAddrV1”是包括targetAddrV1的原始函数单元的起始地址,这里使用记号“targetStartAddrV2”称谓包括targetAddrV2的新函数单元的起始地址。
图7是根据实施例的文件的原始版本V1和新版本V2的框图,其示出参考电子文件的原始版本的代码(文本)部分的新目标地址值的产生所描述的差异地址(和相应的记号)。第一公共函数单元CFU A和第二公共函数单元CFU B是原始版本V1和新版本V2公共的。原始版本V1的公共函数单元CFU B具有起始地址startAddrV1,并且包括位于指令地址addrV1的可计算指令cal_insA。下面描述可计算指令。原始版本V1的公共函数单元CFU A具有起始地址targetStartAddrV1,并且包括可计算指令cal_insA的目标地址targetAddrV1。
类似地,新版本V2的公共函数单元CFU B具有起始地址startAddrV2,并且包括位于指令地址addrV2的可计算指令cal_insB。新版本V2的公共函数单元CFU A具有起始地址targetStartAddrV2,并且包括可计算指令cal_insB的目标地址targetAddrV2。
返回到图6,在块602,新目标地址值的产生通过从原始文件版本的原始函数单元j中读取未经预处理的可计算指令开始,其中,j是计数器值,其被初始化为值一,随后每一次增加1,直到j=n为止,其中,n表示原始版本和新版本之间的公共函数单元的总数。
然后,在块604,如下产生或者计算可计算指令的当前目标地址。对于包括目标地址的任意指令,例如程序计数器相关的跳转指令和加载/存储指令,使用当前指令地址和相应的指令解码(instruction decoding)来计算目标地址。使用上述记号,当前目标地址计算变为 targetAddrV1=addrV1+decode(instruction) 或者可选地, decode(instruction)=targetAd由V1-addrV1。
如果值[targetAddrV1-addrV1]是已知的,则可以基于相应的编码方案如下计算指令 instruction=encode(targetAddrV1-addrV1)。
将这种类型的指令称为可计算指令,这里称为“cal_ins”,并且将值(targetAddrV1-addrV1)称为可计算指令的值或者“指令值”。
对于公共函数单元中的可计算指令,实施例的预处理器使用原始版本中的指令值以及原始函数单元起始地址和新函数单元起始地址来产生公共函数单元的新版本中的指令值。因此,使用上述记号,使用原始版本中的指令值(targetAddrV1-addrV1)、startAddrV1、targetStartAddrV1、startAddrV2和targetStartAddrV2来产生或者计算新版本中的指令值(targetAddrV2-addrV2)。
因此,在产生原始文件的目标地址(targetAddrV1)时,在块606,预处理器访问HintTable以识别k,即包括目标地址targetAddrV1的原始文件版本的函数单元。在块608,通过原始函数单元j和其目标函数单元k的标识符,预处理器从HintTable中读取startAddrV1、startAddrV2、targetStartAddrV1和targetStartAddrV2。
随后,在块610,预处理器现在产生cal_insB的指令值(targetAddrV2-addrV2)以代替cal_insA的指令值,如下。实施例的预处理器在至少两个假设下工作,但是不限于此。第一假设假设原始版本和新版本两者中具有相同大小的公共函数单元在原始版本和新版本两者之间具有相同的指令结构,其中,指令结构包括指令类型和指令顺序。第二假设假设对于满足第一假设的公共函数单元中的任意可计算指令,当可计算指令是函数调用或者可计算指令的目标地址落入也满足第一假设的公共函数单元中时,通常在原始版本和新版本两者之间保持两个不变量,如下 addrV1-startAddrV1=addrV2-startAddrV2 以及 targetAddrV1-targetStartAddrV1=targetAddrV2-targetStartAddrV2。
因此,根据这两个假设,在块610,预处理器产生cal_insA的新指令值(targetAddrV2-addrV2),如下 targetAddrV2-addrV2=(targetAddrV1-addrV1) +(targetStartAddrV2-targetStartAddrV1) -(startAddrV2-startAddrV1), 这里称为公式1。
在块612,使用cal_insA的新指令值,预处理器将cal_insA修正为instruction=encode(targetAddrV2-addrV2)。
然后,使用新指令代替原始版本的地址addrV1处的原始指令cal_insA。
在块614,预处理器随后判断原始函数单元j的任何可计算指令是否保持未经预处理。当可计算指令保持未经预处理时,预处理器返回,在块602从原始函数单元j中读取另一个或者可选地下一个未经预处理的可计算指令,如上面所描述的继续进行预处理。
当在块614判断为对原始函数单元j的所有可计算指令进行了预处理时,在块616,预处理器判断计数器j的值是否大于值n。判断为j不大于n表示存在未经预处理的公共函数单元,因此在块618将计数器j的值增加1,如上面所描述的继续进行预处理。
判断为j大于n表示已经对原始文件版本的所有函数单元进行了预处理。因此,在块620,预处理器输出包括新文件的近似版本的原始文件的修正版本。
如上面参考图4所描述的,除了根据文本(代码)模型假设去除次级变化之外,预处理器和近似例程还用来在块410根据数据模型假设去除次级变化。图8是根据图4的实施例用来对电子文件的原始版本和新版本的数据部分进行预处理的流程图410。通常,文件的数据部分由一个或者多个这里称为“数据单元”的全局变量单元或者块构成。
实施例的数据部分的预处理从在块802识别原始文件和新文件的每一个数据单元的起始地址和结束地址开始,这里将原始文件的数据单元称为“原始数据单元”,这里将新文件的数据单元称为“新数据单元”。使用映射文件来识别数据单元的起始地址和结束地址,但是不限于此。
接下来,在块804,预处理对每一个唯一数据单元分配唯一索引或者索引值。这种对唯一数据单元的索引值的分配支持对于原始文件版本和新文件版本两者公共的数据单元的识别。因此,当在文件的原始版本和新版本两者中找到相同的数据单元时,对该数据单元分配公共索引值,但是本实施例不限于此。对唯一数据单元分配索引值与上述对唯一函数单元分配索引值相同,但是不限于此。类似地,根据索引值组织的且包括每一个数据单元的起始地址和结束地址的表的产生与上述原始文件版本和新文件版本的函数单元的表的产生相同。然而,可选实施例可以使用任意数量的本领域已知的技术来分配索引值并产生表。
随后,在块806,预处理器使用来自上述表的索引值、起始地址和结束地址的信息来产生公共数据单元的HintTable。HintTable包括在一个表中组成的公共数据单元的信息,包括原始文件版本(V1)的原始数据单元的索引值、起始地址和结束地址以及新文件版本(V2)的新数据单元的起始地址和结束地址。HintTable的产生如上述参考公共函数单元的HintTable所描述的,但是在可选实施例中可以使用任意数量的本领域已知技术来产生HintTable。
在块808,预处理器继续产生原始版本的数据指针的新数据指针值。图9是根据图8的实施例用于产生电子文件的原始版本中的数据指针的新数据指针值的流程图808。
数据指针是指向数据单元中的某些数据的指令。这里描述新数据指针值的产生时所使用的记号如下。这里,通常使用记号“dataPointer”称谓包括数据指针的指令的地址;因此,“dataPointerV1”是指原始版本中的dataPointer,“dataPointerV2”是指新版本中的dataPointer。这里,使用记号“dataStartAddr”来称谓包括数据指针所指向的数据的数据单元的起始地址;因此,“dataStartAddrV1”是指原始版本中的dataStartAddr,“dataStartAddrV2”是指新版本中的dataStartAddr。
图10是根据实施例的文件的原始版本V1和新版本V2的框图,其示出在产生电子文件的原始版本的新数据指针值时所使用的差异地址(和相应的记号)。原始版本V1和新版本V2都包括代码(文本)片段和数据片段。数据片段包括原始文件版本V1和新文件版本V2两者公共的公共数据单元CDUA。原始版本V1包括代码(文本)片段中指向原始版本的公共数据单元CDU A中的某些数据的数据指针dataPointerV1,其中原始版本V1中的CDU A的起始地址是dataStartAddrV1。类似地,新版本V2包括代码(文本)片段中指向新版本V2的公共数据单元CDU A中的某些数据的数据指针dataPointerV2,其中原始版本V2中的CDU A的起始地址是dataStartAddrV2。dataStartAddr地址来自与文件的原始版本V1和新版本V2的软件镜像相关联的映射文件。
返回到图9,在块902通过识别原始版本中未经预处理的数据指针,开始新数据指针值的产生。如下面所描述的,实施例的预处理器使用原始版本中的指针值(dataPointerV1)以及包括dataPointerV1指向的数据的数据单元的起始地址(dataStartAddrV1)和其相应的新版本中的数据单元的起始地址(dataStartAddrV2)来产生新版本的数据指针值(dataPointerV2)。在块904这通过访问HintTable来识别k,即原始版本中包括dataPointerV1指向的数据的数据单元,来进行。在块906,预处理器使用数据单元k的标识符从HintTable中读取dataStartAddrV1和dataStartAddrV2。
随后,在块908,预处理器产生数据指针值(dataPointerV2)来代替dataPointerV1,如下。实施例的预处理器在关于数据单元的至少两个附加假设下工作,这里称为第三和第四假设,但是不限于此。第三假设假设原始版本和新版本两者中具有相同大小的公共数据单元在原始版本和新版本两者之间具有相同的数据结构,其中数据结构包括数据变量的类型、大小和顺序。第四假设假设对于满足第三假设的公共数据单元中的任意数据指针,通常在原始版本和新版本两者之间保持不变量,如下 dataPointerV1-dataStartAddrV1=dataPointerV2-dataStartAddrV2。因此,在块908,预处理器根据第三和第四假设产生新数据单元的新数据指针值(dataPointerV2),如下 dataPointerV2=dataPointerV1+(dataStartAddrV2-dataStartAddrV1),这里称为公式2。
在块910,使用数据指针值dataPointerV2,预处理器在原始版本中相应的地址处用dataPointerV2代替dataPointerV1。随后,在块912,预处理器判断是否有原始数据单元的数据指针保持未经处理。
当原始数据单元的数据指针保持未经处理时,预处理器返回,在块902从原始数据单元中读取另一个或者可选地下一个未经处理的数据指针,并且如上面所描述的继续进行预处理。当在决912进行判断为对原始数据单元的所有数据指针进行了预处理时,在块914,预处理器输出包括新文件的近似版本的原始文件的修正后的版本。
由于在确定不同文件版本之间的公共单元的相对位置时使用,如上述在HintTable中使用的,将公共函数单元和公共数据单元的起始地址和结束地址统称为“算法线索”或者“线索”。同样地,如上所述,将这些线索传送到接收差异或者△文件的客户设备,用于在从△文件和原始文件恢复新文件版本时使用。因为经由用来将△文件和其它信息传送到客户设备的同一低带宽信道进行线索的传送,所以实施例的预处理器进行线索合并来合并HintTable的公共函数单元和公共数据单元,而不影响预处理算法或者例程的性能。这种合并减小了包括线索的文件的大小,从而减少了传送到客户设备的信息的量。
返回到图4,在块404,使用以上描述的通过对代码(文本)部分进行预处理而产生的公共函数单元,预处理器在线索合并例程或者算法的控制下合并公共函数单元以形成公共函数块。图11是根据图4的实施例的公共函数单元的线索合并404的流程图。
类似地,在块406,预处理器使用以上描述的通过对数据部分进行预处理而产生的公共数据单元来合并公共数据单元以形成公共数据块。图12是根据图4的实施例的公共数据单元的线索合并406的流程图。下面,依次描述公共函数单元和公共数据单元的线索合并。
虽然为了清楚这里分开描述公共函数单元和公共数据单元的线索合并,但是实施例能够以任意顺序或者任意组合执行与合并相关联的操作。关于记号,如上所述,这里通常使用记号“startAddress”来称谓函数或者数据单元的起始地址;因此,“startAddress V1”是指原始函数或者数据单元的起始地址,而“startAddress V2”是指新函数或者数据单元的相应的起始地址。类似地,这里通常使用记号“endAddress”来称谓函数或者数据单元的结束地址;因此,“endAddress V1”是指原始函数或者数据单元的结束地址,而“endAddress V2”是指新函数或者数据单元的相应的结束地址。
如上面参考图5所描述的,产生包括组成在一个表中的公共函数单元的信息的公共函数单元的HintTable,包括原始文件版本V1的原始函数单元的索引值、起始地址和结束地址以及新文件版本V2的新函数单元的起始地址和结束地址。上面提供的HintTable用作描述公共函数单元的线索合并时的示例,但是本实施例不限于此 索引 startAddrV1 endAddrV1 startAddrV2 endAddrV2 1 0x8040 0x8062 0x80600x8082 2 0x8062 0x8080 0x80820x80a0 3 0x8086 0x809e 0x80a60x80be 参考图4和图11以及HintTable,公共函数单元的线索合并操作404从预处理器将HintTable的所有n个项标记为可用、设置计数器j=1开始并且在块1102从相关联的HintTable中读取函数单元j和单元)(j+1)的原始版本和新版本。在该示例中,单元j和单元(j+1)的值对应于线索表的索引值,其中j=1,2,...,(n-1),但是不限于此。此外,起初将j的值设置为等于1,随后随着线索合并404的进程和对公共单元进行处理,使用本领域已知的方法使j的值增大。因此,在块1102,读取与索引值1和2(j+1=1+1=2)相关联的公共函数单元的信息。
在块1104,预处理器判断公共函数单元j的原始版本V1和新版本V2的大小是否相等。通过在原始版本V1和新版本V2的起始地址和结束地址之间求差来进行该判断,如下 endAddrV1(j)-startAddrV1(j)=endAddrV2(j)-startAddrV2(j), 但是不限于此。当原始版本V1和新版本V2具有不同大小的文件时,操作进行到块1112,判断j的值是否小于量(n-1)。
当原始版本V1和新版本V2的大小相等时,在块1106,预处理器判断公共函数单元j的原始版本V1的结束地址是否与公共函数单元(j+1)的原始版本V1的起始地址相同,如下 endAddrV1(j)=startAddrV1(j+1), 但是不限于此。当公共函数单元j的原始版本V1的结束地址与公共函数单元(j+1)的原始版本V1的起始地址不同时,操作进行到块1112,判断j的值是否小于量(n-1)。
当公共函数单元j的原始版本V1的结束地址与公共函数单元(j+1)的原始版本V1的起始地址相同时,在块1108,预处理器判断公共函数单元j的新版本V2的结束地址是否与公共函数单元(j+1)的新版本V2的起始地址相同,如下 endAddrV2(j)=startAddrV2(j+1) 但是不限于此。当公共函数单元j的新版本V2的结束地址与公共函数单元(j+1)的新版本V2的起始地址不同时,操作进行到块1112,判断j的值是否小于量(n-1)。
当公共函数单元j的新版本V2的结束地址与公共函数单元(j+1)的新版本V2的起始地址相同时,在块1110,预处理器合并公共函数单元j和公共函数单元(j+1)的信息以形成公共函数块来代替单元(j+1)的项,然后将单元j的项标记为不可用。然后,操作进行到块1112,判断j的值是否小于量(n-1)。
在块1112,预处理器判断j的值是否小于量(n-1)。当j的值等于量(n-1)时,表示对所有函数单元进行了预处理,操作进行到块1116,作为公共函数块输出所有可用项,然后操作返回。当j的值小于量(n-1)时,表示剩余函数单元未经预处理,在块1114递增j的值,操作进行到块1102,读取与新的j值相对应的公共函数单元的信息。然后,如上面所描述的继续进行预处理。
下面,参考图11和HintTable描述涉及公共函数单元的线索合并的示例。操作从预处理器将所有三个项标记为可用并且从HintTable中读取函数单元1和2的原始版本和新版本开始。然后,预处理器判断公共函数单元1的原始版本V1和新版本V2的大小是否相等。通过在原始版本V1和新版本V2的起始地址和结束地址之间求差来进行该判断,如下 endAddrV1(1)-startAddrV1(1)=endAddrV2(1)-startAddrV2(1)。
代入来自HintTable的实际值,得到 (0x8062)-(0x8040)=(0x8082)-(0x8060)。
当原始版本V1和新版本V2的大小相等时,接下来,预处理器判断公共函数单元1的原始版本V1的结束地址是否与公共函数单元2的原始版本V1的起始地址相同,如下 endAddrV1(1)=startAddrV1(2)。
代入来自HintTable的实际值得到公共函数单元1的原始版本V1的结束地址与公共函数单元2的原始版本V1的起始地址相同的判断,如下 (0x8062)=(0x8062)。
因为公共函数单元1的原始版本V1的结束地址与公共函数单元2的原始版本V1的起始地址相同,接下来对公共函数单元1的新版本V2的结束地址是否与公共函数单元2的新版本V2的起始地址相同进行判断,如下 endAddrV2(1)=startAddrV2(2)。
代入来自HintTable的实际值得到公共函数单元1的新版本V2的结束地址与公共函数单元2的新版本V2的起始地址相同的判断,如下 (0x8082)=(0x8082) 响应于公共函数单元1的新版本V2的结束地址与公共函数单元2的新版本V2的起始地址相同的判断,预处理器合并公共函数单元1和公共函数单元2的信息以形成公共函数块,如下 索引 startAddrV1 endAddrV1 startAddrV2 endAddrV2 1 0x8040 0x8062 0x8060 0x8082不可用 2 0x8040 0x8080 0x8060 0x80a0可用 3 0x8086 0x809e 0x80a6 0x80be可用 继续该示例,接下来,预处理器从HintTable中读取函数单元2和3的原始版本和新版本。预处理器判断公共函数单元2的原始版本V1和新版本V2的大小是否相等。通过在原始版本V1和新版本V2的起始地址和结束地址之间求差来进行该判断,如下 endAddrV1(2)-startAddrV1(2)=endAddrV2(2)-startAddrV2(2)。
代入来自HintTable的实际值,得到 (0x8080)-(0x8040)=(0x80a0)-(0x8060), 这显示原始版本V1和新版本V2的大小相等。
接下来,预处理器判断公共函数单元2的原始版本V1的结束地址是否与公共函数单元3的原始版本V1的起始地址相同,如下 endAddrV1(2)=startAddrV1(3)。
代入来自HintTable的实际值得到公共函数单元2的原始版本V1的结束地址与公共函数单元3的原始版本V1的起始地址不同的判断,如下 (0x8080)不等于(0x8086)。
因为公共函数单元2的原始版本V1的结束地址与公共函数单元3的原始版本V1的起始地址不相同,所以操作返回,并且不合并公共函数单元2和3以形成公共函数块。
在合并公共函数单元之后,输出上述示例的HintTable的可用项如下 索引 startAddrV1 endAddrV1 startAddrV2 endAddrV2 2 0x8040 0x8080 0x8060 0x80a0 3 0x8086 0x809e 0x80a6 0x80be 实施例的预处理器以与上述对公共函数单元进行线索合并类似的方式对公共数据单元进行线索合并。参考图4和图12,公共数据单元的线索合并操作406从预处理器标记HintTable的所有n个项、设置计数器j=1开始并且在块1202从相关联的HintTable中读取数据单元j和(j+1)的原始版本和新版本。单元j和单元(j+1)的值对应于线索表的索引值,其中j=1,2,...,(n-1),但是不限于此。
在块1204,预处理器判断公共数据单元j的原始版本V1和新版本V2的大小是否相等。通过在原始版本V1和新版本V2的起始地址和结束地址之间求差来进行该判断,如下 endAddrV1(j)-startAddrV1(j)=endAddrV2(j)-startAddrV2(j), 但是不限于此。当原始版本V1和新版本V2具有不同大小的文件时,操作进行到块1212,判断j的值是否小于量(n-1)。
当原始版本V1和新版本V2的大小相等时,在块1206,预处理器判断公共数据单元j的原始版本V1的结束地址是否与公共数据单元(j+1)的原始版本V1的起始地址相同,如下 endAddrV1(j)=startAddrV1(j+1), 但是不限于此。当公共数据单元j的原始版本V1的结束地址与公共数据单元(j+1)的原始版本V1的起始地址不同时,操作进行到块1212,判断j的值是否小于量(n-1)。
当公共数据单元j的原始版本V1的结束地址与公共数据单元(j+1)的原始版本V1的起始地址相同时,在块1208,预处理器判断公共数据单元j的新版本V2的结束地址是否与公共数据单元(j+1)的新版本V2的起始地址相同,如下 endAddrV2(j)=startAddrV2(j+1), 但是不限于此。当公共数据单元j的新版本V2的结束地址与公共数据单元(j+1)的新版本V2的起始地址不同时,操作进行到块1212,判断j的值是否小于量(n-1)。
当公共数据单元j的新版本V2的结束地址与公共数据单元(j+1)的新版本V2的起始地址相同时,在块1210,预处理器合并公共数据单元j和公共数据单元(j+1)的信息以形成公共函数块来代替单元(j+1)的项,然后将单元j的项标记为不可用。然后,操作进行到块1212,判断j的值是否小于量(n-1)。
在块1212,预处理器判断j的值是否小于量(n-1)。当j的值等于量(n-1)时,表示对所有函数单元进行了预处理,操作进行到块1216,作为公共数据块输出HintTable中的可用项,然后操作返回。当j的值小于量(n-1)时,表示剩余函数单元未经预处理,在块1214递增j的值,操作进行到块1202,读取与新的j值相对应的公共数据单元的信息。然后,如上面所描述的继续进行预处理。
所描述的用于对电子文件的不同版本进行预处理的系统和方法可以应用于使用任意数量的指令架构的任意数量的处理和/或基于处理器的系统的软件和可执行文件。例如,如在D.Jagger和D.Seal的“ARMArchitecture Reference Manual”第二版中所描述的,可以在

架构中使用这里的系统和方法。

架构是基于16/32位嵌入式精简指令集计算机(RISC,Reduced Instruction Set Computer)核心的微处理器架构,其包含Thumb 16位指令集。在

架构中使用时,例如,上述引入的可计算指令包括ARM/Thumb指令集的“branch with link(BL)”和“branch with link and change mode to ARM/Thumb(BLX)”指令。此外,上面引入的数据指针包括ARM/Thumb指令集的DCD指令。
除了不使用来自编译器/连接器产生的映射文件、符号文件或者日志文件的符号信息而直接从可执行软件对产生公共代码/数据表的预处理之外,这里描述的实施例的处理还包括后处理。对经过预处理的数据的后处理包括对如上所述的公共代码块阵列的后处理。
图13示出根据实施例的产生一个或多个新代码块的后处理。图14示出根据实施例的增大一个或多个先前识别的公共代码块的大小同时还产生至少一个新代码块的后处理。如这里所描述的,提供系统和方法用于对文件的原始版本和新版本进行预处理,作为在原始文件版本和新文件版本之间的差异文件产生的一部分。作为预处理的一部分,各个实施例在文件版本之间使用近似规则来去除/减小次级变化并对相应的差异文件的信息中与这些变化的去除有关的信息进行编码。差异文件可以“over-the-air”(OTA,经由无线下载)发送,并且用于在不同的计算机系统上产生新文件版本的拷贝。
参考图13和14,左侧标为“旧镜像V1”的竖线表示电子文件的原始版本。右侧标为“新镜像V2”的竖线表示电子文件的新版本。每一个竖线表示例如字节序列的代码单元。在描述用于改进经过预处理的指令的性能的后处理系统和方法的实施例时使用旧镜像V1和新镜像V2,但是不限于此。
在实施例中,如下面所描述的,后处理检查指令特性以确定具有指定关系的指令对。例如,后处理检查指令特性以确定对齐的指令对。对于每一对对齐的指令,后处理产生一对目标地址。在集合了目标地址对之后,可以使用后处理算法来延伸一些现有(已知)公共代码块和/或创建新公共代码块。后处理算法解决在提高预处理成功率和保持小的预处理数据的总量之间的平衡。这是重要的考虑,因为容易通过引入大量新的预处理数据来提高预处理成功率,而这是不理想的。在一个或多个后处理算法改进了公共代码块之后,可以重新计算任意数据块,这改进了对具有数据指针的指令的预处理性能。这些指令包括但是不限于常见的ARM LDR指令。
这里描述的经过预处理的数据的后处理接收经过预处理的数据作为公共代码块的阵列。可以在一个或多个公共代码块中分析例如Thumb BL指令的可计算指令,以识别可以用于判断是否延伸和/或增加公共代码块的指令特性。例如,可以分析可计算指令来识别具有在镜像中但是不在已知公共代码块中的目标地址的指令。由于这时旧镜像和新镜像两者均可用,因此可以对在代码块中是否存在具有指定关系的指令例如对齐的指令进行判断。然后,可以部分基于指令的关系和/或起始地址和/或目标地址来进行关于是否增加和/或延伸的评价。基于对包括起始地址和目标地址的这种类型数据的收集,可以延伸现有或者已知公共代码块和/或产生新公共代码块。
实施例的后处理通过创建或者产生大小等于旧镜像中的字节数的两个整数阵列来收集数据。将所有整数都初始化为零,并且 int*backward,*forward。
如果地址“i”在旧镜像中并且不在已知代码块中,则backward[i]计算如果向前延伸在前的代码块以包括地址“i”则可以对多少例如BL指令的指令正确地进行预处理。Forward[i]计算如果向后延伸随后的代码块以包括地址“i”则可以对多少指令正确地进行预处理。后处理还创建addr_pair结构列表,其中这些结构具有所分配的等于旧镜像中的字节数的大约一半的大小,这应当足以处理指令。例如,由于对于Thumb BL指令的第一部分和第二部分相关位是不同的,因此应当在镜像中有不比镜像中的字节数的大约四分之一多的BL指令。变量跟踪存储在该列表中的addr_pair的数目,起初将该变量设置为零。
实施例的addr_pair结构包括如下的一对值 addr_pair*addrArray, 这些值表示旧镜像中的目标地址和新镜像中的目标地址,但是本实施例不限于此。当一对目标地址包括导致使用在前或者在后的代码块指令没有被正确预处理的特性时,将这一对目标地址增加到该列表中。通常,当尝试延伸已知代码块时,可以使用“backward(向后)”阵列和“forward(向前)”阵列,而当尝试创建新代码块时,可以使用addr_pair列表。
如图13所示,旧镜像V1和新镜像V2包括多个已知公共代码块1300、1302、1304和新公共代码块1307。例如,已知公共代码块1300可以表示JPEG或者MPEG文件。已知公共代码块1302可以表示WAV文件。已知公共代码块1304可以表示地址簿。公共代码块1307是实施例的后处理产生的“新”公共代码块(公共代码块1307的“虚线”边界表示其是新公共代码块)。虽然示出了特定数量的公共代码块,但是可以有更大或者更小数量的公共代码块。
实施例的后处理改进了使用相对寻址概念的指令的预处理的性能。可以将这些指令称为“信标”或者“广义信标”。它们包括但不限于可计算指令,例如常见的ARM BL指令。由于当创建预处理数据时旧镜像和新镜像两者均可用,因此可以测试在公共代码块中是否存在处于对齐位置的指令。还可以检查相关联的起始和/或目标地址。基于关于指令的包括起始地址和/或目标地址的这种类型的数据的收集,可以延伸现有公共代码块和/或创建新公共代码块。
根据实施例,函数/算法使用addr_pair列表来尝试创建新代码块。
例如,该函数使用addr_pair列表来尝试创建新代码块,如下 /* 通过addrArray搜索具有相同偏移(例如对齐)的地址对的连续序列(仅允许maxInterrupt中断)。
返回DT_OK或者错误代码。
*/ static dt_int16 modify_tryToAddArray() 图13示出了导致新公共代码块的1307的增加的后处理。当判断是否增加例如公共代码块1307的新公共代码块时,后处理识别具有在镜像中但是不在已知代码块中的目标地址的指令。例如,后处理识别出指令1308、1310、1312和1314是包括可能导致产生一个或多个新公共代码块的特性的指令。每一个指令包括相关联的起始地址和目标地址(1308a-b、1310a-b、1312a-b和1314a-b)。指令1308、1310、1312和1314的后处理导致新公共代码块1307的增加。
如上所述,后处理识别出指令1308、1310、1312和1314具有导致创建新公共代码块1307的特性。例如,后处理识别出在已知代码块中不存在指令1308、1310、1312和1314的目标地址1308b、1310b、1312b和1314b,并且根据定义的最小间隔将目标地址1308b、1310b、1312b和1314b间隔开。另外,在例如已知公共代码块1306的一个或多个已知公共代码块内存在指令1308、1310、1312和1314的起始地址1308a、1310a、1312a和1314a。
目标地址1308b、1310b、1312b和1314b之间的间隔仅仅是在判断是否创建新公共代码块时可以使用的一个因素。包括指向公共区域的目标地址的指令的数量是在判断是否创建新公共代码块时可以使用的另一个因素。另外,包括指向公共区域的目标地址的指令的频率是在判断是否创建新公共代码块时可以使用的另一个因素。根据实施例,基于可以指向旧镜像和新镜像中的一个或多个公共代码区域的指令的数量、指令的频率和指令之间的间隔中的至少一个来创建一个或多个新代码块。
现在,参考图14,根据实施例,使用后处理来增大一个或多个先前识别出的公共代码块的大小或者扩展一个或多个先前识别出的公共代码块,同时还产生新公共代码块。关于对代码块进行后处理的算法,该函数/算法可以使用“backward”阵列和“forward”阵列来延伸代码块,如下 /* 查看代码块之间的每一个间隙。
可以将相邻的块延伸到间隙中。
返回DT_OK或者代码错误。
*/ static dt_int16 modify_tryToExtend() 如图14所示,旧镜像V1和新镜像V2包括多个已知公共代码块1400、1402、1404、1406和新公共代码块1408。如上面所讨论的,后处理可以扩展例如已知公共代码块1400~1406中的一个或多个的一个或多个先前识别出的公共代码块或者增大其大小。当判断是否延伸或扩展例如公共代码块1402的已知公共代码块时,后处理识别具有在镜像中但是不在已知代码块中的目标地址的指令。后处理还识别具有相对于指令和/或已知公共代码块具有可计算关系的起始地址的指令。
例如,后处理识别出指令1410和1412是包括可能导致例如已知公共代码块1402的一个或多个已知公共代码块的扩展的特性的指令。即,识别出的指令1410和1412具有不在已知公共代码块中的相应的目标地址1410b和1412b。由于目标地址1410b和1412b不在已知公共代码块中,因此后处理可以评价指令1410和1412的一个或多个特性来判断是否扩展已知公共代码块1402。
在确定目标地址1410b和1412b不在已知公共代码块中之后,后处理可以检查指令1410和1412的每一个起始地址1410a和1412a,来判断是否扩展已知公共代码块1402以包括目标地址1410b和1412b。根据实施例,由于起始地址1410a在已知公共代码块1400内,因此后处理检查指令1410的起始地址1410a和已知公共代码块1400的起始地址1400a之间的偏移或者差。在图14中,将该差表示为“△a”。类似地,后处理检查指令1412的起始地址1412a和已知公共代码块1400的起始地址1400a之间的偏移或者差。将该差表示为“△b”。
如果△a等于△b,则起始地址1410a和1412a对齐,后处理扩展已知公共代码块1402以包括目标地址1410b和1412b。换句话说,基于指令1410和1412的一个或多个特性,后处理可以增大公共代码块1402的大小使得现在扩展后的公共代码块1402包含目标地址1410b和1412b。因此,延伸后的公共代码块1402包括新的边界1418,其对应于公共代码块1402的大小的增加。后处理可以通过使用backward和/或forward阵列来延伸公共代码块的大小,从而改变线索表中的两个编号。如上面所描述的,移动边界(通过修正StartADDRV1(i)和StartADDV2(i))也可以改变SIZE变量。
作为又一个示例,后处理识别出指令1414和1416是包括可能导致例如已知公共代码块1406的一个或多个已知公共代码块的扩展的特性的指令。即,识别出的指令1414和1416具有不在已知公共代码块中的相应的目标地址1414b和1416b。由于目标地址1414b和1416b不在已知公共代码块中,因此后处理可以评价指令1414和1416的一个或多个的一个或多个特性来判断是否扩展已知公共代码块1406。
由于目标地址1414b和1416b不在已知公共代码块中,因此后处理可以检查指令1414和1416的每一个起始地址1414a和1416a,来判断是否扩展已知公共代码块1406以包括目标地址1414b和1416b。如上所述,根据实施例,后处理检查指令1414的起始地址1414a和已知公共代码块1404的起始地址1404a之间的偏移或者差。在图14中,将该差表示为“△c”。类似地,后处理检查指令1416的起始地址1416a和已知公共代码块1404的起始地址1404b之间的偏移或者差。将该差表示为“△d”。
如果△c等于△d,则起始地址1414a和1416a对齐,后处理扩展已知公共代码块1404以包括目标地址1414b和1416b。换句话说,基于指令1414和1416的一个或多个特性,后处理可以增大公共代码块1406的大小使得现在扩展后的公共代码块1406包含目标地址1414b和1416b。因此,延伸后的公共代码块1406包括新的边界1420,其对应于公共代码块1406的大小的增加。在该示例中,向后延伸了公共代码块1406,而在第一示例中向前延伸了公共代码块1402。如前面所描述的,关于向后还是向前延伸的判断至少部分基于要正确地对多少指令进行预处理。
除了延伸已知公共代码块1402和1406之外,后处理还增加了新公共代码块1408。公共代码块1408是实施例的后处理产生的“新”公共代码块(公共代码块1408的“虚线”边界表示其是新公共代码块)。当判断是否增加例如公共代码块1408的新公共代码块时,后处理识别具有在镜像中但是不在已知代码块中的目标地址的指令。例如,后处理识别出指令1422、1424、1426和1428是包括可能导致一个或多个新公共代码块的产生的特性的指令。指令1422、1424、1426和1428的后处理导致增加新公共代码块1408。
如上所述,后处理识别出指令1422、1424、1426和1428具有导致创建新公共代码块1408的特性。例如,后处理识别出在已知代码块中不存在目标地址1422b、1424b、1426b和1428b,并且根据定义的最小间隔将目标地址1422b、1424b、1426b和1428b间隔开。另外,在已知公共代码块1402和1404内存在起始地址1422a、1424a、1426a和1428a。目标地址1422b、1424b、1426b和1428b之间的间隔仅仅是在判断是否创建例如新公共代码块1408的新公共代码块时可以使用的一个因素。
包括指向公共区域的目标地址的指令的数量是在判断是否创建新公共代码块时可以使用的另一个因素。另外,包括指向公共区域的目标地址的指令的频率是在判断是否创建新公共代码块时可以使用的另一个因素。根据实施例,基于可以指向旧版本和新版本中的一个或多个公共代码区域的指令的数量、指令的频率和指令之间的间隔中的至少一个来创建一个或多个新代码块。
可能改变的参数包括但不限于 /*可以增加的块的最大数量。
基于经验,增加大于10000个无用*/ const int maxAdditional=10000 /*地址对的连续序列的最大长度, 尝试增加块*/ const int minLength=10 /*在地址对的连续序列中允许的中断的最大数量*/ const int maxInterrupt=1 在一些实例中,使用后处理技术实现的总体改进是相当显著的。这是可预期的,部分因为这些实施例能够找到大小不大但是按照镜像内的指令的总体图却非常重要的公共代码块。一个这种示例是ARM代码中公共的插入代码(veneer)。这些插入代码通常仅仅是几个字节,因此使用传统技术难以检测到。
实施例的“数据阵列”包括但不限于以下 int *backward,*forward; addr_pair*addrArray; 根据实施例,对于代码块阵列的给定输入,可以执行两个不同的后处理过程,并且基于经过正确预处理的指令数量选择过程。两个不同的过程包括下面描述的第一过程和第二过程。第一过程包括但不限于清除数据阵列;基于输入代码块计算数据阵列;modify_tryToAddArray();清除数据阵列;基于修正后的代码块计算数据阵列;modify_tryToExtend();以及基于修正后的代码块计算经过正确预处理的指令数量。
第二过程包括但不限于清除数据阵列;基于输入代码块计算数据阵列;modify_tryToExtend();清除数据阵列;基于修正后的代码块计算数据阵列;modify_tryToAddArray();基于修正后的代码块计算经过正确预处理的指令数量。第一过程和第二过程的不同之处在于,它们以相反的序列使用算法(modify_tryToAddArray()和modify_tryToExtend())。至少部分基于经过正确预处理的指令数量来进行第一或者第二过程的选择。
图15A~15F是提供上面讨论的预处理和后处理方法的示例结果的图形表示。采样数据包括表示“旧镜像”的“v1.bin”和表示“新镜像”的“v2.bin”。两个镜像具有近似相同数量的BL指令。在v1.bin中有259,653个BL指令,在v2.bin中有261,283个BL指令。
图15A示出预处理之后的结果。如图15A所示,垂直条纹显示具有变化的宽度的多个公共代码块。例如,1500、1502、1504、1506、1508、1510和1512是示例性公共代码块。除了公共代码块1500~1512之外,图15A还包括其它公共代码块。图15A底部的水平轴是去除了填充(padding)区域之后的旧镜像(v1.bin)的地址空间。该图中间的水平轴是去除了填充区域之后的新镜像(v2.bin)的地址空间。对于本示例,仅在地址9,585,324有一个填充区域位于图的右侧附近。填充区域的大小是245,076字节。小于9,585,324的地址不受填充影响,图中的地址等于镜像中的实际地址。
如上所述,每一个垂直条纹表示一个公共代码块,第一部分标识出旧镜像中的区域(这是与图中的下部轴相接触的条纹的范围),第二部分标识出新镜像中的区域(这是与图中的中间轴相接触的条纹的范围)。图中的大多数条纹显示是几乎垂直的,这是因为该图的水平刻度大于九兆字节,在这种大的刻度上不容易看出代码块小的偏移。
在公共代码块中的v1.bin中有258,822个BL指令。其中,187,162个具有也在公共代码块中的目标地址。在这些目标地址中,公共代码块正确地预测了186,058个。正确的预测通常意味着目标地址之间的间隔以与相关公共代码块偏移一致的方式在旧镜像和新镜像之间不同。如上面所说明的,后处理方法分析在公共代码块中没有目标地址的例如BL指令的指令。如果指令在公共代码块中没有目标地址,则后处理尝试通过延伸已知公共代码块和/或增加新公共代码块来改进公共代码块,但是不限于此。
如上面所描述的,根据实施例,后处理尝试以下过程 1.modify_tryToAddArray 2.modify_tryToExtend 后处理产生正确预测的242,198个BL指令的计数。
接下来,后处理尝试以下过程 1.modify_tryToExtend 2.modify_tryToAddArray 该后处理产生正确预测的257,217个BL指令的计数。由于第二过程产生更多数量的正确预测的指令,因此对于该示例使用第二过程。应当指出,来自第二过程的计数相当接近v1.bin中的BL指令的总数258,822。此外,回顾在后处理之前正确预测的BL指令的计数是186,058。因此,作为后处理方法的结果是△文件明显更小。未经后处理的△文件的大小是274,259字节。经过后处理的△文件的大小是131,799字节。因此,对于该示例,后处理产生了大小小于没有使用后处理的△文件的大小的一半的△文件。
图15B示出后处理之后的结果。如图15B所示,垂直条纹显示具有变化的宽度的多个公共代码块。例如,1514、1516、1518、1520、1522、1524和1526是示例性公共代码块。除了公共代码块1514~1526之外,图15B还包括其它公共代码块。上部区域是受后处理影响的字节的密度。我们注意到该曲线趋于比图1中的相应的曲线高。尤其在左侧从0到大约2,000,000的地址范围内这值得注意(地址以图底部的水平轴作为参考)。为了理解该结果,我们看图15C,其示出v2.bin中具有镜像内的目标地址的BL指令。对于v1.bin可以绘制类似的曲线图。用菱形标记每一个点,以使其更容易看到。点表示BL指令。水平轴上的值是指令的地址,垂直轴上的值是其目标地址。参看图的左下部,我们看到很少的具有从0到2,000,000的范围内的地址的BL指令具有1,000,000附近的目标地址。这对应于左下部(被虚线包围)的水平分组的点。
图15D和15E分别是图15A和15B的相关区域的放大结果。仅放大了水平轴(垂直轴未发生变化)。图15D是放大了的图15A,扩展了水平轴以显示使公共代码块1500、1502和1504高亮的从900,000到1,100,000的范围。图15E是放大了的图15B,扩展了水平轴以显示使公共代码块1514、1516、1518和1520高亮的从900,000到1,100,000的范围。在针对没有使用后处理方法的计算的图15D中,有一些可以看到的间隙。然而,如图15E所示,后处理通过延伸(例如使用modify_tryToExtend())相邻的公共代码块(例如1514、1516和1520)和/或通过引入新(例如使用modify_tryToAddArray())公共代码块(例如1518)几乎填满了这些间隙。
下面的表提供更详细的信息。该表突出了上面讨论的对于检查后的区域中的几个公共代码块的后处理的效果。
在上述表中,用三个编号描述每一个公共代码块a、b和c。前缀“a”表示v1.bin中的块的起始地址。前缀“b”表示v2.bin中的块的起始地址。前缀“c”表示(v1.bin和v2.bin两者中的)块的长度。
表中的编号显示第一块在其末端经过了延伸,这是因为a和b值是相同的,但是c值增大了。该延伸是使用modify_tryToExtend()算法完成的。还使用modify_tryToExtend()算法在左右两侧延伸了第二块。使用modify_tryToAddArray()算法增加了新的块(这是图15E的第三窄块)。应当指出,表中的最后一块未发生变化。在图15D~15E中这些变化是明显的。图15F是放大的图15C的区域,其示出了后处理增加的块的效果。增加的块中所包含的点表示现在预处理的BL指令。
作为使用上述预处理和/或后处理的设备和/或系统的示例,接收并使用△文件的计算设备可以是驻留需要更新的相应软件应用程序的客户设备,例如蜂窝式电话、移动电子设备、移动通信设备、个人数字助理以及其它基于处理器的设备。通过使电信公司(carrier)和设备制造商能够经由其无线基础设施有效地分配电子文件内容和应用程序来为从固件到嵌入式应用程序的所有移动设备软件提供这种支持。
受益于上述预处理和/或后处理的系统的另一个示例包括使用有线串行连接以将△文件从驻留文件差异产生器的设备传送到驻留文件更新产生器的设备的系统。这些系统一般具有慢的传送速率,并且因为传送速率慢,所以△文件的大小的减小是一种实现更快的传送时间的方式。
受益于预处理和/或后处理的使用的系统的又一个示例包括使用无线电通信将△文件从驻留文件差异产生器的设备传送到驻留文件更新产生器的设备的无线系统。在遭受与无线连接相关联的低可靠性的同时,这些系统还具有慢的传送速率。在这些系统中使用更小的△文件提供几个优点。例如,更小的文件大小产生更快的△文件传送时间。更快的传送时间在为设备用户节省时间的同时,减少了将错误引入△文件中的机会,从而提高了系统可靠性。此外,使用蜂窝式通信,对于一般对服务按分钟收费的消费者,减少了的传送时间产生成本的节约。
作为另一个优点,更小的△文件减小了将△文件传送到客户设备所需的带宽。减小的带宽允许经由分配的信道支持更多客户设备。与减少的传送时间相同,这也使无线服务供应商的运营成本降低。
本发明的各方面可以实现为被编程到各种电路中的任意一个中的功能,各种电路包括例如场可编程门阵列(FPGA,field programmable gatearray)、可编程阵列逻辑(PAL,programmable array logic)器件的可编程逻辑器件(PLD,programmalbe logic device)、电可编程逻辑和存储器件及基于标准单元的器件以及专用集成电路(ASIC,application specificintegrated circuit)。用于实现本发明的各方面的一些其它可能包括具有存储器(例如电可擦除可编程只读存储器(EEPROM,electronicallyerasable programmable read only memory))的微控制器、嵌入式微处理器、固件、软件等等。此外,可以在具有基于软件的电路仿真、离散逻辑(连续的和组合的)、定制器件、模糊(神经)逻辑、量子(quantum)器件和上述器件类型的任意组合的微处理器中实施本发明的各方面。当然,可以以各种元件类型提供基本器件技术,例如像互补金属氧化物半导体(CMOS)的金属氧化物半导体场效应晶体管(MOSFET)技术、像射极耦合逻辑(ECL,emitter-coupled logic)的双极技术、聚合技术(例如硅共轭聚合体(silicon-conjugated polymer)和金属共轭聚合体金属结构(metal-conjugated polymer-metal structure))、混合模拟和数字(mixedanalog and digital)等等。
可以通过程序或者程序代码的集合来执行作为本发明在这里描述的功能,程序或者程序代码的集合包括在一个或多个通用计算机或者基于处理器的系统上运行或者由一个或多个通用计算机或基于处理器的系统执行的软件、固件、可执行代码或者指令。计算机或者其它基于处理器的系统可以包括用于执行程序代码的一个或多个中央处理器、例如用于在程序执行过程中临时存储数据和数据结构的RAM的易失性存储器、用于存储例如包括数据库和其它数据存储的程序和数据的硬盘驱动或者光盘驱动的非易失性存储器、以及用于访问企业内部互联网和/或因特网的网络接口。然而,还可以使用专用计算机、无线计算机、状态机和/或硬配线电子电路来实现这里描述的功能。
应当指出,按照其行为、寄存器传送、逻辑组件、晶体管、布局几何和/或其它特性,可以使用计算机辅助设计工具来描述这里公开的各种系统和方法的组件,并且将其表达(或者表示)为在各种计算机可读介质中实施的数据和/或指令。可以实现这种电路表达的文件和其它对象的格式包括但不限于支持例如C、Verilog和HLDL的行为语言的格式;支持例如RTL的寄存器级别描述语言的格式;以及支持例如GDSII、GDSIII、GDSIV、CIF、MEBES的几何描述语言的格式以及任何其它合适的格式和语言。
可以实施这种格式化数据和/或指令的计算机可读介质包括但不限于各种形式的非易失性存储介质(例如光、磁或者半导体存储介质)和可以用于通过无线、光和/或有线信令介质传送这种格式化数据和/或指令的载波。通过载波传送这种格式化数据和/或指令的示例包括但不限于经由一个或多个数据传送协议(例如HTTP、FTP、SMTP等等)通过因特网和/或其它计算机网络进行传送(上传、下载、e-mail等等)。当经由一个或多个计算机可读介质在计算机系统内接收到时,可以由计算机系统内的处理实体(例如一个或多个处理器)结合一个或多个其它计算机程序的执行来处理上面描述的系统和方法的基于这种数据和/或指令的表达。
除非是上下文中清楚地需要,在说明书和权利要求书中,词语“包括”、“包含”等被解释为与排他或者穷尽的含义相对的包含的含义;也就是说,“包括但不限于”的含义。使用单数或者复数的词语也分别包括复数或者单数。另外,词语“这里”、“下面”、“以上”、“以下”以及类似意思的词语是指本申请是一个整体,而不是指本申请的任何特定部分。当使用词语“或者”指两个或者更多项的列表时,该词语覆盖所有以下对该词语的解释列表中的项中的任意一个、列表中的所有项以及列表中的项的任意组合。
以上对本发明的说明性实施例的描述不旨在穷尽或者将本发明限制到所公开的具体形式。虽然这里为了说明描述了本发明的特定实施例和示例,但是如本领域技术人员意识到的,可以在本发明的范围内进行各种等同变形。这里提供的本发明的原理可以应用于其它处理系统和通信系统,而不仅仅用于以上描述的文件求差系统。
可以组合上面描述的各种实施例的元件和动作来提供其它实施例。可以按照上述详细说明对本发明进行这些和其它变化。如果需要,可以对本发明的各方面进行修正来使用上面描述的各个专利和申请的系统、功能和概念以提供本发明的其它实施例。
总而言之,在所附权利要求中,使用的术语不应当被解释为将本发明限制到在说明书和权利要求中公开的特定实施例,而应当被解释为包括根据权利要求工作以提供文件求差的所有处理系统。因此,本发明不限于本公开,而是由权利要求整体确定本发明的范围。
虽然下面以特定权利要求的形式呈现了本发明的特定方面,但是本发明人以任意数量的权利要求的形式预期本发明的各个方面。例如,虽然描述为仅在计算机可读介质中实施本发明的一个方面,但是同样可以在计算机可读介质中实施其它方面。因此,本发明人保留在提交申请之后增加附加权利要求以针对本发明的其它方面追加这种附加权利要求形式的权利。
权利要求
1.一种用于更新电子文件的系统,包括
产生组件,用于产生包括被编码的电子文件的原始版本和新版本之间的差异的差异文件,其中产生组件通过如下所述来减小差异文件的大小
识别原始版本和新版本之间公共的第一和第二文本部分,其中原始版本中的第一文本部分包括具有第一起始地址和第一目标地址的第一可计算指令,新版本中的第二文本部分包括具有第二起始地址和第二目标地址的第二可计算指令;
基于第一和第二可计算指令的特性确定是延伸原始版本和新版本之间公共的已知文本部分还是创建原始版本和新版本之间公共的新文本部分中的至少一个;以及
去除识别出的原始版本和新版本公共的文本部分中的差异;以及
传送组件,用于传送差异文件以在产生新版本时使用。
2.根据权利要求1所述的系统,其中如果第一和第二可计算指令的第一和第二目标地址不在一个或多个已知公共文本部分内,则产生组件通过延伸原始版本和新版本之间公共的已知文本部分以包括第一和第二可计算指令的第一和第二目标地址来减小差异文件的大小。
3.根据权利要求2所述的系统,其中如果第一和第二可计算指令的第一和第二起始地址从原始版本和新版本之间公共的第一和第二文本部分的起始地址偏移相等的量,则产生组件通过延伸原始版本和新版本之间公共的已知文本部分以包括第一和第二可计算指令的第一和第二目标地址来进一步减小差异文件的大小。
4.根据权利要求2所述的系统,其中如果在原始版本和新版本之间公共的第一和第二文本部分内第一和第二可计算指令的第一和第二起始地址从相应的基准偏移可计算的量,则产生组件通过延伸原始版本和新版本之间公共的一个或多个已知文本部分以包含第一和第二可计算指令的第一和第二目标地址来减小差异文件的大小。
5.根据权利要求1所述的系统,其中如果第一和第二可计算指令的第一和第二目标地址不在原始版本和新版本之间公共的一个或多个已知文本部分内,则产生组件通过创建包括第一和第二可计算指令的第一和第二目标地址的原始版本和新版本之间公共的一个或多个新文本部分来减小差异文件的大小。
6.根据权利要求5所述的系统,其中产生组件基于一个或多个可计算指令的数量、频率和间隔中的至少一个通过创建包括第一和第二可计算指令的第一和第二目标地址的原始版本和新版本之间公共的一个或多个新文本部分来减小差异文件的大小。
7.根据权利要求5所述的系统,其中如果第一和第二可计算指令的第一和第二起始地址没有从原始版本和新版本之间公共的第一和第二文本部分的相应基准偏移相等的量,则产生组件通过创建包括第一和第二可计算指令的第一和第二目标地址的原始版本和新版本之间公共的一个或多个新文本部分来减小差异文件的大小。
8.根据权利要求1所述的系统,其中至少部分基于经过正确预处理的可计算指令的数量来确定是延伸原始版本和新版本之间公共的已知文本部分还是创建原始版本和新版本之间公共的新文本部分中的至少一个。
9.根据权利要求1所述的系统,其中传送组件传送差异文件以在第二设备上产生新文件版本时使用,其中第二设备是从个人计算机、便携式计算设备、蜂窝式电话、便携式通信设备和个人数字助理中选择的至少一个基于处理器的设备。
10.一种用于产生差异文件的设备,包括
用于接收电子文件的原始版本和新版本的装置;
用于识别原始版本和新版本公共的代码单元的装置;
用于识别代码单元公共的指令的装置,其中识别出的指令包括具有第一起始地址和第一目标地址的原始版本中的第一指令以及具有第二起始地址和第二目标地址的新版本中的第二指令;以及
用于延伸原始版本和新版本公共的代码单元或者创建原始版本和新版本公共的新代码单元的装置。
11.根据权利要求10所述的设备,其中用于延伸代码单元或者创建新代码单元的装置通过评价识别出的指令来延伸原始版本和新版本公共的代码单元或者创建原始版本和新版本公共的新代码单元。
12.根据权利要求11所述的设备,其中用于延伸代码单元或者创建新代码单元的装置通过评价第一和第二识别出的指令的第一和第二目标地址是否不在原始版本和新版本公共的一个或多个已知公共代码单元内,来延伸原始版本和新版本公共的代码单元或者创建原始版本和新版本公共的新代码单元。
13.根据权利要求12所述的设备,其中用于延伸代码单元或者创建新代码单元的装置通过评价第一和第二识别出的指令的第一和第二起始地址的特性来延伸原始版本和新版本公共的代码单元或者创建原始版本和新版本公共的新代码单元。
14.一种用于进行文件求差的方法,包括
接收电子文件的原始版本和新版本;
识别原始版本和新版本公共的代码单元,其中原始版本和新版本公共的代码单元包括公共函数单元;
合并代码单元的公共函数单元以形成原始版本和新版本之间的一个或多个公共函数块;
识别一个或多个函数块公共的指令,其中识别出的指令包括具有第一起始地址和第一目标地址的原始版本中的第一指令以及具有第二起始地址和第二目标地址的新版本中的第二指令;以及
基于对第一和第二识别出的指令的评价来延伸一个或多个公共函数块中的至少一个或者创建一个或多个新公共函数块。
15.根据权利要求14所述的方法,还包括如果第一和第二指令的第一和第二目标地址不在一个或多个已知公共函数块内,则延伸一个或多个公共函数块中的至少一个或者创建一个或多个新公共函数块。
16.根据权利要求15所述的方法,还包括如果第一和第二指令的第一和第二起始地址从一个或多个公共函数块的公共基准偏移相等的量,则延伸一个或多个公共函数块中的至少一个以包括第一和第二指令的第一和第二目标地址。
17.根据权利要求15所述的方法,还包括基于电子文件的原始版本和新版本之间公共的一个或多个指令的数量、频率和间隔中的至少一个来创建包括第一和第二指令的第一和第二目标地址的一个或多个新公共函数块。
18.根据权利要求15所述的方法,还包括如果第一和第二指令的第一和第二起始地址没有从第一和第二公共函数块的相应基准偏移相等的量,则创建包括第一和第二指令的第一和第二目标地址的一个或多个新公共函数块。
19.根据权利要求14所述的方法,还包括至少部分基于经过正确预处理的指令的数量来延伸一个或多个公共函数块中的至少一个或者创建一个或多个新公共函数块。
20.根据权利要求14所述的方法,还包括
产生差异文件;
将差异文件传送到便携式处理系统;以及
使用差异文件在便携式处理系统中产生新文件版本。
21.一种包括可执行指令的计算机可读介质,在处理系统中执行时,所述可执行指令通过如下所述来减小包括电子文件的原始版本和新版本之间的被编码的差异的差异文件的大小
识别原始版本和新版本公共的代码单元,其中原始版本和新版本公共的代码单元包括公共函数单元;
合并代码单元的公共函数单元以形成原始版本和新版本之间的一个或多个公共函数块;
识别一个或多个公共函数块公共的指令,其中识别出的指令包括具有第一起始地址和第一目标地址的原始版本中的第一指令以及具有第二起始地址和第二目标地址的新版本中的第二指令;以及
基于对第一和第二识别出的指令的评价来延伸公共函数块或者创建新公共函数块。
全文摘要
本发明提供一种系统和方法,用于对文件的原始版本和新版本进行预处理和后处理,作为例如字节级别的文件求差的原始文件版本和新文件版本之间的差异文件产生的一部分。文件版本之间的软件/可执行变化包括被定义为源代码变化的初级变化/逻辑变化和次级变化。次级变化通常是由初级变化引起的并且由软件编译器/连接器产生。次级变化包括地址变化、指针目标地址变化和地址偏移的变化。所提供的预处理和/或后处理系统和方法在文件版本之间使用近似规则以去除/减小次级变化,并对相应的差异文件的信息中与这些变化的去除有关的信息进行编码。
文档编号G06F12/00GK101297275SQ200680039466
公开日2008年10月29日 申请日期2006年9月22日 优先权日2005年9月23日
发明者马蒂亚斯·赖因施 申请人:创道软件有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1