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