A bootloader for Android used on various devices powered by Qualcomm Snapdragon chips:
https://en.wikipedia.org/wiki/Devices_using_Qualcomm_Snapdragon_processors
Although not all of the Snapdragon based Android devices use this particular bootloader format, it is known that devices with the following chips have used it (example devices are given for each chip):
APQ8064 (devices)
MSM8974AA (devices)
MSM8992 (devices)
APQ8064-1AA (devices)
MSM8996 Pro-AB (devices)
MSM8998 (devices)
(*)
bootloader_size
is equal to the size of the whole file (not just img_bodies
as usual).
(**)
There are some data after the end of img_bodies
.
On the other hand, devices with these chips do not use this format:
APQ8084 (devices)
MSM8994 (devices)
The bootloader-*.img
samples referenced above originally come from factory
images packed in ZIP archives that can be found on the page Factory Images
for Nexus and Pixel Devices on
the Google Developers site. Note that the codenames on that page may be
different than the ones that are written in the list above. That's because the
Google page indicates ROM codenames in headings (e.g. "occam" for Nexus 4)
but the above list uses model codenames (e.g. "mako" for Nexus 4) because
that is how the original bootloader-*.img
files are identified. For most
devices, however, these code names are the same.
This page hosts a formal specification of Qualcomm Snapdragon (MSM) bootloader.img 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_qcom {
label="AndroidBootldrQcom";
graph[style=dotted];
android_bootldr_qcom__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">8</TD><TD></TD><TD PORT="magic_type">magic</TD></TR>
<TR><TD PORT="num_images_pos">8</TD><TD PORT="num_images_size">4</TD><TD>u4le</TD><TD PORT="num_images_type">num_images</TD></TR>
<TR><TD PORT="ofs_img_bodies_pos">12</TD><TD PORT="ofs_img_bodies_size">4</TD><TD>u4le</TD><TD PORT="ofs_img_bodies_type">ofs_img_bodies</TD></TR>
<TR><TD PORT="bootloader_size_pos">16</TD><TD PORT="bootloader_size_size">4</TD><TD>u4le</TD><TD PORT="bootloader_size_type">bootloader_size</TD></TR>
<TR><TD PORT="img_headers_pos">20</TD><TD PORT="img_headers_size">68</TD><TD>ImgHeader</TD><TD PORT="img_headers_type">img_headers</TD></TR>
<TR><TD COLSPAN="4" PORT="img_headers__repeat">repeat num_images times</TD></TR>
</TABLE>>];
android_bootldr_qcom__inst__img_bodies [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="img_bodies_pos">ofs_img_bodies</TD><TD PORT="img_bodies_size">...</TD><TD>ImgBody</TD><TD PORT="img_bodies_type">img_bodies</TD></TR>
<TR><TD COLSPAN="4" PORT="img_bodies__repeat">repeat num_images times</TD></TR>
</TABLE>>];
subgraph cluster__img_header {
label="AndroidBootldrQcom::ImgHeader";
graph[style=dotted];
img_header__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">64</TD><TD>str(ASCII)</TD><TD PORT="name_type">name</TD></TR>
<TR><TD PORT="len_body_pos">64</TD><TD PORT="len_body_size">4</TD><TD>u4le</TD><TD PORT="len_body_type">len_body</TD></TR>
</TABLE>>];
}
subgraph cluster__img_body {
label="AndroidBootldrQcom::ImgBody";
graph[style=dotted];
img_body__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="body_pos">0</TD><TD PORT="body_size">img_header.len_body</TD><TD></TD><TD PORT="body_type">body</TD></TR>
</TABLE>>];
img_body__inst__img_header [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>img_header</TD><TD>_root.img_headers[idx]</TD></TR>
</TABLE>>];
}
}
android_bootldr_qcom__seq:img_headers_type -> img_header__seq [style=bold];
android_bootldr_qcom__seq:num_images_type -> android_bootldr_qcom__seq:img_headers__repeat [color="#404040"];
android_bootldr_qcom__seq:ofs_img_bodies_type -> android_bootldr_qcom__inst__img_bodies:img_bodies_pos [color="#404040"];
android_bootldr_qcom__inst__img_bodies:img_bodies_type -> img_body__seq [style=bold];
android_bootldr_qcom__seq:num_images_type -> android_bootldr_qcom__inst__img_bodies:img_bodies__repeat [color="#404040"];
img_header__seq:len_body_type -> img_body__seq:body_size [color="#404040"];
android_bootldr_qcom__seq:img_headers_type -> img_body__inst__img_header [color="#404040"];
img_body__params:idx_type -> img_body__inst__img_header [color="#404040"];
}