-
Notifications
You must be signed in to change notification settings - Fork 0
/
bootimg.h
218 lines (173 loc) · 6.84 KB
/
bootimg.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* tools/mkbootimg/bootimg.h (modified for libbootimg)
**
** Copyright 2016, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <stdint.h>
#ifndef _BOOT_IMAGE_H_
#define _BOOT_IMAGE_H_
typedef unsigned char byte;
#define BOOT_MAGIC "ANDROID!"
#define BOOT_MAGIC_CHROMEOS "CHROMEOS"
#define BOOT_MAGIC_SIZE 8
#define BOOT_BOARD_SIZE 16
#define BOOT_ARGS_SIZE 512
#define BOOT_EXTRA_ARGS_SIZE 1024
#define BOOT_HASH_SIZE 20
#define BOOT_RESERVED_SIZE 12
#ifndef NO_MTK_SUPPORT
#define BOOT_MTK_HDR_MAGIC "\x88\x16\x88\x58"
#define BOOT_MTK_HDR_MAGIC_SIZE 4
#define BOOT_MTK_HDR_STRING_SIZE 32
#define BOOT_MTK_HDR_PADDING_SIZE 472
#endif
/* defaults when creating a new boot image */
#define BOOT_DEFAULT_PAGESIZE 2048
#define BOOT_DEFAULT_BASE 0x10000000U
#define BOOT_DEFAULT_KERNEL_OFFSET 0x00008000U
#define BOOT_DEFAULT_RAMDISK_OFFSET 0x01000000U
#define BOOT_DEFAULT_SECOND_OFFSET 0x00F00000U
#define BOOT_DEFAULT_TAGS_OFFSET 0x00000100U
/* the header of an Android boot image
* this is the beginning of all valid images */
typedef struct boot_img_hdr
{
byte magic[BOOT_MAGIC_SIZE];
uint32_t kernel_size; /* size in bytes */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_size; /* size in bytes including mtk header if applicable */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t second_size; /* size in bytes */
uint32_t second_addr; /* physical load addr */
uint32_t tags_addr; /* physical addr for kernel tags */
uint32_t pagesize; /* flash page size we assume */
uint32_t dt_size; /* device tree size in bytes */
/* operating system version and security patch level; for
* version "A.B.C" and patch level "Y-M-D":
* ver = A << 14 | B << 7 | C (7 bits for each of A, B, C)
* lvl = ((Y - 2000) & 127) << 4 | M (7 bits for Y, 4 bits for M)
* os_version = ver << 11 | lvl */
uint32_t os_version;
byte board[BOOT_BOARD_SIZE]; /* asciiz product name */
byte cmdline[BOOT_ARGS_SIZE]; /* kernel command line */
byte hash[BOOT_HASH_SIZE]; /* sha1 (kernel + ramdisk + second + dt) */
byte reserved[BOOT_RESERVED_SIZE]; /* modification timestamp? */
/* Supplemental command line data; kept here to maintain
* binary compatibility with older versions of mkbootimg */
byte extra_cmdline[BOOT_EXTRA_ARGS_SIZE];
} __attribute__((packed)) boot_img_hdr;
#ifndef NO_MTK_SUPPORT
/* a pointless header prepended to all the objects embedded
* within the Android boot image on some MediaTek devices, shame! */
typedef struct boot_mtk_hdr
{
byte magic[BOOT_MTK_HDR_MAGIC_SIZE];
uint32_t size; /* size of content after header in bytes */
byte string[BOOT_MTK_HDR_STRING_SIZE]; /* KERNEL/ROOTFS/RECOVERY */
byte padding[BOOT_MTK_HDR_PADDING_SIZE]; /* padding of FF */
} __attribute__((packed)) boot_mtk_hdr;
#endif
/* an item embedded in the Android boot image, ex. kernel/ramdisk/second/dt
* this is not an actual layout */
typedef struct boot_img_item
{
#ifndef NO_MTK_SUPPORT
boot_mtk_hdr *mtk_header;
#endif
byte *data;
size_t size;
uint32_t offset;
} boot_img_item;
/* a container struct for working with Android boot images
* this is not an actual layout */
typedef struct boot_img
{
boot_img_hdr hdr; /* the boot image header */
boot_img_item kernel; /* kernel image struct */
boot_img_item ramdisk; /* ramdisk image struct */
boot_img_item second; /* second image struct */
boot_img_item dt; /* dt image struct */
uint32_t base; /* base location offsets are relative to */
uint32_t tags_offset; /* offset of kernel tags */
unsigned chromeos:1;
} boot_img;
/*
** +-----------------+
** | boot header | 1 page
** +-----------------+
** | [ mtk header ] |
** | kernel | n pages
** +-----------------+
** | [ mtk header ] |
** | ramdisk | m pages
** +-----------------+
** | [ mtk header ] |
** | second stage | o pages
** +-----------------+
** | [ mtk header ] |
** | device tree | p pages
** +-----------------+
**
** n = (kernel_size + pagesize - 1) / pagesize
** m = (ramdisk_size + pagesize - 1) / pagesize
** o = (second_size + pagesize - 1) / pagesize
** p = (dt_size + pagesize - 1) / pagesize
**
** 0. all entities are pagesize aligned in flash
** 1. kernel and ramdisk are required (size != 0)
** 2. second is optional (second_size == 0 -> no second)
** 3. load each element (kernel, ramdisk, second) at
** the specified physical address (kernel_addr, etc)
** 4. prepare tags at tag_addr. kernel_args[] is
** appended to the kernel commandline in the tags.
** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
** 6. if second_size != 0: jump to second_addr
** else: jump to kernel_addr
** 7. mtk headers are only used in some mediatek devices.
** they can be prepended to any item in the boot image
** and are also added to the size of each item
** (+512 bytes) before the page alignment is calculated.
*/
/* boot image items (const byte item) */
enum {
BOOTIMG_KERNEL = 1,
BOOTIMG_RAMDISK,
BOOTIMG_SECOND,
BOOTIMG_DT
};
byte *bootimg_generate_hash(const boot_img *image);
int bootimg_update_hash(boot_img *image);
int bootimg_load(boot_img *image, const byte item, const char *file);
int bootimg_save(boot_img *image, const byte item, const char *file);
int bootimg_set_board(boot_img *image, const char *board);
int bootimg_set_os_version(boot_img *image, const char *os_version);
int bootimg_set_patch_level(boot_img *image, const char *patch_level);
/* returns a malloc char * (string) that should be freed */
char *bootimg_get_os_version(const boot_img *image);
char *bootimg_get_patch_level(const boot_img *image);
int bootimg_set_cmdline(boot_img *image, const char *cmdline);
/* a null val will delete the arg from the cmdline */
int bootimg_set_cmdline_arg(boot_img *image, const char *arg, const char *val);
#ifndef NO_MTK_SUPPORT
int bootimg_set_mtk_header(boot_img *image, const byte item, const char *string);
#endif
int bootimg_set_pagesize(boot_img *image, const int pagesize);
void bootimg_set_base(boot_img *image, const uint32_t base);
void bootimg_set_offset(boot_img *image, const byte item, const uint32_t offset);
void bootimg_set_tags_offset(boot_img *image, const uint32_t offset);
boot_img *new_boot_image(void);
boot_img *load_boot_image(const char *file);
int write_boot_image(boot_img *image, const char *file);
void free_boot_image(boot_img *image);
#endif