blob: 9c0ba40675791f549ed5b70473f1036d98bc8265 [file] [log] [blame]
Brian Swetland9c4c0752009-01-25 16:23:50 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Kuogee Hsiehfb4b5c32013-12-20 08:34:10 -08005 * Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
Brian Swetland9c4c0752009-01-25 16:23:50 -08006 *
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070014 * * Neither the name of The Linux Foundation nor
Chandan Uddaraju5fa471a2009-12-02 17:31:34 -080015 * the names of its contributors may be used to endorse or promote
16 * products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
Brian Swetland9c4c0752009-01-25 16:23:50 -080031 */
32
33#include <app.h>
34#include <debug.h>
35#include <arch/arm.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080036#include <string.h>
Channagoud Kadabi132ff552013-04-19 14:34:44 -070037#include <stdlib.h>
Channagoud Kadabice737c82014-06-18 17:41:01 -070038#include <limits.h>
Brian Swetland9c4c0752009-01-25 16:23:50 -080039#include <kernel/thread.h>
40#include <arch/ops.h>
41
Dima Zavin214cc642009-01-26 11:16:21 -080042#include <dev/flash.h>
43#include <lib/ptable.h>
Dima Zavinb4283602009-01-26 16:36:57 -080044#include <dev/keys.h>
Shashank Mittal4f99a882010-02-01 13:58:50 -080045#include <dev/fbcon.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080046#include <baseband.h>
Greg Griscod6250552011-06-29 14:40:23 -070047#include <target.h>
48#include <mmc.h>
Kinson Chikf1a43512011-07-14 11:28:39 -070049#include <partition_parser.h>
Greg Griscod6250552011-06-29 14:40:23 -070050#include <platform.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070051#include <crypto_hash.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070052#include <malloc.h>
Amol Jadi492d5a52013-03-15 16:12:34 -070053#include <boot_stats.h>
Amir Samuelov57a6fa22013-06-05 16:36:43 +030054#include <sha.h>
Dima Zavin214cc642009-01-26 11:16:21 -080055
Neeti Desai17379b82012-06-04 18:42:53 -070056#if DEVICE_TREE
57#include <libfdt.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070058#include <dev_tree.h>
Neeti Desai17379b82012-06-04 18:42:53 -070059#endif
60
Shashank Mittalcd98d472011-08-02 14:29:24 -070061#include "image_verify.h"
Shashank Mittal024c0332010-02-03 11:44:00 -080062#include "recovery.h"
Brian Swetland9c4c0752009-01-25 16:23:50 -080063#include "bootimg.h"
64#include "fastboot.h"
Ajay Dudani5c761132011-04-07 20:19:04 -070065#include "sparse_format.h"
Greg Grisco6e754772011-06-23 12:19:39 -070066#include "mmc.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070067#include "devinfo.h"
Neeti Desai465491e2012-07-31 12:53:35 -070068#include "board.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070069#include "scm.h"
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -070070
Sridhar Parasuram78344412015-08-29 11:13:07 -070071#if VERIFIED_BOOT
72#include "boot_verifier.h"
73#include "secapp_loader.h"
74#endif
75
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070076extern bool target_use_signed_kernel(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070077extern void platform_uninit(void);
Channagoud Kadabi33defe22013-06-18 18:35:40 -070078extern void target_uninit(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070079
80void write_device_info_mmc(device_info *dev);
81void write_device_info_flash(device_info *dev);
82
Sridhar Parasuram901bb702014-10-24 14:06:03 -070083/* fastboot command function pointer */
84typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
85
86struct fastboot_cmd_desc {
87 char * name;
88 fastboot_cmd_fn cb;
89};
90
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -070091#define EXPAND(NAME) #NAME
92#define TARGET(NAME) EXPAND(NAME)
Brian Swetland2defe162009-08-18 14:35:59 -070093
Ajay Dudanicd01f9b2010-02-23 21:13:04 -080094#ifdef MEMBASE
95#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE))
96#else
David Ng183a7422009-12-07 14:55:21 -080097#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
Ajay Dudanicd01f9b2010-02-23 21:13:04 -080098#endif
99
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700100#ifndef MEMSIZE
101#define MEMSIZE 1024*1024
102#endif
103
104#define MAX_TAGS_SIZE 1024
105
Chandan Uddarajude85d3f2010-01-05 16:32:33 -0800106#define RECOVERY_MODE 0x77665502
107#define FASTBOOT_MODE 0x77665500
108
Sridhar Parasuram78344412015-08-29 11:13:07 -0700109#if VERIFIED_BOOT
110#define DM_VERITY_LOGGING 0x77665508
111#define DM_VERITY_ENFORCING 0x77665509
112#define DM_VERITY_KEYSCLEAR 0x7766550A
113#endif
114
Kun Liang2f1601a2013-08-12 16:29:54 +0800115/* make 4096 as default size to ensure EFS,EXT4's erasing */
116#define DEFAULT_ERASE_SIZE 4096
Kuogee Hsiehfb4b5c32013-12-20 08:34:10 -0800117#define MAX_PANEL_BUF_SIZE 128
Kun Liang2f1601a2013-08-12 16:29:54 +0800118
Channagoud Kadabice737c82014-06-18 17:41:01 -0700119#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
120
David Ng183a7422009-12-07 14:55:21 -0800121static const char *emmc_cmdline = " androidboot.emmc=true";
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800122static const char *usb_sn_cmdline = " androidboot.serialno=";
Pavel Nedev328ac822013-04-05 15:25:11 +0300123static const char *androidboot_mode = " androidboot.mode=";
Dhaval Patel223ec952013-07-18 14:49:44 -0700124static const char *display_cmdline = " mdss_mdp.panel=";
Pavel Nedev898298c2013-02-27 12:36:09 -0800125static const char *loglevel = " quiet";
Ajay Dudanica3a33c2011-11-18 08:31:40 -0800126static const char *battchg_pause = " androidboot.mode=charger";
Shashank Mittalcd98d472011-08-02 14:29:24 -0700127static const char *auth_kernel = " androidboot.authorized_kernel=true";
Pavel Nedev5614d222013-06-17 18:01:02 +0300128static const char *secondary_gpt_enable = " gpt";
David Ng183a7422009-12-07 14:55:21 -0800129
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800130static const char *baseband_apq = " androidboot.baseband=apq";
131static const char *baseband_msm = " androidboot.baseband=msm";
132static const char *baseband_csfb = " androidboot.baseband=csfb";
133static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
Ajay Dudani403bc492011-09-30 16:17:21 -0700134static const char *baseband_mdm = " androidboot.baseband=mdm";
Amol Jadi5c61a952012-05-04 17:05:35 -0700135static const char *baseband_sglte = " androidboot.baseband=sglte";
Amol Jadi2a15a272013-01-22 12:03:36 -0800136static const char *baseband_dsda = " androidboot.baseband=dsda";
137static const char *baseband_dsda2 = " androidboot.baseband=dsda2";
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800138static const char *baseband_sglte2 = " androidboot.baseband=sglte2";
Ajay Dudanid04110c2011-01-17 23:55:07 -0800139
Sridhar Parasuram78344412015-08-29 11:13:07 -0700140#if VERIFIED_BOOT
141static const char *verity_mode = " androidboot.veritymode=";
142static const char *verified_state= " androidboot.verifiedbootstate=";
143
144//indexed based on enum values, green is 0 by default
145
146struct verified_boot_verity_mode vbvm[] =
147{
148 {false, "logging"},
149 {true, "enforcing"},
150};
151struct verified_boot_state_name vbsn[] =
152{
153 {GREEN, "green"},
154 {ORANGE, "orange"},
155 {YELLOW,"yellow"},
156 {RED,"red" },
157};
158#endif
159
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700160static unsigned page_size = 0;
161static unsigned page_mask = 0;
162static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
163static bool boot_into_ffbm;
164
Shashank Mittalcd98d472011-08-02 14:29:24 -0700165/* Assuming unauthorized kernel image by default */
166static int auth_kernel_img = 0;
167
Sridhar Parasuram78344412015-08-29 11:13:07 -0700168#if VERIFIED_BOOT
169static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, 1};
170#else
Unnati Gandhi15d08f92014-01-24 11:01:01 +0530171static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0};
Sridhar Parasuram78344412015-08-29 11:13:07 -0700172#endif
Shashank Mittal162244e2011-08-08 19:01:25 -0700173
Dima Zavin42168f22009-01-30 11:52:22 -0800174struct atag_ptbl_entry
175{
176 char name[16];
177 unsigned offset;
178 unsigned size;
179 unsigned flags;
180};
181
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700182/*
183 * Partition info, required to be published
184 * for fastboot
185 */
186struct getvar_partition_info {
Mayank Grover429012c2017-10-27 13:07:59 +0530187 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700188 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
189 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
190 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
191 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
192};
193
194/*
Mayank Grover429012c2017-10-27 13:07:59 +0530195 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700196 */
Mayank Grover429012c2017-10-27 13:07:59 +0530197struct getvar_partition_info part_info[NUM_PARTITIONS];
198struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700199{
200 { "system" , "partition-size:", "partition-type:", "", "ext4" },
201 { "userdata", "partition-size:", "partition-type:", "", "ext4" },
202 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
203};
204
205char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700206char charger_screen_enabled[MAX_RSP_SIZE];
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800207char sn_buf[13];
Dhaval Patel223ec952013-07-18 14:49:44 -0700208char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi15d08f92014-01-24 11:01:01 +0530209char panel_display_mode[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700210
Greg Griscod2471ef2011-07-14 13:00:42 -0700211extern int emmc_recovery_init(void);
212
Kinson Chik0b1c8162011-08-31 16:31:57 -0700213#if NO_KEYPAD_DRIVER
214extern int fastboot_trigger(void);
215#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700216
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700217static void update_ker_tags_rdisk_addr(struct boot_img_hdr *hdr)
218{
219 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700220#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
221 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
222 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
223 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700224#endif
225}
226
Dima Zavin42168f22009-01-30 11:52:22 -0800227static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
228{
229 struct atag_ptbl_entry atag_ptn;
230
231 memcpy(atag_ptn.name, ptn->name, 16);
232 atag_ptn.name[15] = '\0';
233 atag_ptn.offset = ptn->start;
234 atag_ptn.size = ptn->length;
235 atag_ptn.flags = ptn->flags;
236 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
237 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
238}
Brian Swetland9c4c0752009-01-25 16:23:50 -0800239
Neeti Desaie245d492012-06-01 12:52:13 -0700240unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800241{
David Ng183a7422009-12-07 14:55:21 -0800242 int cmdline_len = 0;
243 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800244 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700245 int pause_at_bootup = 0;
Pavel Nedev5614d222013-06-17 18:01:02 +0300246 bool gpt_exists = partition_gpt_exists();
Sridhar Parasuram78344412015-08-29 11:13:07 -0700247#if VERIFIED_BOOT
248 uint32_t boot_state = boot_verify_get_state();
249#endif
250
Dima Zavin42168f22009-01-30 11:52:22 -0800251
Brian Swetland9c4c0752009-01-25 16:23:50 -0800252 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800253 cmdline_len = strlen(cmdline);
254 have_cmdline = 1;
255 }
256 if (target_is_emmc_boot()) {
257 cmdline_len += strlen(emmc_cmdline);
258 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800259
260 cmdline_len += strlen(usb_sn_cmdline);
261 cmdline_len += strlen(sn_buf);
262
Sridhar Parasuram78344412015-08-29 11:13:07 -0700263#if VERIFIED_BOOT
264 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
265 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
266#endif
267
268
Pavel Nedev5614d222013-06-17 18:01:02 +0300269 if (boot_into_recovery && gpt_exists)
270 cmdline_len += strlen(secondary_gpt_enable);
271
Pavel Nedev328ac822013-04-05 15:25:11 +0300272 if (boot_into_ffbm) {
273 cmdline_len += strlen(androidboot_mode);
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700274 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800275 /* reduce kernel console messages to speed-up boot */
276 cmdline_len += strlen(loglevel);
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700277 } else if (device.charger_screen_enabled &&
278 target_pause_for_battery_charge()) {
David Ngf773dde2010-07-26 19:55:08 -0700279 pause_at_bootup = 1;
280 cmdline_len += strlen(battchg_pause);
281 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800282
Shashank Mittalcd98d472011-08-02 14:29:24 -0700283 if(target_use_signed_kernel() && auth_kernel_img) {
284 cmdline_len += strlen(auth_kernel);
285 }
286
Ajay Dudanid04110c2011-01-17 23:55:07 -0800287 /* Determine correct androidboot.baseband to use */
288 switch(target_baseband())
289 {
290 case BASEBAND_APQ:
291 cmdline_len += strlen(baseband_apq);
292 break;
293
294 case BASEBAND_MSM:
295 cmdline_len += strlen(baseband_msm);
296 break;
297
298 case BASEBAND_CSFB:
299 cmdline_len += strlen(baseband_csfb);
300 break;
301
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800302 case BASEBAND_SVLTE2A:
303 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800304 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700305
306 case BASEBAND_MDM:
307 cmdline_len += strlen(baseband_mdm);
308 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700309
310 case BASEBAND_SGLTE:
311 cmdline_len += strlen(baseband_sglte);
312 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530313
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800314 case BASEBAND_SGLTE2:
315 cmdline_len += strlen(baseband_sglte2);
316 break;
317
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530318 case BASEBAND_DSDA:
319 cmdline_len += strlen(baseband_dsda);
320 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800321
322 case BASEBAND_DSDA2:
323 cmdline_len += strlen(baseband_dsda2);
324 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800325 }
326
Dhaval Patel223ec952013-07-18 14:49:44 -0700327 if (target_display_panel_node(display_panel_buf, MAX_PANEL_BUF_SIZE) &&
328 strlen(display_panel_buf))
329 {
330 cmdline_len += strlen(display_cmdline);
331 cmdline_len += strlen(display_panel_buf);
332 }
333
David Ng183a7422009-12-07 14:55:21 -0800334 if (cmdline_len > 0) {
335 const char *src;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700336 unsigned char *dst = (unsigned char*) malloc((cmdline_len + 4) & (~3));
337 ASSERT(dst != NULL);
Neeti Desaie245d492012-06-01 12:52:13 -0700338
Amol Jadi168b7712012-03-06 16:15:00 -0800339 /* Save start ptr for debug print */
Neeti Desaie245d492012-06-01 12:52:13 -0700340 cmdline_final = dst;
David Ng183a7422009-12-07 14:55:21 -0800341 if (have_cmdline) {
342 src = cmdline;
343 while ((*dst++ = *src++));
344 }
345 if (target_is_emmc_boot()) {
346 src = emmc_cmdline;
347 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700348 have_cmdline = 1;
349 while ((*dst++ = *src++));
350 }
Sridhar Parasuram78344412015-08-29 11:13:07 -0700351#if VERIFIED_BOOT
352 src = verified_state;
353 if(have_cmdline) --dst;
354 have_cmdline = 1;
355 while ((*dst++ = *src++));
356 src = vbsn[boot_state].name;
357 if(have_cmdline) --dst;
358 while ((*dst++ = *src++));
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800359
Sridhar Parasuram78344412015-08-29 11:13:07 -0700360 src = verity_mode;
361 if(have_cmdline) --dst;
362 while ((*dst++ = *src++));
363 src = vbvm[device.verity_mode].name;
364 if(have_cmdline) -- dst;
365 while ((*dst++ = *src++));
366#endif
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800367 src = usb_sn_cmdline;
368 if (have_cmdline) --dst;
369 have_cmdline = 1;
370 while ((*dst++ = *src++));
371 src = sn_buf;
372 if (have_cmdline) --dst;
373 have_cmdline = 1;
374 while ((*dst++ = *src++));
375
Pavel Nedev5614d222013-06-17 18:01:02 +0300376 if (boot_into_recovery && gpt_exists) {
377 src = secondary_gpt_enable;
378 if (have_cmdline) --dst;
379 while ((*dst++ = *src++));
380 }
381
Pavel Nedev328ac822013-04-05 15:25:11 +0300382 if (boot_into_ffbm) {
383 src = androidboot_mode;
384 if (have_cmdline) --dst;
385 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700386 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +0300387 if (have_cmdline) --dst;
388 while ((*dst++ = *src++));
Pavel Nedev898298c2013-02-27 12:36:09 -0800389 src = loglevel;
390 if (have_cmdline) --dst;
391 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +0300392 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -0700393 src = battchg_pause;
394 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -0800395 while ((*dst++ = *src++));
396 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800397
Shashank Mittalcd98d472011-08-02 14:29:24 -0700398 if(target_use_signed_kernel() && auth_kernel_img) {
399 src = auth_kernel;
400 if (have_cmdline) --dst;
401 while ((*dst++ = *src++));
402 }
403
Ajay Dudanid04110c2011-01-17 23:55:07 -0800404 switch(target_baseband())
405 {
406 case BASEBAND_APQ:
407 src = baseband_apq;
408 if (have_cmdline) --dst;
409 while ((*dst++ = *src++));
410 break;
411
412 case BASEBAND_MSM:
413 src = baseband_msm;
414 if (have_cmdline) --dst;
415 while ((*dst++ = *src++));
416 break;
417
418 case BASEBAND_CSFB:
419 src = baseband_csfb;
420 if (have_cmdline) --dst;
421 while ((*dst++ = *src++));
422 break;
423
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800424 case BASEBAND_SVLTE2A:
425 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800426 if (have_cmdline) --dst;
427 while ((*dst++ = *src++));
428 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700429
430 case BASEBAND_MDM:
431 src = baseband_mdm;
432 if (have_cmdline) --dst;
433 while ((*dst++ = *src++));
434 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700435
436 case BASEBAND_SGLTE:
437 src = baseband_sglte;
438 if (have_cmdline) --dst;
439 while ((*dst++ = *src++));
440 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530441
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800442 case BASEBAND_SGLTE2:
443 src = baseband_sglte2;
444 if (have_cmdline) --dst;
445 while ((*dst++ = *src++));
446 break;
447
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530448 case BASEBAND_DSDA:
449 src = baseband_dsda;
450 if (have_cmdline) --dst;
451 while ((*dst++ = *src++));
452 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800453
454 case BASEBAND_DSDA2:
455 src = baseband_dsda2;
456 if (have_cmdline) --dst;
457 while ((*dst++ = *src++));
458 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800459 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700460
461 if (strlen(display_panel_buf)) {
462 src = display_cmdline;
463 if (have_cmdline) --dst;
464 while ((*dst++ = *src++));
465 src = display_panel_buf;
466 if (have_cmdline) --dst;
467 while ((*dst++ = *src++));
468 }
Neeti Desaie245d492012-06-01 12:52:13 -0700469 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700470
471
Deepa Dinamani8b8736d2012-12-19 15:00:56 -0800472 dprintf(INFO, "cmdline: %s\n", cmdline_final);
Neeti Desaie245d492012-06-01 12:52:13 -0700473 return cmdline_final;
474}
475
476unsigned *atag_core(unsigned *ptr)
477{
478 /* CORE */
479 *ptr++ = 2;
480 *ptr++ = 0x54410001;
481
482 return ptr;
483
484}
485
486unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
487 unsigned ramdisk_size)
488{
489 if (ramdisk_size) {
490 *ptr++ = 4;
491 *ptr++ = 0x54420005;
492 *ptr++ = (unsigned)ramdisk;
493 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -0800494 }
495
Neeti Desaie245d492012-06-01 12:52:13 -0700496 return ptr;
497}
498
499unsigned *atag_ptable(unsigned **ptr_addr)
500{
501 int i;
502 struct ptable *ptable;
503
504 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700505 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
506 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -0700507 *(*ptr_addr)++ = 0x4d534d70;
508 for (i = 0; i < ptable->count; ++i)
509 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
510 }
511
512 return (*ptr_addr);
513}
514
515unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
516{
517 int cmdline_length = 0;
518 int n;
Neeti Desaie245d492012-06-01 12:52:13 -0700519 char *dest;
520
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800521 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -0700522 n = (cmdline_length + 4) & (~3);
523
524 *ptr++ = (n / 4) + 2;
525 *ptr++ = 0x54410009;
526 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800527 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -0700528 ptr += (n / 4);
529
530 return ptr;
531}
532
533unsigned *atag_end(unsigned *ptr)
534{
Brian Swetland9c4c0752009-01-25 16:23:50 -0800535 /* END */
536 *ptr++ = 0;
537 *ptr++ = 0;
538
Neeti Desaie245d492012-06-01 12:52:13 -0700539 return ptr;
540}
541
542void generate_atags(unsigned *ptr, const char *cmdline,
543 void *ramdisk, unsigned ramdisk_size)
544{
545
546 ptr = atag_core(ptr);
547 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
548 ptr = target_atag_mem(ptr);
549
550 /* Skip NAND partition ATAGS for eMMC boot */
551 if (!target_is_emmc_boot()){
552 ptr = atag_ptable(&ptr);
553 }
554
555 ptr = atag_cmdline(ptr, cmdline);
556 ptr = atag_end(ptr);
557}
558
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700559typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -0700560void boot_linux(void *kernel, unsigned *tags,
561 const char *cmdline, unsigned machtype,
562 void *ramdisk, unsigned ramdisk_size)
563{
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800564 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -0800565#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -0700566 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -0800567#endif
568
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700569 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -0800570 uint32_t tags_phys = PA((addr_t)tags);
571
572 ramdisk = PA(ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -0700573
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800574 final_cmdline = update_cmdline((const char*)cmdline);
575
Neeti Desai17379b82012-06-04 18:42:53 -0700576#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -0800577 dprintf(INFO, "Updating device tree: start\n");
578
Neeti Desai17379b82012-06-04 18:42:53 -0700579 /* Update the Device Tree */
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800580 ret = update_device_tree((void *)tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -0700581 if(ret)
582 {
583 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
584 ASSERT(0);
585 }
Amol Jadib6be5c12012-11-14 13:39:51 -0800586 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -0700587#else
Neeti Desaie245d492012-06-01 12:52:13 -0700588 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -0800589 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -0700590#endif
Neeti Desaie245d492012-06-01 12:52:13 -0700591
Channagoud Kadabi33defe22013-06-18 18:35:40 -0700592 /* Perform target specific cleanup */
593 target_uninit();
594
Aravind Venkateswarandb0d5262014-02-25 16:25:30 -0800595 /* Turn off splash screen if enabled */
596#if DISPLAY_SPLASH_SCREEN
597 target_display_shutdown();
598#endif
599
600
Deepa Dinamani33734bc2013-03-06 12:16:06 -0800601 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
602 entry, ramdisk, ramdisk_size, tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -0800603
604 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700605
Amol Jadi4421e652011-06-16 15:00:48 -0700606 /* do any platform specific cleanup before kernel entry */
607 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700608
Brian Swetland9c4c0752009-01-25 16:23:50 -0800609 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700610
Amol Jadi504f9fe2012-08-16 13:56:48 -0700611#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -0800612 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -0700613#endif
Amol Jadi492d5a52013-03-15 16:12:34 -0700614 bs_set_timestamp(BS_KERNEL_ENTRY);
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700615 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -0800616}
617
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700618/* Function to check if the memory address range falls within the aboot
619 * boundaries.
620 * start: Start of the memory region
621 * size: Size of the memory region
622 */
623int check_aboot_addr_range_overlap(uint32_t start, uint32_t size)
624{
625 /* Check for boundary conditions. */
Sundarajan Srinivasan74252482013-12-16 17:02:56 -0800626 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700627 return -1;
628
629 /* Check for memory overlap. */
630 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
631 return 0;
Channagoud Kadabib4413fd2013-10-15 12:53:52 -0700632 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700633 return 0;
634 else
635 return -1;
636}
637
Shashank Mittaldcc2e352009-11-19 19:11:16 -0800638#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
Brian Swetland9c4c0752009-01-25 16:23:50 -0800639
Channagoud Kadabi132ff552013-04-19 14:34:44 -0700640BUF_DMA_ALIGN(buf, 4096); //Equal to max-supported pagesize
Amol Jadib6be5c12012-11-14 13:39:51 -0800641#if DEVICE_TREE
Channagoud Kadabi132ff552013-04-19 14:34:44 -0700642BUF_DMA_ALIGN(dt_buf, 4096);
Amol Jadib6be5c12012-11-14 13:39:51 -0800643#endif
Dima Zavin214cc642009-01-26 11:16:21 -0800644
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700645static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
646{
647 int ret;
Sridhar Parasuram78344412015-08-29 11:13:07 -0700648#if !VERIFIED_BOOT
649#if IMAGE_VERIF_ALGO_SHA1
650 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
651#else
652 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
653#endif
654#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700655
656 /* Assume device is rooted at this time. */
657 device.is_tampered = 1;
658
659 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
Sridhar Parasuram78344412015-08-29 11:13:07 -0700660#if VERIFIED_BOOT
661 if(boot_into_recovery)
662 {
663 ret = boot_verify_image((unsigned char *)bootimg_addr,
664 bootimg_size, "/recovery");
665 }
666 else
667 {
668 ret = boot_verify_image((unsigned char *)bootimg_addr,
669 bootimg_size, "/boot");
670 }
671 boot_verify_print_state();
672#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700673 ret = image_verify((unsigned char *)bootimg_addr,
674 (unsigned char *)(bootimg_addr + bootimg_size),
675 bootimg_size,
676 CRYPTO_AUTH_ALG_SHA256);
Sridhar Parasuram78344412015-08-29 11:13:07 -0700677#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700678 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
679
680 if (ret)
681 {
682 /* Authorized kernel */
683 device.is_tampered = 0;
684 }
685
686#if USE_PCOM_SECBOOT
687 set_tamper_flag(device.is_tampered);
688#endif
Sridhar Parasuram78344412015-08-29 11:13:07 -0700689#if VERIFIED_BOOT
690 switch(boot_verify_get_state())
691 {
692 case RED:
693 dprintf(CRITICAL,
694 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
695 mdelay(5000);
696 break;
697 case YELLOW:
698 dprintf(CRITICAL,
699 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
700 mdelay(5000);
701 break;
702 default:
703 break;
704 }
705#endif
706#if !VERIFIED_BOOT
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700707 if(device.is_tampered)
708 {
709 write_device_info_mmc(&device);
710 #ifdef TZ_TAMPER_FUSE
711 set_tamper_fuse_cmd();
712 #endif
713 #ifdef ASSERT_ON_TAMPER
714 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
715 ASSERT(0);
716 #endif
717 }
Sridhar Parasuram78344412015-08-29 11:13:07 -0700718#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700719}
720
Maunik Shah78a85e52014-03-02 17:47:58 +0530721static bool check_format_bit()
722{
723 bool ret = false;
724 int index;
725 uint64_t offset;
726 struct boot_selection_info *in = NULL;
727 char *buf = NULL;
728
729 index = partition_get_index("bootselect");
730 if (index == INVALID_PTN)
731 {
732 dprintf(INFO, "Unable to locate /bootselect partition\n");
733 return ret;
734 }
735 offset = partition_get_offset(index);
736 if(!offset)
737 {
738 dprintf(INFO, "partition /bootselect doesn't exist\n");
739 return ret;
740 }
741 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
742 ASSERT(buf);
743 if (mmc_read(offset, (unsigned int *)buf, page_size))
744 {
745 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
746 free(buf);
747 return ret;
748 }
749 in = (struct boot_selection_info *) buf;
750 if ((in->signature == BOOTSELECT_SIGNATURE) &&
751 (in->version == BOOTSELECT_VERSION)) {
752 if ((in->state_info & BOOTSELECT_FORMAT) &&
753 !(in->state_info & BOOTSELECT_FACTORY))
754 ret = true;
755 } else {
756 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
757 in->signature, in->version);
758 ASSERT(0);
759 }
760 free(buf);
761 return ret;
762}
Sridhar Parasuram78344412015-08-29 11:13:07 -0700763#if VERIFIED_BOOT
764void boot_verifier_init()
765{
766 uint32_t boot_state;
767 /* Check if device unlock */
768 if(device.is_unlocked)
769 {
770 boot_verify_send_event(DEV_UNLOCK);
771 boot_verify_print_state();
772 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
773 return;
774 }
775 else
776 {
777 boot_verify_send_event(BOOT_INIT);
778 }
779
780 /* Initialize keystore */
781 boot_state = boot_verify_keystore_init();
782}
783#endif
Maunik Shah78a85e52014-03-02 17:47:58 +0530784
Shashank Mittal23b8f422010-04-16 19:27:21 -0700785int boot_linux_from_mmc(void)
786{
787 struct boot_img_hdr *hdr = (void*) buf;
788 struct boot_img_hdr *uhdr;
789 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700790 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700791 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -0700792 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700793
Shashank Mittalcd98d472011-08-02 14:29:24 -0700794 unsigned char *image_addr = 0;
795 unsigned kernel_actual;
796 unsigned ramdisk_actual;
797 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -0700798 unsigned second_actual = 0;
Neeti Desai465491e2012-07-31 12:53:35 -0700799
800#if DEVICE_TREE
801 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -0700802 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -0700803 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -0800804 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -0700805 uint32_t dt_hdr_size;
Neeti Desai465491e2012-07-31 12:53:35 -0700806#endif
Maunik Shah78a85e52014-03-02 17:47:58 +0530807 if (check_format_bit())
808 boot_into_recovery = 1;
809
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700810 if (!boot_into_recovery) {
811 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
812 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
813 if (rcode <= 0) {
814 boot_into_ffbm = false;
815 if (rcode < 0)
816 dprintf(CRITICAL,"failed to get ffbm cookie");
817 } else
818 boot_into_ffbm = true;
819 } else
820 boot_into_ffbm = false;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700821 uhdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
822 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
823 dprintf(INFO, "Unified boot method!\n");
824 hdr = uhdr;
825 goto unified_boot;
826 }
Greg Griscod6250552011-06-29 14:40:23 -0700827 if (!boot_into_recovery) {
Kinson Chikf1a43512011-07-14 11:28:39 -0700828 index = partition_get_index("boot");
829 ptn = partition_get_offset(index);
830 if(ptn == 0) {
Shashank Mittal85b91f62010-10-30 10:12:38 -0700831 dprintf(CRITICAL, "ERROR: No boot partition found\n");
832 return -1;
833 }
Kinson Chikf1a43512011-07-14 11:28:39 -0700834 }
835 else {
836 index = partition_get_index("recovery");
837 ptn = partition_get_offset(index);
838 if(ptn == 0) {
Shashank Mittal85b91f62010-10-30 10:12:38 -0700839 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
840 return -1;
841 }
Shashank Mittal23b8f422010-04-16 19:27:21 -0700842 }
843
Greg Griscod6250552011-06-29 14:40:23 -0700844 if (mmc_read(ptn + offset, (unsigned int *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -0700845 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
846 return -1;
847 }
Shashank Mittal23b8f422010-04-16 19:27:21 -0700848
849 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -0700850 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Shashank Mittal23b8f422010-04-16 19:27:21 -0700851 return -1;
852 }
853
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -0700854 if (hdr->page_size && (hdr->page_size != page_size)) {
855 page_size = hdr->page_size;
856 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -0700857 }
858
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700859 /*
860 * Update the kernel/ramdisk/tags address if the boot image header
861 * has default values, these default values come from mkbootimg when
862 * the boot image is flashed using fastboot flash:raw
863 */
864 update_ker_tags_rdisk_addr(hdr);
865
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700866 /* Get virtual addresses since the hdr saves physical addresses. */
867 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
868 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
869 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700870
871 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
872 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
873
874 /* Check if the addresses in the header are valid. */
875 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
876 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
877 {
878 dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
879 return -1;
880 }
881
882#ifndef DEVICE_TREE
883 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
884 {
885 dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
886 return -1;
887 }
888#endif
889
Sridhar Parasuram78344412015-08-29 11:13:07 -0700890#if VERIFIED_BOOT
891 boot_verifier_init();
892#endif
893
894
Shashank Mittalcd98d472011-08-02 14:29:24 -0700895 /* Authenticate Kernel */
Amir Samuelov57a6fa22013-06-05 16:36:43 +0300896 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
897 (int) target_use_signed_kernel(),
898 device.is_unlocked,
899 device.is_tampered);
900
Deepa Dinamani23b60d42013-06-24 18:10:52 -0700901 if(target_use_signed_kernel() && (!device.is_unlocked))
Subbaraman Narayanamurthy958fa242011-01-27 17:42:38 -0800902 {
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700903 offset = 0;
904
Shashank Mittalcd98d472011-08-02 14:29:24 -0700905 image_addr = (unsigned char *)target_get_scratch_address();
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700906
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -0800907#if DEVICE_TREE
908 dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
909 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700910
Deepa Dinamanid14bb4d2013-07-12 17:28:29 -0700911 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700912 {
913 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
914 return -1;
915 }
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -0800916#else
Channagoud Kadabi4b276512012-08-28 15:16:30 +0530917 imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
Shashank Mittal162244e2011-08-08 19:01:25 -0700918
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700919#endif
Shashank Mittal162244e2011-08-08 19:01:25 -0700920
Amol Jadib6be5c12012-11-14 13:39:51 -0800921 dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -0700922 bs_set_timestamp(BS_KERNEL_LOAD_START);
Amol Jadib6be5c12012-11-14 13:39:51 -0800923
Deepa Dinamanid14bb4d2013-07-12 17:28:29 -0700924 if (check_aboot_addr_range_overlap(image_addr, imagesize_actual))
925 {
926 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
927 return -1;
928 }
929
Shashank Mittalcd98d472011-08-02 14:29:24 -0700930 /* Read image without signature */
931 if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
932 {
933 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
934 return -1;
Subbaraman Narayanamurthy958fa242011-01-27 17:42:38 -0800935 }
Shashank Mittalcd98d472011-08-02 14:29:24 -0700936
Amol Jadib6be5c12012-11-14 13:39:51 -0800937 dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -0700938 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
Amol Jadib6be5c12012-11-14 13:39:51 -0800939
Shashank Mittalcd98d472011-08-02 14:29:24 -0700940 offset = imagesize_actual;
Deepa Dinamanid14bb4d2013-07-12 17:28:29 -0700941
942 if (check_aboot_addr_range_overlap(image_addr + offset, page_size))
943 {
944 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
945 return -1;
946 }
947
Shashank Mittalcd98d472011-08-02 14:29:24 -0700948 /* Read signature */
949 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
950 {
951 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700952 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -0700953 }
Amol Jadib6be5c12012-11-14 13:39:51 -0800954
wangxl6145a502015-04-10 09:58:03 +0800955 // verify_signed_bootimg(image_addr, imagesize_actual);
Shashank Mittalcd98d472011-08-02 14:29:24 -0700956
Neeti Desai465491e2012-07-31 12:53:35 -0700957 /* Move kernel, ramdisk and device tree to correct address */
Shashank Mittalcd98d472011-08-02 14:29:24 -0700958 memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
959 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittal162244e2011-08-08 19:01:25 -0700960
Neeti Desai465491e2012-07-31 12:53:35 -0700961 #if DEVICE_TREE
962 if(hdr->dt_size) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700963 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
Deepa Dinamani19648b42013-09-05 17:05:55 -0700964 table = (struct dt_table*) dt_table_offset;
Neeti Desai465491e2012-07-31 12:53:35 -0700965
Deepa Dinamani19648b42013-09-05 17:05:55 -0700966 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Neeti Desai465491e2012-07-31 12:53:35 -0700967 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
968 return -1;
969 }
Deepa Dinamani19648b42013-09-05 17:05:55 -0700970
Neeti Desai465491e2012-07-31 12:53:35 -0700971 /* Find index of device tree within device tree table */
Joel Kingaa335dc2013-06-03 16:11:08 -0700972 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Neeti Desai465491e2012-07-31 12:53:35 -0700973 dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
974 return -1;
975 }
976
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700977 /* Validate and Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -0700978 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700979 {
980 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
981 return -1;
982 }
983
Joel Kingaa335dc2013-06-03 16:11:08 -0700984 memmove((void *)hdr->tags_addr, (char *)dt_table_offset + dt_entry.offset, dt_entry.size);
Channagoud Kadabi35095622013-03-01 13:53:05 -0800985 } else {
Dima Zavin77e41f32013-03-06 16:10:43 -0800986 /*
987 * If appended dev tree is found, update the atags with
988 * memory address to the DTB appended location on RAM.
989 * Else update with the atags address in the kernel header
990 */
991 void *dtb;
992 dtb = dev_tree_appended((void*) hdr->kernel_addr,
Dima Zavine63e5572013-05-03 12:23:06 -0700993 hdr->kernel_size,
994 (void *)hdr->tags_addr);
Dima Zavin77e41f32013-03-06 16:10:43 -0800995 if (!dtb) {
996 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
997 return -1;
998 }
Neeti Desai465491e2012-07-31 12:53:35 -0700999 }
1000 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07001001 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07001002 else
1003 {
Amol Jadib6be5c12012-11-14 13:39:51 -08001004 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Shashank Mittalcd98d472011-08-02 14:29:24 -07001005
Amol Jadib6be5c12012-11-14 13:39:51 -08001006 dprintf(INFO, "Loading boot image (%d): start\n",
1007 kernel_actual + ramdisk_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001008 bs_set_timestamp(BS_KERNEL_LOAD_START);
Amol Jadib6be5c12012-11-14 13:39:51 -08001009
1010 offset = page_size;
1011
1012 /* Load kernel */
1013 if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, kernel_actual)) {
Shashank Mittalcd98d472011-08-02 14:29:24 -07001014 dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
1015 return -1;
1016 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001017 offset += kernel_actual;
Shashank Mittalcd98d472011-08-02 14:29:24 -07001018
Amol Jadib6be5c12012-11-14 13:39:51 -08001019 /* Load ramdisk */
1020 if(ramdisk_actual != 0)
Shashank Mittalcd98d472011-08-02 14:29:24 -07001021 {
Amol Jadib6be5c12012-11-14 13:39:51 -08001022 if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) {
Shashank Mittalcd98d472011-08-02 14:29:24 -07001023 dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
1024 return -1;
1025 }
1026 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001027 offset += ramdisk_actual;
1028
1029 dprintf(INFO, "Loading boot image (%d): done\n",
1030 kernel_actual + ramdisk_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001031 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
Neeti Desai465491e2012-07-31 12:53:35 -07001032
1033 if(hdr->second_size != 0) {
Amol Jadib6be5c12012-11-14 13:39:51 -08001034 offset += second_actual;
1035 /* Second image loading not implemented. */
1036 ASSERT(0);
Neeti Desai465491e2012-07-31 12:53:35 -07001037 }
1038
1039 #if DEVICE_TREE
1040 if(hdr->dt_size != 0) {
Deepa Dinamani19648b42013-09-05 17:05:55 -07001041 /* Read the first page of device tree table into buffer */
Neeti Desai465491e2012-07-31 12:53:35 -07001042 if(mmc_read(ptn + offset,(unsigned int *) dt_buf, page_size)) {
1043 dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
1044 return -1;
1045 }
1046 table = (struct dt_table*) dt_buf;
1047
Deepa Dinamani19648b42013-09-05 17:05:55 -07001048 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Neeti Desai465491e2012-07-31 12:53:35 -07001049 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
1050 return -1;
1051 }
1052
Deepa Dinamani19648b42013-09-05 17:05:55 -07001053 table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size);
1054 if (!table)
1055 return -1;
1056
1057 /* Read the entire device tree table into buffer */
1058 if(mmc_read(ptn + offset,(unsigned int *) table, dt_hdr_size)) {
1059 dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
1060 return -1;
1061 }
1062
Joel Kingaa335dc2013-06-03 16:11:08 -07001063 /* Find index of device tree within device tree table */
1064 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Neeti Desai465491e2012-07-31 12:53:35 -07001065 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
1066 return -1;
1067 }
1068
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001069 /* Validate and Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -07001070 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001071 {
1072 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1073 return -1;
1074 }
1075
Joel Kingaa335dc2013-06-03 16:11:08 -07001076 if(mmc_read(ptn + offset + dt_entry.offset,
1077 (void *)hdr->tags_addr, dt_entry.size)) {
Neeti Desai465491e2012-07-31 12:53:35 -07001078 dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
1079 return -1;
1080 }
Amir Samuelov57a6fa22013-06-05 16:36:43 +03001081 #ifdef TZ_SAVE_KERNEL_HASH
1082 aboot_save_boot_hash_mmc(hdr->kernel_addr, kernel_actual,
1083 hdr->ramdisk_addr, ramdisk_actual,
1084 ptn, offset, hdr->dt_size);
1085 #endif /* TZ_SAVE_KERNEL_HASH */
1086
Channagoud Kadabi35095622013-03-01 13:53:05 -08001087 } else {
Aparna Mallavarapuf5432e42014-06-03 22:15:54 +05301088
1089 /* Validate the tags_addr */
1090 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual))
1091 {
1092 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1093 return -1;
1094 }
Dima Zavin77e41f32013-03-06 16:10:43 -08001095 /*
1096 * If appended dev tree is found, update the atags with
1097 * memory address to the DTB appended location on RAM.
1098 * Else update with the atags address in the kernel header
1099 */
1100 void *dtb;
1101 dtb = dev_tree_appended((void*) hdr->kernel_addr,
Dima Zavine63e5572013-05-03 12:23:06 -07001102 kernel_actual,
1103 (void *)hdr->tags_addr);
Dima Zavin77e41f32013-03-06 16:10:43 -08001104 if (!dtb) {
1105 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
1106 return -1;
1107 }
Neeti Desai465491e2012-07-31 12:53:35 -07001108 }
1109 #endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07001110 }
Sridhar Parasuram78344412015-08-29 11:13:07 -07001111#if VERIFIED_BOOT
1112 if(boot_verify_get_state() == ORANGE)
1113 {
1114 dprintf(CRITICAL,
1115 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
1116 mdelay(5000);
1117 }
1118
1119 // send root of trust
1120 if(!send_rot_command((uint32_t)device.is_unlocked))
1121 ASSERT(0);
1122#endif
1123
Shashank Mittal23b8f422010-04-16 19:27:21 -07001124
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03001125 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
1126 target_load_ssd_keystore();
1127
Shashank Mittal23b8f422010-04-16 19:27:21 -07001128unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07001129
Dima Zavin77e41f32013-03-06 16:10:43 -08001130 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07001131 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07001132 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
1133
1134 return 0;
1135}
1136
Dima Zavin214cc642009-01-26 11:16:21 -08001137int boot_linux_from_flash(void)
1138{
1139 struct boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08001140 struct ptentry *ptn;
1141 struct ptable *ptable;
1142 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08001143
Shashank Mittalcd98d472011-08-02 14:29:24 -07001144 unsigned char *image_addr = 0;
1145 unsigned kernel_actual;
1146 unsigned ramdisk_actual;
1147 unsigned imagesize_actual;
Amol Jadib6be5c12012-11-14 13:39:51 -08001148 unsigned second_actual;
Shashank Mittalcd98d472011-08-02 14:29:24 -07001149
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001150#if DEVICE_TREE
1151 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001152 struct dt_entry dt_entry;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001153 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001154 uint32_t dt_hdr_size;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001155#endif
1156
David Ng183a7422009-12-07 14:55:21 -08001157 if (target_is_emmc_boot()) {
1158 hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
1159 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1160 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
1161 return -1;
1162 }
1163 goto continue_boot;
1164 }
1165
Dima Zavin214cc642009-01-26 11:16:21 -08001166 ptable = flash_get_ptable();
1167 if (ptable == NULL) {
1168 dprintf(CRITICAL, "ERROR: Partition table not found\n");
1169 return -1;
1170 }
1171
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08001172 if(!boot_into_recovery)
1173 {
1174 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001175
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08001176 if (ptn == NULL) {
1177 dprintf(CRITICAL, "ERROR: No boot partition found\n");
1178 return -1;
1179 }
1180 }
1181 else
1182 {
1183 ptn = ptable_find(ptable, "recovery");
1184 if (ptn == NULL) {
1185 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
1186 return -1;
1187 }
Dima Zavin214cc642009-01-26 11:16:21 -08001188 }
1189
Shashank Mittaldcc2e352009-11-19 19:11:16 -08001190 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08001191 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1192 return -1;
1193 }
Dima Zavin214cc642009-01-26 11:16:21 -08001194
1195 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001196 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08001197 return -1;
1198 }
1199
Shashank Mittaldcc2e352009-11-19 19:11:16 -08001200 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001201 dprintf(CRITICAL, "ERROR: Invalid boot image pagesize. Device pagesize: %d, Image pagesize: %d\n",page_size,hdr->page_size);
Shashank Mittaldcc2e352009-11-19 19:11:16 -08001202 return -1;
1203 }
1204
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001205 /*
1206 * Update the kernel/ramdisk/tags address if the boot image header
1207 * has default values, these default values come from mkbootimg when
1208 * the boot image is flashed using fastboot flash:raw
1209 */
1210 update_ker_tags_rdisk_addr(hdr);
1211
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001212 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001213 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
1214 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
1215 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
1216
1217 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1218 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
1219
1220 /* Check if the addresses in the header are valid. */
1221 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
1222 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
1223 {
1224 dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
1225 return -1;
1226 }
1227
1228#ifndef DEVICE_TREE
1229 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
1230 {
1231 dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
1232 return -1;
1233 }
1234#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001235
Shashank Mittalcd98d472011-08-02 14:29:24 -07001236 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07001237 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07001238 {
1239 image_addr = (unsigned char *)target_get_scratch_address();
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001240 offset = 0;
1241
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001242#if DEVICE_TREE
1243 dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
1244 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + dt_actual);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001245
1246 if (check_aboot_addr_range_overlap(hdr->tags_addr, hdr->dt_size))
1247 {
1248 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1249 return -1;
1250 }
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001251#else
Shashank Mittalcd98d472011-08-02 14:29:24 -07001252 imagesize_actual = (page_size + kernel_actual + ramdisk_actual);
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001253#endif
Shashank Mittal162244e2011-08-08 19:01:25 -07001254
Amol Jadib6be5c12012-11-14 13:39:51 -08001255 dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001256 bs_set_timestamp(BS_KERNEL_LOAD_START);
Amol Jadib6be5c12012-11-14 13:39:51 -08001257
Vijay Kumar Pendotic5162592016-07-05 13:45:54 +05301258 if (UINT_MAX - page_size < imagesize_actual)
1259 {
1260 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
1261 return -1;
1262 }
1263
1264 /*Check the availability of RAM before reading boot image + max signature length from flash*/
1265 if (target_get_max_flash_size() < (imagesize_actual + page_size))
1266 {
1267 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
1268 return -1;
1269 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07001270 /* Read image without signature */
1271 if (flash_read(ptn, offset, (void *)image_addr, imagesize_actual))
1272 {
1273 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
1274 return -1;
1275 }
Dima Zavin214cc642009-01-26 11:16:21 -08001276
Amol Jadib6be5c12012-11-14 13:39:51 -08001277 dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001278 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
Amol Jadib6be5c12012-11-14 13:39:51 -08001279
Shashank Mittalcd98d472011-08-02 14:29:24 -07001280 offset = imagesize_actual;
1281 /* Read signature */
1282 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
1283 {
1284 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001285 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07001286 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07001287
wangxl6145a502015-04-10 09:58:03 +08001288 //verify_signed_bootimg(image_addr, imagesize_actual);
Shashank Mittalcd98d472011-08-02 14:29:24 -07001289
1290 /* Move kernel and ramdisk to correct address */
1291 memmove((void*) hdr->kernel_addr, (char *)(image_addr + page_size), hdr->kernel_size);
1292 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001293#if DEVICE_TREE
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001294 /* Validate and Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -07001295 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001296 {
1297 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1298 return -1;
1299 }
1300
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001301 memmove((void*) hdr->tags_addr, (char *)(image_addr + page_size + kernel_actual + ramdisk_actual), hdr->dt_size);
1302#endif
Shashank Mittal162244e2011-08-08 19:01:25 -07001303
1304 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07001305 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07001306 {
1307 write_device_info_flash(&device);
1308 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05301309#if USE_PCOM_SECBOOT
1310 set_tamper_flag(device.is_tampered);
1311#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07001312 }
1313 else
1314 {
Shashank Mittal162244e2011-08-08 19:01:25 -07001315 offset = page_size;
1316
Amol Jadib6be5c12012-11-14 13:39:51 -08001317 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1318 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
1319 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
1320
1321 dprintf(INFO, "Loading boot image (%d): start\n",
1322 kernel_actual + ramdisk_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001323 bs_set_timestamp(BS_KERNEL_LOAD_START);
Amol Jadib6be5c12012-11-14 13:39:51 -08001324
Vijay Kumar Pendoti7fc22bb2017-05-16 09:32:14 +08001325 if (UINT_MAX - offset < kernel_actual)
1326 {
1327 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
1328 return -1;
1329 }
1330
Amol Jadib6be5c12012-11-14 13:39:51 -08001331 if (flash_read(ptn, offset, (void *)hdr->kernel_addr, kernel_actual)) {
Shashank Mittalcd98d472011-08-02 14:29:24 -07001332 dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
1333 return -1;
1334 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001335 offset += kernel_actual;
Shashank Mittalcd98d472011-08-02 14:29:24 -07001336
Vijay Kumar Pendoti7fc22bb2017-05-16 09:32:14 +08001337 if (UINT_MAX - offset < ramdisk_actual)
1338 {
1339 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
1340 return -1;
1341 }
1342
Amol Jadib6be5c12012-11-14 13:39:51 -08001343 if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) {
Shashank Mittalcd98d472011-08-02 14:29:24 -07001344 dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
1345 return -1;
1346 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001347 offset += ramdisk_actual;
1348
1349 dprintf(INFO, "Loading boot image (%d): done\n",
1350 kernel_actual + ramdisk_actual);
Amol Jadi492d5a52013-03-15 16:12:34 -07001351 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001352
1353 if(hdr->second_size != 0) {
Vijay Kumar Pendoti7fc22bb2017-05-16 09:32:14 +08001354 if (UINT_MAX - offset < second_actual)
1355 {
1356 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
1357 return -1;
1358 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001359 offset += second_actual;
1360 /* Second image loading not implemented. */
1361 ASSERT(0);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001362 }
1363
1364#if DEVICE_TREE
1365 if(hdr->dt_size != 0) {
1366
1367 /* Read the device tree table into buffer */
1368 if(flash_read(ptn, offset, (void *) dt_buf, page_size)) {
1369 dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
1370 return -1;
1371 }
1372
1373 table = (struct dt_table*) dt_buf;
1374
Deepa Dinamani19648b42013-09-05 17:05:55 -07001375 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001376 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
1377 return -1;
1378 }
1379
Deepa Dinamani19648b42013-09-05 17:05:55 -07001380 table = (struct dt_table*) memalign(CACHE_LINE, dt_hdr_size);
1381 if (!table)
1382 return -1;
1383
1384 /* Read the entire device tree table into buffer */
1385 if(flash_read(ptn, offset, (void *)table, dt_hdr_size)) {
1386 dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
1387 return -1;
1388 }
1389
1390
Joel Kingaa335dc2013-06-03 16:11:08 -07001391 /* Find index of device tree within device tree table */
1392 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001393 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
1394 return -1;
1395 }
1396
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001397 /* Validate and Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -07001398 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001399 {
1400 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1401 return -1;
1402 }
1403
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001404 /* Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -07001405 if(flash_read(ptn, offset + dt_entry.offset,
1406 (void *)hdr->tags_addr, dt_entry.size)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001407 dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
1408 return -1;
1409 }
1410 }
1411#endif
1412
Shashank Mittalcd98d472011-08-02 14:29:24 -07001413 }
David Ng183a7422009-12-07 14:55:21 -08001414continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08001415
Dima Zavin214cc642009-01-26 11:16:21 -08001416 /* TODO: create/pass atags to kernel */
1417
Ajay Dudanie28a6072011-07-01 13:59:46 -07001418 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07001419 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08001420 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
1421
1422 return 0;
1423}
Brian Swetland9c4c0752009-01-25 16:23:50 -08001424
Channagoud Kadabi132ff552013-04-19 14:34:44 -07001425BUF_DMA_ALIGN(info_buf, 4096);
Shashank Mittal162244e2011-08-08 19:01:25 -07001426void write_device_info_mmc(device_info *dev)
1427{
1428 struct device_info *info = (void*) info_buf;
1429 unsigned long long ptn = 0;
1430 unsigned long long size;
1431 int index = INVALID_PTN;
1432
1433 index = partition_get_index("aboot");
1434 ptn = partition_get_offset(index);
1435 if(ptn == 0)
1436 {
1437 return;
1438 }
1439
1440 size = partition_get_size(index);
1441
1442 memcpy(info, dev, sizeof(device_info));
1443
1444 if(mmc_write((ptn + size - 512), 512, (void *)info_buf))
1445 {
1446 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
1447 return;
1448 }
1449}
1450
1451void read_device_info_mmc(device_info *dev)
1452{
1453 struct device_info *info = (void*) info_buf;
1454 unsigned long long ptn = 0;
1455 unsigned long long size;
1456 int index = INVALID_PTN;
1457
1458 index = partition_get_index("aboot");
1459 ptn = partition_get_offset(index);
1460 if(ptn == 0)
1461 {
1462 return;
1463 }
1464
1465 size = partition_get_size(index);
1466
1467 if(mmc_read((ptn + size - 512), (void *)info_buf, 512))
1468 {
1469 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
1470 return;
1471 }
1472
1473 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
1474 {
1475 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
1476 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07001477 info->is_tampered = 0;
Liu Yuec78d6d12015-09-28 09:59:51 +08001478 info->charger_screen_enabled = 1;
Sridhar Parasuram78344412015-08-29 11:13:07 -07001479#if VERIFIED_BOOT
1480 info->verity_mode = 1;
1481#endif
Shashank Mittal162244e2011-08-08 19:01:25 -07001482 write_device_info_mmc(info);
1483 }
1484 memcpy(dev, info, sizeof(device_info));
1485}
1486
1487void write_device_info_flash(device_info *dev)
1488{
1489 struct device_info *info = (void *) info_buf;
1490 struct ptentry *ptn;
1491 struct ptable *ptable;
1492
1493 ptable = flash_get_ptable();
1494 if (ptable == NULL)
1495 {
1496 dprintf(CRITICAL, "ERROR: Partition table not found\n");
1497 return;
1498 }
1499
1500 ptn = ptable_find(ptable, "devinfo");
1501 if (ptn == NULL)
1502 {
1503 dprintf(CRITICAL, "ERROR: No boot partition found\n");
1504 return;
1505 }
1506
1507 memcpy(info, dev, sizeof(device_info));
1508
1509 if (flash_write(ptn, 0, (void *)info_buf, page_size))
1510 {
1511 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
1512 return;
1513 }
1514}
1515
1516void read_device_info_flash(device_info *dev)
1517{
1518 struct device_info *info = (void*) info_buf;
1519 struct ptentry *ptn;
1520 struct ptable *ptable;
1521
1522 ptable = flash_get_ptable();
1523 if (ptable == NULL)
1524 {
1525 dprintf(CRITICAL, "ERROR: Partition table not found\n");
1526 return;
1527 }
1528
1529 ptn = ptable_find(ptable, "devinfo");
1530 if (ptn == NULL)
1531 {
1532 dprintf(CRITICAL, "ERROR: No boot partition found\n");
1533 return;
1534 }
1535
1536 if (flash_read(ptn, 0, (void *)info_buf, page_size))
1537 {
1538 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
1539 return;
1540 }
1541
1542 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
1543 {
Shashank Mittal162244e2011-08-08 19:01:25 -07001544 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
1545 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07001546 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07001547 write_device_info_flash(info);
1548 }
1549 memcpy(dev, info, sizeof(device_info));
1550}
1551
1552void write_device_info(device_info *dev)
1553{
1554 if(target_is_emmc_boot())
1555 {
1556 write_device_info_mmc(dev);
1557 }
1558 else
1559 {
1560 write_device_info_flash(dev);
1561 }
1562}
1563
1564void read_device_info(device_info *dev)
1565{
1566 if(target_is_emmc_boot())
1567 {
1568 read_device_info_mmc(dev);
1569 }
1570 else
1571 {
1572 read_device_info_flash(dev);
1573 }
1574}
1575
1576void reset_device_info()
1577{
1578 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07001579 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07001580 write_device_info(&device);
1581}
1582
1583void set_device_root()
1584{
1585 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07001586 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07001587 write_device_info(&device);
1588}
1589
Amol Jadicb524072012-08-09 16:40:18 -07001590#if DEVICE_TREE
1591int copy_dtb(uint8_t *boot_image_start)
1592{
1593 uint32 dt_image_offset = 0;
1594 uint32_t n;
1595 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001596 struct dt_entry dt_entry;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001597 uint32_t dt_hdr_size;
Amol Jadicb524072012-08-09 16:40:18 -07001598
1599 struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start);
1600
Amol Jadicb524072012-08-09 16:40:18 -07001601 if(hdr->dt_size != 0) {
1602
1603 /* add kernel offset */
1604 dt_image_offset += page_size;
1605 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1606 dt_image_offset += n;
1607
1608 /* add ramdisk offset */
1609 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
1610 dt_image_offset += n;
1611
1612 /* add second offset */
1613 if(hdr->second_size != 0) {
1614 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
1615 dt_image_offset += n;
1616 }
1617
1618 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001619 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07001620
Deepa Dinamani19648b42013-09-05 17:05:55 -07001621 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07001622 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
1623 return -1;
1624 }
Joel Kingaa335dc2013-06-03 16:11:08 -07001625 /* Find index of device tree within device tree table */
1626 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07001627 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
1628 return -1;
1629 }
1630
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001631 /* Validate and Read device device tree in the "tags_add */
Joel Kingaa335dc2013-06-03 16:11:08 -07001632 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001633 {
1634 dprintf(CRITICAL, "Device tree addresses overlap with aboot addresses.\n");
1635 return -1;
1636 }
1637
Amol Jadicb524072012-08-09 16:40:18 -07001638 /* Read device device tree in the "tags_add */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001639 memmove((void*) hdr->tags_addr,
Joel Kingaa335dc2013-06-03 16:11:08 -07001640 boot_image_start + dt_image_offset + dt_entry.offset,
1641 dt_entry.size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07001642 } else
1643 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07001644
1645 /* Everything looks fine. Return success. */
1646 return 0;
1647}
1648#endif
1649
Brian Swetland9c4c0752009-01-25 16:23:50 -08001650void cmd_boot(const char *arg, void *data, unsigned sz)
1651{
1652 unsigned kernel_actual;
1653 unsigned ramdisk_actual;
Channagoud Kadabice737c82014-06-18 17:41:01 -07001654 uint32_t image_actual;
1655 uint32_t dt_actual = 0;
Channagoud Kadabi87c2dd62014-06-26 14:26:39 -07001656 uint32_t sig_actual = SIGNATURE_SIZE;
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001657 struct boot_img_hdr *hdr;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001658 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07001659 int ret = 0;
1660 uint8_t dtb_copied = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001661
1662 if (sz < sizeof(hdr)) {
1663 fastboot_fail("invalid bootimage header");
1664 return;
1665 }
1666
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001667 hdr = (struct boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001668
1669 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001670 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001671
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001672 if(target_is_emmc_boot() && hdr->page_size) {
1673 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001674 page_mask = page_size - 1;
1675 }
1676
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001677 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1678 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Channagoud Kadabice737c82014-06-18 17:41:01 -07001679#if DEVICE_TREE
1680 dt_actual = ROUND_TO_PAGE(hdr->dt_size, page_mask);
1681#endif
1682
1683 image_actual = ADD_OF(page_size, kernel_actual);
1684 image_actual = ADD_OF(image_actual, ramdisk_actual);
1685 image_actual = ADD_OF(image_actual, dt_actual);
1686
Channagoud Kadabi87c2dd62014-06-26 14:26:39 -07001687 if (target_use_signed_kernel() && (!device.is_unlocked))
1688 image_actual = ADD_OF(image_actual, sig_actual);
1689
Channagoud Kadabice737c82014-06-18 17:41:01 -07001690 /* sz should have atleast raw boot image */
1691 if (image_actual > sz) {
Channagoud Kadabi87c2dd62014-06-26 14:26:39 -07001692 fastboot_fail("bootimage: incomplete or not signed");
Channagoud Kadabice737c82014-06-18 17:41:01 -07001693 return;
1694 }
1695
1696 /* Verify the boot image
1697 * device & page_size are initialized in aboot_init
1698 */
1699 if (target_use_signed_kernel() && (!device.is_unlocked))
Channagoud Kadabi87c2dd62014-06-26 14:26:39 -07001700 /* Pass size excluding signature size, otherwise we would try to
1701 * access signature beyond its length
1702 */
wangxl6145a502015-04-10 09:58:03 +08001703 //verify_signed_bootimg((uint32_t)data, (image_actual - sig_actual));
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001704
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001705 /*
1706 * Update the kernel/ramdisk/tags address if the boot image header
1707 * has default values, these default values come from mkbootimg when
1708 * the boot image is flashed using fastboot flash:raw
1709 */
1710 update_ker_tags_rdisk_addr(hdr);
Dima Zavin3cadfff2013-03-21 14:30:48 -07001711
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001712 /* Get virtual addresses since the hdr saves physical addresses. */
1713 hdr->kernel_addr = VA(hdr->kernel_addr);
1714 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
1715 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001716
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001717 /* Check if the addresses in the header are valid. */
1718 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
1719 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual))
1720 {
1721 dprintf(CRITICAL, "kernel/ramdisk addresses overlap with aboot addresses.\n");
Channagoud Kadabia54102a2013-12-03 11:19:20 -08001722 return;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001723 }
1724
Amol Jadicb524072012-08-09 16:40:18 -07001725#if DEVICE_TREE
1726 /* find correct dtb and copy it to right location */
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07001727 ret = copy_dtb(data);
1728
1729 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001730#else
1731 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
1732 {
1733 dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
Channagoud Kadabia54102a2013-12-03 11:19:20 -08001734 return;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001735 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07001736#endif
1737
1738 /* Load ramdisk & kernel */
1739 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
1740 memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
1741
1742#if DEVICE_TREE
1743 /*
1744 * If dtb is not found look for appended DTB in the kernel.
1745 * If appended dev tree is found, update the atags with
1746 * memory address to the DTB appended location on RAM.
1747 * Else update with the atags address in the kernel header
1748 */
1749 if (!dtb_copied) {
1750 void *dtb;
Dima Zavine63e5572013-05-03 12:23:06 -07001751 dtb = dev_tree_appended((void *)hdr->kernel_addr, hdr->kernel_size,
1752 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07001753 if (!dtb) {
1754 fastboot_fail("dtb not found");
1755 return;
1756 }
Amol Jadicb524072012-08-09 16:40:18 -07001757 }
1758#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08001759
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001760#ifndef DEVICE_TREE
1761 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE))
1762 {
1763 dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
Channagoud Kadabia54102a2013-12-03 11:19:20 -08001764 return;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001765 }
1766#endif
1767
Brian Swetland9c4c0752009-01-25 16:23:50 -08001768 fastboot_okay("");
1769 udc_stop();
1770
Dima Zavin77e41f32013-03-06 16:10:43 -08001771 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001772 (const char*) hdr->cmdline, board_machtype(),
1773 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001774}
1775
Sridhar Parasuram901bb702014-10-24 14:06:03 -07001776void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08001777{
1778 struct ptentry *ptn;
1779 struct ptable *ptable;
1780
1781 ptable = flash_get_ptable();
1782 if (ptable == NULL) {
1783 fastboot_fail("partition table doesn't exist");
1784 return;
1785 }
1786
1787 ptn = ptable_find(ptable, arg);
1788 if (ptn == NULL) {
1789 fastboot_fail("unknown partition name");
1790 return;
1791 }
1792
1793 if (flash_erase(ptn)) {
1794 fastboot_fail("failed to erase partition");
1795 return;
1796 }
1797 fastboot_okay("");
1798}
1799
Bikas Gurungd48bd242010-09-04 19:54:32 -07001800
1801void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
1802{
Kun Liang2f1601a2013-08-12 16:29:54 +08001803 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
Bikas Gurungd48bd242010-09-04 19:54:32 -07001804 unsigned long long ptn = 0;
Oliver Wang0e0dfa72013-10-22 18:40:13 +08001805 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001806 int index = INVALID_PTN;
Bikas Gurungd48bd242010-09-04 19:54:32 -07001807
Kinson Chikf1a43512011-07-14 11:28:39 -07001808 index = partition_get_index(arg);
1809 ptn = partition_get_offset(index);
Oliver Wang0e0dfa72013-10-22 18:40:13 +08001810 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07001811
Kinson Chikf1a43512011-07-14 11:28:39 -07001812 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07001813 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07001814 return;
1815 }
Kun Liang2f1601a2013-08-12 16:29:54 +08001816
Oliver Wang0e0dfa72013-10-22 18:40:13 +08001817#if MMC_SDHCI_SUPPORT
1818 if (mmc_erase_card(ptn, size)) {
1819 fastboot_fail("failed to erase partition\n");
1820 return;
1821 }
1822#else
Kun Liang2f1601a2013-08-12 16:29:54 +08001823 size = partition_get_size(index);
1824 if (size > DEFAULT_ERASE_SIZE)
1825 size = DEFAULT_ERASE_SIZE;
1826
neetidb4b24d62012-01-20 12:13:09 -08001827 /* Simple inefficient version of erase. Just writing
Kun Liang2f1601a2013-08-12 16:29:54 +08001828 0 in first several blocks */
1829 if (mmc_write(ptn , size, (unsigned int *)out)) {
neetidb4b24d62012-01-20 12:13:09 -08001830 fastboot_fail("failed to erase partition");
Bikas Gurungd48bd242010-09-04 19:54:32 -07001831 return;
1832 }
Oliver Wang0e0dfa72013-10-22 18:40:13 +08001833#endif
Sridhar Parasuram78344412015-08-29 11:13:07 -07001834#if VERIFIED_BOOT
1835 if(!(strncmp(arg, "userdata", 8)))
1836 if(send_delete_keys_to_tz())
1837 ASSERT(0);
1838#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07001839 fastboot_okay("");
1840}
1841
Sridhar Parasuram901bb702014-10-24 14:06:03 -07001842void cmd_erase(const char *arg, void *data, unsigned sz)
1843{
Sridhar Parasuram78344412015-08-29 11:13:07 -07001844
1845#if VERIFIED_BOOT
1846 if(!device.is_unlocked)
1847 {
1848 fastboot_fail("device is locked. Cannot erase");
1849 return;
1850 }
1851#endif
1852
Sridhar Parasuram901bb702014-10-24 14:06:03 -07001853 if(target_is_emmc_boot())
1854 cmd_erase_mmc(arg, data, sz);
1855 else
1856 cmd_erase_nand(arg, data, sz);
1857}
Bikas Gurungd48bd242010-09-04 19:54:32 -07001858
Ajay Dudani5c761132011-04-07 20:19:04 -07001859void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07001860{
1861 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07001862 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001863 int index = INVALID_PTN;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07001864
Greg Grisco6e754772011-06-23 12:19:39 -07001865 if (!strcmp(arg, "partition"))
1866 {
1867 dprintf(INFO, "Attempt to write partition image.\n");
Neeti Desai5f26aff2011-09-30 10:27:40 -07001868 if (write_partition(sz, (unsigned char *) data)) {
Greg Grisco6e754772011-06-23 12:19:39 -07001869 fastboot_fail("failed to write partition");
Shashank Mittal23b8f422010-04-16 19:27:21 -07001870 return;
1871 }
1872 }
Greg Grisco6e754772011-06-23 12:19:39 -07001873 else
1874 {
Kinson Chikf1a43512011-07-14 11:28:39 -07001875 index = partition_get_index(arg);
1876 ptn = partition_get_offset(index);
Greg Grisco6e754772011-06-23 12:19:39 -07001877 if(ptn == 0) {
1878 fastboot_fail("partition table doesn't exist");
1879 return;
1880 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001881
Greg Grisco6e754772011-06-23 12:19:39 -07001882 if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) {
1883 if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1884 fastboot_fail("image is not a boot image");
1885 return;
1886 }
1887 }
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07001888
Kinson Chikf1a43512011-07-14 11:28:39 -07001889 size = partition_get_size(index);
Greg Grisco6e754772011-06-23 12:19:39 -07001890 if (ROUND_TO_PAGE(sz,511) > size) {
1891 fastboot_fail("size too large");
1892 return;
1893 }
1894 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
1895 fastboot_fail("flash write failure");
1896 return;
1897 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001898 }
1899 fastboot_okay("");
1900 return;
1901}
1902
Ajay Dudani5c761132011-04-07 20:19:04 -07001903void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
1904{
1905 unsigned int chunk;
1906 unsigned int chunk_data_sz;
Channagoud Kadabic478bc52013-09-09 14:08:20 -07001907 uint32_t *fill_buf = NULL;
1908 uint32_t fill_val;
1909 uint32_t chunk_blk_cnt = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07001910 sparse_header_t *sparse_header;
1911 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07001912 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07001913 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05301914 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001915 int index = INVALID_PTN;
Channagoud Kadabic478bc52013-09-09 14:08:20 -07001916 int i;
vijay kumard6ebd9a2015-04-24 20:26:19 +05301917 /*End of the sparse image address*/
1918 uint32_t data_end = (uint32_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07001919
Kinson Chikf1a43512011-07-14 11:28:39 -07001920 index = partition_get_index(arg);
1921 ptn = partition_get_offset(index);
1922 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07001923 fastboot_fail("partition table doesn't exist");
1924 return;
1925 }
1926
Channagoud Kadabi65b91002011-10-11 17:34:33 +05301927 size = partition_get_size(index);
vijay kumard6ebd9a2015-04-24 20:26:19 +05301928
1929 if (sz < sizeof(sparse_header_t)) {
1930 fastboot_fail("size too low");
Channagoud Kadabi65b91002011-10-11 17:34:33 +05301931 return;
1932 }
1933
Ajay Dudani5c761132011-04-07 20:19:04 -07001934 /* Read and skip over sparse image header */
1935 sparse_header = (sparse_header_t *) data;
vijay kumard6ebd9a2015-04-24 20:26:19 +05301936
vijay kumar05e00a52015-03-27 12:13:42 +05301937 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08001938 fastboot_fail("size too large");
1939 return;
1940 }
1941
vijay kumar3c9ccff2015-04-23 13:05:49 +05301942 data += sizeof(sparse_header_t);
vijay kumard6ebd9a2015-04-24 20:26:19 +05301943
1944 if (data_end < (uint32_t)data) {
1945 fastboot_fail("buffer overreads occured due to invalid sparse header");
1946 return;
1947 }
1948
vijay kumar3c9ccff2015-04-23 13:05:49 +05301949 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07001950 {
vijay kumar3c9ccff2015-04-23 13:05:49 +05301951 fastboot_fail("sparse header size mismatch");
1952 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07001953 }
1954
Ajay Dudanib06c05f2011-05-12 14:46:10 -07001955 dprintf (SPEW, "=== Sparse Image Header ===\n");
1956 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
1957 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
1958 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
1959 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
1960 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
1961 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
1962 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
1963 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07001964
1965 /* Start processing chunks */
1966 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
1967 {
Aparna Mallavarapu4f829bb2015-03-28 01:41:08 +05301968 /* Make sure the total image size does not exceed the partition size */
1969 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
1970 fastboot_fail("size too large");
1971 return;
1972 }
Ajay Dudani5c761132011-04-07 20:19:04 -07001973 /* Read and skip over chunk header */
1974 chunk_header = (chunk_header_t *) data;
1975 data += sizeof(chunk_header_t);
1976
vijay kumard6ebd9a2015-04-24 20:26:19 +05301977 if (data_end < (uint32_t)data) {
1978 fastboot_fail("buffer overreads occured due to invalid sparse header");
1979 return;
1980 }
1981
Ajay Dudani5c761132011-04-07 20:19:04 -07001982 dprintf (SPEW, "=== Chunk Header ===\n");
1983 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
1984 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
1985 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
1986
vijay kumard6ebd9a2015-04-24 20:26:19 +05301987 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07001988 {
vijay kumard6ebd9a2015-04-24 20:26:19 +05301989 fastboot_fail("chunk header size mismatch");
1990 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07001991 }
1992
1993 chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
Aparna Mallavarapu4f829bb2015-03-28 01:41:08 +05301994
1995 /* Make sure multiplication does not overflow uint32 size */
1996 if (sparse_header->blk_sz && (chunk_header->chunk_sz != chunk_data_sz / sparse_header->blk_sz))
1997 {
1998 fastboot_fail("Bogus size sparse and chunk header");
1999 return;
2000 }
2001
2002 /* Make sure that the chunk size calculated from sparse image does not
2003 * exceed partition size
2004 */
2005 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
2006 {
2007 fastboot_fail("Chunk data size exceeds partition size");
2008 return;
2009 }
2010
Ajay Dudani5c761132011-04-07 20:19:04 -07002011 switch (chunk_header->chunk_type)
2012 {
2013 case CHUNK_TYPE_RAW:
2014 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
2015 chunk_data_sz))
2016 {
2017 fastboot_fail("Bogus chunk size for chunk type Raw");
2018 return;
2019 }
2020
vijay kumard6ebd9a2015-04-24 20:26:19 +05302021 if (data_end < (uint32_t)data + chunk_data_sz) {
2022 fastboot_fail("buffer overreads occured due to invalid sparse header");
2023 return;
2024 }
2025
Ajay Dudaniab18f022011-05-12 14:39:22 -07002026 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
2027 chunk_data_sz,
2028 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07002029 {
2030 fastboot_fail("flash write failure");
2031 return;
2032 }
Aparna Mallavarapu4f829bb2015-03-28 01:41:08 +05302033 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
2034 fastboot_fail("Bogus size for RAW chunk type");
2035 return;
2036 }
Ajay Dudani5c761132011-04-07 20:19:04 -07002037 total_blocks += chunk_header->chunk_sz;
2038 data += chunk_data_sz;
2039 break;
2040
Channagoud Kadabic478bc52013-09-09 14:08:20 -07002041 case CHUNK_TYPE_FILL:
2042 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
2043 sizeof(uint32_t)))
2044 {
2045 fastboot_fail("Bogus chunk size for chunk type FILL");
2046 return;
2047 }
2048
2049 fill_buf = (uint32_t *)memalign(CACHE_LINE, ROUNDUP(sparse_header->blk_sz, CACHE_LINE));
2050 if (!fill_buf)
2051 {
2052 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
2053 return;
2054 }
2055
2056 fill_val = *(uint32_t *)data;
2057 data = (char *) data + sizeof(uint32_t);
2058 chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
2059
2060 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
2061 {
2062 fill_buf[i] = fill_val;
2063 }
2064
2065 for (i = 0; i < chunk_blk_cnt; i++)
2066 {
2067 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
2068 sparse_header->blk_sz,
2069 fill_buf))
2070 {
2071 fastboot_fail("flash write failure");
2072 free(fill_buf);
2073 return;
2074 }
2075
2076 total_blocks++;
2077 }
2078
2079 free(fill_buf);
2080 break;
2081
Ajay Dudani5c761132011-04-07 20:19:04 -07002082 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu4f829bb2015-03-28 01:41:08 +05302083 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
2084 fastboot_fail("bogus size for chunk DONT CARE type");
2085 return;
2086 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07002087 total_blocks += chunk_header->chunk_sz;
2088 break;
2089
Ajay Dudani5c761132011-04-07 20:19:04 -07002090 case CHUNK_TYPE_CRC:
2091 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
2092 {
2093 fastboot_fail("Bogus chunk size for chunk type Dont Care");
2094 return;
2095 }
Aparna Mallavarapu4f829bb2015-03-28 01:41:08 +05302096 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
2097 fastboot_fail("bogus size for chunk CRC type");
2098 return;
2099 }
Ajay Dudani5c761132011-04-07 20:19:04 -07002100 total_blocks += chunk_header->chunk_sz;
vijay kumard6ebd9a2015-04-24 20:26:19 +05302101 if ((uint32_t)data > UINT_MAX - chunk_data_sz) {
2102 fastboot_fail("integer overflow occured");
2103 return;
2104 }
Ajay Dudani5c761132011-04-07 20:19:04 -07002105 data += chunk_data_sz;
vijay kumard6ebd9a2015-04-24 20:26:19 +05302106 if (data_end < (uint32_t)data) {
2107 fastboot_fail("buffer overreads occured due to invalid sparse header");
2108 return;
2109 }
Ajay Dudani5c761132011-04-07 20:19:04 -07002110 break;
2111
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07002112 default:
Channagoud Kadabic478bc52013-09-09 14:08:20 -07002113 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07002114 fastboot_fail("Unknown chunk type");
2115 return;
2116 }
2117 }
2118
Ajay Dudani0c6927b2011-05-18 11:12:16 -07002119 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
2120 total_blocks, sparse_header->total_blks);
2121
2122 if(total_blocks != sparse_header->total_blks)
2123 {
2124 fastboot_fail("sparse image write failure");
2125 }
Ajay Dudani5c761132011-04-07 20:19:04 -07002126
2127 fastboot_okay("");
2128 return;
2129}
2130
2131void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
2132{
2133 sparse_header_t *sparse_header;
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07002134 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
2135 unsigned int *magic_number = (unsigned int *) data;
Ajay Dudani5c761132011-04-07 20:19:04 -07002136
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07002137#ifdef SSD_ENABLE
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002138 int ret=0;
2139 uint32 major_version=0;
2140 uint32 minor_version=0;
2141
2142 ret = scm_svc_version(&major_version,&minor_version);
2143 if(!ret)
2144 {
2145 if(major_version >= 2)
2146 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03002147 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002148 {
2149 ret = encrypt_scm((uint32 **) &data, &sz);
2150 if (ret != 0) {
2151 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
2152 return;
2153 }
2154
Amir Samuelovbb65ce02013-05-05 12:20:18 +03002155 /* Protect only for SSD */
2156 if (!strcmp(arg, "ssd")) {
2157 ret = scm_protect_keystore((uint32 *) data, sz);
2158 if (ret != 0) {
2159 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
2160 return;
2161 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002162 }
2163 }
2164 else
2165 {
2166 ret = decrypt_scm_v2((uint32 **) &data, &sz);
2167 if(ret != 0)
2168 {
2169 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
2170 return;
2171 }
2172 }
2173 }
2174 else
2175 {
2176 if (magic_number[0] == DECRYPT_MAGIC_0 &&
2177 magic_number[1] == DECRYPT_MAGIC_1)
2178 {
2179 ret = decrypt_scm((uint32 **) &data, &sz);
2180 if (ret != 0) {
2181 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
2182 return;
2183 }
2184 }
2185 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
2186 magic_number[1] == ENCRYPT_MAGIC_1)
2187 {
2188 ret = encrypt_scm((uint32 **) &data, &sz);
2189 if (ret != 0) {
2190 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
2191 return;
2192 }
2193 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07002194 }
2195 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002196 else
Neeti Desai127b9e02012-03-20 16:11:23 -07002197 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002198 dprintf(CRITICAL,"INVALID SVC Version\n");
2199 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07002200 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08002201#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07002202
Sridhar Parasuram78344412015-08-29 11:13:07 -07002203#if VERIFIED_BOOT
2204 if(!device.is_unlocked)
2205 {
2206 fastboot_fail("device is locked. Cannot flash images");
2207 return;
2208 }
2209#endif
2210
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07002211 sparse_header = (sparse_header_t *) data;
Ajay Dudani5c761132011-04-07 20:19:04 -07002212 if (sparse_header->magic != SPARSE_HEADER_MAGIC)
2213 cmd_flash_mmc_img(arg, data, sz);
2214 else
2215 cmd_flash_mmc_sparse_img(arg, data, sz);
Sridhar Parasuram78344412015-08-29 11:13:07 -07002216
2217#if VERIFIED_BOOT
2218 if((!strncmp(arg, "system", 6)) && !device.verity_mode)
2219 {
2220 // reset dm_verity mode to enforcing
2221 device.verity_mode = 1;
2222 write_device_info(&device);
2223 }
2224#endif
2225
Ajay Dudani5c761132011-04-07 20:19:04 -07002226 return;
2227}
2228
Sridhar Parasuram901bb702014-10-24 14:06:03 -07002229void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08002230{
2231 struct ptentry *ptn;
2232 struct ptable *ptable;
2233 unsigned extra = 0;
Gaurav Nebhwani575fe1c2017-06-21 14:38:46 +08002234 uint64_t partition_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08002235
2236 ptable = flash_get_ptable();
2237 if (ptable == NULL) {
2238 fastboot_fail("partition table doesn't exist");
2239 return;
2240 }
2241
2242 ptn = ptable_find(ptable, arg);
2243 if (ptn == NULL) {
2244 fastboot_fail("unknown partition name");
2245 return;
2246 }
2247
2248 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
2249 if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2250 fastboot_fail("image is not a boot image");
2251 return;
2252 }
2253 }
2254
Amol Jadi5c61a952012-05-04 17:05:35 -07002255 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07002256 || !strcmp(ptn->name, "userdata")
2257 || !strcmp(ptn->name, "persist")
2258 || !strcmp(ptn->name, "recoveryfs")) {
Channagoud Kadabi404a7062011-03-21 19:27:50 +05302259 if (flash_ecc_bch_enabled())
2260 /* Spare data bytes for 8 bit ECC increased by 4 */
2261 extra = ((page_size >> 9) * 20);
2262 else
2263 extra = ((page_size >> 9) * 16);
2264 } else
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002265 sz = ROUND_TO_PAGE(sz, page_mask);
Dima Zavin214cc642009-01-26 11:16:21 -08002266
Gaurav Nebhwani575fe1c2017-06-21 14:38:46 +08002267 partition_size = (uint64_t)ptn->length * (uint64_t)flash_num_pages_per_blk() * (uint64_t)flash_page_size();
2268 if (partition_size > UINT_MAX) {
2269 fastboot_fail("Invalid partition size");
2270 return;
2271 }
2272
2273 if (sz > partition_size) {
2274 fastboot_fail("Image size too large");
2275 return;
2276 }
2277
Dima Zavin214cc642009-01-26 11:16:21 -08002278 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
2279 if (flash_write(ptn, extra, data, sz)) {
2280 fastboot_fail("flash write failure");
2281 return;
2282 }
2283 dprintf(INFO, "partition '%s' updated\n", ptn->name);
2284 fastboot_okay("");
2285}
2286
Sridhar Parasuram901bb702014-10-24 14:06:03 -07002287void cmd_flash(const char *arg, void *data, unsigned sz)
2288{
2289 if(target_is_emmc_boot())
2290 cmd_flash_mmc(arg, data, sz);
2291 else
2292 cmd_flash_nand(arg, data, sz);
2293}
2294
Dima Zavin214cc642009-01-26 11:16:21 -08002295void cmd_continue(const char *arg, void *data, unsigned sz)
2296{
2297 fastboot_okay("");
2298 udc_stop();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002299 if (target_is_emmc_boot())
2300 {
2301 boot_linux_from_mmc();
2302 }
2303 else
2304 {
2305 boot_linux_from_flash();
2306 }
Dima Zavin214cc642009-01-26 11:16:21 -08002307}
2308
Chandan Uddaraju94183c02010-01-15 15:13:59 -08002309void cmd_reboot(const char *arg, void *data, unsigned sz)
2310{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002311 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08002312 fastboot_okay("");
2313 reboot_device(0);
2314}
2315
2316void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
2317{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002318 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08002319 fastboot_okay("");
2320 reboot_device(FASTBOOT_MODE);
2321}
2322
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002323void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
2324{
2325 dprintf(INFO, "Enabling charger screen check\n");
2326 device.charger_screen_enabled = 1;
2327 write_device_info(&device);
2328 fastboot_okay("");
2329}
2330
2331void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
2332{
2333 dprintf(INFO, "Disabling charger screen check\n");
2334 device.charger_screen_enabled = 0;
2335 write_device_info(&device);
2336 fastboot_okay("");
2337}
2338
Unnati Gandhi15d08f92014-01-24 11:01:01 +05302339void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
2340{
2341 dprintf(INFO, "Selecting display panel %s\n", arg);
2342 if (arg)
2343 strlcpy(device.display_panel, arg,
2344 sizeof(device.display_panel));
2345 write_device_info(&device);
2346 fastboot_okay("");
2347}
2348
Sridhar Parasuram78344412015-08-29 11:13:07 -07002349void cmd_oem_lock(const char *arg, void *data, unsigned sz)
2350{
2351 struct recovery_message msg;
Dirk Vogt39f68db2017-10-16 15:05:11 +02002352 memset(&msg, 0, sizeof(msg));
Sridhar Parasuram78344412015-08-29 11:13:07 -07002353 if(device.is_unlocked)
2354 {
2355 device.is_unlocked = 0;
2356 write_device_info(&device);
2357 // upon oem lock, reboot to recovery to wipe user data
2358 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
2359 write_misc(0, &msg, sizeof(msg));
2360 fastboot_okay("");
2361 reboot_device(RECOVERY_MODE);
2362 }
2363 fastboot_okay("");
2364}
2365
2366
Shashank Mittal162244e2011-08-08 19:01:25 -07002367void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
2368{
2369 if(!device.is_unlocked)
2370 {
2371 device.is_unlocked = 1;
2372 write_device_info(&device);
Sridhar Parasuram78344412015-08-29 11:13:07 -07002373 struct recovery_message msg;
Dirk Vogt39f68db2017-10-16 15:05:11 +02002374 memset(&msg, 0, sizeof(msg));
Sridhar Parasuram78344412015-08-29 11:13:07 -07002375 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
2376 write_misc(0, &msg, sizeof(msg));
2377
2378 fastboot_okay("");
2379 reboot_device(RECOVERY_MODE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002380 }
2381 fastboot_okay("");
2382}
2383
Shashank Mittala0032282011-08-26 14:50:11 -07002384void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
2385{
Unnati Gandhi15d08f92014-01-24 11:01:01 +05302386 char response[128];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002387 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07002388 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002389 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
2390 fastboot_info(response);
2391 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07002392 fastboot_info(response);
Unnati Gandhi15d08f92014-01-24 11:01:01 +05302393 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
2394 fastboot_info(response);
Shashank Mittala0032282011-08-26 14:50:11 -07002395 fastboot_okay("");
2396}
2397
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07002398void cmd_preflash(const char *arg, void *data, unsigned sz)
2399{
2400 fastboot_okay("");
2401}
2402
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302403static struct fbimage logo_header = {0};
2404struct fbimage* splash_screen_flash();
2405
2406int splash_screen_check_header(struct fbimage *logo)
2407{
2408 if (memcmp(logo->header.magic, LOGO_IMG_MAGIC, 8))
2409 return -1;
2410 if (logo->header.width == 0 || logo->header.height == 0)
2411 return -1;
2412 return 0;
2413}
2414
2415struct fbimage* splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002416{
2417 struct ptentry *ptn;
2418 struct ptable *ptable;
2419 struct fbcon_config *fb_display = NULL;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302420 struct fbimage *logo = &logo_header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002421
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302422
2423 ptable = flash_get_ptable();
2424 if (ptable == NULL) {
2425 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2426 return NULL;
2427 }
2428 ptn = ptable_find(ptable, "splash");
2429 if (ptn == NULL) {
2430 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
2431 return NULL;
2432 }
2433
2434 if (flash_read(ptn, 0,(unsigned int *) logo, sizeof(logo->header))) {
2435 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2436 return NULL;
2437 }
2438
2439 if (splash_screen_check_header(logo)) {
2440 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
2441 return NULL;
2442 }
2443
2444 fb_display = fbcon_display();
2445 if (fb_display) {
Vineet Bajajb42103d2014-09-09 12:29:46 +05302446 if ((logo->header.width != fb_display->width) || (logo->header.height != fb_display->height)) {
2447 dprintf(CRITICAL, "Logo config doesn't match with fb config. Fall back to default logo\n");
2448 return NULL;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002449 }
Vineet Bajajb42103d2014-09-09 12:29:46 +05302450 uint8_t *base = (uint8_t *) fb_display->base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302451 if (flash_read(ptn + sizeof(logo->header), 0,
2452 base,
2453 ((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) {
2454 fbcon_clear();
Vineet Bajajb42103d2014-09-09 12:29:46 +05302455 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302456 return NULL;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002457 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302458 logo->image = base;
2459 }
2460
2461 return logo;
2462}
2463
2464struct fbimage* splash_screen_mmc()
2465{
2466 int index = INVALID_PTN;
2467 unsigned long long ptn = 0;
2468 struct fbcon_config *fb_display = NULL;
2469 struct fbimage *logo = &logo_header;
2470
2471 index = partition_get_index("splash");
2472 if (index == 0) {
2473 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
2474 return NULL;
2475 }
2476
2477 ptn = partition_get_offset(index);
2478 if (ptn == 0) {
2479 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
2480 return NULL;
2481 }
2482
2483 if (mmc_read(ptn, (unsigned int *) logo, sizeof(logo->header))) {
2484 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
2485 return NULL;
2486 }
2487
2488 if (splash_screen_check_header(logo)) {
2489 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
2490 return NULL;
2491 }
2492
2493 fb_display = fbcon_display();
2494 if (fb_display) {
Vineet Bajajb42103d2014-09-09 12:29:46 +05302495 if ((logo->header.width != fb_display->width) || (logo->header.height != fb_display->height)) {
2496 dprintf(CRITICAL, "Logo config doesn't match with fb config. Fall back default logo\n");
2497 return NULL;
2498 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302499 uint8_t *base = (uint8_t *) fb_display->base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302500 if (mmc_read(ptn + sizeof(logo->header),
2501 base,
2502 ((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) {
2503 fbcon_clear();
Vineet Bajajb42103d2014-09-09 12:29:46 +05302504 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05302505 return NULL;
2506 }
2507
2508 logo->image = base;
2509 }
2510
2511 return logo;
2512}
2513
2514
2515struct fbimage* fetch_image_from_partition()
2516{
2517 if (target_is_emmc_boot()) {
2518 return splash_screen_mmc();
2519 } else {
2520 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002521 }
2522}
2523
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07002524/* Get the size from partiton name */
2525static void get_partition_size(const char *arg, char *response)
2526{
2527 uint64_t ptn = 0;
2528 uint64_t size;
2529 int index = INVALID_PTN;
2530
2531 index = partition_get_index(arg);
2532
2533 if (index == INVALID_PTN)
2534 {
2535 dprintf(CRITICAL, "Invalid partition index\n");
2536 return;
2537 }
2538
2539 ptn = partition_get_offset(index);
2540
2541 if(!ptn)
2542 {
2543 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
2544 return;
2545 }
2546
2547 size = partition_get_size(index);
2548
2549 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
2550 return;
2551}
2552
2553/*
2554 * Publish the partition type & size info
2555 * fastboot getvar will publish the required information.
2556 * fastboot getvar partition_size:<partition_name>: partition size in hex
2557 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
2558 */
2559static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
2560{
Mayank Grover429012c2017-10-27 13:07:59 +05302561 uint8_t i,n;
2562 struct partition_entry *ptn_entry =
2563 partition_get_partition_entries();
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07002564
2565 for (i = 0; i < num_parts; i++) {
Mayank Grover429012c2017-10-27 13:07:59 +05302566 strlcat(info[i].part_name, (char const *)ptn_entry[i].name, MAX_RSP_SIZE);
2567 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
2568 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
2569
2570 /* Mark partiton type for known paritions only */
2571 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
2572 {
2573 if (!strncmp(part_type_known[n].part_name, info[i].part_name,
2574 strlen(part_type_known[n].part_name)))
2575 {
2576 strlcat(info[i].type_response,
2577 part_type_known[n].type_response,
2578 MAX_RSP_SIZE);
2579 break;
2580 }
2581 }
2582
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07002583 get_partition_size(info[i].part_name, info[i].size_response);
2584
2585 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
2586 {
2587 dprintf(CRITICAL, "partition size name truncated\n");
2588 return;
2589 }
2590 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
2591 {
2592 dprintf(CRITICAL, "partition type name truncated\n");
2593 return;
2594 }
2595
2596 /* publish partition size & type info */
2597 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
2598 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
2599 }
2600}
2601
Amol Jadi5edf3552013-07-23 14:15:34 -07002602/* register commands and variables for fastboot */
2603void aboot_fastboot_register_commands(void)
2604{
Sridhar Parasuram901bb702014-10-24 14:06:03 -07002605 int i;
Amol Jadi5edf3552013-07-23 14:15:34 -07002606
Sridhar Parasuram901bb702014-10-24 14:06:03 -07002607 struct fastboot_cmd_desc cmd_list[] = {
2608 /* By default the enabled list is empty. */
2609 {"", NULL},
2610 /* move commands enclosed within the below ifndef to here
2611 * if they need to be enabled in user build.
2612 */
2613#ifndef DISABLE_FASTBOOT_CMDS
2614 /* Register the following commands only for non-user builds */
2615 {"flash:", cmd_flash},
2616 {"erase:", cmd_erase},
2617 {"boot", cmd_boot},
2618 {"continue", cmd_continue},
2619 {"reboot", cmd_reboot},
2620 {"reboot-bootloader", cmd_reboot_bootloader},
2621 {"oem unlock", cmd_oem_unlock},
Sridhar Parasuram78344412015-08-29 11:13:07 -07002622 {"oem lock", cmd_oem_lock},
Sridhar Parasuram901bb702014-10-24 14:06:03 -07002623 {"oem device-info", cmd_oem_devinfo},
2624 {"preflash", cmd_preflash},
2625 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
2626 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
2627 {"oem select-display-panel", cmd_oem_select_display_panel},
2628#endif
2629 };
2630
2631 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
2632 for (i = 1; i < fastboot_cmds_count; i++)
2633 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
2634
Amol Jadi5edf3552013-07-23 14:15:34 -07002635 /* publish variables and their values */
2636 fastboot_publish("product", TARGET(BOARD));
2637 fastboot_publish("kernel", "lk");
2638 fastboot_publish("serialno", sn_buf);
2639
2640 /*
2641 * partition info is supported only for emmc partitions
2642 * Calling this for NAND prints some error messages which
2643 * is harmless but misleading. Avoid calling this for NAND
2644 * devices.
2645 */
2646 if (target_is_emmc_boot())
Mayank Grover429012c2017-10-27 13:07:59 +05302647 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07002648
2649 /* Max download size supported */
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002650 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
2651 target_get_max_flash_size());
Amol Jadi5edf3552013-07-23 14:15:34 -07002652 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002653 /* Is the charger screen check enabled */
2654 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
2655 device.charger_screen_enabled);
2656 fastboot_publish("charger-screen-enabled",
2657 (const char *) charger_screen_enabled);
Unnati Gandhi15d08f92014-01-24 11:01:01 +05302658 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
2659 device.display_panel);
2660 fastboot_publish("display-panel",
2661 (const char *) panel_display_mode);
Amol Jadi5edf3552013-07-23 14:15:34 -07002662}
2663
Brian Swetland9c4c0752009-01-25 16:23:50 -08002664void aboot_init(const struct app_descriptor *app)
2665{
Shashank Mittal4f99a882010-02-01 13:58:50 -08002666 unsigned reboot_mode = 0;
Pavel Nedev5d91d412013-04-29 11:34:24 +03002667 bool boot_into_fastboot = false;
Chandan Uddarajubedca152010-06-02 23:05:15 -07002668
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002669 /* Setup page size information for nand/emmc reads */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002670 if (target_is_emmc_boot())
2671 {
2672 page_size = 2048;
2673 page_mask = page_size - 1;
2674 }
2675 else
2676 {
2677 page_size = flash_page_size();
2678 page_mask = page_size - 1;
2679 }
2680
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002681 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
2682
Ameya Thakur11cf1a62013-08-05 12:44:48 -07002683 read_device_info(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07002684
Aravind Venkateswarandb0d5262014-02-25 16:25:30 -08002685 /* Display splash screen if enabled */
2686#if DISPLAY_SPLASH_SCREEN
2687 dprintf(SPEW, "Display Init: Start\n");
Unnati Gandhi15d08f92014-01-24 11:01:01 +05302688 target_display_init(device.display_panel);
Aravind Venkateswarandb0d5262014-02-25 16:25:30 -08002689 dprintf(SPEW, "Display Init: Done\n");
2690#endif
2691
2692
Greg Griscod6250552011-06-29 14:40:23 -07002693 target_serialno((unsigned char *) sn_buf);
Ajay Dudanib06c05f2011-05-12 14:46:10 -07002694 dprintf(SPEW,"serial number: %s\n",sn_buf);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08002695
Dhaval Patel223ec952013-07-18 14:49:44 -07002696 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
2697
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002698 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07002699 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07002700 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03002701 dprintf(ALWAYS,"dload mode key sequence detected\n");
2702 if (set_download_mode(EMERGENCY_DLOAD))
Ameya Thakur0b9c2442013-05-10 13:22:56 -07002703 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03002704 dprintf(CRITICAL,"dload mode not supported by target\n");
Ameya Thakur0b9c2442013-05-10 13:22:56 -07002705 }
2706 else
2707 {
2708 reboot_device(0);
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03002709 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
Ameya Thakur0b9c2442013-05-10 13:22:56 -07002710 }
2711 boot_into_fastboot = true;
2712 }
2713 if (!boot_into_fastboot)
2714 {
2715 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
2716 boot_into_recovery = 1;
2717 if (!boot_into_recovery &&
2718 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03002719 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07002720 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002721 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07002722 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03002723 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002724 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07002725
Ajay Dudani77421292010-10-27 19:34:06 -07002726 reboot_mode = check_reboot_mode();
2727 if (reboot_mode == RECOVERY_MODE) {
2728 boot_into_recovery = 1;
2729 } else if(reboot_mode == FASTBOOT_MODE) {
Pavel Nedev5d91d412013-04-29 11:34:24 +03002730 boot_into_fastboot = true;
Sridhar Parasuram78344412015-08-29 11:13:07 -07002731#if VERIFIED_BOOT
2732 } else if(reboot_mode == DM_VERITY_ENFORCING) {
2733 device.verity_mode = 1;
2734 write_device_info(&device);
2735 } else if(reboot_mode == DM_VERITY_LOGGING) {
2736 device.verity_mode = 0;
2737 write_device_info(&device);
2738 } else if(reboot_mode == DM_VERITY_KEYSCLEAR) {
2739 if(send_delete_keys_to_tz())
2740 ASSERT(0);
2741#endif
Ajay Dudani77421292010-10-27 19:34:06 -07002742 }
2743
Pavel Nedev5d91d412013-04-29 11:34:24 +03002744 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002745 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03002746 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07002747 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03002748 if(emmc_recovery_init())
2749 dprintf(ALWAYS,"error in emmc_recovery_init\n");
2750 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07002751 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03002752 if((device.is_unlocked) || (device.is_tampered))
2753 {
2754 #ifdef TZ_TAMPER_FUSE
2755 set_tamper_fuse_cmd();
2756 #endif
2757 #if USE_PCOM_SECBOOT
2758 set_tamper_flag(device.is_tampered);
2759 #endif
2760 }
Shashank Mittala0032282011-08-26 14:50:11 -07002761 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03002762 boot_linux_from_mmc();
Shashank Mittala0032282011-08-26 14:50:11 -07002763 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03002764 else
2765 {
2766 recovery_init();
2767 #if USE_PCOM_SECBOOT
2768 if((device.is_unlocked) || (device.is_tampered))
2769 set_tamper_flag(device.is_tampered);
2770 #endif
2771 boot_linux_from_flash();
2772 }
2773 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
2774 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07002775 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07002776
Amol Jadi5edf3552013-07-23 14:15:34 -07002777 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07002778
Amol Jadi5edf3552013-07-23 14:15:34 -07002779 /* register aboot specific fastboot commands */
2780 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07002781
Amol Jadi5edf3552013-07-23 14:15:34 -07002782 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07002783 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07002784
2785 /* initialize and start fastboot */
2786 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Brian Swetland9c4c0752009-01-25 16:23:50 -08002787}
2788
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07002789uint32_t get_page_size()
2790{
2791 return page_size;
2792}
2793
Amir Samuelov57a6fa22013-06-05 16:36:43 +03002794/*
2795 * Calculated and save hash (SHA256) for non-signed boot image.
2796 *
2797 * Hash the same data that is checked on the signed boot image.
2798 * Kernel and Ramdisk are already read to memory buffers.
2799 * Need to read the entire device-tree from mmc
2800 * since non-signed image only read the DT tags of the relevant platform.
2801 *
2802 * @param kernel_addr - kernel bufer
2803 * @param kernel_actual - kernel size in bytes
2804 * @param ramdisk_addr - ramdisk buffer
2805 * @param ramdisk_actual - ramdisk size
2806 * @param ptn - partition
2807 * @param dt_offset - device tree offset on mmc partition
2808 * @param dt_size
2809 *
2810 * @return int - 0 on success, negative value on failure.
2811 */
2812int aboot_save_boot_hash_mmc(void *kernel_addr, unsigned kernel_actual,
2813 void *ramdisk_addr, unsigned ramdisk_actual,
2814 unsigned long long ptn,
2815 unsigned dt_offset, unsigned dt_size)
2816{
2817 SHA256_CTX sha256_ctx;
2818 char digest[32]={0};
2819 char *buf = (char *)target_get_scratch_address();
2820 unsigned dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
2821 unsigned imagesize_actual = page_size + kernel_actual + ramdisk_actual + dt_actual;
2822
2823 SHA256_Init(&sha256_ctx);
2824
2825 /* Read Boot Header */
2826 if (mmc_read(ptn, buf, page_size))
2827 {
2828 dprintf(CRITICAL, "ERROR: mmc_read() fail.\n");
2829 return -1;
2830 }
2831 /* Read entire Device Tree */
2832 if (mmc_read(ptn + dt_offset, buf+page_size, dt_actual))
2833 {
2834 dprintf(CRITICAL, "ERROR: mmc_read() fail.\n");
2835 return -1;
2836 }
2837 SHA256_Update(&sha256_ctx, buf, page_size); // Boot Header
2838 SHA256_Update(&sha256_ctx, kernel_addr, kernel_actual);
2839 SHA256_Update(&sha256_ctx, ramdisk_addr, ramdisk_actual);
2840 SHA256_Update(&sha256_ctx, buf+page_size, dt_actual); // Device Tree
2841
2842 SHA256_Final(digest, &sha256_ctx);
2843
2844 save_kernel_hash_cmd(digest);
2845 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) imagesize_actual);
2846
2847 return 0;
2848}
2849
Brian Swetland9c4c0752009-01-25 16:23:50 -08002850APP_START(aboot)
2851 .init = aboot_init,
2852APP_END