具体实施方式
为了更加具体地强调其实现非相关性,将本说明书中描述的许多功能单元标记为模块。例如,一个模块可以实现为硬件电路,包括定制超大规模集成电路或门阵列,现有半导体(例如逻辑芯片、晶体管)或者其它离散部件。模块也可以在可编程硬件设备,例如现场可编程门阵列、可编程阵列逻辑、可编程逻辑设备及相似物中实现。
也可以在通过各种处理器执行的软件中实现模块。一个具有可执行代码的已识别模块可以包括例如一个或多个具有计算机指令的物理或逻辑块,所述指令可例如被组织为对象、过程或者函数。尽管如此,已识别模块的可执行代码不必物理地设置在一起,而是可以包括存储在不同位置的分立指令,其中当逻辑连接在一起时,所述指令包括该模块并且实现所描述的模块目的。
事实上,可执行代码模块可以是单个指令或许多指令,甚至可以分布在几个不同代码段上,不同程序中间,和几个存储设备上。相似地,操作数据可以在此在模块内标识和说明,并且可以体现为任何适合的形式,并且组织在任何适合的数据结构类型内。操作数据可收集为单个数据集,或可分布在不同位置上,包括分布在不同存储设备上,而且可以至少部分地仅仅作为系统或者网络上的电子信号存在。
贯穿本说明书中有关“一个实施例”,“实施例”的表述或者相似的语言表示结合该实施例描述的具体特性、结构或特征包括在本发明的至少一个实施例中。因此,贯穿本说明书的短语“在一个实施例中”,“在实施例中”,和相似的语言可以但不必全部指相同的实施例。
而且,本发明的所述特性、结构或特征可以任何适合的方式结合在一个或多个实施例中。在下面的描述中,提供了大量具体细节,例如编程、软件模块、用户选择、网络事务处理、数据库查询、数据库结构、硬件模块、硬件电路、硬件芯片等等的例子,以提供对本发明实施例的全面理解。然而相关技术领域的普通技术人员会认识到,本发明可以无需这些具体细节的一个或多个来执行,或者采用其它的方法、部件、材料等等来执行。在其它例子中,众所周知的结构、材料或操作不被示出或者详细描述,以免混淆本发明。
图1示出了一个传统代码映像更新方法100。用于执行传统代码覆盖和重新加载I/O适配器的标准技术开始执行102,并使主机总线适配器(HBA)脱机从而停止I/O 104。传统代码映像更新方法100接着向主机总线适配器中加载新的代码映像并且覆盖旧的代码映像106。代码覆盖传统上由例如存储在旧代码或者快擦写存储器(flash)映像中的引导程序代码来执行。此外,根据需要将新代码映像固化到任何快擦写存储器中108,并且运行加电自检测(POST)110。
接着,新的代码映像初始化任何代码结构112并将主机总线适配器恢复为联机状态114,从而允许I/O恢复。所述的传统代码映像更新方法100接着结束116。尽管该描述是对传统代码映像更新方法100的准确表达,然而所例举的步骤的执行顺序与额外的步骤会因不同的实现而有所不同。
主机总线适配器位于其中的主机可在主机总线适配器脱机期间在例如大约两分钟或者更长的时间内重试发送I/O。如果主机不能够在重试阈值内发送I/O,则命令会暂时停止(timeout)例如通常为30到60秒之间的一段时间。所述的脱机和暂时停止时间段是大约的,并且会根据具体的硬件或者应用配置而变化。当暂时停止时,主机可假定主机总线适配器不工作,标记端口为“坏的”,并且从路径组中清除该路径。主机很可能不得不执行一个恢复序列以重建该路径。因此,传统的代码映像更新方法100可能导致超过两分钟或更长时间的主机停机。
图2示出了适于实现本发明的通信系统200的一个实施例。示出的通信系统200包括连接到存储系统208的三个主机202,204,206。存储系统208,在一个实施例中,是设置成用于存储数据的存储服务器。第一和第二主机202、204通过交换机210冗余地连接到存储系统208。可选地,第三主机206直接连接到存储系统208。为了清楚起见,省略了其它连接设备。
尽管三个主机202,204,206在所示的实施例中出现,然而通信系统200可以更少或更多的主机202,204,206和存储系统208进行操作。另外,主机202,204,206可在具有不同冗余和直通性(directness)的可选配置下连接到存储系统208。此外,示出的线缆连接可包括光纤通道(Fibre Channel),企业系统连接(ESCON),光纤连接(FICON)通道,小型计算机系统接口(SCSI),等等。
每一个示出的主机202,204,206均包括一个或多个主机总线适配器(HBA)212,214,216。每个HBA 212,214,216被构造成用于管理在相应主机202,204,206和存储系统208之间传送数据所需的大多数I/O操作。特别是,优化每个主机总线适配器212,214,216来非常快速地执行许多I/O操作但极少或者不需要主机202,204,206介入,从而最小化主机202,204,206上的工作负荷。
示出的存储系统208包括多个冗余主机适配器218,220和集簇(cluster)222,224。主机适配器218,220基本上与上述的主机总线适配器212,214,216相似。每个集簇222,224可包括一个或多个多处理器226,228,以及到几个逻辑单元号(LUN)230,232,234,236的连接。在一个特定的实施例中,一个集簇222可主要访问偶数LUN230,234,而其它的集簇224可主要访问奇数LUN 232,236。在主机适配器218,220和集簇222,224之间以及在多处理器226,228与LUN 230,232,234,236之间的冗余路径允许在故障情况下,例如在硬件故障的情况下进行数据存储和访问。另外,存储系统208可采用独立磁盘冗余阵列(RAID)(可能镜像并划分存储的数据),也计算并存储奇偶校验数据。
对示出的主机202,204,206之一的任何引用均应当被理解为对任何或全部主机202,204,206的引用,除非另外明确地指出。同样地,对示出的主机总线适配器212,214,216之一的任何引用均应当被理解为对任何或全部主机总线适配器212,214,216或主机适配器218,220的引用,除非另外明确地指出。而且,对冗余示出的集簇222,224,多处理器226,228,或LUN 230,232,234,236之一的任何引用均分别应当被理解为对单个相应设备的引用,除非另外明确地指出。
贯穿本说明书,为了简洁和清楚地描述本发明,将结合主机总线适配器212,214,216和主机适配器218,220中具体使用的处理器和存储器描述本发明的各个实施例。这里所描述的实施例是有代表性的实例,并且不被用来限制由权利要求书所确定的本发明的保护范围。本领域普通技术人员应当理解,本发明可以在任何包括处理器,例如微处理器、专用集成电路(ASIC)等等,执行代码映像并且允许使用代码覆盖来更新代码映像的计算机或电系统上执行。
图3示出了基本上与图2的主机适配器218,220相似的主机总线适配器(HBA)300的一个实施例。示出的主机适配器300包括处理器(CPU)302,一个或多个快擦写存储器设备304,一个或多个可编程逻辑阵列(PLA),I/O端口308,本地存储器设备310和并行代码加载设备312。现有的代码映像314存储在本地存储器设备310上。现有代码映像314指的是旧的代码映像314,因为它将被新的代码映像316代替或被抛弃。新的代码映像316可以被加载并存储在本地存储器设备310上。
CPU 202被构造成用于执行旧代码映像314中的操作指令。在一个实施例中,旧代码映像314被构造成用于允许主机适配器300例如在主机202和存储系统208之间执行高速I/O操作。快擦写存储器设备304和可编程逻辑阵列306与CPU交互以正确地执行I/O操作。另外,I/O端口308允许主机适配器300与其它设备,例如主机202传递数据和控制信息。
在一个实施例中,新代码映像316存储在本地存储器设备310的临时位置。临时存储器位置最好被配置成使得CPU 302可以执行存储在临时存储器位置的指令。在一个实施例中,临时存储器位置是存储器310中的缓冲区。包括临时存储器位置的本地存储器设备310最好是高速主存储器,例如随机存取存储器(RAM),非易失性随机存取存储器(NVRAM),等等。
在一个实施例中,旧代码映像314和新代码映像316存储在本地存储器设备310的相邻块中。可选地,旧代码映像314和新代码映像316可存储在本地存储器设备310的分立块中,或不同的存储器设备中。另外,本地存储器设备310可被构造成用于存储与旧代码映像314和新代码映像316分立的一个或多个数据结构306。
示出的并行代码加载设备312包括查询模块318,映像加载模块320,映像桥接模块322,存储器初始化模块324,映像覆盖模块326,快速加载关键字模块328,标准适配器初始化模块330,和快速加载适配器初始化模块332。尽管并行代码加载设备312被描述为位于主机适配器300之内,然而并行代码加载设备312或一个或多个模块可以存储在处理器226或存储系统208内的另一个设备上。
查询模块318,在一个实施例中,被构造成用于识别旧代码映像314的特征并且确定在旧代码映像314和新代码映像316之间是否有差异或不兼容性。为了确定在旧代码映像314和新代码映像316之间是否存在不兼容性,查询模块318可以确定旧代码映像314的版本是否与新代码映像316的版本有所不同。可选地,查询模块318可确定旧代码映像314的大小、位置或其它特征与新代码映像316的是否不同。
在一个实施例中,映像加载模块302被构造成用于将新代码映像316的复本加载到本地存储器设备310或另一个相似的存储器设备中。在另一个实施例中,代码加载模块320可以将新代码映像316加载到本地存储器设备310中未被旧代码映像314的一部分占用的位置。新代码映像316可从例如磁盘或光盘的源介质处加载,并且在一个实施例中,在存储系统208处加载并传送到主机适配器218。可选地,新代码映像316可在主机202加载以更新在主机总线适配器212上的旧代码映像314。
在一个实施例中,映像桥接模块322被构造成用于调解旧代码映像314和新代码映像316之间的不兼容性。可被执行以调解不兼容性的确切指令依赖于所调解的不兼容性的类型。在一个例子中,不兼容性的调解可包括改变存储寄存器、存储器或硬件设备的初始化的顺序。在另一个例子中,不兼容性的调解可包括转换数据结构的格式以便新代码映像316使用该数据结构。还有其它类型的操作可被执行以调解其它类型的不兼容性。
在一个实施例中,存储器初始化模块324被构造成用于初始化本地存储器设备310或其一部分,以准备用新代码映像316覆盖旧代码映像314。存储器初始化模块324可进一步被构造成用于初始化本地存储器设备或其一部分,使得新代码映像316中的可执行程序可从临时存储器位置执行。在另一个实施例中,存储器初始化模块324可被构造成用于初始化快擦写存储器设备304和PLA 306。
在一个实施例中,映像覆盖模块326被构造成用于用新代码映像316覆盖旧代码映像314。该覆盖可将新代码映像316复制到旧代码映像314的部分或全部上。此外,该覆盖可将新代码映像316的各部分复制到未被旧代码映像314占用的各位置上。此外,映像覆盖模块326可被构造成用于执行检错和纠错以验证新代码映像316成功复制。在可选实施例中,映像覆盖模块可以从临时存储器位置清除新代码映像316的复本,也可以不这样。
在一个实施例中,快速加载关键字模块328被构造成用于创建和存储快速加载关键字(fastload key)。所述快速加载关键字可指明使用快速加载代码覆盖成功地用新代码映像316覆盖主机适配器218中的旧代码映像314。在一个实施例中,该快速加载关键字可存储在新代码映像316的元数据段502中。快速加载关键字模块328也可确定在快速加载代码覆盖重新建立I/O通信时,主机适配器218是否可使用快速加载初始化序列而不是标准初始化序列加以初始化。在一个实施例中,快速加载初始化序列可包括标准适配器初始化序列的全部或部分。
在一个实施例中,标准适配器初始化模块330被构造成用于使用传统初始化序列初始化主机适配器218。主机适配器218被初始化成在例如主机适配器218脱机并且恢复联机之后开始I/O通信。如果在新代码映像316的元数据段502中没有发现快速加载关键字,标准适配器初始化模块330可使用传统初始化序列初始化主机适配器218,传统初始化序列包括正常启动引导握手和POST。
在一个实施例中,快速加载适配器初始化模块332被构造成用于使用快速加载初始化序列初始化主机适配器218。快速加载初始化序列将初始化主机适配器300所需的时间降到最少,例如通过假定存储器和/或硬件已经在有效状态,因为这些状态在代码覆盖前已经确认。在一个实施例中,在本地存储器设备310中的初始化变量在代码更新过程中初始化。在另一个实施例中,硬件机器状态被确认为有效,也就是,在开始代码更新过程开始之前,具有完好的纠错码(ECC)。在某一实施例中,如果提供适当的快速加载关键字,快速加载适配器初始化模块332仅启动快速加载初始化序列。此外,快速加载初始化模块332可启动快速加载初始化序列的一个或多个部分以在传统初始化序列期间执行。在此方式中,标准初始化序列可被更改为包括一个或多个来自快速加载初始化序列的步骤。例如,在实施传统初始化序列过程中,快速加载初始化模块332可启动一个或多个快速加载初始化操作,因此完成快速加载初始化序列。
图4描述了旧代码映像314的一个实施例,其可存储在图3示出的主机适配器300的本地存储器设备310中。所示例的旧代码映像314包括元数据段402、运行时刻段404和数据段406。元数据段402可包括描述旧代码映像314和其内容的元数据。在一个实施例中,运行时刻段404包括一个或多个由CPU 302执行的指令。在运行时刻段404中的指令被称为“正文(text)”。数据段406包括可被运行时刻段404中的可执行代码使用的任何数据和/或数据结构。虽然元数据段402、运行时刻段404和数据段406均被描述为单独的数据块,然而段402、404和406可被分割,并且其部分彼此分散在本地存储器设备310的各个不同结构中。
在一个实施例中,运行时刻段404可包括更新模块408。更新模块408可包含加载模块410和分支模块412。在一个实施例中,加载模块410被构造成用于将新代码映像316加载到本地存储器设备310中。加载模块410可响应人工的或自动代码更新命令或中断而加载新代码映像316。
如上所述,新代码映像316可存储在缓冲区、临时存储位置,或另一相似位置中。在另一个实施例中,加载模块410可被构造成用于在将新代码映像316加载到本地存储器设备310之后,对新代码映像316执行检错和其它有效性检查。此外,加载模块410可将本地存储器设备310配置成允许执行来自临时存储单元的新代码映像316中的指令。
在传统代码映像更新中,可执行在旧代码映像314中的引导程序代码(未示出)。然而,在本发明中,分支模块412可使CPU 302开始执行在新代码映像316而不是旧代码映像314中找到的指令。随后,由于旧代码映像314和新代码映像316存储在本地存储器设备310或其它设备的非覆盖位置,在从临时位置执行来自新代码映像316的指令的同时,可保留旧代码映像206的运行时刻段404和数据段406。
图5描述了新代码映像316的一个实施例,其可存储在图3示出的主机适配器300的本地存储器设备310中。示例的新代码映像316包括元数据段502、运行时刻段504和数据段506。元数据段502可包括描述新代码映像316及其内容的元数据。在一个实施例中,运行时刻段504包括一个或多个可由CPU 302执行的指令。数据段506包括可被时间段404中的可执行代码使用的任何数据和/或数据结构。虽然元数据段502、运行时刻段504和数据段506均被描述为单独的数据块,然而段502、504和506可被分割,并且其部分彼此分散在本地存储器设备310内的不同结构中。
在一个实施例中,如参考图3的描述,元数据段502可包括快速加载关键字508。在一个实施例中,运行时刻段504包括引导程序模块510。引导程序模块510可包含转换模块512和复制模块514。
在一个实施例中,转换模块512被构造成用于调解旧代码映像314和新代码映像316之间的潜在不兼容性。不兼容性可包含旧代码映像314和新代码映像316之间的差异,其导致新代码映像316无法执行至少一项达到旧代码映像314的性能指标的功能。相应地,不兼容性可通过各种形式表现。最显著的是,如果已知新代码映像316和旧代码映像314的版本不同,则隐含不兼容性。在一个实施例中,新代码映像316的版本可存储在其元数据段502中。相似地,旧代码映像314的版本可存储在其元数据段402中。
至少一种不兼容性可包含旧代码映像314和新代码映像316使用的数据结构之间的差别。数据结构之间的差别可以是不同值,不同格式等等。数据结构可以是存储在旧代码映像314或新代码映像316中的数据结构。
在另一个实施例中,另一种不兼容性可包含新代码映像316和旧代码映像314的不同初始化需求。初始化需求可包括寄存器复位、缓冲区和/或高速缓冲存储器清除等等。此外,如果新代码映像316增加数据结构,则这些数据结构也需要初始化。
转换模块512也可被构造成用于调解任何识别的不兼容性。例如,转换模块512可被构造成用于调整数据结构和配置设置,使得新代码映像316充分执行至少与旧代码映像314相同的功能。此外,新代码映像316可执行额外的功能和提供在旧代码映像314上的改进。
在一个实施例中,引导程序模块510的复制模块514以新代码映像316至少覆盖部分的旧代码映像314。优选地,新代码映像316的覆盖象旧代码映像314那样在本地存储器设备310的相同地址开始。通过这种方式,对于其它微码部分和可能依赖本地存储器设备310的预定或固定地址位置的硬件中断的不利影响最小。在某一实施例中,复制模块514还可对新代码映像316的复本进行完整性和有效性检查,以确认覆盖复本没有错误。此外,复制模块514可刷新(flush)临时存储新代码映像316的本地存储器设备310。在另一个实施例中,复制模块514或转换模块512还可更新快擦写存储器设备304、PLA 306,或其它可与新代码映像316接口的模块。
以下示意性流程图一般性地作为逻辑流程图示出。同样,描述的顺序和标记的步骤均指示所提供的过程的一个实施例。其它步骤和过程可认为与示例过程的一个或多个步骤,或它们的部分在功能、逻辑或效果等同。另外,所使用的格式和符号表示用于解释过程的逻辑步骤,并且不被理解为对过程的范围的限制。虽然在流程图中可采用各种箭头类型和线条类型,但应理解它们并不是对相应过程的范围的限制。实际上,某些箭头或其它连接符可用于仅仅指示过程的逻辑流程。例如,一个箭头可指示在所描述过程的列举步骤之间未指定时长的等待或监视时间段。此外,具体过程进行的顺序可与所示出的相应步骤的顺序一致,也可不一致。
图6描述了可在主机适配器300或主机总线适配器212上使用的代码映像准备方法600的一个实施例。示例的代码映像准备方法600开始602,并且向主机适配器300查询604机器状态、代码级别和更新。在一个实施例中,查询模块318查询604主机适配器300。查询模块318还可确定606快速加载代码更新是否被主机适配器300支持。这种支持可取决于旧代码映像314的版本、新代码映像316的版本,主机适配器300的硬件部分等。
在一个实施例中,如果快速加载代码更新在主机适配器300上得到支持,则映像加载模块320将新代码映像316加载608到本地存储器设备310。映像加载模块320还可验证610新代码映像316以确认其被正确地加载608。在一个实施例中,映像加载模块320可采用检错和纠错技术验证610新代码映像316。
示例的代码映像准备方法600接下来比较新代码映像316的级别和目前在例如快擦写存储器设备304中的级别。在一个实施例中,映像桥接模块322接着确定614快擦写存储器设备304是否需要更新,并且如果需要,更新616快擦写存储器304。更新616快擦写存储器304将参考图7详细讨论。在另一个实施例中,映像桥接模块322还可确定在主机适配器300中的任何PLA 306或其它硬件部件是否需要升级。在另一实施例中,映像桥接模块322还可调解在旧代码映像314和新代码映像316之间的任何不兼容性。
在一个实施例中,例如,执行前述所有步骤,而主机适配器300继续处理与主机202的I/O通信。至少部分地通过保持旧代码映像314完整并且更新模块408分支到新代码映像316中的引导程序模块510,可达到此目的,其中新代码映像316与旧代码映像314存储在分立的存储位置。换句话说,引导程序模块510可执行前述的许多或全部功能,并且主机适配器300继续接受来自主机的I/O请求。
在一个实施例中,主机适配器300.脱机618,并且I/O仅在前述步骤完成后停顿(停止)。在一个实施例中,主机适配器300可继续从主机接受I/O命令但不处理这些命令。与在执行这些功能之前将主机适配器300脱机相比,所描述的代码映像准备方法600可显著地最小化主机适配器300脱机并且不能处理I/O请求的时间。此后,所示例的代码映像准备方法600结束620。
图7描述了快擦写存储器更新方法700的一个实施例,其中通过如图6的代码映像准备方法600所示的快擦写存储器设备304的更新616的例子提供。在一个实施例中,快擦写存储器设备304的更新在小的段中进行。所示例的快擦写存储器更新方法700开始702,并且擦除704快擦写存储器设备304中的段,然后确认706擦除完成704。快擦写存储器更新方法700继续更新708擦除的段并且确认710更新710正确完成。此后,快擦写存储器更新方法700确定是否有其它的段需要更新,并且如果没有,返回以擦除704随后的段。
一旦所有的段都已正确更新708和确认710,所述快擦写存储器更新方法700此后结束714。如上所述,在主机适配器300并行地继续接受I/O请求的同时,可更新一个或多个快擦写存储器设备304。通过此方式,更新快擦写存储器设备304没有增加主机适配器300脱机的时间,即使擦除704和更新708每个段可能花费相当长的时间。在另一个实施例中,在并行I/O处理期间,PLA 306和其它硬件也可更新。
图8描述了可在主机总线适配器300上采用的代码映像复制方法800的一个实施例。在一个实施例中,代码映像复制方法800在代码映像准备方法600完成并且主机总线适配器300脱机318之后的某个时刻执行。示例代码映像复制方法800开始802,并且将新代码映像316定位804在例如主机总线适配器300的本地存储器设备310中。此后,存储器初始化模块324根据需要初始化806本地存储器设备310。
此后,如上参考图3所述,映像覆盖模块326用新代码映像316覆盖旧代码映像314。在一个实施例中,映像覆盖模块326也可刷新810任何代码映像数据引用(reference),并且刷新812来自高速缓冲存储器的指令引用,因为这些引用对应于被覆盖808的旧代码映像314。然而,在某些实施例中,映像覆盖模块326不需要清除新代码映像316或旧代码映像314的任何部分或对其的引用。接着,快速加载关键字模块328可创建并存储814快速加载关键字在例如新代码映像316的元数据段502中,以指示快速加载代码更新被执行。引导程序模块510随后分支816到初始化,并且所述代码映像复制方法808结束818。
图9描述了可在主机总线适配器300上采用的代码映像初始化方法900的一个实施例。在一个实施例中,代码映像初始化方法由图7中的代码映像复制方法700启动。代码映像初始化方法900开始902,并且对主机适配器300“关闭灯”904。至此,主机适配器300快速停止I/O处理,但是并不关闭任何硬件,包括任何光纤传输硬件。在此点,主机总线适配器904关闭至少某些通信设备以“关闭灯”904。在一个可选实施例中,可不需要“关闭灯”904。实际上,在某一实施例中,灯的“关”或“开”无关紧要。
代码映像初始化方法900接着确定906是否存在快速加载关键字以表明快速加载代码更新已执行。在一个实施例中,如果快速加载关键字模块328在新代码映像316中发现适当的快速加载关键字508,则快速加载适配器初始化模块332执行快速加载初始化序列。否则,标准初始化模块330可实现常规初始化序列,该序列可比快速加载初始化序列需要更多时间。在快速加载或标准初始化序列完成之后,主机总线适配器300“开灯”912并再次恢复处理I/O请求。
在另一个实施例中,快速加载初始化模块332可执行某些补充标准初始化序列的快速加载初始化步骤。通过此方式,标准初始化模块330可执行其中某些传统步骤被快速加载初始化序列的步骤替换的传统初始化序列。在一个可选实施例中,快速加载初始化模块332可以通过作为对传统初始化序列的补充的方式执行一个或多个快速加载初始化步骤。
通过使用快速加载代码更新和初始化序列,主机适配器300可在大部分的前述过程中继续处理I/O。在一个实施例中,例如,主机适配器300脱机的总时间可接近2-3秒,包括近1秒钟的灯“关闭”的时间。当灯“关闭”904时,主机212将看到状态变化,并且会备份入日志。由于主机适配器300仅在看上去是“可忍受失灵”的时间,而不是传统技术的超过两分钟的时间的脱机,所以主机212将能够在耗尽任何超时周期之前备份入日志。在另一个实施例中,根据通信系统200的特定拓扑和主机适配器300采用的协议,在代码映像初始化方法900期间可不必“关闭灯”904。
虽然前面的描述在存储系统和存储区域网的范围内使用术语“主机适配器”和“主机总线适配器”,然而应理解,本发明的范围可扩展到微代码可更新的所有通信适配器。本发明特别适用于形成通信系统的一部分的通信适配器上代码映像的更新,使得代码映像更新期间的脱机时间最小,或I/O处理时间最多。
本发明可以其它具体方式体现而不偏离其精神和本质特征。所描述的实施例应视作示例性的而不是限制性的。因此,本发明的范围由附加权利要求而不是前面的描述指示。任何在权利要求等同的含义和范围之内的改变都包含在其范围之内。