image-android.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <image.h>
  8. #include <android_image.h>
  9. #include <malloc.h>
  10. #include <errno.h>
  11. #define ANDROID_IMAGE_DEFAULT_KERNEL_ADDR 0x10008000
  12. static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1];
  13. static ulong android_image_get_kernel_addr(const struct andr_img_hdr *hdr)
  14. {
  15. /*
  16. * All the Android tools that generate a boot.img use this
  17. * address as the default.
  18. *
  19. * Even though it doesn't really make a lot of sense, and it
  20. * might be valid on some platforms, we treat that adress as
  21. * the default value for this field, and try to execute the
  22. * kernel in place in such a case.
  23. *
  24. * Otherwise, we will return the actual value set by the user.
  25. */
  26. if (hdr->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR)
  27. return (ulong)hdr + hdr->page_size;
  28. return hdr->kernel_addr;
  29. }
  30. /**
  31. * android_image_get_kernel() - processes kernel part of Android boot images
  32. * @hdr: Pointer to image header, which is at the start
  33. * of the image.
  34. * @verify: Checksum verification flag. Currently unimplemented.
  35. * @os_data: Pointer to a ulong variable, will hold os data start
  36. * address.
  37. * @os_len: Pointer to a ulong variable, will hold os data length.
  38. *
  39. * This function returns the os image's start address and length. Also,
  40. * it appends the kernel command line to the bootargs env variable.
  41. *
  42. * Return: Zero, os start address and length on success,
  43. * otherwise on failure.
  44. */
  45. int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify,
  46. ulong *os_data, ulong *os_len)
  47. {
  48. u32 kernel_addr = android_image_get_kernel_addr(hdr);
  49. /*
  50. * Not all Android tools use the id field for signing the image with
  51. * sha1 (or anything) so we don't check it. It is not obvious that the
  52. * string is null terminated so we take care of this.
  53. */
  54. strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE);
  55. andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0';
  56. if (strlen(andr_tmp_str))
  57. printf("Android's image name: %s\n", andr_tmp_str);
  58. printf("Kernel load addr 0x%08x size %u KiB\n",
  59. kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024));
  60. int len = 0;
  61. if (*hdr->cmdline) {
  62. printf("Kernel command line: %s\n", hdr->cmdline);
  63. len += strlen(hdr->cmdline);
  64. }
  65. char *bootargs = getenv("bootargs");
  66. if (bootargs)
  67. len += strlen(bootargs);
  68. char *newbootargs = malloc(len + 2);
  69. if (!newbootargs) {
  70. puts("Error: malloc in android_image_get_kernel failed!\n");
  71. return -ENOMEM;
  72. }
  73. *newbootargs = '\0';
  74. if (bootargs) {
  75. strcpy(newbootargs, bootargs);
  76. strcat(newbootargs, " ");
  77. }
  78. if (*hdr->cmdline)
  79. strcat(newbootargs, hdr->cmdline);
  80. setenv("bootargs", newbootargs);
  81. if (os_data) {
  82. *os_data = (ulong)hdr;
  83. *os_data += hdr->page_size;
  84. }
  85. if (os_len)
  86. *os_len = hdr->kernel_size;
  87. return 0;
  88. }
  89. int android_image_check_header(const struct andr_img_hdr *hdr)
  90. {
  91. return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE);
  92. }
  93. ulong android_image_get_end(const struct andr_img_hdr *hdr)
  94. {
  95. ulong end;
  96. /*
  97. * The header takes a full page, the remaining components are aligned
  98. * on page boundary
  99. */
  100. end = (ulong)hdr;
  101. end += hdr->page_size;
  102. end += ALIGN(hdr->kernel_size, hdr->page_size);
  103. end += ALIGN(hdr->ramdisk_size, hdr->page_size);
  104. end += ALIGN(hdr->second_size, hdr->page_size);
  105. return end;
  106. }
  107. ulong android_image_get_kload(const struct andr_img_hdr *hdr)
  108. {
  109. return android_image_get_kernel_addr(hdr);
  110. }
  111. int android_image_get_ramdisk(const struct andr_img_hdr *hdr,
  112. ulong *rd_data, ulong *rd_len)
  113. {
  114. if (!hdr->ramdisk_size) {
  115. *rd_data = *rd_len = 0;
  116. return -1;
  117. }
  118. printf("RAM disk load addr 0x%08x size %u KiB\n",
  119. hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024));
  120. *rd_data = (unsigned long)hdr;
  121. *rd_data += hdr->page_size;
  122. *rd_data += ALIGN(hdr->kernel_size, hdr->page_size);
  123. *rd_len = hdr->ramdisk_size;
  124. return 0;
  125. }
  126. #if !defined(CONFIG_SPL_BUILD)
  127. /**
  128. * android_print_contents - prints out the contents of the Android format image
  129. * @hdr: pointer to the Android format image header
  130. *
  131. * android_print_contents() formats a multi line Android image contents
  132. * description.
  133. * The routine prints out Android image properties
  134. *
  135. * returns:
  136. * no returned results
  137. */
  138. void android_print_contents(const struct andr_img_hdr *hdr)
  139. {
  140. const char * const p = IMAGE_INDENT_STRING;
  141. printf("%skernel size: %x\n", p, hdr->kernel_size);
  142. printf("%skernel address: %x\n", p, hdr->kernel_addr);
  143. printf("%sramdisk size: %x\n", p, hdr->ramdisk_size);
  144. printf("%sramdisk addrress: %x\n", p, hdr->ramdisk_addr);
  145. printf("%ssecond size: %x\n", p, hdr->second_size);
  146. printf("%ssecond address: %x\n", p, hdr->second_addr);
  147. printf("%stags address: %x\n", p, hdr->tags_addr);
  148. printf("%spage size: %x\n", p, hdr->page_size);
  149. printf("%sname: %s\n", p, hdr->name);
  150. printf("%scmdline: %s\n", p, hdr->cmdline);
  151. }
  152. #endif