xref: /rk3399_rockchip-uboot/common/android_bootloader.c (revision df50318e9dc135a4a5a1c3028ae66e89d915ac6a)
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <android_bootloader.h>
8 #include <android_bootloader_message.h>
9 #include <android_avb/avb_slot_verify.h>
10 #include <android_avb/avb_ops_user.h>
11 #include <android_avb/rk_avb_ops_user.h>
12 
13 #include <cli.h>
14 #include <common.h>
15 #include <malloc.h>
16 #include <fs.h>
17 #include <boot_rkimg.h>
18 #include <attestation_key.h>
19 
20 #define ANDROID_PARTITION_BOOT "boot"
21 #define ANDROID_PARTITION_MISC "misc"
22 #define ANDROID_PARTITION_OEM  "oem"
23 #define ANDROID_PARTITION_RECOVERY  "recovery"
24 #define ANDROID_PARTITION_SYSTEM "system"
25 
26 #define ANDROID_ARG_SLOT_SUFFIX "androidboot.slot_suffix="
27 #define ANDROID_ARG_ROOT "root="
28 #define ANDROID_ARG_SERIALNO "androidboot.serialno="
29 #ifdef CONFIG_ROCKCHIP_RESOURCE_IMAGE
30 #define ANDROID_ARG_FDT_FILENAME "rk-kernel.dtb"
31 #define BOOTLOADER_MESSAGE_OFFSET_IN_MISC	(16 * 1024)
32 #define BOOTLOADER_MESSAGE_BLK_OFFSET	(BOOTLOADER_MESSAGE_OFFSET_IN_MISC >> 9)
33 #else
34 #define ANDROID_ARG_FDT_FILENAME "kernel.dtb"
35 #endif
36 
37 char *android_str_append(char *base_name, char *slot_suffix)
38 {
39 	char *part_name;
40 	size_t part_name_len;
41 
42 	part_name_len = strlen(base_name) + 1;
43 	if (slot_suffix)
44 		part_name_len += strlen(slot_suffix);
45 	part_name = malloc(part_name_len);
46 	if (!part_name)
47 		return NULL;
48 	strcpy(part_name, base_name);
49 	if (slot_suffix && (slot_suffix[0] != '\0'))
50 		strcat(part_name, slot_suffix);
51 
52 	return part_name;
53 }
54 
55 int android_bootloader_message_load(
56 	struct blk_desc *dev_desc,
57 	const disk_partition_t *part_info,
58 	struct android_bootloader_message *message)
59 {
60 	ulong message_blocks = sizeof(struct android_bootloader_message) /
61 	    part_info->blksz;
62 	if (message_blocks > part_info->size) {
63 		printf("misc partition too small.\n");
64 		return -1;
65 	}
66 
67 #ifdef CONFIG_RKIMG_BOOTLOADER
68 	if (blk_dread(dev_desc, part_info->start + BOOTLOADER_MESSAGE_BLK_OFFSET,
69 	     message_blocks, message) !=
70 #else
71 	if (blk_dread(dev_desc, part_info->start, message_blocks, message) !=
72 #endif
73 	    message_blocks) {
74 		printf("Could not read from misc partition\n");
75 		return -1;
76 	}
77 	debug("ANDROID: Loaded BCB, %lu blocks.\n", message_blocks);
78 	return 0;
79 }
80 
81 static int android_bootloader_message_write(
82 	struct blk_desc *dev_desc,
83 	const disk_partition_t *part_info,
84 	struct android_bootloader_message *message)
85 {
86 	ulong message_blocks = sizeof(struct android_bootloader_message) /
87 	    part_info->blksz;
88 	if (message_blocks > part_info->size) {
89 		printf("misc partition too small.\n");
90 		return -1;
91 	}
92 
93 	if (blk_dwrite(dev_desc, part_info->start, message_blocks, message) !=
94 	    message_blocks) {
95 		printf("Could not write to misc partition\n");
96 		return -1;
97 	}
98 	debug("ANDROID: Wrote new BCB, %lu blocks.\n", message_blocks);
99 	return 0;
100 }
101 
102 static enum android_boot_mode android_bootloader_load_and_clear_mode(
103 	struct blk_desc *dev_desc,
104 	const disk_partition_t *misc_part_info)
105 {
106 	struct android_bootloader_message bcb;
107 
108 #ifdef CONFIG_FASTBOOT
109 	char *bootloader_str;
110 
111 	/* Check for message from bootloader stored in RAM from a previous boot.
112 	 */
113 	bootloader_str = (char *)CONFIG_FASTBOOT_BUF_ADDR;
114 	if (!strcmp("reboot-bootloader", bootloader_str)) {
115 		bootloader_str[0] = '\0';
116 		return ANDROID_BOOT_MODE_BOOTLOADER;
117 	}
118 #endif
119 
120 	/* Check and update the BCB message if needed. */
121 	if (android_bootloader_message_load(dev_desc, misc_part_info, &bcb) <
122 	    0) {
123 		printf("WARNING: Unable to load the BCB.\n");
124 		return ANDROID_BOOT_MODE_NORMAL;
125 	}
126 
127 	if (!strcmp("bootonce-bootloader", bcb.command)) {
128 		/* Erase the message in the BCB since this value should be used
129 		 * only once.
130 		 */
131 		memset(bcb.command, 0, sizeof(bcb.command));
132 		android_bootloader_message_write(dev_desc, misc_part_info,
133 						 &bcb);
134 		return ANDROID_BOOT_MODE_BOOTLOADER;
135 	}
136 
137 	if (!strcmp("boot-recovery", bcb.command))
138 		return ANDROID_BOOT_MODE_RECOVERY;
139 
140 	return ANDROID_BOOT_MODE_NORMAL;
141 }
142 
143 /**
144  * Return the reboot reason string for the passed boot mode.
145  *
146  * @param mode	The Android Boot mode.
147  * @return a pointer to the reboot reason string for mode.
148  */
149 static const char *android_boot_mode_str(enum android_boot_mode mode)
150 {
151 	switch (mode) {
152 	case ANDROID_BOOT_MODE_NORMAL:
153 		return "(none)";
154 	case ANDROID_BOOT_MODE_RECOVERY:
155 		return "recovery";
156 	case ANDROID_BOOT_MODE_BOOTLOADER:
157 		return "bootloader";
158 	}
159 	return NULL;
160 }
161 
162 static int android_part_get_info_by_name_suffix(struct blk_desc *dev_desc,
163 						const char *base_name,
164 						const char *slot_suffix,
165 						disk_partition_t *part_info)
166 {
167 	char *part_name;
168 	int part_num;
169 	size_t part_name_len;
170 
171 	part_name_len = strlen(base_name) + 1;
172 	if (slot_suffix)
173 		part_name_len += strlen(slot_suffix);
174 	part_name = malloc(part_name_len);
175 	if (!part_name)
176 		return -1;
177 	strcpy(part_name, base_name);
178 	if (slot_suffix && (slot_suffix[0] != '\0'))
179 		strcat(part_name, slot_suffix);
180 
181 	part_num = part_get_info_by_name(dev_desc, part_name, part_info);
182 	if (part_num < 0) {
183 		debug("ANDROID: Could not find partition \"%s\"\n", part_name);
184 		part_num = -1;
185 	}
186 
187 	free(part_name);
188 	return part_num;
189 }
190 
191 static int android_bootloader_boot_bootloader(void)
192 {
193 	const char *fastboot_cmd = env_get("fastbootcmd");
194 
195 	if (fastboot_cmd)
196 		return run_command(fastboot_cmd, CMD_FLAG_ENV);
197 	return -1;
198 }
199 
200 #ifdef CONFIG_SUPPORT_OEM_DTB
201 static int android_bootloader_get_fdt(const char *part_name,
202 		const char *load_file_name)
203 {
204 	const char *dev_iface = "mmc";
205 	struct blk_desc *dev_desc;
206 	disk_partition_t boot_part_info;
207 	char *fdt_addr = NULL;
208 	char slot_suffix[5] = {0};
209 	char dev_part[3] = {0};
210 	loff_t bytes = 0;
211 	loff_t pos = 0;
212 	loff_t len_read;
213 	unsigned long addr = 0;
214 	int part_num = -1;
215 	int dev_num = 0;
216 	int ret;
217 
218 	dev_desc = blk_get_dev(dev_iface, dev_num);
219 	if (!dev_desc) {
220 		printf("Could not find %s %d\n", dev_iface, dev_num);
221 		return -1;
222 	}
223 
224 	memset(&boot_part_info, 0, sizeof(boot_part_info));
225 
226 #ifdef CONFIG_RK_AVB_LIBAVB_USER
227 	if (rk_avb_get_current_slot(slot_suffix)) {
228 		printf("ANDROID: Get Current Slot error.\n");
229 		return -1;
230 	}
231 
232 	part_num = android_part_get_info_by_name_suffix(dev_desc,
233 					     part_name,
234 					     slot_suffix, &boot_part_info);
235 #else
236 	part_num = part_get_info_by_name(dev_desc, part_name, &boot_part_info);
237 	if (part_num < 0) {
238 		printf("ANDROID: Could not find partition \"%s\"\n", part_name);
239 		return -1;
240 	}
241 #endif
242 
243 	snprintf(dev_part, ARRAY_SIZE(dev_part), ":%x", part_num);
244 	if (fs_set_blk_dev(dev_iface, dev_part, FS_TYPE_EXT))
245 		return -1;
246 
247 	fdt_addr = env_get("fdt_addr_r");
248 	if (!fdt_addr) {
249 		printf("ANDROID: No Found FDT Load Address.\n");
250 		return -1;
251 	}
252 	addr = simple_strtoul(fdt_addr, NULL, 16);
253 
254 	ret = fs_read(load_file_name, addr, pos, bytes, &len_read);
255 	if (ret < 0)
256 		return -1;
257 
258 	return 0;
259 }
260 #endif
261 
262 int android_bootloader_boot_kernel(unsigned long kernel_address)
263 {
264 	char kernel_addr_str[12];
265 	char *fdt_addr = env_get("fdt_addr");
266 	char *bootm_args[] = {
267 		"bootm", kernel_addr_str, kernel_addr_str, fdt_addr, NULL };
268 
269 	sprintf(kernel_addr_str, "0x%lx", kernel_address);
270 
271 	printf("Booting kernel at %s with fdt at %s...\n\n\n",
272 	       kernel_addr_str, fdt_addr);
273 	do_bootm(NULL, 0, 4, bootm_args);
274 
275 	return -1;
276 }
277 
278 static char *strjoin(const char **chunks, char separator)
279 {
280 	int len, joined_len = 0;
281 	char *ret, *current;
282 	const char **p;
283 
284 	for (p = chunks; *p; p++)
285 		joined_len += strlen(*p) + 1;
286 
287 	if (!joined_len) {
288 		ret = malloc(1);
289 		if (ret)
290 			ret[0] = '\0';
291 		return ret;
292 	}
293 
294 	ret = malloc(joined_len);
295 	current = ret;
296 	if (!ret)
297 		return ret;
298 
299 	for (p = chunks; *p; p++) {
300 		len = strlen(*p);
301 		memcpy(current, *p, len);
302 		current += len;
303 		*current = separator;
304 		current++;
305 	}
306 	/* Replace the last separator by a \0. */
307 	current[-1] = '\0';
308 	return ret;
309 }
310 
311 /** android_assemble_cmdline - Assemble the command line to pass to the kernel
312  * @return a newly allocated string
313  */
314 char *android_assemble_cmdline(const char *slot_suffix,
315 				      const char *extra_args)
316 {
317 	const char *cmdline_chunks[16];
318 	const char **current_chunk = cmdline_chunks;
319 	char *env_cmdline, *cmdline, *rootdev_input, *serialno;
320 	char *allocated_suffix = NULL;
321 	char *allocated_serialno = NULL;
322 	char *allocated_rootdev = NULL;
323 	unsigned long rootdev_len;
324 
325 	env_cmdline = env_get("bootargs");
326 	if (env_cmdline)
327 		*(current_chunk++) = env_cmdline;
328 
329 	/* The |slot_suffix| needs to be passed to the kernel to know what
330 	 * slot to boot from.
331 	 */
332 	if (slot_suffix) {
333 		allocated_suffix = malloc(strlen(ANDROID_ARG_SLOT_SUFFIX) +
334 					  strlen(slot_suffix));
335 		strcpy(allocated_suffix, ANDROID_ARG_SLOT_SUFFIX);
336 		strcat(allocated_suffix, slot_suffix);
337 		*(current_chunk++) = allocated_suffix;
338 	}
339 
340 	serialno = env_get("serial#");
341 	if (serialno) {
342 		allocated_serialno = malloc(strlen(ANDROID_ARG_SERIALNO) +
343 					  strlen(serialno) + 1);
344 		memset(allocated_serialno, 0, strlen(ANDROID_ARG_SERIALNO) +
345 				strlen(serialno) + 1);
346 		strcpy(allocated_serialno, ANDROID_ARG_SERIALNO);
347 		strcat(allocated_serialno, serialno);
348 		*(current_chunk++) = allocated_serialno;
349 	}
350 
351 	rootdev_input = env_get("android_rootdev");
352 	if (rootdev_input) {
353 		rootdev_len = strlen(ANDROID_ARG_ROOT) + CONFIG_SYS_CBSIZE + 1;
354 		allocated_rootdev = malloc(rootdev_len);
355 		strcpy(allocated_rootdev, ANDROID_ARG_ROOT);
356 		cli_simple_process_macros(rootdev_input,
357 					  allocated_rootdev +
358 					  strlen(ANDROID_ARG_ROOT));
359 		/* Make sure that the string is null-terminated since the
360 		 * previous could not copy to the end of the input string if it
361 		 * is too big.
362 		 */
363 		allocated_rootdev[rootdev_len - 1] = '\0';
364 		*(current_chunk++) = allocated_rootdev;
365 	}
366 
367 	if (extra_args)
368 		*(current_chunk++) = extra_args;
369 
370 	*(current_chunk++) = NULL;
371 	cmdline = strjoin(cmdline_chunks, ' ');
372 	free(allocated_suffix);
373 	free(allocated_rootdev);
374 	return cmdline;
375 }
376 
377 #ifdef CONFIG_ANDROID_AVB
378 static void slot_set_unbootable(AvbABSlotData* slot)
379 {
380 	slot->priority = 0;
381 	slot->tries_remaining = 0;
382 	slot->successful_boot = 0;
383 }
384 
385 static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
386 			       unsigned long load_address,
387 			       char *slot_suffix)
388 {
389 	const char *requested_partitions[1] = {NULL};
390 	uint8_t unlocked = true;
391 	AvbOps *ops;
392 	AvbSlotVerifyFlags flags;
393 	AvbSlotVerifyData *slot_data[1] = {NULL};
394 	AvbSlotVerifyResult verify_result;
395 	AvbABData ab_data, ab_data_orig;
396 	size_t slot_index_to_boot = 0;
397 
398 	requested_partitions[0] = boot_partname;
399 	ops = avb_ops_user_new();
400 	if (ops == NULL) {
401 		printf("avb_ops_user_new() failed!\n");
402 		return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
403 	}
404 
405 	if (ops->read_is_device_unlocked(ops, (bool *)&unlocked) != AVB_IO_RESULT_OK)
406 		printf("Error determining whether device is unlocked.\n");
407 
408 	printf("read_is_device_unlocked() ops returned that device is %s\n",
409 	       (unlocked & LOCK_MASK)? "UNLOCKED" : "LOCKED");
410 
411 	flags = AVB_SLOT_VERIFY_FLAGS_NONE;
412 	if (unlocked & LOCK_MASK)
413 		flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
414 
415 	if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
416 		printf("Can not load metadata\n");
417 		return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
418 	}
419 
420 	if (strncmp(slot_suffix, "_a", 2))
421 		slot_index_to_boot = 0;
422 	else if(strncmp(slot_suffix, "_b", 2))
423 		slot_index_to_boot = 1;
424 	else
425 		slot_index_to_boot = 0;
426 
427 	verify_result =
428 	avb_slot_verify(ops,
429 			requested_partitions,
430 			slot_suffix,
431 			flags,
432 			AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
433 			&slot_data[0]);
434 
435 	if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
436 		slot_set_unbootable(&ab_data.slots[slot_index_to_boot]);
437 		goto out;
438 	}
439 
440 	memcpy((uint8_t*)load_address,
441 	       slot_data[0]->loaded_partitions->data,
442 	       slot_data[0]->loaded_partitions->data_size);
443 	env_set("bootargs", slot_data[0]->cmdline);
444 
445 	/* ... and decrement tries remaining, if applicable. */
446 	if (!ab_data.slots[slot_index_to_boot].successful_boot &&
447 		ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
448 		ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
449 	}
450 out:
451 	if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) {
452 		printf("Can not save metadata\n");
453 		verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
454 	}
455 
456 	if (slot_data[0] != NULL)
457 		avb_slot_verify_data_free(slot_data[0]);
458 
459 	return verify_result;
460 }
461 #endif
462 
463 int android_bootloader_boot_flow(struct blk_desc *dev_desc,
464 				 unsigned long load_address)
465 {
466 	enum android_boot_mode mode;
467 	disk_partition_t misc_part_info;
468 	int part_num;
469 	int ret;
470 	char *command_line;
471 	char slot_suffix[3] = {0};
472 	const char *mode_cmdline = NULL;
473 	char *boot_partname = ANDROID_PARTITION_BOOT;
474 	ulong fdt_addr;
475 
476 	/*
477 	 * 1. Load MISC partition and determine the boot mode
478 	 *   clear its value for the next boot if needed.
479 	 */
480 	part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_MISC,
481 					 &misc_part_info);
482 	if (part_num < 0)
483 		printf("%s Could not find misc partition\n", __func__);
484 
485 #ifdef CONFIG_OPTEE_CLIENT
486 	/* load attestation key from misc partition. */
487 	load_attestation_key(dev_desc, &misc_part_info);
488 #endif
489 
490 	mode = android_bootloader_load_and_clear_mode(dev_desc, &misc_part_info);
491 	printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode));
492 
493 	switch (mode) {
494 	case ANDROID_BOOT_MODE_NORMAL:
495 		/* In normal mode, we load the kernel from "boot" but append
496 		 * "skip_initramfs" to the cmdline to make it ignore the
497 		 * recovery initramfs in the boot partition.
498 		 */
499 #ifdef CONFIG_ANDROID_AB
500 		mode_cmdline = "skip_initramfs";
501 #endif
502 		break;
503 	case ANDROID_BOOT_MODE_RECOVERY:
504 		/* In recovery mode we still boot the kernel from "boot" but
505 		 * don't skip the initramfs so it boots to recovery.
506 		 */
507 #ifndef CONFIG_ANDROID_AB
508 		boot_partname = ANDROID_PARTITION_RECOVERY;
509 #endif
510 		break;
511 	case ANDROID_BOOT_MODE_BOOTLOADER:
512 		/* Bootloader mode enters fastboot. If this operation fails we
513 		 * simply return since we can't recover from this situation by
514 		 * switching to another slot.
515 		 */
516 		return android_bootloader_boot_bootloader();
517 	}
518 
519 #ifdef CONFIG_ANDROID_AB
520 	/*TODO: get from pre-loader or misc partition*/
521 	if (rk_avb_get_current_slot(slot_suffix))
522 		return -1;
523 
524 	if (slot_suffix[0] != '_') {
525 		printf("There is no bootable slot!\n");
526 		return -1;
527 	}
528 #endif
529 
530 #ifdef CONFIG_ANDROID_AVB
531 	if (android_slot_verify(boot_partname, load_address, slot_suffix))
532 		return -1;
533 #else
534 	/*
535 	 * 2. Load the boot/recovery from the desired "boot" partition.
536 	 * Determine if this is an AOSP image.
537 	 */
538 	disk_partition_t boot_part_info;
539 	part_num =
540 	    android_part_get_info_by_name_suffix(dev_desc,
541 						 boot_partname,
542 						 slot_suffix, &boot_part_info);
543 	if (part_num < 0) {
544 		printf("%s Could not found bootable partition %s\n", __func__,
545 		       boot_partname);
546 		return -1;
547 	}
548 	debug("ANDROID: Loading kernel from \"%s\", partition %d.\n",
549 	      boot_part_info.name, part_num);
550 
551 	ret = android_image_load(dev_desc, &boot_part_info, load_address,
552 				 -1UL);
553 	if (ret < 0) {
554 		printf("%s %s part load fail\n", __func__, boot_part_info.name);
555 		return ret;
556 	}
557 #endif
558 
559 	/* Set Android root variables. */
560 	env_set_ulong("android_root_devnum", dev_desc->devnum);
561 	env_set("android_slotsufix", slot_suffix);
562 
563 	/* Assemble the command line */
564 	command_line = android_assemble_cmdline(slot_suffix, mode_cmdline);
565 	env_update("bootargs", command_line);
566 
567 	debug("ANDROID: bootargs: \"%s\"\n", command_line);
568 
569 #ifdef CONFIG_SUPPORT_OEM_DTB
570 	if (android_bootloader_get_fdt(ANDROID_PARTITION_OEM,
571 				       ANDROID_ARG_FDT_FILENAME)) {
572 		printf("Can not get the fdt data from oem!\n");
573 	}
574 #else
575 	ret = android_image_get_fdt((void *)load_address, &fdt_addr);
576 	if (!ret)
577 		env_set_hex("fdt_addr", fdt_addr);
578 #endif
579 	android_bootloader_boot_kernel(load_address);
580 
581 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
582 	return -1;
583 }
584 
585 int android_avb_boot_flow(char *slot_suffix, unsigned long kernel_address)
586 {
587 	const char *dev_iface = "mmc";
588 	int dev_num = 0;
589 	struct blk_desc *dev_desc;
590 	disk_partition_t boot_part_info;
591 	int ret;
592 	dev_desc = blk_get_dev(dev_iface, dev_num);
593 	if (!dev_desc) {
594 		printf("Could not find %s %d\n", dev_iface, dev_num);
595 		return -1;
596 	}
597 	/* Load the kernel from the desired "boot" partition. */
598 	android_part_get_info_by_name_suffix(dev_desc,
599 					     ANDROID_PARTITION_BOOT,
600 					     slot_suffix, &boot_part_info);
601 	ret = android_image_load(dev_desc, &boot_part_info, kernel_address,
602 				 -1UL);
603 	if (ret < 0)
604 		return ret;
605 	android_bootloader_boot_kernel(kernel_address);
606 
607 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
608 	return -1;
609 }
610 
611 int android_boot_flow(unsigned long kernel_address)
612 {
613 	const char *dev_iface = "mmc";
614 	int dev_num = 0;
615 	struct blk_desc *dev_desc;
616 	disk_partition_t boot_part_info;
617 	int ret;
618 	dev_desc = blk_get_dev(dev_iface, dev_num);
619 	if (!dev_desc) {
620 		printf("Could not find %s %d\n", dev_iface, dev_num);
621 		return -1;
622 	}
623 	/* Load the kernel from the desired "boot" partition. */
624 	part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT, &boot_part_info);
625 	ret = android_image_load(dev_desc, &boot_part_info, kernel_address,
626 				 -1UL);
627 	if (ret < 0)
628 		return ret;
629 	android_bootloader_boot_kernel(kernel_address);
630 
631 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
632 	return -1;
633 }
634