diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/.gitignore | 2 | ||||
-rw-r--r-- | scripts/Kconfig | 78 | ||||
-rw-r--r-- | scripts/Makefile | 24 | ||||
-rw-r--r-- | scripts/bareboximd.c | 100 | ||||
-rw-r--r-- | scripts/common.c | 168 | ||||
-rw-r--r-- | scripts/common.h | 10 | ||||
-rw-r--r-- | scripts/imx/imx-image.c | 47 | ||||
-rw-r--r-- | scripts/imx/imx-usb-loader.c | 77 | ||||
-rw-r--r-- | scripts/omap3-usb-loader.c | 47 | ||||
-rw-r--r-- | scripts/rk-usb-loader-target.c | 1 | ||||
-rw-r--r-- | scripts/rk-usb-loader.c | 328 | ||||
-rw-r--r-- | scripts/rkimage.c | 71 | ||||
-rw-r--r-- | scripts/rockchip.h | 35 | ||||
-rw-r--r-- | scripts/socfpga_mkimage.c | 51 |
14 files changed, 675 insertions, 364 deletions
diff --git a/scripts/.gitignore b/scripts/.gitignore index cf645ec746..ae70c92af8 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -31,6 +31,8 @@ omap4_usbboot omap4_usbboot-target omap3-usb-loader omap3-usb-loader-target +rk-usb-loader +rk-usb-loader-target mips-relocs rsatoc stm32image diff --git a/scripts/Kconfig b/scripts/Kconfig index a490aaa44e..9b744deba9 100644 --- a/scripts/Kconfig +++ b/scripts/Kconfig @@ -12,6 +12,69 @@ config COMPILE_HOST_TOOLS source "scripts/imx/Kconfig" +config SOCFPGA_MKIMAGE + bool "SoCFPGA mkimage" if COMPILE_HOST_TOOLS + depends on ARCH_SOCFPGA || COMPILE_HOST_TOOLS + default y if ARCH_SOCFPGA + help + This enables building the image creation tool for SoCFPGA + +config ZYNQ_MKIMAGE + bool "Zynq mkimage" if COMPILE_HOST_TOOLS + depends on ARCH_ZYNQ || COMPILE_HOST_TOOLS + default y if ARCH_ZYNQ + help + This enables building the image creation tool for Zynq + +config MXS_HOSTTOOLS + bool "MXS host tools" if COMPILE_HOST_TOOLS + depends on ARCH_MXS || COMPILE_HOST_TOOLS + default y if ARCH_MXS + help + This enables building the host tools for Freescale MXS SoCs + +config LAYERSCAPE_PBLIMAGE + bool "Layerscape PBL image tool" if COMPILE_HOST_TOOLS + depends on ARCH_LAYERSCAPE || COMPILE_HOST_TOOLS + default y if ARCH_LAYERSCAPE + help + This enables building the PBL image tool for Freescale Layerscape SoCs + +config STM32_IMAGE + bool "STM32MP image tool" if COMPILE_HOST_TOOLS + depends on ARCH_STM32MP || COMPILE_HOST_TOOLS + default y if ARCH_STM32MP + help + This enables building the image creation tool for STM32MP SoCs + +config RK_IMAGE + bool "Rockchip image tool" if COMPILE_HOST_TOOLS + depends on ARCH_ROCKCHIP || COMPILE_HOST_TOOLS + default y if ARCH_ROCKCHIP + help + This enables building the image creation tool for Rockchip SoCs + +config OMAP_IMAGE + bool "TI OMAP image tools" if COMPILE_HOST_TOOLS + depends on ARCH_OMAP || COMPILE_HOST_TOOLS + default y if ARCH_OMAP + help + This enables building the image creation tools for TI OMAP SoCs + +config S5P_IMAGE + bool "S5P image tool" if COMPILE_HOST_TOOLS + depends on ARCH_S5PCxx || COMPILE_HOST_TOOLS + default y if ARCH_S5PCxx + help + This enables building the image creation tool for S5P SoCs + +config DAVINCI_IMAGE + bool "Davinci image tool" if COMPILE_HOST_TOOLS + depends on ARCH_DAVINCI || COMPILE_HOST_TOOLS + default y if ARCH_DAVINCI + help + This enables building the image creation tool for Davinci SoCs + config MVEBU_HOSTTOOLS bool "mvebu hosttools" if COMPILE_HOST_TOOLS depends on ARCH_MVEBU || COMPILE_HOST_TOOLS @@ -39,6 +102,14 @@ config OMAP4_HOSTTOOL_USBBOOT You need libusb-1.0 to compile this tool. +config RK_USB_LOADER + bool "Rockchip USB loader" + depends on ARCH_ROCKCHIP || COMPILE_HOST_TOOLS + help + Say Y here to build the rockchip usb loader tool. + + You need libusb-1.0 to compile this tool. + endmenu menu "Target Tools" @@ -104,4 +175,11 @@ config OMAP4_USBBOOT_TARGET Say Y here to build the omap4 usb loader tool for the target. The cross toolchain needs libusb-1.0 to compile this tool. +config RK_USB_LOADER_TARGET + bool "Rockchip USB loader for target" + depends on HAS_TARGET_LIBUSB_1_0 + help + Say Y here to build the rockchip usb loader tool for the target. + The cross toolchain needs libusb-1.0 to compile this tool. + endmenu diff --git a/scripts/Makefile b/scripts/Makefile index 1527b07d47..dc5fa75f90 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -15,17 +15,17 @@ hostprogs-always-$(CONFIG_IMD) += bareboximd hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms hostprogs-always-$(CONFIG_MIPS) += mips-relocs hostprogs-always-$(CONFIG_MVEBU_HOSTTOOLS) += kwbimage kwboot mvebuimg -hostprogs-always-$(CONFIG_ARCH_OMAP) += omap_signGP mk-omap-image -hostprogs-always-$(CONFIG_ARCH_S5PCxx) += s5p_cksum -hostprogs-always-$(CONFIG_ARCH_DAVINCI) += mkublheader +hostprogs-always-$(CONFIG_OMAP_IMAGE) += omap_signGP mk-omap-image +hostprogs-always-$(CONFIG_S5P_IMAGE) += s5p_cksum +hostprogs-always-$(CONFIG_DAVINCI_IMAGE) += mkublheader HOSTCFLAGS_zynq_mkimage.o = -I$(srctree) -I$(srctree)/arch/arm/mach-zynq/include -hostprogs-always-$(CONFIG_ARCH_ZYNQ) += zynq_mkimage -hostprogs-always-$(CONFIG_ARCH_SOCFPGA) += socfpga_mkimage -hostprogs-always-$(CONFIG_ARCH_MXS) += mxsimage mxsboot -hostprogs-always-$(CONFIG_ARCH_LAYERSCAPE) += pblimage -hostprogs-always-$(CONFIG_ARCH_STM32MP) += stm32image +hostprogs-always-$(CONFIG_ZYNQ_MKIMAGE) += zynq_mkimage +hostprogs-always-$(CONFIG_SOCFPGA_MKIMAGE) += socfpga_mkimage +hostprogs-always-$(CONFIG_MXS_HOSTTOOLS) += mxsimage mxsboot +hostprogs-always-$(CONFIG_LAYERSCAPE_PBLIMAGE) += pblimage +hostprogs-always-$(CONFIG_STM32_IMAGE) += stm32image hostprogs-always-$(CONFIG_RISCV) += prelink-riscv -hostprogs-always-$(CONFIG_ARCH_ROCKCHIP) += rkimage +hostprogs-always-$(CONFIG_RK_IMAGE) += rkimage HOSTCFLAGS_rkimage = `pkg-config --cflags openssl` HOSTLDLIBS_rkimage = `pkg-config --libs openssl` KBUILD_HOSTCFLAGS += -I$(srctree)/scripts/include/ @@ -36,6 +36,9 @@ hostprogs-always-$(CONFIG_OMAP3_USB_LOADER) += omap3-usb-loader HOSTCFLAGS_omap4_usbboot.o = `pkg-config --cflags libusb-1.0` HOSTLDLIBS_omap4_usbboot = -lpthread `pkg-config --libs libusb-1.0` hostprogs-always-$(CONFIG_OMAP4_HOSTTOOL_USBBOOT) += omap4_usbboot +HOSTCFLAGS_rk-usb-loader.o = `pkg-config --cflags libusb-1.0` +HOSTLDLIBS_rk-usb-loader = `pkg-config --libs libusb-1.0` +hostprogs-always-$(CONFIG_RK_USB_LOADER) += rk-usb-loader userprogs-always-$(CONFIG_BAREBOXENV_TARGET) += bareboxenv-target userprogs-always-$(CONFIG_KERNEL_INSTALL_TARGET) += kernel-install-target @@ -44,11 +47,14 @@ userprogs-always-$(CONFIG_IMD_TARGET) += bareboximd-target userprogs-always-$(CONFIG_OMAP3_USB_LOADER_TARGET) += omap3-usb-loader-target userprogs-always-$(CONFIG_OMAP4_USBBOOT_TARGET) += omap4_usbboot-target userprogs-always-$(CONFIG_MVEBU_KWBOOT_TARGET) += kwboot-target +userprogs-always-$(CONFIG_RK_USB_LOADER_TARGET) += rk-usb-loader-target omap3-usb-loader-target-userccflags += `$(CROSS_PKG_CONFIG) --cflags libusb-1.0` omap3-usb-loader-target-userldlibs += `$(CROSS_PKG_CONFIG) --libs libusb-1.0` omap4_usbboot-target-userccflags += `$(CROSS_PKG_CONFIG) --cflags libusb-1.0` omap4_usbboot-target-userldlibs += -lpthread `$(CROSS_PKG_CONFIG) --libs libusb-1.0` +rk-usb-loader-target-userccflags += `$(CROSS_PKG_CONFIG) --cflags libusb-1.0` +rk-usb-loader-target-userldlibs += `$(CROSS_PKG_CONFIG) --libs libusb-1.0` userccflags += -I $(srctree)/$(src)/include -isystem $(srctree)/scripts/include diff --git a/scripts/bareboximd.c b/scripts/bareboximd.c index c3dcb4dcf0..a734399aa5 100644 --- a/scripts/bareboximd.c +++ b/scripts/bareboximd.c @@ -17,6 +17,8 @@ #include <linux/kernel.h> #include <sys/mman.h> +#include "common.h" +#include "common.c" #include "../include/image-metadata.h" #define eprintf(args...) fprintf(stderr, ## args) @@ -40,104 +42,6 @@ int imd_command_setenv(const char *variable_name, const char *value) return -EINVAL; } -static int write_file(const char *filename, const void *buf, size_t size) -{ - int fd, ret = 0; - int now; - - fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return fd; - - while (size) { - now = write(fd, buf, size); - if (now < 0) { - ret = now; - goto out; - } - size -= now; - buf += now; - } - -out: - close(fd); - - return ret; -} - -static int read_file_2(const char *filename, size_t *size, void **outbuf, size_t max_size) -{ - off_t fsize; - ssize_t rsize; - int ret, fd; - void *buf; - - *size = 0; - *outbuf = NULL; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); - return -errno; - } - - fsize = lseek(fd, 0, SEEK_END); - if (fsize == -1) { - fprintf(stderr, "Cannot get size %s: %s\n", filename, strerror(errno)); - ret = -errno; - goto close; - } - - if (fsize < max_size) - max_size = fsize; - - if (lseek(fd, 0, SEEK_SET) == -1) { - fprintf(stderr, "Cannot seek to start %s: %s\n", filename, strerror(errno)); - ret = -errno; - goto close; - } - - buf = mmap(NULL, max_size, PROT_READ, MAP_SHARED, fd, 0); - if (buf == MAP_FAILED ) { - buf = malloc(max_size); - if (!buf) { - fprintf(stderr, "Cannot allocate memory\n"); - ret = -ENOMEM; - goto close; - } - - *outbuf = buf; - - while (*size < max_size) { - rsize = read(fd, buf, max_size - *size); - if (rsize == 0) { - ret = -EIO; - goto free; - } - - if (rsize < 0) { - ret = -errno; - goto free; - } - - buf += rsize; - *size += rsize; - } - } else { - *outbuf = buf; - *size = max_size; - } - - ret = 0; - goto close; -free: - *outbuf = NULL; - free(buf); -close: - close(fd); - return ret; -} - static inline void read_file_2_free(void *buf) { /* diff --git a/scripts/common.c b/scripts/common.c new file mode 100644 index 0000000000..b780b09941 --- /dev/null +++ b/scripts/common.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include <stdio.h> +#include <sys/types.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> +#include <sys/mman.h> + +#include "common.h" + +int read_file_2(const char *filename, size_t *size, void **outbuf, size_t max_size) +{ + off_t fsize; + ssize_t rsize; + int ret, fd; + void *buf; + + *size = 0; + *outbuf = NULL; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); + return -errno; + } + + fsize = lseek(fd, 0, SEEK_END); + if (fsize == -1) { + fprintf(stderr, "Cannot get size %s: %s\n", filename, strerror(errno)); + ret = -errno; + goto close; + } + + if (fsize < max_size) + max_size = fsize; + + if (lseek(fd, 0, SEEK_SET) == -1) { + fprintf(stderr, "Cannot seek to start %s: %s\n", filename, strerror(errno)); + ret = -errno; + goto close; + } + + buf = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED ) { + buf = malloc(max_size); + if (!buf) { + fprintf(stderr, "Cannot allocate memory\n"); + ret = -ENOMEM; + goto close; + } + + *outbuf = buf; + + while (*size < max_size) { + rsize = read(fd, buf, max_size - *size); + if (rsize == 0) { + ret = -EIO; + goto free; + } + + if (rsize < 0) { + ret = -errno; + goto free; + } + + buf += rsize; + *size += rsize; + } + } else { + *outbuf = buf; + *size = max_size; + } + + ret = 0; + goto close; +free: + *outbuf = NULL; + free(buf); +close: + close(fd); + return ret; +} + +void *read_file(const char *filename, size_t *size) +{ + int ret; + void *buf; + + ret = read_file_2(filename, size, &buf, (size_t)-1); + if (!ret) + return buf; + + errno = -ret; + + return NULL; +} + +int write_file(const char *filename, const void *buf, size_t size) +{ + int fd, ret = 0; + int now; + + fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (fd < 0) { + fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); + return -errno; + } + + while (size) { + now = write(fd, buf, size); + if (now < 0) { + fprintf(stderr, "Cannot write to %s: %s\n", filename, + strerror(errno)); + ret = -errno; + goto out; + } + size -= now; + buf += now; + } + +out: + close(fd); + + return ret; +} + +int read_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + int total = 0; + + while (size) { + now = read(fd, buf, size); + if (now == 0) + return total; + if (now < 0) + return now; + total += now; + size -= now; + buf += now; + } + + return insize; +} + +int write_full(int fd, void *buf, size_t size) +{ + size_t insize = size; + int now; + + while (size) { + now = write(fd, buf, size); + if (now <= 0) + return now; + size -= now; + buf += now; + } + + return insize; +} diff --git a/scripts/common.h b/scripts/common.h new file mode 100644 index 0000000000..820108c52c --- /dev/null +++ b/scripts/common.h @@ -0,0 +1,10 @@ +#ifndef __COMMON_H +#define __COMMON_H + +int read_file_2(const char *filename, size_t *size, void **outbuf, size_t max_size); +void *read_file(const char *filename, size_t *size); +int write_file(const char *filename, const void *buf, size_t size); +int read_full(int fd, void *buf, size_t size); +int write_full(int fd, void *buf, size_t size); + +#endif /* __COMMON_H */ diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c index b97f561897..439912a805 100644 --- a/scripts/imx/imx-image.c +++ b/scripts/imx/imx-image.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <sys/file.h> #include "../compiler.h" +#include "../common.h" #include "imx.h" @@ -23,6 +24,8 @@ #define FLASH_HEADER_OFFSET 0x400 #define ARM_HEAD_SIZE_INDEX (ARM_HEAD_SIZE_OFFSET / sizeof(uint32_t)) +#include "../common.c" + /* * Conservative DCD element limit set to restriction v2 header size to * HEADER_SIZE @@ -721,38 +724,6 @@ static int hab_sign(struct config_data *data) return 0; } -static void *xread_file(const char *filename, size_t *size) -{ - int fd, ret; - void *buf; - struct stat s; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno)); - exit(1); - } - - ret = fstat(fd, &s); - if (ret) { - fprintf(stderr, "Cannot stat %s: %s\n", filename, strerror(errno)); - exit(1); - } - - *size = s.st_size; - buf = malloc(*size); - if (!buf) { - perror("malloc"); - exit(1); - } - - xread(fd, buf, *size); - - close(fd); - - return buf; -} - static bool cpu_is_aarch64(const struct config_data *data) { return cpu_is_mx8m(data); @@ -914,8 +885,10 @@ int main(int argc, char *argv[]) if (data.signed_hdmi_firmware_file) { free(buf); - buf = xread_file(data.signed_hdmi_firmware_file, + buf = read_file(data.signed_hdmi_firmware_file, &signed_hdmi_firmware_size); + if (!buf) + exit(1); signed_hdmi_firmware_size = roundup(signed_hdmi_firmware_size, @@ -957,7 +930,9 @@ int main(int argc, char *argv[]) bb_header[0] = data.first_opcode; bb_header[ARM_HEAD_SIZE_INDEX] = barebox_image_size; - infile = xread_file(imagename, &insize); + infile = read_file(imagename, &insize); + if (!infile) + exit(1); outfd = open(data.outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (outfd < 0) { @@ -1024,7 +999,9 @@ int main(int argc, char *argv[]) if (create_usb_image) { uint32_t *dcd; - infile = xread_file(data.outfile, &insize); + infile = read_file(data.outfile, &insize); + if (!infile) + exit(1); dcd = infile + dcd_ptr_offset; *dcd = dcd_ptr_content; diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index cff77f27f2..d8b2842989 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -34,9 +34,12 @@ #include <arpa/inet.h> #include <linux/kernel.h> +#include "../common.h" #include "../compiler.h" #include "imx.h" +#include "../common.c" + #define get_min(a, b) (((a) < (b)) ? (a) : (b)) #define FT_APP 0xaa @@ -409,61 +412,6 @@ static void dump_bytes(const void *src, unsigned cnt, unsigned addr) } } -static long get_file_size(FILE *xfile) -{ - long size; - fseek(xfile, 0, SEEK_END); - size = ftell(xfile); - rewind(xfile); - - return size; -} - -static int read_file(const char *name, unsigned char **buffer, unsigned *size) -{ - FILE *xfile; - unsigned fsize; - int cnt; - unsigned char *buf; - xfile = fopen(name, "rb"); - if (!xfile) { - printf("error, can not open input file: %s\n", name); - return -5; - } - - fsize = get_file_size(xfile); - if (fsize < 0x20) { - printf("error, file: %s is too small\n", name); - fclose(xfile); - return -2; - } - - buf = malloc(ALIGN(fsize, 4)); - if (!buf) { - printf("error, out of memory\n"); - fclose(xfile); - return -2; - } - - cnt = fread(buf, 1 , fsize, xfile); - if (cnt < fsize) { - printf("error, cannot read %s\n", name); - fclose(xfile); - free(buf); - return -1; - } - - if (size) - *size = fsize; - - if (buffer) - *buffer = buf; - else - free(buf); - - return 0; -} - /* * HID Class-Specific Requests values. See section 7.2 of the HID specifications */ @@ -1381,7 +1329,7 @@ static int do_irom_download(struct usb_work *curr, int verify) { int ret; unsigned char type; - unsigned fsize = 0; + size_t fsize = 0; unsigned header_offset; unsigned char *buf = NULL; unsigned char *image; @@ -1391,9 +1339,9 @@ static int do_irom_download(struct usb_work *curr, int verify) unsigned header_addr = 0; unsigned total_size = 0; - ret = read_file(curr->filename, &buf, &fsize); - if (ret < 0) - return ret; + buf = read_file(curr->filename, &fsize); + if (!buf) + return -errno; max_length = fsize; @@ -1436,7 +1384,7 @@ static int do_irom_download(struct usb_work *curr, int verify) } } - printf("loading binary file(%s) to 0x%08x, fsize=%u type=%d...\n", + printf("loading binary file(%s) to 0x%08x, fsize=%zu type=%d...\n", curr->filename, header_addr, fsize, type); ret = load_file(image, fsize, header_addr, type, false); @@ -1552,13 +1500,12 @@ static int mxs_load_file(libusb_device_handle *dev, uint8_t *data, int size) static int mxs_work(struct usb_work *curr) { - unsigned fsize = 0; + size_t fsize = 0; unsigned char *buf = NULL; - int ret; - ret = read_file(curr->filename, &buf, &fsize); - if (ret < 0) - return ret; + buf = read_file(curr->filename, &fsize); + if (!buf) + return -errno; return mxs_load_file(usb_dev_handle, buf, fsize); } diff --git a/scripts/omap3-usb-loader.c b/scripts/omap3-usb-loader.c index 0f352c8453..a8d626c32f 100644 --- a/scripts/omap3-usb-loader.c +++ b/scripts/omap3-usb-loader.c @@ -30,6 +30,9 @@ #include <libusb.h> /* the main event */ +#include "common.h" +#include "common.c" + /* Device specific defines (OMAP) * Primary source: http://www.ti.com/lit/pdf/sprugn4 * Section 26.4.5 "Peripheral Booting" @@ -325,50 +328,6 @@ found: return handle; } -static unsigned char *read_file(char *path, size_t *readamt) -{ - FILE *fp = fopen(path, "rb"); - - if (!fp) { - log_error("failed to open file \'%s\': %s\n", path, - strerror(errno)); - return NULL; - } - - unsigned char *data = NULL; - size_t allocsize = 0; - size_t iter = 0; - - while (1) { - allocsize += 1024; - data = realloc(data, allocsize); - if (!data) - return NULL; - - size_t readsize = allocsize - iter; - size_t ret = fread(data + iter, sizeof (unsigned char), readsize, fp); - - iter += ret; - - if (ret != readsize) { - if (feof(fp)) { - break; - } else if (ferror(fp)) { - log_error("error file reading file \'%s\': %s\n", - path, strerror(errno)); - free(data); - return NULL; - } - } - } - - /* trim the allocation down to size */ - data = realloc(data, iter); - *readamt = iter; - - return data; -} - static int transfer_first_stage(libusb_device_handle * handle, struct arg_state *args) { unsigned char *buffer = NULL; diff --git a/scripts/rk-usb-loader-target.c b/scripts/rk-usb-loader-target.c new file mode 100644 index 0000000000..fe1540d752 --- /dev/null +++ b/scripts/rk-usb-loader-target.c @@ -0,0 +1 @@ +#include "rk-usb-loader.c" diff --git a/scripts/rk-usb-loader.c b/scripts/rk-usb-loader.c new file mode 100644 index 0000000000..9c2367ed28 --- /dev/null +++ b/scripts/rk-usb-loader.c @@ -0,0 +1,328 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +/* + * rk-usb-loader: A tool to USB Bootstrap Rockchip SoCs + * + * This tool bootstraps Rockchip SoCs via USB. It is known to work + * on these SoCs: + * + * - RK3568 + * - RK3566 + * + * rk-usb-loader takes the barebox images the barebox build process + * generates as input. The upload protocol has been taken from the + * rkdevelop tool, but it's not a full replacement of that tool. + */ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <string.h> +#include <stdbool.h> +#include <unistd.h> +#include <getopt.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <libusb.h> + +#include "common.h" +#include "common.c" +#include "rockchip.h" + +static void log_error(char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + fprintf(stdout, "[-] "); + vfprintf(stdout, fmt, va); + va_end(va); +} + +static void log_info(char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + fprintf(stdout, "[+] "); + vfprintf(stdout, fmt, va); + va_end(va); +} + +static int debug; + +static void log_debug(char *fmt, ...) +{ + va_list va; + + if (!debug) + return; + + va_start(va, fmt); + fprintf(stdout, "[D] "); + vfprintf(stdout, fmt, va); + va_end(va); +} + +static libusb_device_handle *rk_usb_open(libusb_context *ctx, uint16_t vendor, uint16_t product) +{ + libusb_device **devlist; + libusb_device_handle *handle; + struct libusb_device_descriptor desc; + ssize_t count, i; + int ret; + + log_info("scanning for USB device matching %04hx:%04hx...\n", + vendor, product); + + while (1) { + if ((count = libusb_get_device_list(ctx, &devlist)) < 0) { + log_error("failed to gather USB device list: %s\n", + libusb_error_name(count)); + return NULL; + } + + for (i = 0; i < count; i++) { + ret = libusb_get_device_descriptor(devlist[i], &desc); + if (ret < 0) { + log_error("failed to get USB device descriptor: %s\n", + libusb_error_name(ret)); + libusb_free_device_list(devlist, 1); + return NULL; + } + + if (desc.idVendor != vendor) + continue; + + if (product) { + if (desc.idProduct != product) + continue; + goto found; + } + } + + libusb_free_device_list(devlist, 1); + + /* nothing found yet. have a 10ms nap */ + usleep(10000); + } +found: + + ret = libusb_open(devlist[i], &handle); + if (ret < 0) { + log_error("failed to open USB device %04hx:%04hx: %s\n", + vendor, product, libusb_error_name(ret)); + libusb_free_device_list(devlist, 1); + return NULL; + } + + ret = libusb_claim_interface(handle, 0); + if (ret) { + printf("Claim failed\n"); + return NULL; + } + + log_info("successfully opened %04hx:%04hx\n", vendor, product); + + return handle; +} + +#define poly16_CCITT 0x1021 /* crc-ccitt mask */ + +static uint16_t crc_calculate(uint16_t crc, unsigned char ch) +{ + unsigned int i; + + for (i = 0x80; i != 0; i >>= 1) { + if (crc & 0x8000) { + crc <<= 1; + crc ^= poly16_CCITT; + } else { + crc <<= 1; + } + + if (ch & i) + crc ^= poly16_CCITT; + } + return crc; +} + +static uint16_t crc_ccitt(unsigned char *p, int n) +{ + uint16_t crc = 0xffff; + + while (n--) { + crc = crc_calculate(crc, *p); + p++; + } + + return crc; +} + +static int upload(libusb_device_handle *dev, unsigned int dwRequest, void *buf, int n_bytes) +{ + uint16_t crc; + uint8_t *data; + int sent = 0, ret; + + data = calloc(n_bytes + 5, 1); + memcpy(data, buf, n_bytes); + + crc = crc_ccitt(data, n_bytes); + data[n_bytes] = (crc & 0xff00) >> 8; + data[n_bytes + 1] = crc & 0x00ff; + n_bytes += 2; + + while (sent < n_bytes) { + int now; + + if (n_bytes - sent > 4096) + now = 4096; + else + now = n_bytes - sent; + + ret = libusb_control_transfer(dev, 0x40, 0xC, 0, dwRequest, + data + sent, now, 0); + if (ret != now) { + log_error("DeviceRequest 0x%x failed, err=%d", + dwRequest, ret); + + ret = -EIO; + goto err; + } + sent += now; + } + + ret = 0; +err: + free(data); + + return ret; +} + +static int upload_image(const char *filename) +{ + libusb_context *ctx; + libusb_device_handle *dev; + int ret; + void *buf; + struct newidb *hdr; + int i, n_files; + size_t size; + + buf = read_file(filename, &size); + if (!buf) + exit(1); + + hdr = buf; + + if (hdr->magic != NEWIDB_MAGIC) { + log_error("%s has invalid magic 0x%08x ( != 0x%08x )\n", filename, + hdr->magic, NEWIDB_MAGIC); + exit(1); + } + + ret = libusb_init(&ctx); + if (ret < 0) { + log_error("failed to initialize libusb context: %s\n", + libusb_error_name(ret)); + return ret; + } + + dev = rk_usb_open(ctx, 0x2207, 0x350a); + if (!dev) { + libusb_exit(ctx); + return 1; + } + + n_files = hdr->n_files >> 16; + + if (n_files > 2) { + /* + * This tool is designed for barebox images generated with rkimage. + * These have one blob containing the SDRAM setup sent with the + * CODE471_OPTION and one blob containing the barebox image sent with + * the CODE472_OPTION. + */ + log_error("Invalid image with %d blobs\n", n_files); + ret = -EINVAL; + goto err; + } + + for (i = 0; i < n_files; i++) { + struct newidb_entry *entry = &hdr->entries[i]; + int foffset, fsize, wIndex; + + if (i) + wIndex = 0x472; + else + wIndex = 0x471; + + log_info("Uploading %d/%d\n", i + 1, n_files); + + foffset = (entry->sector & 0xffff) * SECTOR_SIZE; + fsize = (entry->sector >> 16) * SECTOR_SIZE; + + log_debug("image starting at offset 0x%08x, size 0x%08x\n", foffset, fsize); + + ret = upload(dev, wIndex, buf + foffset, fsize); + if (ret) + goto err; + } + + ret = 0; +err: + libusb_close(dev); + libusb_exit(ctx); + + return ret; +} + +static void usage(const char *prgname) +{ + printf( +"Usage: %s [OPTIONS] <IMAGE>\n" +"\n" +"Options:\n" +" -d Enable debugging output\n" +" -h This help\n", + prgname); +} + +static struct option cbootcmd[] = { + {"debug", 0, NULL, 'd'}, + {"help", 0, NULL, 'h'}, + {0, 0, 0, 0}, +}; + +int main(int argc, char **argv) +{ + int opt, ret; + const char *filename; + + while ((opt = getopt_long(argc, argv, "hd", cbootcmd, NULL)) > 0) { + switch (opt) { + case 'h': + usage(argv[0]); + exit(0); + case 'd': + debug = 1; + break; + } + } + + if (argc == optind) { + usage(argv[0]); + exit(1); + } + + filename = argv[optind]; + + ret = upload_image(filename); + if (ret) + exit(1); + + exit(0); +} diff --git a/scripts/rkimage.c b/scripts/rkimage.c index dde9724886..6e68d508ac 100644 --- a/scripts/rkimage.c +++ b/scripts/rkimage.c @@ -13,6 +13,10 @@ #include <errno.h> #include <stdbool.h> +#include "common.h" +#include "common.c" +#include "rockchip.h" + #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) @@ -34,37 +38,6 @@ static void sha512(const void *buf, int len, void *out) SHA512_Final(out, &sha512); } -#define NEWIDB_MAGIC 0x534e4b52 /* 'RKNS' */ - -struct newidb_entry { - uint32_t sector; - uint32_t unknown_ffffffff; - uint32_t unknown1; - uint32_t image_number; - unsigned char unknown2[8]; - unsigned char hash[64]; -}; - -struct newidb { - uint32_t magic; - unsigned char unknown1[4]; - uint32_t n_files; - uint32_t hashtype; - unsigned char unknown2[8]; - unsigned char unknown3[8]; - unsigned char unknown4[88]; - struct newidb_entry entries[4]; - unsigned char unknown5[40]; - unsigned char unknown6[512]; - unsigned char unknown7[16]; - unsigned char unknown8[32]; - unsigned char unknown9[464]; - unsigned char hash[512]; -}; - -#define SECTOR_SIZE 512 -#define PAGE_SIZE 2048 - typedef enum { HASH_TYPE_SHA256 = 1, HASH_TYPE_SHA512 = 2, @@ -149,42 +122,6 @@ static void usage(const char *prgname) prgname); } -static int read_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - int total = 0; - - while (size) { - now = read(fd, buf, size); - if (now == 0) - return total; - if (now < 0) - return now; - total += now; - size -= now; - buf += now; - } - - return insize; -} - -static int write_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - - while (size) { - now = write(fd, buf, size); - if (now <= 0) - return now; - size -= now; - buf += now; - } - - return insize; -} - int main(int argc, char *argv[]) { int opt, i, fd; diff --git a/scripts/rockchip.h b/scripts/rockchip.h new file mode 100644 index 0000000000..8cc14f8f2f --- /dev/null +++ b/scripts/rockchip.h @@ -0,0 +1,35 @@ +#ifndef __ROCKCHIP_H +#define __ROCKCHIP_H + +#define NEWIDB_MAGIC 0x534e4b52 /* 'RKNS' */ + +struct newidb_entry { + uint32_t sector; + uint32_t unknown_ffffffff; + uint32_t unknown1; + uint32_t image_number; + unsigned char unknown2[8]; + unsigned char hash[64]; +}; + +struct newidb { + uint32_t magic; + unsigned char unknown1[4]; + uint32_t n_files; + uint32_t hashtype; + unsigned char unknown2[8]; + unsigned char unknown3[8]; + unsigned char unknown4[88]; + struct newidb_entry entries[4]; + unsigned char unknown5[40]; + unsigned char unknown6[512]; + unsigned char unknown7[16]; + unsigned char unknown8[32]; + unsigned char unknown9[464]; + unsigned char hash[512]; +}; + +#define SECTOR_SIZE 512 +#define PAGE_SIZE 2048 + +#endif /* __ROCKCHIP_H */ diff --git a/scripts/socfpga_mkimage.c b/scripts/socfpga_mkimage.c index 73dfbeae3a..e88e75962f 100644 --- a/scripts/socfpga_mkimage.c +++ b/scripts/socfpga_mkimage.c @@ -10,6 +10,9 @@ #include <fcntl.h> #include <endian.h> +#include "common.h" +#include "common.c" + #define VALIDATION_WORD 0x31305341 #define BRANCH_INST 0xea /* ARM opcode for "b" (unconditional branch) */ @@ -65,42 +68,6 @@ static uint32_t bb_header[] = { 0xea00006b, /* entry. b 0x200 (offset may be adjusted) */ }; -static int read_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - int total = 0; - - while (size) { - now = read(fd, buf, size); - if (now == 0) - return total; - if (now < 0) - return now; - total += now; - size -= now; - buf += now; - } - - return insize; -} - -static int write_full(int fd, void *buf, size_t size) -{ - size_t insize = size; - int now; - - while (size) { - now = write(fd, buf, size); - if (now <= 0) - return now; - size -= now; - buf += now; - } - - return insize; -} - static const uint32_t crc_table[256] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, @@ -381,17 +348,9 @@ int main(int argc, char *argv[]) if (ret) exit(1); - fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (fd < 0) { - perror("open outfile"); - exit(1); - } - - ret = write_full(fd, buf, s.st_size + 4 + addsize + pad); - if (ret < 0) { - perror("write outfile"); + ret = write_file(outfile, buf, s.st_size + 4 + addsize + pad); + if (ret) exit(1); - } exit(0); } |