Skip to content

Commit 577b380

Browse files
committed
Merge pull request #1 from AdrianDC/master
libbootimg: Add support Sony ELF boot image format
2 parents 6607d1c + 16ac77b commit 577b380

3 files changed

Lines changed: 200 additions & 19 deletions

File tree

include/boot_img_hdr.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
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
5456
#define BOOT_NAME_SIZE 16
5557
#define BOOT_ARGS_SIZE 512
5658

@@ -79,6 +81,58 @@ struct boot_img_hdr
7981
uint32_t id[8]; /* timestamp / checksum / sha1 / etc */
8082
};
8183

84+
struct boot_img_hdr_elf
85+
{
86+
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 */
133+
uint8_t name[BOOT_NAME_SIZE]; /* added - asciiz product name */
134+
};
135+
82136
typedef struct boot_img_hdr boot_img_hdr;
83137

84138
#endif

include/libbootimg.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ struct bootimg
8686
struct boot_img_hdr hdr; /*!< Boot image header */
8787
struct bootimg_blob blobs[LIBBOOTIMG_BLOB_CNT]; /*!< Blobs packed in the boot image. */
8888
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 */
90+
uint8_t is_elf; /*!< Select the ELF boot image format */
8991
};
9092

9193
/**
@@ -110,10 +112,30 @@ int libbootimg_init_load(struct bootimg *img, const char *path, int load_blob_ma
110112
* Loads boot_img_hdr from file on disk
111113
* @param hdr pointer to boot_img_hdr structure
112114
* @param path path to boot.img to load header from
113-
* @return positive offset of the header from the start of the file if successful, negative value from libbootimg_error if failed.
115+
* @return positive offset of the header from the start of the file if
116+
* successful, negative value from libbootimg_error if failed.
114117
*/
115118
int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path);
116119

120+
/**
121+
* Loads boot_img_hdr or boot_img_hdr_elf from file on disk
122+
* @param hdr pointer to boot_img_hdr structure
123+
* @param hdr_elf pointer to boot_img_hdr_elf structure
124+
* @param is_elf pointer to is_elf attribute
125+
* @param path path to boot.img to load header from
126+
* @return positive offset of the header from the start of the file if
127+
* successful, negative value from libbootimg_error if failed.
128+
*/
129+
int libbootimg_load_headers(struct boot_img_hdr *hdr,
130+
struct boot_img_hdr_elf *hdr_elf, uint8_t *is_elf, const char *path);
131+
132+
/**
133+
* Updates the header addresses to the blobs.
134+
* @param img pointer to initialized struct bootimg
135+
* @return Zero if successful, negative value from libbootimg_error if failed.
136+
*/
137+
int libbootimg_update_headers(struct bootimg *b);
138+
117139
/**
118140
* Frees all resources used by this bootimg struct
119141
* @param b pointer to struct bootimg

src/libbootimg.c

Lines changed: 123 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static inline unsigned align_size(unsigned size, unsigned page_size)
1818

1919
static int translate_errnum(int errnum)
2020
{
21-
switch(errno)
21+
switch (errnum)
2222
{
2323
case EIO: return LIBBOOTIMG_ERROR_IO;
2424
case EACCES: return LIBBOOTIMG_ERROR_ACCESS;
@@ -92,6 +92,9 @@ void libbootimg_init_new(struct bootimg *img)
9292
memset(img, 0, sizeof(struct bootimg));
9393
memcpy(img->hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE);
9494
img->hdr.page_size = DEFAULT_PAGE_SIZE;
95+
img->hdr_elf = malloc(sizeof(struct boot_img_hdr_elf));
96+
memset(img->hdr_elf, sizeof(struct boot_img_hdr_elf), 0);
97+
img->is_elf = 0;
9598

9699
img->blobs[LIBBOOTIMG_BLOB_KERNEL].size = &img->hdr.kernel_size;
97100
img->blobs[LIBBOOTIMG_BLOB_RAMDISK].size = &img->hdr.ramdisk_size;
@@ -109,7 +112,7 @@ int libbootimg_init_load(struct bootimg *img, const char *path, int load_blob_ma
109112

110113
libbootimg_init_new(img);
111114

112-
res = libbootimg_load_header(&img->hdr, path);
115+
res = libbootimg_load_headers(&img->hdr, img->hdr_elf, &img->is_elf, path);
113116
if(res < 0)
114117
{
115118
libbootimg_destroy(img);
@@ -148,7 +151,14 @@ int libbootimg_init_load(struct bootimg *img, const char *path, int load_blob_ma
148151
}
149152
}
150153

151-
addr += align_size(*blob->size, img->hdr.page_size);
154+
if (!img->is_elf)
155+
{
156+
addr += align_size(*blob->size, img->hdr.page_size);
157+
}
158+
else
159+
{
160+
addr += *blob->size;
161+
}
152162
}
153163

154164
fclose(f);
@@ -164,6 +174,7 @@ void libbootimg_destroy(struct bootimg *b)
164174
{
165175
struct bootimg_blob *blob = b->blobs;
166176
struct bootimg_blob * const blobs_end = blob + LIBBOOTIMG_BLOB_CNT;
177+
free(b->hdr_elf);
167178
for(; blob != blobs_end; ++blob)
168179
{
169180
free(blob->data);
@@ -172,30 +183,72 @@ void libbootimg_destroy(struct bootimg *b)
172183
}
173184

174185
int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path)
186+
{
187+
struct boot_img_hdr_elf hdr_elf;
188+
return libbootimg_load_headers(hdr, &hdr_elf, NULL, path);
189+
}
190+
191+
int libbootimg_load_headers(struct boot_img_hdr *hdr,
192+
struct boot_img_hdr_elf *hdr_elf, uint8_t *is_elf, const char *path)
175193
{
176194
int res = 0;
177195
FILE *f;
178196
size_t i;
197+
uint32_t cmd_len;
179198
static const int known_magic_pos[] = {
180199
0x0, // default
181200
0x100, // HTC signed boot images
182201
};
183202

184203
f= fopen(path, "r");
185-
if(!f)
204+
if (!f)
186205
return translate_errnum(errno);
187206

188207
res = LIBBOOTIMG_ERROR_INVALID_MAGIC;
189-
for(i = 0; i < sizeof(known_magic_pos)/sizeof(known_magic_pos[0]); ++i)
208+
for (i = 0; i < sizeof(known_magic_pos)/sizeof(known_magic_pos[0]); ++i)
190209
{
191210
fseek(f, known_magic_pos[i], SEEK_SET);
192-
if(fread(hdr, sizeof(struct boot_img_hdr), 1, f) == 1)
211+
if (fread(hdr, sizeof(struct boot_img_hdr), 1, f) == 1)
193212
{
194-
if(memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
213+
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0)
195214
{
215+
if (is_elf != NULL)
216+
{
217+
*is_elf = 0;
218+
}
196219
res = known_magic_pos[i];
197220
break;
198221
}
222+
else if (hdr_elf != NULL && memcmp(hdr->magic + 1, BOOT_MAGIC_ELF,
223+
BOOT_MAGIC_ELF_SIZE) == 0)
224+
{
225+
fseek(f, 0, SEEK_SET);
226+
if (fread(hdr_elf, sizeof(struct boot_img_hdr_elf), 1, f) == 1)
227+
{
228+
hdr->kernel_size = hdr_elf->kernel_size;
229+
hdr->kernel_addr = hdr_elf->kernel_offset;
230+
hdr->ramdisk_size = hdr_elf->ramdisk_size;
231+
hdr->ramdisk_addr = hdr_elf->ramdisk_offset;
232+
hdr->second_size = hdr_elf->rpm_size;
233+
hdr->second_addr = hdr_elf->rpm_offset;
234+
hdr->page_size = hdr_elf->kernel_offset;
235+
hdr->tags_addr = 0;
236+
hdr->dt_size = 0;
237+
hdr->id[0] = '\0';
238+
memcpy(hdr->name, hdr_elf->name, BOOT_NAME_SIZE);
239+
cmd_len = hdr_elf->cmd_size;
240+
memset(hdr->cmdline, '\0', BOOT_ARGS_SIZE);
241+
fseek(f, hdr_elf->cmd_offset, SEEK_SET);
242+
fread(hdr->cmdline, cmd_len < BOOT_ARGS_SIZE ?
243+
cmd_len : BOOT_ARGS_SIZE, 1, f);
244+
res = known_magic_pos[i];
245+
if (is_elf != NULL)
246+
{
247+
*is_elf = 1;
248+
}
249+
break;
250+
}
251+
}
199252
}
200253
else
201254
{
@@ -208,6 +261,39 @@ int libbootimg_load_header(struct boot_img_hdr *hdr, const char *path)
208261
return res;
209262
}
210263

264+
int libbootimg_update_headers(struct bootimg *b)
265+
{
266+
uint32_t addr;
267+
268+
if (b == NULL)
269+
return translate_errnum(ENOENT);
270+
271+
if (b->is_elf)
272+
{
273+
b->hdr_elf->kernel_size = b->hdr.kernel_size;
274+
b->hdr_elf->kernel_msize = b->hdr.kernel_size;
275+
b->hdr_elf->ramdisk_size = b->hdr.ramdisk_size;
276+
b->hdr_elf->ramdisk_msize = b->hdr.ramdisk_size;
277+
b->hdr_elf->rpm_size = b->hdr.second_size;
278+
b->hdr_elf->rpm_msize = b->hdr.second_size;
279+
280+
addr = b->hdr_elf->kernel_offset;
281+
282+
addr += b->hdr_elf->kernel_size;
283+
b->hdr_elf->ramdisk_offset = addr;
284+
285+
addr += b->hdr_elf->ramdisk_size;
286+
b->hdr_elf->rpm_offset = addr;
287+
288+
addr += b->hdr_elf->rpm_size;
289+
b->hdr_elf->cmd_offset = addr;
290+
291+
memcpy(b->hdr_elf->name, b->hdr.name, BOOT_NAME_SIZE);
292+
}
293+
294+
return 0;
295+
}
296+
211297
int libbootimg_dump_blob(struct bootimg_blob *blob, const char *dest)
212298
{
213299
FILE *f;
@@ -364,31 +450,50 @@ int libbootimg_write_img_fileptr(struct bootimg *b, FILE *f)
364450
memset(blank, 0, b->hdr.page_size);
365451

366452
// write header
367-
if(fwrite(&b->hdr, sizeof(b->hdr), 1, f) != 1)
368-
goto fail_fwrite;
453+
if (!b->is_elf)
454+
{
455+
if (fwrite(&b->hdr, sizeof(b->hdr), 1, f) != 1)
456+
goto fail_fwrite;
457+
458+
padding = align_size(sizeof(b->hdr), b->hdr.page_size) - sizeof(b->hdr);
459+
}
460+
else
461+
{
462+
libbootimg_update_headers(b);
369463

370-
padding = align_size(sizeof(b->hdr), b->hdr.page_size) - sizeof(b->hdr);
371-
if(fwrite(blank, 1, padding, f) != padding)
464+
if (fwrite(b->hdr_elf, sizeof(*b->hdr_elf), 1, f) != 1)
465+
goto fail_fwrite;
466+
467+
padding = align_size(sizeof(*b->hdr_elf), b->hdr.page_size) - sizeof(*b->hdr_elf);
468+
}
469+
470+
if (fwrite(blank, 1, padding, f) != padding)
372471
goto fail_fwrite;
373472

374-
for(i = 0; i < LIBBOOTIMG_BLOB_CNT; ++i)
473+
for (i = 0; i < LIBBOOTIMG_BLOB_CNT; ++i)
375474
{
376475
blob = &b->blobs[i];
377476

378-
if(*blob->size == 0)
477+
if (*blob->size == 0)
379478
continue;
380479

381-
if(fwrite(blob->data, *blob->size, 1, f) != 1)
480+
if (fwrite(blob->data, *blob->size, 1, f) != 1)
382481
goto fail_fwrite;
383482

384-
padding = align_size(*blob->size, b->hdr.page_size) - *blob->size;
385-
if(fwrite(blank, 1, padding, f) != padding)
386-
goto fail_fwrite;
483+
if (!b->is_elf)
484+
{
485+
padding = align_size(*blob->size, b->hdr.page_size) - *blob->size;
486+
if (fwrite(blank, 1, padding, f) != padding)
487+
goto fail_fwrite;
488+
}
387489
}
388490

491+
if (b->is_elf && fwrite(b->hdr.cmdline, b->hdr_elf->cmd_size, 1, f) != 1)
492+
goto fail_fwrite;
493+
389494
pos_end = ftell(f);
390495

391-
if(pos_end > 0)
496+
if (pos_end > 0)
392497
res = pos_end - pos_start;
393498
else
394499
res = translate_errnum(errno);

0 commit comments

Comments
 (0)