Skip to content

Commit 4466202

Browse files
DiewiAdrianDC
authored andcommitted
Add support for newer Sony ELF boot images.
The boot image found in sony firmwares (stock) is different to the already implemented version. This change adds support for these images (found in the Z2) by introducing more flexibility in the ELF handling and the output format (ELF --> ANDROID!). In particular: - Use a more dynamic structure to describe elf files: Add handling information (e.g., the elf version) and separate structures for the ELF header, the program headers, and the section headers. - Adjust the read/load operations to account for the new structure. - Add handling code for the differentiation between the two known ELF versions. - Adjust the writing code such that it can output the content of an ELF image as a standard ANDROID! image: The newer ELF versions are not booted if a single (unused) bit is modifed. Possibly the (unlocked) bootloader performs a signature check only for ELF files. - Add some debug code that allows to print either to stdout or the kernel log (useful for on-device debugging). The code has been tested with the boot image of an Xperia Z2. Change-Id: I0e9a41ae6ce26bf4608ef86cec1e2735f746abb6 Signed-off-by: Alexander Diewald <Diewi@diewald-net.com>
1 parent 11e79c5 commit 4466202

4 files changed

Lines changed: 600 additions & 140 deletions

File tree

Android.mk

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LOCAL_FORCE_STATIC_EXECUTABLE := true
1313
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
1414
LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED)
1515

16-
LOCAL_STATIC_LIBRARIES := libc
16+
LOCAL_STATIC_LIBRARIES := libc libcutils
1717

1818
include $(BUILD_EXECUTABLE)
1919

@@ -46,4 +46,5 @@ include $(CLEAR_VARS)
4646
LOCAL_SRC_FILES := src/libbootimg.c
4747
LOCAL_MODULE := libbootimg
4848
LOCAL_MODULE_TAGS := eng
49+
LOCAL_SHARED_LIBRARIES := libc
4950
include $(BUILD_STATIC_LIBRARY)

include/boot_img_hdr.h

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <stdint.h>
2121

2222
/*
23-
** +-----------------+
23+
** +-----------------+
2424
** | boot header | 1 page
2525
** +-----------------+
2626
** | kernel | n pages
@@ -51,11 +51,18 @@
5151

5252
#define BOOT_MAGIC "ANDROID!"
5353
#define BOOT_MAGIC_SIZE 8
54-
#define BOOT_MAGIC_ELF "ELF"
55-
#define BOOT_MAGIC_ELF_SIZE 3
5654
#define BOOT_NAME_SIZE 16
5755
#define BOOT_ARGS_SIZE 512
5856

57+
#define BOOT_MAGIC_ELF "ELF"
58+
#define BOOT_MAGIC_ELF_SIZE 3
59+
#define VER_ELF_1 (1 << 0)
60+
#define VER_ELF_2 (1 << 1)
61+
62+
#define OUT_ELF (1 << 0) // Same output format: ELF container.
63+
#define OUT_AND (1 << 1) // Different output format: standard Android container.
64+
65+
5966
struct boot_img_hdr
6067
{
6168
uint8_t magic[BOOT_MAGIC_SIZE];
@@ -81,59 +88,62 @@ struct boot_img_hdr
8188
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
8289
};
8390

84-
struct boot_img_hdr_elf
91+
struct boot_img_elf_hdr
8592
{
8693
uint8_t magic[8]; /* .ELF (0x00 to 0x07) */
87-
uint8_t unused[8]; /* unused chars */
88-
uint16_t type; /* boot type */
89-
uint16_t machine; /* boot machine */
90-
uint32_t version; /* boot version */
91-
uint32_t entry_addr; /* boot entry */
92-
uint32_t phoff; /* boot phoff */
93-
uint32_t shoff; /* boot shoff */
94-
uint32_t flags; /* boot flags */
95-
uint16_t ehsize; /* boot ehsize */
96-
uint16_t phentsize; /* boot phentsize */
97-
uint16_t phnum; /* boot phnum */
98-
uint16_t shentsize; /* boot shentsize */
99-
uint16_t shnum; /* boot shnum */
100-
uint16_t shstrndx; /* boot shstrndx */
101-
uint32_t kernel_type; /* kernel type (0x34 to 0x37) */
102-
uint32_t kernel_offset; /* kernel offset (0x38 to 0x3B) */
103-
uint32_t kernel_vaddr; /* kernel address (0x3C to 0x3F) */
104-
uint32_t kernel_paddr; /* kernel address duplicate */
105-
uint32_t kernel_size; /* kernel size (0x44 to 0x47) */
106-
uint32_t kernel_msize; /* kernel size duplicate */
107-
uint32_t kernel_flags; /* kernel flags (0x4C to 0x4F) */
108-
uint32_t kernel_align; /* kernel alignment */
109-
uint32_t ramdisk_type; /* kernel type (0x54) */
110-
uint32_t ramdisk_offset; /* ramdisk offset (0x58 to 0x5B) */
111-
uint32_t ramdisk_vaddr; /* ramdisk address (0x5C to 0x5F) */
112-
uint32_t ramdisk_paddr; /* ramdisk address duplicate */
113-
uint32_t ramdisk_size; /* ramdisk size (0x64 to 0x67) */
114-
uint32_t ramdisk_msize; /* ramdisk size duplicate */
115-
uint32_t ramdisk_flags; /* ramdisk flags (0x6C to 0x6F) */
116-
uint32_t ramdisk_align; /* cmdline alignment */
117-
uint32_t rpm_type; /* rpm type (0x74 to 0x77) */
118-
uint32_t rpm_offset; /* rpm offset (0x78 to 0x7B) */
119-
uint32_t rpm_vaddr; /* rpm address (0x7C to 0x7F) */
120-
uint32_t rpm_paddr; /* rpm address duplicate */
121-
uint32_t rpm_size; /* rpm size (0x84 to 0x87) */
122-
uint32_t rpm_msize; /* rpm size duplicate */
123-
uint32_t rpm_flags; /* rpm flags (0x8C to 0x8F) */
124-
uint32_t rpm_align; /* rpm alignment */
125-
uint32_t cmd_type; /* cmdline type (0x94 to 0x97) */
126-
uint32_t cmd_offset; /* cmdline offset (0x98 to 0x9B) */
127-
uint32_t cmd_vaddr; /* cmdline address (0x9C to 0x9F) */
128-
uint32_t cmd_paddr; /* cmdline address duplicate */
129-
uint32_t cmd_size; /* cmdline size (0xA4 to 0xA7) */
130-
uint32_t cmd_msize; /* cmdline size duplicate */
131-
uint32_t cmd_flags; /* cmdline flags (0xAC to 0xAF) */
132-
uint32_t cmd_align; /* cmdline alignment */
94+
uint8_t unused[8]; /* unused chars (0x08 to 0x0F) */
95+
uint16_t type; /* boot type (0x10 to 0x11) */
96+
uint16_t machine; /* boot machine (0x12 to 0x13) */
97+
uint32_t version; /* boot version (0x14 to 0x17) */
98+
uint32_t entry_addr; /* boot entry (0x18 to 0x1B) */
99+
uint32_t phoff; /* boot phoff (0x1C to 0x1F) */
100+
uint32_t shoff; /* boot shoff (0x20 to 0x23) */
101+
uint32_t flags; /* boot flags (0x24 to 0x27) */
102+
uint16_t ehsize; /* boot ehsize (0x28 to 0x29) */
103+
uint16_t phentsize; /* boot phentsize (0x2A to 0x2B) */
104+
uint16_t phnum; /* boot phnum (0x2C to 0x2D) */
105+
uint16_t shentsize; /* boot shentsize (0x2E to 0x2F)*/
106+
uint16_t shnum; /* boot shnum (0x30 to 0x31) */
107+
uint16_t shstrndx; /* boot shstrndx (0x32 to 0x33) */
108+
};
109+
110+
struct boot_img_elf_info
111+
{
112+
struct boot_img_elf_hdr hdr; /* The ELF file header. */
113+
struct boot_img_elf_prog_hdr* prog; /* The program header entries. */
114+
struct boot_img_elf_sect_hdr* sect; /* The section header entries. */
115+
struct boot_img_elf_misc_hdr* misc; /* Miscellaneous information found in some ELF versions. */
116+
uint8_t elf_version;
117+
uint8_t elf_out_format;
118+
};
119+
120+
struct boot_img_elf_prog_hdr
121+
{
122+
uint32_t type; /* type (offset + 0x0 to 0x3) */
123+
uint32_t offset; /* offset (offset + 0x4 to 0x7) */
124+
uint32_t vaddr; /* address (offset + 0x8 to 0xB) */
125+
uint32_t paddr; /* address duplicate (offset + 0xC to 0xF) */
126+
uint32_t size; /* size (offset + 0x10 to 0x13) */
127+
uint32_t msize; /* size duplicate (offset + 0x14 to 0x17) */
128+
uint32_t flags; /* flags (offset + 0x18 to 0x1B) */
129+
uint32_t align; /* alignment (offset + 0x1C to 0x1F)*/
130+
};
131+
132+
struct boot_img_elf_sect_hdr
133+
{
134+
uint32_t name;
135+
uint32_t type;
136+
uint32_t flags;
137+
uint32_t addr;
138+
uint32_t offset;
139+
uint32_t size;
140+
uint8_t misc[16];
141+
};
142+
143+
struct boot_img_elf_misc_hdr
144+
{
133145
uint8_t header_vals[3900]; /* header additional values */
134146
uint8_t name[BOOT_NAME_SIZE]; /* added - asciiz product name */
135147
};
136148

137-
typedef struct boot_img_hdr boot_img_hdr;
138-
139149
#endif

include/libbootimg.h

Lines changed: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ extern "C" {
1111

1212
#include <stdint.h>
1313
#include <stdio.h>
14+
#include <cutils/klog.h>
1415
#include "boot_img_hdr.h"
1516

1617
#define LIBBOOTIMG_VERSION 0x000203 // 0xMMNNPP
1718
#define LIBBOOTIMG_VERSION_STR "0.2.3"
1819

20+
#define DEBUG_KMSG
21+
#ifdef DEBUG_KMSG
22+
#define LOG_DBG(fmt, ...) klog_write(3, "<3>%s: " fmt, "libbootimg", ##__VA_ARGS__)
23+
#elif DEBUG_STDOUT
24+
#define LOG_DBG printf("libbootimg: "); printf
25+
#else
26+
#define LOG_DBG(fmt, ...) ""
27+
#endif
28+
1929
/**
2030
* Enum containing possible blob types in a boot image.
2131
*/
@@ -84,10 +94,12 @@ struct bootimg_blob
8494
struct bootimg
8595
{
8696
struct boot_img_hdr hdr; /*!< Boot image header */
97+
struct bootimg_blob blob; /* Complete blob */
98+
uint32_t blob_size; /* Size of the complete blob. */
8799
struct bootimg_blob blobs[LIBBOOTIMG_BLOB_CNT]; /*!< Blobs packed in the boot image. */
88100
int start_offset; /*!< Offset of the boot image structure from the start of the file. Only used when loading blobs from boot.img file. */
89-
struct boot_img_hdr_elf* hdr_elf; /*!< Boot image header in ELF format */
90101
uint8_t is_elf; /*!< Select the ELF boot image format */
102+
struct boot_img_elf_info* hdr_info; /*!< Boot image meta-information for ELF formats. */
91103
};
92104

93105
/**
@@ -117,6 +129,61 @@ int libbootimg_init_load(struct bootimg *img, const char *path, int load_blob_ma
117129
*/
118130
int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path);
119131

132+
/**
133+
* Determines the ELF boot image version (custom definition) and the
134+
* required output format (ELF or ANDROID!) based on the number of
135+
* program headers given by the ELF header.
136+
* @param hdr_info pointer to the structure holding the read header information.
137+
*/
138+
void libbootimg_get_elf_version(struct boot_img_elf_info *hdr_info);
139+
140+
/**
141+
* Reads the program headers from the given ELF file and adds the content
142+
* of each header to the given structure.
143+
* @param hdr_info structure holding the meta-information of the given ELF file.
144+
* @param f pointer to the file descriptor of the ELF file.
145+
* @return zero on success or the error code returned by the file operations.
146+
*/
147+
int libbootimg_load_elf_prog_header(struct boot_img_elf_info *hdr_info, FILE *f);
148+
149+
/**
150+
* Reads the section headers from the given ELF file and adds the content
151+
* of each header to the given structure.
152+
* @param hdr_info structure holding the meta-information of the given ELF file.
153+
* @param f pointer to the file descriptor of the ELF file.
154+
* @return zero on success or the error code returned by the file operations.
155+
*/
156+
int libbootimg_load_elf_sect_header(struct boot_img_elf_info *hdr_info, FILE *f);
157+
158+
/**
159+
* Reads the miscellaneous information from the given ELF file and adds the content
160+
* to the given structure. This information is present in some ELF versions and
161+
* required for them to operate properly (version 1).
162+
* @param hdr_info structure holding the meta-information of the given ELF file.
163+
* @param f pointer to the file descriptor of the ELF file.
164+
* @return one on success or the error code returned by the file operations.
165+
*/
166+
int libbootimg_load_elf_misc_header(struct boot_img_elf_info *hdr_info, FILE *f);
167+
168+
/**
169+
* Extracts the kernel boot command line from an ELF file and adds it to
170+
* the generic structure describing the blob (-> hdr).
171+
* @param hdr pointer to boot_img_hdr structure
172+
* @param elf_info structure holding the meta-information of the given ELF file.
173+
* @param f pointer to the file descriptor of the ELF file.
174+
*/
175+
void libbootimg_read_cmdline(struct boot_img_hdr *hdr, struct boot_img_elf_info *elf_info, FILE *f);
176+
177+
/**
178+
* Returns a pointer referencing the ELF program header which describes the content
179+
* of a given type like the kernel or ramdisk part of a boot image.
180+
* @param hdr_info structure holding the meta-information of the given ELF file.
181+
* @param type integer value that describes the desired pointer as given in the enum
182+
* {@link libbootimg_blob_type}.
183+
* @return pointer to the program header describing the desired part of the boot image.
184+
*/
185+
struct boot_img_elf_prog_hdr* get_elf_proc_hdr_of(struct boot_img_elf_info *elf_info, int type);
186+
120187
/**
121188
* Loads boot_img_hdr or boot_img_hdr_elf from file on disk
122189
* @param hdr pointer to boot_img_hdr structure
@@ -127,7 +194,8 @@ int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path);
127194
* successful, negative value from libbootimg_error if failed.
128195
*/
129196
int libbootimg_load_headers(struct boot_img_hdr *hdr,
130-
struct boot_img_hdr_elf *hdr_elf, uint8_t *is_elf, const char *path);
197+
struct boot_img_elf_info *hdr_elf, struct bootimg *img,
198+
uint8_t *is_elf, const char *path);
131199

132200
/**
133201
* Updates the header addresses to the blobs.
@@ -142,8 +210,6 @@ int libbootimg_update_headers(struct bootimg *b);
142210
*/
143211
void libbootimg_destroy(struct bootimg *b);
144212

145-
146-
147213
/**
148214
* Writes blob to a file.
149215
* @param blob pointer to source struct bootimg_blob
@@ -244,6 +310,14 @@ int libbootimg_write_img(struct bootimg *b, const char *dest);
244310
*/
245311
int libbootimg_write_img_fileptr(struct bootimg *b, FILE *f);
246312

313+
/**
314+
* Writes boot image to a file: Updated implementation that effectively *injects* data into an existing boot image
315+
* @param b pointer to struct bootimg
316+
* @param f pointer to FILE to write data into
317+
* @return number of bytes written to the file if successful, negative value from libbootimg_error if failed.
318+
*/
319+
int libbootimg_write_img_fileptr_new(struct bootimg *b, FILE *f);
320+
247321
/**
248322
* Writes boot image to a file and then calls libbootimg_destroy.
249323
* The bootimg struct is destroyed even if this function fails.
@@ -274,6 +348,34 @@ const char *libbootimg_version_str(void);
274348
*/
275349
const char *libbootimg_error_str(int error);
276350

351+
/**
352+
* Prints the content of the boot image information to the stdout or
353+
* the kernel log (dmesg).
354+
* @param hdr pointer to the boot image information.
355+
*/
356+
void print_hdr_to_log(struct boot_img_hdr* hdr);
357+
358+
/**
359+
* Prints the content of an elf header described by the given structure
360+
* to the stdout or the kernel log (dmesg).
361+
* @param elf_info pointer to the elf header information.
362+
*/
363+
void print_elf_hdr_to_log(struct boot_img_elf_info* elf_info);
364+
365+
/**
366+
* Prints the content of an elf program header described by the given structure
367+
* to the stdout or the kernel log (dmesg).
368+
* @param elf_prog_hdr pointer to the program header information.
369+
*/
370+
void print_elf_prog_hdr_to_log(struct boot_img_elf_prog_hdr* elf_prog_hdr);
371+
372+
/**
373+
* Prints the content of an elf section header described by the given structure
374+
* to the stdout or the kernel log (dmesg).
375+
* @param elf_prog_hdr pointer to the section header information.
376+
*/
377+
void print_elf_sect_hdr_to_log(struct boot_img_elf_sect_hdr* elf_sect_hdr);
378+
277379
#ifdef __cplusplus
278380
}
279381
#endif

0 commit comments

Comments
 (0)