Format of bootloader-*.img
files found in factory images of certain Android devices from Huawei:
All image versions can be found in factory images at https://developers.google.com/android/images for the specific device. To avoid having to download an entire ZIP archive when you only need one file from it, install remotezip and use its command line tool to list members in the archive and then to download only the file you want.
This page hosts a formal specification of Huawei Bootloader packed image format using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
digraph {
rankdir=LR;
node [shape=plaintext];
subgraph cluster__android_bootldr_huawei {
label="AndroidBootldrHuawei";
graph[style=dotted];
android_bootldr_huawei__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="meta_header_pos">0</TD><TD PORT="meta_header_size">76</TD><TD>MetaHdr</TD><TD PORT="meta_header_type">meta_header</TD></TR>
<TR><TD PORT="header_ext_pos">76</TD><TD PORT="header_ext_size">meta_header.len_meta_header - 76</TD><TD></TD><TD PORT="header_ext_type">header_ext</TD></TR>
<TR><TD PORT="image_header_pos">...</TD><TD PORT="image_header_size">meta_header.len_image_header</TD><TD>ImageHdr</TD><TD PORT="image_header_type">image_header</TD></TR>
</TABLE>>];
subgraph cluster__image_hdr {
label="AndroidBootldrHuawei::ImageHdr";
graph[style=dotted];
image_hdr__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="entries_pos">0</TD><TD PORT="entries_size">80</TD><TD>ImageHdrEntry</TD><TD PORT="entries_type">entries</TD></TR>
<TR><TD COLSPAN="4" PORT="entries__repeat">repeat to end of stream</TD></TR>
</TABLE>>];
}
subgraph cluster__image_hdr_entry {
label="AndroidBootldrHuawei::ImageHdrEntry";
graph[style=dotted];
image_hdr_entry__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="name_pos">0</TD><TD PORT="name_size">72</TD><TD>str(ASCII)</TD><TD PORT="name_type">name</TD></TR>
<TR><TD PORT="ofs_body_pos">72</TD><TD PORT="ofs_body_size">4</TD><TD>u4le</TD><TD PORT="ofs_body_type">ofs_body</TD></TR>
<TR><TD PORT="len_body_pos">76</TD><TD PORT="len_body_size">4</TD><TD>u4le</TD><TD PORT="len_body_type">len_body</TD></TR>
</TABLE>>];
image_hdr_entry__inst__body [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="body_pos">ofs_body</TD><TD PORT="body_size">len_body</TD><TD></TD><TD PORT="body_type">body</TD></TR>
<TR><TD COLSPAN="4" PORT="body__if">if is_used</TD></TR>
</TABLE>>];
image_hdr_entry__inst__is_used [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>is_used</TD><TD> ((ofs_body != 0) && (len_body != 0)) </TD></TR>
</TABLE>>];
}
subgraph cluster__meta_hdr {
label="AndroidBootldrHuawei::MetaHdr";
graph[style=dotted];
meta_hdr__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="magic_pos">0</TD><TD PORT="magic_size">4</TD><TD>3C D6 1A CE</TD><TD PORT="magic_type">magic</TD></TR>
<TR><TD PORT="version_pos">4</TD><TD PORT="version_size">4</TD><TD>Version</TD><TD PORT="version_type">version</TD></TR>
<TR><TD PORT="image_version_pos">8</TD><TD PORT="image_version_size">64</TD><TD>str(ASCII)</TD><TD PORT="image_version_type">image_version</TD></TR>
<TR><TD PORT="len_meta_header_pos">72</TD><TD PORT="len_meta_header_size">2</TD><TD>u2le</TD><TD PORT="len_meta_header_type">len_meta_header</TD></TR>
<TR><TD PORT="len_image_header_pos">74</TD><TD PORT="len_image_header_size">2</TD><TD>u2le</TD><TD PORT="len_image_header_type">len_image_header</TD></TR>
</TABLE>>];
}
subgraph cluster__version {
label="AndroidBootldrHuawei::Version";
graph[style=dotted];
version__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="major_pos">0</TD><TD PORT="major_size">2</TD><TD>u2le</TD><TD PORT="major_type">major</TD></TR>
<TR><TD PORT="minor_pos">2</TD><TD PORT="minor_size">2</TD><TD>u2le</TD><TD PORT="minor_type">minor</TD></TR>
</TABLE>>];
}
}
android_bootldr_huawei__seq:meta_header_type -> meta_hdr__seq [style=bold];
meta_hdr__seq:len_meta_header_type -> android_bootldr_huawei__seq:header_ext_size [color="#404040"];
android_bootldr_huawei__seq:meta_header_size -> android_bootldr_huawei__seq:header_ext_size [color="#404040"];
meta_hdr__seq:len_image_header_type -> android_bootldr_huawei__seq:image_header_size [color="#404040"];
android_bootldr_huawei__seq:image_header_type -> image_hdr__seq [style=bold];
image_hdr__seq:entries_type -> image_hdr_entry__seq [style=bold];
image_hdr_entry__seq:ofs_body_type -> image_hdr_entry__inst__body:body_pos [color="#404040"];
image_hdr_entry__seq:len_body_type -> image_hdr_entry__inst__body:body_size [color="#404040"];
image_hdr_entry__inst__is_used:is_used_type -> image_hdr_entry__inst__body:body__if [color="#404040"];
image_hdr_entry__seq:ofs_body_type -> image_hdr_entry__inst__is_used [color="#404040"];
image_hdr_entry__seq:len_body_type -> image_hdr_entry__inst__is_used [color="#404040"];
meta_hdr__seq:version_type -> version__seq [style=bold];
}