以故障保险方式向非易失存储应用自定义软件映象更新的制作方法

xiaoxiao2020-7-23  12

【知识产权代理】【专利服务】Tel:18215660330

专利名称:以故障保险方式向非易失存储应用自定义软件映象更新的制作方法
技术领域
本发明一般涉及计算装置,尤其涉及更新计算装置的非易失存储。
背景技术
诸如个人数字助理、当代移动电话和手持式及袖珍计算机等移动计算设备正在变为重要且流行的用户工具。一般而言,它们变得足够小,使得它们极度方便,而消耗较少的电池功率,且在同时变得能够运行更强大的应用程序。
在制造这类设备的过程中,嵌入式操作系统映象通常被构建到每一设备的单块映象文件中,并储存在非易失存储中(如,NAND或NOR闪存、硬盘等等)。作为结果,迄今为止,更新这类设备是一个相当复杂且资源密集型问题,它一般需要自定义的解决方案。
例如,更新这类设备通常涉及下载整个新单块映象文件,它包括所开发并发行的在设备集合上运行的单个静态映象。可以容易地理解,无论改变了什么,都需要非常大量的系统资源(如,用于临时保存更新映象的存储、用于接收整个映象文件的网络带宽等等),由此,设备更新过程通常需要一次性的自定义解决方案。
需要一种比现有更新机制更灵活、动态且有效,而仍是故障保险的更新计算设备的非易失存储的更好的方法。

发明内容
简单而言,本发明针对一种以故障保险的方式向嵌入式设备的非易失存储应用自包含、安全实体形式的软件更新的系统和方法。可应用各种类型的软件更新,包括可仅包含对前一更新的改变的更新。此外,软件更新可包含可执行代码和数据两者。
在一个实现中,在重启之后,初始程序加载器确定更新何时被请求或在进行中,如果是,则引导到更新加载器而非正常的操作系统代码。更新加载器操作以确认任何待决的更新,用于在适当时向闪存(或其它存储媒质)应用更新。为了安全和控制,更新加载器是系统中对受保护的存储(如,NK分区和系统分区)具有写访问权限的唯一实体。应当注意,更新应用程序也具有对闪存中保留区域的写权限。
为了更新,更新包(可以是各种形式)被下载到系统上,并由包确认过程确认,该过程包括为安全原因检查每一包是否被正确签署、及总体检查包是否被正确构造。如果有效,则更新被排队,并且为初始程序加载器设置一标志以检测期望更新。然后重启设备。
在重启之后,初始程序加载器看见更新标志被设置,并例如通过将更新加载器解压(如果被压缩)到RAM并跳至更新加载器代码来促使更新加载器运行。以内核包(如果存在这样一个的话)开始,对每一包,更新加载器处理该包、重新确认它们、基于闪存考虑事项在需要时修正RAM段中的文件、并将这些文件写入其对应的分区中。注意,初始程序加载器保持闪存未锁定,使得它可被更新加载器写入。
为解释包内容,每一包包含具有关于该包的详细信息的设备清单文件,更新加载器读取其内容,包括包标识的全局唯一ID、包版本、与其它包相关的依赖信息、各种设置以及包括在包内的文件和文件版本的列表。该清单文件包括在包内,由此令包为自描述的,并且在安装之后最终储存在设备中。设备上清单文件的集合包括设备上包的安装状态的数据库,它可被枚举。
更新加载器通过从分区/映象中检索关于映象的各种信息,将映象解压到RAM中,来处理压缩和非压缩映象。如果未压缩,则可简单地读取信息,如通过提供要更新的活动分区的位置的主引导记录驻留在何处的现有知识来读取。
在一个实现中,首先以故障保险方式应用任何内核更新,主要通过经将其读入RAM中并将其压缩到用户存储中来备份现有内核。更新对分区是一个整体,如果成功,则删除备份的内核,而如果不成功,则解压并回复备份的内核。
系统分区一般大于内核分区,因此,它通常太大,以至于无法为故障保险相关原因而备份。相反,使用IMGFS文件系统来向个别的模块和文件应用更新,每次应用一个。个别的模块和文件可能太大,以至于无法作为整体来完成,因此,可通过较小的块来应用更新。
IMGFS可首先模拟更新过程,这需要两次通过该过程,即在第一遍中,IMGFS和更新应用程序将不向闪存提交任何内容。如果模拟成功,则运行第二遍,以实际提交变化。如果模拟失败,在重新运行包确认器之后重试模拟,并传入不包括失败的包的包列表。然后用包确认器返回的新列表再次运行模拟。重试模拟,直到模拟成功,或者没有可应用的任何包。这预防了在尽管发生了破坏但仍被签署的包中所出现的数据破坏。
当使用现有的设备清单文件重复通过IMGFS中的模块时,该过程检查来看文件是否在该包的新设备清单文件中出现。如果不是,则从IMGFS分区删除该文件,过程继续下一文件。如果是,则从新设备清单文件获取新模块标志,并且将模块头部加载到模块结构中。
为执行更新,更新应用程序过程在嵌套的循环中循环通过每一包分组,以个别地处理包中的每一文件。如果在该过程中丢失电源,则一日志文件可精确地告知该过程停留在哪一包以及该包中的哪一文件上,当恢复电源时,更新可从该处继续进行。上述处理的一部分包括(对于可执行代码)更新对更新模块的虚拟地址分配。
更新可以是规范形式或二进制差(增量)形式。非模块不需要虚拟地址修正,并且一旦执行二进制更新时可被写入到存储中。如果文件是模块,则每次处理每一分段的一个;每一分段被写入新流中(其中,流是作为IMGFS一部分的文件系统概念)。如果文件是常规数据文件,则数据被写入默认流中。
如果模块是规范更新,则处理该模块中的每一分段,包括向由虚拟分配器分配的地址重新定位整个分段,以及将整个分段作为新的流写入新的IMGFS文件中。在原地更新旧模块,当写入新块时,将旧存储块解除分配。在规范的情况下,通过获取被写出的新文件中的每一流的大小执行对电源故障的恢复,并将其与规范文件中该分段的大小进行比较。如果新文件中的流小于规范文件,则那就是过程所停留之处,并且可继续进行在数据上复制。
在二进制差的情况下,每次在一个块上执行打补丁过程,其中,块可等于页/扇区大小。这是因为可能没有足够的闪存空间来同时保留分段的旧版本和新版本。当创建新块时,可将旧块解除分配,因为它们已不再需要。对于二进制差异更新,对该分段在新模块文件中创建稀疏流,并将旧分段读入RAM中。将整个旧分段重新定位回原始的基地址。对于二进制差文件中的每一新块,基于二进制差异命令构建新块,并将新块重新定位到由虚拟地址分配器所分配的地址,并将其写出到稀疏流。来自旧文件流的不再需要的任何旧块被解除分配。
在二进制差的情况下,通过将流大小与头部中指定的大小相比较来缩小停留在哪一分段的范围,以处理电源故障。一旦确定了该分段,补丁顺序返回下一块,并检查该块是否被提交。如果块已被提交,则执行核实以检查适当的旧块已被提交。一旦找到所停留的块,(即,尚未被提交的块),则过程如常继续。
对于更新保留的存储器分段,以与内核分区更新类似的方式,使用同一更新组件完成保留分段更新(如,在分区之外)。通过处理包中的每一文件,并确定该文件是否为二进制差模块,处理每一保留相关的包更新。如果不是,则只要从文件中读出文件数据并写入保留的区域中。如果是二进制差模块,则读取现有的区域(如,到RAM)中,并在将更新的数据写回保留的区域之前向其应用二进制差。
当结合附图阅读以下详细描述时,可以清楚其它优点。


图1是一般表示可在其中结合本发明的计算机系统的框图;图2是表示依照本发明的一个方面用于方便故障保险组件更新的分区的操作系统映象和加载器组件的框图;图3是表示依照本发明的一个方面向设备的存储应用更新包的框图;图4是表示依照本发明的一个方面描述包的设备清单文件的格式的框图;图5A和5B包括表示依照本发明的一个方面确定更新模式的初始程序加载器引导过程的示例逻辑的流程图;图6是表示依照本发明的一个方面的整体更新过程的示例逻辑的流程图;图7A和7B包括表示依照本发明的一个方面更新内核分区的示例逻辑的流程图;图8A和8B包括表示依照本发明的一个方面更新操作系统分区的示例逻辑的流程图;图9是表示依照本发明的一个方面通过依赖图以块向设备应用更新的框图;以及图10是表示依照本发明的一个方面更新保留的存储器分段的示例逻辑的流程图。
具体实施例方式
示例性操作环境图1示出了一个这样的手持式计算设备120的功能组件,包括处理器122、存储器124、显示屏126和键盘128(可以是物理或虚拟键盘,或表示两者)。可存在麦克风129以接收音频输入。存储器124一般包括易失存储器(如,RAM)和非易失存储器(如,ROM、PCMCIA卡等等)。操作系统130驻留在存储器124中,并在处理器122上执行,如微软公司的Windows操作系统或另一操作系统。
一个或多个应用程序132被加载到存储器124中,并在操作系统130上运行。应用程序的示例包括电子邮件程序、调度程序、PIM(个人信息管理)程序、文字处理程序、电子表格程序、因特网浏览器程序等等。手持式个人计算机120也可包括加载到存储器124中的通知管理器134,它在处理器122上执行。通知管理器134处理如来自应用程序132的通知请求。同样,如下所述,手持式个人计算机120包括适用于将手持式个人计算机120连接到网络(包括作出电话呼叫)的网络软件136(如,硬件驱动程序等)和网络组件138(如,无线电和天线)。
手持式个人计算机120具有电源140,它被实现为一个或多个电池。电源140还可包括忽略内置电池或对其重新充电的外部电源,如AC适配器或加电对接托架。
图1所示的示例性手持式个人计算机120被示出为具有三种类型的外部通知机制一个或多个发光二极管(LED)142和音频生成器144。这些设备可直接耦合至电源140,使得当被激活时,即使手持式个人计算机处理器122或其它组件被关闭以保存电池能量时,它们也保留一段由通知机制指示的持续时间。LED 142较佳地不确定地保留,直到用户采取行动。注意,音频生成器144的当代版本使用当今手持式个人计算机电池的太多能量,因此它被配置成当系统的剩余部分被关闭时,或者在激活后的一段确定持续时间之后被关闭。
注意,尽管示出了基本手持式个人计算机,然而,为实现本发明的目的,实际上能够以可由程序使用的某一方式接收数据通信和处理数据的任何设备都是等效的。
自定义软件映象更新的故障保险应用本发明一般针对安装和/或更新储存在诸如基于微软的WindowsCE.NET的便携式设备等小型移动计算设备上的软件,包括在其中向嵌入式设备的非易失存储器,如闪存写入初始软件或软件更新的那些设备。尽管如此,本发明提供了在总体上计算的益处,并由此可应用到其它计算设备和其它类型的存储,包括各种类型的存储器和/或其它类型的存储媒质,如硬盘驱动器。为简化目的,术语“闪存”在后文参考设备的可更新存储来使用,尽管可以理解,任一存储机制都是等效的。此外,术语“映象”一般包括初始软件安装映象以及对该映象的随后的软件更新的概念,即使仅更新该映象的一部分。
依照本发明的一个方面,以故障保险的方式向嵌入式设备的非易失存储应用自包含、安全实体形式的软件更新。可应用各种类型的软件更新,包括仅包含对前一更新的改变的更新。此外,软件更新可包含可执行代码和数据两者。可以理解,可执行代码在安装时被定制到嵌入式设备的虚拟地址空间环境。依照本发明,软件更新以故障保险的方式安装,并根据更新的阶段,允许卷进(roll-forward)和卷回(roll-back)恢复选项。
下表提供了本发明所描述的某些术语和文件类型的通用、非限制定义术语


文件类型

如上述名为“以存储技术抽象方式在文件内创建文件系统”的美国专利中所描述的,可从组件部分构建初始映象(包括包、下文描述),并在制造过程中以自定义方式将其安装到设备上。该映象用单独的分区构建,一般在图2中表示,并可如后文所描述的被部分更新,而不需要替换单块映象。
分区模式方便了未来的嵌入式设备以及已有的设备上的软件的可靠更新。与意味着在一组设备上运行的在软件开发和发行过程中生成单个静态映象相反,本发明提供了一种方便可更新映象的更好组件化,而同时仍是故障保险的更动态的映象更新机制。为此,本发明提供了一种将操作系统映象分裂成可单独更新的单独的可更新组件,而保持任何跨组件依赖性的更灵活的机制。为支持这一概念,初始操作系统映象用某些关键体系结构特征来构造。
图2示出了用于安装在闪存和/或其它合适的非易失存储媒质上的操作系统映象202的示例分区模式。为储存内核映象的目的,提供了内核分区204作为受限制/受保护的分区。内核/NK分区为操作系统映象的核心片段(内核、文件系统等)提供了存储,并包含在引导过程中执行的代码。提供了受限制/受保护的系统分区206用于储存系统组件应用程序和操作系统映象的其它部分(驱动程序、应用程序、数据文件等)。如后文所描述的,这些分区204和206的内容由文件系统驱动程序管理,它们抽象存储的物理映射,并服务以支持系统分区206中组件的已处理更新,由此启用了一种依照本发明的故障保险/恢复解决方案。对受保护的内核分区的内容的访问通过二进制文件系统(BINFS)来控制,而对受保护的系统分区的内容的访问通过映象文件系统(IMGFS)来控制。
图2也示出了(尽管实际上并非操作系统202的一部分)系统/用户可在需要时使用的用户存储分区210,它本质上可以是任何文件系统格式(如,TFAT)。如后文所描述的,除其它可能的使用之外,该分区可用于临时储存要在更新过程中安装的某些包。注意,书写主引导记录以定义这些分组,如其偏移/大小。
图2也提供了加载器环境的功能示图。一般而言,加载器负责以程序引导嵌入式系统到可作出关于是作出正常的操作系统引导还是更新引导的决策的一点上(通过初始程序加载器222,它可结合预先存在的引导加载器224一起工作,如果存在的话)。注意,“预先存在”的引导加载器对新设备并非必需,然而设备制造商可任选地决定它应当存在。
对于更新引导,加载器的一部分包括担当任一闪存更新的监控者(gatekeeper)的更新加载器(UL 220)。更新加载器220负责确认任何待决的更新,并且一旦被确认,在适当时将更新应用到闪存。为安全性和控制,更新加载器220是系统中具有对受保护的存储(如,NK分区和系统分区)具有写访问权限的唯一实体,并由此提供了负责保护系统存储的完整性的单个点。注意,更新加载器相对较大,并仅在应用更新时使用,由此,在一个实现中,它以压缩形式存储,并在需要时被解压到RAM中。
图3表示更新安装机制/过程。注意,图3从更新的观点开始,在设备先前被用初始程序加载器、主引导记录(MBR)、和更新加载器(UL)组件初始地填充(如,通过JTAG接口或在制造过程中的程序员群体)之后。同样,规范包(后文描述)从持久存储/RAM应用到内核和系统分区中。
在图3中,将更新包302(可以是规范、增量更新或超级包,如后文所描述的)下载到系统RAM 304和/或用户数据存储210中,有可能在向设备用户通知更新可用的情况下,以手动或自动方式下载。这一般在图3中由标签为带圈的数字1的箭头表示。
由此,一旦在设备上安装了初始制造映象,通过更新被封装成包的映象的离散部分来完成对映象将来的更新。一般而言,包是映象文件(代码、数据、脚本等)的自描述集合,并且在一个实现中,它包括被签署并被包装用于分发的组件的集合。包提供了操作系统映象软件文件被分裂成文件的较小功能组的方法。在一个实现中,整个操作系统映象包括一个或多个包(不包括加载器组件),并且然后可仅作为较小的包的总和来处理,这些较小的包可被个别地管理、构建和更新,其每一个都可个别地或与其它包组合地更新,取决于每一包的需求。由此,依照本发明,映象更新不再需要作为整个操作系统映象区域来完成。
包可以各种方式来配置,包括“规范”、“增量/差”和“超级”形式,其每一个都服务关于软件更新的各种目的。例如,规范包包含包内每一文件的完整副本,而增量/差包包含仅包含基于该文件的较早版本的二进制差的一个或多个文件。增量/差包通常相对于其它包较小,并且由此在试图优化下载成本和下载时间时使用。超级包包含其它包,并在需要下载一个以上包(如,对于互相依赖的包)时为方便而使用。在一个实现中,包文件是Win32 CAB文件,它们包含清单文件(后文描述)以及定义诸如要安装的包的文件。
规范包在构建过程中通过将操作系统特征和元数据(如,特定应用程序的可执行代码和所有关联的数据和配置信息)与包定义相关联来生成。增量/差包通过向两个规范包的内容应用二进制差算法,并捕捉增量/差包在基线规范包版本上具有的依赖关系,从规范包生成。一旦操作系统映象特征和元数据被映射到个别的包,如上述美国专利申请“自描述软件映象更新组件”中一般描述的,通过使用包装工具来枚举包的内容,并通过处理可执行文件(用称为RelMerge的重定位工具)以令它们能够在将来被更新用于存储器相关的修正更新,创建每一包。
当用户引导更新过程时,包确认器核实包,如上述相关的名为“确定对安装有效的最大依赖软件更新集”和“确保软件更新仅在特定的设备或设备类别上安装或运行”的专利申请中所描述的。如果被确认,系统在闪存中设置更新标志,并重启。注意,如后文所描述的,保存更新标志,使得在丢失电源的情况下,一旦更新加载器代码引导,设备可重新进入更新模式。
在重启之后,初始程序加载器222看见更新标志被设置,并将压缩的更新加载器解压到RAM 304中,如图3中通过未压缩的更新加载器代码308所表示的,并将控制传递到更新加载器代码308。这一般在图3中由标签为带圈的数字2的箭头表示。注意,当更新加载器开始更新应用程序时,更新应用程序使用文件列表,或由updagebin.exe应用程序在设备重启前设置的一组目录规范重新运行确认过程。重新运行确认过程以预防包的恶意替换。
以内核包(如果有的话)开始,对于每一包,更新加载器处理该包、在需要时基于闪存考虑事项修正RAM分段310中的文件、并使用BINFS服务将文件写入其对应的分区中,如图3中通过标签为3到6的箭头所示的。修正在下文一般描述,并也在上述名为“自描述软件映象更新组件”的相关专利申请中有描述。
每一包包含设备清单文件400,它包含关于该包的详细信息,如图4中一般表示的。清单文件本质上是每一包的规范文件,并包含诸如包标识的全局唯一ID、包版本、与其它包有关的依赖信息、设置、包括在包内的文件列表和文件版本以及其它共享的公用特征等信息。清单文件400包括在包内,由此令包为自描述的,它在安装过程中被审阅,并最终储存在设备上。设备上清单文件的集合包括可枚举的设备上的包安装状态的数据库。
在对应于包含在图4所示的设备清单文件中的格式和信息的一个实现中,设备清单文件也用以下结构定义来描述



所创建的每一包为安全原因被签署,然后可用于下载/安装。如上述名为“自描述软件映象更新组件”的相关美国专利申请中所描述的,包生成过程/包生成器自动化了包含由包描述文件所定义的文件的完整版本的包文件的创建。一般而言,包生成器输入包定义文件(如,由命令行自变量指定);其它输入文件基于指定的包定义文件内容来确定。包生成器分析包定义文件(如,包括一个或多个包定义,每一包作为一XML文档条目编码),并可分析包含涉及与用于诸如注册表设置等设置的其它包有关的优先顺序的数据的包阴影文件。此外,包生成器分析构建清单文件以找出其中指定的每一文件,然后确定该文件的类型。对于可执行文件类型,包生成器调用执行重定位相关操作以及执行格式化(如,将可执行文件转换成WindowsCE文件格式)的过程(RelMerge)。
在一个实现中,包生成器包括使用名为如PkgCommon的.NET类库的应用程序。包生成器应用程序创建多个子目录,所创建的子目录的数量等于命令行中指定的包集合文件中的有效包的数量。每一包具有在包生成过程中为其创建的唯一的子目录。另外,包生成器在每一子目录中使用包定义内找到的信息创建另外的文件。对于每一包,创建一设备清单文件,该设备清单文件的名字从该包的GUID导出。对于每一有效的包定义,创建一包文件以包含包括该包的文件,包括设备清单文件。这些包文件符合微软的CAB文件1.3版格式。
安装过程大量使用设备清单文件的内容,既用于已安装在设备上的那些包,又用于被排队用于设备上的可能安装的那些包。包信息API被设计成提供查询包信息的抽象方法,并既在设备又在构建主机上使用。API在上述名为“确定对安装有效的最大依赖软件更新集”的相关专利申请中有详细描述。
管理对内核或系统分区的更新并将其传送到使用包机制的设备上。包被传送到设备、储存在临时存储中、并被排队用于通过任一合适的方法来安装,如通过现有的操作系统映象的组件。可使用用于将包传送到设备的任一合适的传输方法(物理和/或接口协议),并且方法可根据要更新的包而变化(如,对智能电话为无线,对智能显示屏为USB,对某些台式机更新应用通过某一物理连接,等等)。终端用户界面感受将根据所更新的设备的类型,以及由设备制造商定制的更新过程而变化。依照本发明的故障保险方面,每一临时包储存在持久存储中,使得在丢失电源的情况下,系统能够恢复并继续安装。
当调用包确认器库时,触发更新过程。在一个实现中,名为UpdateBin.exe的可执行文件与.pkg.cab、.pku.cab和.pks.cab文件扩展名相关联。这一可执行文件利用包确认器库来确定更新设备所使用的包的组。
包确认器检查包上的签名、确认包内容、核实版本等等。一旦更新包被认为是适当的,它们被排队用于安装,并且确认器设置更新标志以向设备发信号通知更新可用,然后重启系统。
在重启时,初始程序加载器222是从CPU的复位矢量起运行的第一个代码片段(尽管在某些设备中,初始程序加载器可由现有的引导加载器映象进行程序引导)。初始程序加载器222负责确定设备是否处于更新模式,或者设备是否处于正常引导模式。如果设备处于正常引导模式,则初始程序加载器定位并用程序引导操作系统映象,否则,初始程序加载器定位、解压并用程序引导解压的更新加载器映象308。图5A和5B描述了初始程序加载器引导过程。如图5A所示,在步骤502某些初始化之后(如,初始化CPU,如果是NAND则初始化控制器、初始化SDRAM等等),初始程序加载器通过步骤504和506确定复位的原因。更具体地,某些CPU体系结构在从挂起的状态继续执行时模仿重启序列。然后,引导代码通常基于CPU寄存器值将继续执行与“正常”引导区别开来。初始程序加载器调节继续执行操作,并且为了完整性示出步骤504-508。
如果不是继续执行,则步骤506分支到步骤510-528,如所见到的,检测更新模式,并且如果是更新,则扫描更新加载器分区(步骤520),否则在步骤518扫描操作系统分区。如通过522所见的,在初始程序加载器无法定位设备上的操作系统映象的情况下,初始程序加载器试图加载并运行更新加载器。如果未找到适当的分区,则输出错误(步骤532);注意在这一时刻,设备未使用正常的显示驱动程序等运行,由此,在这一时刻所显示的任何图像都是来自数据存储的位图。
此外,当引导到操作系统时,通过步骤524锁定闪存,该步骤在引导到更新加载器时不执行。过程然后继续到图5B的步骤538,以处理压缩和非压缩映象。注意,图5B可用于更新加载器或操作系统。更新加载器(在典型的设备上)以压缩形式储存,而操作系统可以压缩或不以压缩形式存储,取决于该设备是否是允许代码在原地执行的设备(如果是,则不能被压缩)。
如果被压缩,则从分区/映象检索关于该映象的各种信息,并且将该映象解压到RAM中,并通过步骤540-546开始执行。注意,可使用任一合适的压缩算法,只要压缩类型和压缩数据的格式是初始程序加载器所已知的。如果未被压缩,则步骤538在步骤544从分区扇区读取关于该映象的信息、从该扇区查找目录(TOC)、偏移和签名。为此,初始程序加载器具有主引导记录驻留在何处(初始程序加载器映象之后的下一好闪存块的起始)的先验知识,并在储存在主引导记录中的分区表中查找活动分区。由此,初始程序加载器依赖于具有正确地同时位于操作系统映象的原地执行区域以及更新加载器映象中的目录(TOC)的ROM映象/盘映象。在一个实现中,以下作为位置提供在字节偏移(映象起始+0x40)UNIT32 ROMSignature;UNIT32*pTOC;该信息由操作系统映象用于查找TOC(如由ROM映象/盘映象所放置的)。指针仅在存储器管理单元(MMU)被打开,且映射与对其构建操作系统映象的地址兼容时有意义。一种替换方案是如下实现在字节偏移(映象起始+0x40)UINT32 ROMSignature;UINT32*pTOC;UINT32 TOCOffset;其中,TOCOffset是从映象起始位置到TOC的字节偏移,并可由初始程序加载器(或更新加载器应用程序)用于在不知道该映象被构建于何处来运行的情况下查找TOC。
初始程序加载器也可检查签名,如步骤548所表示的。如果在步骤548无效,则引导过程在步骤550暂停,否则通过步骤552和554读取目录以找出映象起始、映象长度,并从目录跳至该地址。步骤558在必要时基于制造商供应的数据表修正该地址。更具体地,初始程序加载器通常运行在设备的物理地址空间(或有时候在不同于操作系统映象或更新加载器映象的虚拟地址空间中)。该例程负责将任何映象专用虚拟地址(如,操作系统映象TOC值)转换成与初始程序加载器兼容的地址。如果制造商的引导例程未启用存储器管理单元,这意味着将虚拟地址转换成物理地址。如果启用了存储器管理单元,并且映射与如何构建操作系统或更新加载器映象兼容,则不需要任何转换。
步骤558测试映象是需要被加载到RAM中(如果是,则在步骤562出现),还是可在原地执行。然后如步骤564所示的跳转至映象(加载的或原地)开始执行。采用活动分区的位置,初始程序加载器(如所设计的)在NAND(或可能是NOR)的情况下将活动分区(内核分区)的内容加载在RAM中,或者如果它是NOR(原地执行)内核,则跳至分区内的引导地址。如果是正常引导,则内核开始并继续加载同样位于内核分区内的操作系统组件,以指出操作系统能够从系统分区中读取。在这一点上不位于内核分区内的任何内容被从系统分区中取出(或者加载或者在原地执行),直到操作系统映象被完全引导。
在一个实现中,初始程序加载器是相对非常小尺寸的软件组件,它由CPU的复位矢量作程序引导,并负责有条件地加载/开始操作系统映象或更新加载器映象。如上所述,初始程序加载器需要能够读各种寄存器,包括RAM标志、闪存/非易失标志、以及硬件开关,以确定它是应当引导正常的操作系统映象还是更新加载器映象。更具体地,初始程序加载器需要检查由UpdateBIN应用程序(如,在确认之后)或由更新加载器应用程序设置的任何标志,因为通常操作系统映象以只读闪存文件系统运行。为适应电源故障条件,更新模式标志应当是非易失的,由此,如果无法在重启前储存非易失标志,则更新加载器应用程序在第一次运行时设置非易失标志,并在成功地完成安装之后清除该标志,由此令该标志跨电源故障得以持久保存。
此外,初始程序加载器需要以各种类型的存储技术分析存储分区结构,以查找映象,并能够处理压缩映象类型以及闪存XIP(在闪存中原地执行)和RAM映象(复制到RAM来执行)。一般而言,初始程序加载器抽象存储属性,如分区结构、保留的块、坏块等等,以及用于任一OEM提供的代码的任何存储技术的细节(如,NOR闪存、NAND闪存、HDD、DOC等等)。初始程序加载器可在以程序引导映象之前确认操作系统映象和/或更新加载器映象的完整性(如,通过执行校验和和签名核实),如检测恶意更新并由此提供核实用于数字权限管理的可信代码的方法,它需要信任从内核映象返回的UUID由未被恶意地篡改的代码提供。
由此,如图5所见的并如图3所示出的,当在更新模式时,初始程序加载器222将压缩的更新加载器220解压到RAM 304中作为解压缩的更新加载器308、保留闪存未锁定以给予解压缩的更新加载器308对系统闪存的写访问权限、并跳至解压缩的加载器代码以开始执行。当由初始程序加载器第一次以程序引导时,更新加载器应用程序需要在非易失存储中储存指示该设备处于更新模式的标志。这是因为操作系统映象可能具有只读闪存文件系统,并且无法设置该标志,而这对电源丢失恢复是重要的。初始程序加载器在确定是加载更新加载器映象还是操作系统映象时检查RAM标志以及这一非易失标志的存在;RAM标志由UpdateBIN应用程序(直接或间接)设置。
转向更新过程的解释,如上所述,用于更新内核或系统分区内容的过程在更新加载器被完全引导并加载到RAM之后执行,并操作以找出用户存储中所确认的包(如由确认器所指定的)。注意,更新加载器包含必要的文件系统驱动程序,并一次开始一个包的更新过程。用于更新包的包信息记录在文件系统中,由确认器在将来的更新中使用。依照本发明的一个方面,为提供故障保险更新,初始程序加载器能够从随机电源故障中在加载过程中的任一点上恢复。为此,在事务日志中跟踪更新进展,以允许万一在更新过程中出现电源故障能够进行卷进更新。
在更新模式中,更新加载器运行并开始更新应用程序,它是作为更新加载器映象308(图3)的一部分的可执行文件,并负责将包内容应用到NK/内核分区204和系统分区206。换言之,在更新过程中由初始程序加载器加载的更新应用程序负责将包更新应用到映象。注意,更新加载器映象包含更新应用程序所需的最小模块集,如nk、filesys、闪存驱动程序、coredll、IMGFS等等。
图6-8分别描述了整体更新过程、NK/内核分区更新的应用程序以及系统分区更新。更新应用程序与包确认器一起工作以确认包,并与ROMIMAGE模块一起工作以处理虚拟和物理分配、修正和安排功能。如图6所见的,更新应用程序在步骤600检索包安装列表(如,从注册表)、通过确认器确认包(步骤602)。在更新模式中,更新应用程序负责将包内容应用到NK/分区和系统分区。
在更新应用程序将包内容应用到非易失存储之前,确认包,这(尤其)包括签名检查以核实包来自可信源等等。如可容易地理解的,知道包更新来自可信源并确保存在对闪存有可写访问权限的单个可信监控者在试图包括设备的闪存的完整性时是重要的。更新包在构建过程中签署、并假定它们是由更新的许多可能不同的每一包可信源之一签署的、并允许继续通过上述包确认过程。如果它们未被签署或者不是由可信源签署的,则包确认失败并且由此不被更新。
注意,系统的设计是使得被允许更新闪存的内容的唯一软件组件也是负责检查被排队来安装(更新加载器)的任一包的有效性(包括检查签名)的同一组件。同样注意,更新加载器不能包括任何不可信或第三方代码,如通用操作系统。由此,该系统仅运行可信代码,并不易受篡改的影响。当未运行更新加载器时,该设计利用了禁止向闪存部分写入的硬件锁机制(在硬件层),而无需首先复位该部分(它通常依赖于CPU,并由此需要同时复位)。此外,操作系统映象包含文件系统的只读版本,由此进一步确保闪存的内容是不可更新的,除非系统处于更新加载器环境内,其中,确保包确认和安全检查得以执行。
核实也包括检查包内容的正确性、将设备清单文件中的信息与包内容相关、并确保文件(按名字)在一个且仅一个包内存在。确认也核实包的必要版本已安装在系统上或已被排队来安装。例如,如果包A的版本1.0已安装在系统上,并且增量/差包A将版本2.0变为版本3.0,则需要一个将包A变为版本2.0的包被排队来安装,以使该增量/差包得以安装。还满足包括核实必要的包依赖性的其它核实。例如,如果包A的版本2.0依赖于包B的版本3.0的内容,则核实检查后一包已被安装或已被排队并确认来安装。包确认过程也在上述名为“确定对安装有效的最大依赖软件更新集”的美国专利申请中有描述。
设备上确认过程的结果是可安装在设备上的包(及其文件)的列表,因为它们满足了确认需求。确认过程也生成不能连同关于对每一具体包确认过程为何失败的数据一起安装的包列表。安装过程的剩余部分仅利用通过确认的那些包。
返回到图6,更新加载器负责将任何更新应用到内核分区(步骤604和606),并将任何系统更新应用到系统分组(步骤608和610)。如果有其它更新,如存储器的保留的无线电分段(存在于分区的范围之外,即,唯一地位于闪存中的指定位置,其分区结构被定义为在保留区域“周围”),则它们通过步骤612和614被类似地处理,如参考图10所描述的。
包可通过步骤616来删除。在步骤618将标志设置成一个值(如cleared),以引导操作系统映象,当作出内核更新或系统更新时更新该系统映象,并重启系统(步骤620)。
图7A和7B示出了内核更新的一般逻辑,其中(假定原地执行),通过将现有的内核读入RAM中,并将其压缩到用户存储中,备份该内核。这由步骤700表示,其中,通过文件系统展示为具有一个默认文件的XIP文件夹的XIP分区获取其用于将整个映象读入本地缓冲器的句柄。在用户存储中创建新文件、调用压缩例程来压缩映象、并然后将压缩的文件数据写入新文件中。
步骤702读取头部和其它元数据。为此,该过程走查(walk)pToc(目录结构)以确定每一分段的位置、用模块信息填充旧模块列表、并设置分段数据指针以指向为备份所创建的RAM内副本中的适当位置。现有TOC的一部分被保存并被复制到接近NK/XIP分区更新的末端附近的新TOC中。注意,当读模块的头部时,该过程也读旧设备清单文件以查找额外的标志(压缩、内核模块、插槽1忽略[L标志]等等)。
通过步骤704和722,随后通过处理包中的每一模块(步骤706和720)、确定该文件是否为bindiff(二进制差)模块来处理每一包。这涉及循环通过每一包中的每一模块,并应用规范更新,其中提供了新文件的整个副本;或应用二进制差更新,其中仅提供文件的二进制差。应用二进制差的过程被称为patchbin(打二进制补丁);单独的二进制差在每一分段中完成,每次完成一个。新模块的头部以原始的规范形式提供。当逐个更新文件时,它们被添加到(以文件对象的形式)新文件列表。在该步骤的最后,存在包含更新模块和文件的未修正版本的新文件列表。如果它们是现有文件,则将它们从旧列表中移除,使得在该步骤的最后,旧列表仅包含对其没有更新的文件。注意,该过程基于该分区中包清单文件的存在知道哪一(些)包与该分区相关联。尚未在设备上安装的任何新包被保存在IMGFS分区中。
由此,在步骤708,如果不是二进制差模块,则只要在步骤718将该模块添加到新列表。如果是二进制差模块,则需要向旧代码应用这些差,对每一分段各个挨次地执行步骤710-716。
更具体地,如上所述,增量/差包包含一个或多个二进制差文件,每一二进制差文件对应于一特定的文件/模块。该差文件基于它在安装时刻被更新的特定基线版本,并且二进制差文件通常小于所得版本的整个正规文件,由此,它改进了下载时间/成本,并减少了安装过程中需要的临时存储额外开销。二进制差文件在构建时刻基于检测两个不同的规范包之间的文件/模块的差异来生成。如果文件是可执行模块,则它们由链接器处理,并位于链接器定义的地址中。它们尚未被重定位到最终的位置,这如上所述地将在安装时刻在设备上完成。
为使可执行模块的二进制差能够应用到已在设备上的基线版本,该基线版本需要被解除重定位,返回到从其计算该二进制差的链接器生成的基地址。一旦向模块的解除重定位版本应用了该二进制差,它可被重新定位到适当的基础虚拟地址。解除重定位和重定位的过程是相同的,并通过将模块的基地址移位到特定的位置来完成。
当处理了每一包之后,内核更新继续到图7B的步骤724,其中,尚未被修改的任何模块被添加到新模块列表。在这一点上,旧文件列表包含将不被更新的模块和文件;这些需要被解除修正,返回到原始基地址,使得存在可被整体处理的未修正模块和文件的一个统一列表。旧文件列表中出现在新设备清单文件中的对象被转移到新文件列表。注意,如果文件要被删除,则它不在新设备清单文件中出现,并因此不被放入新模块列表中。
存储器分配和修正在步骤726和728执行,并且在步骤730将新的原地执行内核映象写回闪存中,这也由盘映象工具完成,并在romimage.dll中实现(如下所述)。romimage中存在一个功能,它采用模块列表,并通过分配新缓冲器构建新映象、循环通过模块列表以复制由数据指针指定的适当位置处的分段数据并将头部和文件名串复制到目录(TOC)中指定的正确的位置,来构建新映象。如后文所描述的,在映象的末端写新TOC,并更新pTOC指针以指向放置新TOC的位置。同样如后文所描述的,跟踪插槽0中的数据分段带用于NK/XIP映象,它与IMGFS带连接,并在IMGFS更新过程中被输出到包含ROMINFO结构的IMGFS文件中。
在向闪存写出任何内容时,该过程在日志文件中记录写正在进行中。一旦写完成,它被记录,由此,如果在删除备份文件之前丢失电源,也知道正确的状态。
如果整个过程都是成功的,则在步骤732删除备份文件,这包括在删除该文件之后向日志文件写入XIP分区完成。如果在NK/XIP更新过程的任一步骤出现了错误,诸如如果映象增长超过了分区的大小,则恢复该映象的备份版本,且合适的用户界面指示在更新过程中出现错误并恢复原始映象。如果不能成功地写入备份版本(如,在闪存错误中),则提供一个不同的UI消息以指示在更新过程中出现了错误,但是原始映象无法被恢复并可能被破坏。
同样,记录更新的状态用于UpdateBin。注意,这是不同的,更新应用程序所使用的日志文件是内部地用于事务记录的。
在这一点上,存在组成该映象的模块和文件的单个文件列表。这与由盘映象工具结合romimage.dll所执行的初始安装相同,如在上述名为“以存储技术抽象方式在文件内创建文件系统”的美国专利申请中所描述的。
在较高的级别上,包安装过程涉及提取包内容并将其应用到设备。然而,这些机制包括主要围绕代码修正或代码重定位的概念的若干步骤。本发明在安装时刻在设备上执行修正和重定位,而非在构建时刻在构建系统中执行。一个益处是对特定系统的包安装能力,因为安装不需要整个设备映象在构建时刻可用。相反,它允许包更新被作为从安装在设备上的特定操作系统映象配置很大程度隔离的实体来处理。
为使可执行模块可被重定位,模块需要包含指导定位器在模块的基地址定位改变时在需要被更新的模块内寻址的信息。映象更新模块利用重定位信息编码模式以在可执行模块本身内以压缩的形式提供这一信息。
如在上述美国专利申请“自描述软件映象更新组件”中所一般描述的,RelMerge工具将模块(.EXe或.DLL)转化成适合包括在包内,并因此可被安装到设备的格式。这包括将重定位信息转化成更适合在设备上长期储存的压缩格式,并将文件头部转化成由设备上的ROMFS文件系统使用的_rom变量。另外,当重新布置时,任何过剩的填充也被从文件的所有分段中移除。
一旦用这一信息编码,可改变可执行模块的基础虚拟地址,并可修改模块内所有相关的地址引用,以解决基地址中的变化。重定位过程利用在设备和台式机之间共享的代码库。在后一情况下,它用于创建初始制造映象,使得在代码模块上执行实际的重定位,并也用于创建当安装每一更新模块时所使用的虚拟地址空间的列表,由此,允许API的消费者相信模块重定位不会重叠。通过盘映象工具和romimage.dll组件创建初始制造映象在上述名为“以存储技术抽象方式在文件内创建文件系统”的相关的美国专利申请中有描述。
一般而言,虚拟/物理分配和修正与盘映象工具相同地工作,即,定位来自NK/XIP映象的旧目录(TOC)并定位旧ROMINFO。在映象中的固定位置(如,偏移0x44)上定位指向TOC的指针。从称为“.rom”的IMGFS文件中读取旧ROMINFO结构。
为分配虚拟地址,插槽0分配器以插槽0的顶端开始,并基于IMGFSROMINFO结构中的值dwSlot_0_DllBase结束。插槽1分配器以插槽1的顶端开始,并基于IMGFS ROMINFO结构中的值dwSlot_1_DllBase的值结束。然后将代码和数据修正成新的VA分配,并且令整个模块列表可用。压缩被标记成压缩的分段,并将其大小记录在模块对象中。
为向映象分配物理空间,对RAM使用RAMIMAGE,并对闪存使用ROMIMAGE。对于RAM,RAMIMAGE物理分配器使用旧TOC的physfirst作为物理分配器的起始地址。物理分配器的末端最初被指定为旧TOC的ulRAMEnd。对于RAMIMAGE,由物理分配器返回RamStart=PhysFirst+PhysLength(映象所需的实际长度);确定副本分段的虚拟地址位置从RamStart开始,并且从那里开始,涉及副本分段的文本/数据被修正。
对于ROM,ROMIMAGE物理分配器使用旧TOC的physfirst用于物理分配器的起始地址,而物理分配器的末端通过使用GetPartitionInfo获取闪存上的分区的长度来确定。
注意,更新的TOC在物理分配过程中生成。
与XIP分区不同,在IMGFS分区中,不重新作出整个映象,因为这太大以至于无法备份。相反,IMGFS文件系统用于向个别的模块和文件应用更新,每次更新一个。此外,注意,个别的模块和文件可能太大,以至于无法作为一个整体来完成,则可通过较小的块应用更新,如后文参考图9所描述的。
IMGFS更新使用NT更新所使用的同一文件列表,尽管当过程前进时一个列表将被更新。如后文所描述的,IMGFS首先模拟更新进程,需要两次通过该过程。在第一遍中,IMGFS和更新应用程序都不向闪存提交任何内容。如果模拟成功,则运行第二遍以实际提交改变。如果模拟失败,则在重新运行包确认器之后重试模拟,并传入不包括失败的包的包列表。然后用包确认器返回的新列表再次运行模拟。重试模拟,直到模拟成功,或者没有可应用的任何包为止。这预防可能在尽管有破坏但仍被签署的包内出现的数据破坏。
图8A和8B示出了系统分区更新的一般逻辑,其中,更新应用程序与映象文件系统驱动程序(IMGFS)的读/写版本接口,以管理系统分区。注意,在典型系统的正常(非更新)操作中,系统分区对于IMGFS驱动程序是只读的(并且闪存被锁定)。此外,注意,与内核更新不同,系统更新不作为整体来备份,尽管事务日志可将设备恢复到故障(如电源故障)之前它在系统更新过程中的位置,并且系统更新可以从那一点上继续进行。
在步骤800,扫描系统分区(imgfs区域)中的现有模块,并将它们添加到虚拟地址(VA)分配器。在扫描过程中,该过程也检测删除情况。更具体地,当使用现有设备清单文件反复通过IMGFS中的模块时,该过程检查来看文件是否在该包的新设备清单文件中出现。如果不是,则将该文件从IMGFS分区中删除,并且过程继续下一文件。如果是,则从新设备清单文件获取新模块标志,并且使用IOCTL_BIN_GET_E32和IOCTL_BIN_GET_O32将模块头部加载到模块结构中。注意,在此时,不读入用于模块和文件数据的数据,因为并不需要。一旦读入了每一模块头部,则将该模块列表传递到分配器以保留虚拟地址(包括从存储在闪存中的保留表中得知的保留的分段)。
一旦扫描了现有模块,并且定义了当前分配的虚拟地址,该过程已准备好开始更新。为此,过程循环通过每一包(通过步骤802和828),并循环(通过步骤804和826)通过包内的每一文件,逐个处理每一文件。文件以大小的净增益的顺序来处理,从收缩最多的文件开始,并以增长最多的文件结束。文件大小的增量通过将旧设备清单文件与新设备清单文件相比较来确定。
如果在该过程中丢失电源,则日志文件将确切地告知该过程停留在哪一包以及包内的哪一文件上。该过程在所停留的文件处继续进行,在电源故障这一点上已完成的更新文件被作为现有文件处理。为恢复,更新过程中的任何新模块不被包括在初始保留中,而旧模块在保留中。旧模块虚拟地址空间被如常地解除分配。如果新头部已被写出,则它将包含用于该新模块的虚拟地址空间分配。在这一情况下,使用Reserve(保留)函数将其添加到虚拟地址空间分配器。如果新头部尚未被写出,则使用Allocate(分配)函数如常地分配新虚拟地址空间。
上述处理的一部分包括(对于可执行文件,而非数据文件)更新用于更新模块的虚拟地址分配,这通过确定虚拟地址是否改变,并且如果是,则如步骤806所示,解除分配旧虚拟地址空间并且用于新模块分配虚拟地址空间来完成。如果虚拟地址大小改变,则调用Deallocate(解除分配)函数从分配器移除旧虚拟地址空间,并调用Allocate(分配)函数为新模块分配新虚拟地址空间,根据代码或数据传入适当的对齐要求。解除分配可对应于删除模块的命令,在这一情况下,通过步骤808和824删除旧模块,(但是如果它是刚安装的新模块,则不删除)。如果不是删除命令,则步骤810在IMGFS调用CreageFile(创建文件)函数,例如在命名新文件时使用new_<module_name>.<module_extension>,以在映象文件系统中创建新文件;(为在电源在这一操作附近故障时恢复,如果该文件已存在,则不再创建它)。
对于可执行文件,步骤812通过使用IOCTL_BIN_SET_E32和IOCTL_BIN_SET_O32将新头部读入模块对象中,并用新虚拟地址空间分配更新该头部来向可执行文件写入适当的头部,如步骤812所示的。每一操作在IMGFS中是原子的。在这一点上,头部应当是完整的。不管数据指针(dataptr)(为0),因为当内核请求E32/O32时IMGFS伪造该值。头部是规范形式,甚至是在二进制差文件中。
如果在写头部时丢失电源,如果两个头部都存在,则不需要完成任何恢复。如果仅写出了E32头部,则仅需要再次写出O32头部。每一头部的存在可通过IOCTL_BIN_GET_E32和IOCTL_BIN_GET_O32来知道。
为应用更新,注意到对文件的更新可以是规范形式或二进制差形式。如果更新的文件不是模块,则以与个别分段相同的方式处理该文件的数据。如果该文件是模块,则以净增益的顺序处理每一分段,每次处理一个,以收缩最多的分段开始。首先处理.creloc分段。每一分段被写到一个新流。如果文件是常规数据文件,则该数据被写入默认流中。
如果如在步骤814所评估的,模块是规范更新,则步骤816-822处理模块中的每一分段,包括将整个分段重定位到由虚拟分配器所分配的地址(步骤818),并将整个分段作为新的流写入新IMGFS文件中(步骤820)。然后在步骤824删除旧模块,除非旧模块实际上是新模块。
在规范的情况下,通过获取被写出的文件中的每一流的大小,并将其与规范文件中的该分段的大小相比较,来执行对电源故障的恢复。如果新文件中的流小于规范文件,则这就是过程所停留之处,并可继续进行在数据上复制。
在二进制差的情况下,每次对一个块完成patchbin(打二进制补丁)程序(如后文参考图9所描述的),其中,一个块等于页/扇区大小。这是由于可能没有足够的闪存空间来同时保留分段的旧和新版本。可以如由二进制差文件所指定的任何顺序创建新文件的块,使得可以通过优先使用闪存空间来完成patchbin的过程。当创建新块时,旧块可被解除分配,因为它们不再需要。
为此,如果在步骤814,模块不是规范更新,则过程分支到图8B的步骤832,其中,结合步骤852,循环通过该模块中的每一分段,以在逐块的基础上应用二进制更新。更具体地,步骤834为该分段在新模块文件中创建稀疏流,并且将旧分段读入RAM中(步骤836)。整个旧分段被重新定位回到原始的基地址(步骤838)。
对于二进制差文件中的每一新块(步骤840和850),基于二进制差命令构建新块(步骤842)。新块在步骤844被重定位到由虚拟地址分配器分配的地址上,并且在步骤846被写出到稀疏流中。旧文件流中不再需要的任何旧块被解除分配,如由步骤848所示的。块更新的概念也在下文参考图9描述。
在二进制差的情况下,电源故障通过缩小停留在哪一分段的范围来处理,这通过将流大小与头部中所指定的大小相比较来完成。一旦确定了分段,如常创建patchbin的实例。当顺序返回下一块时(patchbin输出必需是可再现/可确定的),检查该块是否被提交。由于块写是原子的,无法提交部分块。如果块已被提交,则丢弃从patchbin返回的数据,并且执行核实以检查适当的旧块已被解除提交。一旦找到所停留的块,(即,尚未被提交的块),则过程如常继续。
为结束,如果这是现有的文件或块,并且是二进制差情况,则删除旧模块(在规范情况下,该文件已被删除),并且日志文件记录该模块已完成。如果包已被完成,则代之以记录这一情况。当完成了所有的包时,用更新的ROMINFO结构更新.rom文件,它包含插槽0基础、插槽1基础和用于NK/XIP和IMGFS映象两者的插槽0数据带。
如果在IMGFS更新过程的任一步骤中出现错误,如,如果二进制差没有足够的闪存块可用,则取消更新过程,并且不尝试恢复,因为它可能是无法恢复的,并且显示适当的消息。注意,预先运行模拟可避免这一问题。
如所见的,对内核分区的更新从更新到系统分区被不同地处理,尽管从构建和包装观点来看,它们是相同的。更具体地,当更新内核分区时,从闪存中取出某些NK.NB0(签署的内核分区映象)文件到RAM中、在适当时更新并修正成分组件、然后将修改的.NB0内容以连续的块写回闪存中。这允许在需要时跳过任何坏块。
依照本发明的另一方面,如上所述,这些机制考虑如何应用二进制差文件的优化顺序的概念。如所理解的,需要某些临时填充存储器,以向基线映象应用二进制差文件,并由此生成所得的更新的模块/文件。在构建时,当生成二进制差文件时,在所得的映象上运行排列过程,以排列更新二进制差文件中的块的顺序,使得保留必要的可用临时填充存储器到某一指定的最大值。通过在构建系统上执行这一优化操作,本发明确保了如果设备具有足够的存储器用于映象的整体增长(或收缩),并且它具有必要的临时填充空间,则设备一定具有足够的存储器来完成更新过程。在开始更新之前,在确认过程中执行大小检查。
图9一般表示了块更新概念。一般而言,系统文件较大,并且由此,如果整体创建新文件,并且向旧文件整体应用二进制差,则会消耗大量的临时存储(大于可用的临时存储)。相反,向要更新的文件的现有块应用差更新,能获得新的更新的块,将更新的块复制到更新的文件流中,并在不再需要时解除分配旧块。
为实现块更新,构建旧块和新块之间的依赖图,这由图9的图900来一般表示。如所理解的,差文件902将被应用到由该图中的节点所表示的数据的实际块中。在一个实现中,块为四千字节大小,并且任一时刻最多允许32个块,这意味着仅需要128千字节可用来确保系统可被更新。注意,上述的示例块大小和整体限制是任意值,但是需要由系统更新和设备的更新应用程序的提供者同意。在特定更新无法满足所同意的限制的情况下,在销售商处构建更新的过程中,需要由销售商断开依赖链接(对这样的块不需要非差更新)。
如图9所示,单个旧更新块可提供一个或多个新更新块的依赖数据(向这些数据应用差文件),并且新更新块可依赖于一个或多个旧更新块。一般而言,更新通过向旧块应用适当的一个或多个差文件,直到应用了该旧块的每一差文件来进展。在这一时刻,可断开依赖链接(如,如由图9所示,通过断开旧块X和新块Y之间的链接),由于旧块不再为新块所需。由于这是与旧块X相关联的唯一链接,因此可解除分配旧块X以释放空间用于另一块。同样,由于在向旧块应用了差文件之后断开依赖链接,当新块没有到旧块的依赖链接时,即,当新块完全通过差更新过程被写入时,该新块可在适当时被复制到闪存,并从RAM中解除分配,以释放空间用于另一块。注意,可在同一时刻解除分配多个块。
如可容易地理解的,应用差更新的顺序可帮助存储器的释放。一般而言,该顺序为首先向对具有最多依赖链接的新块具有最少依赖链接的旧块应用差更新。一种算法对具有最高计数新块的最低计数旧块执行二级搜索(如,链接计数器数组的搜索)。
对于对块更新执行预闪存模拟,由于整个文件可能不在模拟中在任意时刻存在,因此基于要写入的每一块计算校验和,并且对照每一更新的校验和核实所得的校验和。如果该模拟生成的校验和通过,则可执行对闪存的实际更新。
转向更新保留分段,图10示出了保留分段更新(如,在分区之外)以类似于NK分区更新的方式使用同一更新组件完成。通过步骤1000和1016,通过处理包中的每一文件(步骤1002和1014)来处理每一保留相关包更新,确定该文件是否为bindiff(二进制差)模块。如果不是,则只要在步骤1010和1012将文件数据从文件读出并写入保留的区域中。如果是二进制差模块,则读现有的区域(如,读入RAM)中并在向保留的区域写回更新数据之前向其应用二进制差,如由步骤1006、1008和1012一般表示的。
当以适当的顺序(按照包版本)应用每一排队的包的包内容,并且更新完成时,包文件可任选地从用户存储中移除,或被标记为完成。在这一时刻,一旦确认的包的内容被安装到适当的闪存分区中,更新应用程序通过禁用更新模式(清除闪存更新标志)完成其工作,并且重启设备。在以前,初始程序加载器检测当前系统模式,但是此次,由于清除的标志,以锁定的闪存来如上所述地引导更新的操作系统映象,并且安装完成。
依照本发明的一个方面,提供了故障保险/恢复更新方法。为此,映象更新设计的一部分提供了如由于意外的电源丢失而使更新过程被中断的情况下的故障保险恢复。实现故障保险恢复的方法包括通过记入日志和文件系统人为因素(如,卷进恢复)使得重新进入令更新加载器和更新应用程序,并能够决定更新操作停留在何处。同时调节的是支持向文件写入更新而无需完全解除提交旧副本直到向存储提交了新更新(这以系统分区中的子文件增量完成,如,块)的事务文件系统。可执行到提交到存储这一点上的整个安装过程的模拟以确保已实行了几乎所有相关的代码路径,而将实际更新上的故障模式降低到硬件(如,闪存故障)中的故障或低级闪存软件例程中的可能故障。提供NK/内核的备份和保留的(如,无线电)区域,使得在更新失败的情况下,在某些具体数量的重试之后,可恢复原始映象分区内容的备份,并中止安装(即,卷回恢复)。
更新应用程序跟踪安装进展、在意外中断的情况下重新获得它所停留之处、并备份(并可能恢复)NK/内核和保留的区域。更新应用程序更新RAMIMAGE、ROMIMAGE、IMGFS和保留的映象。RAMIMAGE和ROMIMAGE分区以与台式机盘映象工具生成分区的同一方式生成,即,IMGFS分区通过用现有的布局工作以及对IMGFS和分配器作出调用以虚拟和物理地正确排列更新的模块来更新。上文参考图10所描述的保留更新通过覆写整个区域来作出。
在一个实现中,当更新应用程序开始时,它假定要安装的包位于临时保存目录中,如用户存储中的更新应用程序输入文件中所指定的,它包含用于更新应用程序的输入。更新应用程序输入文件的路径在注册表中指定。更新应用程序不关注包存储在何处,无论它是内部数据存储还是外部存储卡,只要提供了完整的路径用于保存目录。同时提供的是到用于更新的位图文件的路径;注意,正常的操作系统代码不在运行,并由此,为用户界面目的提供了位图(如,示出进度条、正在更新哪些文件、错误消息等等)。
更新应用程序通过将保存目录路径传递到包确认器开始,它返回指定安装包的顺序的列表,如在上述名为“确定对安装有效的最大依赖软件更新集”的相关美国专利申请中所描述的。然后,更新加载器处理重复通过每一包,并应用适当的更新-XIP、IMGFS和/或保留,如上文参考图6所描述的。
更新应用程序可被认为具有若干进程/组件,包括负责对NK/XIP分区的更新的NK/XIP更新进程。该分区中的映象可以是ROMIMAGE或RAMIMAGE(其中,ROMIMAGE是直接从闪存中执行并需要NOR闪存的映象,而RAMIMAGE是被加载到RAM并可储存在NOR或NAND闪存中的映象)。无论映象的类型如何,在读和写时,区域更新直接与块驱动程序接口。
映象的另一进程/组件是IMGFS更新,它负责对操作系统分区的更新,由映象文件系统(IMGFS)管理。保留更新进程负责对无线电或其它保留区域的更新。保留区域更新在读和写时直接与块驱动程序接口。
Romimage是当制造设备时提供初始安装映象的共享组件(与台式机盘映象工具共享),并负责虚拟和物理(存储)分配和模块修正。Romimage.dll包含用于创建并管理多个分配器的Allocator(分配器)类分层结构和功能、用于创建并管理文件列表的File(文件)类分层结构(用于储存关于文件或模块的元数据)和功能、以及支持更新和构建过程的功能。Patchbin组件提供应用二进制差更新来生成新文件的过程。旧模块数据和二进制差作为输入提供给该组件,并且其输出是用于新模块的数据。可提供UI组件以在更新过程中显示适当的用户界面数据。注意,可视内容可基于操作系统地区设置预先生成。
NK/XIP更新过程可以是由更新应用程序的主函数调用的函数,它采用NK/XIP包的列表来应用。对NK/XIP分区的更新需要更新应用程序重新作出完整的映象(实际上为设备上的盘映象工具过程)。在NK/XIP更新过程中,维护旧文件列表和新文件列表。旧文件列表用NK/XIP分区中的当前模块来初始化,该信息结合包一起使用来创建新文件列表作为最终结果。新文件列表包含创建映象所需的信息(头部、分段数据、标志等等),并且该列表被传递到虚拟和物理分配器来重新执行分配过程。
上文描述的图7A和7B输出示出了内核区域如何被更新。为概括图7A和7B的步骤,该过程将整个XIP(或其它)区域读入RAM中并将其备份为用户存储中的压缩文件、扫描XIP区域中的现有模块以读取头部和其它元数据并构建更新模块和文件的未修正版本。该过程然后将未被修改的模块和文件的剩余部分添加到新模块列表、执行虚拟/物理分配和模块修正、并将新XIP映象写回闪存中。
该步骤中的故障保险方法是相当明了的,因为不向闪存提交任何内容直到过程结束。因此,如果在写入新映象之前出现电源故障,只需重新执行该过程。如果在写出新映象时出现电源故障,旧映象的备份副本仍存在,并可用于恢复映象(如果日志文件指定新映象处于被写出的过程中,则可使用压缩的备份文件来恢复旧映象的副本)。日志文件记录事务中的步骤,令其明了以知道过程在何处失败。
权利要求
1.在计算设备中,一种方法,其特征在于,它包括确定是将所述设备引导到操作系统模式还是更新模式;以及当所述设备被引导到所述更新模式时,对所述设备存储中的映象执行至少一个更新,同时将所述更新的状态记入日志,以便能够从每一更新过程中可能出现的任一故障中恢复。
2.如权利要求1所述的方法,其特征在于,确定是将所述设备引导到操作系统模式还是更新模式包括检查一在重启之前设置的标志。
3.如权利要求1所述的方法,其特征在于,所述映象被划分成至少两个分区,并且其中,通过为一选择的分区构建一替换映象、并将所述替换映象覆写到所述分区中的现有映象上,更新所选择的分区。
4.如权利要求3所述的方法,其特征在于,它还包括将所述分区中的所述现有映象备份成一备份映象,确定写所述替换映象是否成功地完成,如果不是,则从所述备份映象恢复所述现有映象。
5.如权利要求4所述的方法,其特征在于,备份所述现有映象包括以压缩形式储存所述备份映象。
6.如权利要求1所述的方法,其特征在于,所述映象被划分成至少两个分区,并且其中,通过单独地更新所述映象中的至少两个组件来更新一选择的分区。
7.如权利要求6所述的方法,其特征在于,所述分区之一是系统分区,并且其中,单独地更新所述映象中的至少两个组件包括将操作系统文件写入所述分区中。
8.如权利要求1所述的方法,其特征在于,执行所述至少一个更新包括向一现有组件应用一二进制差文件。
9.如权利要求8所述的方法,其特征在于,向现有组件应用二进制差文件包括向所述现有组件的一个子集应用所述二进制差文件的一个子集。
10.如权利要求9所述的方法,其特征在于,所述子集包括一具有确定大小的数据块。
11.如权利要求9所述的方法,其特征在于,执行对映象的至少一个更新包括在提交所述更新之前模拟一更新过程、及确定所述模拟成功。
12.如权利要求1所述的方法,其特征在于,一组更新中的所述更新在包中的文件和文件上个别地执行,并且所述个别包和文件信息被记入日志,使得在任一故障之后,访问所述日志文件确定所述故障出现在哪一包以及包中哪一文件上。
13.一个或多个具有计算机可执行指令的计算机可读媒质,当所述指令被执行时,执行权利要求1所述的方法。
14.在计算环境中,一种方法,其特征在于,它包括将一操作系统映象分裂成单独可更新的分区;以及与另一分区隔离地更新至少一个分区。
15.如权利要求14所述的方法,其特征在于,更新至少一个分区包括将计算设备引导到更新模式。
16.如权利要求14所述的方法,其特征在于,与另一分区隔离地更新至少一个分区包括为第一分区构建一替换映象并将所述替换映象覆写到所述第一分区中的现有映象上、及通过单独地更新第二分区中的映象的至少两个组件来更新所述第二分区。
17.如权利要求16所述的方法,其特征在于,它还包括将所述第一分区中的所述现有映象备份成一备份映象,确定写所述替换映象是否成功完成,如果不是,则从所述备份映象恢复所述映象。
18.如权利要求17所述的方法,其特征在于,备份所述现有映象包括以压缩的形式储存所述备份映象。
19.如权利要求16所述的方法,其特征在于,更新所述第二分区包括将所述每一更新的组件的身份记入一日志文件中,使得如果出现故障,访问所述日志文件确定所述故障出现在哪一组件上。
20.如权利要求16所述的方法,其特征在于,更新所述第二分区包括向一现有组件应用一二进制差文件。
21.如权利要求20所述的方法,其特征在于,向现有组件应用二进制差文件包括向所述现有组件的一个子集应用所述二进制差文件的一个子集。
22.如权利要求21所述的方法,其特征在于,所述子集包括一具有确定大小的数据块。
23.如权利要求16所述的方法,其特征在于,更新所述第二分区包括在向所述第二分区提交更新之前模拟更新过程、及确定所述模拟成功。
24.一个或多个具有计算机可执行指令的计算机可读媒质,当所述指令被执行时,执行权利要求14所述的方法。
25.在计算设备中,一种系统,其特征在于,它包括一引导机制;以及一更新加载器,在检测到一待决更新时所述引导机制引导到所述更新加载器,所述更新加载器包括所述设备代码中对所述设备的受保护存储器具有写访问权限的唯一实体,所述受保护的存储器包括至少两个分区,并且所述更新加载器单独地更新每一分区。
26.如权利要求25所述的系统,其特征在于,它还包括一确认进程,其中,在引导到所述更新加载器之前,所述确认进程确认至少一个更新包,如果所述至少一个更新包有效,则所述确认进程将每一有效包排队来更新,并设置一所述引导机制用于检测所述待决更新的机制。
27.如权利要求26所述的系统,其特征在于,所述确认进程通过核查每一包被正确地签署来确认所述至少一个更新包。
28.如权利要求26所述的系统,其特征在于,所述确认进程通过核查每一包被正确地构造来确认所述至少一个更新包。
29.如权利要求25所述的系统,其特征在于,所述引导机制基于一在重启之前设置的标志值将所述设备引导到所述更新模式。
30.如权利要求25所述的系统,其特征在于,所述设备的受保护的存储器被划分成多个分区,并且其中,由所述更新组件通过为一选择的分区构建一替换映象,并将所述替换映象覆写到所选择的分区的现有映象上,更新所选择的分区。
31.如权利要求30所述的系统,其特征在于,所述更新组件将所选择的分区中的所述现有映象备份成一备份映象,用于如果所述替换映象未被成功地写入所选择的分区时恢复到所选择的分区。
32.如权利要求31所述的系统,其特征在于,所述更新组件以压缩的形式备份所述现有映象。
33.如权利要求30所述的系统,其特征在于,所述设备的受保护的存储器被划分成多个分区,并且其中,通过由所述更新组件单独地更新一选择的分区中的至少两个组件,更新所选择的分区。
34.如权利要求33所述的系统,其特征在于,所述更新加载器通过向一现有组件应用一二进制差文件更新所选择的分区中的组件的至少一个。
35.如权利要求34所述的系统,其特征在于,所述更新加载器通过向所述现有组件的一个子集应用所述二进制差文件的一个子集来应用所述二进制差文件。
36.如权利要求33所述的系统,其特征在于,所述更新加载器在提交所述更新之前模拟至少一个更新。
全文摘要
所描述的是一种系统和方法,其中,以故障保险的方式向一嵌入式设备的失非易失存储应用自包含、安全实体形式的软件更新。可应用各种类型的软件更新,并且更新可包含可执行代码和/或数据。在重启之后,初始程序加载器确定更新模式,如果是更新,则引导到一特殊的更新加载器。该更新加载器处理更新包来应用更新。可用整个文件或二进制差文件来更新内核分区、系统分区和保留分区,对每一类型的更新提供故障处理机制。可在提交更新前模拟更新。更新可在对设备适当时在存储器内重定位。
文档编号G06F9/445GK1641582SQ20041010201
公开日2005年7月20日 申请日期2004年12月16日 优先权日2003年12月16日
发明者A·罗杰斯, J·格罗姆, M·普拉格, M·同科洛维茨, M·马克雷, S·帕特尔, S·谢尔 申请人:微软公司

最新回复(0)