2 # SPDX-License-Identifier: GPL-2.0-or-later
4 # Copyright (C) 2022 Luiz Angelo Daros de Luca <luizluca@gmail.com>
6 # Cameo Image header geneator, used by some D-Link DGS-1210 switches
7 # and APRESIA ApresiaLightGS series
19 parser
= argparse
.ArgumentParser(description
='Generate Cameo firmware header.')
20 parser
.add_argument('source_file', type=argparse
.FileType('rb'))
21 parser
.add_argument('dest_file', type=argparse
.FileType('wb'))
22 parser
.add_argument('model')
23 parser
.add_argument('signature')
24 parser
.add_argument('partition', type=int, choices
=range(0,10),
25 metavar
="partition=[0-9]",help="partition id")
26 parser
.add_argument('customer_signature', type=int, choices
=range(0,10),
27 metavar
="customer_signature=[0-9]",
28 help="customer signature")
29 parser
.add_argument('board_version', type=int, choices
=range(0,2**32),
30 metavar
="board_version=[0-4294967295]",
32 parser
.add_argument('linux_loadaddr', nargs
='?',
33 help="Kernel start address in 0xFFFFFFFF format")
34 args
= parser
.parse_args()
36 if len(args
.model
) > MODEL_LEN
:
37 raise ValueError(f
"Model '{args.model}' is greater than {MODEL_LEN} bytes")
39 if len(args
.signature
) > SIGNATURE_LEN
:
40 raise ValueError(f
"Signature '{args.signature}' is greater than"
41 f
"{SIGNATURE_LEN} bytes")
43 if args
.signature
== "os":
44 if args
.linux_loadaddr
:
45 if len(args
.linux_loadaddr
) > LINUXLOAD_LEN
:
46 raise ValueError(f
"linux_loadaddr '{args.linux_loadaddr}' is greater"
47 f
"than {LINUXLOAD_LEN} bytes")
48 if (args
.linux_loadaddr
[0:2] != "0x"):
49 raise ValueError(f
"linux_loadaddr '{args.linux_loadaddr}' must use"
50 f
"the 0x789ABCDE format")
51 int(args
.linux_loadaddr
[2:],16)
53 raise ValueError(f
"linux_loadaddr is required for signature 'os'")
55 args
.linux_loadaddr
= ""
60 buf
= args
.source_file
.read(BUFSIZE
)
63 checksum
= sum(iter(buf
),checksum
) % (1<<32)
66 args
.dest_file
.write(struct
.pack('!I', checksum
))
67 args
.dest_file
.write(struct
.pack(f
'{MODEL_LEN}s',
68 args
.model
.encode("ascii")))
69 args
.dest_file
.write(struct
.pack(f
'{SIGNATURE_LEN}s',
70 args
.signature
.encode("ascii")))
71 args
.dest_file
.write(struct
.pack('!B', args
.partition
))
72 args
.dest_file
.write(struct
.pack('!B', 0x40)) # ??? This header size?
73 args
.dest_file
.write(struct
.pack('!B', 0x00)) # ??? Encrypted?
74 args
.dest_file
.write(struct
.pack('!B', args
.customer_signature
))
75 args
.dest_file
.write(struct
.pack('!I', args
.board_version
))
76 args
.dest_file
.write(struct
.pack('!I', size
))
77 args
.dest_file
.write(struct
.pack(f
'{LINUXLOAD_LEN}s',
78 args
.linux_loadaddr
.encode("ascii")))
79 args
.dest_file
.write(struct
.pack('!2x'))
81 args
.source_file
.seek(0)
83 buf
= args
.source_file
.read(BUFSIZE
)
86 args
.dest_file
.write(buf
)