generic: 6.1, 6.6: replace Airoha EN8811H PHY driver with upstream
[openwrt/openwrt.git] / scripts / sercomm-kernel-header.py
1 #!/usr/bin/env python3
2 """
3 # SPDX-License-Identifier: GPL-2.0-or-later
4 #
5 # sercomm-kernel-header.py: Creates Sercomm kernel header
6 #
7 # Copyright © 2022 Mikhail Zhilkin
8 """
9
10 import argparse
11 import binascii
12 import os
13 import struct
14
15 KERNEL_HEADER_SIZE = 0x100
16 PADDING = 0xff
17 ROOTFS_FAKE_HEADER = "UBI#"
18
19 def auto_int(x):
20 return int(x, 0)
21
22 def create_kernel_header(args):
23 out_file = open(args.header_file, "wb")
24 header = get_kernel_header(args)
25 out_file.write(header)
26 out_file.close()
27
28 def get_kernel_header(args):
29 header = bytearray([PADDING] * KERNEL_HEADER_SIZE)
30
31 struct.pack_into('<L', header, 0xc, 0xffffff02)
32 struct.pack_into('<L', header, 0x1c, 0x0)
33 struct.pack_into('<L', header, 0x34, 0x0)
34 struct.pack_into('<L', header, 0x10, args.kernel_offset)
35 struct.pack_into('<L', header, 0x28, args.rootfs_offset)
36
37 if (args.rootfs_file):
38 if (args.rootfs_checking_size):
39 rootfs_size = args.rootfs_checking_size
40 else:
41 rootfs_size = os.path.getsize(args.rootfs_file)
42 buf = open(args.rootfs_file,'rb').read(rootfs_size)
43 crc = binascii.crc32(buf) & 0xffffffff
44 else:
45 rootfs_size = len(ROOTFS_FAKE_HEADER)
46 crc = binascii.crc32(str.encode(ROOTFS_FAKE_HEADER)) & \
47 0xffffffff
48 struct.pack_into('<L', header, 0x2c, rootfs_size)
49 struct.pack_into('<L', header, 0x30, crc)
50
51 kernel_size = os.path.getsize(args.kernel_file)
52 struct.pack_into('<L', header, 0x14, kernel_size)
53
54 kernel_end_offset = args.kernel_offset + kernel_size
55 struct.pack_into('<L', header, 0x4, kernel_end_offset)
56
57 buf = open(args.kernel_file,'rb').read()
58 crc = binascii.crc32(buf) & 0xffffffff
59 struct.pack_into('<L', header, 0x18, crc)
60
61 crc = binascii.crc32(header) & 0xffffffff
62 struct.pack_into('<L', header, 0x8, crc)
63
64 struct.pack_into('<L', header, 0x0, 0x726553)
65
66 return header
67
68 def main():
69 global args
70
71 parser = argparse.ArgumentParser(description='This script generates \
72 a kernel header for the Sercomm mt7621 devices')
73
74 parser.add_argument('--kernel-image',
75 dest='kernel_file',
76 action='store',
77 type=str,
78 help='Path to a Kernel binary image')
79
80 parser.add_argument('--kernel-offset',
81 dest='kernel_offset',
82 action='store',
83 type=auto_int,
84 help='Kernel offset')
85
86 parser.add_argument('--rootfs-offset',
87 dest='rootfs_offset',
88 action='store',
89 type=auto_int,
90 help='RootFS offset')
91
92 parser.add_argument('--output-header',
93 dest='header_file',
94 action='store',
95 type=str,
96 help='Output kernel header file')
97
98 parser.add_argument('--rootfs-image',
99 dest='rootfs_file',
100 action='store',
101 type=str,
102 help='Path to RootFS binary image (optional)')
103
104 parser.add_argument('--rootfs-checking-size',
105 dest='rootfs_checking_size',
106 action='store',
107 type=auto_int,
108 help='Bytes count for CRC calculation (optional)')
109
110 args = parser.parse_args()
111
112 if ((not args.kernel_file) or
113 (not args.kernel_offset) or
114 (not args.rootfs_offset) or
115 (not args.header_file)):
116 parser.print_help()
117 exit()
118
119 create_kernel_header(args)
120
121 main()