Advertisement
Zacharee1

split_boot

Aug 27th, 2017
460
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.38 KB | None | 0 0
  1. ######################################################################
  2. #
  3. # File : split_boot
  4. # Author(s) : William Enck <enck@cse.psu.edu>
  5. # Modified by CNexus to split the <nameHere>.img to a separate folder
  6. # and to display the BASE address so that the files can be repacked correctly.
  7. #
  8. # Description : Split appart an Android boot image created
  9. # with mkbootimg. The format can be found in
  10. # android-src/system/core/mkbootimg/bootimg.h
  11. #
  12. # Thanks to alansj on xda-developers.com for
  13. # identifying the format in bootimg.h and
  14. # describing initial instructions for splitting
  15. # the boot.img file.
  16. #
  17. # Last Modified : Tue Dec 2 23:36:25 EST 2008
  18. # By : William Enck <enck@cse.psu.edu>
  19. #
  20. # Copyright (c) 2008 The Pennsylvania State University
  21. # Systems and Internet Infrastructure Security Laboratory
  22. #
  23. # Licensed under the Apache License, Version 2.0 (the "License");
  24. # you may not use this file except in compliance with the License.
  25. # You may obtain a copy of the License at
  26. #
  27. # http://www.apache.org/licenses/LICENSE-2.0
  28. #
  29. # Unless required by applicable law or agreed to in writing, software
  30. # distributed under the License is distributed on an "AS IS" BASIS,
  31. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  32. # See the License for the specific language governing permissions and
  33. # limitations under the License.
  34. #
  35. ######################################################################
  36.  
  37. use strict;
  38. use warnings;
  39.  
  40. # Turn on print flushing
  41. $|++;
  42.  
  43. ######################################################################
  44. ## Global Variables and Constants
  45.  
  46. my $SCRIPT = __FILE__;
  47. my $IMAGE_FN = undef;
  48.  
  49. # Constants (from bootimg.h)
  50. use constant BOOT_MAGIC => 'ANDROID!';
  51. use constant BOOT_MAGIC_SIZE => 8;
  52. use constant BOOT_NAME_SIZE => 16;
  53. use constant BOOT_ARGS_SIZE => 512;
  54.  
  55. # Unsigned integers are 4 bytes
  56. use constant UNSIGNED_SIZE => 4;
  57.  
  58. # Parsed Values
  59. my $PAGE_SIZE = undef;
  60. my $KERNEL_SIZE = undef;
  61. my $RAMDISK_SIZE = undef;
  62. my $SECOND_SIZE = undef;
  63.  
  64. ######################################################################
  65. ## Main Code
  66.  
  67. &parse_cmdline();
  68. &parse_header($IMAGE_FN);
  69.  
  70. =format (from bootimg.h)
  71. ** +-----------------+
  72. ** | boot header | 1 page
  73. ** +-----------------+
  74. ** | kernel | n pages
  75. ** +-----------------+
  76. ** | ramdisk | m pages
  77. ** +-----------------+
  78. ** | second stage | o pages
  79. ** +-----------------+
  80. **
  81. ** n = (kernel_size + page_size - 1) / page_size
  82. ** m = (ramdisk_size + page_size - 1) / page_size
  83. ** o = (second_size + page_size - 1) / page_size
  84. =cut
  85.  
  86. my $n = int(($KERNEL_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);
  87. my $m = int(($RAMDISK_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);
  88. my $o = int(($SECOND_SIZE + $PAGE_SIZE - 1) / $PAGE_SIZE);
  89.  
  90. my $k_offset = $PAGE_SIZE;
  91. my $r_offset = $k_offset + ($n * $PAGE_SIZE);
  92. my $s_offset = $r_offset + ($m * $PAGE_SIZE);
  93.  
  94. (my $base = $IMAGE_FN) =~ s/.*\/(.*)$/$1/;
  95. (my $base2 = $base) =~ s/\.[^.]+$//;
  96.  
  97. my $k_file = $base2. "/" . $base . "-kernel";
  98. my $r_file = $base2. "/" . $base . "-ramdisk.cpio.gz";
  99. my $s_file = $base2. "/" . $base . "-second.gz";
  100.  
  101. mkdir $base2;
  102. mkdir $base2 . "/ramdisk";
  103.  
  104. # The kernel is always there
  105. print "Writing $k_file ...";
  106. &dump_file($IMAGE_FN, $k_file, $k_offset, $KERNEL_SIZE);
  107. print " complete.\n";
  108.  
  109. # The ramdisk is always there
  110. print "Writing $r_file ...";
  111. &dump_file($IMAGE_FN, $r_file, $r_offset, $RAMDISK_SIZE);
  112. print " complete.\n";
  113.  
  114. # The Second stage bootloader is optional
  115. unless ($SECOND_SIZE == 0) {
  116. print "Writing $s_file ...";
  117. &dump_file($IMAGE_FN, $s_file, $s_offset, $SECOND_SIZE);
  118. print " complete.\n";
  119. }
  120.  
  121. print "Unpacking ramdisk...";
  122. print " complete.\n";
  123. system("cd $base2/ramdisk && gunzip -c ../$base-ramdisk.cpio.gz | cpio -i > /dev/null 2>&1");
  124.  
  125. ######################################################################
  126. ## Supporting Subroutines
  127.  
  128. =header_format (from bootimg.h)
  129. struct boot_img_hdr
  130. {
  131. unsigned char magic[BOOT_MAGIC_SIZE];
  132.  
  133. unsigned kernel_size; /* size in bytes */
  134. unsigned kernel_addr; /* physical load addr */
  135.  
  136. unsigned ramdisk_size; /* size in bytes */
  137. unsigned ramdisk_addr; /* physical load addr */
  138.  
  139. unsigned second_size; /* size in bytes */
  140. unsigned second_addr; /* physical load addr */
  141.  
  142. unsigned tags_addr; /* physical addr for kernel tags */
  143. unsigned page_size; /* flash page size we assume */
  144. unsigned unused[2]; /* future expansion: should be 0 */
  145.  
  146. unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */
  147.  
  148. unsigned char cmdline[BOOT_ARGS_SIZE];
  149.  
  150. unsigned id[8]; /* timestamp / checksum / sha1 / etc */
  151. };
  152. =cut
  153. sub parse_header {
  154. my ($fn) = @_;
  155. my $buf = undef;
  156.  
  157. open INF, $fn or die "Could not open $fn: $!\n";
  158. binmode INF;
  159.  
  160. # Read the Magic
  161. read(INF, $buf, BOOT_MAGIC_SIZE);
  162. unless ($buf eq BOOT_MAGIC) {
  163. die "Android Magic not found in $fn. Giving up.\n";
  164. }
  165.  
  166. # Read kernel size and address (assume little-endian)
  167. read(INF, $buf, UNSIGNED_SIZE * 2);
  168. my ($k_size, $k_addr) = unpack("VV", $buf);
  169.  
  170. # Read ramdisk size and address (assume little-endian)
  171. read(INF, $buf, UNSIGNED_SIZE * 2);
  172. my ($r_size, $r_addr) = unpack("VV", $buf);
  173.  
  174. # Read second size and address (assume little-endian)
  175. read(INF, $buf, UNSIGNED_SIZE * 2);
  176. my ($s_size, $s_addr) = unpack("VV", $buf);
  177.  
  178. # Read tags_addr
  179. read(INF, $buf, UNSIGNED_SIZE);
  180. my ($tags_addr) = unpack("V", $buf);
  181.  
  182. # get the page size (assume little-endian)
  183. read(INF, $buf, UNSIGNED_SIZE);
  184. my ($p_size) = unpack("V", $buf);
  185.  
  186. # Ignore unused
  187. read(INF, $buf, UNSIGNED_SIZE * 2);
  188.  
  189. # Read the name (board name)
  190. read(INF, $buf, BOOT_NAME_SIZE);
  191. my $name = $buf;
  192.  
  193. # Read the command line
  194. read(INF, $buf, BOOT_ARGS_SIZE);
  195. my $cmdline = $buf;
  196.  
  197. # Ignore the id
  198. read(INF, $buf, UNSIGNED_SIZE * 8);
  199.  
  200. # Close the file
  201. close INF;
  202.  
  203. # Print important values
  204. printf "Page size: %d (0x%08x)\n", $p_size, $p_size;
  205. printf "Kernel size: %d (0x%08x)\n", $k_size, $k_size;
  206. printf "Ramdisk size: %d (0x%08x)\n", $r_size, $r_size;
  207. printf "Second size: %d (0x%08x)\n", $s_size, $s_size;
  208. printf "Board name: $name\n";
  209. printf "Command line: \'$cmdline\'\n";
  210. printf "Base address: (0x%08x)\n", $tags_addr - 0x00000100;
  211. print "\n";
  212.  
  213. # Save the values
  214. $PAGE_SIZE = $p_size;
  215. $KERNEL_SIZE = $k_size;
  216. $RAMDISK_SIZE = $r_size;
  217. $SECOND_SIZE = $s_size;
  218. }
  219.  
  220. sub dump_file {
  221. my ($infn, $outfn, $offset, $size) = @_;
  222. my $buf = undef;
  223.  
  224. open INF, $infn or die "Could not open $infn: $!\n";
  225. open OUTF, ">$outfn" or die "Could not open $outfn: $!\n";
  226.  
  227. binmode INF;
  228. binmode OUTF;
  229.  
  230. seek(INF, $offset, 0) or die "Could not seek in $infn: $!\n";
  231. read(INF, $buf, $size) or die "Could not read $infn: $!\n";
  232. print OUTF $buf or die "Could not write $outfn: $!\n";
  233.  
  234. close INF;
  235. close OUTF;
  236. }
  237.  
  238. ######################################################################
  239. ## Configuration Subroutines
  240.  
  241. sub parse_cmdline {
  242. unless ($#ARGV == 0) {
  243. die "Usage: $SCRIPT boot.img\n";
  244. }
  245. $IMAGE_FN = $ARGV[0];
  246. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement