diff options
Diffstat (limited to 'common/filetype.c')
-rw-r--r-- | common/filetype.c | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/common/filetype.c b/common/filetype.c index fd6e8e3d1c..f922494500 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * filetype.c - detect filetypes * * Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <common.h> #include <filetype.h> @@ -28,8 +17,9 @@ #include <disks.h> #include <image-sparse.h> #include <elf.h> +#include <linux/zstd.h> -#include <arm/mach-imx/include/mach/imx-header.h> +#include <mach/imx/imx-header.h> struct filetype_str { const char *name; /* human readable filetype */ @@ -56,6 +46,7 @@ static const struct filetype_str filetype_str[] = { [filetype_mbr] = { "MBR sector", "mbr" }, [filetype_bmp] = { "BMP image", "bmp" }, [filetype_png] = { "PNG image", "png" }, + [filetype_qoi] = { "QOI image", "qoi" }, [filetype_ext] = { "EXT filesystem", "ext" }, [filetype_gpt] = { "GUID Partition Table", "gpt" }, [filetype_ubifs] = { "UBIFS image", "ubifs" }, @@ -72,15 +63,25 @@ static const struct filetype_str filetype_str[] = { [filetype_kwbimage_v1] = { "MVEBU kwbimage (v1)", "kwb1" }, [filetype_android_sparse] = { "Android sparse image", "sparse" }, [filetype_arm64_linux_image] = { "ARM aarch64 Linux image", "aarch64-linux" }, + [filetype_arm64_efi_linux_image] = { "ARM aarch64 Linux/EFI image", "aarch64-efi-linux" }, + [filetype_riscv_linux_image] = { "RISC-V Linux image", "riscv-linux" }, + [filetype_riscv_efi_linux_image] = { "RISC-V Linux/EFI image", "riscv-efi-linux" }, + [filetype_riscv_barebox_image] = { "RISC-V barebox image", "riscv-barebox" }, [filetype_elf] = { "ELF", "elf" }, [filetype_imx_image_v1] = { "i.MX image (v1)", "imx-image-v1" }, [filetype_imx_image_v2] = { "i.MX image (v2)", "imx-image-v2" }, [filetype_layerscape_image] = { "Layerscape image", "layerscape-PBL" }, [filetype_layerscape_qspi_image] = { "Layerscape QSPI image", "layerscape-qspi-PBL" }, + [filetype_nxp_fspi_image] = { "NXP FlexSPI image", "nxp-fspi-image" }, [filetype_ubootvar] = { "U-Boot environmemnt variable data", "ubootvar" }, - [filetype_stm32_image_v1] = { "STM32 image (v1)", "stm32-image-v1" }, + [filetype_stm32_image_fsbl_v1] = { "STM32MP FSBL image (v1)", "stm32-fsbl-v1" }, + [filetype_stm32_image_ssbl_v1] = { "STM32MP SSBL image (v1)", "stm32-ssbl-v1" }, [filetype_zynq_image] = { "Zynq image", "zynq-image" }, + [filetype_mxs_sd_image] = { "i.MX23/28 SD card image", "mxs-sd-image" }, + [filetype_rockchip_rkns_image] = { "Rockchip boot image", "rk-image" }, + [filetype_fip] = { "TF-A Firmware Image Package", "fip" }, + [filetype_zstd_compressed] = { "ZSTD compressed", "zstd" }, }; const char *file_type_to_string(enum filetype f) @@ -225,7 +226,7 @@ enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec) * first partition so we could check if there is a FAT boot * sector there */ - *bootsec = get_unaligned_le16(§or[MBR_Table + MBR_StartSector]); + *bootsec = get_unaligned_le32(§or[MBR_Table + MBR_StartSector]); return filetype_mbr; } @@ -252,6 +253,11 @@ enum filetype file_detect_partition_table(const void *_buf, size_t bufsize) return filetype_unknown; } +static bool is_dos_exe(const u8 *buf8) +{ + return buf8[0] == 'M' && buf8[1] == 'Z'; +} + #define CH_TOC_section_name 0x14 enum filetype file_detect_type(const void *_buf, size_t bufsize) @@ -307,12 +313,25 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) return filetype_aimage; if (buf64[0] == le64_to_cpu(0x0a1a0a0d474e5089ull)) return filetype_png; + if (strncmp(buf8, "qoif", 4) == 0) + return filetype_qoi; if (is_barebox_mips_head(_buf)) return filetype_mips_barebox; if (buf[0] == be32_to_cpu(0x534F4659)) return filetype_bpk; if (le32_to_cpu(buf[14]) == 0x644d5241) - return filetype_arm64_linux_image; + return is_dos_exe(buf8) ? filetype_arm64_efi_linux_image : filetype_arm64_linux_image; + if (le32_to_cpu(buf[14]) == 0x05435352) + return is_dos_exe(buf8) ? filetype_riscv_efi_linux_image : filetype_riscv_linux_image; + if (le32_to_cpu(buf[14]) == 0x56435352 && !memcmp(&buf[12], "barebox", 8)) + return filetype_riscv_barebox_image; + if (strncmp(buf8, "RKNS", 4) == 0) + return filetype_rockchip_rkns_image; + if (le32_to_cpu(buf[0]) == le32_to_cpu(0xaa640001)) + return filetype_fip; + if (le32_to_cpu(buf[0]) == le32_to_cpu(ZSTD_MAGICNUMBER)) + return filetype_zstd_compressed; + if ((buf8[0] == 0x5a || buf8[0] == 0x69 || buf8[0] == 0x78 || buf8[0] == 0x8b || buf8[0] == 0x9c) && buf8[0x1] == 0 && buf8[0x2] == 0 && buf8[0x3] == 0 && @@ -341,6 +360,11 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) return filetype_layerscape_image; if (buf[0] == 0x01ee0100 && buf[1] == 0xaa55aa55) return filetype_layerscape_qspi_image; + if (buf[0] == 0xaa55aa55 && buf[1] == 0x80100000) + return filetype_layerscape_image; + + if (le32_to_cpu(buf[0]) == 0x00112233 && le32_to_cpu(buf[1]) == 0x1) + return filetype_mxs_sd_image; if (bufsize < 64) return filetype_unknown; @@ -356,15 +380,21 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01) return filetype_arm_zimage; - if (buf8[0] == 'M' && buf8[1] == 'Z') + if (is_dos_exe(buf8)) return filetype_exe; if (bufsize < 256) return filetype_unknown; if (strncmp(buf8, "STM\x32", 4) == 0) { - if (buf8[74] == 0x01) - return filetype_stm32_image_v1; + if (buf8[74] == 0x01) { + switch(le32_to_cpu(buf[63])) { + case 0x00000000: + return filetype_stm32_image_ssbl_v1; + case 0x10000000: + return filetype_stm32_image_fsbl_v1; + } + } } if (bufsize < 512) @@ -393,21 +423,24 @@ enum filetype file_detect_type(const void *_buf, size_t bufsize) if (is_imx_flash_header_v2(_buf)) return filetype_imx_image_v2; + if (buf[0] == cpu_to_be32(FCFB_HEAD_TAG) && + buf[1] == cpu_to_le32(FCFB_VERSION)) + return filetype_nxp_fspi_image; + if (buf[8] == 0xAA995566 && buf[9] == 0x584C4E58) return filetype_zynq_image; return filetype_unknown; } -enum filetype file_name_detect_type_offset(const char *filename, loff_t pos) +int file_name_detect_type_offset(const char *filename, loff_t pos, enum filetype *type) { int fd, ret; void *buf; - enum filetype type = filetype_unknown; fd = open_and_lseek(filename, O_RDONLY, pos); if (fd < 0) - goto out; + return fd; buf = xzalloc(FILE_TYPE_SAFE_BUFSIZE); @@ -415,34 +448,29 @@ enum filetype file_name_detect_type_offset(const char *filename, loff_t pos) if (ret < 0) goto err_out; - type = file_detect_type(buf, ret); + *type = file_detect_type(buf, ret); + ret = 0; err_out: close(fd); free(buf); -out: - return type; + + return ret; } -enum filetype file_name_detect_type(const char *filename) +int file_name_detect_type(const char *filename, enum filetype *type) { - return file_name_detect_type_offset(filename, 0); + return file_name_detect_type_offset(filename, 0, type); } -enum filetype cdev_detect_type(const char *name) +int cdev_detect_type(struct cdev *cdev, enum filetype *type) { - enum filetype type = filetype_unknown; int ret; - struct cdev *cdev; void *buf; - cdev = cdev_open(name, O_RDONLY); - if (!cdev) - return type; - if (cdev->filetype != filetype_unknown) { - type = cdev->filetype; - goto cdev_close; + *type = cdev->filetype; + return 0; } buf = xzalloc(FILE_TYPE_SAFE_BUFSIZE); @@ -450,13 +478,12 @@ enum filetype cdev_detect_type(const char *name) if (ret < 0) goto err_out; - type = file_detect_type(buf, ret); + *type = file_detect_type(buf, ret); + ret = 0; err_out: free(buf); -cdev_close: - cdev_close(cdev); - return type; + return ret; } bool filetype_is_barebox_image(enum filetype ft) @@ -468,6 +495,8 @@ bool filetype_is_barebox_image(enum filetype ft) case filetype_ch_image_be: case filetype_layerscape_image: case filetype_layerscape_qspi_image: + case filetype_stm32_image_fsbl_v1: + case filetype_fip: return true; default: return false; |