summaryrefslogtreecommitdiffstats
path: root/common/filetype.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/filetype.c')
-rw-r--r--common/filetype.c109
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(&sector[MBR_Table + MBR_StartSector]);
+ *bootsec = get_unaligned_le32(&sector[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;