1 /* 2 * Copyright (c) 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <image.h> 9 #include <android_image.h> 10 #include <malloc.h> 11 #include <errno.h> 12 13 static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; 14 15 /** 16 * android_image_get_kernel() - processes kernel part of Android boot images 17 * @hdr: Pointer to image header, which is at the start 18 * of the image. 19 * @verify: Checksum verification flag. Currently unimplemented. 20 * @os_data: Pointer to a ulong variable, will hold os data start 21 * address. 22 * @os_len: Pointer to a ulong variable, will hold os data length. 23 * 24 * This function returns the os image's start address and length. Also, 25 * it appends the kernel command line to the bootargs env variable. 26 * 27 * Return: Zero, os start address and length on success, 28 * otherwise on failure. 29 */ 30 int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, 31 ulong *os_data, ulong *os_len) 32 { 33 /* 34 * Not all Android tools use the id field for signing the image with 35 * sha1 (or anything) so we don't check it. It is not obvious that the 36 * string is null terminated so we take care of this. 37 */ 38 strncpy(andr_tmp_str, hdr->name, ANDR_BOOT_NAME_SIZE); 39 andr_tmp_str[ANDR_BOOT_NAME_SIZE] = '\0'; 40 if (strlen(andr_tmp_str)) 41 printf("Android's image name: %s\n", andr_tmp_str); 42 43 printf("Kernel load addr 0x%08x size %u KiB\n", 44 hdr->kernel_addr, DIV_ROUND_UP(hdr->kernel_size, 1024)); 45 46 int len = 0; 47 if (*hdr->cmdline) { 48 printf("Kernel command line: %s\n", hdr->cmdline); 49 len += strlen(hdr->cmdline); 50 } 51 52 char *bootargs = getenv("bootargs"); 53 if (bootargs) 54 len += strlen(bootargs); 55 56 char *newbootargs = malloc(len + 2); 57 if (!newbootargs) { 58 puts("Error: malloc in android_image_get_kernel failed!\n"); 59 return -ENOMEM; 60 } 61 *newbootargs = '\0'; 62 63 if (bootargs) { 64 strcpy(newbootargs, bootargs); 65 strcat(newbootargs, " "); 66 } 67 if (*hdr->cmdline) 68 strcat(newbootargs, hdr->cmdline); 69 70 setenv("bootargs", newbootargs); 71 72 if (os_data) { 73 *os_data = (ulong)hdr; 74 *os_data += hdr->page_size; 75 } 76 if (os_len) 77 *os_len = hdr->kernel_size; 78 return 0; 79 } 80 81 int android_image_check_header(const struct andr_img_hdr *hdr) 82 { 83 return memcmp(ANDR_BOOT_MAGIC, hdr->magic, ANDR_BOOT_MAGIC_SIZE); 84 } 85 86 ulong android_image_get_end(const struct andr_img_hdr *hdr) 87 { 88 ulong end; 89 /* 90 * The header takes a full page, the remaining components are aligned 91 * on page boundary 92 */ 93 end = (ulong)hdr; 94 end += hdr->page_size; 95 end += ALIGN(hdr->kernel_size, hdr->page_size); 96 end += ALIGN(hdr->ramdisk_size, hdr->page_size); 97 end += ALIGN(hdr->second_size, hdr->page_size); 98 99 return end; 100 } 101 102 ulong android_image_get_kload(const struct andr_img_hdr *hdr) 103 { 104 return hdr->kernel_addr; 105 } 106 107 int android_image_get_ramdisk(const struct andr_img_hdr *hdr, 108 ulong *rd_data, ulong *rd_len) 109 { 110 if (!hdr->ramdisk_size) 111 return -1; 112 113 printf("RAM disk load addr 0x%08x size %u KiB\n", 114 hdr->ramdisk_addr, DIV_ROUND_UP(hdr->ramdisk_size, 1024)); 115 116 *rd_data = (unsigned long)hdr; 117 *rd_data += hdr->page_size; 118 *rd_data += ALIGN(hdr->kernel_size, hdr->page_size); 119 120 *rd_len = hdr->ramdisk_size; 121 return 0; 122 } 123