mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 18:35:42 +01:00 
			
		
		
		
	android: boot: support boot image header version 3 and 4
Enable the support for boot image header version 3 and 4 using abootimg command. In order to use version 3 or 4: 1- Vendor boot image address should be given to abootimg cmd. abootimg addr $1 $vendor_boot_load_addr 2- "ramdisk_addr_r" env variable (ramdisk address) should be set to host the ramdisk : generic ramdisk + vendor ramdisk Replace "struct andr_boot_img_hdr_v0*" by "void *" in some functions since v3 and v4 are now supported as well. Signed-off-by: Safae Ouajih <souajih@baylibre.com> Reviewed-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> Tested-by: Mattijs Korpershoek <mkorpershoek@baylibre.com>
This commit is contained in:
		
							
								
								
									
										37
									
								
								boot/bootm.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								boot/bootm.c
									
									
									
									
									
								
							| @@ -113,6 +113,10 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, | |||||||
| 			 char *const argv[]) | 			 char *const argv[]) | ||||||
| { | { | ||||||
| 	const void *os_hdr; | 	const void *os_hdr; | ||||||
|  | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
|  | 	const void *vendor_boot_img; | ||||||
|  | 	const void *boot_img; | ||||||
|  | #endif | ||||||
| 	bool ep_found = false; | 	bool ep_found = false; | ||||||
| 	int ret; | 	int ret; | ||||||
|  |  | ||||||
| @@ -181,14 +185,23 @@ static int bootm_find_os(struct cmd_tbl *cmdtp, int flag, int argc, | |||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_ANDROID_BOOT_IMAGE | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
| 	case IMAGE_FORMAT_ANDROID: | 	case IMAGE_FORMAT_ANDROID: | ||||||
|  | 		boot_img = os_hdr; | ||||||
|  | 		vendor_boot_img = NULL; | ||||||
|  | 		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { | ||||||
|  | 			boot_img = map_sysmem(get_abootimg_addr(), 0); | ||||||
|  | 			vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); | ||||||
|  | 		} | ||||||
| 		images.os.type = IH_TYPE_KERNEL; | 		images.os.type = IH_TYPE_KERNEL; | ||||||
| 		images.os.comp = android_image_get_kcomp(os_hdr, NULL); | 		images.os.comp = android_image_get_kcomp(boot_img, vendor_boot_img); | ||||||
| 		images.os.os = IH_OS_LINUX; | 		images.os.os = IH_OS_LINUX; | ||||||
|  | 		images.os.end = android_image_get_end(boot_img, vendor_boot_img); | ||||||
| 		images.os.end = android_image_get_end(os_hdr, NULL); | 		images.os.load = android_image_get_kload(boot_img, vendor_boot_img); | ||||||
| 		images.os.load = android_image_get_kload(os_hdr, NULL); |  | ||||||
| 		images.ep = images.os.load; | 		images.ep = images.os.load; | ||||||
| 		ep_found = true; | 		ep_found = true; | ||||||
|  | 		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { | ||||||
|  | 			unmap_sysmem(vendor_boot_img); | ||||||
|  | 			unmap_sysmem(boot_img); | ||||||
|  | 		} | ||||||
| 		break; | 		break; | ||||||
| #endif | #endif | ||||||
| 	default: | 	default: | ||||||
| @@ -889,6 +902,10 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, | |||||||
| 	int		os_noffset; | 	int		os_noffset; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
|  | 	const void *boot_img; | ||||||
|  | 	const void *vendor_boot_img; | ||||||
|  | #endif | ||||||
| 	img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0], | 	img_addr = genimg_get_kernel_addr_fit(argc < 1 ? NULL : argv[0], | ||||||
| 					      &fit_uname_config, | 					      &fit_uname_config, | ||||||
| 					      &fit_uname_kernel); | 					      &fit_uname_kernel); | ||||||
| @@ -964,10 +981,20 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, | |||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_ANDROID_BOOT_IMAGE | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
| 	case IMAGE_FORMAT_ANDROID: | 	case IMAGE_FORMAT_ANDROID: | ||||||
|  | 		boot_img = buf; | ||||||
|  | 		vendor_boot_img = NULL; | ||||||
|  | 		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { | ||||||
|  | 			boot_img = map_sysmem(get_abootimg_addr(), 0); | ||||||
|  | 			vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); | ||||||
|  | 		} | ||||||
| 		printf("## Booting Android Image at 0x%08lx ...\n", img_addr); | 		printf("## Booting Android Image at 0x%08lx ...\n", img_addr); | ||||||
| 		if (android_image_get_kernel(buf, NULL, images->verify, | 		if (android_image_get_kernel(boot_img, vendor_boot_img, images->verify, | ||||||
| 					     os_data, os_len)) | 					     os_data, os_len)) | ||||||
| 			return NULL; | 			return NULL; | ||||||
|  | 		if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { | ||||||
|  | 			unmap_sysmem(vendor_boot_img); | ||||||
|  | 			unmap_sysmem(boot_img); | ||||||
|  | 		} | ||||||
| 		break; | 		break; | ||||||
| #endif | #endif | ||||||
| 	default: | 	default: | ||||||
|   | |||||||
| @@ -201,7 +201,7 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data) | |||||||
|  * Return: Zero, os start address and length on success, |  * Return: Zero, os start address and length on success, | ||||||
|  *		otherwise on failure. |  *		otherwise on failure. | ||||||
|  */ |  */ | ||||||
| int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, | int android_image_get_kernel(const void *hdr, | ||||||
| 			     const void *vendor_boot_img, int verify, | 			     const void *vendor_boot_img, int verify, | ||||||
| 			     ulong *os_data, ulong *os_len) | 			     ulong *os_data, ulong *os_len) | ||||||
| { | { | ||||||
| @@ -286,7 +286,7 @@ bool is_android_vendor_boot_image_header(const void *vendor_boot_img) | |||||||
| 	return !memcmp(VENDOR_BOOT_MAGIC, vendor_boot_img, ANDR_VENDOR_BOOT_MAGIC_SIZE); | 	return !memcmp(VENDOR_BOOT_MAGIC, vendor_boot_img, ANDR_VENDOR_BOOT_MAGIC_SIZE); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr) | bool is_android_boot_image_header(const void *hdr) | ||||||
| { | { | ||||||
| 	return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); | 	return !memcmp(ANDR_BOOT_MAGIC, hdr, ANDR_BOOT_MAGIC_SIZE); | ||||||
| } | } | ||||||
| @@ -305,7 +305,7 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, | |||||||
| 	return img_data.boot_img_total_size; | 	return img_data.boot_img_total_size; | ||||||
| } | } | ||||||
|  |  | ||||||
| ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, | ulong android_image_get_kload(const void *hdr, | ||||||
| 			      const void *vendor_boot_img) | 			      const void *vendor_boot_img) | ||||||
| { | { | ||||||
| 	struct andr_image_data img_data; | 	struct andr_image_data img_data; | ||||||
| @@ -316,7 +316,7 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, | |||||||
| 	return android_image_get_kernel_addr(&img_data); | 	return android_image_get_kernel_addr(&img_data); | ||||||
| } | } | ||||||
|  |  | ||||||
| ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, | ulong android_image_get_kcomp(const void *hdr, | ||||||
| 			      const void *vendor_boot_img) | 			      const void *vendor_boot_img) | ||||||
| { | { | ||||||
| 	struct andr_image_data img_data; | 	struct andr_image_data img_data; | ||||||
| @@ -364,14 +364,18 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, | int android_image_get_second(const void *hdr, ulong *second_data, ulong *second_len) | ||||||
| 			     ulong *second_data, ulong *second_len) |  | ||||||
| { | { | ||||||
| 	struct andr_image_data img_data; | 	struct andr_image_data img_data; | ||||||
|  |  | ||||||
| 	if (!android_image_get_data(hdr, NULL, &img_data)) | 	if (!android_image_get_data(hdr, NULL, &img_data)) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
|  |  | ||||||
|  | 	if (img_data.header_version > 2) { | ||||||
|  | 		printf("Second stage bootloader is only supported for boot image version <= 2\n"); | ||||||
|  | 		return -EOPNOTSUPP; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (!img_data.second_size) { | 	if (!img_data.second_size) { | ||||||
| 		*second_data = *second_len = 0; | 		*second_data = *second_len = 0; | ||||||
| 		return -1; | 		return -1; | ||||||
|   | |||||||
| @@ -426,10 +426,22 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a | |||||||
| 		break; | 		break; | ||||||
| 	case IMAGE_FORMAT_ANDROID: | 	case IMAGE_FORMAT_ANDROID: | ||||||
| 		if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { | 		if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { | ||||||
| 			void *ptr = map_sysmem(images->os.start, 0); |  | ||||||
| 			int ret; | 			int ret; | ||||||
| 			ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp); | 			if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) { | ||||||
| 			unmap_sysmem(ptr); | 				void *boot_img = map_sysmem(get_abootimg_addr(), 0); | ||||||
|  | 				void *vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0); | ||||||
|  |  | ||||||
|  | 				ret = android_image_get_ramdisk(boot_img, vendor_boot_img, | ||||||
|  | 								rd_datap, rd_lenp); | ||||||
|  | 				unmap_sysmem(vendor_boot_img); | ||||||
|  | 				unmap_sysmem(boot_img); | ||||||
|  | 			} else { | ||||||
|  | 				void *ptr = map_sysmem(images->os.start, 0); | ||||||
|  |  | ||||||
|  | 				ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp); | ||||||
|  | 				unmap_sysmem(ptr); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			if (ret) | 			if (ret) | ||||||
| 				return ret; | 				return ret; | ||||||
| 			done = true; | 			done = true; | ||||||
|   | |||||||
| @@ -529,7 +529,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, | |||||||
| 		} | 		} | ||||||
| #ifdef CONFIG_ANDROID_BOOT_IMAGE | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
| 	} else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { | 	} else if (genimg_get_format(buf) == IMAGE_FORMAT_ANDROID) { | ||||||
| 		struct andr_boot_img_hdr_v0 *hdr = buf; | 		void *hdr = buf; | ||||||
| 		ulong		fdt_data, fdt_len; | 		ulong		fdt_data, fdt_len; | ||||||
| 		u32			fdt_size, dtb_idx; | 		u32			fdt_size, dtb_idx; | ||||||
| 		/* | 		/* | ||||||
|   | |||||||
| @@ -17,6 +17,16 @@ | |||||||
| static ulong _abootimg_addr = -1; | static ulong _abootimg_addr = -1; | ||||||
| static ulong _avendor_bootimg_addr = -1; | static ulong _avendor_bootimg_addr = -1; | ||||||
|  |  | ||||||
|  | ulong get_abootimg_addr(void) | ||||||
|  | { | ||||||
|  | 	return (_abootimg_addr == -1 ? image_load_addr : _abootimg_addr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ulong get_avendor_bootimg_addr(void) | ||||||
|  | { | ||||||
|  | 	return _avendor_bootimg_addr; | ||||||
|  | } | ||||||
|  |  | ||||||
| static int abootimg_get_ver(int argc, char *const argv[]) | static int abootimg_get_ver(int argc, char *const argv[]) | ||||||
| { | { | ||||||
| 	const struct andr_boot_img_hdr_v0 *hdr; | 	const struct andr_boot_img_hdr_v0 *hdr; | ||||||
| @@ -70,12 +80,21 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) | |||||||
| 		return CMD_RET_USAGE; | 		return CMD_RET_USAGE; | ||||||
| 	struct andr_image_data img_data = {0}; | 	struct andr_image_data img_data = {0}; | ||||||
| 	const struct andr_boot_img_hdr_v0 *hdr; | 	const struct andr_boot_img_hdr_v0 *hdr; | ||||||
|  | 	const struct andr_vnd_boot_img_hdr *vhdr; | ||||||
|  |  | ||||||
| 	hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); | 	hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); | ||||||
| 	if (!android_image_get_data(hdr, NULL, &img_data)) { | 	if (get_avendor_bootimg_addr() != -1) | ||||||
|  | 		vhdr = map_sysmem(get_avendor_bootimg_addr(), sizeof(*vhdr)); | ||||||
|  |  | ||||||
|  | 	if (!android_image_get_data(hdr, vhdr, &img_data)) { | ||||||
|  | 		if (get_avendor_bootimg_addr() != -1) | ||||||
|  | 			unmap_sysmem(vhdr); | ||||||
| 		unmap_sysmem(hdr); | 		unmap_sysmem(hdr); | ||||||
| 		return CMD_RET_FAILURE; | 		return CMD_RET_FAILURE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (get_avendor_bootimg_addr() != -1) | ||||||
|  | 		unmap_sysmem(vhdr); | ||||||
| 	unmap_sysmem(hdr); | 	unmap_sysmem(hdr); | ||||||
|  |  | ||||||
| 	if (img_data.header_version < 2) { | 	if (img_data.header_version < 2) { | ||||||
| @@ -119,7 +138,8 @@ static int abootimg_get_dtb_by_index(int argc, char *const argv[]) | |||||||
| 		return CMD_RET_FAILURE; | 		return CMD_RET_FAILURE; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (!android_image_get_dtb_by_index(abootimg_addr(), 0, num, | 	if (!android_image_get_dtb_by_index(abootimg_addr(), | ||||||
|  | 					    get_avendor_bootimg_addr(), num, | ||||||
| 					    &addr, &size)) { | 					    &addr, &size)) { | ||||||
| 		return CMD_RET_FAILURE; | 		return CMD_RET_FAILURE; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -1767,7 +1767,7 @@ struct andr_boot_img_hdr_v0; | |||||||
|  * Return: Zero, os start address and length on success, |  * Return: Zero, os start address and length on success, | ||||||
|  *		otherwise on failure. |  *		otherwise on failure. | ||||||
|  */ |  */ | ||||||
| int android_image_get_kernel(const struct andr_boot_img_hdr_v0 *hdr, | int android_image_get_kernel(const void *hdr, | ||||||
| 			     const void *vendor_boot_img, int verify, | 			     const void *vendor_boot_img, int verify, | ||||||
| 			     ulong *os_data, ulong *os_len); | 			     ulong *os_data, ulong *os_len); | ||||||
|  |  | ||||||
| @@ -1796,8 +1796,7 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, | |||||||
|  * @second_len : Pointer to a ulong variable, will hold secondary bootloader length |  * @second_len : Pointer to a ulong variable, will hold secondary bootloader length | ||||||
|  * Return: 0 if succeeded, -1 if secondary bootloader size is 0 |  * Return: 0 if succeeded, -1 if secondary bootloader size is 0 | ||||||
|  */ |  */ | ||||||
| int android_image_get_second(const struct andr_boot_img_hdr_v0 *hdr, | int android_image_get_second(const void *hdr, ulong *second_data, ulong *second_len); | ||||||
| 			     ulong *second_data, ulong *second_len); |  | ||||||
| bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size); | bool android_image_get_dtbo(ulong hdr_addr, ulong *addr, u32 *size); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1838,7 +1837,7 @@ ulong android_image_get_end(const struct andr_boot_img_hdr_v0 *hdr, | |||||||
|  * @vendor_boot_img : Pointer to vendor boot image header |  * @vendor_boot_img : Pointer to vendor boot image header | ||||||
|  * Return: The kernel load address |  * Return: The kernel load address | ||||||
|  */ |  */ | ||||||
| ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, | ulong android_image_get_kload(const void *hdr, | ||||||
| 			      const void *vendor_boot_img); | 			      const void *vendor_boot_img); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1850,7 +1849,7 @@ ulong android_image_get_kload(const struct andr_boot_img_hdr_v0 *hdr, | |||||||
|  * @vendor_boot_img : Pointer to vendor boot image header |  * @vendor_boot_img : Pointer to vendor boot image header | ||||||
|  * Return: Kernel compression type |  * Return: Kernel compression type | ||||||
|  */ |  */ | ||||||
| ulong android_image_get_kcomp(const struct andr_boot_img_hdr_v0 *hdr, | ulong android_image_get_kcomp(const void *hdr, | ||||||
| 			      const void *vendor_boot_img); | 			      const void *vendor_boot_img); | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -1874,7 +1873,7 @@ bool android_image_print_dtb_contents(ulong hdr_addr); | |||||||
|  * @hdr: Pointer to boot image |  * @hdr: Pointer to boot image | ||||||
|  * Return: non-zero if the magic is correct, zero otherwise |  * Return: non-zero if the magic is correct, zero otherwise | ||||||
|  */ |  */ | ||||||
| bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); | bool is_android_boot_image_header(const void *hdr); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * is_android_vendor_boot_image_header() - Check the magic of vendor boot image |  * is_android_vendor_boot_image_header() - Check the magic of vendor boot image | ||||||
| @@ -1887,6 +1886,20 @@ bool is_android_boot_image_header(const struct andr_boot_img_hdr_v0 *hdr); | |||||||
|  */ |  */ | ||||||
| bool is_android_vendor_boot_image_header(const void *vendor_boot_img); | bool is_android_vendor_boot_image_header(const void *vendor_boot_img); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * get_abootimg_addr() - Get Android boot image address | ||||||
|  |  * | ||||||
|  |  * Return: Android boot image address | ||||||
|  |  */ | ||||||
|  | ulong get_abootimg_addr(void); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * get_avendor_bootimg_addr() - Get Android vendor boot image address | ||||||
|  |  * | ||||||
|  |  * Return: Android vendor boot image address | ||||||
|  |  */ | ||||||
|  | ulong get_avendor_bootimg_addr(void); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * board_fit_config_name_match() - Check for a matching board name |  * board_fit_config_name_match() - Check for a matching board name | ||||||
|  * |  * | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user