xref: /rk3399_rockchip-uboot/common/android_bootloader.c (revision 78ef5fbdb92712dc771643c913975ff4faff380d)
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) + 1);
335 		memset(allocated_suffix, 0, strlen(ANDROID_ARG_SLOT_SUFFIX)
336 		       + strlen(slot_suffix) + 1);
337 		strcpy(allocated_suffix, ANDROID_ARG_SLOT_SUFFIX);
338 		strcat(allocated_suffix, slot_suffix);
339 		*(current_chunk++) = allocated_suffix;
340 	}
341 
342 	serialno = env_get("serial#");
343 	if (serialno) {
344 		allocated_serialno = malloc(strlen(ANDROID_ARG_SERIALNO) +
345 					  strlen(serialno) + 1);
346 		memset(allocated_serialno, 0, strlen(ANDROID_ARG_SERIALNO) +
347 				strlen(serialno) + 1);
348 		strcpy(allocated_serialno, ANDROID_ARG_SERIALNO);
349 		strcat(allocated_serialno, serialno);
350 		*(current_chunk++) = allocated_serialno;
351 	}
352 
353 	rootdev_input = env_get("android_rootdev");
354 	if (rootdev_input) {
355 		rootdev_len = strlen(ANDROID_ARG_ROOT) + CONFIG_SYS_CBSIZE + 1;
356 		allocated_rootdev = malloc(rootdev_len);
357 		strcpy(allocated_rootdev, ANDROID_ARG_ROOT);
358 		cli_simple_process_macros(rootdev_input,
359 					  allocated_rootdev +
360 					  strlen(ANDROID_ARG_ROOT));
361 		/* Make sure that the string is null-terminated since the
362 		 * previous could not copy to the end of the input string if it
363 		 * is too big.
364 		 */
365 		allocated_rootdev[rootdev_len - 1] = '\0';
366 		*(current_chunk++) = allocated_rootdev;
367 	}
368 
369 	if (extra_args)
370 		*(current_chunk++) = extra_args;
371 
372 	*(current_chunk++) = NULL;
373 	cmdline = strjoin(cmdline_chunks, ' ');
374 	free(allocated_suffix);
375 	free(allocated_rootdev);
376 	return cmdline;
377 }
378 
379 #ifdef CONFIG_ANDROID_AVB
380 static void slot_set_unbootable(AvbABSlotData* slot)
381 {
382 	slot->priority = 0;
383 	slot->tries_remaining = 0;
384 	slot->successful_boot = 0;
385 }
386 
387 static AvbSlotVerifyResult android_slot_verify(char *boot_partname,
388 			       unsigned long load_address,
389 			       char *slot_suffix)
390 {
391 	const char *requested_partitions[1] = {NULL};
392 	uint8_t unlocked = true;
393 	AvbOps *ops;
394 	AvbSlotVerifyFlags flags;
395 	AvbSlotVerifyData *slot_data[1] = {NULL};
396 	AvbSlotVerifyResult verify_result;
397 	AvbABData ab_data, ab_data_orig;
398 	size_t slot_index_to_boot = 0;
399 
400 	requested_partitions[0] = boot_partname;
401 	ops = avb_ops_user_new();
402 	if (ops == NULL) {
403 		printf("avb_ops_user_new() failed!\n");
404 		return AVB_SLOT_VERIFY_RESULT_ERROR_OOM;
405 	}
406 
407 	if (ops->read_is_device_unlocked(ops, (bool *)&unlocked) != AVB_IO_RESULT_OK)
408 		printf("Error determining whether device is unlocked.\n");
409 
410 	printf("read_is_device_unlocked() ops returned that device is %s\n",
411 	       (unlocked & LOCK_MASK)? "UNLOCKED" : "LOCKED");
412 
413 	flags = AVB_SLOT_VERIFY_FLAGS_NONE;
414 	if (unlocked & LOCK_MASK)
415 		flags |= AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR;
416 
417 	if(load_metadata(ops->ab_ops, &ab_data, &ab_data_orig)) {
418 		printf("Can not load metadata\n");
419 		return AVB_SLOT_VERIFY_RESULT_ERROR_IO;
420 	}
421 
422 	if (strncmp(slot_suffix, "_a", 2))
423 		slot_index_to_boot = 0;
424 	else if(strncmp(slot_suffix, "_b", 2))
425 		slot_index_to_boot = 1;
426 	else
427 		slot_index_to_boot = 0;
428 
429 	verify_result =
430 	avb_slot_verify(ops,
431 			requested_partitions,
432 			slot_suffix,
433 			flags,
434 			AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE,
435 			&slot_data[0]);
436 
437 	if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
438 		slot_set_unbootable(&ab_data.slots[slot_index_to_boot]);
439 		goto out;
440 	}
441 
442 	memcpy((uint8_t*)load_address,
443 	       slot_data[0]->loaded_partitions->data,
444 	       slot_data[0]->loaded_partitions->data_size);
445 	env_set("bootargs", slot_data[0]->cmdline);
446 
447 	/* ... and decrement tries remaining, if applicable. */
448 	if (!ab_data.slots[slot_index_to_boot].successful_boot &&
449 		ab_data.slots[slot_index_to_boot].tries_remaining > 0) {
450 		ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
451 	}
452 out:
453 	if (save_metadata_if_changed(ops->ab_ops, &ab_data, &ab_data_orig)) {
454 		printf("Can not save metadata\n");
455 		verify_result = AVB_SLOT_VERIFY_RESULT_ERROR_IO;
456 	}
457 
458 	if (slot_data[0] != NULL)
459 		avb_slot_verify_data_free(slot_data[0]);
460 
461 	return verify_result;
462 }
463 #endif
464 
465 int android_bootloader_boot_flow(struct blk_desc *dev_desc,
466 				 unsigned long load_address)
467 {
468 	enum android_boot_mode mode;
469 	disk_partition_t misc_part_info;
470 	int part_num;
471 	int ret;
472 	char *command_line;
473 	char slot_suffix[3] = {0};
474 	const char *mode_cmdline = NULL;
475 	char *boot_partname = ANDROID_PARTITION_BOOT;
476 	ulong fdt_addr;
477 
478 	/*
479 	 * 1. Load MISC partition and determine the boot mode
480 	 *   clear its value for the next boot if needed.
481 	 */
482 	part_num = part_get_info_by_name(dev_desc, ANDROID_PARTITION_MISC,
483 					 &misc_part_info);
484 	if (part_num < 0)
485 		printf("%s Could not find misc partition\n", __func__);
486 
487 #ifdef CONFIG_OPTEE_CLIENT
488 	/* load attestation key from misc partition. */
489 	load_attestation_key(dev_desc, &misc_part_info);
490 #endif
491 
492 	mode = android_bootloader_load_and_clear_mode(dev_desc, &misc_part_info);
493 	printf("ANDROID: reboot reason: \"%s\"\n", android_boot_mode_str(mode));
494 
495 	switch (mode) {
496 	case ANDROID_BOOT_MODE_NORMAL:
497 		/* In normal mode, we load the kernel from "boot" but append
498 		 * "skip_initramfs" to the cmdline to make it ignore the
499 		 * recovery initramfs in the boot partition.
500 		 */
501 #ifdef CONFIG_ANDROID_AB
502 		mode_cmdline = "skip_initramfs";
503 #endif
504 		break;
505 	case ANDROID_BOOT_MODE_RECOVERY:
506 		/* In recovery mode we still boot the kernel from "boot" but
507 		 * don't skip the initramfs so it boots to recovery.
508 		 */
509 #ifndef CONFIG_ANDROID_AB
510 		boot_partname = ANDROID_PARTITION_RECOVERY;
511 #endif
512 		break;
513 	case ANDROID_BOOT_MODE_BOOTLOADER:
514 		/* Bootloader mode enters fastboot. If this operation fails we
515 		 * simply return since we can't recover from this situation by
516 		 * switching to another slot.
517 		 */
518 		return android_bootloader_boot_bootloader();
519 	}
520 
521 #ifdef CONFIG_ANDROID_AB
522 	/*TODO: get from pre-loader or misc partition*/
523 	if (rk_avb_get_current_slot(slot_suffix))
524 		return -1;
525 
526 	if (slot_suffix[0] != '_') {
527 		printf("There is no bootable slot!\n");
528 		return -1;
529 	}
530 #endif
531 
532 #ifdef CONFIG_ANDROID_AVB
533 	if (android_slot_verify(boot_partname, load_address, slot_suffix))
534 		return -1;
535 #else
536 	/*
537 	 * 2. Load the boot/recovery from the desired "boot" partition.
538 	 * Determine if this is an AOSP image.
539 	 */
540 	disk_partition_t boot_part_info;
541 	part_num =
542 	    android_part_get_info_by_name_suffix(dev_desc,
543 						 boot_partname,
544 						 slot_suffix, &boot_part_info);
545 	if (part_num < 0) {
546 		printf("%s Could not found bootable partition %s\n", __func__,
547 		       boot_partname);
548 		return -1;
549 	}
550 	debug("ANDROID: Loading kernel from \"%s\", partition %d.\n",
551 	      boot_part_info.name, part_num);
552 
553 	ret = android_image_load(dev_desc, &boot_part_info, load_address,
554 				 -1UL);
555 	if (ret < 0) {
556 		printf("%s %s part load fail\n", __func__, boot_part_info.name);
557 		return ret;
558 	}
559 #endif
560 
561 	/* Set Android root variables. */
562 	env_set_ulong("android_root_devnum", dev_desc->devnum);
563 	env_set("android_slotsufix", slot_suffix);
564 
565 	/* Assemble the command line */
566 	command_line = android_assemble_cmdline(slot_suffix, mode_cmdline);
567 	env_update("bootargs", command_line);
568 
569 	debug("ANDROID: bootargs: \"%s\"\n", command_line);
570 
571 #ifdef CONFIG_SUPPORT_OEM_DTB
572 	if (android_bootloader_get_fdt(ANDROID_PARTITION_OEM,
573 				       ANDROID_ARG_FDT_FILENAME)) {
574 		printf("Can not get the fdt data from oem!\n");
575 	}
576 #else
577 	ret = android_image_get_fdt((void *)load_address, &fdt_addr);
578 	if (!ret)
579 		env_set_hex("fdt_addr", fdt_addr);
580 #endif
581 	android_bootloader_boot_kernel(load_address);
582 
583 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
584 	return -1;
585 }
586 
587 int android_avb_boot_flow(char *slot_suffix, unsigned long kernel_address)
588 {
589 	const char *dev_iface = "mmc";
590 	int dev_num = 0;
591 	struct blk_desc *dev_desc;
592 	disk_partition_t boot_part_info;
593 	int ret;
594 	dev_desc = blk_get_dev(dev_iface, dev_num);
595 	if (!dev_desc) {
596 		printf("Could not find %s %d\n", dev_iface, dev_num);
597 		return -1;
598 	}
599 	/* Load the kernel from the desired "boot" partition. */
600 	android_part_get_info_by_name_suffix(dev_desc,
601 					     ANDROID_PARTITION_BOOT,
602 					     slot_suffix, &boot_part_info);
603 	ret = android_image_load(dev_desc, &boot_part_info, kernel_address,
604 				 -1UL);
605 	if (ret < 0)
606 		return ret;
607 	android_bootloader_boot_kernel(kernel_address);
608 
609 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
610 	return -1;
611 }
612 
613 int android_boot_flow(unsigned long kernel_address)
614 {
615 	const char *dev_iface = "mmc";
616 	int dev_num = 0;
617 	struct blk_desc *dev_desc;
618 	disk_partition_t boot_part_info;
619 	int ret;
620 	dev_desc = blk_get_dev(dev_iface, dev_num);
621 	if (!dev_desc) {
622 		printf("Could not find %s %d\n", dev_iface, dev_num);
623 		return -1;
624 	}
625 	/* Load the kernel from the desired "boot" partition. */
626 	part_get_info_by_name(dev_desc, ANDROID_PARTITION_BOOT, &boot_part_info);
627 	ret = android_image_load(dev_desc, &boot_part_info, kernel_address,
628 				 -1UL);
629 	if (ret < 0)
630 		return ret;
631 	android_bootloader_boot_kernel(kernel_address);
632 
633 	/* TODO: If the kernel doesn't boot mark the selected slot as bad. */
634 	return -1;
635 }
636