创建布局 XML 文件
在 layout.dtd 文档类型定义 (DTD) 文件中定义了 XML 文件格式,如下所示:
<?xml version="1.0"?> <!ELEMENT LAYOUT (FIELD)+> <!ATTLIST LAYOUT Header CDATA #REQUIRED length CDATA #REQUIRED> <!ELEMENT GROUP EMPTY> <!ATTLIST GROUP Name CDATA #REQUIRED> <!ELEMENT FIELD (FIELD)*> <!ATTLIST FIELD Header CDATA #REQUIRED Type (16_BIT_INT|16_BIT_UINT|16_BIT_HINT|32_BIT_INT|32_BIT_UINT|32_BIT_HINT|32_BIT_FLOAT|64_BIT_INT|64_BIT_FLOAT|CHARACTER|HEX|ASCII|EBCDIC|STRUCTURE|PADDING|BIT|BITMASK|MAP) #REQUIRED length CDATA #REQUIRED layout CDATA #IMPLIED filename CDATA #IMPLIED Groups CDATA #IMPLIED>
这意味着,XML 布局文件首先指定头(标题)以及后跟子元素 (FIELD) 列表的布局总长度,子元素 (FIELD) 由头(名称)、长度以及用来确定该子元素的缺省表示法的基本类型来描述。
还有下列特殊的子元素类型:
以下示例定义了下列 C 语言结构的布局:
typedef struct { char char_val; unsigned short ushort_val; short short_val; unsigned long ulong_val; long long_val; char string_val[32]; } _test;
以下是对 _test 结构的树形视图进行描述并且符合此格式的 XML 文件:
<?xml version="1.0"?> <LAYOUT Header="A Layout" description="Tree view" length="17"> <FIELD Header="char_val" Type="CHARACTER" length="1"></FIELD> <FIELD Header="ushort_val" Type="16_BIT_UINT" length="2"></FIELD> <FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD> <FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD> <FIELD Header="long_val" Type="32_BIT_INT" length="4"></FIELD> <FIELD Header="string_val" Type="ASCII" length="32"></FIELD> <FIELD Header="hex_val" Type="HEX" length="0x64" offset="300" offset_mode="relative"></FIELD> </LAYOUT>
可通过用 0x 作为前缀来以十六进制指定字段长度和 offset 属性。
offset 和 offset_mode 属性允许您按以下方式指定字段的准确位置:相对于映射的起点 (offset_mode=absolute) 或相对于当前地址 (offset_mode=relative)。在以下示例中,元素 b 的 offset 为 10 并且 offset_mode 定义为 relative。在不使用这些属性的情况下,此元素的偏移量将为 80,但是,因为相对于当前位置的偏移量定义为 10,所以总偏移量为 90。请注意,元素 a 的长度是以十六进制定义的,因为该长度用 0x 作为前缀。元素 c 的偏移量为 4 并且偏移方式为 absolute。这意味着,此元素的偏移量为 4 个字节(距离布局的起点)。字段 a 也涵盖由字段 c 映射的 10 个字节:
<LAYOUT Header="offset_Test" length="80"> <FIELD Header="a" Type="HEX" length="0x64"></FIELD> <FIELD Header="b" description="offset = 90" Type="HEX" length="80" offset="10" offset_mode="relative"></FIELD> <FIELD Header="c" Type="HEX" length="10" offset="4" offset_mode="absolute"></FIELD> </LAYOUT>
定义填充字段
如果决定忽略 long_val 字段,但是要在布局中显示 string_val 类型,那么该 XML 文件将与下面的内容类似:
<FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD> <FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD> <FIELD Header="" Type="PADDING" length="4"></FIELD> <FIELD Header="string_val" Type="ASCII" length="32"></FIELD>
还可在此处使用 offset 属性来跳过 long_val 字段,方法是将 string_val 的 offset 指定为 4 并将 offset_mode 指定为 relative:
<FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD> <FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD> <FIELD Header="string_val" Type="ASCII" length="32" offset="4" offset_mode="relative"></FIELD>
这意味着,string_val 字段的地址相对于 ulong_val 字段实际上为 4 个字节。
定义 PADDING 子元素的初始目的是为了处理字节对齐的结构,但它也可用来跳过布局中不需要细节化的数据区。
定义结构
以下 XML 片段显示用于对嵌套结构进行映射的 STRUCTURE 字段的使用情况。结构的顶级元素不包含关联的值,可以展开它以显示其子元素。虽然 STRUCTURE 字段的长度已添加至 XML 布局的总大小,但是,所包含字段大小仅旨在用于显示。例如,以下结构意味着仅 344 字节超出总布局大小。
<FIELD Header="MACHINE CHECK LOG OUT AREA" Type="STRUCTURE" length="344"> <FIELD Header="reserved" Type="HEX" length="16"></FIELD> <FIELD Header="FLCSID" Type="HEX" length="4"></FIELD> <FIELD Header="FLCIOFP" Type="HEX" length="4"></FIELD> <FIELD Header="reserved" Type="HEX" length="20"></FIELD> <FIELD Header="FLCESAR" Type="HEX" length="4"></FIELD> <FIELD Header="FLCCTSA" Type="HEX" length="8"></FIELD> <FIELD Header="FLCCCSA" Type="HEX" length="8"></FIELD> <FIELD Header="FLCMCIC" Type="HEX" length="8"></FIELD> <FIELD Header="reserved" Type="HEX" length="8"></FIELD> <FIELD Header="FLCFSA" Type="HEX" length="4"></FIELD> <FIELD Header="reserved" Type="HEX" length="4"></FIELD> <FIELD Header="FLCFLA" Type="HEX" length="16"></FIELD> <FIELD Header="FLCRV110" Type="HEX" length="16"></FIELD> <FIELD Header="FLCARSAV" Type="STRUCTURE"length="64"> <FIELD Header="AR0" Type="HEX" length="4"></FIELD> <FIELD Header="AR1" Type="HEX" length="4"></FIELD> <FIELD Header="AR2" Type="HEX" length="4"></FIELD> <FIELD Header="AR3" Type="HEX" length="4"></FIELD> <FIELD Header="AR4" Type="HEX" length="4"></FIELD> <FIELD Header="AR5" Type="HEX" length="4"></FIELD> <FIELD Header="AR6" Type="HEX" length="4"></FIELD> <FIELD Header="AR7" Type="HEX" length="4"></FIELD> <FIELD Header="AR8" Type="HEX" length="4"></FIELD> <FIELD Header="AR9" Type="HEX" length="4"></FIELD> <FIELD Header="AR10" Type="HEX" length="4"></FIELD> <FIELD Header="AR11" Type="HEX" length="4"></FIELD> <FIELD Header="AR12" Type="HEX" length="4"></FIELD> <FIELD Header="AR13" Type="HEX" length="4"></FIELD> <FIELD Header="AR14" Type="HEX" length="4"></FIELD> <FIELD Header="AR15" Type="HEX" length="4"></FIELD> </FIELD> <FIELD Header="FLCFPSAV" Type="HEX" length="32"></FIELD> <FIELD Header="" Type="PADDING" length="64"></FIELD> <FIELD Header="" Type="PADDING" length="64"></FIELD> </FIELD>
可对布局以内部或外部方式定义结构。通过在结构字段中指定 filename="<file name>",可创建类似于嵌套布局的外部结构,其中 <file name> 引用的文件包含结构的实际定义。
例如,可在映射布局中以外部方式指定 MACHINE CHECK LOG OUT AREA 结构,如下所示:<FIELD Header="MACHINE CHECK LOG OUT AREA" Type="STRUCTURE" length="344" filename="machine.xml"></FIELD>。
定义位屏蔽字段
以下 XML 片段是用于描述 BITMASK 字段的样本。BITMASK 的长度以字节指定,并且它包含一组 BIT 字段(这些字段的长度以位指定)。针对 BIT 字段显示的偏移量是 BITMASK 字段内的位偏移量。虽然位屏蔽字段的长度已添加至 XML 布局的总大小,但是,各个 BIT 字段大小仅旨在用于显示。
<FIELD Header="BITMASK" Type="BITMASK" length="1"> <FIELD Header="BIT 1" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 2" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 3" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 4" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 5" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 6" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 7" Type="BIT" length="1"></FIELD> <FIELD Header="BIT 8" Type="BIT" length="1"></FIELD> </FIELD>
定义 union
以下示例定义了下列 C 语言 union 的布局:
union my_union { int my_intVal; double my_doubleVal; };
以下 XML 样本显示如何描述 union。请注意,在 XML 中,union 的长度为其最大字段的大小:
<LAYOUT Header="UNIONS" length="8"> <FIELD Header="my_union" Type="UNION" length="8"> <FIELD Header="my_intVal" Type="HEX" length="4" description="value within the union"></FIELD> <FIELD Header="my_doubleVal" Type="HEX" length="8"></FIELD> </FIELD> </LAYOUT>
定义嵌套布局
通过将 MAP 字段类型与可选布局字段一起使用,可以描述嵌套布局,如以下 DSA 布局示例中所示:
<?xml version="1.0"?> <!DOCTYPE LAYOUT SYSTEM "Layout.dtd"> <LAYOUT Header="DSA" length="72"> <FIELD Header="FLAGS" Type="HEX" length="2"></FIELD> <FIELD Header="junk" Type="HEX" length="2"></FIELD> <FIELD Header="Back Chain" Type="MAP" length="4" layout="dsa.xml"></FIELD> <FIELD Header="Forward Chain" Type="MAP" length="4" layout="dsa.xml"></FIELD> <FIELD Header="R14" Type="HEX" length="4"></FIELD> <FIELD Header="R15" Type="HEX" length="4"></FIELD> <FIELD Header="R0" Type="HEX" length="4"></FIELD> <FIELD Header="R1" Type="HEX" length="4"></FIELD> <FIELD Header="R2" Type="HEX" length="4"></FIELD> <FIELD Header="R3" Type="HEX" length="4"></FIELD> <FIELD Header="R4" Type="HEX" length="4"></FIELD> <FIELD Header="R5" Type="HEX" length="4"></FIELD> <FIELD Header="R6" Type="HEX" length="4"></FIELD> <FIELD Header="R7" Type="HEX" length="4"></FIELD> <FIELD Header="R8" Type="HEX" length="4"></FIELD> <FIELD Header="R9" Type="HEX" length="4"></FIELD> <FIELD Header="R10" Type="HEX" length="4"></FIELD> <FIELD Header="R11" Type="HEX" length="4"></FIELD> <FIELD Header="R12" Type="HEX" length="4"></FIELD> </LAYOUT>
此格式正确的 XML 布局存储在称为 DSA.XML 的文件中。由于已知字段 3 和 4 包含指向不同 DSA 结构的指针,所以您会添加两个嵌套布局定义。
定义组
借助组语法,可以将映射布局中的字段分为若干组,以便它们更容易使用。要定义组,需将 <GROUP Name="groupName"></GROUP> 放置在布局文件的顶部。然后,通过指定以下内容来指示字段属于预定义的组:<FIELD Header="RESERVED" Type="HEX" length="12" Groups="groupName"></FIELD>。
一个字段可以属于多个组。要定义多个组,请在 Groups 属性中通过以逗号分隔的列表来指定这些组。Groups 属性中的每个组都必须已在布局中通过使用 <GROUP> 标记来定义。
名称为 ALL 的组是特殊组。在某个字段中指定此名称将使该字段属于所有组,并且该字段在所有组中都将可视。以下代码样本包含组:
<?xml version="1.0"?> <!DOCTYPE LAYOUT SYSTEM "Layout.dtd"> <LAYOUT Header="GROUP_EXAMPLE" length="32"> <GROUP Name="GroupA"></GROUP> <GROUP Name="GroupB"></GROUP> <FIELD Header="FIELD_A" Type="HEX" length="8" Groups="GroupA"></FIELD> <FIELD Header="FIELD_B" Type="HEX" length="8" Groups="GroupB"></FIELD> <FIELD Header="FIELD_AB" Type="HEX" length="8" Groups="GroupA,GroupB"></FIELD> <FIELD Header="FIELD_ALL" Type="HEX" length="8" Groups="ALL"></FIELD> </LAYOUT>
定义 ORG 组
可以使用 ORG_GROUP 标记来定义内存的先前所定义部分的布局。这类似于汇编程序中的 ORG 指令的行为。可以使用 FIELD 属性来指定新布局的起始位置。在简单情况下,FIELD 属性的值可以是映射中先前所定义字段的名称。还可使用 *NONE 或 * 作为值,这意味着布局用于内存中的当前位置。Header 属性只是新布局的名称。
<LAYOUT Header="SW00SR" length="271"> <ORG_GROUP FIELD="*NONE" Header="ORG_GROUP1"> <FIELD Header="A" length="4" Type="HEX"></FIELD> <FIELD Header="B" length="4" Type="HEX"></FIELD> <FIELD Header="c" length="4" Type="HEX"></FIELD> </ORG_GROUP> <ORG_GROUP FIELD="A" Header="my_custom_header"> <FIELD Header="F" length="4" Type="HEX" description="address of F == address of A"></FIELD> <FIELD Header="G" length="4" Type="HEX"></FIELD> <FIELD Header="H" length="4" Type="HEX"></FIELD> <ORG_GROUP FIELD="*+4" Header="another_org"> <FIELD Header="J" length="2" Type="HEX" description="address of J = current location + 4"></FIELD> </ORG_GROUP> </ORG_GROUP> <FIELD Header="R" length="4" Type="HEX"></FIELD> <FIELD Header="Z" length="4" Type="HEX"></FIELD> </LAYOUT>
其中: