1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
15 #if !defined(__BYTE_ORDER)
16 #error "Unknown byte order"
19 #if __BYTE_ORDER == __BIG_ENDIAN
20 #define cpu_to_le32(x) bswap_32(x)
21 #define le32_to_cpu(x) bswap_32(x)
22 #elif __BYTE_ORDER == __LITTLE_ENDIAN
23 #define cpu_to_le32(x) (x)
24 #define le32_to_cpu(x) (x)
26 #error "Unsupported endianness"
29 struct bcm4908kernel_header
{
30 uint32_t boot_load_addr
; /* AKA la_address */
31 uint32_t boot_addr
; /* AKA la_entrypt */
34 uint32_t uncomplen
; /* Empty for LZMA, used for LZ4 */
40 printf("\t-i pathname\t\t\tinput kernel filepath\n");
41 printf("\t-o pathname\t\t\toutput kernel filepath\n");
44 int main(int argc
, char **argv
) {
45 struct bcm4908kernel_header header
;
54 if (argc
>= 2 && !strcmp(argv
[1], "-h")) {
59 while ((c
= getopt(argc
, argv
, "i:o:")) != -1) {
62 in
= fopen(optarg
, "r");
65 out
= fopen(optarg
, "w+");
71 fprintf(stderr
, "Failed to open input and/or output file\n");
76 if (fread(&header
, 1, sizeof(header
), in
) != sizeof(header
)) {
77 fprintf(stderr
, "Failed to read %zu bytes from input file\n", sizeof(header
));
82 if (!memcmp(header
.magic
, "BRCM", 4)) {
83 fprintf(stderr
, "Input file already contains BCM4908 kernel header\n");
88 err
= fseek(out
, sizeof(header
), SEEK_SET
);
91 fprintf(stderr
, "Failed to fseek(): %d\n", err
);
97 while ((bytes
= fread(buf
, 1, sizeof(buf
), in
)) > 0) {
98 if (fwrite(buf
, 1, bytes
, out
) != bytes
) {
99 fprintf(stderr
, "Failed to write %zu B to the output file\n", bytes
);
106 header
.boot_load_addr
= cpu_to_le32(0x00080000);
107 header
.boot_addr
= cpu_to_le32(0x00080000);
108 header
.data_len
= cpu_to_le32(length
);
109 header
.magic
[0] = 'B';
110 header
.magic
[1] = 'R';
111 header
.magic
[2] = 'C';
112 header
.magic
[3] = 'M';
113 header
.uncomplen
= 0;
115 fseek(out
, 0, SEEK_SET
);
117 if (fwrite(&header
, 1, sizeof(header
), out
) != sizeof(header
)) {
118 fprintf(stderr
, "Failed to write header to the output file\n");