背景技术
在分布式系统环境中,通常需要对不同类型、不同功能的多个处理机节点进行快速、批量部署不同的版本。由于通信领域的产品比较复杂,网元、物理单板种类繁多,而且同一物理单板在不同网络环境下可以完成不同的逻辑功能处理,例如:开局时需要大规模的版本批量部署;版本更新时需要大量的单板版本升级。在这种情况下,就特别需要提供一种通用、灵活、高效的方式来支持分布式环境中众多不同类型的处理机版本的下载、启动和更新。由于存在上述需求,版本管理应运而生。
版本管理是分布式系统的一个重要功能组件,主要完成分布式环境下各个处理机版本的配置、查询、下载和启动(包括启动参数的传递)。版本管理通常采用服务器-客户端模型,由统一的版本服务器对不同的处理机节点的版本进行集中管理,每个处理机上运行版本管理客户端。版本管理客户端负责本地物理配置信息的上传,从版本服务器查询和获取处理机功能版本信息,并下载和启动相应版本。
分布式系统中通常将版本管理集成到本地存储的启动加载程序(以下简称为boot)里,主要提供版本管理客户端运行的基本环境,比如配置单板IP地址和运行FTP客户端等基本网络功能。在boot启动之后,版本管理客户端可以进行版本信息的配置、查询,并从版本服务器下载和加载版本、获取启动参数等。
参见图1和图2,介绍了VxWork系统中现有的三阶段上电启动过程,该三阶段包括:固件上电自检阶段、boot版本管理阶段和内核启动阶段,其中
1)固件上电自检阶段,固件也可称为“BIOS”。系统引导过程从硬件加电启动开始,一些初始化工作完成后,控制转到固件。固件检测并配置平台芯片组、存储器控制器、总线桥、中断控制器和其他的低级硬件。
在本阶段中,系统花费了大量的时间。固件基于设置将控制移交给一个引导装载程序,在普通PC上是主引导记录MBR(Master Boot Record,主引导记录),在嵌入式领域通常是烧制在Flash上的boot;
2)boot版本管理阶段,在boot里面集成了版本管理功能。通常boot是一个相对比较完善的小内核,具有基本的IP、MAC(Media Access Control,介质访问控制)配置功能和TFTP/FTP(简单文件传输协议/文件传输协议)下载功能。固件阶段BIOS把Flash上的boot加载到内存某位置处,并跳转到boot入口执行。boot执行Vxworks的一些公共代码和硬件初始化工作;然后激活VxWorks内核,执行VxWorks内核指定的根任务;开始阅读和执行用户输入命令。根据用户是否有输入决定是否进入版本管理界面。如果用户有输入,则进入版本管理,用户可以对版本进行配置。配置完成后开始内核的下载和加载,并跳转到内核的起始位置执行。
3)VxWorks内核启动阶段,VxWorks内核启动过程首先是sysInit禁止中断,清除cache(缓存),初始化CPU基本寄存器;然后usrInit设置cache的工作模式,板级硬件初始化,初始化Wind内核,启动usrRoot根任务;进行内存初始化,添加用户应用程序,至此VxWorks内核启动完成。这种启动方式的最大缺点是每次系统重启都需要进行硬件上电、自检及boot小内核的引导启动过程。
目前,随着计算机技术的发展,系统的处理速度更快、存储容量更大、性能结构更加先进和复杂,系统重新启动的时间不仅没有降低反而有增长的趋势。延长重新启动的时间意味着延长版本升级过程和开发调试过程,导致既浪费时间,也严重地影响了系统的工作效率。
发明内容
为了解决上述问题,本发明的目的是提供一种应用于分布式系统中的升级方法及版本管理客户端,可有效提高在升级过程中分布式系统的重启速度,改善用户体验,进而提高分布式系统的工作效率。
为了达到上述目的,本发明提供一种应用于分布式系统中的升级方法,所述方法包括:
版本管理客户端下载新内核,并将新内核映像加载到动态内存中;
所述版本管理客户端将分布式系统的快速重启模块DSFRM的汇编存根代码拷贝到所述动态内存中,所述DSFRM的汇编存根代码用于将所述动态内存中指定的内容从原位置搬移到指定位置;
在拷贝完成后跳转到所述DSFRM的汇编存根代码的执行入口,并通过执行所述DSFRM的汇编存根代码将所述新内核映像拷贝到所述动态内存中的目标位置,并在拷贝完成后跳转到新内核的执行入口,启动所述新内核;
在将所述DSFRM的汇编存根代码拷贝到所述动态内存中之前,所述方法还包括:
所述版本管理客户端向所述分布式系统中的当前内核发送禁止内核任务抢占和关中断的命令。
优选的,所述版本管理客户端将分布式系统的快速重启模块DSFRM的汇编存根代码拷贝到所述动态内存中的步骤具体为:
在所述动态内存中分配至少一代码页;
将所述DSFRM的汇编存根代码拷贝到所述代码页中。
优选的,所述新内核是所述版本管理客户端从本地Flash下载、从PC机下载、或通过FTP从网络位置下载得到。
优选的,在跳转到所述DSFRM的汇编存根代码的执行入口之前,所述方法还包括:
所述版本管理客户端装载内核数据段值到段寄存器,并将全局描述符表GDT和中断描述符表IDT设置为无效。
优选的,在跳转到所述DSFRM的汇编存根代码的执行入口之后,所述方法还包括:
所述版本管理客户端将所述新内核映像的起始地址和/或存储有DSFRM的汇编存根代码的代码页的地址以参数的形式发送给所述新内核。
优选的,所述方法还包括:
从所述动态内存的栈中读取所述代码页的地址,并将所述代码页的地址存储到寄存器中;
通过所述代码页的地址,在所述代码页的顶端设置当前函数执行堆栈,将所述新内核的起始地址存储到栈中。
优选的,在所述版本管理客户端下载新内核,并将新内核映像加载到动态内存中之后,所述方法还包括:
所述版本管理客户端初始化分布式系统的快速重启模块DSFRM的管理数据结构T_VerFRMCtrlInfo,所述管理数据结构T_VerFRMCtrlInfo用于指定新内核在内存中的位置、新内核启动位置和DSFRM的汇编存根代码页的位置。
本发明还提供一种版本管理客户端,包括:
加载模块,用于将新内核映像加载到动态内存中;
拷贝模块,用于将分布式系统的快速重启模块DSFRM的汇编存根代码拷贝到所述动态内存中,所述DSFRM的汇编存根代码用于将所述动态内存中指定的内容从原位置搬移到指定位置;
引导模块,用于在拷贝完成后跳转到所述DSFRM的汇编存根代码的执行入口;所述版本管理客户端向所述分布式系统中的当前内核发送禁止内核任务抢占和关中断的命令,通过执行所述DSFRM的汇编存根代码将所述新内核映像拷贝到所述动态内存中的目标位置,并在拷贝完成后跳转到新内核的执行入口,启动所述新内核。
优选的,所述版本管理客户端还包括:
初始化模块,用于初始化分布式系统的快速重启模块DSFRM的管理数据结构T_VerFRMCtrlInfo,所述管理数据结构T_VerFRMCtrlInfo用于指定新内核在内存中的位置、新内核启动位置和DSFRM的汇编存根代码页的位置。
优选的,所述版本管理客户端还包括:
下载模块,用于从本地Flash下载、从PC机下载、或通过FTP从网络位置下载所述新内核。
上述技术方案中的至少一个技术方案具有如下有益效果:首先将下载的新内核,并将该新内核映像加载到动态内存中;然后将DSFRM的汇编存根代码拷贝到动态内存中,并在拷贝完成后跳转到DSFRM汇编代码执行入口;最后通过DSFRM的汇编存根代码将新内核映像拷贝到动态内存中,拷贝完成后跳转到新内核的执行入口,并启动新内核。通过上述方式既充分利用了版本管理的灵活性和扩展性,又跳过了系统重启过程中比较耗时的固件上电自检阶段和boot内核启动阶段,有效减少了在升级过程中分布式系统的重启时间,改善用户体验,大大提高了系统的工作效率,同时也可以为开发调试人员带来便利。
具体实施方式
在本实施例中,首先将新内核下载到本地并加载到内存中,然后为DSFRM的汇编存根代码和DSFRM的管理数据结构T_VerFRMCtrlInfo分配动态内存页。初始化设置T_VerFRMCtrlInfo的内容,如新内核在内存中位置、新内核启动位置、内核大小、DSFRM的汇编存根代码页的位置等,上述DSFRM的汇编存根代码用于把指定内存中的内容搬移到另一个指定位置,然后跳转到新位置的开始处执行。上述T_VerFRMCtrlInfo管理数据结构可用于保存快速重启内核所需要的相关信息。然后版本管理调用体系结构相关的函数machine_kfrmexec实现快速重启,入参是版本管理初始化了的T_VerFRMCtrlInfo结构。machine_kfrmexec跳转到该DSFRM的汇编存根代码的起始处执行,将分布式系统的快速重启模块DSFRM(假设DSFRM内核代码段位置用dsfrm_code_start表示,大小为dsfrm_code_size)的代码拷贝到在内存中分配的存根代码页中,然后跳转到DSFRM快速重启的入口函数。DSFRM的汇编存根代码完成新内核拷贝到最终位置,并跳转到内核初始化入口执行,从而完成系统的重启。
为了使本发明实施例的目的、技术方案和优点更加清楚明白,下面结合实施例和附图,对本发明实施例做进一步详细地说明。在此,本发明的示意性实施例及说明用于解释本发明,但并不作为对本发明的限定。
如图3所示,为分布式系统的升级方法流程图,具体步骤如下:
步骤301、版本管理客户端下载新内核,并将新内核映像加载到动态内存中;
版本管理客户端接收到快速重启命令后,系统跳转到版本管理客户端中的版本管理模块入口。如果在规定时间内用户没有输入,则直接执行新内核的下载和加载;否则,根据用户配置参数进行新内核的下载和加载。
步骤302、版本管理客户端将DSFRM的汇编存根代码拷贝到所述动态内存中,该DSFRM的汇编存根代码用于将动态内存中指定的内容从原位置搬移到指定位置;
步骤303、在拷贝完成后跳转到DSFRM的汇编存根代码的执行入口,并通过执行DSFRM的汇编存根代码将新内核映像拷贝到动态内存中的目标位置,并在拷贝完成后跳转到新内核的执行入口,启动所述新内核。
在步骤302中,新内核加载后进行DSFRM切换的准备和初始化工作,包括:在动态内存中申请至少一页面用于T_VerFRMCtrlInfo管理结构,根据新加载内核的信息初始化T_VerFRMCtrlInfo结构的某些字段;根据DSFRM的汇编存根代码大小申请相应的动态页面。
在本实施例中,通过将DSFRM的汇编存根代码拷贝到动态内存中的代码页中,可以保证在新内核覆盖旧内核的过程中DSFRM的汇编存根代码不会被覆盖。
T_VerFRMCtrlInfo管理结构是重要的DSFRM控制结构:
上述结构中kimage_segment结构表示:内核映像的地址和大小;考虑到内核可能比较大,T_VerFRMCtrlInfo结构中可以把内核最大拆分为KIMAGE_SEGMENT_MAX个段存放;
nr_segments表示:实际分段数;
dsfrm_code_page成员表示:DSFRM的汇编存根代码的代码页的地址;
start表示:新内核加载的起始位置。
版本管理模块完成新内核加载和快速重启需要的必要初始化工作,然后将控制交给体系结构相关的实现machine_kfrmexec执行。
下面以X86体系结构为例说明。machine_kfrmexec主要作用是判断系统是否支持快速重启,如果不支持,则跳转到系统的正常重启入口,否则禁止内核任务抢占和关中断;将内核代码段中DSFRM的汇编存根代码拷贝到版本管理模块申请的dsfrm_code_page内存页中;装载内核数据段值到段寄存器,并使GDT(Global Description Table,全局描述符表)和IDT(Interrupt DescriptionTable,中断描述符表)无效;跳转到dsfrm_code_page的起始代码,将一些重要的信息以参数的形式传递给新内核,比如容纳有内核映像的源/目的地址的间接页,新内核的起始地址,DSFRM的汇编存根代码页的地址,以及一个标明系统是否启用了物理地址扩展(Physical Address Extension,PAE)的标志。
参见图4,为本实施例中内存布局示意图。在本实施例中DSFRM快速重启的关键点在于DSFRM的控制数据结构和DSFRM的汇编存根代码要独立于当前内核运行位置,可保证DSFRM的汇编存根代码在搬移新内核覆盖当前内核的过程中,DSFRM的汇编存根代码不被破坏。
新内核的加载地址通常就是当前运行内核的起始地址,内核一般从底端内存某位置开始。
新内核的加载位置、DSFRM控制数据结构的内存页、DSFRM的汇编存根代码的代码页的分配可由版本管理模块借助VxWorks的内存管理功能完成。版本管理模块能够获取新内核的大小和最终目的地址信息,因而可以保证申请的新内核加载位置不会与最终加载位置交叉或重合。同理,对于DSFRM控制数据结构的内存页、DSFRM的汇编存根代码的代码页的分配也要保证不能位于新内核最终加载内存范围,所以版本管理分配内存的策略是尽量分配高端内存。
当前内核的运行位置一般是固定的,对于新内核加载位置、DSFRM控制数据结构的内存页和DSFRM的汇编存根代码的代码页的位置并没有顺序要求,只要版本管理模块在分配内存时保证前面所说的约束条件即可。
在步骤303中,DSFRM的汇编存根代码执行下面的操作:
1)自栈中读取参数,并将它们存储到寄存器中,然后禁用中断。
2)使用以参数形式传递给自己的页地址,在页的末端设置一个栈。
3)将新内核映像的起始地址存储到栈中,以使得存根代码的返回自动将系统引导到新的内核映像。
4)设置cr0寄存器的适当位来禁用内存分页。
5)将页目录基址寄存器cr4重设为0。
6)清空快表(Translation Lookaside Buffers,TLB)。
7)将所有内核映像页拷贝到最终目标页。
8)再次清空TLB。
9)将除了栈指针寄存器esp(因为它指向容纳新内核起始地址的栈)以外的所有寄存器重设为0。
10)自存根代码“返回”。自动将系统引导到新内核。
如图5所示,为本实施例中分布式系统的升级方法流程图,本流程过程分为三个阶段。
第一阶段:通过版本管理加载新内核和DSFRM快速重启的初始化分配。
步骤501、首先用户输入快速重启命令,系统跳转到版本管理快速重启入口。
步骤502、版本管理判断是否需要快速重启,如果不需要,则直接调用系统reboot操作;否则,进入版本管理的配置过程。版本管理的配置操作由用户选择完成,如果用户没有输入,则根据当前配置进行下一步操作。
步骤503、版本管理根据配置下载和加载内核到内存中。内核下载方式有多种,可以从本地Flash下载、从PC机下载或者通过FTP从网络位置下载等。内核加载到内存中,由版本管理负责分配加载新内核所需要的空间,并保证所分配空间与新内核最终加载的位置不会重合。
步骤504、版本管理为DSFRM的汇编存根代码分配动态内存页,通常为一页大小。根据当前内核DSFRM代码段的大小DSFRM_code_size分配。
步骤505、版本管理为DSFRM管理结构T_VerFRMCtrlInfo分配一个动态内存页,并初始化如新内核加载位置和大小、内核最终加载地址、DSFRM的汇编存根代码页地址等信息。
步骤506、调用体系结构相关的machine_kfrmexec函数,入参为初始化了的T_VerFRMCtrlInfo结构,进入第二阶段。
第二阶段:machine_kfrmexec完成体系结构相关的快速重启前的准备工作。
步骤507、如果当前体系结构不支持快速重启功能,则直接reboot重启;否则进入下一步。
步骤508、禁止内核抢占并关中断,保证当前操作不会被打断。
步骤509、把DSFRM的汇编存根代码从dsfrm_code_start位置开始拷贝到版本管理所分配的动态内存页,这份DSFRM拷贝是最终完成新内核搬移和启动的代码。之所以不直接使用当前内核的DSFRM代码是因为当前内核会被新内核覆盖。
步骤510、装载数据段寄存器,并使GDT和IDT表无效。
步骤511、跳转到动态分配的DSFRM汇编代码页的起始位置处执行,并将一些重要的信息以参数的形式传递给新内核,如新内核的起始地址,DSFRM汇编存根代码页的地址,是否启用了PAE的标志等。然后进入第三阶段。
第三阶段:DSFRM的汇编存根代码完成新内核的搬移和启动工作。
步骤512、自栈中读取参数,并将它们存储到寄存器中,然后禁用中断。
步骤513、使用以参数形式传递的页地址,在页顶端设置当前函数执行堆栈。
步骤514、将新内核映像的起始地址存储到当前栈中,以使得存根代码当前函数的返回自动将系统引导到新的内核映像。
步骤515、禁用内存分页,这是通过设置cr0寄存器的适当位来完成。
步骤516、将页目录基址寄存器cr4设为0。
步骤517、清空TLB缓存(Translation Lookaside Buffers),因为页表无效,防止下一步操作使用不正确的TLB缓存。
步骤518、将所有内核映像页拷贝到最终目标页,这主要通过汇编循环搬移指令完成。
步骤519、再次清空TLB缓存,主要是清除上一步操作产生的TLB内容。
步骤520、将除了栈指针寄存器esp以外的所有寄存器重设为0。因为esp含有指向新内核起始地址的栈信息,所以保留。
步骤521、DSFRM的汇编存根代码“返回”,自动将系统引导到新内核起始地址(步骤514保存到栈中的地址)。
至此,快速重启过程完成,控制权转交到新内核,新内核进行必要的初始化工作最终将控制转交到用户。
由上述技术方案可知,有益效果:首先将下载的新内核加载到内存的新内核映像页中;然后在内存中给DSFRM的汇编存根代码分配至少一存根代码页,并将该DSFRM的汇编存根代码拷贝到该存根代码页中,跳转到DSFRM汇编代码执行入口;最后通过DSFRM的汇编存根代码将新内核映像页中的新内核拷贝到内存的目标页中,拷贝完成后跳转到新内核的执行入口,启动新内核。通过上述方式既充分利用了版本管理的灵活性和扩展性,又跳过了系统重启过程中比较耗时的固件上电自检阶段和boot内核启动阶段,有效减少了在升级过程中分布式系统的重启时间,改善用户体验,大大提高了系统的工作效率,同时也可以为开发调试人员带来便利。
参见图6,为本实施例中版本管理客户端的结构示意图,由图中可知,该版本管理客户端,包括:
加载模块,用于将新内核映像加载到动态内存中;
拷贝模块,用于将分布式系统的快速重启模块DSFRM的汇编存根代码拷贝到所述动态内存中,并在拷贝完成后跳转到所述DSFRM的汇编存根代码的执行入口;
引导模块,用于通过所述DSFRM的汇编存根代码将所述新内核映像拷贝到所述动态内存中的目标位置,并在拷贝完成后启动所述新内核。
在本发明的另一实施例中,该版本管理客户端还包括:
初始化模块,用于初始化分布式系统的快速重启模块DSFRM的管理数据结构T_VerFRMCtrlInfo,所述管理数据结构T_VerFRMCtrlInfo用于指定新内核在内存中的位置、新内核启动位置和DSFRM的汇编存根代码页的位置。
在本发明的另一实施例中,该版本管理客户端还包括:
下载模块,用于从本地Flash下载、从PC机下载、或通过FTP从网络位置下载新内核。
以上所述仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以作出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。