]>
Commit | Line | Data |
---|---|---|
9ace3fc8 SS |
1 | /* |
2 | * Copyright (c) 2011 Sebastian Andrzej Siewior <[email protected]> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
6 | ||
7 | #include <common.h> | |
8 | #include <image.h> | |
9 | #include <android_image.h> | |
86f4695b AD |
10 | #include <malloc.h> |
11 | #include <errno.h> | |
9ace3fc8 SS |
12 | |
13 | static char andr_tmp_str[ANDR_BOOT_ARGS_SIZE + 1]; | |
14 | ||
86f4695b AD |
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 | */ | |
9ace3fc8 SS |
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)); | |
86f4695b AD |
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, " "); | |
9ace3fc8 | 66 | } |
86f4695b AD |
67 | if (*hdr->cmdline) |
68 | strcat(newbootargs, hdr->cmdline); | |
69 | ||
70 | setenv("bootargs", newbootargs); | |
9ace3fc8 SS |
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 | { | |
86f4695b | 88 | ulong end; |
9ace3fc8 SS |
89 | /* |
90 | * The header takes a full page, the remaining components are aligned | |
91 | * on page boundary | |
92 | */ | |
86f4695b AD |
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); | |
9ace3fc8 | 98 | |
86f4695b | 99 | return end; |
9ace3fc8 SS |
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; | |
86f4695b AD |
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 | ||
9ace3fc8 SS |
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 | } |