diff options
author | John Crispin <john@openwrt.org> | 2014-01-12 12:07:46 +0000 |
---|---|---|
committer | John Crispin <john@openwrt.org> | 2014-01-12 12:07:46 +0000 |
commit | 2b4a04089ffa854324a8bc16cfe208d5fc058c62 (patch) | |
tree | 0dee6dc96274a0ba664648159ed89f6134ea0a4d /tools | |
parent | 3a64ddd0a18efe3c8fbf65579dca58672bf04fb1 (diff) | |
download | upstream-2b4a04089ffa854324a8bc16cfe208d5fc058c62.tar.gz upstream-2b4a04089ffa854324a8bc16cfe208d5fc058c62.tar.bz2 upstream-2b4a04089ffa854324a8bc16cfe208d5fc058c62.zip |
firmware-utils: add HLK-RM04 tool
Signed-off-by: John Crispin <blogic@openwrt.org>
SVN-Revision: 39238
Diffstat (limited to 'tools')
-rw-r--r-- | tools/firmware-utils/Makefile | 1 | ||||
-rw-r--r-- | tools/firmware-utils/src/mkhilinkfw.c | 320 |
2 files changed, 321 insertions, 0
From 4f740351484e88bcea3776578288b6ec400829c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Fri, 15 Jan 2021 16:01:04 +0100
Subject: [PATCH 2/3] dt-bindings: mtd: add binding from BCM4908 partitions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
BCM4908 uses fixed partitions layout but function of some partitions may
vary. Some devices use multiple firmware partitions and those should be
marked to let system discover their purpose.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
.../partitions/brcm,bcm4908-partitions.yaml | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm4908-partitions.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM4908 partitioning
+
+description: |
+ Broadcom BCM4908 CFE bootloader supports two firmware partitions. One is used
+ for regular booting, the other is treated as fallback.
+
+ This binding allows defining all fixed partitions and marking those containing
+ firmware. System can use that information e.g. for booting or flashing
+ purposes.
+
+maintainers:
+ - Rafał Miłecki <rafal@milecki.pl>
+
+properties:
+ compatible:
+ const: brcm,bcm4908-partitions
+
+ "#address-cells": true
+
+ "#size-cells": true
+
+patternProperties:
+ "@[0-9a-f]+$":
+ allOf:
+ - $ref: "partition.yaml#"
+ - properties:
+ compatible:
+ const: brcm,bcm4908-firmware
+
+required:
+ - "#address-cells"
+ - "#size-cells"
+ break;+ + case 'o':+ output_opt++;+ if (output_opt > 1) {+ fprintf(stderr, "%s: only one output file may be specified\n",+ argv[0]);+ show_usage(argv[0]);+ }+ if (strcmp("-", optarg) != 0) {+ output_filename = optarg;+ }+ break;+ + case '?':+ exit(-1);+ + default:+ abort();+ }+ }+ + if (decrypt_opt && encrypt_opt) {+ fprintf(stderr, "%s: decrypt and encrypt may not be used together\n",+ argv[0]);+ show_usage(argv[0]);+ }+ + if (!decrypt_opt && !encrypt_opt) {+ fprintf(stderr, "%s: neither decrypt or encrypt were specified\n",+ argv[0]);+ show_usage(argv[0]);+ }+ + temp_fd = fileno(tmpfile());+ if (temp_fd < 0) {+ fprintf(stderr, "Can't create temporary file\n");+ exit(EXIT_FAILURE);+ }+ + atexit(exit_cleanup);+ DES_set_key_unchecked((const_DES_cblock *)DES_KEY, &schedule);+ + if (input_filename) {+ input_fd = open(input_filename, O_RDONLY);+ if (input_fd < 0) {+ fprintf(stderr, "Can't open %s for reading: %s\n", input_filename,+ strerror(errno));+ exit(EXIT_FAILURE);+ }+ copy_file(input_fd, temp_fd);+ close(input_fd);+ }+ else {+ copy_file(STDIN_FILENO, temp_fd);+ }+ + file_len = lseek(temp_fd, 0, SEEK_CUR);+ if (file_len < 64) {+ fprintf(stderr, "Not enough data\n");+ exit(EXIT_FAILURE);+ }+ + p = mmap(0, file_len, PROT_READ|PROT_WRITE, MAP_SHARED, temp_fd, 0);+ if (p == MAP_FAILED) {+ fprintf(stderr, "mmap failed: %s\n", strerror(errno));+ exit(EXIT_FAILURE);+ } + + if (encrypt_opt) {+ header = (image_header_t *)p;+ off_t len = min(file_len,+ ntohl(header->ih_size) + sizeof(image_header_t));+ if (ntohl(header->ih_magic) != IH_MAGIC) {+ fprintf(stderr, "Header magic incorrect: "+ "expected 0x%08X, got 0x%08X\n",+ IH_MAGIC, ntohl(header->ih_magic));+ munmap(p, file_len);+ exit(EXIT_FAILURE);+ }+ encrypt(p, len);+ munmap(p, file_len);+ if (len != file_len) {+ if (ftruncate(temp_fd, len) < 0) {+ fprintf(stderr, "ftruncate failed: %s\n", strerror(errno));+ exit(EXIT_FAILURE);+ }+ } + }+ + if (decrypt_opt) {+ off_t header_len = min(file_len, sizeof(image_header_t) + 3);+ memcpy(buf, p, header_len);+ decrypt(buf, header_len);+ header = (image_header_t *)buf;+ if (ntohl(header->ih_magic) != IH_MAGIC) {+ fprintf(stderr, "Header magic incorrect: "+ "expected 0x%08X, got 0x%08X\n",+ IH_MAGIC, ntohl(header->ih_magic));+ exit(EXIT_FAILURE);+ }+ decrypt(p, file_len);+ munmap(p, file_len);+ }+ + lseek(temp_fd, 0, SEEK_SET);+ if (output_filename) {+ output_fd = creat(output_filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);+ if (output_fd < 0) {+ fprintf(stderr, "Can't open %s for writing: %s\n",+ output_filename, strerror(errno));+ exit(EXIT_FAILURE);+ }+ copy_file(temp_fd, output_fd);+ close(output_fd);+ }+ else {+ copy_file(temp_fd, STDOUT_FILENO);+ }+ + exit(EXIT_SUCCESS);+ return 0;+}+ +static void show_usage(const char *arg0)+{+ fprintf(stderr, "usage: %s -d|-e [-i FILE] [-o FILE]\n\n", arg0);+ fprintf(stderr, "%-15s %s\n", "-d, --decrypt", "decrypt data");+ fprintf(stderr, "%-15s %s\n", "-e, --encrypt", "encrypt data");+ fprintf(stderr, "%-15s %s\n", "-i, --input", "intput file (defaults to stdin)");+ fprintf(stderr, "%-15s %s\n", "-o, --output", "output file (defaults to stdout)");+ exit(-1);+}+ +static void exit_cleanup(void)+{+ if (temp_fd >= 0) {+ close(temp_fd);+ }+}+ +static void copy_file(int src, int dst)+{+ char buf[4096];+ ssize_t size;+ + while ((size = read(src, buf, 4096)) > 0) {+ write(dst, buf, size);+ }+}+ +static void encrypt(void *p, off_t len)+{+ DES_cblock *pblock;+ int num_blocks;+ + num_blocks = len / 8;+ pblock = (DES_cblock *) p;+ while (num_blocks--) {+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT);+ pblock++;+ }+ + num_blocks = (len - 3) / 8;+ pblock = (DES_cblock *) (p + 3);+ while (num_blocks--) {+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_ENCRYPT);+ pblock++;+ }+}+ +static void decrypt(void *p, off_t len)+{+ DES_cblock *pblock;+ int num_blocks;+ + num_blocks = (len - 3) / 8;+ pblock = (DES_cblock *) (p + 3);+ while (num_blocks--) {+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT);+ pblock++;+ }+ + num_blocks = len / 8;+ pblock = (DES_cblock *) p;+ while (num_blocks--) {+ DES_ecb_encrypt(pblock, pblock, &schedule, DES_DECRYPT);+ pblock++;+ }+}