blob: 7341c8c20fca10ab41ee23c57b87899059120e59 [file] [log] [blame]
Brian Swetland9c4c0752009-01-25 16:23:50 -08001/*
2 * Copyright (c) 2009, Google Inc.
3 * All rights reserved.
4 *
Rahul Shaharee7baede2021-02-02 13:23:57 +05305 * Copyright (c) 2009-2021, 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 Kadabifc3b31f2014-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>
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +020043#include <dev/flash-ubi.h>
Dima Zavin214cc642009-01-26 11:16:21 -080044#include <lib/ptable.h>
Dima Zavinb4283602009-01-26 16:36:57 -080045#include <dev/keys.h>
Shashank Mittal4f99a882010-02-01 13:58:50 -080046#include <dev/fbcon.h>
Ajay Dudanid04110c2011-01-17 23:55:07 -080047#include <baseband.h>
Greg Griscod6250552011-06-29 14:40:23 -070048#include <target.h>
49#include <mmc.h>
Kinson Chikf1a43512011-07-14 11:28:39 -070050#include <partition_parser.h>
Mayank Grover351a75e2017-05-30 20:06:08 +053051#include <ab_partition_parser.h>
Monika Singh292b3e92018-03-17 22:40:23 +053052#include <verifiedboot.h>
Greg Griscod6250552011-06-29 14:40:23 -070053#include <platform.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070054#include <crypto_hash.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070055#include <malloc.h>
Amol Jadi492d5a52013-03-15 16:12:34 -070056#include <boot_stats.h>
Amir Samuelov57a6fa22013-06-05 16:36:43 +030057#include <sha.h>
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -070058#include <platform/iomap.h>
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -070059#include <boot_device.h>
Shashank Mittald3e54dd2014-08-28 15:24:02 -070060#include <boot_verifier.h>
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +053061#include <image_verify.h>
Matthew Qinbb7923d2015-02-09 10:56:09 +080062#include <decompress.h>
Unnati Gandhi17b3bfc2015-05-11 12:58:16 +053063#include <platform/timer.h>
lijuang511a2b52015-08-14 20:50:51 +080064#include <sys/types.h>
Channagoud Kadabi036c6052015-02-09 15:19:59 -080065#if USE_RPMB_FOR_DEVINFO
66#include <rpmb.h>
67#endif
Dima Zavin214cc642009-01-26 11:16:21 -080068
Channagoud Kadabi90869ce2015-04-27 11:15:14 -070069#if ENABLE_WBC
Umang Chheda4c140de2019-12-19 14:30:38 +053070#include <pm_smbchg_common.h>
Channagoud Kadabi90869ce2015-04-27 11:15:14 -070071#endif
72
Neeti Desai17379b82012-06-04 18:42:53 -070073#if DEVICE_TREE
74#include <libfdt.h>
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070075#include <dev_tree.h>
Neeti Desai17379b82012-06-04 18:42:53 -070076#endif
77
Aparna Mallavarapu118ccae2015-06-03 13:47:11 +053078#if WDOG_SUPPORT
79#include <wdog.h>
80#endif
81
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -070082#include <reboot.h>
Shashank Mittalcd98d472011-08-02 14:29:24 -070083#include "image_verify.h"
Shashank Mittal024c0332010-02-03 11:44:00 -080084#include "recovery.h"
Brian Swetland9c4c0752009-01-25 16:23:50 -080085#include "bootimg.h"
86#include "fastboot.h"
Ajay Dudani5c761132011-04-07 20:19:04 -070087#include "sparse_format.h"
Ajay Dudanide984792015-03-02 09:57:41 -080088#include "meta_format.h"
Greg Grisco6e754772011-06-23 12:19:39 -070089#include "mmc.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070090#include "devinfo.h"
Neeti Desai465491e2012-07-31 12:53:35 -070091#include "board.h"
Shashank Mittal162244e2011-08-08 19:01:25 -070092#include "scm.h"
Amit Blay6281ebc2015-01-11 14:44:08 +020093#include "mdtp.h"
Sridhar Parasuram32b30662015-07-10 13:33:22 -070094#include "secapp_loader.h"
lijuanga40d6302015-07-20 20:10:13 +080095#include <menu_keys_detect.h>
96#include <display_menu.h>
Channagoud Kadabi736c4962015-08-21 11:56:52 -070097#include "fastboot_test.h"
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -070098
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -070099extern bool target_use_signed_kernel(void);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700100extern void platform_uninit(void);
Channagoud Kadabi33defe22013-06-18 18:35:40 -0700101extern void target_uninit(void);
Joonwoo Park61112782013-10-02 19:50:39 -0700102extern int get_target_boot_params(const char *cmdline, const char *part,
vijay kumar870515d2015-08-31 16:37:24 +0530103 char **buf);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700104
Sridhar Parasuram7e16d172015-07-05 11:35:23 -0700105void *info_buf;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -0700106void write_device_info_mmc(device_info *dev);
107void write_device_info_flash(device_info *dev);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -0700108static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size);
Channagoud Kadabiad259832015-05-29 11:14:17 -0700109static int aboot_frp_unlock(char *pname, void *data, unsigned sz);
Kishor PK38ed93d2017-04-25 14:19:26 +0530110static inline uint64_t validate_partition_size();
Parth Dixit54ac3bb2017-03-07 15:52:48 +0530111bool pwr_key_is_pressed = false;
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530112static bool is_systemd_present=false;
Mayank Grover351a75e2017-05-30 20:06:08 +0530113static void publish_getvar_multislot_vars();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700114/* fastboot command function pointer */
115typedef void (*fastboot_cmd_fn) (const char *, void *, unsigned);
Monika Singh292b3e92018-03-17 22:40:23 +0530116bool get_perm_attr_status();
Sridhar Parasurame94e8152014-10-24 14:06:03 -0700117
118struct fastboot_cmd_desc {
119 char * name;
120 fastboot_cmd_fn cb;
121};
122
Subbaraman Narayanamurthyeb92bcc2010-07-20 14:32:46 -0700123#define EXPAND(NAME) #NAME
124#define TARGET(NAME) EXPAND(NAME)
Brian Swetland2defe162009-08-18 14:35:59 -0700125
Ajay Singh Parmara7865a82015-04-16 21:27:52 -0700126#define DISPLAY_PANEL_HDMI "hdmi"
127
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800128#ifdef MEMBASE
129#define EMMC_BOOT_IMG_HEADER_ADDR (0xFF000+(MEMBASE))
130#else
David Ng183a7422009-12-07 14:55:21 -0800131#define EMMC_BOOT_IMG_HEADER_ADDR 0xFF000
Ajay Dudanicd01f9b2010-02-23 21:13:04 -0800132#endif
133
Deepa Dinamani0e163a42013-05-24 17:08:15 -0700134#ifndef MEMSIZE
135#define MEMSIZE 1024*1024
136#endif
137
138#define MAX_TAGS_SIZE 1024
Kishor PKee5c0a32018-03-06 16:49:46 +0530139#define PLL_CODES_OFFSET 4096
Kun Liang2f1601a2013-08-12 16:29:54 +0800140/* make 4096 as default size to ensure EFS,EXT4's erasing */
141#define DEFAULT_ERASE_SIZE 4096
Ujwal Patelc0b0a252015-08-16 14:05:35 -0700142#define MAX_PANEL_BUF_SIZE 196
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +0530143#define FOOTER_SIZE 16384
Kun Liang2f1601a2013-08-12 16:29:54 +0800144
Dhaval Patelf83d73b2014-06-23 16:24:37 -0700145#define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700146#define BOOT_DEV_MAX_LEN 64
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -0800147
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800148#define IS_ARM64(ptr) (ptr->magic_64 == KERNEL64_HDR_MAGIC) ? true : false
149
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -0700150#define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
151
Ameya Thakur10a33452016-06-13 14:24:26 -0700152//Size of the header that is used in case the boot image has
153//a uncompressed kernel + appended dtb
154#define PATCHED_KERNEL_HEADER_SIZE 20
155
156//String used to determine if the boot image has
157//a uncompressed kernel + appended dtb
158#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
159
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800160#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700161static const char *emmc_cmdline = " androidboot.bootdevice=";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700162#else
David Ng183a7422009-12-07 14:55:21 -0800163static const char *emmc_cmdline = " androidboot.emmc=true";
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700164#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530165static const char *dynamic_bootdev_cmdline =
166 " androidboot.boot_devices=soc/";
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800167static const char *usb_sn_cmdline = " androidboot.serialno=";
Pavel Nedev328ac822013-04-05 15:25:11 +0300168static const char *androidboot_mode = " androidboot.mode=";
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530169
170static const char *systemd_ffbm_mode = " systemd.unit=ffbm.target";
Matthew Qind886f3c2014-01-17 16:52:01 +0800171static const char *alarmboot_cmdline = " androidboot.alarmboot=true";
Pavel Nedev898298c2013-02-27 12:36:09 -0800172static const char *loglevel = " quiet";
Ajay Dudanica3a33c2011-11-18 08:31:40 -0800173static const char *battchg_pause = " androidboot.mode=charger";
Shashank Mittalcd98d472011-08-02 14:29:24 -0700174static const char *auth_kernel = " androidboot.authorized_kernel=true";
Pavel Nedev5614d222013-06-17 18:01:02 +0300175static const char *secondary_gpt_enable = " gpt";
Monika Singh292b3e92018-03-17 22:40:23 +0530176#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200177static const char *mdtp_activated_flag = " mdtp";
Monika Singh292b3e92018-03-17 22:40:23 +0530178#endif
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800179static const char *baseband_apq = " androidboot.baseband=apq";
180static const char *baseband_msm = " androidboot.baseband=msm";
181static const char *baseband_csfb = " androidboot.baseband=csfb";
182static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
Ajay Dudani403bc492011-09-30 16:17:21 -0700183static const char *baseband_mdm = " androidboot.baseband=mdm";
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800184static const char *baseband_mdm2 = " androidboot.baseband=mdm2";
Amol Jadi5c61a952012-05-04 17:05:35 -0700185static const char *baseband_sglte = " androidboot.baseband=sglte";
Amol Jadi2a15a272013-01-22 12:03:36 -0800186static const char *baseband_dsda = " androidboot.baseband=dsda";
187static const char *baseband_dsda2 = " androidboot.baseband=dsda2";
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800188static const char *baseband_sglte2 = " androidboot.baseband=sglte2";
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800189static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530190static const char *baseband_apq_nowgr = " androidboot.baseband=baseband_apq_nowgr";
Mayank Grover351a75e2017-05-30 20:06:08 +0530191static const char *androidboot_slot_suffix = " androidboot.slot_suffix=";
192static const char *skip_ramfs = " skip_initramfs";
Mayank Grover466d6562018-05-10 14:52:20 +0530193
194#if HIBERNATION_SUPPORT
195static const char *resume = " resume=/dev/mmcblk0p";
196#endif
197
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530198#ifdef INIT_BIN_LE
199static const char *sys_path_cmdline = " rootwait ro init="INIT_BIN_LE;
200#else
Mayank Grover3804be72017-06-22 11:59:23 +0530201static const char *sys_path_cmdline = " rootwait ro init=/init";
Sourabh Banerjee6c7153c2018-03-20 01:21:57 +0530202#endif
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530203
204#if VERITY_LE
205static const char *verity_dev = " root=/dev/dm-0";
206static const char *verity_system_part = " dm=\"system";
207static const char *verity_params = " none ro,0 1 android-verity /dev/mmcblk0p";
208#else
Mayank Grover5384ed82018-05-09 12:09:24 +0530209static const char *sys_path = " root=/dev/mmcblk0p";
lijuang83ef4b22018-08-23 11:01:55 +0800210
211#define MAX_DTBO_IDX_STR 64
212static const char *android_boot_dtbo_idx = " androidboot.dtbo_idx=";
Parth Dixit1375d9e2019-07-08 20:56:13 +0530213
214#define MAX_DTB_IDX_STR MAX_DTBO_IDX_STR
215static const char *android_boot_dtb_idx = " androidboot.dtb_idx=";
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530216#endif
Ajay Dudanid04110c2011-01-17 23:55:07 -0800217
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700218#if VERIFIED_BOOT
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700219static const char *verity_mode = " androidboot.veritymode=";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700220static const char *verified_state= " androidboot.verifiedbootstate=";
Parth Dixita5715a02015-10-29 12:25:10 +0530221static const char *keymaster_v1= " androidboot.keymaster=1";
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700222//indexed based on enum values, green is 0 by default
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700223
224struct verified_boot_verity_mode vbvm[] =
225{
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700226#if ENABLE_VB_ATTEST
227 {false, "eio"},
228#else
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700229 {false, "logging"},
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700230#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -0700231 {true, "enforcing"},
232};
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700233struct verified_boot_state_name vbsn[] =
234{
235 {GREEN, "green"},
236 {ORANGE, "orange"},
237 {YELLOW,"yellow"},
238 {RED,"red" },
239};
240#endif
Channagoud Kadabi86b0c112016-03-16 19:23:16 -0700241/*As per spec delay wait time before shutdown in Red state*/
242#define DELAY_WAIT 30000
Ashish Bhimanpalliwar8cb34fd2020-11-12 19:26:41 +0530243static unsigned page_size = BOARD_KERNEL_PAGESIZE;
244
245uint32_t kernel_hdr_page_size()
246{
247 return page_size;
248}
249
250
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700251static unsigned page_mask = 0;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +0530252static unsigned mmc_blocksize = 0;
253static unsigned mmc_blocksize_mask = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700254static char ffbm_mode_string[FFBM_MODE_BUF_SIZE];
255static bool boot_into_ffbm;
vijay kumar870515d2015-08-31 16:37:24 +0530256static char *target_boot_params = NULL;
Matthew Qind886f3c2014-01-17 16:52:01 +0800257static bool boot_reason_alarm;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -0700258static bool devinfo_present = true;
Channagoud Kadabi736c4962015-08-21 11:56:52 -0700259bool boot_into_fastboot = false;
Parth Dixit4097b622016-03-15 14:42:27 +0530260static uint32_t dt_size = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530261static char *vbcmdline;
262static bootinfo info = {0};
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530263static void *recovery_dtbo_buf = NULL;
264static uint32_t recovery_dtbo_size = 0;
265
Shashank Mittalcd98d472011-08-02 14:29:24 -0700266/* Assuming unauthorized kernel image by default */
267static int auth_kernel_img = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530268static device_info device = {DEVICE_MAGIC,0,0,0,0,{0},{0},{0},1,{0},0,{0}};
269
vijay kumarc65876c2015-04-24 13:29:16 +0530270static bool is_allow_unlock = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -0700271
vijay kumarca2e6812015-07-08 20:28:25 +0530272static char frp_ptns[2][8] = {"config","frp"};
273
lijuang511a2b52015-08-14 20:50:51 +0800274static const char *critical_flash_allowed_ptn[] = {
275 "aboot",
276 "rpm",
277 "tz",
278 "sbl",
279 "sdi",
280 "sbl1",
281 "xbl",
282 "hyp",
283 "pmic",
284 "bootloader",
285 "devinfo",
286 "partition"};
287
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +0530288static const char *VirtualAbCriticalPartitions[] = {
289 "misc",
290 "metadata",
291 "userdata"};
292
293static bool CheckVirtualAbCriticalPartition (const char *PartitionName);
294
Rahul Shaharee7baede2021-02-02 13:23:57 +0530295static const char *VabSnapshotMergeStatus[] = {
296 "none",
297 "unknown",
298 "snapshotted",
299 "merging",
300 "cancelled"};
301
Dima Zavin42168f22009-01-30 11:52:22 -0800302struct atag_ptbl_entry
303{
304 char name[16];
305 unsigned offset;
306 unsigned size;
307 unsigned flags;
308};
309
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700310/*
311 * Partition info, required to be published
312 * for fastboot
313 */
314struct getvar_partition_info {
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530315 char part_name[MAX_GPT_NAME_SIZE]; /* Partition name */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700316 char getvar_size[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for size */
317 char getvar_type[MAX_GET_VAR_NAME_SIZE]; /* fastboot get var name for type */
318 char size_response[MAX_RSP_SIZE]; /* fastboot response for size */
319 char type_response[MAX_RSP_SIZE]; /* fastboot response for type */
320};
321
322/*
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530323 * Update the part_type_known for known paritions types.
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700324 */
Mayank Groverd38fe012018-03-13 15:33:16 +0530325#define RAW_STR "raw"
Mayank Grover52cd10a2018-03-15 12:57:54 +0530326#define EXT_STR "ext4"
327#define F2FS_STR "f2fs"
328
329#define FS_SUPERBLOCK_OFFSET 0x400
330#define EXT_MAGIC 0xEF53
331#define EXT_MAGIC_OFFSET_SB 0x38
332#define F2FS_MAGIC 0xF2F52010 // F2FS Magic Number
333#define F2FS_MAGIC_OFFSET_SB 0x0
334
335typedef enum fs_signature_type {
336 EXT_FS_SIGNATURE = 1,
337 EXT_F2FS_SIGNATURE = 2,
338 NO_FS = -1
339} fs_signature_type;
340
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530341struct getvar_partition_info part_info[NUM_PARTITIONS];
342struct getvar_partition_info part_type_known[] =
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700343{
Mayank Grover49920212018-02-09 18:15:55 +0530344 { "system" , "partition-size:", "partition-type:", "", "ext4" },
345 { "userdata" , "partition-size:", "partition-type:", "", "ext4" },
346 { "cache" , "partition-size:", "partition-type:", "", "ext4" },
347 { "recoveryfs" , "partition-size:", "partition-type:", "", "ext4" },
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -0700348};
349
350char max_download_size[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -0700351char charger_screen_enabled[MAX_RSP_SIZE];
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800352char sn_buf[13];
Dhaval Patel223ec952013-07-18 14:49:44 -0700353char display_panel_buf[MAX_PANEL_BUF_SIZE];
Unnati Gandhi62c8ab82014-01-24 11:01:01 +0530354char panel_display_mode[MAX_RSP_SIZE];
Mayank Grovera64dfbe2018-05-17 14:06:34 +0530355char soc_version_str[MAX_RSP_SIZE];
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530356char block_size_string[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +0530357static char SnapshotMergeState[MAX_RSP_SIZE];
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +0530358#if PRODUCT_IOT
Mayank Grover7b8a8f82017-10-27 13:07:59 +0530359
360/* For IOT we are using custom version */
361#define PRODUCT_IOT_VERSION "IOT001"
362char bootloader_version_string[MAX_RSP_SIZE];
363#endif
lijuang102dfa92015-10-09 18:31:03 +0800364
365#if CHECK_BAT_VOLTAGE
lijuang65c5a822015-08-29 16:35:36 +0800366char battery_voltage[MAX_RSP_SIZE];
lijuang102dfa92015-10-09 18:31:03 +0800367char battery_soc_ok [MAX_RSP_SIZE];
368#endif
369
lijuangf16461c2015-08-03 17:09:34 +0800370char get_variant[MAX_RSP_SIZE];
Greg Griscod6250552011-06-29 14:40:23 -0700371
Greg Griscod2471ef2011-07-14 13:00:42 -0700372extern int emmc_recovery_init(void);
373
Kinson Chik0b1c8162011-08-31 16:31:57 -0700374#if NO_KEYPAD_DRIVER
375extern int fastboot_trigger(void);
376#endif
Greg Griscod2471ef2011-07-14 13:00:42 -0700377
Mayank Grovere1ab96c2018-09-04 20:31:31 +0530378static void update_ker_tags_rdisk_addr(boot_img_hdr *hdr, bool is_arm64)
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700379{
380 /* overwrite the destination of specified for the project */
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700381#ifdef ABOOT_IGNORE_BOOT_HEADER_ADDRS
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -0800382 if (is_arm64)
383 hdr->kernel_addr = ABOOT_FORCE_KERNEL64_ADDR;
384 else
385 hdr->kernel_addr = ABOOT_FORCE_KERNEL_ADDR;
Channagoud Kadabi7042fa32013-04-26 16:44:14 -0700386 hdr->ramdisk_addr = ABOOT_FORCE_RAMDISK_ADDR;
387 hdr->tags_addr = ABOOT_FORCE_TAGS_ADDR;
Channagoud Kadabia22144f2013-03-20 11:49:01 -0700388#endif
389}
390
Dima Zavin42168f22009-01-30 11:52:22 -0800391static void ptentry_to_tag(unsigned **ptr, struct ptentry *ptn)
392{
393 struct atag_ptbl_entry atag_ptn;
394
395 memcpy(atag_ptn.name, ptn->name, 16);
396 atag_ptn.name[15] = '\0';
397 atag_ptn.offset = ptn->start;
398 atag_ptn.size = ptn->length;
399 atag_ptn.flags = ptn->flags;
400 memcpy(*ptr, &atag_ptn, sizeof(struct atag_ptbl_entry));
401 *ptr += sizeof(struct atag_ptbl_entry) / sizeof(unsigned);
402}
Mayank Grover9df84c02018-08-30 15:46:35 +0530403#ifdef VERIFIED_BOOT_2
404void load_vbmeta_image(void **vbmeta_image_buf, uint32_t *vbmeta_image_sz)
405{
406 int index = 0;
407 char *vbm_img_buf = NULL;
408 unsigned long long ptn = 0;
409 unsigned long long ptn_size = 0;
410
411 /* Immediately return if dtbo is not supported */
412 index = partition_get_index("vbmeta");
413 ptn = partition_get_offset(index);
414 if(!ptn)
415 {
416 dprintf(CRITICAL, "ERROR: vbmeta partition not found.\n");
417 return;
418 }
419
420 ptn_size = partition_get_size(index);
421 if (ptn_size > MAX_SUPPORTED_VBMETA_IMG_BUF)
422 {
423 dprintf(CRITICAL, "ERROR: vbmeta parition size is greater than supported.\n");
424 return;
425 }
426
427 vbm_img_buf = (char *)memalign(CACHE_LINE, ROUNDUP((uint32_t)ptn_size, CACHE_LINE));
428 if (!vbm_img_buf)
429 {
430 dprintf(CRITICAL, "ERROR: vbmeta unable to locate buffer\n");
431 return;
432 }
433
434 mmc_set_lun(partition_get_lun(index));
435 if (mmc_read(ptn, (uint32_t *)vbm_img_buf, (uint32_t)ptn_size))
436 {
437 dprintf(CRITICAL, "ERROR: vbmeta read failure\n");
438 free(vbm_img_buf);
439 return;
440 }
441
442 *vbmeta_image_buf = vbm_img_buf;
443 *vbmeta_image_sz = (uint32_t)ptn_size;
444 return;
445}
446#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -0800447
lijuang102dfa92015-10-09 18:31:03 +0800448#if CHECK_BAT_VOLTAGE
449void update_battery_status(void)
450{
451 snprintf(battery_voltage,MAX_RSP_SIZE, "%d",target_get_battery_voltage());
452 snprintf(battery_soc_ok ,MAX_RSP_SIZE, "%s",target_battery_soc_ok()? "yes":"no");
453}
454#endif
455
Neeti Desaie245d492012-06-01 12:52:13 -0700456unsigned char *update_cmdline(const char * cmdline)
Brian Swetland9c4c0752009-01-25 16:23:50 -0800457{
David Ng183a7422009-12-07 14:55:21 -0800458 int cmdline_len = 0;
459 int have_cmdline = 0;
Amol Jadi168b7712012-03-06 16:15:00 -0800460 unsigned char *cmdline_final = NULL;
Neeti Desaie245d492012-06-01 12:52:13 -0700461 int pause_at_bootup = 0;
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800462 bool warm_boot = false;
Pavel Nedev5614d222013-06-17 18:01:02 +0300463 bool gpt_exists = partition_gpt_exists();
Joonwoo Park61112782013-10-02 19:50:39 -0700464 int have_target_boot_params = 0;
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700465 char *boot_dev_buf = NULL;
Monika Singh292b3e92018-03-17 22:40:23 +0530466#ifdef MDTP_SUPPORT
Mayank Grover351a75e2017-05-30 20:06:08 +0530467 bool is_mdtp_activated = 0;
Monika Singh292b3e92018-03-17 22:40:23 +0530468#endif
Mayank Grover351a75e2017-05-30 20:06:08 +0530469 int current_active_slot = INVALID;
Mayank Grover3804be72017-06-22 11:59:23 +0530470 int system_ptn_index = -1;
471 unsigned int lun = 0;
472 char lun_char_base = 'a';
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530473#if VERITY_LE
474 int syspath_buflen = strlen(verity_dev)
475 + strlen(verity_system_part) + (sizeof(char) * 2) + 2
476 + strlen(verity_params) + sizeof(int) + 2;
477#else
lijuang83ef4b22018-08-23 11:01:55 +0800478 int syspath_buflen = strlen(sys_path) + sizeof(int) + 2; /*allocate buflen for largest possible string*/
479 char dtbo_idx_str[MAX_DTBO_IDX_STR] = "\0";
480 int dtbo_idx = INVALID_PTN;
Parth Dixit1375d9e2019-07-08 20:56:13 +0530481 char dtb_idx_str[MAX_DTB_IDX_STR] = "\0";
482 int dtb_idx = INVALID_PTN;
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530483#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530484 char syspath_buf[syspath_buflen];
Mayank Grover466d6562018-05-10 14:52:20 +0530485#if HIBERNATION_SUPPORT
486 int resume_buflen = strlen(resume) + sizeof(int) + 2;
487 char resume_buf[resume_buflen];
488 int swap_ptn_index = INVALID_PTN;
489#endif
490
Mayank Grover889be1b2017-09-12 20:12:23 +0530491#if VERIFIED_BOOT
492 uint32_t boot_state = RED;
493#endif
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530494
495#if USE_LE_SYSTEMD
496 is_systemd_present=true;
497#endif
498
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700499#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530500 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +0530501 {
502 boot_state = boot_verify_get_state();
503 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530504#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700505
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200506#ifdef MDTP_SUPPORT
507 mdtp_activated(&is_mdtp_activated);
508#endif /* MDTP_SUPPORT */
Dima Zavin42168f22009-01-30 11:52:22 -0800509
Brian Swetland9c4c0752009-01-25 16:23:50 -0800510 if (cmdline && cmdline[0]) {
David Ng183a7422009-12-07 14:55:21 -0800511 cmdline_len = strlen(cmdline);
512 have_cmdline = 1;
513 }
514 if (target_is_emmc_boot()) {
515 cmdline_len += strlen(emmc_cmdline);
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700516 boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530517 if (!boot_dev_buf) {
518 dprintf(CRITICAL, "ERROR: Failed to allocate boot_dev_buf\n");
519 } else {
lijuangd28587b2021-04-27 15:54:05 +0800520 platform_boot_dev_cmdline(boot_dev_buf, sizeof(char) * BOOT_DEV_MAX_LEN);
Mayank Groverb716edf2019-05-08 16:06:55 +0530521#if USE_BOOTDEV_CMDLINE
522 cmdline_len += strlen(boot_dev_buf);
Sundarajan Srinivasan3827a102013-09-10 13:57:40 -0700523#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530524 if (target_dynamic_partition_supported()) {
525 cmdline_len += strlen(dynamic_bootdev_cmdline);
526 cmdline_len += strlen(boot_dev_buf);
527 }
528 }
David Ng183a7422009-12-07 14:55:21 -0800529 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800530
531 cmdline_len += strlen(usb_sn_cmdline);
532 cmdline_len += strlen(sn_buf);
533
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700534#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530535 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700536 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530537 cmdline_len += strlen(verified_state) + strlen(vbsn[boot_state].name);
538 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
539 {
540 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
541 ASSERT(0);
542 }
543 cmdline_len += strlen(verity_mode) + strlen(vbvm[device.verity_mode].name);
544 cmdline_len += strlen(keymaster_v1);
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700545 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530546#endif
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700547
Monika Singh292b3e92018-03-17 22:40:23 +0530548
549 if (vbcmdline != NULL) {
550 dprintf(DEBUG, "UpdateCmdLine vbcmdline present len %d\n",
551 strlen(vbcmdline));
552 cmdline_len += strlen(vbcmdline);
553 }
554
Pavel Nedev5614d222013-06-17 18:01:02 +0300555 if (boot_into_recovery && gpt_exists)
556 cmdline_len += strlen(secondary_gpt_enable);
557
Monika Singh292b3e92018-03-17 22:40:23 +0530558#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200559 if(is_mdtp_activated)
560 cmdline_len += strlen(mdtp_activated_flag);
Monika Singh292b3e92018-03-17 22:40:23 +0530561#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300562 if (boot_into_ffbm) {
563 cmdline_len += strlen(androidboot_mode);
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530564
565 if(is_systemd_present)
566 cmdline_len += strlen(systemd_ffbm_mode);
567
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700568 cmdline_len += strlen(ffbm_mode_string);
Pavel Nedev898298c2013-02-27 12:36:09 -0800569 /* reduce kernel console messages to speed-up boot */
570 cmdline_len += strlen(loglevel);
Matthew Qind886f3c2014-01-17 16:52:01 +0800571 } else if (boot_reason_alarm) {
572 cmdline_len += strlen(alarmboot_cmdline);
Zhenhua Huang431dafa2015-06-30 16:13:37 +0800573 } else if ((target_build_variant_user() || device.charger_screen_enabled)
lijuang266b17d2018-08-17 18:53:42 +0800574 && target_pause_for_battery_charge() && !boot_into_recovery) {
David Ngf773dde2010-07-26 19:55:08 -0700575 pause_at_bootup = 1;
576 cmdline_len += strlen(battchg_pause);
577 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800578
Shashank Mittalcd98d472011-08-02 14:29:24 -0700579 if(target_use_signed_kernel() && auth_kernel_img) {
580 cmdline_len += strlen(auth_kernel);
581 }
582
Joonwoo Park61112782013-10-02 19:50:39 -0700583 if (get_target_boot_params(cmdline, boot_into_recovery ? "recoveryfs" :
584 "system",
vijay kumar870515d2015-08-31 16:37:24 +0530585 &target_boot_params) == 0) {
Joonwoo Park61112782013-10-02 19:50:39 -0700586 have_target_boot_params = 1;
587 cmdline_len += strlen(target_boot_params);
588 }
589
Ajay Dudanid04110c2011-01-17 23:55:07 -0800590 /* Determine correct androidboot.baseband to use */
591 switch(target_baseband())
592 {
593 case BASEBAND_APQ:
594 cmdline_len += strlen(baseband_apq);
595 break;
596
597 case BASEBAND_MSM:
598 cmdline_len += strlen(baseband_msm);
599 break;
600
601 case BASEBAND_CSFB:
602 cmdline_len += strlen(baseband_csfb);
603 break;
604
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800605 case BASEBAND_SVLTE2A:
606 cmdline_len += strlen(baseband_svlte2a);
Ajay Dudanid04110c2011-01-17 23:55:07 -0800607 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700608
609 case BASEBAND_MDM:
610 cmdline_len += strlen(baseband_mdm);
611 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700612
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800613 case BASEBAND_MDM2:
614 cmdline_len += strlen(baseband_mdm2);
615 break;
616
Amol Jadi5c61a952012-05-04 17:05:35 -0700617 case BASEBAND_SGLTE:
618 cmdline_len += strlen(baseband_sglte);
619 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530620
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800621 case BASEBAND_SGLTE2:
622 cmdline_len += strlen(baseband_sglte2);
623 break;
624
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530625 case BASEBAND_DSDA:
626 cmdline_len += strlen(baseband_dsda);
627 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800628
629 case BASEBAND_DSDA2:
630 cmdline_len += strlen(baseband_dsda2);
631 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530632 case BASEBAND_APQ_NOWGR:
633 cmdline_len += strlen(baseband_apq_nowgr);
634 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800635 }
636
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300637#if ENABLE_DISPLAY
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800638 if (cmdline) {
639 if ((strstr(cmdline, DISPLAY_DEFAULT_PREFIX) == NULL) &&
Padmanabhan Komandurubccbcdc2015-06-30 16:19:24 +0530640 target_display_panel_node(display_panel_buf,
641 MAX_PANEL_BUF_SIZE) &&
Lijuan Gao4a5b8322014-07-24 10:38:42 +0800642 strlen(display_panel_buf)) {
643 cmdline_len += strlen(display_panel_buf);
644 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700645 }
Vladislav Levenetz3cd45242017-04-05 08:58:07 +0300646#endif
Dhaval Patel223ec952013-07-18 14:49:44 -0700647
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800648 if (target_warm_boot()) {
649 warm_boot = true;
650 cmdline_len += strlen(warmboot_cmdline);
651 }
652
Mayank Grover5384ed82018-05-09 12:09:24 +0530653 if (target_uses_system_as_root() ||
654 partition_multislot_is_supported())
Mayank Grover351a75e2017-05-30 20:06:08 +0530655 {
656 current_active_slot = partition_find_active_slot();
657 cmdline_len += (strlen(androidboot_slot_suffix)+
658 strlen(SUFFIX_SLOT(current_active_slot)));
659
Mayank Grover3804be72017-06-22 11:59:23 +0530660 system_ptn_index = partition_get_index("system");
661 if (platform_boot_dev_isemmc())
662 {
Sourabh Banerjee386b1322018-02-27 09:37:28 +0530663#if VERITY_LE
664 /*
665 Condition 4: Verity and A/B both enabled
666 Eventual command line looks like:
667 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
668 ... root=/dev/dm-0 dm="system_<slot_suffix> none ro,0 1 android-verity /dev/mmcblk0p<NN>"
669 */
670 snprintf(syspath_buf, syspath_buflen, " %s %s%s %s%d\"",
671 verity_dev,
672 verity_system_part, suffix_slot[current_active_slot],
673 verity_params, system_ptn_index + 1);
674#else
675 /*
676 Condition 5: A/B enabled, but verity disabled
677 Eventual command line looks like:
678 ... androidboot.slot_suffix=<slot_suffix> ... rootfstype=ext4 ...
679 ... root=/dev/mmcblk0p<NN> ...
680 */
681 snprintf(syspath_buf, syspath_buflen, " %s%d",
682 sys_path, system_ptn_index + 1);
683#endif
Mayank Grover3804be72017-06-22 11:59:23 +0530684 }
685 else
686 {
687 lun = partition_get_lun(system_ptn_index);
688 snprintf(syspath_buf, syspath_buflen, " root=/dev/sd%c%d",
689 lun_char_base + lun,
690 partition_get_index_in_lun("system", lun));
691 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530692
Monika Singh292b3e92018-03-17 22:40:23 +0530693#ifndef VERIFIED_BOOT_2
Mayank Grover3804be72017-06-22 11:59:23 +0530694 cmdline_len += strlen(syspath_buf);
Monika Singh292b3e92018-03-17 22:40:23 +0530695#endif
Mayank Grover5384ed82018-05-09 12:09:24 +0530696 }
697
698 if (target_uses_system_as_root() ||
699 partition_multislot_is_supported())
700 {
701 cmdline_len += strlen(sys_path_cmdline);
Mayank Groverb716edf2019-05-08 16:06:55 +0530702
703 /* For dynamic partition, support skip skip_initramfs */
704 if (!target_dynamic_partition_supported() &&
705 !boot_into_recovery)
Mayank Grover351a75e2017-05-30 20:06:08 +0530706 cmdline_len += strlen(skip_ramfs);
707 }
708
Mayank Grover466d6562018-05-10 14:52:20 +0530709#if HIBERNATION_SUPPORT
710 if (platform_boot_dev_isemmc())
711 {
712 swap_ptn_index = partition_get_index("swap");
713 if (swap_ptn_index != INVALID_PTN)
714 {
715 snprintf(resume_buf, resume_buflen,
716 " %s%d", resume,
717 (swap_ptn_index + 1));
718 cmdline_len += strlen(resume_buf);
719 }
720 else
721 {
722 dprintf(INFO, "WARNING: swap partition not found\n");
723 }
724 }
725#endif
726
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800727#if TARGET_CMDLINE_SUPPORT
728 char *target_cmdline_buf = malloc(TARGET_MAX_CMDLNBUF);
729 int target_cmd_line_len;
730 ASSERT(target_cmdline_buf);
731 target_cmd_line_len = target_update_cmdline(target_cmdline_buf);
732 cmdline_len += target_cmd_line_len;
733#endif
734
lijuang83ef4b22018-08-23 11:01:55 +0800735#if !VERITY_LE
736 dtbo_idx = get_dtbo_idx ();
737 if (dtbo_idx != INVALID_PTN) {
738 snprintf(dtbo_idx_str, sizeof(dtbo_idx_str), "%s%d",
739 android_boot_dtbo_idx, dtbo_idx);
740 cmdline_len += strlen (dtbo_idx_str);
741 }
Parth Dixit1375d9e2019-07-08 20:56:13 +0530742
743 dtb_idx = get_dtb_idx ();
744 if (dtb_idx != INVALID_PTN) {
745 snprintf(dtb_idx_str, sizeof(dtb_idx_str), "%s%d",
746 android_boot_dtb_idx, dtb_idx);
747 cmdline_len += strlen (dtb_idx_str);
748 }
lijuang83ef4b22018-08-23 11:01:55 +0800749#endif
750
David Ng183a7422009-12-07 14:55:21 -0800751 if (cmdline_len > 0) {
752 const char *src;
Maria Yu52254c02014-07-04 16:14:54 +0800753 unsigned char *dst;
754
755 cmdline_final = (unsigned char*) malloc((cmdline_len + 4) & (~3));
756 ASSERT(cmdline_final != NULL);
vijay kumar287bb542015-09-29 13:01:52 +0530757 memset((void *)cmdline_final, 0, sizeof(*cmdline_final));
Maria Yu52254c02014-07-04 16:14:54 +0800758 dst = cmdline_final;
Neeti Desaie245d492012-06-01 12:52:13 -0700759
Amol Jadi168b7712012-03-06 16:15:00 -0800760 /* Save start ptr for debug print */
David Ng183a7422009-12-07 14:55:21 -0800761 if (have_cmdline) {
762 src = cmdline;
763 while ((*dst++ = *src++));
764 }
765 if (target_is_emmc_boot()) {
766 src = emmc_cmdline;
767 if (have_cmdline) --dst;
David Ngf773dde2010-07-26 19:55:08 -0700768 have_cmdline = 1;
769 while ((*dst++ = *src++));
Sridhar Parasuram7bd4aaf2015-02-12 11:14:38 -0800770#if USE_BOOTDEV_CMDLINE
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700771 src = boot_dev_buf;
Mayank Groverb716edf2019-05-08 16:06:55 +0530772 if (have_cmdline &&
773 boot_dev_buf) {
774 --dst;
775 while ((*dst++ = *src++));
776 }
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -0700777#endif
Mayank Groverb716edf2019-05-08 16:06:55 +0530778 /* Dynamic partition append boot_devices */
779 if (target_dynamic_partition_supported() &&
780 boot_dev_buf) {
781 src = dynamic_bootdev_cmdline;
782 if (have_cmdline) --dst;
783 while ((*dst++ = *src++));
784 src = boot_dev_buf;
785 if (have_cmdline) --dst;
786 while ((*dst++ = *src++));
787 }
David Ngf773dde2010-07-26 19:55:08 -0700788 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800789
Sridhar Parasuram4311b8e2015-05-28 17:01:59 -0700790#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +0530791 if (VB_M <= target_get_vb_version())
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700792 {
Mayank Grover889be1b2017-09-12 20:12:23 +0530793 src = verified_state;
794 if(have_cmdline) --dst;
795 have_cmdline = 1;
796 while ((*dst++ = *src++));
797 src = vbsn[boot_state].name;
798 if(have_cmdline) --dst;
799 while ((*dst++ = *src++));
800
801 if ((device.verity_mode != 0 ) && (device.verity_mode != 1))
802 {
803 dprintf(CRITICAL, "Devinfo paritition possibly corrupted!!!. Please erase devinfo partition to continue booting\n");
804 ASSERT(0);
805 }
806 src = verity_mode;
807 if(have_cmdline) --dst;
808 while ((*dst++ = *src++));
809 src = vbvm[device.verity_mode].name;
810 if(have_cmdline) -- dst;
811 while ((*dst++ = *src++));
812 src = keymaster_v1;
813 if(have_cmdline) --dst;
814 while ((*dst++ = *src++));
Sridhar Parasuram7d8bb9a2015-09-23 18:21:19 -0700815 }
Parth Dixitddbc7352015-10-18 03:13:31 +0530816#endif
Monika Singh292b3e92018-03-17 22:40:23 +0530817
818 if (vbcmdline != NULL) {
819 src = vbcmdline;
820 if (have_cmdline) --dst;
821 while ((*dst++ = *src++));
822 }
823
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800824 src = usb_sn_cmdline;
825 if (have_cmdline) --dst;
826 have_cmdline = 1;
827 while ((*dst++ = *src++));
828 src = sn_buf;
829 if (have_cmdline) --dst;
830 have_cmdline = 1;
831 while ((*dst++ = *src++));
Hanumant Singh8e1ac232014-01-29 13:41:51 -0800832 if (warm_boot) {
833 if (have_cmdline) --dst;
834 src = warmboot_cmdline;
835 while ((*dst++ = *src++));
836 }
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -0800837
Pavel Nedev5614d222013-06-17 18:01:02 +0300838 if (boot_into_recovery && gpt_exists) {
839 src = secondary_gpt_enable;
840 if (have_cmdline) --dst;
841 while ((*dst++ = *src++));
842 }
Monika Singh292b3e92018-03-17 22:40:23 +0530843#ifdef MDTP_SUPPORT
Shay Nachmanibc10dfe2015-02-10 14:45:55 +0200844 if (is_mdtp_activated) {
845 src = mdtp_activated_flag;
846 if (have_cmdline) --dst;
847 while ((*dst++ = *src++));
848 }
Monika Singh292b3e92018-03-17 22:40:23 +0530849#endif
Pavel Nedev328ac822013-04-05 15:25:11 +0300850 if (boot_into_ffbm) {
851 src = androidboot_mode;
852 if (have_cmdline) --dst;
853 while ((*dst++ = *src++));
Deepa Dinamani41fa8d62013-05-23 13:25:36 -0700854 src = ffbm_mode_string;
Pavel Nedev328ac822013-04-05 15:25:11 +0300855 if (have_cmdline) --dst;
856 while ((*dst++ = *src++));
Hareesh Gauthamabf1e1e2017-04-12 18:09:24 +0530857
858 if(is_systemd_present) {
859 src = systemd_ffbm_mode;
860 if (have_cmdline) --dst;
861 while ((*dst++ = *src++));
862 }
863
Pavel Nedev898298c2013-02-27 12:36:09 -0800864 src = loglevel;
865 if (have_cmdline) --dst;
866 while ((*dst++ = *src++));
Matthew Qind886f3c2014-01-17 16:52:01 +0800867 } else if (boot_reason_alarm) {
868 src = alarmboot_cmdline;
869 if (have_cmdline) --dst;
870 while ((*dst++ = *src++));
Pavel Nedev328ac822013-04-05 15:25:11 +0300871 } else if (pause_at_bootup) {
David Ngf773dde2010-07-26 19:55:08 -0700872 src = battchg_pause;
873 if (have_cmdline) --dst;
David Ng183a7422009-12-07 14:55:21 -0800874 while ((*dst++ = *src++));
875 }
Ajay Dudanid04110c2011-01-17 23:55:07 -0800876
Shashank Mittalcd98d472011-08-02 14:29:24 -0700877 if(target_use_signed_kernel() && auth_kernel_img) {
878 src = auth_kernel;
879 if (have_cmdline) --dst;
880 while ((*dst++ = *src++));
881 }
882
Ajay Dudanid04110c2011-01-17 23:55:07 -0800883 switch(target_baseband())
884 {
885 case BASEBAND_APQ:
886 src = baseband_apq;
887 if (have_cmdline) --dst;
888 while ((*dst++ = *src++));
889 break;
890
891 case BASEBAND_MSM:
892 src = baseband_msm;
893 if (have_cmdline) --dst;
894 while ((*dst++ = *src++));
895 break;
896
897 case BASEBAND_CSFB:
898 src = baseband_csfb;
899 if (have_cmdline) --dst;
900 while ((*dst++ = *src++));
901 break;
902
Ajay Dudani6cff85e2011-02-04 16:02:16 -0800903 case BASEBAND_SVLTE2A:
904 src = baseband_svlte2a;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800905 if (have_cmdline) --dst;
906 while ((*dst++ = *src++));
907 break;
Ajay Dudani403bc492011-09-30 16:17:21 -0700908
909 case BASEBAND_MDM:
910 src = baseband_mdm;
911 if (have_cmdline) --dst;
912 while ((*dst++ = *src++));
913 break;
Amol Jadi5c61a952012-05-04 17:05:35 -0700914
Sundarajan Srinivasanaaa8aff2013-11-12 17:19:14 -0800915 case BASEBAND_MDM2:
916 src = baseband_mdm2;
917 if (have_cmdline) --dst;
918 while ((*dst++ = *src++));
919 break;
920
Amol Jadi5c61a952012-05-04 17:05:35 -0700921 case BASEBAND_SGLTE:
922 src = baseband_sglte;
923 if (have_cmdline) --dst;
924 while ((*dst++ = *src++));
925 break;
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530926
sundarajan srinivasanf8e9f3f2013-03-04 15:56:58 -0800927 case BASEBAND_SGLTE2:
928 src = baseband_sglte2;
929 if (have_cmdline) --dst;
930 while ((*dst++ = *src++));
931 break;
932
Channagoud Kadabi141f2982012-10-31 11:23:02 +0530933 case BASEBAND_DSDA:
934 src = baseband_dsda;
935 if (have_cmdline) --dst;
936 while ((*dst++ = *src++));
937 break;
Amol Jadi2a15a272013-01-22 12:03:36 -0800938
939 case BASEBAND_DSDA2:
940 src = baseband_dsda2;
941 if (have_cmdline) --dst;
942 while ((*dst++ = *src++));
943 break;
Vijay Kumar Pendotib228cfc2016-06-13 20:15:23 +0530944 case BASEBAND_APQ_NOWGR:
945 src = baseband_apq_nowgr;
946 if (have_cmdline) --dst;
947 while ((*dst++ = *src++));
948 break;
Ajay Dudanid04110c2011-01-17 23:55:07 -0800949 }
Dhaval Patel223ec952013-07-18 14:49:44 -0700950
951 if (strlen(display_panel_buf)) {
Dhaval Patel223ec952013-07-18 14:49:44 -0700952 src = display_panel_buf;
953 if (have_cmdline) --dst;
954 while ((*dst++ = *src++));
955 }
Joonwoo Park61112782013-10-02 19:50:39 -0700956
957 if (have_target_boot_params) {
958 if (have_cmdline) --dst;
959 src = target_boot_params;
960 while ((*dst++ = *src++));
vijay kumar870515d2015-08-31 16:37:24 +0530961 free(target_boot_params);
Joonwoo Park61112782013-10-02 19:50:39 -0700962 }
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -0800963
Mayank Grover351a75e2017-05-30 20:06:08 +0530964 if (partition_multislot_is_supported() && have_cmdline)
965 {
966 src = androidboot_slot_suffix;
967 --dst;
968 while ((*dst++ = *src++));
969 --dst;
970 src = SUFFIX_SLOT(current_active_slot);
971 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530972 }
Mayank Grover351a75e2017-05-30 20:06:08 +0530973
Mayank Grover351a75e2017-05-30 20:06:08 +0530974
Mayank Grover5384ed82018-05-09 12:09:24 +0530975 /*
976 * System-As-Root behaviour, system.img should contain both
977 * system content and ramdisk content, and should be mounted at
978 * root(a/b).
979 * Apending skip_ramfs for non a/b builds which use, system as root.
980 */
981 if ((target_uses_system_as_root() ||
982 partition_multislot_is_supported()) &&
983 have_cmdline)
984 {
Mayank Groverb716edf2019-05-08 16:06:55 +0530985 if (!target_dynamic_partition_supported() &&
986 !boot_into_recovery)
Mayank Grover5384ed82018-05-09 12:09:24 +0530987 {
988 src = skip_ramfs;
Mayank Grover351a75e2017-05-30 20:06:08 +0530989 --dst;
990 while ((*dst++ = *src++));
Mayank Grover5384ed82018-05-09 12:09:24 +0530991 }
992
993 src = sys_path_cmdline;
994 --dst;
995 while ((*dst++ = *src++));
Mayank Grover3804be72017-06-22 11:59:23 +0530996
Monika Singh292b3e92018-03-17 22:40:23 +0530997#ifndef VERIFIED_BOOT_2
Mayank Grover5384ed82018-05-09 12:09:24 +0530998 src = syspath_buf;
999 --dst;
1000 while ((*dst++ = *src++));
Monika Singh292b3e92018-03-17 22:40:23 +05301001#endif
Mayank Grover351a75e2017-05-30 20:06:08 +05301002 }
1003
Mayank Grover466d6562018-05-10 14:52:20 +05301004#if HIBERNATION_SUPPORT
1005 if (swap_ptn_index != INVALID_PTN)
1006 {
1007 src = resume_buf;
1008 --dst;
1009 while ((*dst++ = *src++));
1010 }
1011#endif
1012
Channagoud Kadabi85c7ec32016-01-28 23:09:21 -08001013#if TARGET_CMDLINE_SUPPORT
1014 if (target_cmdline_buf && target_cmd_line_len)
1015 {
1016 if (have_cmdline) --dst;
1017 src = target_cmdline_buf;
1018 while((*dst++ = *src++));
1019 free(target_cmdline_buf);
1020 }
1021#endif
lijuang83ef4b22018-08-23 11:01:55 +08001022
1023#if !VERITY_LE
1024 if (dtbo_idx != INVALID_PTN) {
1025 src = dtbo_idx_str;
1026 --dst;
1027 while ((*dst++ = *src++));
1028 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301029
1030 if (dtb_idx != INVALID_PTN) {
1031 src = dtb_idx_str;
1032 --dst;
1033 while ((*dst++ = *src++));
1034 }
lijuang83ef4b22018-08-23 11:01:55 +08001035#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001036 }
Dhaval Patel223ec952013-07-18 14:49:44 -07001037
1038
Sundarajan Srinivasane52065a2014-03-20 16:25:59 -07001039 if (boot_dev_buf)
1040 free(boot_dev_buf);
1041
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08001042 if (cmdline_final)
1043 dprintf(INFO, "cmdline: %s\n", cmdline_final);
1044 else
1045 dprintf(INFO, "cmdline is NULL\n");
Neeti Desaie245d492012-06-01 12:52:13 -07001046 return cmdline_final;
1047}
1048
1049unsigned *atag_core(unsigned *ptr)
1050{
1051 /* CORE */
1052 *ptr++ = 2;
1053 *ptr++ = 0x54410001;
1054
1055 return ptr;
1056
1057}
1058
1059unsigned *atag_ramdisk(unsigned *ptr, void *ramdisk,
1060 unsigned ramdisk_size)
1061{
1062 if (ramdisk_size) {
1063 *ptr++ = 4;
1064 *ptr++ = 0x54420005;
1065 *ptr++ = (unsigned)ramdisk;
1066 *ptr++ = ramdisk_size;
Brian Swetland9c4c0752009-01-25 16:23:50 -08001067 }
1068
Neeti Desaie245d492012-06-01 12:52:13 -07001069 return ptr;
1070}
1071
1072unsigned *atag_ptable(unsigned **ptr_addr)
1073{
1074 int i;
1075 struct ptable *ptable;
1076
1077 if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001078 *(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
1079 sizeof(unsigned)));
Neeti Desaie245d492012-06-01 12:52:13 -07001080 *(*ptr_addr)++ = 0x4d534d70;
1081 for (i = 0; i < ptable->count; ++i)
1082 ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
1083 }
1084
1085 return (*ptr_addr);
1086}
1087
1088unsigned *atag_cmdline(unsigned *ptr, const char *cmdline)
1089{
1090 int cmdline_length = 0;
1091 int n;
Neeti Desaie245d492012-06-01 12:52:13 -07001092 char *dest;
1093
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001094 cmdline_length = strlen((const char*)cmdline);
Neeti Desaie245d492012-06-01 12:52:13 -07001095 n = (cmdline_length + 4) & (~3);
1096
1097 *ptr++ = (n / 4) + 2;
1098 *ptr++ = 0x54410009;
1099 dest = (char *) ptr;
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001100 while ((*dest++ = *cmdline++));
Neeti Desaie245d492012-06-01 12:52:13 -07001101 ptr += (n / 4);
1102
1103 return ptr;
1104}
1105
1106unsigned *atag_end(unsigned *ptr)
1107{
Brian Swetland9c4c0752009-01-25 16:23:50 -08001108 /* END */
1109 *ptr++ = 0;
1110 *ptr++ = 0;
1111
Neeti Desaie245d492012-06-01 12:52:13 -07001112 return ptr;
1113}
1114
1115void generate_atags(unsigned *ptr, const char *cmdline,
1116 void *ramdisk, unsigned ramdisk_size)
1117{
vijay kumar21a37452015-12-29 16:23:21 +05301118 unsigned *orig_ptr = ptr;
Neeti Desaie245d492012-06-01 12:52:13 -07001119 ptr = atag_core(ptr);
1120 ptr = atag_ramdisk(ptr, ramdisk, ramdisk_size);
1121 ptr = target_atag_mem(ptr);
1122
1123 /* Skip NAND partition ATAGS for eMMC boot */
1124 if (!target_is_emmc_boot()){
1125 ptr = atag_ptable(&ptr);
1126 }
1127
vijay kumar21a37452015-12-29 16:23:21 +05301128 /*
1129 * Atags size filled till + cmdline size + 1 unsigned for 4-byte boundary + 4 unsigned
1130 * for atag identifier in atag_cmdline and atag_end should be with in MAX_TAGS_SIZE bytes
1131 */
Mayank Groverbc8a2ef2018-02-23 18:03:36 +05301132 if (!cmdline)
1133 return;
1134
vijay kumar21a37452015-12-29 16:23:21 +05301135 if (((ptr - orig_ptr) + strlen(cmdline) + 5 * sizeof(unsigned)) < MAX_TAGS_SIZE) {
1136 ptr = atag_cmdline(ptr, cmdline);
1137 ptr = atag_end(ptr);
1138 }
1139 else {
1140 dprintf(CRITICAL,"Crossing ATAGs Max size allowed\n");
1141 ASSERT(0);
1142 }
Neeti Desaie245d492012-06-01 12:52:13 -07001143}
1144
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001145typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
Neeti Desaie245d492012-06-01 12:52:13 -07001146void boot_linux(void *kernel, unsigned *tags,
1147 const char *cmdline, unsigned machtype,
1148 void *ramdisk, unsigned ramdisk_size)
1149{
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001150 unsigned char *final_cmdline;
Amol Jadib6be5c12012-11-14 13:39:51 -08001151#if DEVICE_TREE
Neeti Desai17379b82012-06-04 18:42:53 -07001152 int ret = 0;
Amol Jadib6be5c12012-11-14 13:39:51 -08001153#endif
1154
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001155 void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001156 uint32_t tags_phys = PA((addr_t)tags);
vijay kumar1a50a642015-11-16 12:41:15 +05301157 struct kernel64_hdr *kptr = ((struct kernel64_hdr*)(PA((addr_t)kernel)));
Deepa Dinamani25a9f762012-11-30 15:57:15 -08001158
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301159 ramdisk = (void *)PA((addr_t)ramdisk);
Neeti Desaie245d492012-06-01 12:52:13 -07001160
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001161 final_cmdline = update_cmdline((const char*)cmdline);
1162
Neeti Desai17379b82012-06-04 18:42:53 -07001163#if DEVICE_TREE
Amol Jadib6be5c12012-11-14 13:39:51 -08001164 dprintf(INFO, "Updating device tree: start\n");
1165
Neeti Desai17379b82012-06-04 18:42:53 -07001166 /* Update the Device Tree */
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301167 ret = update_device_tree((void *)tags,(const char *)final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001168 if(ret)
1169 {
1170 dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
1171 ASSERT(0);
1172 }
Amol Jadib6be5c12012-11-14 13:39:51 -08001173 dprintf(INFO, "Updating device tree: done\n");
Neeti Desai17379b82012-06-04 18:42:53 -07001174#else
Neeti Desaie245d492012-06-01 12:52:13 -07001175 /* Generating the Atags */
Amol Jadi10c7d1c2013-01-25 13:24:29 -08001176 generate_atags(tags, final_cmdline, ramdisk, ramdisk_size);
Neeti Desai17379b82012-06-04 18:42:53 -07001177#endif
Neeti Desaie245d492012-06-01 12:52:13 -07001178
Monika Singh0ec6db82019-07-18 16:57:58 +05301179#if VERIFIED_BOOT
Monika Singhb0db4b82018-09-26 12:18:02 +05301180 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301181 {
1182 if (device.verity_mode == 0) {
lijuangbdd9bb42016-03-01 18:22:17 +08001183#if FBCON_DISPLAY_MSG
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001184#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05301185 display_bootverify_menu(DISPLAY_MENU_EIO);
1186 wait_for_users_action();
1187 if(!pwr_key_is_pressed)
1188 shutdown_device();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001189#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301190 display_bootverify_menu(DISPLAY_MENU_LOGGING);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001191#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301192 wait_for_users_action();
lijuangbdd9bb42016-03-01 18:22:17 +08001193#else
Mayank Grover889be1b2017-09-12 20:12:23 +05301194 dprintf(CRITICAL,
1195 "The dm-verity is not started in enforcing mode.\nWait for 5 seconds before proceeding\n");
1196 mdelay(5000);
lijuangbdd9bb42016-03-01 18:22:17 +08001197#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05301198 }
lijuangbdd9bb42016-03-01 18:22:17 +08001199 }
lijuangbdd9bb42016-03-01 18:22:17 +08001200#endif
1201
1202#if VERIFIED_BOOT
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001203 /* Write protect the device info */
Channagoud Kadabi3bd9d1e2015-05-05 16:18:20 -07001204 if (!boot_into_recovery && target_build_variant_user() && devinfo_present && mmc_write_protect("devinfo", 1))
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07001205 {
1206 dprintf(INFO, "Failed to write protect dev info\n");
1207 ASSERT(0);
1208 }
1209#endif
1210
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001211 /* Turn off splash screen if enabled */
1212#if DISPLAY_SPLASH_SCREEN
1213 target_display_shutdown();
1214#endif
1215
Veera Sundaram Sankaran67ea0932015-09-25 10:09:30 -07001216 /* Perform target specific cleanup */
1217 target_uninit();
Monika Singh292b3e92018-03-17 22:40:23 +05301218 free_verified_boot_resource(&info);
1219 if (final_cmdline)
1220 free(final_cmdline);
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08001221
Deepa Dinamani33734bc2013-03-06 12:16:06 -08001222 dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d), tags/device tree @ %p\n",
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301223 entry, ramdisk, ramdisk_size, (void *)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001224
1225 enter_critical_section();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001226
Amol Jadi4421e652011-06-16 15:00:48 -07001227 /* do any platform specific cleanup before kernel entry */
1228 platform_uninit();
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001229
Brian Swetland9c4c0752009-01-25 16:23:50 -08001230 arch_disable_cache(UCACHE);
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07001231
Amol Jadi504f9fe2012-08-16 13:56:48 -07001232#if ARM_WITH_MMU
Brian Swetland9c4c0752009-01-25 16:23:50 -08001233 arch_disable_mmu();
Amol Jadi504f9fe2012-08-16 13:56:48 -07001234#endif
Amol Jadi492d5a52013-03-15 16:12:34 -07001235 bs_set_timestamp(BS_KERNEL_ENTRY);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001236
1237 if (IS_ARM64(kptr))
1238 /* Jump to a 64bit kernel */
1239 scm_elexec_call((paddr_t)kernel, tags_phys);
1240 else
1241 /* Jump to a 32bit kernel */
1242 entry(0, machtype, (unsigned*)tags_phys);
Brian Swetland9c4c0752009-01-25 16:23:50 -08001243}
1244
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001245/* Function to check if the memory address range falls within the aboot
1246 * boundaries.
1247 * start: Start of the memory region
1248 * size: Size of the memory region
1249 */
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301250int check_aboot_addr_range_overlap(uintptr_t start, uint32_t size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001251{
1252 /* Check for boundary conditions. */
Sundarajan Srinivasance2a0ea2013-12-16 17:02:56 -08001253 if ((UINT_MAX - start) < size)
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001254 return -1;
1255
1256 /* Check for memory overlap. */
1257 if ((start < MEMBASE) && ((start + size) <= MEMBASE))
1258 return 0;
Channagoud Kadabi94143912013-10-15 12:53:52 -07001259 else if (start >= (MEMBASE + MEMSIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001260 return 0;
1261 else
1262 return -1;
1263}
1264
Mayank Grovere559cec2017-10-17 15:12:03 +05301265/* Function to check if the memory address range falls beyond ddr region.
1266 * start: Start of the memory region
1267 * size: Size of the memory region
1268 */
1269int check_ddr_addr_range_bound(uintptr_t start, uint32_t size)
1270{
1271 uintptr_t ddr_pa_start_addr = PA(get_ddr_start());
1272 uint64_t ddr_size = smem_get_ddr_size();
1273 uint64_t ddr_pa_end_addr = ddr_pa_start_addr + ddr_size;
1274 uintptr_t pa_start_addr = PA(start);
1275
1276 /* Check for boundary conditions. */
1277 if ((UINT_MAX - start) < size)
1278 return -1;
1279
1280 /* Check if memory range is beyond the ddr range. */
1281 if (pa_start_addr < ddr_pa_start_addr ||
1282 pa_start_addr >= (ddr_pa_end_addr) ||
1283 (pa_start_addr + size) > ddr_pa_end_addr)
1284 return -1;
1285 else
1286 return 0;
1287}
1288
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001289BUF_DMA_ALIGN(buf, BOOT_IMG_MAX_PAGE_SIZE); //Equal to max-supported pagesize
Dima Zavin214cc642009-01-26 11:16:21 -08001290
Mayank Groverdd080e82018-09-04 20:12:13 +05301291int getimage(void **image_buffer, uint32_t *imgsize,
1292 const char *imgname)
Monika Singh292b3e92018-03-17 22:40:23 +05301293{
Mayank Groverdd080e82018-09-04 20:12:13 +05301294 uint32_t loadedindex;
1295 if (image_buffer == NULL || imgsize == NULL ||
Monika Singh292b3e92018-03-17 22:40:23 +05301296 imgname == NULL) {
1297 dprintf(CRITICAL, "getimage: invalid parameters\n");
1298 return -1;
1299 }
Mayank Groverdd080e82018-09-04 20:12:13 +05301300 for (loadedindex = 0; loadedindex < info.num_loaded_images; loadedindex++) {
1301 if (!strncmp(info.images[loadedindex].name, imgname,
Monika Singh292b3e92018-03-17 22:40:23 +05301302 strlen(imgname))) {
Mayank Groverdd080e82018-09-04 20:12:13 +05301303 *image_buffer = info.images[loadedindex].image_buffer;
1304 *imgsize = info.images[loadedindex].imgsize;
Mayank Grover027a9412018-09-04 15:12:05 +05301305 dprintf(SPEW, "getimage(): Loaded image [%s|%d]\n",
1306 info.images[loadedindex].name,
1307 info.images[loadedindex].imgsize);
Monika Singh292b3e92018-03-17 22:40:23 +05301308 return 0;
1309 }
1310 }
1311 return -1;
1312}
1313
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001314static void verify_signed_bootimg(uint32_t bootimg_addr, uint32_t bootimg_size)
1315{
1316 int ret;
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001317
1318#if !VERIFIED_BOOT
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001319#if IMAGE_VERIF_ALGO_SHA1
1320 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
1321#else
1322 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
1323#endif
Channagoud Kadabia8c623f2015-01-13 14:48:48 -08001324#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001325
1326 /* Assume device is rooted at this time. */
1327 device.is_tampered = 1;
1328
1329 dprintf(INFO, "Authenticating boot image (%d): start\n", bootimg_size);
1330
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001331#if VERIFIED_BOOT
Monika Singh7d2fc272018-03-16 17:16:01 +05301332 uint32_t bootstate;
1333 if(boot_into_recovery &&
Mayank Grover68fbf0d2017-10-24 14:13:39 +05301334 (!partition_multislot_is_supported()))
Monika Singh7d2fc272018-03-16 17:16:01 +05301335 {
1336 ret = boot_verify_image((unsigned char *)bootimg_addr,
1337 bootimg_size, "/recovery", &bootstate);
1338 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001339 else
Monika Singh7d2fc272018-03-16 17:16:01 +05301340 {
1341 ret = boot_verify_image((unsigned char *)bootimg_addr,
1342 bootimg_size, "/boot", &bootstate);
1343 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001344 boot_verify_print_state();
1345#else
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001346 ret = image_verify((unsigned char *)bootimg_addr,
1347 (unsigned char *)(bootimg_addr + bootimg_size),
1348 bootimg_size,
Sundarajan Srinivasance54d6e2013-11-11 12:45:00 -08001349 auth_algo);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001350#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001351 dprintf(INFO, "Authenticating boot image: done return value = %d\n", ret);
1352
1353 if (ret)
1354 {
1355 /* Authorized kernel */
1356 device.is_tampered = 0;
Sundarajan Srinivasan3fb21f12013-09-16 18:36:15 -07001357 auth_kernel_img = 1;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001358 }
1359
Amit Blay4aa292f2015-04-28 21:55:59 +03001360#ifdef MDTP_SUPPORT
1361 {
1362 /* Verify MDTP lock.
1363 * For boot & recovery partitions, use aboot's verification result.
1364 */
1365 mdtp_ext_partition_verification_t ext_partition;
1366 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1367 ext_partition.integrity_state = device.is_tampered ? MDTP_PARTITION_STATE_INVALID : MDTP_PARTITION_STATE_VALID;
1368 ext_partition.page_size = 0; /* Not needed since already validated */
1369 ext_partition.image_addr = 0; /* Not needed since already validated */
1370 ext_partition.image_size = 0; /* Not needed since already validated */
1371 ext_partition.sig_avail = FALSE; /* Not needed since already validated */
1372 mdtp_fwlock_verify_lock(&ext_partition);
1373 }
1374#endif /* MDTP_SUPPORT */
1375
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001376#if USE_PCOM_SECBOOT
1377 set_tamper_flag(device.is_tampered);
1378#endif
1379
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001380#if VERIFIED_BOOT
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001381 switch(boot_verify_get_state())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001382 {
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001383 case RED:
lijuanga40d6302015-07-20 20:10:13 +08001384#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001385 display_bootverify_menu(DISPLAY_MENU_RED);
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001386#if ENABLE_VB_ATTEST
1387 mdelay(DELAY_WAIT);
1388 shutdown_device();
1389#else
lijuanga40d6302015-07-20 20:10:13 +08001390 wait_for_users_action();
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07001391#endif
lijuanga40d6302015-07-20 20:10:13 +08001392#else
1393 dprintf(CRITICAL,
1394 "Your device has failed verification and may not work properly.\nWait for 5 seconds before proceeding\n");
1395 mdelay(5000);
1396#endif
1397
1398 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001399 case YELLOW:
lijuanga40d6302015-07-20 20:10:13 +08001400#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08001401 display_bootverify_menu(DISPLAY_MENU_YELLOW);
lijuanga40d6302015-07-20 20:10:13 +08001402 wait_for_users_action();
1403#else
1404 dprintf(CRITICAL,
1405 "Your device has loaded a different operating system.\nWait for 5 seconds before proceeding\n");
1406 mdelay(5000);
1407#endif
1408 break;
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001409 default:
lijuanga40d6302015-07-20 20:10:13 +08001410 break;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001411 }
1412#endif
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001413#if !VERIFIED_BOOT
Unnati Gandhi1be04752015-03-27 19:41:53 +05301414 if(device.is_tampered)
1415 {
1416 write_device_info_mmc(&device);
1417 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05301418 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Unnati Gandhi1be04752015-03-27 19:41:53 +05301419 #endif
1420 #ifdef ASSERT_ON_TAMPER
1421 dprintf(CRITICAL, "Device is tampered. Asserting..\n");
1422 ASSERT(0);
1423 #endif
1424 }
Sridhar Parasuram8b792422015-07-05 11:38:13 -07001425#endif
Deepa Dinamani0e163a42013-05-24 17:08:15 -07001426}
1427
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301428static bool check_format_bit()
1429{
1430 bool ret = false;
1431 int index;
1432 uint64_t offset;
1433 struct boot_selection_info *in = NULL;
1434 char *buf = NULL;
1435
1436 index = partition_get_index("bootselect");
1437 if (index == INVALID_PTN)
1438 {
1439 dprintf(INFO, "Unable to locate /bootselect partition\n");
1440 return ret;
1441 }
1442 offset = partition_get_offset(index);
1443 if(!offset)
1444 {
1445 dprintf(INFO, "partition /bootselect doesn't exist\n");
1446 return ret;
1447 }
1448 buf = (char *) memalign(CACHE_LINE, ROUNDUP(page_size, CACHE_LINE));
Mayank Grover48860402016-11-29 12:34:53 +05301449 mmc_set_lun(partition_get_lun(index));
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301450 ASSERT(buf);
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301451 if (mmc_read(offset, (uint32_t *)buf, page_size))
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301452 {
1453 dprintf(INFO, "mmc read failure /bootselect %d\n", page_size);
1454 free(buf);
1455 return ret;
1456 }
1457 in = (struct boot_selection_info *) buf;
1458 if ((in->signature == BOOTSELECT_SIGNATURE) &&
1459 (in->version == BOOTSELECT_VERSION)) {
1460 if ((in->state_info & BOOTSELECT_FORMAT) &&
1461 !(in->state_info & BOOTSELECT_FACTORY))
1462 ret = true;
1463 } else {
1464 dprintf(CRITICAL, "Signature: 0x%08x or version: 0x%08x mismatched of /bootselect\n",
1465 in->signature, in->version);
1466 ASSERT(0);
1467 }
1468 free(buf);
1469 return ret;
1470}
1471
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001472void boot_verifier_init()
1473{
Shashank Mittald3e54dd2014-08-28 15:24:02 -07001474 uint32_t boot_state;
1475 /* Check if device unlock */
1476 if(device.is_unlocked)
1477 {
1478 boot_verify_send_event(DEV_UNLOCK);
1479 boot_verify_print_state();
1480 dprintf(CRITICAL, "Device is unlocked! Skipping verification...\n");
1481 return;
1482 }
1483 else
1484 {
1485 boot_verify_send_event(BOOT_INIT);
1486 }
1487
1488 /* Initialize keystore */
1489 boot_state = boot_verify_keystore_init();
1490 if(boot_state == YELLOW)
1491 {
1492 boot_verify_print_state();
1493 dprintf(CRITICAL, "Keystore verification failed! Continuing anyways...\n");
1494 }
1495}
1496
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301497/* Function to return recovery appended dtbo buffer info */
1498void get_recovery_dtbo_info(uint32_t *dtbo_size, void **dtbo_buf)
1499{
1500 *dtbo_size = recovery_dtbo_size;
1501 *dtbo_buf = recovery_dtbo_buf;
1502 return;
1503}
1504
Shashank Mittal23b8f422010-04-16 19:27:21 -07001505int boot_linux_from_mmc(void)
1506{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301507 boot_img_hdr *hdr = (void*) buf;
1508 boot_img_hdr *uhdr;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001509 unsigned offset = 0;
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001510 int rcode;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001511 unsigned long long ptn = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07001512 int index = INVALID_PTN;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001513
Shashank Mittalcd98d472011-08-02 14:29:24 -07001514 unsigned char *image_addr = 0;
1515 unsigned kernel_actual;
1516 unsigned ramdisk_actual;
1517 unsigned imagesize_actual;
Neeti Desai465491e2012-07-31 12:53:35 -07001518 unsigned second_actual = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301519 void * image_buf = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001520
Matthew Qin271927e2015-03-31 22:07:07 -04001521 unsigned int dtb_size = 0;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301522 unsigned dtb_image_size = 0;
1523 uint32_t dtb_image_offset = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001524 unsigned int out_len = 0;
1525 unsigned int out_avai_len = 0;
1526 unsigned char *out_addr = NULL;
1527 uint32_t dtb_offset = 0;
1528 unsigned char *kernel_start_addr = NULL;
1529 unsigned int kernel_size = 0;
Ameya Thakur10a33452016-06-13 14:24:26 -07001530 unsigned int patched_kernel_hdr_size = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301531 uint64_t image_size = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08001532 int rc;
Monika Singh292b3e92018-03-17 22:40:23 +05301533#if VERIFIED_BOOT_2
1534 int status;
Mayank Grover027a9412018-09-04 15:12:05 +05301535 void *dtbo_image_buf = NULL;
1536 uint32_t dtbo_image_sz = 0;
Mayank Grover9df84c02018-08-30 15:46:35 +05301537 void *vbmeta_image_buf = NULL;
1538 uint32_t vbmeta_image_sz = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05301539#endif
Mayank Groverc93cad82017-10-03 12:23:45 +05301540 char *ptn_name = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001541#if DEVICE_TREE
1542 struct dt_table *table;
Joel Kingaa335dc2013-06-03 16:11:08 -07001543 struct dt_entry dt_entry;
Neeti Desai465491e2012-07-31 12:53:35 -07001544 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08001545 uint32_t dt_actual;
Deepa Dinamani19648b42013-09-05 17:05:55 -07001546 uint32_t dt_hdr_size;
Matthew Qin271927e2015-03-31 22:07:07 -04001547 unsigned char *best_match_dt_addr = NULL;
Neeti Desai465491e2012-07-31 12:53:35 -07001548#endif
Matthew Qin49e51fa2015-02-09 10:40:45 +08001549 struct kernel64_hdr *kptr = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05301550 int current_active_slot = INVALID;
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001551
Maunik Shah0f3c8ac2014-03-02 17:47:58 +05301552 if (check_format_bit())
1553 boot_into_recovery = 1;
1554
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07001555 if (!boot_into_recovery) {
1556 memset(ffbm_mode_string, '\0', sizeof(ffbm_mode_string));
1557 rcode = get_ffbm(ffbm_mode_string, sizeof(ffbm_mode_string));
1558 if (rcode <= 0) {
1559 boot_into_ffbm = false;
1560 if (rcode < 0)
1561 dprintf(CRITICAL,"failed to get ffbm cookie");
1562 } else
1563 boot_into_ffbm = true;
1564 } else
1565 boot_into_ffbm = false;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301566 uhdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001567 if (!memcmp(uhdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
1568 dprintf(INFO, "Unified boot method!\n");
1569 hdr = uhdr;
1570 goto unified_boot;
1571 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301572
1573 /* For a/b recovery image code is on boot partition.
1574 If we support multislot, always use boot partition. */
1575 if (boot_into_recovery &&
Mayank Grover8ab4a762019-04-25 17:23:34 +05301576 ((!partition_multislot_is_supported()) ||
1577 (target_dynamic_partition_supported())))
Mayank Groverc93cad82017-10-03 12:23:45 +05301578 ptn_name = "recovery";
1579 else
1580 ptn_name = "boot";
1581
1582 index = partition_get_index(ptn_name);
1583 ptn = partition_get_offset(index);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301584 image_size = partition_get_size(index);
1585 if(ptn == 0 || image_size == 0) {
Mayank Groverc93cad82017-10-03 12:23:45 +05301586 dprintf(CRITICAL, "ERROR: No %s partition found\n", ptn_name);
1587 return -1;
Kinson Chikf1a43512011-07-14 11:28:39 -07001588 }
Mayank Groverc93cad82017-10-03 12:23:45 +05301589
Channagoud Kadabief0547c2015-02-10 12:57:38 -08001590 /* Set Lun for boot & recovery partitions */
1591 mmc_set_lun(partition_get_lun(index));
Shashank Mittal23b8f422010-04-16 19:27:21 -07001592
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05301593 if (mmc_read(ptn + offset, (uint32_t *) buf, page_size)) {
Shashank Mittal23b8f422010-04-16 19:27:21 -07001594 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
1595 return -1;
1596 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07001597
1598 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07001599 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Mayank Grover351a75e2017-05-30 20:06:08 +05301600 return ERR_INVALID_BOOT_MAGIC;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001601 }
1602
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001603 if (hdr->page_size && (hdr->page_size != page_size)) {
vijay kumar2e21b3a2014-06-26 17:40:15 +05301604
1605 if (hdr->page_size > BOOT_IMG_MAX_PAGE_SIZE) {
1606 dprintf(CRITICAL, "ERROR: Invalid page size\n");
1607 return -1;
1608 }
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07001609 page_size = hdr->page_size;
1610 page_mask = page_size - 1;
Shashank Mittal23b8f422010-04-16 19:27:21 -07001611 }
1612
Matthew Qin49e51fa2015-02-09 10:40:45 +08001613 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
1614 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301615 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001616
Matthew Qin49e51fa2015-02-09 10:40:45 +08001617 image_addr = (unsigned char *)target_get_scratch_address();
Mayank Grover6fd36792018-09-10 13:26:58 +05301618#if VERIFIED_BOOT_2
1619 /* Create hole in start of image for VB salt to copy */
1620 image_addr += SALT_BUFF_OFFSET;
1621#endif
Kishor PK9e91b592017-05-24 12:14:55 +05301622 memcpy(image_addr, (void *)buf, page_size);
1623
1624 /* ensure commandline is terminated */
1625 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001626
1627#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05301628#ifndef OSVERSION_IN_BOOTIMAGE
1629 dt_size = hdr->dt_size;
Mayank Grover5a502582018-09-12 11:24:49 +05301630#else
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301631 dprintf(INFO, "BootImage Header: %d\n", hdr->header_version);
Mayank Grover5a502582018-09-12 11:24:49 +05301632#endif
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301633
Parth Dixit4097b622016-03-15 14:42:27 +05301634 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05301635 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
Vijay Kumar Pendoti208f9622016-06-09 19:34:01 +05301636 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1637 return -1;
1638 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301639 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001640#else
Kishor PKd8ddcad2017-07-27 13:53:57 +05301641 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual + (uint64_t)second_actual + page_size)) {
Vijay Kumar Pendoti208f9622016-06-09 19:34:01 +05301642 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields at %u in %s\n",__LINE__,__FILE__);
1643 return -1;
1644 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05301645 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Matthew Qin49e51fa2015-02-09 10:40:45 +08001646#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05301647 dtb_image_size = hdr->kernel_size;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001648
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301649#ifdef OSVERSION_IN_BOOTIMAGE
1650 /* If header version is ONE and booting into recovery,
1651 dtbo is appended with recovery image.
1652 Doing following:
1653 * Validating the recovery offset and size.
1654 * Extracting recovery dtbo to be used as dtbo.
1655 */
1656 if (boot_into_recovery &&
1657 hdr->header_version == BOOT_HEADER_VERSION_ONE)
1658 {
1659 struct boot_img_hdr_v1 *hdr1 =
1660 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
Mayank Grovera1a83c72018-09-24 11:23:15 +05301661 unsigned int recovery_dtbo_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301662
Mayank Grovera1a83c72018-09-24 11:23:15 +05301663 recovery_dtbo_actual = ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301664 if ((hdr1->header_size !=
1665 sizeof(struct boot_img_hdr_v1) + sizeof(boot_img_hdr)))
1666 {
1667 dprintf(CRITICAL, "Invalid boot image header: %d\n", hdr1->header_size);
1668 return -1;
1669 }
1670
Mayank Grovera1a83c72018-09-24 11:23:15 +05301671 if (recovery_dtbo_actual > MAX_SUPPORTED_DTBO_IMG_BUF)
1672 {
1673 dprintf(CRITICAL, "Recovery Dtbo Size too big %x, Allowed size %x\n", recovery_dtbo_actual,
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301674 MAX_SUPPORTED_DTBO_IMG_BUF);
1675 return -1;
1676 }
1677
Mayank Grovera1a83c72018-09-24 11:23:15 +05301678 if (UINT_MAX < ((uint64_t)imagesize_actual + recovery_dtbo_actual))
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301679 {
1680 dprintf(CRITICAL, "Integer overflow detected in recoveryimage header fields at %u in %s\n",__LINE__,__FILE__);
1681 return -1;
1682 }
1683
Mayank Grovera1a83c72018-09-24 11:23:15 +05301684 if (UINT_MAX < (hdr1->recovery_dtbo_offset + recovery_dtbo_actual)) {
1685 dprintf(CRITICAL,
1686 "Integer overflow detected in recovery image header fields at %u in %s\n",__LINE__,__FILE__);
1687 return -1;
1688 }
1689
1690 if (hdr1->recovery_dtbo_offset + recovery_dtbo_actual > image_size)
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301691 {
1692 dprintf(CRITICAL, "Invalid recovery dtbo: Recovery Dtbo Offset=0x%llx,"
1693 " Recovery Dtbo Size=0x%x, Image Size=0x%llx\n",
1694 hdr1->recovery_dtbo_offset, recovery_dtbo_size, image_size);
1695 return -1;
1696 }
1697
1698 recovery_dtbo_buf = (void *)(hdr1->recovery_dtbo_offset + image_addr);
Mayank Grovera1a83c72018-09-24 11:23:15 +05301699 recovery_dtbo_size = recovery_dtbo_actual;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301700 imagesize_actual += recovery_dtbo_size;
1701
1702 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1703 dprintf(SPEW, "Recovery Dtbo Size 0x%x\n", recovery_dtbo_size);
1704 dprintf(SPEW, "Recovery Dtbo Offset 0x%llx\n", hdr1->recovery_dtbo_offset);
1705
1706 }
Parth Dixit1375d9e2019-07-08 20:56:13 +05301707
1708 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
1709 struct boot_img_hdr_v1 *hdr1 =
1710 (struct boot_img_hdr_v1 *) (image_addr + sizeof(boot_img_hdr));
1711 struct boot_img_hdr_v2 *hdr2 = (struct boot_img_hdr_v2 *)
1712 (image_addr + sizeof(boot_img_hdr) +
1713 BOOT_IMAGE_HEADER_V2_OFFSET);
1714 unsigned int recovery_dtbo_actual = 0;
1715
lijuang0b17ba22019-09-04 14:20:47 +08001716 recovery_dtbo_actual =
1717 ROUND_TO_PAGE(hdr1->recovery_dtbo_size, page_mask);
1718 imagesize_actual += recovery_dtbo_actual;
Parth Dixit1375d9e2019-07-08 20:56:13 +05301719
1720 imagesize_actual += ROUND_TO_PAGE(hdr2->dtb_size, page_mask);
1721
1722
1723 dtb_image_offset = page_size + patched_kernel_hdr_size +
1724 kernel_actual + ramdisk_actual + second_actual +
1725 recovery_dtbo_actual;
1726
1727 dprintf(SPEW, "Header version: %d\n", hdr->header_version);
1728 dprintf(SPEW, "Dtb image offset 0x%x\n", dtb_image_offset);
1729 }
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301730#endif
1731
Parth Dixit1375d9e2019-07-08 20:56:13 +05301732
Saranya Chidurab1aaf232018-11-19 15:47:50 +05301733 /* Validate the boot/recovery image size is within the bounds of partition size */
1734 if (imagesize_actual > image_size) {
1735 dprintf(CRITICAL, "Image size is greater than partition size.\n");
1736 return -1;
1737 }
1738
Matthew Qin49e51fa2015-02-09 10:40:45 +08001739#if VERIFIED_BOOT
1740 boot_verifier_init();
1741#endif
1742
Mayank Grover1ceaee22019-04-01 17:54:32 +05301743#if VERIFIED_BOOT_2
1744 /* read full partition if device is unlocked */
1745 if (device.is_unlocked)
1746 imagesize_actual = image_size;
1747#endif
1748
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301749 if (check_aboot_addr_range_overlap((uintptr_t) image_addr, imagesize_actual))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001750 {
1751 dprintf(CRITICAL, "Boot image buffer address overlaps with aboot addresses.\n");
1752 return -1;
1753 }
1754
Matthew Qinbb7923d2015-02-09 10:56:09 +08001755 /*
1756 * Update loading flow of bootimage to support compressed/uncompressed
1757 * bootimage on both 64bit and 32bit platform.
1758 * 1. Load bootimage from emmc partition onto DDR.
1759 * 2. Check if bootimage is gzip format. If yes, decompress compressed kernel
1760 * 3. Check kernel header and update kernel load addr for 64bit and 32bit
1761 * platform accordingly.
1762 * 4. Sanity Check on kernel_addr and ramdisk_addr and copy data.
1763 */
Mayank Grover351a75e2017-05-30 20:06:08 +05301764 if (partition_multislot_is_supported())
1765 {
1766 current_active_slot = partition_find_active_slot();
1767 dprintf(INFO, "Loading boot image (%d) active_slot(%s): start\n",
1768 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1769 }
1770 else
1771 {
1772 dprintf(INFO, "Loading (%s) image (%d): start\n",
1773 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1774 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001775 bs_set_timestamp(BS_KERNEL_LOAD_START);
1776
Gaurav Nebhwani43e2a462016-03-17 21:32:56 +05301777 if ((target_get_max_flash_size() - page_size) < imagesize_actual)
1778 {
1779 dprintf(CRITICAL, "booimage size is greater than DDR can hold\n");
1780 return -1;
1781 }
Kishor PK9e91b592017-05-24 12:14:55 +05301782 offset = page_size;
1783 /* Read image without signature and header*/
1784 if (mmc_read(ptn + offset, (void *)(image_addr + offset), imagesize_actual - page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001785 {
1786 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
1787 return -1;
1788 }
1789
Mayank Grover351a75e2017-05-30 20:06:08 +05301790 if (partition_multislot_is_supported())
1791 {
1792 dprintf(INFO, "Loading boot image (%d) active_slot(%s): done\n",
1793 imagesize_actual, SUFFIX_SLOT(current_active_slot));
1794 }
1795 else
1796 {
1797 dprintf(INFO, "Loading (%s) image (%d): done\n",
Channagoud Kadabif0705b52015-08-20 14:16:08 -07001798 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
1799
Mayank Grover351a75e2017-05-30 20:06:08 +05301800 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001801 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
1802
1803 /* Authenticate Kernel */
1804 dprintf(INFO, "use_signed_kernel=%d, is_unlocked=%d, is_tampered=%d.\n",
1805 (int) target_use_signed_kernel(),
1806 device.is_unlocked,
1807 device.is_tampered);
Monika Singh292b3e92018-03-17 22:40:23 +05301808#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05301809 /* if device is unlocked skip reading signature, as full partition is read */
1810 if (!device.is_unlocked)
Monika Singh292b3e92018-03-17 22:40:23 +05301811 {
Mayank Grover1ceaee22019-04-01 17:54:32 +05301812 offset = imagesize_actual;
1813 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
1814 {
1815 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1816 return -1;
1817 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08001818
Mayank Grover1ceaee22019-04-01 17:54:32 +05301819 /* Read signature */
1820 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1821 {
1822 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1823 return -1;
1824 }
Monika Singh292b3e92018-03-17 22:40:23 +05301825 }
1826
Mayank Grover027a9412018-09-04 15:12:05 +05301827 /* load and validate dtbo partition */
1828 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
1829
Mayank Grover9df84c02018-08-30 15:46:35 +05301830 /* load vbmeta partition */
1831 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
1832
Monika Singh292b3e92018-03-17 22:40:23 +05301833 memset(&info, 0, sizeof(bootinfo));
Mayank Grover027a9412018-09-04 15:12:05 +05301834
1835 /* Pass loaded boot image passed */
Mayank Grover6fd36792018-09-10 13:26:58 +05301836 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(image_addr);
Mayank Grover027a9412018-09-04 15:12:05 +05301837 info.images[IMG_BOOT].imgsize = imagesize_actual;
1838 info.images[IMG_BOOT].name = ptn_name;
1839 ++info.num_loaded_images;
1840
1841 /* Pass loaded dtbo image */
1842 if (dtbo_image_buf != NULL) {
Mayank Grover6fd36792018-09-10 13:26:58 +05301843 info.images[IMG_DTBO].image_buffer =
1844 SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
Mayank Grover027a9412018-09-04 15:12:05 +05301845 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
1846 info.images[IMG_DTBO].name = "dtbo";
1847 ++info.num_loaded_images;
1848 }
1849
Mayank Grover9df84c02018-08-30 15:46:35 +05301850 /* Pass loaded vbmeta image */
1851 if (vbmeta_image_buf != NULL) {
1852 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
1853 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
1854 info.images[IMG_VBMETA].name = "vbmeta";
1855 ++info.num_loaded_images;
1856 }
1857
Mayank Grovere1ab96c2018-09-04 20:31:31 +05301858 info.header_version = hdr->header_version;
Monika Singh292b3e92018-03-17 22:40:23 +05301859 info.multi_slot_boot = partition_multislot_is_supported();
1860 info.bootreason_alarm = boot_reason_alarm;
1861 info.bootinto_recovery = boot_into_recovery;
1862 status = load_image_and_auth(&info);
1863 if(status)
1864 return -1;
1865
1866 vbcmdline = info.vbcmdline;
Mayank Grover9df84c02018-08-30 15:46:35 +05301867
1868 /* Free the buffer allocated to vbmeta post verification */
Saranya Chidurab4933332018-10-15 17:30:06 +05301869 if (vbmeta_image_buf != NULL) {
1870 free(vbmeta_image_buf);
1871 --info.num_loaded_images;
1872 }
Monika Singh292b3e92018-03-17 22:40:23 +05301873#else
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001874 /* Change the condition a little bit to include the test framework support.
1875 * We would never reach this point if device is in fastboot mode, even if we did
1876 * that means we are in test mode, so execute kernel authentication part for the
1877 * tests */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301878 if((target_use_signed_kernel() && (!device.is_unlocked)) || is_test_mode_enabled())
Matthew Qin49e51fa2015-02-09 10:40:45 +08001879 {
1880 offset = imagesize_actual;
Vijay Kumar Pendoti9c002ad2016-03-09 13:52:45 +05301881 if (check_aboot_addr_range_overlap((uintptr_t)image_addr + offset, page_size))
Matthew Qin49e51fa2015-02-09 10:40:45 +08001882 {
1883 dprintf(CRITICAL, "Signature read buffer address overlaps with aboot addresses.\n");
1884 return -1;
1885 }
1886
1887 /* Read signature */
1888 if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
1889 {
1890 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
1891 return -1;
1892 }
1893
1894 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001895 /* The purpose of our test is done here */
Parth Dixitcb0c6082015-12-30 15:01:13 +05301896 if(is_test_mode_enabled() && auth_kernel_img)
Channagoud Kadabi736c4962015-08-21 11:56:52 -07001897 return 0;
Matthew Qin49e51fa2015-02-09 10:40:45 +08001898 } else {
1899 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
1900 #ifdef TZ_SAVE_KERNEL_HASH
1901 aboot_save_boot_hash_mmc((uint32_t) image_addr, imagesize_actual);
1902 #endif /* TZ_SAVE_KERNEL_HASH */
Amit Blay4aa292f2015-04-28 21:55:59 +03001903
1904#ifdef MDTP_SUPPORT
1905 {
1906 /* Verify MDTP lock.
1907 * For boot & recovery partitions, MDTP will use boot_verifier APIs,
1908 * since verification was skipped in aboot. The signature is not part of the loaded image.
1909 */
1910 mdtp_ext_partition_verification_t ext_partition;
1911 ext_partition.partition = boot_into_recovery ? MDTP_PARTITION_RECOVERY : MDTP_PARTITION_BOOT;
1912 ext_partition.integrity_state = MDTP_PARTITION_STATE_UNSET;
1913 ext_partition.page_size = page_size;
1914 ext_partition.image_addr = (uint32)image_addr;
1915 ext_partition.image_size = imagesize_actual;
1916 ext_partition.sig_avail = FALSE;
1917 mdtp_fwlock_verify_lock(&ext_partition);
1918 }
1919#endif /* MDTP_SUPPORT */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001920 }
Monika Singh292b3e92018-03-17 22:40:23 +05301921#endif
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08001922
Sridhar Parasuram00bfedb2015-05-26 14:21:27 -07001923#if VERIFIED_BOOT
taozhang93088bd2016-11-16 15:50:46 +08001924 if((boot_verify_get_state() == ORANGE) && (!boot_into_ffbm))
Reut Zysmanba8a9d52016-02-18 11:44:04 +02001925 {
1926#if FBCON_DISPLAY_MSG
1927 display_bootverify_menu(DISPLAY_MENU_ORANGE);
1928 wait_for_users_action();
1929#else
1930 dprintf(CRITICAL,
1931 "Your device has been unlocked and can't be trusted.\nWait for 5 seconds before proceeding\n");
1932 mdelay(5000);
1933#endif
1934 }
1935#endif
1936
1937#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05301938 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05301939 {
1940 /* set boot and system versions. */
1941 set_os_version((unsigned char *)image_addr);
1942 // send root of trust
1943 if(!send_rot_command((uint32_t)device.is_unlocked))
1944 ASSERT(0);
1945 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05301946#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07001947 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08001948 * Check if the kernel image is a gzip package. If yes, need to decompress it.
1949 * If not, continue booting.
1950 */
1951 if (is_gzip_package((unsigned char *)(image_addr + page_size), hdr->kernel_size))
1952 {
1953 out_addr = (unsigned char *)(image_addr + imagesize_actual + page_size);
1954 out_avai_len = target_get_max_flash_size() - imagesize_actual - page_size;
Mayank Grover027a9412018-09-04 15:12:05 +05301955#if VERIFIED_BOOT_2
1956 if (dtbo_image_sz)
1957 out_avai_len -= DTBO_IMG_BUF;
1958#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04001959 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001960 rc = decompress((unsigned char *)(image_addr + page_size),
1961 hdr->kernel_size, out_addr, out_avai_len,
1962 &dtb_offset, &out_len);
1963 if (rc)
1964 {
Matthew Qin0b15b322015-05-19 05:20:54 -04001965 dprintf(CRITICAL, "decompressing kernel image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001966 ASSERT(0);
1967 }
1968
Matthew Qin0b15b322015-05-19 05:20:54 -04001969 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08001970 kptr = (struct kernel64_hdr *)out_addr;
1971 kernel_start_addr = out_addr;
1972 kernel_size = out_len;
1973 } else {
Ameya Thakur10a33452016-06-13 14:24:26 -07001974 dprintf(INFO, "Uncpmpressed kernel in use\n");
1975 if (!strncmp((char*)(image_addr + page_size),
1976 PATCHED_KERNEL_MAGIC,
1977 sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
1978 dprintf(INFO, "Patched kernel detected\n");
1979 kptr = (struct kernel64_hdr *)(image_addr + page_size +
1980 PATCHED_KERNEL_HEADER_SIZE);
1981 //The size of the kernel is stored at start of kernel image + 16
1982 //The dtb would start just after the kernel
1983 dtb_offset = *((uint32_t*)((unsigned char*)
1984 (image_addr + page_size +
1985 sizeof(PATCHED_KERNEL_MAGIC) -
1986 1)));
1987 //The actual kernel starts after the 20 byte header.
1988 kernel_start_addr = (unsigned char*)(image_addr +
1989 page_size + PATCHED_KERNEL_HEADER_SIZE);
1990 kernel_size = hdr->kernel_size;
1991 patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
1992 } else {
1993 dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
1994 kptr = (struct kernel64_hdr *)(image_addr + page_size);
1995 kernel_start_addr = (unsigned char *)(image_addr + page_size);
1996 kernel_size = hdr->kernel_size;
1997 }
Matthew Qinbb7923d2015-02-09 10:56:09 +08001998 }
1999
2000 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002001 * Update the kernel/ramdisk/tags address if the boot image header
2002 * has default values, these default values come from mkbootimg when
2003 * the boot image is flashed using fastboot flash:raw
2004 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002005 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002006
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002007 /* Get virtual addresses since the hdr saves physical addresses. */
2008 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2009 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2010 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002011
Matthew Qinbb7923d2015-02-09 10:56:09 +08002012 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002013 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002014 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302015 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
2016 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2017 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002018 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302019 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002020 return -1;
2021 }
2022
2023#ifndef DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05302024 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2025 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002026 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302027 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002028 return -1;
2029 }
2030#endif
2031
Matthew Qin49e51fa2015-02-09 10:40:45 +08002032 /* Move kernel, ramdisk and device tree to correct address */
Matthew Qinbb7923d2015-02-09 10:56:09 +08002033 memmove((void*) hdr->kernel_addr, kernel_start_addr, kernel_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002034 memmove((void*) hdr->ramdisk_addr, (char *)(image_addr + page_size + kernel_actual), hdr->ramdisk_size);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07002035
Matthew Qin49e51fa2015-02-09 10:40:45 +08002036 #if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05302037 if(dt_size) {
Matthew Qin49e51fa2015-02-09 10:40:45 +08002038 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2039 table = (struct dt_table*) dt_table_offset;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002040
Matthew Qin49e51fa2015-02-09 10:40:45 +08002041 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2042 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2043 return -1;
2044 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002045
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302046 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2047 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05302048 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05302049 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2050 return -1;
2051 }
2052
Matthew Qin49e51fa2015-02-09 10:40:45 +08002053 /* Find index of device tree within device tree table */
2054 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2055 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2056 return -1;
2057 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002058
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302059 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2060 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2061 return -1;
2062 }
2063
2064 /* Ensure we are not overshooting dt_size with the dt_entry selected */
Parth Dixit4097b622016-03-15 14:42:27 +05302065 if ((dt_entry.offset + dt_entry.size) > dt_size) {
P.V. Phani Kumar3c333202016-03-09 11:54:37 +05302066 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2067 return -1;
2068 }
2069
Matthew Qin271927e2015-03-31 22:07:07 -04002070 if (is_gzip_package((unsigned char *)dt_table_offset + dt_entry.offset, dt_entry.size))
2071 {
2072 unsigned int compressed_size = 0;
2073 out_addr += out_len;
2074 out_avai_len -= out_len;
Matthew Qin0b15b322015-05-19 05:20:54 -04002075 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002076 rc = decompress((unsigned char *)dt_table_offset + dt_entry.offset,
2077 dt_entry.size, out_addr, out_avai_len,
2078 &compressed_size, &dtb_size);
2079 if (rc)
2080 {
Matthew Qin0b15b322015-05-19 05:20:54 -04002081 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002082 ASSERT(0);
2083 }
2084
Matthew Qin0b15b322015-05-19 05:20:54 -04002085 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04002086 best_match_dt_addr = out_addr;
2087 } else {
2088 best_match_dt_addr = (unsigned char *)dt_table_offset + dt_entry.offset;
2089 dtb_size = dt_entry.size;
2090 }
2091
Matthew Qin49e51fa2015-02-09 10:40:45 +08002092 /* Validate and Read device device tree in the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302093 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
2094 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002095 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302096 dprintf(CRITICAL, "Device tree addresses are not valid\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002097 return -1;
2098 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002099
Matthew Qin271927e2015-03-31 22:07:07 -04002100 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002101 } else {
2102 /* Validate the tags_addr */
Mayank Grovere559cec2017-10-17 15:12:03 +05302103 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2104 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002105 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302106 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002107 return -1;
2108 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002109 /*
2110 * If appended dev tree is found, update the atags with
2111 * memory address to the DTB appended location on RAM.
2112 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302113 *
2114 * Make sure everything from scratch address is read before next step!
2115 * In case of dtbo, this API is going to read dtbo on scratch.
Matthew Qin49e51fa2015-02-09 10:40:45 +08002116 */
2117 void *dtb;
Parth Dixit1375d9e2019-07-08 20:56:13 +05302118 image_buf = (void*)(image_addr + page_size + patched_kernel_hdr_size);
2119
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302120#ifdef OSVERSION_IN_BOOTIMAGE
Parth Dixit1375d9e2019-07-08 20:56:13 +05302121 if ( hdr->header_version == BOOT_HEADER_VERSION_TWO) {
2122
2123 image_buf = (void*)(image_addr);
2124 dtb_offset = dtb_image_offset;
2125 dtb_image_size = imagesize_actual;
2126 }
Nagireddy Annem0d60bb62019-08-16 19:16:00 +05302127#endif
Parth Dixit1375d9e2019-07-08 20:56:13 +05302128
2129 dtb = dev_tree_appended(image_buf, dtb_image_size, dtb_offset,
Ameya Thakur10a33452016-06-13 14:24:26 -07002130 (void *)hdr->tags_addr);
Matthew Qin49e51fa2015-02-09 10:40:45 +08002131 if (!dtb) {
2132 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07002133 return -1;
2134 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002135 }
Matthew Qin49e51fa2015-02-09 10:40:45 +08002136 #endif
Shashank Mittal23b8f422010-04-16 19:27:21 -07002137
Stanimir Varbanov69ec5462013-07-18 18:17:42 +03002138 if (boot_into_recovery && !device.is_unlocked && !device.is_tampered)
2139 target_load_ssd_keystore();
2140
Shashank Mittal23b8f422010-04-16 19:27:21 -07002141unified_boot:
Shashank Mittal23b8f422010-04-16 19:27:21 -07002142
Dima Zavin77e41f32013-03-06 16:10:43 -08002143 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002144 (const char *)hdr->cmdline, board_machtype(),
Shashank Mittal23b8f422010-04-16 19:27:21 -07002145 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2146
2147 return 0;
2148}
2149
Dima Zavin214cc642009-01-26 11:16:21 -08002150int boot_linux_from_flash(void)
2151{
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302152 boot_img_hdr *hdr = (void*) buf;
Dima Zavin214cc642009-01-26 11:16:21 -08002153 struct ptentry *ptn;
2154 struct ptable *ptable;
2155 unsigned offset = 0;
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002156
Shashank Mittalcd98d472011-08-02 14:29:24 -07002157 unsigned char *image_addr = 0;
2158 unsigned kernel_actual;
2159 unsigned ramdisk_actual;
2160 unsigned imagesize_actual;
vijay kumar8f53e362015-11-24 13:38:11 +05302161 unsigned second_actual = 0;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002162
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002163#if DEVICE_TREE
Monika Singh292b3e92018-03-17 22:40:23 +05302164 struct dt_table *table = NULL;
Joel Kingaa335dc2013-06-03 16:11:08 -07002165 struct dt_entry dt_entry;
vijay kumar8f53e362015-11-24 13:38:11 +05302166 unsigned dt_table_offset;
Deepa Dinamani7aaf83d2012-12-21 11:27:01 -08002167 uint32_t dt_actual;
Monika Singh292b3e92018-03-17 22:40:23 +05302168 uint32_t dt_hdr_size = 0;
Vivek Kumar07bd0862018-04-10 14:19:23 +05302169 uint32_t dtb_offset = 0;
vijay kumar8f53e362015-11-24 13:38:11 +05302170 unsigned int dtb_size = 0;
2171 unsigned char *best_match_dt_addr = NULL;
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002172#endif
2173
David Ng183a7422009-12-07 14:55:21 -08002174 if (target_is_emmc_boot()) {
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302175 hdr = (boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
David Ng183a7422009-12-07 14:55:21 -08002176 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
2177 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
2178 return -1;
2179 }
2180 goto continue_boot;
2181 }
2182
Dima Zavin214cc642009-01-26 11:16:21 -08002183 ptable = flash_get_ptable();
2184 if (ptable == NULL) {
2185 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2186 return -1;
2187 }
2188
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002189 if(!boot_into_recovery)
2190 {
2191 ptn = ptable_find(ptable, "boot");
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002192
Chandan Uddarajude85d3f2010-01-05 16:32:33 -08002193 if (ptn == NULL) {
2194 dprintf(CRITICAL, "ERROR: No boot partition found\n");
2195 return -1;
2196 }
2197 }
2198 else
2199 {
2200 ptn = ptable_find(ptable, "recovery");
2201 if (ptn == NULL) {
2202 dprintf(CRITICAL, "ERROR: No recovery partition found\n");
2203 return -1;
2204 }
Dima Zavin214cc642009-01-26 11:16:21 -08002205 }
2206
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302207 /* Read boot.img header from flash */
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002208 if (flash_read(ptn, offset, buf, page_size)) {
Dima Zavin214cc642009-01-26 11:16:21 -08002209 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
2210 return -1;
2211 }
Dima Zavin214cc642009-01-26 11:16:21 -08002212
2213 if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002214 dprintf(CRITICAL, "ERROR: Invalid boot image header\n");
Dima Zavin214cc642009-01-26 11:16:21 -08002215 return -1;
2216 }
2217
Shashank Mittaldcc2e352009-11-19 19:11:16 -08002218 if (hdr->page_size != page_size) {
Kinson Chik kchik@codeaurora.org82e4ae62011-04-12 17:42:07 -07002219 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 -08002220 return -1;
2221 }
2222
Kishor PK9e91b592017-05-24 12:14:55 +05302223 image_addr = (unsigned char *)target_get_scratch_address();
2224 memcpy(image_addr, (void *)buf, page_size);
vijay kumar287bb542015-09-29 13:01:52 +05302225
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002226 /*
2227 * Update the kernel/ramdisk/tags address if the boot image header
2228 * has default values, these default values come from mkbootimg when
2229 * the boot image is flashed using fastboot flash:raw
2230 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08002231 update_ker_tags_rdisk_addr(hdr, false);
Channagoud Kadabia22144f2013-03-20 11:49:01 -07002232
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002233 /* Get virtual addresses since the hdr saves physical addresses. */
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002234 hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
2235 hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
2236 hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
2237
2238 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2239 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Mayank Grover032736f2017-07-14 20:34:51 +05302240 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002241
Kishor PK9e91b592017-05-24 12:14:55 +05302242 /* ensure commandline is terminated */
2243 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
2244
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002245 /* Check if the addresses in the header are valid. */
2246 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_actual) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05302247 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_actual) ||
2248 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
2249 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002250 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302251 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002252 return -1;
2253 }
2254
2255#ifndef DEVICE_TREE
Kishor PKd8ddcad2017-07-27 13:53:57 +05302256 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302257 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2258 return -1;
2259 }
Kishor PKd8ddcad2017-07-27 13:53:57 +05302260 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302261
Mayank Grovere559cec2017-10-17 15:12:03 +05302262 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
2263 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302264 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302265 dprintf(CRITICAL, "Tags addresses are not valid.\n");
Vijay Kumar Pendotid3ed20e2016-09-20 00:34:46 +05302266 return -1;
2267 }
2268#else
2269
2270#ifndef OSVERSION_IN_BOOTIMAGE
2271 dt_size = hdr->dt_size;
2272#endif
Mayank Grover032736f2017-07-14 20:34:51 +05302273 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05302274 if (UINT_MAX < ((uint64_t)kernel_actual + (uint64_t)ramdisk_actual+ (uint64_t)second_actual + (uint64_t)dt_actual + page_size)) {
Mayank Grover032736f2017-07-14 20:34:51 +05302275 dprintf(CRITICAL, "Integer overflow detected in bootimage header fields\n");
2276 return -1;
2277 }
2278
Kishor PKd8ddcad2017-07-27 13:53:57 +05302279 imagesize_actual = (page_size + kernel_actual + ramdisk_actual + second_actual + dt_actual);
Mayank Grover032736f2017-07-14 20:34:51 +05302280
Mayank Grovere559cec2017-10-17 15:12:03 +05302281 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_size) ||
2282 check_ddr_addr_range_bound(hdr->tags_addr, dt_size))
Mayank Grover032736f2017-07-14 20:34:51 +05302283 {
Mayank Grovere559cec2017-10-17 15:12:03 +05302284 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Mayank Grover032736f2017-07-14 20:34:51 +05302285 return -1;
2286 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002287#endif
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07002288
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302289 /* Read full boot.img from flash */
2290 dprintf(INFO, "Loading (%s) image (%d): start\n",
2291 (!boot_into_recovery ? "boot" : "recovery"),imagesize_actual);
2292 bs_set_timestamp(BS_KERNEL_LOAD_START);
2293
2294 if (UINT_MAX - page_size < imagesize_actual)
2295 {
2296 dprintf(CRITICAL,"Integer overflow detected in bootimage header fields %u %s\n", __LINE__,__func__);
2297 return -1;
2298 }
2299
2300 /*Check the availability of RAM before reading boot image + max signature length from flash*/
2301 if (target_get_max_flash_size() < (imagesize_actual + page_size))
2302 {
2303 dprintf(CRITICAL, "bootimage size is greater than DDR can hold\n");
2304 return -1;
2305 }
2306
2307 offset = page_size;
2308 /* Read image without signature and header */
2309 if (flash_read(ptn, offset, (void *)(image_addr + offset), imagesize_actual - page_size))
2310 {
2311 dprintf(CRITICAL, "ERROR: Cannot read boot image\n");
2312 return -1;
2313 }
2314
2315 dprintf(INFO, "Loading (%s) image (%d): done\n",
2316 (!boot_into_recovery ? "boot" : "recovery"), imagesize_actual);
2317 bs_set_timestamp(BS_KERNEL_LOAD_DONE);
2318
Shashank Mittalcd98d472011-08-02 14:29:24 -07002319 /* Authenticate Kernel */
Deepa Dinamani23b60d42013-06-24 18:10:52 -07002320 if(target_use_signed_kernel() && (!device.is_unlocked))
Shashank Mittalcd98d472011-08-02 14:29:24 -07002321 {
Shashank Mittalcd98d472011-08-02 14:29:24 -07002322 offset = imagesize_actual;
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302323
Shashank Mittalcd98d472011-08-02 14:29:24 -07002324 /* Read signature */
2325 if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
2326 {
2327 dprintf(CRITICAL, "ERROR: Cannot read boot image signature\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07002328 return -1;
Shashank Mittalcd98d472011-08-02 14:29:24 -07002329 }
Shashank Mittalcd98d472011-08-02 14:29:24 -07002330
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05302331 verify_signed_bootimg((uint32_t)image_addr, imagesize_actual);
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302332 }
2333 offset = page_size;
2334 if(hdr->second_size != 0) {
2335 if (UINT_MAX - offset < second_actual)
2336 {
2337 dprintf(CRITICAL, "ERROR: Integer overflow in boot image header %s\t%d\n",__func__,__LINE__);
2338 return -1;
vijay kumar8f53e362015-11-24 13:38:11 +05302339 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302340 offset += second_actual;
2341 /* Second image loading not implemented. */
2342 ASSERT(0);
2343 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302344 /* Move kernel and ramdisk to correct address */
2345 memmove((void*) hdr->kernel_addr, (char*) (image_addr + page_size), hdr->kernel_size);
2346 memmove((void*) hdr->ramdisk_addr, (char*) (image_addr + page_size + kernel_actual), hdr->ramdisk_size);
2347
2348#if DEVICE_TREE
2349 if(dt_size != 0) {
2350
2351 dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
2352
2353 table = (struct dt_table*) dt_table_offset;
2354
2355 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
2356 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2357 return -1;
2358 }
2359
2360 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
2361 goes beyound hdr->dt_size*/
2362 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
2363 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
2364 return -1;
2365 }
2366
2367 /* Find index of device tree within device tree table */
2368 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
2369 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
2370 return -1;
2371 }
2372
2373 /* Validate and Read device device tree in the "tags_add */
2374 if (check_aboot_addr_range_overlap(hdr->tags_addr, dt_entry.size) ||
2375 check_ddr_addr_range_bound(hdr->tags_addr, dt_entry.size))
2376 {
2377 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2378 return -1;
2379 }
2380
2381 if(dt_entry.offset > (UINT_MAX - dt_entry.size)) {
2382 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2383 return -1;
2384 }
2385
2386 /* Ensure we are not overshooting dt_size with the dt_entry selected */
2387 if ((dt_entry.offset + dt_entry.size) > dt_size) {
2388 dprintf(CRITICAL, "ERROR: Device tree contents are Invalid\n");
2389 return -1;
2390 }
2391
2392 best_match_dt_addr = (unsigned char *)table + dt_entry.offset;
2393 dtb_size = dt_entry.size;
2394 memmove((void *)hdr->tags_addr, (char *)best_match_dt_addr, dtb_size);
Vivek Kumar07bd0862018-04-10 14:19:23 +05302395
2396 } else {
2397 /* Validate the tags_addr */
2398 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
2399 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
2400 {
2401 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
2402 return -1;
2403 }
2404 /*
2405 * If appended dev tree is found, update the atags with
2406 * memory address to the DTB appended location on RAM.
2407 * Else update with the atags address in the kernel header
Mayank Grover1ed3e8b2018-09-19 15:16:50 +05302408 *
2409 * Make sure everything from scratch address is read before next step!
2410 * In case of dtbo, this API is going to read dtbo on scratch.
Vivek Kumar07bd0862018-04-10 14:19:23 +05302411 */
2412 void *dtb = NULL;
2413 dtb = dev_tree_appended((void*)(image_addr + page_size ),hdr->kernel_size, dtb_offset, (void *)hdr->tags_addr);
2414 if (!dtb) {
2415 dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
2416 return -1;
2417 }
2418 }
Mayank Groverfc7a2ce2017-12-20 12:58:17 +05302419#endif
2420 if(target_use_signed_kernel() && (!device.is_unlocked))
2421 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002422 /* Make sure everything from scratch address is read before next step!*/
Shashank Mittala0032282011-08-26 14:50:11 -07002423 if(device.is_tampered)
Shashank Mittal162244e2011-08-08 19:01:25 -07002424 {
2425 write_device_info_flash(&device);
2426 }
Channagoud Kadabi5c86fe32012-02-16 10:58:48 +05302427#if USE_PCOM_SECBOOT
2428 set_tamper_flag(device.is_tampered);
2429#endif
Shashank Mittalcd98d472011-08-02 14:29:24 -07002430 }
David Ng183a7422009-12-07 14:55:21 -08002431continue_boot:
Dima Zavin214cc642009-01-26 11:16:21 -08002432
Dima Zavin214cc642009-01-26 11:16:21 -08002433 /* TODO: create/pass atags to kernel */
2434
Ajay Dudanie28a6072011-07-01 13:59:46 -07002435 boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
Dima Zavinbd3daa02013-03-26 11:06:44 -07002436 (const char *)hdr->cmdline, board_machtype(),
Dima Zavin214cc642009-01-26 11:16:21 -08002437 (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
2438
2439 return 0;
2440}
Brian Swetland9c4c0752009-01-25 16:23:50 -08002441
Shashank Mittal162244e2011-08-08 19:01:25 -07002442void write_device_info_mmc(device_info *dev)
2443{
Shashank Mittal162244e2011-08-08 19:01:25 -07002444 unsigned long long ptn = 0;
2445 unsigned long long size;
2446 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002447 uint8_t lun = 0;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002448 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302449 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002450
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002451 if (devinfo_present)
2452 index = partition_get_index("devinfo");
2453 else
2454 index = partition_get_index("aboot");
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002455
Shashank Mittal162244e2011-08-08 19:01:25 -07002456 ptn = partition_get_offset(index);
2457 if(ptn == 0)
2458 {
2459 return;
2460 }
2461
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08002462 lun = partition_get_lun(index);
2463 mmc_set_lun(lun);
2464
Shashank Mittal162244e2011-08-08 19:01:25 -07002465 size = partition_get_size(index);
2466
Mayank Groverddd348d2018-01-23 14:07:09 +05302467 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2468 mmc_blocksize_mask);
2469 if (device_info_sz == UINT_MAX)
2470 {
2471 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2472 return;
2473 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002474
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002475 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302476 ret = mmc_write(ptn, device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002477 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302478 ret = mmc_write((ptn + size - device_info_sz), device_info_sz, (void *)info_buf);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002479 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002480 {
2481 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002482 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002483 }
2484}
2485
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002486void read_device_info_mmc(struct device_info *info)
Shashank Mittal162244e2011-08-08 19:01:25 -07002487{
Shashank Mittal162244e2011-08-08 19:01:25 -07002488 unsigned long long ptn = 0;
2489 unsigned long long size;
2490 int index = INVALID_PTN;
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002491 uint32_t ret = 0;
Mayank Groverddd348d2018-01-23 14:07:09 +05302492 uint32_t device_info_sz = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002493
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002494 if ((index = partition_get_index("devinfo")) < 0)
2495 {
2496 devinfo_present = false;
2497 index = partition_get_index("aboot");
2498 }
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002499
Shashank Mittal162244e2011-08-08 19:01:25 -07002500 ptn = partition_get_offset(index);
2501 if(ptn == 0)
2502 {
2503 return;
2504 }
2505
Channagoud Kadabi5d0371c2014-10-21 22:27:07 -07002506 mmc_set_lun(partition_get_lun(index));
2507
Shashank Mittal162244e2011-08-08 19:01:25 -07002508 size = partition_get_size(index);
2509
Mayank Groverddd348d2018-01-23 14:07:09 +05302510 device_info_sz = ROUND_TO_PAGE(sizeof(struct device_info),
2511 mmc_blocksize_mask);
2512 if (device_info_sz == UINT_MAX)
2513 {
2514 dprintf(CRITICAL, "ERROR: Incorrect blocksize of card\n");
2515 return;
2516 }
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07002517
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002518 if (devinfo_present)
Mayank Groverddd348d2018-01-23 14:07:09 +05302519 ret = mmc_read(ptn, (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002520 else
Mayank Groverddd348d2018-01-23 14:07:09 +05302521 ret = mmc_read((ptn + size - device_info_sz), (void *)info_buf, device_info_sz);
Channagoud Kadabi80a182b2015-03-11 17:04:23 -07002522 if (ret)
Shashank Mittal162244e2011-08-08 19:01:25 -07002523 {
2524 dprintf(CRITICAL, "ERROR: Cannot read device info\n");
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002525 ASSERT(0);
Shashank Mittal162244e2011-08-08 19:01:25 -07002526 }
Shashank Mittal162244e2011-08-08 19:01:25 -07002527}
2528
2529void write_device_info_flash(device_info *dev)
2530{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002531 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002532 struct ptentry *ptn;
2533 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002534 if(info == NULL)
2535 {
2536 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2537 ASSERT(0);
2538 }
2539 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002540 ptable = flash_get_ptable();
2541 if (ptable == NULL)
2542 {
2543 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2544 return;
2545 }
2546
2547 ptn = ptable_find(ptable, "devinfo");
2548 if (ptn == NULL)
2549 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002550 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002551 return;
2552 }
2553
Mayank Groverdedbc892017-10-24 13:41:34 +05302554 memset(info, 0, BOOT_IMG_MAX_PAGE_SIZE);
Shashank Mittal162244e2011-08-08 19:01:25 -07002555 memcpy(info, dev, sizeof(device_info));
2556
2557 if (flash_write(ptn, 0, (void *)info_buf, page_size))
2558 {
2559 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2560 return;
2561 }
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002562 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002563}
2564
vijay kumarc65876c2015-04-24 13:29:16 +05302565static int read_allow_oem_unlock(device_info *dev)
2566{
vijay kumarc65876c2015-04-24 13:29:16 +05302567 unsigned offset;
2568 int index;
2569 unsigned long long ptn;
2570 unsigned long long ptn_size;
2571 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002572 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302573
vijay kumarca2e6812015-07-08 20:28:25 +05302574 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302575 if (index == INVALID_PTN)
2576 {
vijay kumarca2e6812015-07-08 20:28:25 +05302577 index = partition_get_index(frp_ptns[1]);
2578 if (index == INVALID_PTN)
2579 {
2580 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2581 return -1;
2582 }
vijay kumarc65876c2015-04-24 13:29:16 +05302583 }
2584
2585 ptn = partition_get_offset(index);
2586 ptn_size = partition_get_size(index);
2587 offset = ptn_size - blocksize;
2588
Mayank Grover48860402016-11-29 12:34:53 +05302589 /* Set Lun for partition */
2590 mmc_set_lun(partition_get_lun(index));
2591
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002592 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302593 {
2594 dprintf(CRITICAL, "Reading MMC failed\n");
2595 return -1;
2596 }
2597
2598 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2599 is_allow_unlock = buf[blocksize-1] & 0x01;
2600 return 0;
2601}
2602
2603static int write_allow_oem_unlock(bool allow_unlock)
2604{
vijay kumarc65876c2015-04-24 13:29:16 +05302605 unsigned offset;
vijay kumarc65876c2015-04-24 13:29:16 +05302606 int index;
2607 unsigned long long ptn;
2608 unsigned long long ptn_size;
2609 unsigned blocksize = mmc_get_device_blocksize();
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002610 STACKBUF_DMA_ALIGN(buf, blocksize);
vijay kumarc65876c2015-04-24 13:29:16 +05302611
vijay kumarca2e6812015-07-08 20:28:25 +05302612 index = partition_get_index(frp_ptns[0]);
vijay kumarc65876c2015-04-24 13:29:16 +05302613 if (index == INVALID_PTN)
2614 {
vijay kumarca2e6812015-07-08 20:28:25 +05302615 index = partition_get_index(frp_ptns[1]);
2616 if (index == INVALID_PTN)
2617 {
2618 dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
2619 return -1;
2620 }
vijay kumarc65876c2015-04-24 13:29:16 +05302621 }
2622
2623 ptn = partition_get_offset(index);
2624 ptn_size = partition_get_size(index);
2625 offset = ptn_size - blocksize;
Mayank Grover48860402016-11-29 12:34:53 +05302626 mmc_set_lun(partition_get_lun(index));
vijay kumarc65876c2015-04-24 13:29:16 +05302627
Channagoud Kadabib1fe4062015-08-07 16:08:44 -07002628 if (mmc_read(ptn + offset, (void *)buf, blocksize))
vijay kumarc65876c2015-04-24 13:29:16 +05302629 {
2630 dprintf(CRITICAL, "Reading MMC failed\n");
2631 return -1;
2632 }
2633
2634 /*is_allow_unlock is a bool value stored at the LSB of last byte*/
2635 buf[blocksize-1] = allow_unlock;
2636 if (mmc_write(ptn + offset, blocksize, buf))
2637 {
2638 dprintf(CRITICAL, "Writing MMC failed\n");
2639 return -1;
2640 }
2641
2642 return 0;
2643}
2644
Shashank Mittal162244e2011-08-08 19:01:25 -07002645void read_device_info_flash(device_info *dev)
2646{
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002647 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
Shashank Mittal162244e2011-08-08 19:01:25 -07002648 struct ptentry *ptn;
2649 struct ptable *ptable;
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002650 if(info == NULL)
2651 {
2652 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2653 ASSERT(0);
2654 }
2655 info_buf = info;
Shashank Mittal162244e2011-08-08 19:01:25 -07002656 ptable = flash_get_ptable();
2657 if (ptable == NULL)
2658 {
2659 dprintf(CRITICAL, "ERROR: Partition table not found\n");
2660 return;
2661 }
2662
2663 ptn = ptable_find(ptable, "devinfo");
2664 if (ptn == NULL)
2665 {
Smita Ghosh670c8b82015-05-07 09:30:03 -07002666 dprintf(CRITICAL, "ERROR: No devinfo partition found\n");
Shashank Mittal162244e2011-08-08 19:01:25 -07002667 return;
2668 }
2669
2670 if (flash_read(ptn, 0, (void *)info_buf, page_size))
2671 {
2672 dprintf(CRITICAL, "ERROR: Cannot write device info\n");
2673 return;
2674 }
2675
2676 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2677 {
Shashank Mittal162244e2011-08-08 19:01:25 -07002678 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
2679 info->is_unlocked = 0;
Shashank Mittala0032282011-08-26 14:50:11 -07002680 info->is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002681 write_device_info_flash(info);
2682 }
2683 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002684 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002685}
2686
2687void write_device_info(device_info *dev)
2688{
2689 if(target_is_emmc_boot())
2690 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002691 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2692 if(info == NULL)
2693 {
2694 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2695 ASSERT(0);
2696 }
2697 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002698 memcpy(info, dev, sizeof(struct device_info));
2699
2700#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302701 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302702 is_secure_boot_enable()) {
2703 if((write_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2704 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002705 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002706 else
2707 write_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002708#else
2709 write_device_info_mmc(info);
2710#endif
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002711 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002712 }
2713 else
2714 {
2715 write_device_info_flash(dev);
2716 }
2717}
2718
Monika Singh94316462018-03-15 18:39:01 +05302719int read_rollback_index(uint32_t loc, uint64_t *roll_back_index)
2720{
2721 if (!devinfo_present) {
2722 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2723 return -EINVAL;
2724 }
2725 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2726 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2727 __func__, loc, ARRAY_SIZE(device.rollback_index));
2728 ASSERT(0);
2729 }
2730
2731 *roll_back_index = device.rollback_index[loc];
2732 return 0;
2733}
2734
2735int write_rollback_index(uint32_t loc, uint64_t roll_back_index)
2736{
2737 if (!devinfo_present) {
2738 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2739 return -EINVAL;
2740 }
2741 if (loc >= ARRAY_SIZE(device.rollback_index)) {
2742 dprintf(CRITICAL, "%s() Loc out of range index: %d, array len: %d\n",
2743 __func__, loc, ARRAY_SIZE(device.rollback_index));
2744 ASSERT(0);
2745 }
2746
2747 device.rollback_index[loc] = roll_back_index;
2748 write_device_info(&device);
2749 return 0;
2750}
2751
Monika Singhb0fad822018-03-15 18:50:55 +05302752int store_userkey(uint8_t *user_key, uint32_t user_key_size)
2753{
2754 if (!devinfo_present) {
2755 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2756 return -EINVAL;
2757 }
2758
2759 if (user_key_size > ARRAY_SIZE(device.user_public_key)) {
2760 dprintf(CRITICAL, "StoreUserKey, UserKeySize too large!\n");
2761 return -ENODEV;
2762 }
2763
2764 memcpy(device.user_public_key, user_key, user_key_size);
2765 device.user_public_key_length = user_key_size;
2766 write_device_info(&device);
2767 return 0;
2768}
2769
2770int erase_userkey()
2771{
2772 if (!devinfo_present) {
2773 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2774 return -EINVAL;
2775 }
2776 memset(device.user_public_key, 0, ARRAY_SIZE(device.user_public_key));
2777 device.user_public_key_length = 0;
2778 write_device_info(&device);
2779 return 0;
2780}
2781
2782int get_userkey(uint8_t **user_key, uint32_t *user_key_size)
2783{
2784 if (!devinfo_present) {
2785 dprintf(CRITICAL, "DeviceInfo not initalized \n");
2786 return -EINVAL;
2787 }
2788 *user_key = device.user_public_key;
2789 *user_key_size = device.user_public_key_length;
2790 return 0;
2791}
2792
Shashank Mittal162244e2011-08-08 19:01:25 -07002793void read_device_info(device_info *dev)
2794{
2795 if(target_is_emmc_boot())
2796 {
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002797 struct device_info *info = memalign(PAGE_SIZE, ROUNDUP(BOOT_IMG_MAX_PAGE_SIZE, PAGE_SIZE));
2798 if(info == NULL)
2799 {
2800 dprintf(CRITICAL, "Failed to allocate memory for device info struct\n");
2801 ASSERT(0);
2802 }
2803 info_buf = info;
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002804
2805#if USE_RPMB_FOR_DEVINFO
Mayank Grover912eaa62017-10-26 12:08:53 +05302806 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302807 is_secure_boot_enable()) {
2808 if((read_device_info_rpmb((void*) info, PAGE_SIZE)) < 0)
2809 ASSERT(0);
Sridhar Parasurame1a97922015-07-27 15:31:22 -07002810 }
Channagoud Kadabic80cb492015-04-28 16:08:28 -07002811 else
2812 read_device_info_mmc(info);
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002813#else
2814 read_device_info_mmc(info);
2815#endif
2816
2817 if (memcmp(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE))
2818 {
2819 memcpy(info->magic, DEVICE_MAGIC, DEVICE_MAGIC_SIZE);
lijuang511a2b52015-08-14 20:50:51 +08002820 if (is_secure_boot_enable()) {
Channagoud Kadabi05f78ba2015-07-06 11:58:14 -07002821 info->is_unlocked = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302822#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302823 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302824 info->is_unlock_critical = 0;
Parth Dixitddbc7352015-10-18 03:13:31 +05302825#endif
lijuang511a2b52015-08-14 20:50:51 +08002826 } else {
Channagoud Kadabi2fda4092015-07-07 13:34:11 -07002827 info->is_unlocked = 1;
Monika Singh292b3e92018-03-17 22:40:23 +05302828#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302829 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05302830 info->is_unlock_critical = 1;
Parth Dixitddbc7352015-10-18 03:13:31 +05302831#endif
lijuang511a2b52015-08-14 20:50:51 +08002832 }
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002833 info->is_tampered = 0;
2834 info->charger_screen_enabled = 0;
Monika Singh292b3e92018-03-17 22:40:23 +05302835#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302836 if (VB_M <= target_get_vb_version())
Monika Singh1c71a1c2019-12-03 12:12:48 +05302837 {
Mayank Grover889be1b2017-09-12 20:12:23 +05302838 info->verity_mode = 1; //enforcing by default
Monika Singh1c71a1c2019-12-03 12:12:48 +05302839 info->user_public_key_length = 0;
2840 memset(info->rollback_index, 0, sizeof(info->rollback_index));
2841 memset(info->user_public_key, 0, sizeof(info->user_public_key));
2842 }
Parth Dixitddbc7352015-10-18 03:13:31 +05302843#endif
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002844 write_device_info(info);
2845 }
jessicatseng8e7644c2020-04-22 11:13:20 +08002846
2847 info->charger_screen_enabled = 1;
2848 write_device_info(info);
2849
Channagoud Kadabi036c6052015-02-09 15:19:59 -08002850 memcpy(dev, info, sizeof(device_info));
Sridhar Parasuram7e16d172015-07-05 11:35:23 -07002851 free(info);
Shashank Mittal162244e2011-08-08 19:01:25 -07002852 }
2853 else
2854 {
2855 read_device_info_flash(dev);
2856 }
2857}
2858
2859void reset_device_info()
2860{
2861 dprintf(ALWAYS, "reset_device_info called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002862 device.is_tampered = 0;
Shashank Mittal162244e2011-08-08 19:01:25 -07002863 write_device_info(&device);
2864}
2865
2866void set_device_root()
2867{
2868 dprintf(ALWAYS, "set_device_root called.");
Shashank Mittala0032282011-08-26 14:50:11 -07002869 device.is_tampered = 1;
Shashank Mittal162244e2011-08-08 19:01:25 -07002870 write_device_info(&device);
2871}
2872
lijuang4ece1e72015-08-14 21:02:36 +08002873/* set device unlock value
2874 * Must check FRP before call this function
2875 * Need to wipe data when unlock status changed
2876 * type 0: oem unlock
2877 * type 1: unlock critical
2878 * status 0: unlock as false
2879 * status 1: lock as true
2880 */
2881void set_device_unlock_value(int type, bool status)
lijuang21f12f52015-08-22 16:22:19 +08002882{
lijuang4ece1e72015-08-14 21:02:36 +08002883 if (type == UNLOCK)
2884 device.is_unlocked = status;
Monika Singh292b3e92018-03-17 22:40:23 +05302885#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302886 else if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302887 type == UNLOCK_CRITICAL)
2888 device.is_unlock_critical = status;
Parth Dixitddbc7352015-10-18 03:13:31 +05302889#endif
lijuang4ece1e72015-08-14 21:02:36 +08002890 write_device_info(&device);
2891}
2892
2893static void set_device_unlock(int type, bool status)
2894{
2895 int is_unlocked = -1;
2896 char response[MAX_RSP_SIZE];
2897
2898 /* check device unlock status if it is as expected */
2899 if (type == UNLOCK)
2900 is_unlocked = device.is_unlocked;
Monika Singh292b3e92018-03-17 22:40:23 +05302901#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05302902 if(VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05302903 type == UNLOCK_CRITICAL)
2904 {
2905 is_unlocked = device.is_unlock_critical;
2906 }
Parth Dixitddbc7352015-10-18 03:13:31 +05302907#endif
lijuang4ece1e72015-08-14 21:02:36 +08002908 if (is_unlocked == status) {
2909 snprintf(response, sizeof(response), "\tDevice already : %s", (status ? "unlocked!" : "locked!"));
2910 fastboot_info(response);
2911 fastboot_okay("");
2912 return;
2913 }
2914
2915 /* status is true, it means to unlock device */
lijuang07c5d6e2018-04-23 18:32:13 +08002916 if (status && !is_allow_unlock) {
2917 fastboot_fail("oem unlock is not allowed");
2918 return;
2919 }
lijuang21f12f52015-08-22 16:22:19 +08002920
lijuang4ece1e72015-08-14 21:02:36 +08002921#if FBCON_DISPLAY_MSG
lijuang07c5d6e2018-04-23 18:32:13 +08002922 display_unlock_menu(type, status);
2923 fastboot_okay("");
2924 return;
lijuang4ece1e72015-08-14 21:02:36 +08002925#else
lijuang07c5d6e2018-04-23 18:32:13 +08002926 if (status && type == UNLOCK) {
2927 fastboot_fail("Need wipe userdata. Do 'fastboot oem unlock-go'");
2928 return;
lijuang21f12f52015-08-22 16:22:19 +08002929 }
lijuang07c5d6e2018-04-23 18:32:13 +08002930#endif
lijuang4ece1e72015-08-14 21:02:36 +08002931
2932 set_device_unlock_value(type, status);
2933
2934 /* wipe data */
2935 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05302936 memset(&msg, 0, sizeof(msg));
lijuang4ece1e72015-08-14 21:02:36 +08002937 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
2938 write_misc(0, &msg, sizeof(msg));
2939
2940 fastboot_okay("");
2941 reboot_device(RECOVERY_MODE);
lijuang21f12f52015-08-22 16:22:19 +08002942}
2943
lijuang511a2b52015-08-14 20:50:51 +08002944static bool critical_flash_allowed(const char * entry)
2945{
2946 uint32_t i = 0;
2947 if (entry == NULL)
2948 return false;
2949
2950 for (i = 0; i < ARRAY_SIZE(critical_flash_allowed_ptn); i++) {
2951 if(!strcmp(entry, critical_flash_allowed_ptn[i]))
2952 return true;
2953 }
2954 return false;
Matthew Qin271927e2015-03-31 22:07:07 -04002955}
2956
2957#if DEVICE_TREE
Amol Jadicb524072012-08-09 16:40:18 -07002958int copy_dtb(uint8_t *boot_image_start, unsigned int scratch_offset)
2959{
2960 uint32 dt_image_offset = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002961 uint32_t n;
Monika Singh292b3e92018-03-17 22:40:23 +05302962 struct dt_table *table = NULL;
Amol Jadicb524072012-08-09 16:40:18 -07002963 struct dt_entry dt_entry;
Monika Singh292b3e92018-03-17 22:40:23 +05302964 uint32_t dt_hdr_size = 0;
Amol Jadicb524072012-08-09 16:40:18 -07002965 unsigned int compressed_size = 0;
2966 unsigned int dtb_size = 0;
2967 unsigned int out_avai_len = 0;
2968 unsigned char *out_addr = NULL;
2969 unsigned char *best_match_dt_addr = NULL;
2970 int rc;
2971
Mayank Grovere1ab96c2018-09-04 20:31:31 +05302972 boot_img_hdr *hdr = (boot_img_hdr *) (boot_image_start);
Amol Jadicb524072012-08-09 16:40:18 -07002973
Parth Dixit4097b622016-03-15 14:42:27 +05302974#ifndef OSVERSION_IN_BOOTIMAGE
2975 dt_size = hdr->dt_size;
2976#endif
2977
2978 if(dt_size != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002979 /* add kernel offset */
2980 dt_image_offset += page_size;
2981 n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
2982 dt_image_offset += n;
2983
2984 /* add ramdisk offset */
2985 n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
2986 dt_image_offset += n;
2987
2988 /* add second offset */
2989 if(hdr->second_size != 0) {
2990 n = ROUND_TO_PAGE(hdr->second_size, page_mask);
2991 dt_image_offset += n;
2992 }
2993
2994 /* offset now point to start of dt.img */
Deepa Dinamani28c0ffe2012-09-24 11:45:21 -07002995 table = (struct dt_table*)(boot_image_start + dt_image_offset);
Amol Jadicb524072012-08-09 16:40:18 -07002996
Deepa Dinamani19648b42013-09-05 17:05:55 -07002997 if (dev_tree_validate(table, hdr->page_size, &dt_hdr_size) != 0) {
Amol Jadicb524072012-08-09 16:40:18 -07002998 dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
2999 return -1;
3000 }
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303001
3002 /* Its Error if, dt_hdr_size (table->num_entries * dt_entry size + Dev_Tree Header)
3003 goes beyound hdr->dt_size*/
Parth Dixit4097b622016-03-15 14:42:27 +05303004 if (dt_hdr_size > ROUND_TO_PAGE(dt_size,hdr->page_size)) {
P.V. Phani Kumar82916762016-03-09 09:20:19 +05303005 dprintf(CRITICAL, "ERROR: Invalid Device Tree size \n");
3006 return -1;
3007 }
3008
Joel Kingaa335dc2013-06-03 16:11:08 -07003009 /* Find index of device tree within device tree table */
3010 if(dev_tree_get_entry_info(table, &dt_entry) != 0){
Amol Jadicb524072012-08-09 16:40:18 -07003011 dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
3012 return -1;
3013 }
3014
Matthew Qin271927e2015-03-31 22:07:07 -04003015 best_match_dt_addr = (unsigned char *)boot_image_start + dt_image_offset + dt_entry.offset;
3016 if (is_gzip_package(best_match_dt_addr, dt_entry.size))
3017 {
3018 out_addr = (unsigned char *)target_get_scratch_address() + scratch_offset;
3019 out_avai_len = target_get_max_flash_size() - scratch_offset;
Matthew Qin0b15b322015-05-19 05:20:54 -04003020 dprintf(INFO, "decompressing dtb: start\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003021 rc = decompress(best_match_dt_addr,
3022 dt_entry.size, out_addr, out_avai_len,
3023 &compressed_size, &dtb_size);
3024 if (rc)
3025 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003026 dprintf(CRITICAL, "decompressing dtb failed!!!\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003027 ASSERT(0);
3028 }
3029
Matthew Qin0b15b322015-05-19 05:20:54 -04003030 dprintf(INFO, "decompressing dtb: done\n");
Matthew Qin271927e2015-03-31 22:07:07 -04003031 best_match_dt_addr = out_addr;
3032 } else {
3033 dtb_size = dt_entry.size;
3034 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003035 /* Validate and Read device device tree in the "tags_add */
Mayank Grovere559cec2017-10-17 15:12:03 +05303036 if (check_aboot_addr_range_overlap(hdr->tags_addr, dtb_size) ||
3037 check_ddr_addr_range_bound(hdr->tags_addr, dtb_size))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003038 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303039 dprintf(CRITICAL, "Device tree addresses are not valid.\n");
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003040 return -1;
3041 }
3042
Amol Jadicb524072012-08-09 16:40:18 -07003043 /* Read device device tree in the "tags_add */
Matthew Qin271927e2015-03-31 22:07:07 -04003044 memmove((void*) hdr->tags_addr, (void *)best_match_dt_addr, dtb_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003045 } else
3046 return -1;
Amol Jadicb524072012-08-09 16:40:18 -07003047
3048 /* Everything looks fine. Return success. */
3049 return 0;
3050}
3051#endif
3052
Brian Swetland9c4c0752009-01-25 16:23:50 -08003053void cmd_boot(const char *arg, void *data, unsigned sz)
3054{
3055 unsigned kernel_actual;
3056 unsigned ramdisk_actual;
Kishor PKd8ddcad2017-07-27 13:53:57 +05303057 unsigned second_actual;
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003058 uint32_t image_actual;
3059 uint32_t dt_actual = 0;
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303060 boot_img_hdr *hdr = NULL;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003061 struct kernel64_hdr *kptr = NULL;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003062 char *ptr = ((char*) data);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003063 int ret = 0;
3064 uint8_t dtb_copied = 0;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003065 unsigned int out_len = 0;
3066 unsigned int out_avai_len = 0;
3067 unsigned char *out_addr = NULL;
3068 uint32_t dtb_offset = 0;
3069 unsigned char *kernel_start_addr = NULL;
3070 unsigned int kernel_size = 0;
Matthew Qin271927e2015-03-31 22:07:07 -04003071 unsigned int scratch_offset = 0;
Saranya Chidurab4933332018-10-15 17:30:06 +05303072#if VERIFIED_BOOT_2
3073 void *dtbo_image_buf = NULL;
3074 uint32_t dtbo_image_sz = 0;
3075 void *vbmeta_image_buf = NULL;
3076 uint32_t vbmeta_image_sz = 0;
3077#endif
Monika Singh292b3e92018-03-17 22:40:23 +05303078#if !VERIFIED_BOOT_2
3079 uint32_t sig_actual = 0;
3080 uint32_t sig_size = 0;
3081#ifdef MDTP_SUPPORT
3082 static bool is_mdtp_activated = 0;
3083#endif /* MDTP_SUPPORT */
3084#endif
Matthew Qinbb7923d2015-02-09 10:56:09 +08003085
lijuang2008ff22016-03-07 17:56:27 +08003086#if FBCON_DISPLAY_MSG
3087 /* Exit keys' detection thread firstly */
3088 exit_menu_keys_detection();
3089#endif
3090
Monika Singh292b3e92018-03-17 22:40:23 +05303091#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi6d5375e2015-06-23 17:15:42 -07003092 if(target_build_variant_user() && !device.is_unlocked)
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003093 {
3094 fastboot_fail("unlock device to use this command");
lijuang2008ff22016-03-07 17:56:27 +08003095 goto boot_failed;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003096 }
3097#endif
3098
Brian Swetland9c4c0752009-01-25 16:23:50 -08003099 if (sz < sizeof(hdr)) {
3100 fastboot_fail("invalid bootimage header");
lijuang2008ff22016-03-07 17:56:27 +08003101 goto boot_failed;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003102 }
3103
Mayank Grovere1ab96c2018-09-04 20:31:31 +05303104 hdr = (boot_img_hdr *)data;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003105
3106 /* ensure commandline is terminated */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003107 hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003108
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003109 if(target_is_emmc_boot() && hdr->page_size) {
3110 page_size = hdr->page_size;
Subbaraman Narayanamurthyfbe13a02010-09-10 11:51:12 -07003111 page_mask = page_size - 1;
3112 }
3113
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003114 kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
3115 ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303116 second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003117#if DEVICE_TREE
Parth Dixit4097b622016-03-15 14:42:27 +05303118#ifndef OSVERSION_IN_BOOTIMAGE
3119 dt_size = hdr->dt_size;
3120#endif
3121 dt_actual = ROUND_TO_PAGE(dt_size, page_mask);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003122#endif
3123
3124 image_actual = ADD_OF(page_size, kernel_actual);
3125 image_actual = ADD_OF(image_actual, ramdisk_actual);
Kishor PKd8ddcad2017-07-27 13:53:57 +05303126 image_actual = ADD_OF(image_actual, second_actual);
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003127 image_actual = ADD_OF(image_actual, dt_actual);
3128
Kishor PK5134b332017-05-09 17:50:08 +05303129 /* Checking to prevent oob access in read_der_message_length */
3130 if (image_actual > sz) {
3131 fastboot_fail("bootimage header fields are invalid");
3132 goto boot_failed;
3133 }
Saranya Chidurab4933332018-10-15 17:30:06 +05303134
Monika Singh292b3e92018-03-17 22:40:23 +05303135#if VERIFIED_BOOT_2
Mayank Grover1ceaee22019-04-01 17:54:32 +05303136 /* Pass size of boot partition, as imgsize, to avoid
3137 read fewer bytes error */
3138 image_actual = partition_get_size(partition_get_index("boot"));
Saranya Chidurab4933332018-10-15 17:30:06 +05303139
3140 /* load and validate dtbo partition */
3141 load_validate_dtbo_image(&dtbo_image_buf, &dtbo_image_sz);
3142
3143 /* load vbmeta partition */
3144 load_vbmeta_image(&vbmeta_image_buf, &vbmeta_image_sz);
3145
Monika Singh292b3e92018-03-17 22:40:23 +05303146 memset(&info, 0, sizeof(bootinfo));
Saranya Chidurab4933332018-10-15 17:30:06 +05303147
3148 info.images[IMG_BOOT].image_buffer = SUB_SALT_BUFF_OFFSET(data);
3149 info.images[IMG_BOOT].imgsize = image_actual;
3150 info.images[IMG_BOOT].name = "boot";
3151 ++info.num_loaded_images;
3152
3153 /* Pass loaded dtbo image */
3154 if (dtbo_image_buf != NULL) {
3155 info.images[IMG_DTBO].image_buffer = SUB_SALT_BUFF_OFFSET(dtbo_image_buf);
3156 info.images[IMG_DTBO].imgsize = dtbo_image_sz;
3157 info.images[IMG_DTBO].name = "dtbo";
3158 ++info.num_loaded_images;
3159 }
3160
3161 /* Pass loaded vbmeta image */
3162 if (vbmeta_image_buf != NULL) {
3163 info.images[IMG_VBMETA].image_buffer = vbmeta_image_buf;
3164 info.images[IMG_VBMETA].imgsize = vbmeta_image_sz;
3165 info.images[IMG_VBMETA].name = "vbmeta";
3166 ++info.num_loaded_images;
3167 }
3168
Monika Singh292b3e92018-03-17 22:40:23 +05303169 info.multi_slot_boot = partition_multislot_is_supported();
3170 if (load_image_and_auth(&info))
3171 goto boot_failed;
3172 vbcmdline = info.vbcmdline;
Saranya Chidurab4933332018-10-15 17:30:06 +05303173
3174 /* Free the buffer allocated to vbmeta post verification */
3175 if (vbmeta_image_buf != NULL) {
3176 free(vbmeta_image_buf);
3177 --info.num_loaded_images;
3178 }
Monika Singh292b3e92018-03-17 22:40:23 +05303179#else
Kishor PK5134b332017-05-09 17:50:08 +05303180 sig_size = sz - image_actual;
3181
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303182 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Monika Singh292b3e92018-03-17 22:40:23 +05303183 unsigned chk;
P.V. Phani Kumareecfd822016-03-09 20:09:03 +05303184 /* Calculate the signature length from boot image */
3185 sig_actual = read_der_message_length(
Kishor PK5134b332017-05-09 17:50:08 +05303186 (unsigned char*)(data + image_actual), sig_size);
Monika Singh292b3e92018-03-17 22:40:23 +05303187 chk = ADD_OF(image_actual, sig_actual);
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003188
Monika Singh292b3e92018-03-17 22:40:23 +05303189 if (chk > sz) {
Kishor PK5134b332017-05-09 17:50:08 +05303190 fastboot_fail("bootimage header fields are invalid");
3191 goto boot_failed;
3192 }
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003193 }
3194
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003195 // Initialize boot state before trying to verify boot.img
3196#if VERIFIED_BOOT
Channagoud Kadabi699466e2015-11-03 12:37:42 -08003197 boot_verifier_init();
Mayank Groverb337e932017-01-18 20:00:40 +05303198#endif
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003199 /* Handle overflow if the input image size is greater than
3200 * boot image buffer can hold
3201 */
Monika Singh292b3e92018-03-17 22:40:23 +05303202 if ((target_get_max_flash_size() - page_size) < image_actual)
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003203 {
3204 fastboot_fail("booimage: size is greater than boot image buffer can hold");
lijuang2008ff22016-03-07 17:56:27 +08003205 goto boot_failed;
Channagoud Kadabibf6ce7d2015-09-17 13:25:35 -07003206 }
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003207
Channagoud Kadabifc3b31f2014-06-18 17:41:01 -07003208 /* Verify the boot image
3209 * device & page_size are initialized in aboot_init
3210 */
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003211 if (target_use_signed_kernel() && (!device.is_unlocked)) {
Channagoud Kadabi3d839012014-06-26 14:26:39 -07003212 /* Pass size excluding signature size, otherwise we would try to
3213 * access signature beyond its length
3214 */
Monika Singh292b3e92018-03-17 22:40:23 +05303215 verify_signed_bootimg((uint32_t)data, image_actual);
Sridhar Parasuram7ae9fbc2015-09-17 09:56:30 -07003216 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003217#ifdef MDTP_SUPPORT
3218 else
3219 {
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003220 /* fastboot boot is not allowed when MDTP is activated */
Amit Blay4aa292f2015-04-28 21:55:59 +03003221 mdtp_ext_partition_verification_t ext_partition;
Amit Blay8a510302015-08-17 09:20:01 +03003222
3223 if (!is_mdtp_activated) {
3224 ext_partition.partition = MDTP_PARTITION_NONE;
3225 mdtp_fwlock_verify_lock(&ext_partition);
3226 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003227 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003228
Amir Kotzer7c768c02016-04-13 09:08:05 +03003229 /* If mdtp state cannot be validate, block fastboot boot*/
3230 if(mdtp_activated(&is_mdtp_activated)){
3231 dprintf(CRITICAL, "mdtp_activated cannot validate state.\n");
3232 dprintf(CRITICAL, "Can not proceed with fastboot boot command.\n");
3233 goto boot_failed;
3234 }
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003235 if(is_mdtp_activated){
3236 dprintf(CRITICAL, "fastboot boot command is not available.\n");
lijuang2008ff22016-03-07 17:56:27 +08003237 goto boot_failed;
Shay Nachmani062aa3f2015-05-17 17:28:44 +03003238 }
Amit Blay4aa292f2015-04-28 21:55:59 +03003239#endif /* MDTP_SUPPORT */
Monika Singh292b3e92018-03-17 22:40:23 +05303240#endif /* VERIFIED_BOOT_2 else */
Amit Blay4aa292f2015-04-28 21:55:59 +03003241
Sridhar Parasuram361e4cd2015-09-24 11:19:19 -07003242#if VERIFIED_BOOT
Monika Singh292b3e92018-03-17 22:40:23 +05303243 if (VB_M == target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05303244 {
3245 /* set boot and system versions. */
3246 set_os_version((unsigned char *)data);
3247 // send root of trust
3248 if(!send_rot_command((uint32_t)device.is_unlocked))
3249 ASSERT(0);
3250 }
Parth Dixitbc9b6492015-10-18 00:41:38 +05303251#endif
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003252 /*
Matthew Qinbb7923d2015-02-09 10:56:09 +08003253 * Check if the kernel image is a gzip package. If yes, need to decompress it.
3254 * If not, continue booting.
3255 */
3256 if (is_gzip_package((unsigned char *)(data + page_size), hdr->kernel_size))
3257 {
3258 out_addr = (unsigned char *)target_get_scratch_address();
3259 out_addr = (unsigned char *)(out_addr + image_actual + page_size);
3260 out_avai_len = target_get_max_flash_size() - image_actual - page_size;
Saranya Chidurab4933332018-10-15 17:30:06 +05303261#if VERIFIED_BOOT_2
3262 if (dtbo_image_sz)
3263 out_avai_len -= DTBO_IMG_BUF;
3264#endif
Matthew Qin0b15b322015-05-19 05:20:54 -04003265 dprintf(INFO, "decompressing kernel image: start\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003266 ret = decompress((unsigned char *)(ptr + page_size),
3267 hdr->kernel_size, out_addr, out_avai_len,
3268 &dtb_offset, &out_len);
3269 if (ret)
3270 {
Matthew Qin0b15b322015-05-19 05:20:54 -04003271 dprintf(CRITICAL, "decompressing image failed!!!\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003272 ASSERT(0);
3273 }
3274
Matthew Qin0b15b322015-05-19 05:20:54 -04003275 dprintf(INFO, "decompressing kernel image: done\n");
Matthew Qinbb7923d2015-02-09 10:56:09 +08003276 kptr = (struct kernel64_hdr *)out_addr;
3277 kernel_start_addr = out_addr;
3278 kernel_size = out_len;
3279 } else {
3280 kptr = (struct kernel64_hdr*)((char *)data + page_size);
3281 kernel_start_addr = (unsigned char *)((char *)data + page_size);
3282 kernel_size = hdr->kernel_size;
3283 }
3284
3285 /*
Channagoud Kadabia22144f2013-03-20 11:49:01 -07003286 * Update the kernel/ramdisk/tags address if the boot image header
3287 * has default values, these default values come from mkbootimg when
3288 * the boot image is flashed using fastboot flash:raw
3289 */
Abhimanyu Kapur0f79d572014-02-19 22:03:02 -08003290 update_ker_tags_rdisk_addr(hdr, IS_ARM64(kptr));
Dima Zavin3cadfff2013-03-21 14:30:48 -07003291
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003292 /* Get virtual addresses since the hdr saves physical addresses. */
3293 hdr->kernel_addr = VA(hdr->kernel_addr);
3294 hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
3295 hdr->tags_addr = VA(hdr->tags_addr);
Brian Swetland9c4c0752009-01-25 16:23:50 -08003296
Matthew Qinbb7923d2015-02-09 10:56:09 +08003297 kernel_size = ROUND_TO_PAGE(kernel_size, page_mask);
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003298 /* Check if the addresses in the header are valid. */
Matthew Qinbb7923d2015-02-09 10:56:09 +08003299 if (check_aboot_addr_range_overlap(hdr->kernel_addr, kernel_size) ||
Mayank Grovere559cec2017-10-17 15:12:03 +05303300 check_ddr_addr_range_bound(hdr->kernel_addr, kernel_size) ||
3301 check_aboot_addr_range_overlap(hdr->ramdisk_addr, ramdisk_actual) ||
3302 check_ddr_addr_range_bound(hdr->ramdisk_addr, ramdisk_actual))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003303 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303304 dprintf(CRITICAL, "kernel/ramdisk addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003305 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003306 }
3307
Amol Jadicb524072012-08-09 16:40:18 -07003308#if DEVICE_TREE
Matthew Qin271927e2015-03-31 22:07:07 -04003309 scratch_offset = image_actual + page_size + out_len;
Amol Jadicb524072012-08-09 16:40:18 -07003310 /* find correct dtb and copy it to right location */
Matthew Qin271927e2015-03-31 22:07:07 -04003311 ret = copy_dtb(data, scratch_offset);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003312
3313 dtb_copied = !ret ? 1 : 0;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003314#else
Mayank Grovere559cec2017-10-17 15:12:03 +05303315 if (check_aboot_addr_range_overlap(hdr->tags_addr, MAX_TAGS_SIZE) ||
3316 check_ddr_addr_range_bound(hdr->tags_addr, MAX_TAGS_SIZE))
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003317 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303318 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003319 goto boot_failed;
Deepa Dinamani0e163a42013-05-24 17:08:15 -07003320 }
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003321#endif
3322
3323 /* Load ramdisk & kernel */
3324 memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
Matthew Qinbb7923d2015-02-09 10:56:09 +08003325 memmove((void*) hdr->kernel_addr, (char*) (kernel_start_addr), kernel_size);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003326
3327#if DEVICE_TREE
Mayank Grovere559cec2017-10-17 15:12:03 +05303328 if (check_aboot_addr_range_overlap(hdr->tags_addr, kernel_actual) ||
3329 check_ddr_addr_range_bound(hdr->tags_addr, kernel_actual))
Matthew Qinbb7923d2015-02-09 10:56:09 +08003330 {
Mayank Grovere559cec2017-10-17 15:12:03 +05303331 dprintf(CRITICAL, "Tags addresses are not valid.\n");
lijuang2008ff22016-03-07 17:56:27 +08003332 goto boot_failed;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003333 }
3334
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003335 /*
3336 * If dtb is not found look for appended DTB in the kernel.
3337 * If appended dev tree is found, update the atags with
3338 * memory address to the DTB appended location on RAM.
3339 * Else update with the atags address in the kernel header
3340 */
3341 if (!dtb_copied) {
3342 void *dtb;
Matthew Qinbb7923d2015-02-09 10:56:09 +08003343 dtb = dev_tree_appended((void*)(ptr + page_size),
3344 hdr->kernel_size, dtb_offset,
Dima Zavine63e5572013-05-03 12:23:06 -07003345 (void *)hdr->tags_addr);
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003346 if (!dtb) {
3347 fastboot_fail("dtb not found");
lijuang2008ff22016-03-07 17:56:27 +08003348 goto boot_failed;
Channagoud Kadabi8e9020f2013-04-16 11:24:32 -07003349 }
Amol Jadicb524072012-08-09 16:40:18 -07003350 }
3351#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08003352
3353 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07003354 fastboot_stop();
Brian Swetland9c4c0752009-01-25 16:23:50 -08003355
Dima Zavin77e41f32013-03-06 16:10:43 -08003356 boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07003357 (const char*) hdr->cmdline, board_machtype(),
3358 (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
lijuang2008ff22016-03-07 17:56:27 +08003359
3360 /* fastboot already stop, it's no need to show fastboot menu */
3361 return;
3362boot_failed:
3363#if FBCON_DISPLAY_MSG
3364 /* revert to fastboot menu if boot failed */
3365 display_fastboot_menu();
3366#endif
3367 return;
Brian Swetland9c4c0752009-01-25 16:23:50 -08003368}
3369
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003370void cmd_erase_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08003371{
3372 struct ptentry *ptn;
3373 struct ptable *ptable;
3374
3375 ptable = flash_get_ptable();
3376 if (ptable == NULL) {
3377 fastboot_fail("partition table doesn't exist");
3378 return;
3379 }
3380
3381 ptn = ptable_find(ptable, arg);
3382 if (ptn == NULL) {
3383 fastboot_fail("unknown partition name");
3384 return;
3385 }
3386
Monika Singh292b3e92018-03-17 22:40:23 +05303387 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3388 dprintf(INFO, "erasing avb_custom_key\n");
3389 if (erase_userkey()) {
3390 fastboot_fail("Erasing avb_custom_key failed");
3391 } else {
3392 fastboot_okay("");
3393 }
3394 return;
3395 }
3396
Dima Zavin214cc642009-01-26 11:16:21 -08003397 if (flash_erase(ptn)) {
3398 fastboot_fail("failed to erase partition");
3399 return;
3400 }
3401 fastboot_okay("");
3402}
3403
Bikas Gurungd48bd242010-09-04 19:54:32 -07003404
3405void cmd_erase_mmc(const char *arg, void *data, unsigned sz)
3406{
3407 unsigned long long ptn = 0;
Oliver Wangcee448d2013-10-22 18:40:13 +08003408 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003409 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003410 uint8_t lun = 0;
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303411 char *footer = NULL;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303412 char EraseResultStr[MAX_RSP_SIZE] = "";
3413 VirtualAbMergeStatus SnapshotMergeStatus;
Bikas Gurungd48bd242010-09-04 19:54:32 -07003414
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003415#if VERIFIED_BOOT
3416 if(!strcmp(arg, KEYSTORE_PTN_NAME))
3417 {
3418 if(!device.is_unlocked)
3419 {
3420 fastboot_fail("unlock device to erase keystore");
3421 return;
3422 }
3423 }
3424#endif
3425
Kinson Chikf1a43512011-07-14 11:28:39 -07003426 index = partition_get_index(arg);
3427 ptn = partition_get_offset(index);
Oliver Wangcee448d2013-10-22 18:40:13 +08003428 size = partition_get_size(index);
Neeti Desaica8c9602011-10-06 11:40:00 -07003429
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05303430 if (target_virtual_ab_supported()) {
3431 if (CheckVirtualAbCriticalPartition (arg)) {
3432 snprintf(EraseResultStr, MAX_RSP_SIZE,"Erase of %s is not allowed in %s state",
3433 arg, SnapshotMergeState);
3434 fastboot_fail(EraseResultStr);
3435 return;
3436 }
3437 SnapshotMergeStatus = GetSnapshotMergeStatus ();
3438 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
3439 !strncmp (arg, "super", strlen ("super"))) {
3440
3441 if(SetSnapshotMergeStatus (CANCELLED))
3442 {
3443 fastboot_fail("Failed to update snapshot state to cancel");
3444 return;
3445 }
3446
3447 //updating fbvar snapshot-merge-state
3448 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
3449 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
3450 }
3451 }
3452
Monika Singhc4778b72018-05-16 11:16:42 +05303453 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
3454 dprintf(INFO, "erasing avb_custom_key\n");
3455 if (erase_userkey()) {
3456 fastboot_fail("Erasing avb_custom_key failed");
3457 } else {
3458 fastboot_okay("");
3459 }
3460 return;
3461 }
3462
Kinson Chikf1a43512011-07-14 11:28:39 -07003463 if(ptn == 0) {
Neeti Desaica8c9602011-10-06 11:40:00 -07003464 fastboot_fail("Partition table doesn't exist\n");
Bikas Gurungd48bd242010-09-04 19:54:32 -07003465 return;
3466 }
Kun Liang2f1601a2013-08-12 16:29:54 +08003467
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003468 lun = partition_get_lun(index);
3469 mmc_set_lun(lun);
3470
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003471 if (platform_boot_dev_isemmc())
3472 {
3473 if (mmc_erase_card(ptn, size)) {
3474 fastboot_fail("failed to erase partition\n");
3475 return;
3476 }
3477 } else {
3478 BUF_DMA_ALIGN(out, DEFAULT_ERASE_SIZE);
3479 size = partition_get_size(index);
3480 if (size > DEFAULT_ERASE_SIZE)
3481 size = DEFAULT_ERASE_SIZE;
Kun Liang2f1601a2013-08-12 16:29:54 +08003482
Sridhar Parasuramd7957122015-02-27 11:33:40 -08003483 /* Simple inefficient version of erase. Just writing
3484 0 in first several blocks */
3485 if (mmc_write(ptn , size, (unsigned int *)out)) {
3486 fastboot_fail("failed to erase partition");
3487 return;
3488 }
Vijay Kumar Pendoti0b21f462016-05-02 17:09:18 +05303489 /*Erase FDE metadata at the userdata footer*/
3490 if(!(strncmp(arg, "userdata", 8)))
3491 {
3492 footer = memalign(CACHE_LINE, FOOTER_SIZE);
3493 memset((void *)footer, 0, FOOTER_SIZE);
3494
3495 size = partition_get_size(index);
3496
3497 if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
3498 fastboot_fail("failed to erase userdata footer");
3499 free(footer);
3500 return;
3501 }
3502 free(footer);
3503 }
Bikas Gurungd48bd242010-09-04 19:54:32 -07003504 }
Monika Singh292b3e92018-03-17 22:40:23 +05303505#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05303506 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303507 !(strncmp(arg, "userdata", 8)) &&
3508 send_delete_keys_to_tz())
Sridhar Parasuram32b30662015-07-10 13:33:22 -07003509 ASSERT(0);
3510#endif
Bikas Gurungd48bd242010-09-04 19:54:32 -07003511 fastboot_okay("");
3512}
3513
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003514void cmd_erase(const char *arg, void *data, unsigned sz)
3515{
Monika Singh292b3e92018-03-17 22:40:23 +05303516#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07003517 if (target_build_variant_user())
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003518 {
Sridhar Parasuramc32d07d2015-07-12 10:57:48 -07003519 if(!device.is_unlocked)
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003520 {
Channagoud Kadabi35297672015-06-13 11:09:49 -07003521 fastboot_fail("device is locked. Cannot erase");
Channagoud Kadabice3cf422015-04-17 16:02:30 -07003522 return;
3523 }
3524 }
3525#endif
3526
Sridhar Parasurame94e8152014-10-24 14:06:03 -07003527 if(target_is_emmc_boot())
3528 cmd_erase_mmc(arg, data, sz);
3529 else
3530 cmd_erase_nand(arg, data, sz);
3531}
Bikas Gurungd48bd242010-09-04 19:54:32 -07003532
Mayank Grover11ff9692018-01-11 11:54:49 +05303533/* Get the size from partiton name */
3534static void get_partition_size(const char *arg, char *response)
3535{
3536 uint64_t ptn = 0;
3537 uint64_t size;
3538 int index = INVALID_PTN;
3539
3540 index = partition_get_index(arg);
3541
3542 if (index == INVALID_PTN)
3543 {
3544 dprintf(CRITICAL, "Invalid partition index\n");
3545 return;
3546 }
3547
3548 ptn = partition_get_offset(index);
3549
3550 if(!ptn)
3551 {
3552 dprintf(CRITICAL, "Invalid partition name %s\n", arg);
3553 return;
3554 }
3555
3556 size = partition_get_size(index);
3557
3558 snprintf(response, MAX_RSP_SIZE, "\t 0x%llx", size);
3559 return;
3560}
3561
Mayank Grover52cd10a2018-03-15 12:57:54 +05303562/* Function to check partition type of a partition*/
3563static fs_signature_type
3564check_partition_fs_signature(const char *arg)
3565{
3566 fs_signature_type ret = NO_FS;
3567 int index;
3568 unsigned long long ptn;
Mayank Grover399826a2018-08-27 12:15:15 +05303569 char *buffer = memalign(CACHE_LINE, mmc_blocksize);
3570 uint32_t sb_blk_offset = 0;
3571 char *sb_buffer = buffer;
3572
Mayank Grover52cd10a2018-03-15 12:57:54 +05303573 if (!sb_buffer)
3574 {
3575 dprintf(CRITICAL, "ERROR: Failed to allocate buffer for superblock\n");
3576 goto out;
3577 }
3578
3579 /* Read super block */
3580 if ((index = partition_get_index(arg)) < 0)
3581 {
3582 dprintf(CRITICAL, "ERROR: %s() doesn't exsit\n", arg);
3583 goto out;
3584 }
3585 ptn = partition_get_offset(index);
3586 mmc_set_lun(partition_get_lun(index));
Mayank Grover399826a2018-08-27 12:15:15 +05303587 sb_blk_offset = (FS_SUPERBLOCK_OFFSET/mmc_blocksize);
3588
3589 if(mmc_read(ptn + (sb_blk_offset * mmc_blocksize),
Mayank Grover52cd10a2018-03-15 12:57:54 +05303590 (void *)sb_buffer, mmc_blocksize))
3591 {
3592 dprintf(CRITICAL, "ERROR: Failed to read Superblock\n");
3593 goto out;
3594 }
3595
Mayank Grover399826a2018-08-27 12:15:15 +05303596 if (sb_blk_offset == 0)
3597 sb_buffer += FS_SUPERBLOCK_OFFSET;
3598
3599 if (*((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])) == (uint16)EXT_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303600 {
3601 dprintf(SPEW, "%s() Found EXT FS\n", arg);
3602 ret = EXT_FS_SIGNATURE;
3603 }
Mayank Grover399826a2018-08-27 12:15:15 +05303604 else if (*((uint32 *)(&sb_buffer[F2FS_MAGIC_OFFSET_SB])) == F2FS_MAGIC)
Mayank Grover52cd10a2018-03-15 12:57:54 +05303605 {
3606 dprintf(SPEW, "%s() Found F2FS FS\n", arg);
3607 ret = EXT_F2FS_SIGNATURE;
3608 }
3609 else
3610 {
3611 dprintf(SPEW, "%s() Reverting to default 0x%x\n",
3612 arg, *((uint16 *)(&sb_buffer[EXT_MAGIC_OFFSET_SB])));
3613 ret = NO_FS;
3614 }
3615
3616out:
Mayank Grover399826a2018-08-27 12:15:15 +05303617 if(buffer)
3618 free(buffer);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303619 return ret;
3620}
3621
Mayank Groverd38fe012018-03-13 15:33:16 +05303622/* Function to get partition type */
3623static void get_partition_type(const char *arg, char *response)
3624{
3625 uint n = 0;
Mayank Grover52cd10a2018-03-15 12:57:54 +05303626 fs_signature_type fs_signature;
Mayank Groverd38fe012018-03-13 15:33:16 +05303627
3628 if (arg == NULL ||
3629 response == NULL)
3630 {
3631 dprintf(CRITICAL, "Invalid input parameter\n");
3632 return;
3633 }
3634
3635 /* By default copy raw to response */
Mayank Grover0e559042018-04-11 17:49:30 +05303636 strlcpy(response, RAW_STR, MAX_RSP_SIZE);
Mayank Groverd38fe012018-03-13 15:33:16 +05303637
3638 /* Mark partiton type for known paritions only */
3639 for (n=0; n < ARRAY_SIZE(part_type_known); n++)
3640 {
3641 if (!strncmp(part_type_known[n].part_name, arg, strlen(arg)))
3642 {
Mayank Grover52cd10a2018-03-15 12:57:54 +05303643 /* Check partition for FS signature */
3644 fs_signature = check_partition_fs_signature(arg);
3645 switch (fs_signature)
3646 {
3647 case EXT_FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303648 strlcpy(response, EXT_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303649 break;
3650 case EXT_F2FS_SIGNATURE:
Mayank Grover0e559042018-04-11 17:49:30 +05303651 strlcpy(response, F2FS_STR, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303652 break;
3653 case NO_FS:
Mayank Grover0e559042018-04-11 17:49:30 +05303654 strlcpy(response, part_type_known[n].type_response, MAX_RSP_SIZE);
Mayank Grover52cd10a2018-03-15 12:57:54 +05303655 }
Mayank Groverd38fe012018-03-13 15:33:16 +05303656 }
3657 }
3658 return;
3659}
3660
Mayank Grover11ff9692018-01-11 11:54:49 +05303661/*
3662 * Publish the partition type & size info
3663 * fastboot getvar will publish the required information.
3664 * fastboot getvar partition_size:<partition_name>: partition size in hex
3665 * fastboot getvar partition_type:<partition_name>: partition type (ext/fat)
3666 */
3667static void publish_getvar_partition_info(struct getvar_partition_info *info, uint8_t num_parts)
3668{
Mayank Groverd38fe012018-03-13 15:33:16 +05303669 uint8_t i;
Mayank Grover11ff9692018-01-11 11:54:49 +05303670 static bool published = false;
3671 struct partition_entry *ptn_entry =
3672 partition_get_partition_entries();
3673 memset(info, 0, sizeof(struct getvar_partition_info)* num_parts);
3674
3675 for (i = 0; i < num_parts; i++) {
3676 strlcat(info[i].part_name, (const char *)ptn_entry[i].name, MAX_RSP_SIZE);
3677 strlcat(info[i].getvar_size, "partition-size:", MAX_GET_VAR_NAME_SIZE);
3678 strlcat(info[i].getvar_type, "partition-type:", MAX_GET_VAR_NAME_SIZE);
3679
Mayank Groverd38fe012018-03-13 15:33:16 +05303680 get_partition_type(info[i].part_name, info[i].type_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303681 get_partition_size(info[i].part_name, info[i].size_response);
Mayank Grover11ff9692018-01-11 11:54:49 +05303682 if (strlcat(info[i].getvar_size, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3683 {
3684 dprintf(CRITICAL, "partition size name truncated\n");
3685 return;
3686 }
3687 if (strlcat(info[i].getvar_type, info[i].part_name, MAX_GET_VAR_NAME_SIZE) >= MAX_GET_VAR_NAME_SIZE)
3688 {
3689 dprintf(CRITICAL, "partition type name truncated\n");
3690 return;
3691 }
3692
3693 if (!published)
3694 {
3695 /* publish partition size & type info */
3696 fastboot_publish((const char *) info[i].getvar_size, (const char *) info[i].size_response);
3697 fastboot_publish((const char *) info[i].getvar_type, (const char *) info[i].type_response);
3698 }
3699 }
3700 if (!published)
3701 published = true;
3702}
3703
3704
Ajay Dudani5c761132011-04-07 20:19:04 -07003705void cmd_flash_mmc_img(const char *arg, void *data, unsigned sz)
Shashank Mittal23b8f422010-04-16 19:27:21 -07003706{
3707 unsigned long long ptn = 0;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003708 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003709 int index = INVALID_PTN;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003710 char *token = NULL;
3711 char *pname = NULL;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003712 char *sp;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003713 uint8_t lun = 0;
3714 bool lun_set = false;
Mayank Grover351a75e2017-05-30 20:06:08 +05303715 int current_active_slot = INVALID;
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07003716
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003717 token = strtok_r((char *)arg, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003718 pname = token;
Sridhar Parasuramefc133f2015-05-04 13:35:41 -07003719 token = strtok_r(NULL, ":", &sp);
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003720 if(token)
3721 {
3722 lun = atoi(token);
3723 mmc_set_lun(lun);
3724 lun_set = true;
3725 }
3726
Mao Jinlong226f33a2014-07-04 17:24:10 +08003727 if (pname)
Greg Grisco6e754772011-06-23 12:19:39 -07003728 {
Channagoud Kadabiad259832015-05-29 11:14:17 -07003729 if (!strncmp(pname, "frp-unlock", strlen("frp-unlock")))
3730 {
3731 if (!aboot_frp_unlock(pname, data, sz))
3732 {
3733 fastboot_info("FRP unlock successful");
3734 fastboot_okay("");
3735 }
3736 else
3737 fastboot_fail("Secret key is invalid, please update the bootloader with secret key");
3738
3739 return;
3740 }
3741
Mao Jinlong226f33a2014-07-04 17:24:10 +08003742 if (!strcmp(pname, "partition"))
3743 {
3744 dprintf(INFO, "Attempt to write partition image.\n");
3745 if (write_partition(sz, (unsigned char *) data)) {
3746 fastboot_fail("failed to write partition");
Greg Grisco6e754772011-06-23 12:19:39 -07003747 return;
3748 }
Mayank Grover11ff9692018-01-11 11:54:49 +05303749 /* Re-publish partition table */
3750 publish_getvar_partition_info(part_info, partition_get_partition_count());
Mayank Grover351a75e2017-05-30 20:06:08 +05303751
3752 /* Rescan partition table to ensure we have multislot support*/
3753 if (partition_scan_for_multislot())
3754 {
3755 current_active_slot = partition_find_active_slot();
3756 dprintf(INFO, "Multislot supported: Slot %s active",
3757 (SUFFIX_SLOT(current_active_slot)));
3758 }
3759 partition_mark_active_slot(current_active_slot);
Greg Grisco6e754772011-06-23 12:19:39 -07003760 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003761 else
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003762 {
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003763#if VERIFIED_BOOT
3764 if(!strcmp(pname, KEYSTORE_PTN_NAME))
3765 {
3766 if(!device.is_unlocked)
3767 {
3768 fastboot_fail("unlock device to flash keystore");
3769 return;
3770 }
Gaurav Nebhwanic7313cc2015-12-15 22:25:04 +05303771 if(!boot_verify_validate_keystore((unsigned char *)data,sz))
Shashank Mittald3e54dd2014-08-28 15:24:02 -07003772 {
3773 fastboot_fail("image is not a keystore file");
3774 return;
3775 }
3776 }
3777#endif
Mao Jinlong226f33a2014-07-04 17:24:10 +08003778 index = partition_get_index(pname);
3779 ptn = partition_get_offset(index);
3780 if(ptn == 0) {
3781 fastboot_fail("partition table doesn't exist");
3782 return;
3783 }
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003784
Mayank Grover351a75e2017-05-30 20:06:08 +05303785 if (!strncmp(pname, "boot", strlen("boot"))
3786 || !strcmp(pname, "recovery"))
3787 {
Ashish Bhimanpalliwar84f7db92020-09-23 11:59:16 +05303788 if ((sz < BOOT_MAGIC_SIZE) || memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003789 fastboot_fail("image is not a boot image");
3790 return;
3791 }
Mayank Grover351a75e2017-05-30 20:06:08 +05303792
3793 /* Reset multislot_partition attributes in case of flashing boot */
3794 if (partition_multislot_is_supported())
3795 {
3796 partition_reset_attributes(index);
3797 }
Mao Jinlong226f33a2014-07-04 17:24:10 +08003798 }
3799
3800 if(!lun_set)
3801 {
3802 lun = partition_get_lun(index);
3803 mmc_set_lun(lun);
3804 }
3805
3806 size = partition_get_size(index);
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05303807 if (ROUND_TO_PAGE(sz, mmc_blocksize_mask) > size) {
Mao Jinlong226f33a2014-07-04 17:24:10 +08003808 fastboot_fail("size too large");
3809 return;
3810 }
3811 else if (mmc_write(ptn , sz, (unsigned int *)data)) {
3812 fastboot_fail("flash write failure");
3813 return;
3814 }
Greg Grisco6e754772011-06-23 12:19:39 -07003815 }
Shashank Mittal23b8f422010-04-16 19:27:21 -07003816 }
3817 fastboot_okay("");
3818 return;
3819}
3820
Ajay Dudanide984792015-03-02 09:57:41 -08003821void cmd_flash_meta_img(const char *arg, void *data, unsigned sz)
3822{
3823 int i, images;
3824 meta_header_t *meta_header;
3825 img_header_entry_t *img_header_entry;
Parth Dixit3e2d3032016-03-04 17:11:52 +05303826 /*End of the image address*/
3827 uintptr_t data_end;
3828
3829 if( (UINT_MAX - sz) > (uintptr_t)data )
3830 data_end = (uintptr_t)data + sz;
3831 else
3832 {
3833 fastboot_fail("Cannot flash: image header corrupt");
3834 return;
3835 }
3836
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05303837 if((UINT_MAX - sizeof(meta_header_t) < (uintptr_t)data) || (data_end < ((uintptr_t)data + sizeof(meta_header_t))))
Parth Dixit3e2d3032016-03-04 17:11:52 +05303838 {
3839 fastboot_fail("Cannot flash: image header corrupt");
3840 return;
3841 }
Ajay Dudanide984792015-03-02 09:57:41 -08003842
lijuang8ee21882016-04-19 16:57:11 +08003843 /* If device is locked:
3844 * Forbid to flash image to avoid the device to bypass the image
3845 * which with "any" name other than bootloader. Because it maybe
3846 * a meta package of all partitions.
3847 */
Monika Singh292b3e92018-03-17 22:40:23 +05303848#if VERIFIED_BOOT || VERIFIED_BOOT_2
lijuang8ee21882016-04-19 16:57:11 +08003849 if (target_build_variant_user()) {
3850 if (!device.is_unlocked) {
3851 fastboot_fail("Device is locked, meta image flashing is not allowed");
3852 return;
3853 }
Mayank Grover889be1b2017-09-12 20:12:23 +05303854
Mayank Grover912eaa62017-10-26 12:08:53 +05303855 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05303856 !device.is_unlock_critical)
3857 {
lijuang8ee21882016-04-19 16:57:11 +08003858 fastboot_fail("Device is critical locked, Meta image flashing is not allowed");
3859 return;
3860 }
lijuang8ee21882016-04-19 16:57:11 +08003861 }
3862#endif
3863
Ajay Dudanide984792015-03-02 09:57:41 -08003864 meta_header = (meta_header_t*) data;
Ashish Bhimanpalliwar21494e12020-10-07 13:24:03 +05303865 if(((UINT_MAX - sizeof(meta_header_t) - meta_header->img_hdr_sz) < (uintptr_t)data) || data_end < ((uintptr_t)data + sizeof(meta_header_t) + meta_header->img_hdr_sz))
Parth Dixit3e2d3032016-03-04 17:11:52 +05303866 {
3867 fastboot_fail("Cannot flash: image header corrupt");
3868 return;
3869 }
Ajay Dudanide984792015-03-02 09:57:41 -08003870 img_header_entry = (img_header_entry_t*) (data+sizeof(meta_header_t));
3871
3872 images = meta_header->img_hdr_sz / sizeof(img_header_entry_t);
3873
3874 for (i=0; i<images; i++) {
3875
3876 if((img_header_entry[i].ptn_name == NULL) ||
3877 (img_header_entry[i].start_offset == 0) ||
3878 (img_header_entry[i].size == 0))
3879 break;
Kishor PK49831502017-04-21 17:55:43 +05303880 if ((UINT_MAX - img_header_entry[i].start_offset) < (uintptr_t)data) {
3881 fastboot_fail("Integer overflow detected in start_offset of img");
3882 break;
3883 }
3884 else if ((UINT_MAX - (img_header_entry[i].start_offset + (uintptr_t)data)) < img_header_entry[i].size) {
3885 fastboot_fail("Integer overflow detected in size of img");
3886 break;
3887 }
Parth Dixit3e2d3032016-03-04 17:11:52 +05303888 if( data_end < ((uintptr_t)data + img_header_entry[i].start_offset
3889 + img_header_entry[i].size) )
3890 {
3891 fastboot_fail("Cannot flash: image size mismatch");
3892 break;
3893 }
3894
Ajay Dudanide984792015-03-02 09:57:41 -08003895 cmd_flash_mmc_img(img_header_entry[i].ptn_name,
3896 (void *) data + img_header_entry[i].start_offset,
3897 img_header_entry[i].size);
3898 }
3899
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08003900 if (!strncmp(arg, "bootloader", strlen("bootloader")))
3901 {
3902 strlcpy(device.bootloader_version, TARGET(BOARD), MAX_VERSION_LEN);
3903 strlcat(device.bootloader_version, "-", MAX_VERSION_LEN);
3904 strlcat(device.bootloader_version, meta_header->img_version, MAX_VERSION_LEN);
3905 }
3906 else
3907 {
3908 strlcpy(device.radio_version, TARGET(BOARD), MAX_VERSION_LEN);
3909 strlcat(device.radio_version, "-", MAX_VERSION_LEN);
3910 strlcat(device.radio_version, meta_header->img_version, MAX_VERSION_LEN);
3911 }
3912
3913 write_device_info(&device);
Ajay Dudanide984792015-03-02 09:57:41 -08003914 fastboot_okay("");
3915 return;
3916}
3917
Ajay Dudani5c761132011-04-07 20:19:04 -07003918void cmd_flash_mmc_sparse_img(const char *arg, void *data, unsigned sz)
3919{
3920 unsigned int chunk;
wufeng.jiang813dc352015-06-02 23:02:46 -04003921 uint64_t chunk_data_sz;
Channagoud Kadabif627cf82013-09-09 14:08:20 -07003922 uint32_t *fill_buf = NULL;
3923 uint32_t fill_val;
Mayank Grover4f50bba2017-07-19 18:17:08 +05303924 uint32_t blk_sz_actual = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003925 sparse_header_t *sparse_header;
3926 chunk_header_t *chunk_header;
Ajay Dudaniab18f022011-05-12 14:39:22 -07003927 uint32_t total_blocks = 0;
Ajay Dudani5c761132011-04-07 20:19:04 -07003928 unsigned long long ptn = 0;
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303929 unsigned long long size = 0;
Kinson Chikf1a43512011-07-14 11:28:39 -07003930 int index = INVALID_PTN;
Unnati Gandhi0c8e7c52014-07-17 14:33:09 +05303931 uint32_t i;
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003932 uint8_t lun = 0;
vijay kumar800255e2015-04-24 20:26:19 +05303933 /*End of the sparse image address*/
Parth Dixit64b1a482016-03-07 16:31:26 +05303934 uintptr_t data_end = (uintptr_t)data + sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07003935
Kinson Chikf1a43512011-07-14 11:28:39 -07003936 index = partition_get_index(arg);
3937 ptn = partition_get_offset(index);
3938 if(ptn == 0) {
Ajay Dudani5c761132011-04-07 20:19:04 -07003939 fastboot_fail("partition table doesn't exist");
3940 return;
3941 }
3942
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303943 size = partition_get_size(index);
Channagoud Kadabi65b91002011-10-11 17:34:33 +05303944
Sundarajan Srinivasand3514bb2013-12-04 17:02:00 -08003945 lun = partition_get_lun(index);
3946 mmc_set_lun(lun);
3947
vijay kumar800255e2015-04-24 20:26:19 +05303948 if (sz < sizeof(sparse_header_t)) {
3949 fastboot_fail("size too low");
3950 return;
3951 }
3952
Ajay Dudani5c761132011-04-07 20:19:04 -07003953 /* Read and skip over sparse image header */
3954 sparse_header = (sparse_header_t *) data;
vijay kumar800255e2015-04-24 20:26:19 +05303955
Mayank Grover48bd9bb2017-07-19 12:04:16 +05303956 if (!sparse_header->blk_sz || (sparse_header->blk_sz % 4)){
3957 fastboot_fail("Invalid block size\n");
3958 return;
3959 }
3960
vijay kumar1321f342015-03-27 12:13:42 +05303961 if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
Ajay Dudani876b3282012-12-21 14:12:17 -08003962 fastboot_fail("size too large");
3963 return;
3964 }
3965
vijay kumarde4fcf62015-04-23 13:05:49 +05303966 data += sizeof(sparse_header_t);
vijay kumar800255e2015-04-24 20:26:19 +05303967
Parth Dixit64b1a482016-03-07 16:31:26 +05303968 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05303969 fastboot_fail("buffer overreads occured due to invalid sparse header");
3970 return;
3971 }
3972
vijay kumarde4fcf62015-04-23 13:05:49 +05303973 if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07003974 {
vijay kumarde4fcf62015-04-23 13:05:49 +05303975 fastboot_fail("sparse header size mismatch");
3976 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07003977 }
3978
Ajay Dudanib06c05f2011-05-12 14:46:10 -07003979 dprintf (SPEW, "=== Sparse Image Header ===\n");
3980 dprintf (SPEW, "magic: 0x%x\n", sparse_header->magic);
3981 dprintf (SPEW, "major_version: 0x%x\n", sparse_header->major_version);
3982 dprintf (SPEW, "minor_version: 0x%x\n", sparse_header->minor_version);
3983 dprintf (SPEW, "file_hdr_sz: %d\n", sparse_header->file_hdr_sz);
3984 dprintf (SPEW, "chunk_hdr_sz: %d\n", sparse_header->chunk_hdr_sz);
3985 dprintf (SPEW, "blk_sz: %d\n", sparse_header->blk_sz);
3986 dprintf (SPEW, "total_blks: %d\n", sparse_header->total_blks);
3987 dprintf (SPEW, "total_chunks: %d\n", sparse_header->total_chunks);
Ajay Dudani5c761132011-04-07 20:19:04 -07003988
3989 /* Start processing chunks */
3990 for (chunk=0; chunk<sparse_header->total_chunks; chunk++)
3991 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05303992 /* Make sure the total image size does not exceed the partition size */
3993 if(((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz) >= size) {
3994 fastboot_fail("size too large");
3995 return;
3996 }
Ajay Dudani5c761132011-04-07 20:19:04 -07003997 /* Read and skip over chunk header */
3998 chunk_header = (chunk_header_t *) data;
3999 data += sizeof(chunk_header_t);
4000
Parth Dixit64b1a482016-03-07 16:31:26 +05304001 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304002 fastboot_fail("buffer overreads occured due to invalid sparse header");
4003 return;
4004 }
4005
Ajay Dudani5c761132011-04-07 20:19:04 -07004006 dprintf (SPEW, "=== Chunk Header ===\n");
4007 dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
4008 dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
4009 dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
4010
vijay kumar800255e2015-04-24 20:26:19 +05304011 if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
Ajay Dudani5c761132011-04-07 20:19:04 -07004012 {
vijay kumar800255e2015-04-24 20:26:19 +05304013 fastboot_fail("chunk header size mismatch");
4014 return;
Ajay Dudani5c761132011-04-07 20:19:04 -07004015 }
4016
wufeng.jiang813dc352015-06-02 23:02:46 -04004017 chunk_data_sz = (uint64_t)sparse_header->blk_sz * chunk_header->chunk_sz;
4018
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304019 /* Make sure that the chunk size calculated from sparse image does not
4020 * exceed partition size
4021 */
4022 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + chunk_data_sz > size)
4023 {
4024 fastboot_fail("Chunk data size exceeds partition size");
4025 return;
4026 }
4027
Ajay Dudani5c761132011-04-07 20:19:04 -07004028 switch (chunk_header->chunk_type)
4029 {
4030 case CHUNK_TYPE_RAW:
wufeng.jiang813dc352015-06-02 23:02:46 -04004031 if((uint64_t)chunk_header->total_sz != ((uint64_t)sparse_header->chunk_hdr_sz +
Ajay Dudani5c761132011-04-07 20:19:04 -07004032 chunk_data_sz))
4033 {
4034 fastboot_fail("Bogus chunk size for chunk type Raw");
4035 return;
4036 }
4037
Parth Dixit64b1a482016-03-07 16:31:26 +05304038 if (data_end < (uintptr_t)data + chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304039 fastboot_fail("buffer overreads occured due to invalid sparse header");
4040 return;
4041 }
4042
wufeng.jiang813dc352015-06-02 23:02:46 -04004043 /* chunk_header->total_sz is uint32,So chunk_data_sz is now less than 2^32
4044 otherwise it will return in the line above
4045 */
Ajay Dudaniab18f022011-05-12 14:39:22 -07004046 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
wufeng.jiang813dc352015-06-02 23:02:46 -04004047 (uint32_t)chunk_data_sz,
Ajay Dudaniab18f022011-05-12 14:39:22 -07004048 (unsigned int*)data))
Ajay Dudani5c761132011-04-07 20:19:04 -07004049 {
4050 fastboot_fail("flash write failure");
4051 return;
4052 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304053 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4054 fastboot_fail("Bogus size for RAW chunk type");
4055 return;
4056 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004057 total_blocks += chunk_header->chunk_sz;
wufeng.jiang813dc352015-06-02 23:02:46 -04004058 data += (uint32_t)chunk_data_sz;
Ajay Dudani5c761132011-04-07 20:19:04 -07004059 break;
4060
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004061 case CHUNK_TYPE_FILL:
4062 if(chunk_header->total_sz != (sparse_header->chunk_hdr_sz +
4063 sizeof(uint32_t)))
4064 {
4065 fastboot_fail("Bogus chunk size for chunk type FILL");
4066 return;
4067 }
4068
Mayank Grover4f50bba2017-07-19 18:17:08 +05304069 blk_sz_actual = ROUNDUP(sparse_header->blk_sz, CACHE_LINE);
4070 /* Integer overflow detected */
4071 if (blk_sz_actual < sparse_header->blk_sz)
4072 {
4073 fastboot_fail("Invalid block size");
4074 return;
4075 }
4076
4077 fill_buf = (uint32_t *)memalign(CACHE_LINE, blk_sz_actual);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004078 if (!fill_buf)
4079 {
4080 fastboot_fail("Malloc failed for: CHUNK_TYPE_FILL");
4081 return;
4082 }
4083
Parth Dixit64b1a482016-03-07 16:31:26 +05304084 if (data_end < (uintptr_t)data + sizeof(uint32_t)) {
vijay kumar800255e2015-04-24 20:26:19 +05304085 fastboot_fail("buffer overreads occured due to invalid sparse header");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304086 free(fill_buf);
vijay kumar800255e2015-04-24 20:26:19 +05304087 return;
4088 }
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004089 fill_val = *(uint32_t *)data;
4090 data = (char *) data + sizeof(uint32_t);
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004091
4092 for (i = 0; i < (sparse_header->blk_sz / sizeof(fill_val)); i++)
4093 {
4094 fill_buf[i] = fill_val;
4095 }
4096
Gaurav Nebhwanie94cbe12016-03-17 21:16:34 +05304097 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz))
4098 {
4099 fastboot_fail("bogus size for chunk FILL type");
4100 free(fill_buf);
4101 return;
4102 }
4103
wufeng.jiang813dc352015-06-02 23:02:46 -04004104 for (i = 0; i < chunk_header->chunk_sz; i++)
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004105 {
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304106 /* Make sure that the data written to partition does not exceed partition size */
4107 if ((uint64_t)total_blocks * (uint64_t)sparse_header->blk_sz + sparse_header->blk_sz > size)
4108 {
4109 fastboot_fail("Chunk data size for fill type exceeds partition size");
Gaurav Nebhwani163cbf82016-03-17 21:21:27 +05304110 free(fill_buf);
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304111 return;
4112 }
4113
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004114 if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
4115 sparse_header->blk_sz,
4116 fill_buf))
4117 {
4118 fastboot_fail("flash write failure");
4119 free(fill_buf);
4120 return;
4121 }
4122
4123 total_blocks++;
4124 }
4125
4126 free(fill_buf);
4127 break;
4128
Ajay Dudani5c761132011-04-07 20:19:04 -07004129 case CHUNK_TYPE_DONT_CARE:
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304130 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4131 fastboot_fail("bogus size for chunk DONT CARE type");
4132 return;
4133 }
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004134 total_blocks += chunk_header->chunk_sz;
4135 break;
4136
Ajay Dudani5c761132011-04-07 20:19:04 -07004137 case CHUNK_TYPE_CRC:
4138 if(chunk_header->total_sz != sparse_header->chunk_hdr_sz)
4139 {
wufeng.jiang813dc352015-06-02 23:02:46 -04004140 fastboot_fail("Bogus chunk size for chunk type CRC");
Ajay Dudani5c761132011-04-07 20:19:04 -07004141 return;
4142 }
Aparna Mallavarapu2ae741a2015-03-28 01:41:08 +05304143 if(total_blocks > (UINT_MAX - chunk_header->chunk_sz)) {
4144 fastboot_fail("bogus size for chunk CRC type");
4145 return;
4146 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004147 total_blocks += chunk_header->chunk_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304148 if ((uintptr_t)data > UINT_MAX - chunk_data_sz) {
vijay kumar800255e2015-04-24 20:26:19 +05304149 fastboot_fail("integer overflow occured");
4150 return;
4151 }
wufeng.jiang813dc352015-06-02 23:02:46 -04004152 data += (uint32_t)chunk_data_sz;
Parth Dixit64b1a482016-03-07 16:31:26 +05304153 if (data_end < (uintptr_t)data) {
vijay kumar800255e2015-04-24 20:26:19 +05304154 fastboot_fail("buffer overreads occured due to invalid sparse header");
4155 return;
4156 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004157 break;
4158
Kinson Chik kchik@codeaurora.orgda29b1e2011-05-06 17:36:39 -07004159 default:
Channagoud Kadabif627cf82013-09-09 14:08:20 -07004160 dprintf(CRITICAL, "Unkown chunk type: %x\n",chunk_header->chunk_type);
Ajay Dudani5c761132011-04-07 20:19:04 -07004161 fastboot_fail("Unknown chunk type");
4162 return;
4163 }
4164 }
4165
Ajay Dudani0c6927b2011-05-18 11:12:16 -07004166 dprintf(INFO, "Wrote %d blocks, expected to write %d blocks\n",
4167 total_blocks, sparse_header->total_blks);
4168
4169 if(total_blocks != sparse_header->total_blks)
4170 {
4171 fastboot_fail("sparse image write failure");
4172 }
Ajay Dudani5c761132011-04-07 20:19:04 -07004173
4174 fastboot_okay("");
4175 return;
4176}
4177
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304178static bool CheckVirtualAbCriticalPartition (const char *PartitionName)
4179{
4180 VirtualAbMergeStatus SnapshotMergeStatus;
4181 uint32 Iter = 0;
4182
4183 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4184 if ((SnapshotMergeStatus == MERGING || SnapshotMergeStatus == SNAPSHOTTED)) {
4185 for (Iter = 0; Iter < ARRAY_SIZE (VirtualAbCriticalPartitions); Iter++) {
4186 if (!strncmp (PartitionName, VirtualAbCriticalPartitions[Iter],
4187 strlen (VirtualAbCriticalPartitions[Iter])))
4188 return true;
4189 }
4190 }
4191 return false;
4192}
4193
Ajay Dudani5c761132011-04-07 20:19:04 -07004194void cmd_flash_mmc(const char *arg, void *data, unsigned sz)
4195{
4196 sparse_header_t *sparse_header;
Ajay Dudanide984792015-03-02 09:57:41 -08004197 meta_header_t *meta_header;
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304198 VirtualAbMergeStatus SnapshotMergeStatus;
4199 char FlashResultStr[MAX_RSP_SIZE] = "";
Ajay Dudani5c761132011-04-07 20:19:04 -07004200
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004201#ifdef SSD_ENABLE
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08004202 /* 8 Byte Magic + 2048 Byte xml + Encrypted Data */
4203 unsigned int *magic_number = (unsigned int *) data;
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004204 int ret=0;
4205 uint32 major_version=0;
4206 uint32 minor_version=0;
4207
4208 ret = scm_svc_version(&major_version,&minor_version);
4209 if(!ret)
4210 {
4211 if(major_version >= 2)
4212 {
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004213 if( !strcmp(arg, "ssd") || !strcmp(arg, "tqs") )
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004214 {
4215 ret = encrypt_scm((uint32 **) &data, &sz);
4216 if (ret != 0) {
4217 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4218 return;
4219 }
4220
Amir Samuelovbb65ce02013-05-05 12:20:18 +03004221 /* Protect only for SSD */
4222 if (!strcmp(arg, "ssd")) {
4223 ret = scm_protect_keystore((uint32 *) data, sz);
4224 if (ret != 0) {
4225 dprintf(CRITICAL, "ERROR: scm_protect_keystore Failed\n");
4226 return;
4227 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004228 }
4229 }
4230 else
4231 {
4232 ret = decrypt_scm_v2((uint32 **) &data, &sz);
4233 if(ret != 0)
4234 {
4235 dprintf(CRITICAL,"ERROR: Decryption Failure\n");
4236 return;
4237 }
4238 }
4239 }
4240 else
4241 {
4242 if (magic_number[0] == DECRYPT_MAGIC_0 &&
4243 magic_number[1] == DECRYPT_MAGIC_1)
4244 {
4245 ret = decrypt_scm((uint32 **) &data, &sz);
4246 if (ret != 0) {
4247 dprintf(CRITICAL, "ERROR: Invalid secure image\n");
4248 return;
4249 }
4250 }
4251 else if (magic_number[0] == ENCRYPT_MAGIC_0 &&
4252 magic_number[1] == ENCRYPT_MAGIC_1)
4253 {
4254 ret = encrypt_scm((uint32 **) &data, &sz);
4255 if (ret != 0) {
4256 dprintf(CRITICAL, "ERROR: Encryption Failure\n");
4257 return;
4258 }
4259 }
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004260 }
4261 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004262 else
Neeti Desai127b9e02012-03-20 16:11:23 -07004263 {
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004264 dprintf(CRITICAL,"INVALID SVC Version\n");
4265 return;
Neeti Desai127b9e02012-03-20 16:11:23 -07004266 }
sundarajan srinivasand4b1c482013-02-27 14:15:43 -08004267#endif /* SSD_ENABLE */
Neeti Desai127b9e02012-03-20 16:11:23 -07004268
Monika Singh292b3e92018-03-17 22:40:23 +05304269#if VERIFIED_BOOT || VERIFIED_BOOT_2
Channagoud Kadabi35297672015-06-13 11:09:49 -07004270 if (target_build_variant_user())
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004271 {
lijuang511a2b52015-08-14 20:50:51 +08004272 /* if device is locked:
4273 * common partition will not allow to be flashed
4274 * critical partition will allow to flash image.
4275 */
4276 if(!device.is_unlocked && !critical_flash_allowed(arg)) {
4277 fastboot_fail("Partition flashing is not allowed");
4278 return;
4279 }
Mayank Grover889be1b2017-09-12 20:12:23 +05304280
lijuang511a2b52015-08-14 20:50:51 +08004281 /* if device critical is locked:
4282 * common partition will allow to be flashed
4283 * critical partition will not allow to flash image.
4284 */
Mayank Grover912eaa62017-10-26 12:08:53 +05304285 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304286 !device.is_unlock_critical &&
4287 critical_flash_allowed(arg)) {
4288 fastboot_fail("Critical partition flashing is not allowed");
4289 return;
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004290 }
4291 }
4292#endif
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304293
4294 if (target_virtual_ab_supported())
4295 {
4296 if (CheckVirtualAbCriticalPartition (arg)) {
4297 snprintf(FlashResultStr, MAX_RSP_SIZE,"Flashing of %s is not allowed in %s state",
4298 arg, SnapshotMergeState);
4299 fastboot_fail(FlashResultStr);
4300 return;
4301 }
4302
4303 SnapshotMergeStatus = GetSnapshotMergeStatus ();
4304 if (((SnapshotMergeStatus == MERGING) || (SnapshotMergeStatus == SNAPSHOTTED)) &&
4305 !strncmp (arg, "super", strlen ("super"))) {
4306 if(SetSnapshotMergeStatus (CANCELLED))
4307 {
4308 fastboot_fail("Failed to update snapshot state to cancel");
4309 return;
4310 }
4311
4312 //updating fbvar snapshot-merge-state
4313 snprintf(SnapshotMergeState,strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
4314 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
4315 }
4316 }
4317
Monika Singh292b3e92018-03-17 22:40:23 +05304318 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4319 dprintf(INFO, "flashing avb_custom_key\n");
4320 if (store_userkey(data, sz)) {
4321 fastboot_fail("Flashing avb_custom_key failed");
4322 } else {
4323 fastboot_okay("");
4324 }
4325 return;
4326 }
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004327
kchik@codeaurora.orgbce18ea2011-04-18 20:22:28 -07004328 sparse_header = (sparse_header_t *) data;
Ajay Dudanide984792015-03-02 09:57:41 -08004329 meta_header = (meta_header_t *) data;
4330 if (sparse_header->magic == SPARSE_HEADER_MAGIC)
Ajay Dudani5c761132011-04-07 20:19:04 -07004331 cmd_flash_mmc_sparse_img(arg, data, sz);
Ajay Dudanide984792015-03-02 09:57:41 -08004332 else if (meta_header->magic == META_HEADER_MAGIC)
4333 cmd_flash_meta_img(arg, data, sz);
4334 else
4335 cmd_flash_mmc_img(arg, data, sz);
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004336
4337#if VERIFIED_BOOT
Mayank Grover912eaa62017-10-26 12:08:53 +05304338 if (VB_M <= target_get_vb_version() &&
Mayank Grover889be1b2017-09-12 20:12:23 +05304339 (!strncmp(arg, "system", 6)) &&
4340 !device.verity_mode)
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004341 // reset dm_verity mode to enforcing
4342 device.verity_mode = 1;
4343 write_device_info(&device);
Parth Dixitddbc7352015-10-18 03:13:31 +05304344#endif
Sridhar Parasuramd69f7902015-07-10 13:31:17 -07004345
Ajay Dudani5c761132011-04-07 20:19:04 -07004346 return;
4347}
4348
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004349void cmd_updatevol(const char *vol_name, void *data, unsigned sz)
4350{
4351 struct ptentry *sys_ptn;
4352 struct ptable *ptable;
4353
4354 ptable = flash_get_ptable();
4355 if (ptable == NULL) {
4356 fastboot_fail("partition table doesn't exist");
4357 return;
4358 }
4359
4360 sys_ptn = ptable_find(ptable, "system");
4361 if (sys_ptn == NULL) {
4362 fastboot_fail("system partition not found");
4363 return;
4364 }
4365
4366 sz = ROUND_TO_PAGE(sz, page_mask);
4367 if (update_ubi_vol(sys_ptn, vol_name, data, sz))
4368 fastboot_fail("update_ubi_vol failed");
4369 else
4370 fastboot_okay("");
4371}
4372
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004373void cmd_flash_nand(const char *arg, void *data, unsigned sz)
Dima Zavin214cc642009-01-26 11:16:21 -08004374{
4375 struct ptentry *ptn;
4376 struct ptable *ptable;
4377 unsigned extra = 0;
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304378 uint64_t partition_size = 0;
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304379 unsigned bytes_to_round_page = 0;
4380 unsigned rounded_size = 0;
Dima Zavin214cc642009-01-26 11:16:21 -08004381
Kishor PK38ed93d2017-04-25 14:19:26 +05304382 if((uintptr_t)data > (UINT_MAX - sz)) {
4383 fastboot_fail("Cannot flash: image header corrupt");
4384 return;
4385 }
4386
Dima Zavin214cc642009-01-26 11:16:21 -08004387 ptable = flash_get_ptable();
4388 if (ptable == NULL) {
4389 fastboot_fail("partition table doesn't exist");
4390 return;
4391 }
4392
4393 ptn = ptable_find(ptable, arg);
4394 if (ptn == NULL) {
Tanya Brokhman84eaaf62015-02-24 21:57:06 +02004395 dprintf(INFO, "unknown partition name (%s). Trying updatevol\n",
4396 arg);
4397 cmd_updatevol(arg, data, sz);
Dima Zavin214cc642009-01-26 11:16:21 -08004398 return;
4399 }
4400
Monika Singh292b3e92018-03-17 22:40:23 +05304401 if (!strncmp(arg, "avb_custom_key", strlen("avb_custom_key"))) {
4402 dprintf(INFO, "flashing avb_custom_key\n");
4403 if (store_userkey(data, sz)) {
4404 fastboot_fail("Flashing avb_custom_key failed");
4405 } else {
4406 fastboot_okay("");
4407 }
4408 return;
4409 }
4410
Dima Zavin214cc642009-01-26 11:16:21 -08004411 if (!strcmp(ptn->name, "boot") || !strcmp(ptn->name, "recovery")) {
Kishor PK38ed93d2017-04-25 14:19:26 +05304412 if((sz > BOOT_MAGIC_SIZE) && (!memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE))) {
4413 dprintf(INFO, "Verified the BOOT_MAGIC in image header \n");
4414 } else {
4415 fastboot_fail("Image is not a boot image");
Dima Zavin214cc642009-01-26 11:16:21 -08004416 return;
4417 }
4418 }
4419
Amol Jadi5c61a952012-05-04 17:05:35 -07004420 if (!strcmp(ptn->name, "system")
Deepa Dinamani13e32c42012-03-12 14:34:17 -07004421 || !strcmp(ptn->name, "userdata")
4422 || !strcmp(ptn->name, "persist")
Sundarajan Srinivasanb063a852013-11-19 14:02:27 -08004423 || !strcmp(ptn->name, "recoveryfs")
Sundarajan Srinivasan595b71e2013-11-05 12:44:34 -08004424 || !strcmp(ptn->name, "modem"))
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004425 extra = 1;
Kishor PK38ed93d2017-04-25 14:19:26 +05304426 else {
Vijay Kumar Pendotic6f22a72017-05-19 22:44:34 +05304427 rounded_size = ROUNDUP(sz, page_size);
4428 bytes_to_round_page = rounded_size - sz;
4429 if (bytes_to_round_page) {
4430 if (((uintptr_t)data + sz ) > (UINT_MAX - bytes_to_round_page)) {
4431 fastboot_fail("Integer overflow detected");
4432 return;
4433 }
4434 if (((uintptr_t)data + sz + bytes_to_round_page) >
4435 ((uintptr_t)target_get_scratch_address() + target_get_max_flash_size())) {
4436 fastboot_fail("Buffer size is not aligned to page_size");
4437 return;
4438 }
4439 else {
4440 memset(data + sz, 0, bytes_to_round_page);
4441 sz = rounded_size;
4442 }
Kishor PK38ed93d2017-04-25 14:19:26 +05304443 }
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304444 }
4445
Kishor PK38ed93d2017-04-25 14:19:26 +05304446 /*Checking partition_size for the possible integer overflow */
4447 partition_size = validate_partition_size(ptn);
4448
Gaurav Nebhwanid9730712016-05-06 14:28:29 +05304449 if (sz > partition_size) {
4450 fastboot_fail("Image size too large");
4451 return;
4452 }
4453
Dima Zavin214cc642009-01-26 11:16:21 -08004454 dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
Mayank Grover6cde9352017-06-06 18:45:23 +05304455 if ((sz > UBI_EC_HDR_SIZE) &&
4456 (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE))) {
Tanya Brokhman1c94f1a2015-02-15 09:05:03 +02004457 if (flash_ubi_img(ptn, data, sz)) {
4458 fastboot_fail("flash write failure");
4459 return;
4460 }
4461 } else {
4462 if (flash_write(ptn, extra, data, sz)) {
4463 fastboot_fail("flash write failure");
4464 return;
4465 }
Dima Zavin214cc642009-01-26 11:16:21 -08004466 }
4467 dprintf(INFO, "partition '%s' updated\n", ptn->name);
4468 fastboot_okay("");
4469}
4470
Kishor PK38ed93d2017-04-25 14:19:26 +05304471
4472static inline uint64_t validate_partition_size(struct ptentry *ptn)
4473{
4474 if (ptn->length && flash_num_pages_per_blk() && page_size) {
4475 if ((ptn->length < ( UINT_MAX / flash_num_pages_per_blk())) && ((ptn->length * flash_num_pages_per_blk()) < ( UINT_MAX / page_size))) {
4476 return ptn->length * flash_num_pages_per_blk() * page_size;
4477 }
4478 }
4479 return 0;
4480}
4481
4482
Sridhar Parasurame94e8152014-10-24 14:06:03 -07004483void cmd_flash(const char *arg, void *data, unsigned sz)
4484{
4485 if(target_is_emmc_boot())
4486 cmd_flash_mmc(arg, data, sz);
4487 else
4488 cmd_flash_nand(arg, data, sz);
4489}
4490
Dima Zavin214cc642009-01-26 11:16:21 -08004491void cmd_continue(const char *arg, void *data, unsigned sz)
4492{
4493 fastboot_okay("");
Amol Jadi7c4316c2013-10-07 14:19:26 -07004494 fastboot_stop();
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004495
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004496 if (target_is_emmc_boot())
4497 {
lijuanga40d6302015-07-20 20:10:13 +08004498#if FBCON_DISPLAY_MSG
lijuangde34d502016-02-26 16:04:50 +08004499 /* Exit keys' detection thread firstly */
4500 exit_menu_keys_detection();
lijuanga40d6302015-07-20 20:10:13 +08004501#endif
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004502 boot_linux_from_mmc();
4503 }
4504 else
4505 {
4506 boot_linux_from_flash();
4507 }
Dima Zavin214cc642009-01-26 11:16:21 -08004508}
4509
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004510void cmd_reboot(const char *arg, void *data, unsigned sz)
4511{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004512 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004513 fastboot_okay("");
4514 reboot_device(0);
4515}
4516
Mayank Grover351a75e2017-05-30 20:06:08 +05304517void cmd_set_active(const char *arg, void *data, unsigned sz)
4518{
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304519 char *p, *sp = NULL;
Mayank Grover351a75e2017-05-30 20:06:08 +05304520 unsigned i,current_active_slot;
4521 const char *current_slot_suffix;
4522
4523 if (!partition_multislot_is_supported())
4524 {
4525 fastboot_fail("Command not supported");
4526 return;
4527 }
4528
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304529 if (target_virtual_ab_supported()) {
4530 if (GetSnapshotMergeStatus () == MERGING) {
4531 fastboot_fail ("Slot Change is not allowed in merging state");
4532 return;
4533 }
4534 }
4535
Mayank Grover351a75e2017-05-30 20:06:08 +05304536 if (arg)
4537 {
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304538 p = strtok_r((char *)arg, ":", &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304539 if (p)
Mayank Grover351a75e2017-05-30 20:06:08 +05304540 {
4541 current_active_slot = partition_find_active_slot();
4542
4543 /* Check if trying to make curent slot active */
4544 current_slot_suffix = SUFFIX_SLOT(current_active_slot);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304545 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4546 (char *)suffix_delimiter, &sp);
4547
Mayank Grover5eb5f692017-07-19 20:16:04 +05304548 if (current_slot_suffix &&
4549 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304550 {
4551 fastboot_okay("Slot already set active");
4552 return;
4553 }
4554 else
4555 {
4556 for (i = 0; i < AB_SUPPORTED_SLOTS; i++)
4557 {
4558 current_slot_suffix = SUFFIX_SLOT(i);
Mayank Grover6ccc1c92017-07-04 17:36:46 +05304559 current_slot_suffix = strtok_r((char *)current_slot_suffix,
4560 (char *)suffix_delimiter, &sp);
Mayank Grover5eb5f692017-07-19 20:16:04 +05304561 if (current_slot_suffix &&
4562 !strncmp(p, current_slot_suffix, strlen(current_slot_suffix)))
Mayank Grover351a75e2017-05-30 20:06:08 +05304563 {
lijuang8b03e5f2019-07-12 18:16:19 +08004564 partition_switch_slots(current_active_slot, i, true);
Mayank Grover351a75e2017-05-30 20:06:08 +05304565 publish_getvar_multislot_vars();
4566 fastboot_okay("");
4567 return;
4568 }
4569 }
4570 }
4571 }
4572 }
4573 fastboot_fail("Invalid slot suffix.");
4574 return;
4575}
4576
Mayank Grover98c4c742019-04-25 17:21:37 +05304577#if DYNAMIC_PARTITION_SUPPORT
4578void cmd_reboot_fastboot(const char *arg, void *data, unsigned sz)
4579{
4580 dprintf(INFO, "rebooting the device - userspace fastboot\n");
4581 if (send_recovery_cmd(RECOVERY_BOOT_FASTBOOT_CMD)) {
4582 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4583 fastboot_fail("Failed to update recovery command");
4584 return;
4585 }
4586 fastboot_okay("");
4587 reboot_device(REBOOT_MODE_UNKNOWN);
4588
4589 //shouldn't come here.
4590 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4591 return;
4592}
4593
4594void cmd_reboot_recovery(const char *arg, void *data, unsigned sz)
4595{
4596 dprintf(INFO, "rebooting the device - recovery\n");
4597 if (send_recovery_cmd(RECOVERY_BOOT_RECOVERY_CMD)) {
4598 dprintf(CRITICAL, "ERROR: Failed to update recovery commands\n");
4599 fastboot_fail("Failed to update recovery command");
4600 return;
4601 }
4602 fastboot_okay("");
4603 reboot_device(REBOOT_MODE_UNKNOWN);
4604
4605 //shouldn't come here.
4606 dprintf(CRITICAL, "ERROR: Failed to reboot device\n");
4607 return;
4608}
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05304609
4610#ifdef VIRTUAL_AB_OTA
4611void CmdUpdateSnapshot(const char *arg, void *data, unsigned sz)
4612{
4613 char *command = NULL;
4614 const char *delim = ":";
4615 char *sp;
4616
4617 if (arg) {
4618 command = strtok_r((char *)arg, delim, &sp);
4619 if (command) {
4620 command++;
4621
4622 if(!strncmp (command, "merge", AsciiStrLen ("merge"))) {
4623 if (GetSnapshotMergeStatus () == MERGING) {
4624 cmd_reboot_fastboot(Arg, Data, Size);
4625 }
4626 FastbootOkay ("");
4627 return;
4628 }
4629 else if (!strncmp (Command, "cancel", AsciiStrLen ("cancel"))) {
4630 if(!device.is_unlocked) {
4631 fastboot_fail ("Snapshot Cancel is not allowed in Lock State");
4632 return;
4633 }
4634
4635 if (SetSnapshotMergeStatus (CANCELLED))
4636 {
4637 fastboot_fail("Failed to update snapshot state to cancel");
4638 return;
4639 }
4640
4641 //updating fbvar snapshot-merge-state
4642 snprintf(SnapshotMergeState, strlen(VabSnapshotMergeStatus[NONE_MERGE_STATUS]) + 1,
4643 "%s", VabSnapshotMergeStatus[NONE_MERGE_STATUS]);
4644 fastboot_okay("");
4645 return;
4646 }
4647 }
4648 }
4649 fastboot_fail("Invalid snapshot-update command");
4650 return;
4651}
4652#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05304653#endif
4654
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004655void cmd_reboot_bootloader(const char *arg, void *data, unsigned sz)
4656{
Shashank Mittald8c42bf2010-06-09 15:44:28 -07004657 dprintf(INFO, "rebooting the device\n");
Chandan Uddaraju94183c02010-01-15 15:13:59 -08004658 fastboot_okay("");
4659 reboot_device(FASTBOOT_MODE);
4660}
4661
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004662void cmd_oem_enable_charger_screen(const char *arg, void *data, unsigned size)
4663{
4664 dprintf(INFO, "Enabling charger screen check\n");
4665 device.charger_screen_enabled = 1;
4666 write_device_info(&device);
4667 fastboot_okay("");
4668}
4669
4670void cmd_oem_disable_charger_screen(const char *arg, void *data, unsigned size)
4671{
4672 dprintf(INFO, "Disabling charger screen check\n");
4673 device.charger_screen_enabled = 0;
4674 write_device_info(&device);
4675 fastboot_okay("");
4676}
4677
lijuanga25d8bb2015-09-16 13:11:52 +08004678void cmd_oem_off_mode_charger(const char *arg, void *data, unsigned size)
4679{
4680 char *p = NULL;
4681 const char *delim = " \t\n\r";
Parth Dixit407f15b2016-01-07 14:47:37 +05304682 char *sp;
lijuanga25d8bb2015-09-16 13:11:52 +08004683
4684 if (arg) {
Parth Dixit407f15b2016-01-07 14:47:37 +05304685 p = strtok_r((char *)arg, delim, &sp);
lijuanga25d8bb2015-09-16 13:11:52 +08004686 if (p) {
4687 if (!strncmp(p, "0", 1)) {
4688 device.charger_screen_enabled = 0;
4689 } else if (!strncmp(p, "1", 1)) {
4690 device.charger_screen_enabled = 1;
4691 }
4692 }
4693 }
4694
4695 /* update charger_screen_enabled value for getvar
4696 * command
4697 */
4698 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
4699 device.charger_screen_enabled);
4700
4701 write_device_info(&device);
4702 fastboot_okay("");
4703}
4704
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304705void cmd_oem_select_display_panel(const char *arg, void *data, unsigned size)
4706{
4707 dprintf(INFO, "Selecting display panel %s\n", arg);
4708 if (arg)
4709 strlcpy(device.display_panel, arg,
4710 sizeof(device.display_panel));
4711 write_device_info(&device);
4712 fastboot_okay("");
4713}
4714
Shashank Mittal162244e2011-08-08 19:01:25 -07004715void cmd_oem_unlock(const char *arg, void *data, unsigned sz)
4716{
lijuang4ece1e72015-08-14 21:02:36 +08004717 set_device_unlock(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304718}
4719
4720void cmd_oem_unlock_go(const char *arg, void *data, unsigned sz)
4721{
lijuang4ece1e72015-08-14 21:02:36 +08004722 if(!device.is_unlocked) {
vijay kumarc65876c2015-04-24 13:29:16 +05304723 if(!is_allow_unlock) {
4724 fastboot_fail("oem unlock is not allowed");
4725 return;
4726 }
4727
lijuang4ece1e72015-08-14 21:02:36 +08004728 set_device_unlock_value(UNLOCK, TRUE);
vijay kumarc65876c2015-04-24 13:29:16 +05304729
lijuang4ece1e72015-08-14 21:02:36 +08004730 /* wipe data */
vijay kumarc65876c2015-04-24 13:29:16 +05304731 struct recovery_message msg;
Kishor PK60a68212017-05-08 16:55:57 +05304732 memset(&msg, 0, sizeof(msg));
vijay kumarc65876c2015-04-24 13:29:16 +05304733 snprintf(msg.recovery, sizeof(msg.recovery), "recovery\n--wipe_data");
4734 write_misc(0, &msg, sizeof(msg));
4735
4736 fastboot_okay("");
4737 reboot_device(RECOVERY_MODE);
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004738 }
4739 fastboot_okay("");
4740}
4741
Channagoud Kadabiad259832015-05-29 11:14:17 -07004742static int aboot_frp_unlock(char *pname, void *data, unsigned sz)
4743{
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304744 int ret=1;
4745 bool authentication_success=false;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004746
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304747 /*
4748 Authentication method not implemented.
4749
4750 OEM to implement, authentication system which on successful validataion,
4751 calls write_allow_oem_unlock() with is_allow_unlock.
4752 */
4753#if 0
4754 authentication_success = oem_specific_auth_mthd();
4755#endif
4756
4757 if (authentication_success)
Channagoud Kadabiad259832015-05-29 11:14:17 -07004758 {
Mayank Grover70f8b0e2017-05-17 11:49:00 +05304759 is_allow_unlock = true;
4760 write_allow_oem_unlock(is_allow_unlock);
4761 ret = 0;
Channagoud Kadabiad259832015-05-29 11:14:17 -07004762 }
4763 return ret;
4764}
4765
Shashank Mittald3e54dd2014-08-28 15:24:02 -07004766void cmd_oem_lock(const char *arg, void *data, unsigned sz)
4767{
lijuang4ece1e72015-08-14 21:02:36 +08004768 set_device_unlock(UNLOCK, FALSE);
Shashank Mittal162244e2011-08-08 19:01:25 -07004769}
4770
Shashank Mittala0032282011-08-26 14:50:11 -07004771void cmd_oem_devinfo(const char *arg, void *data, unsigned sz)
4772{
lijuang511a2b52015-08-14 20:50:51 +08004773 char response[MAX_RSP_SIZE];
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004774 snprintf(response, sizeof(response), "\tDevice tampered: %s", (device.is_tampered ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004775 fastboot_info(response);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004776 snprintf(response, sizeof(response), "\tDevice unlocked: %s", (device.is_unlocked ? "true" : "false"));
4777 fastboot_info(response);
Monika Singh292b3e92018-03-17 22:40:23 +05304778#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05304779 if (VB_M <= target_get_vb_version())
Mayank Grover889be1b2017-09-12 20:12:23 +05304780 {
4781 snprintf(response, sizeof(response), "\tDevice critical unlocked: %s",
4782 (device.is_unlock_critical ? "true" : "false"));
4783 fastboot_info(response);
4784 }
Parth Dixitddbc7352015-10-18 03:13:31 +05304785#endif
Ameya Thakur11cf1a62013-08-05 12:44:48 -07004786 snprintf(response, sizeof(response), "\tCharger screen enabled: %s", (device.charger_screen_enabled ? "true" : "false"));
Shashank Mittala0032282011-08-26 14:50:11 -07004787 fastboot_info(response);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05304788 snprintf(response, sizeof(response), "\tDisplay panel: %s", (device.display_panel));
4789 fastboot_info(response);
Shashank Mittala0032282011-08-26 14:50:11 -07004790 fastboot_okay("");
4791}
4792
lijuang511a2b52015-08-14 20:50:51 +08004793void cmd_flashing_get_unlock_ability(const char *arg, void *data, unsigned sz)
4794{
4795 char response[MAX_RSP_SIZE];
4796 snprintf(response, sizeof(response), "\tget_unlock_ability: %d", is_allow_unlock);
4797 fastboot_info(response);
4798 fastboot_okay("");
4799}
4800
4801void cmd_flashing_lock_critical(const char *arg, void *data, unsigned sz)
4802{
lijuang4ece1e72015-08-14 21:02:36 +08004803 set_device_unlock(UNLOCK_CRITICAL, FALSE);
lijuang511a2b52015-08-14 20:50:51 +08004804}
4805
4806void cmd_flashing_unlock_critical(const char *arg, void *data, unsigned sz)
4807{
lijuang4ece1e72015-08-14 21:02:36 +08004808 set_device_unlock(UNLOCK_CRITICAL, TRUE);
lijuang511a2b52015-08-14 20:50:51 +08004809}
4810
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07004811void cmd_preflash(const char *arg, void *data, unsigned sz)
4812{
4813 fastboot_okay("");
4814}
4815
Mao Flynn7b379f32015-04-20 00:28:30 +08004816static uint8_t logo_header[LOGO_IMG_HEADER_SIZE];
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304817
Mao Flynn7b379f32015-04-20 00:28:30 +08004818int splash_screen_check_header(logo_img_header *header)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304819{
Mao Flynn7b379f32015-04-20 00:28:30 +08004820 if (memcmp(header->magic, LOGO_IMG_MAGIC, 8))
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304821 return -1;
Mao Flynn7b379f32015-04-20 00:28:30 +08004822 if (header->width == 0 || header->height == 0)
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304823 return -1;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05304824 if (((header->blocks == 0) || (header->blocks > UINT_MAX/512))) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05304825 return -1;
4826 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304827 return 0;
4828}
4829
Mao Flynn7b379f32015-04-20 00:28:30 +08004830int splash_screen_flash()
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004831{
4832 struct ptentry *ptn;
4833 struct ptable *ptable;
Mao Flynn7b379f32015-04-20 00:28:30 +08004834 struct logo_img_header *header;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004835 struct fbcon_config *fb_display = NULL;
Channagoud Kadabib3ccf5c2014-12-03 12:39:29 -08004836
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304837 ptable = flash_get_ptable();
4838 if (ptable == NULL) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004839 dprintf(CRITICAL, "ERROR: Partition table not found\n");
4840 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304841 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004842
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304843 ptn = ptable_find(ptable, "splash");
4844 if (ptn == NULL) {
4845 dprintf(CRITICAL, "ERROR: splash Partition not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004846 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304847 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004848 if (flash_read(ptn, 0, (void *)logo_header, LOGO_IMG_HEADER_SIZE)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304849 dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004850 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304851 }
4852
Mao Flynn7b379f32015-04-20 00:28:30 +08004853 header = (struct logo_img_header *)logo_header;
4854 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304855 dprintf(CRITICAL, "ERROR: Boot image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004856 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304857 }
4858
4859 fb_display = fbcon_display();
4860 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05304861 if (header->type &&
4862 ((header->blocks * 512) <= (fb_display->width *
4863 fb_display->height * (fb_display->bpp / 8)))) {
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304864 /* RLE24 compressed data */
Mao Flynn7b379f32015-04-20 00:28:30 +08004865 uint8_t *base = (uint8_t *) fb_display->base + LOGO_IMG_OFFSET;
4866
4867 /* if the logo is full-screen size, remove "fbcon_clear()" */
4868 if ((header->width != fb_display->width)
4869 || (header->height != fb_display->height))
4870 fbcon_clear();
4871
4872 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4873 (uint32_t *)base,
4874 (header->blocks * 512))) {
4875 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4876 return -1;
4877 }
4878 fbcon_extract_to_screen(header, base);
4879 return 0;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004880 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004881
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004882 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4883 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004884 return -1;
4885 }
4886
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304887 uint8_t *base = (uint8_t *) fb_display->base;
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304888 uint32_t fb_size = ROUNDUP(fb_display->width *
4889 fb_display->height *
4890 (fb_display->bpp / 8), 4096);
4891 uint32_t splash_size = ((((header->width * header->height *
4892 fb_display->bpp/8) + 511) >> 9) << 9);
4893
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05304894 if ((header->height * header->width * (fb_display->bpp/8)) > (header->blocks * 512)) {
4895 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4896 return -1;
4897 }
4898
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304899 if (splash_size > fb_size) {
4900 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4901 return -1;
4902 }
4903
Mao Flynn7b379f32015-04-20 00:28:30 +08004904 if (flash_read(ptn + LOGO_IMG_HEADER_SIZE, 0,
4905 (uint32_t *)base,
4906 ((((header->width * header->height * fb_display->bpp/8) + 511) >> 9) << 9))) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304907 fbcon_clear();
Vineet Bajaj99291ed2014-09-09 12:29:46 +05304908 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004909 return -1;
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07004910 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304911 }
4912
Mao Flynn7b379f32015-04-20 00:28:30 +08004913 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304914}
4915
Mao Flynn7b379f32015-04-20 00:28:30 +08004916int splash_screen_mmc()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304917{
4918 int index = INVALID_PTN;
4919 unsigned long long ptn = 0;
4920 struct fbcon_config *fb_display = NULL;
Mao Flynn7b379f32015-04-20 00:28:30 +08004921 struct logo_img_header *header;
Mao Flynn1893a7f2015-06-03 12:03:36 +08004922 uint32_t blocksize, realsize, readsize;
4923 uint8_t *base;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304924
4925 index = partition_get_index("splash");
4926 if (index == 0) {
4927 dprintf(CRITICAL, "ERROR: splash Partition table not found\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004928 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304929 }
4930
4931 ptn = partition_get_offset(index);
4932 if (ptn == 0) {
4933 dprintf(CRITICAL, "ERROR: splash Partition invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004934 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304935 }
4936
Mao Flynn1893a7f2015-06-03 12:03:36 +08004937 mmc_set_lun(partition_get_lun(index));
4938
4939 blocksize = mmc_get_device_blocksize();
4940 if (blocksize == 0) {
4941 dprintf(CRITICAL, "ERROR:splash Partition invalid blocksize\n");
4942 return -1;
4943 }
4944
4945 fb_display = fbcon_display();
Channagoud Kadabidaf10a62015-07-22 11:51:55 -07004946 if (!fb_display)
4947 {
4948 dprintf(CRITICAL, "ERROR: fb config is not allocated\n");
4949 return -1;
4950 }
4951
Mao Flynn1893a7f2015-06-03 12:03:36 +08004952 base = (uint8_t *) fb_display->base;
4953
Kishor PKee5c0a32018-03-06 16:49:46 +05304954 if (mmc_read(ptn + PLL_CODES_OFFSET, (uint32_t *)(base + LOGO_IMG_OFFSET), blocksize)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304955 dprintf(CRITICAL, "ERROR: Cannot read splash image header\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004956 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304957 }
4958
Mao Flynn1893a7f2015-06-03 12:03:36 +08004959 header = (struct logo_img_header *)(base + LOGO_IMG_OFFSET);
Mao Flynn7b379f32015-04-20 00:28:30 +08004960 if (splash_screen_check_header(header)) {
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304961 dprintf(CRITICAL, "ERROR: Splash image header invalid\n");
Mao Flynn7b379f32015-04-20 00:28:30 +08004962 return -1;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304963 }
4964
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304965 if (fb_display) {
Ashish Bhimanpalliwareab60c62020-10-09 16:31:11 +05304966 if (header->type &&
Ashish Bhimanpalliwarce39f482020-10-06 15:27:37 +05304967 (((UINT_MAX - LOGO_IMG_HEADER_SIZE) / 512) >= header->blocks) &&
raghavendra ambadas554f4fd2018-10-09 15:50:40 +05304968 ((header->blocks * 512) <= (fb_display->width *
4969 fb_display->height * (fb_display->bpp / 8)))) {
4970 /* 1 RLE24 compressed data */
Mao Flynn1893a7f2015-06-03 12:03:36 +08004971 base += LOGO_IMG_OFFSET;
Mao Flynn7b379f32015-04-20 00:28:30 +08004972
Mao Flynn1893a7f2015-06-03 12:03:36 +08004973 realsize = header->blocks * 512;
4974 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
4975
4976 /* if the logo is not full-screen size, clean screen */
Mao Flynn7b379f32015-04-20 00:28:30 +08004977 if ((header->width != fb_display->width)
4978 || (header->height != fb_display->height))
4979 fbcon_clear();
4980
Sachin Bhayare619e9e42017-05-15 13:10:31 +05304981 uint32_t fb_size = ROUNDUP(fb_display->width *
4982 fb_display->height *
4983 (fb_display->bpp / 8), 4096);
4984
4985 if (readsize > fb_size) {
4986 dprintf(CRITICAL, "ERROR: Splash image size invalid\n");
4987 return -1;
4988 }
4989
Kishor PKee5c0a32018-03-06 16:49:46 +05304990 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize, (uint32_t *)(base + blocksize), readsize)) {
Mao Flynn7b379f32015-04-20 00:28:30 +08004991 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
4992 return -1;
4993 }
Mao Flynn7b379f32015-04-20 00:28:30 +08004994
Mao Flynn1893a7f2015-06-03 12:03:36 +08004995 fbcon_extract_to_screen(header, (base + LOGO_IMG_HEADER_SIZE));
4996 } else { /* 2 Raw BGR data */
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05304997
Veera Sundaram Sankaranc33416f2015-09-28 10:25:55 -07004998 if ((header->width > fb_display->width) || (header->height > fb_display->height)) {
4999 dprintf(CRITICAL, "Logo config greater than fb config. Fall back default logo\n");
Mao Flynn1893a7f2015-06-03 12:03:36 +08005000 return -1;
5001 }
5002
5003 realsize = header->width * header->height * fb_display->bpp / 8;
5004 readsize = ROUNDUP((realsize + LOGO_IMG_HEADER_SIZE), blocksize) - blocksize;
Ashish Bhimanpalliwar36f9f002021-04-14 13:50:52 +05305005 if (realsize > (header->blocks * 512)) {
5006 dprintf(CRITICAL, "Logo Size error\n");
5007 return -1;
5008 }
Mao Flynn1893a7f2015-06-03 12:03:36 +08005009
5010 if (blocksize == LOGO_IMG_HEADER_SIZE) { /* read the content directly */
Kishor PKee5c0a32018-03-06 16:49:46 +05305011 if (mmc_read((ptn + PLL_CODES_OFFSET + LOGO_IMG_HEADER_SIZE), (uint32_t *)base, readsize)) {
Mao Flynn1893a7f2015-06-03 12:03:36 +08005012 fbcon_clear();
5013 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5014 return -1;
5015 }
5016 } else {
Kishor PKee5c0a32018-03-06 16:49:46 +05305017 if (mmc_read(ptn + PLL_CODES_OFFSET + blocksize ,
Mao Flynn1893a7f2015-06-03 12:03:36 +08005018 (uint32_t *)(base + LOGO_IMG_OFFSET + blocksize), readsize)) {
5019 dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
5020 return -1;
5021 }
5022 memmove(base, (base + LOGO_IMG_OFFSET + LOGO_IMG_HEADER_SIZE), realsize);
5023 }
5024 }
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305025 }
5026
Mao Flynn7b379f32015-04-20 00:28:30 +08005027 return 0;
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305028}
5029
Mao Flynn7b379f32015-04-20 00:28:30 +08005030int fetch_image_from_partition()
Aparna Mallavarapuad8c1ec2013-08-23 17:55:47 +05305031{
5032 if (target_is_emmc_boot()) {
5033 return splash_screen_mmc();
5034 } else {
5035 return splash_screen_flash();
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005036 }
5037}
5038
Mayank Grover351a75e2017-05-30 20:06:08 +05305039void publish_getvar_multislot_vars()
5040{
5041 int i,count;
5042 static bool published = false;
5043 static char slot_count[MAX_RSP_SIZE];
5044 static struct ab_slot_info slot_info[AB_SUPPORTED_SLOTS];
5045 static char active_slot_suffix[MAX_RSP_SIZE];
5046 static char has_slot_pname[NUM_PARTITIONS][MAX_GET_VAR_NAME_SIZE];
5047 static char has_slot_reply[NUM_PARTITIONS][MAX_RSP_SIZE];
5048 const char *tmp;
5049 char tmpbuff[MAX_GET_VAR_NAME_SIZE];
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305050 signed active_slt;
Mayank Grover351a75e2017-05-30 20:06:08 +05305051
5052 if (!published)
5053 {
5054 /* Update slot meta info */
5055 count = partition_fill_partition_meta(has_slot_pname, has_slot_reply,
5056 partition_get_partition_count());
5057 for(i=0; i<count; i++)
5058 {
5059 memset(tmpbuff, 0, MAX_GET_VAR_NAME_SIZE);
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305060 snprintf(tmpbuff, MAX_GET_VAR_NAME_SIZE,"has-slot:%s",
5061 has_slot_pname[i]);
5062 strlcpy(has_slot_pname[i], tmpbuff, MAX_GET_VAR_NAME_SIZE);
Mayank Grover351a75e2017-05-30 20:06:08 +05305063 fastboot_publish(has_slot_pname[i], has_slot_reply[i]);
5064 }
5065
5066 for (i=0; i<AB_SUPPORTED_SLOTS; i++)
5067 {
5068 tmp = SUFFIX_SLOT(i);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305069 tmp++; // to remove "_" from slot_suffix.
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305070 snprintf(slot_info[i].slot_is_unbootable, sizeof(slot_info[i].slot_is_unbootable),
5071 "slot-unbootable:%s", tmp);
5072 snprintf(slot_info[i].slot_is_active, sizeof(slot_info[i].slot_is_active),
5073 "slot-active:%s", tmp);
5074 snprintf(slot_info[i].slot_is_succesful, sizeof(slot_info[i].slot_is_succesful),
5075 "slot-success:%s", tmp);
5076 snprintf(slot_info[i].slot_retry_count, sizeof(slot_info[i].slot_retry_count),
5077 "slot-retry-count:%s", tmp);
Mayank Grover351a75e2017-05-30 20:06:08 +05305078 fastboot_publish(slot_info[i].slot_is_unbootable,
5079 slot_info[i].slot_is_unbootable_rsp);
5080 fastboot_publish(slot_info[i].slot_is_active,
5081 slot_info[i].slot_is_active_rsp);
5082 fastboot_publish(slot_info[i].slot_is_succesful,
5083 slot_info[i].slot_is_succesful_rsp);
5084 fastboot_publish(slot_info[i].slot_retry_count,
5085 slot_info[i].slot_retry_count_rsp);
5086 }
5087 fastboot_publish("current-slot", active_slot_suffix);
5088 snprintf(slot_count, sizeof(slot_count),"%d", AB_SUPPORTED_SLOTS);
5089 fastboot_publish("slot-count", slot_count);
5090 published = true;
5091 }
5092
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305093 active_slt = partition_find_active_slot();
5094 if (active_slt != INVALID)
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305095 {
5096 tmp = SUFFIX_SLOT(active_slt);
5097 tmp++; // to remove "_" from slot_suffix.
5098 snprintf(active_slot_suffix, sizeof(active_slot_suffix), "%s", tmp);
5099 }
Mayank Grover2bd84bb2017-06-20 11:06:07 +05305100 else
5101 strlcpy(active_slot_suffix, "INVALID", sizeof(active_slot_suffix));
5102
Mayank Grover351a75e2017-05-30 20:06:08 +05305103 /* Update partition meta information */
5104 partition_fill_slot_meta(slot_info);
5105 return;
5106}
5107
lijuang4ece1e72015-08-14 21:02:36 +08005108void get_product_name(unsigned char *buf)
5109{
5110 snprintf((char*)buf, MAX_RSP_SIZE, "%s", TARGET(BOARD));
5111 return;
5112}
5113
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305114#if PRODUCT_IOT
5115void get_bootloader_version_iot(unsigned char *buf)
5116{
5117 if (buf != NULL)
5118 {
5119 strlcpy(buf, TARGET(BOARD), MAX_VERSION_LEN);
5120 strlcat(buf, "-", MAX_VERSION_LEN);
5121 strlcat(buf, PRODUCT_IOT_VERSION, MAX_VERSION_LEN);
5122 }
5123 return;
5124}
5125#endif
5126
lijuang4ece1e72015-08-14 21:02:36 +08005127void get_bootloader_version(unsigned char *buf)
5128{
5129 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.bootloader_version);
5130 return;
5131}
5132
5133void get_baseband_version(unsigned char *buf)
5134{
5135 snprintf((char*)buf, MAX_RSP_SIZE, "%s", device.radio_version);
5136 return;
5137}
5138
Monika Singh32a09f72018-03-14 13:08:29 +05305139bool is_device_locked_critical()
5140{
5141 return device.is_unlock_critical ? false:true;
5142}
5143
lijuang4ece1e72015-08-14 21:02:36 +08005144bool is_device_locked()
5145{
5146 return device.is_unlocked ? false:true;
5147}
5148
Monika Singh32a09f72018-03-14 13:08:29 +05305149bool is_verity_enforcing()
5150{
5151 return device.verity_mode ? true:false;
5152}
5153
Amol Jadi5edf3552013-07-23 14:15:34 -07005154/* register commands and variables for fastboot */
5155void aboot_fastboot_register_commands(void)
5156{
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005157 int i;
lijuangf16461c2015-08-03 17:09:34 +08005158 char hw_platform_buf[MAX_RSP_SIZE];
Rahul Shaharee7baede2021-02-02 13:23:57 +05305159 VirtualAbMergeStatus SnapshotMergeStatus;
Amol Jadi5edf3552013-07-23 14:15:34 -07005160
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005161 struct fastboot_cmd_desc cmd_list[] = {
lijuang511a2b52015-08-14 20:50:51 +08005162 /* By default the enabled list is empty. */
5163 {"", NULL},
5164 /* move commands enclosed within the below ifndef to here
5165 * if they need to be enabled in user build.
5166 */
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005167#ifndef DISABLE_FASTBOOT_CMDS
lijuang511a2b52015-08-14 20:50:51 +08005168 /* Register the following commands only for non-user builds */
5169 {"flash:", cmd_flash},
5170 {"erase:", cmd_erase},
5171 {"boot", cmd_boot},
5172 {"continue", cmd_continue},
5173 {"reboot", cmd_reboot},
5174 {"reboot-bootloader", cmd_reboot_bootloader},
5175 {"oem unlock", cmd_oem_unlock},
5176 {"oem unlock-go", cmd_oem_unlock_go},
5177 {"oem lock", cmd_oem_lock},
5178 {"flashing unlock", cmd_oem_unlock},
5179 {"flashing lock", cmd_oem_lock},
5180 {"flashing lock_critical", cmd_flashing_lock_critical},
5181 {"flashing unlock_critical", cmd_flashing_unlock_critical},
5182 {"flashing get_unlock_ability", cmd_flashing_get_unlock_ability},
5183 {"oem device-info", cmd_oem_devinfo},
5184 {"preflash", cmd_preflash},
5185 {"oem enable-charger-screen", cmd_oem_enable_charger_screen},
5186 {"oem disable-charger-screen", cmd_oem_disable_charger_screen},
lijuanga25d8bb2015-09-16 13:11:52 +08005187 {"oem off-mode-charge", cmd_oem_off_mode_charger},
lijuang511a2b52015-08-14 20:50:51 +08005188 {"oem select-display-panel", cmd_oem_select_display_panel},
Mayank Grover6ccc1c92017-07-04 17:36:46 +05305189 {"set_active",cmd_set_active},
Mayank Grover98c4c742019-04-25 17:21:37 +05305190#if DYNAMIC_PARTITION_SUPPORT
5191 {"reboot-fastboot",cmd_reboot_fastboot},
5192 {"reboot-recovery",cmd_reboot_recovery},
5193#endif
Rahul Shaharef7a5f8b2021-02-04 16:51:36 +05305194#ifdef VIRTUAL_AB_OTA
5195 {"snapshot-update", CmdUpdateSnapshot},
5196#endif
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005197#if UNITTEST_FW_SUPPORT
Channagoud Kadabid5ddf482015-09-28 10:31:35 -07005198 {"oem run-tests", cmd_oem_runtests},
Channagoud Kadabi736c4962015-08-21 11:56:52 -07005199#endif
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005200#endif
lijuang511a2b52015-08-14 20:50:51 +08005201 };
Sridhar Parasurame94e8152014-10-24 14:06:03 -07005202
5203 int fastboot_cmds_count = sizeof(cmd_list)/sizeof(cmd_list[0]);
5204 for (i = 1; i < fastboot_cmds_count; i++)
5205 fastboot_register(cmd_list[i].name,cmd_list[i].cb);
5206
Amol Jadi5edf3552013-07-23 14:15:34 -07005207 /* publish variables and their values */
5208 fastboot_publish("product", TARGET(BOARD));
5209 fastboot_publish("kernel", "lk");
5210 fastboot_publish("serialno", sn_buf);
5211
Mayank Grovera64dfbe2018-05-17 14:06:34 +05305212 /*publish hw-revision major(upper 16 bits) and minor(lower 16 bits)*/
5213 snprintf(soc_version_str, MAX_RSP_SIZE, "%x", board_soc_version());
5214 fastboot_publish("hw-revision", soc_version_str);
5215
Amol Jadi5edf3552013-07-23 14:15:34 -07005216 /*
5217 * partition info is supported only for emmc partitions
5218 * Calling this for NAND prints some error messages which
5219 * is harmless but misleading. Avoid calling this for NAND
5220 * devices.
5221 */
5222 if (target_is_emmc_boot())
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305223 publish_getvar_partition_info(part_info, partition_get_partition_count());
Amol Jadi5edf3552013-07-23 14:15:34 -07005224
Mayank Grover351a75e2017-05-30 20:06:08 +05305225 if (partition_multislot_is_supported())
5226 publish_getvar_multislot_vars();
5227
Amol Jadi5edf3552013-07-23 14:15:34 -07005228 /* Max download size supported */
lijuang2fbed912019-07-12 14:15:05 +08005229#if !VERIFIED_BOOT_2
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005230 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5231 target_get_max_flash_size());
lijuang2fbed912019-07-12 14:15:05 +08005232#else
5233 snprintf(max_download_size, MAX_RSP_SIZE, "\t0x%x",
5234 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5235#endif
5236
Amol Jadi5edf3552013-07-23 14:15:34 -07005237 fastboot_publish("max-download-size", (const char *) max_download_size);
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005238 /* Is the charger screen check enabled */
5239 snprintf(charger_screen_enabled, MAX_RSP_SIZE, "%d",
5240 device.charger_screen_enabled);
5241 fastboot_publish("charger-screen-enabled",
5242 (const char *) charger_screen_enabled);
lijuanga25d8bb2015-09-16 13:11:52 +08005243 fastboot_publish("off-mode-charge", (const char *) charger_screen_enabled);
Unnati Gandhi62c8ab82014-01-24 11:01:01 +05305244 snprintf(panel_display_mode, MAX_RSP_SIZE, "%s",
5245 device.display_panel);
5246 fastboot_publish("display-panel",
5247 (const char *) panel_display_mode);
Mukesh Ojhabb6e7f32018-03-02 15:04:06 +05305248
5249 if (target_is_emmc_boot())
5250 {
5251 mmc_blocksize = mmc_get_device_blocksize();
5252 }
5253 else
5254 {
5255 mmc_blocksize = flash_block_size();
5256 }
5257 snprintf(block_size_string, MAX_RSP_SIZE, "0x%x", mmc_blocksize);
5258 fastboot_publish("erase-block-size", (const char *) block_size_string);
5259 fastboot_publish("logical-block-size", (const char *) block_size_string);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305260#if PRODUCT_IOT
5261 get_bootloader_version_iot(&bootloader_version_string);
5262 fastboot_publish("version-bootloader", (const char *) bootloader_version_string);
5263
5264 /* Version baseband is n/a for apq iot devices */
5265 fastboot_publish("version-baseband", "N/A");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305266#else
Channagoud Kadabiaafbbfc2015-03-04 17:52:56 -08005267 fastboot_publish("version-bootloader", (const char *) device.bootloader_version);
5268 fastboot_publish("version-baseband", (const char *) device.radio_version);
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305269#endif
lijuangf16461c2015-08-03 17:09:34 +08005270 fastboot_publish("secure", is_secure_boot_enable()? "yes":"no");
Mayank Grover7b8a8f82017-10-27 13:07:59 +05305271 fastboot_publish("unlocked", device.is_unlocked ? "yes":"no");
lijuangf16461c2015-08-03 17:09:34 +08005272 smem_get_hw_platform_name((unsigned char *) hw_platform_buf, sizeof(hw_platform_buf));
5273 snprintf(get_variant, MAX_RSP_SIZE, "%s %s", hw_platform_buf,
5274 target_is_emmc_boot()? "eMMC":"UFS");
5275 fastboot_publish("variant", (const char *) get_variant);
lijuang65c5a822015-08-29 16:35:36 +08005276#if CHECK_BAT_VOLTAGE
lijuang102dfa92015-10-09 18:31:03 +08005277 update_battery_status();
lijuang65c5a822015-08-29 16:35:36 +08005278 fastboot_publish("battery-voltage", (const char *) battery_voltage);
lijuang102dfa92015-10-09 18:31:03 +08005279 fastboot_publish("battery-soc-ok", (const char *) battery_soc_ok);
lijuang65c5a822015-08-29 16:35:36 +08005280#endif
Mayank Grover98c4c742019-04-25 17:21:37 +05305281 if (target_dynamic_partition_supported())
5282 fastboot_publish("is-userspace", "no");
Rahul Shaharee7baede2021-02-02 13:23:57 +05305283
5284 if (target_virtual_ab_supported()) {
5285 SnapshotMergeStatus = GetSnapshotMergeStatus ();
5286
5287 switch (SnapshotMergeStatus) {
5288 case SNAPSHOTTED:
5289 SnapshotMergeStatus = SNAPSHOTTED;
5290 break;
5291 case MERGING:
5292 SnapshotMergeStatus = MERGING;
5293 break;
5294 default:
5295 SnapshotMergeStatus = NONE_MERGE_STATUS;
5296 break;
5297 }
5298
5299 snprintf(SnapshotMergeState,
5300 strlen(VabSnapshotMergeStatus[SnapshotMergeStatus]) + 1,
5301 "%s", VabSnapshotMergeStatus[SnapshotMergeStatus]);
5302 fastboot_publish("snapshot-update-state", SnapshotMergeState);
5303 }
Amol Jadi5edf3552013-07-23 14:15:34 -07005304}
5305
Brian Swetland9c4c0752009-01-25 16:23:50 -08005306void aboot_init(const struct app_descriptor *app)
5307{
Shashank Mittal4f99a882010-02-01 13:58:50 -08005308 unsigned reboot_mode = 0;
Mayank Grover351a75e2017-05-30 20:06:08 +05305309 int boot_err_type = 0;
5310 int boot_slot = INVALID;
Chandan Uddarajubedca152010-06-02 23:05:15 -07005311
lijuang39831732016-01-08 17:49:02 +08005312 /* Initialise wdog to catch early lk crashes */
5313#if WDOG_SUPPORT
5314 msm_wdog_init();
5315#endif
5316
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005317 /* Setup page size information for nv storage */
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005318 if (target_is_emmc_boot())
5319 {
Channagoud Kadabi749b0f82013-09-10 22:36:02 -07005320 page_size = mmc_page_size();
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005321 page_mask = page_size - 1;
Gaurav Nebhwani4d2389c2016-03-17 21:10:05 +05305322 mmc_blocksize = mmc_get_device_blocksize();
5323 mmc_blocksize_mask = mmc_blocksize - 1;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005324 }
5325 else
5326 {
5327 page_size = flash_page_size();
5328 page_mask = page_size - 1;
5329 }
Deepa Dinamani0e163a42013-05-24 17:08:15 -07005330 ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
5331
Ameya Thakur11cf1a62013-08-05 12:44:48 -07005332 read_device_info(&device);
vijay kumarc65876c2015-04-24 13:29:16 +05305333 read_allow_oem_unlock(&device);
Shashank Mittal162244e2011-08-08 19:01:25 -07005334
Mayank Grover351a75e2017-05-30 20:06:08 +05305335 /* Detect multi-slot support */
5336 if (partition_multislot_is_supported())
5337 {
5338 boot_slot = partition_find_active_slot();
5339 if (boot_slot == INVALID)
5340 {
5341 boot_into_fastboot = true;
5342 dprintf(INFO, "Active Slot: (INVALID)\n");
5343 }
5344 else
5345 {
5346 /* Setting the state of system to boot active slot */
5347 partition_mark_active_slot(boot_slot);
5348 dprintf(INFO, "Active Slot: (%s)\n", SUFFIX_SLOT(boot_slot));
5349 }
5350 }
5351
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005352 /* Display splash screen if enabled */
5353#if DISPLAY_SPLASH_SCREEN
lijuang99c02d82015-02-13 19:04:34 +08005354#if NO_ALARM_DISPLAY
5355 if (!check_alarm_boot()) {
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005356#endif
lijuang99c02d82015-02-13 19:04:34 +08005357 dprintf(SPEW, "Display Init: Start\n");
Ajay Singh Parmara7865a82015-04-16 21:27:52 -07005358#if DISPLAY_HDMI_PRIMARY
5359 if (!strlen(device.display_panel))
5360 strlcpy(device.display_panel, DISPLAY_PANEL_HDMI,
5361 sizeof(device.display_panel));
5362#endif
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005363#if ENABLE_WBC
Channagoud Kadabid801ac72015-08-26 11:21:51 -07005364 /* Wait if the display shutdown is in progress */
5365 while(pm_app_display_shutdown_in_prgs());
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005366 if (!pm_appsbl_display_init_done())
5367 target_display_init(device.display_panel);
5368 else
5369 display_image_on_screen();
5370#else
lijuang99c02d82015-02-13 19:04:34 +08005371 target_display_init(device.display_panel);
Channagoud Kadabi90869ce2015-04-27 11:15:14 -07005372#endif
lijuang99c02d82015-02-13 19:04:34 +08005373 dprintf(SPEW, "Display Init: Done\n");
5374#if NO_ALARM_DISPLAY
5375 }
5376#endif
5377#endif
Aravind Venkateswaran8f076242014-02-25 16:25:30 -08005378
Greg Griscod6250552011-06-29 14:40:23 -07005379 target_serialno((unsigned char *) sn_buf);
Ajay Dudanib06c05f2011-05-12 14:46:10 -07005380 dprintf(SPEW,"serial number: %s\n",sn_buf);
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08005381
Dhaval Patel223ec952013-07-18 14:49:44 -07005382 memset(display_panel_buf, '\0', MAX_PANEL_BUF_SIZE);
5383
Matthew Qindefd5562014-07-11 18:02:40 +08005384 /*
5385 * Check power off reason if user force reset,
5386 * if yes phone will do normal boot.
5387 */
5388 if (is_user_force_reset())
5389 goto normal_boot;
5390
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005391 /* Check if we should do something other than booting up */
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005392 if (keys_get_state(KEY_VOLUMEUP) && keys_get_state(KEY_VOLUMEDOWN))
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005393 {
Pavel Nedeva4c9d3a2013-05-15 14:42:34 +03005394 dprintf(ALWAYS,"dload mode key sequence detected\n");
lijuang395b5e62015-11-19 17:39:44 +08005395 reboot_device(EMERGENCY_DLOAD);
5396 dprintf(CRITICAL,"Failed to reboot into dload mode\n");
5397
Ameya Thakur0b9c2442013-05-10 13:22:56 -07005398 boot_into_fastboot = true;
5399 }
5400 if (!boot_into_fastboot)
5401 {
5402 if (keys_get_state(KEY_HOME) || keys_get_state(KEY_VOLUMEUP))
5403 boot_into_recovery = 1;
5404 if (!boot_into_recovery &&
5405 (keys_get_state(KEY_BACK) || keys_get_state(KEY_VOLUMEDOWN)))
Pavel Nedev5d91d412013-04-29 11:34:24 +03005406 boot_into_fastboot = true;
Subbaraman Narayanamurthy0e445b02011-06-19 21:34:46 -07005407 }
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005408 #if NO_KEYPAD_DRIVER
Kinson Chik0b1c8162011-08-31 16:31:57 -07005409 if (fastboot_trigger())
Pavel Nedev5d91d412013-04-29 11:34:24 +03005410 boot_into_fastboot = true;
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005411 #endif
Chandan Uddarajubedca152010-06-02 23:05:15 -07005412
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005413#if USE_PON_REBOOT_REG
5414 reboot_mode = check_hard_reboot_mode();
5415#else
Ajay Dudani77421292010-10-27 19:34:06 -07005416 reboot_mode = check_reboot_mode();
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005417#endif
5418 if (reboot_mode == RECOVERY_MODE)
5419 {
Ajay Dudani77421292010-10-27 19:34:06 -07005420 boot_into_recovery = 1;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005421 }
5422 else if(reboot_mode == FASTBOOT_MODE)
5423 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005424 boot_into_fastboot = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005425 }
5426 else if(reboot_mode == ALARM_BOOT)
5427 {
Matthew Qind886f3c2014-01-17 16:52:01 +08005428 boot_reason_alarm = true;
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005429 }
Monika Singhb0db4b82018-09-26 12:18:02 +05305430#if VERIFIED_BOOT || VERIFIED_BOOT_2
Mayank Grover912eaa62017-10-26 12:08:53 +05305431 else if (VB_M <= target_get_vb_version())
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005432 {
Mayank Grover889be1b2017-09-12 20:12:23 +05305433 if (reboot_mode == DM_VERITY_ENFORCING)
5434 {
5435 device.verity_mode = 1;
5436 write_device_info(&device);
5437 }
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005438#if ENABLE_VB_ATTEST
Mayank Grover889be1b2017-09-12 20:12:23 +05305439 else if (reboot_mode == DM_VERITY_EIO)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005440#else
Mayank Grover889be1b2017-09-12 20:12:23 +05305441 else if (reboot_mode == DM_VERITY_LOGGING)
Channagoud Kadabi86b0c112016-03-16 19:23:16 -07005442#endif
Mayank Grover889be1b2017-09-12 20:12:23 +05305443 {
5444 device.verity_mode = 0;
5445 write_device_info(&device);
5446 }
5447 else if (reboot_mode == DM_VERITY_KEYSCLEAR)
5448 {
5449 if(send_delete_keys_to_tz())
5450 ASSERT(0);
5451 }
Channagoud Kadabicfcfcc52015-08-05 16:23:42 -07005452 }
Parth Dixitddbc7352015-10-18 03:13:31 +05305453#endif
Ajay Dudani77421292010-10-27 19:34:06 -07005454
Matthew Qindefd5562014-07-11 18:02:40 +08005455normal_boot:
Pavel Nedev5d91d412013-04-29 11:34:24 +03005456 if (!boot_into_fastboot)
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005457 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005458 if (target_is_emmc_boot())
Shashank Mittala0032282011-08-26 14:50:11 -07005459 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005460 if(emmc_recovery_init())
5461 dprintf(ALWAYS,"error in emmc_recovery_init\n");
5462 if(target_use_signed_kernel())
Shashank Mittala0032282011-08-26 14:50:11 -07005463 {
Pavel Nedev5d91d412013-04-29 11:34:24 +03005464 if((device.is_unlocked) || (device.is_tampered))
5465 {
5466 #ifdef TZ_TAMPER_FUSE
Monika Singh98257462018-06-06 11:28:49 +05305467 set_tamper_fuse_cmd(HLOS_IMG_TAMPER_FUSE);
Pavel Nedev5d91d412013-04-29 11:34:24 +03005468 #endif
5469 #if USE_PCOM_SECBOOT
5470 set_tamper_flag(device.is_tampered);
5471 #endif
5472 }
Shashank Mittala0032282011-08-26 14:50:11 -07005473 }
Amit Blay6281ebc2015-01-11 14:44:08 +02005474
Mayank Grover351a75e2017-05-30 20:06:08 +05305475retry_boot:
5476 /* Trying to boot active partition */
5477 if (partition_multislot_is_supported())
5478 {
5479 boot_slot = partition_find_boot_slot();
5480 partition_mark_active_slot(boot_slot);
5481 if (boot_slot == INVALID)
5482 goto fastboot;
5483 }
5484
5485 boot_err_type = boot_linux_from_mmc();
5486 switch (boot_err_type)
5487 {
5488 case ERR_INVALID_PAGE_SIZE:
5489 case ERR_DT_PARSE:
5490 case ERR_ABOOT_ADDR_OVERLAP:
Mayank Grover10cabbe2017-10-30 19:11:05 +05305491 case ERR_INVALID_BOOT_MAGIC:
Mayank Grover351a75e2017-05-30 20:06:08 +05305492 if(partition_multislot_is_supported())
Mayank Grover10cabbe2017-10-30 19:11:05 +05305493 {
5494 /*
5495 * Deactivate current slot, as it failed to
5496 * boot, and retry next slot.
5497 */
5498 partition_deactivate_slot(boot_slot);
Mayank Grover351a75e2017-05-30 20:06:08 +05305499 goto retry_boot;
Mayank Grover10cabbe2017-10-30 19:11:05 +05305500 }
Mayank Grover351a75e2017-05-30 20:06:08 +05305501 else
5502 break;
Mayank Grover351a75e2017-05-30 20:06:08 +05305503 default:
5504 break;
5505 /* going to fastboot menu */
5506 }
Shashank Mittala0032282011-08-26 14:50:11 -07005507 }
Pavel Nedev5d91d412013-04-29 11:34:24 +03005508 else
5509 {
5510 recovery_init();
5511 #if USE_PCOM_SECBOOT
5512 if((device.is_unlocked) || (device.is_tampered))
5513 set_tamper_flag(device.is_tampered);
5514 #endif
5515 boot_linux_from_flash();
5516 }
5517 dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
5518 "to fastboot mode.\n");
Shashank Mittald8c42bf2010-06-09 15:44:28 -07005519 }
Chandan Uddaraju2943fd62010-06-21 10:56:39 -07005520
Mayank Grover351a75e2017-05-30 20:06:08 +05305521fastboot:
Amol Jadi5edf3552013-07-23 14:15:34 -07005522 /* We are here means regular boot did not happen. Start fastboot. */
Channagoud Kadabi4c4884e2013-04-09 17:12:13 -07005523
Amol Jadi5edf3552013-07-23 14:15:34 -07005524 /* register aboot specific fastboot commands */
5525 aboot_fastboot_register_commands();
Amol Jadi57abe4c2011-05-24 15:47:27 -07005526
Amol Jadi5edf3552013-07-23 14:15:34 -07005527 /* dump partition table for debug info */
Kinson Chikf1a43512011-07-14 11:28:39 -07005528 partition_dump();
Amol Jadi5edf3552013-07-23 14:15:34 -07005529
5530 /* initialize and start fastboot */
Saranya Chidura41b34532018-10-16 12:29:52 +05305531#if !VERIFIED_BOOT_2
Amol Jadi5edf3552013-07-23 14:15:34 -07005532 fastboot_init(target_get_scratch_address(), target_get_max_flash_size());
Saranya Chidura41b34532018-10-16 12:29:52 +05305533#else
5534 /* Add salt buffer offset at start of image address to copy VB salt */
5535 fastboot_init(ADD_SALT_BUFF_OFFSET(target_get_scratch_address()),
5536 SUB_SALT_BUFF_OFFSET(target_get_max_flash_size()));
5537#endif
lijuang4ece1e72015-08-14 21:02:36 +08005538#if FBCON_DISPLAY_MSG
lijuang9a7d3b92015-11-30 14:41:24 +08005539 display_fastboot_menu();
lijuang4ece1e72015-08-14 21:02:36 +08005540#endif
Brian Swetland9c4c0752009-01-25 16:23:50 -08005541}
5542
Deepa Dinamani41fa8d62013-05-23 13:25:36 -07005543uint32_t get_page_size()
5544{
5545 return page_size;
5546}
5547
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005548/*
5549 * Calculated and save hash (SHA256) for non-signed boot image.
5550 *
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005551 * @param image_addr - Boot image address
5552 * @param image_size - Size of the boot image
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005553 *
5554 * @return int - 0 on success, negative value on failure.
5555 */
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005556static int aboot_save_boot_hash_mmc(uint32_t image_addr, uint32_t image_size)
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005557{
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005558 unsigned int digest[8];
5559#if IMAGE_VERIF_ALGO_SHA1
5560 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA1;
5561#else
5562 uint32_t auth_algo = CRYPTO_AUTH_ALG_SHA256;
5563#endif
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005564
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005565 target_crypto_init_params();
Veera Sundaram Sankaranf9915462014-12-09 11:54:59 -08005566 hash_find((unsigned char *) image_addr, image_size, (unsigned char *)&digest, auth_algo);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005567
5568 save_kernel_hash_cmd(digest);
Channagoud Kadabi82cf5c62014-08-24 22:17:34 -07005569 dprintf(INFO, "aboot_save_boot_hash_mmc: imagesize_actual size %d bytes.\n", (int) image_size);
Amir Samuelov57a6fa22013-06-05 16:36:43 +03005570
5571 return 0;
5572}
5573
Mayank Grover351a75e2017-05-30 20:06:08 +05305574
Brian Swetland9c4c0752009-01-25 16:23:50 -08005575APP_START(aboot)
5576 .init = aboot_init,
5577APP_END