@@ -18,7 +18,7 @@ static inline unsigned align_size(unsigned size, unsigned page_size)
1818
1919static 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
174185int 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+
211297int 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