[openwrt/openwrt] scripts: add support for Sercomm kernel header

LEDE Commits lede-commits at lists.infradead.org
Sun Jul 3 12:05:59 PDT 2022


hauke pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/87092b3c065978fc0e673856c34b3db0829280db

commit 87092b3c065978fc0e673856c34b3db0829280db
Author: Mikhail Zhilkin <csharper2005 at gmail.com>
AuthorDate: Fri Mar 18 17:02:30 2022 +0000

    scripts: add support for Sercomm kernel header
    
    This scripts creates custom kernel header that necessary for Sercomm
    mt7621 devices:
    - Sercomm S3
    - Beeline SmartBox Giga
    - Beeline SmartBox Pro
    - Beeline Smartbox Turbo
    - Beeline Smartbox Turbo+
    - WiFire S1500.NBN
    
    Header format
    -------------
    +--------+---------------+------------------------+
    | Offset | Value         | Description            |
    +========+===============+========================+
    | 0x0    | 53 65 72 00   | Magic "Ser."           |
    +--------+---------------+------------------------+
    | 0x4    | 04 00 00 01   | End offset of RootFS   |
    +--------+---------------+------------------------+
    |        |               | This header checksum   |
    | 0x8    | d6 14 9a c1   | htonl(~crc)            |
    +--------+---------------+------------------------+
    | 0xc    | 02 ff ff ff   | Constant               |
    +--------+---------------+------------------------+
    | 0x10   | 00 01 40 00   | Kernel start offset    |
    +--------+---------------+------------------------+
    | 0x14   | c6 94 24 00   | Kernel length          |
    +--------+---------------+------------------------+
    |        |               | Kernel checksum        |
    | 0x18   | e7 78 89 f1   | htonl(~crc)            |
    +--------+---------------+------------------------+
    | 0x1c   | 00 00 00 00   | Constant               |
    +--------+---------------+------------------------+
    | 0x20   | ff ff ff ff   | Constant               |
    +--------+---------------+------------------------+
    | 0x24   | ff ff ff ff   | Constant               |
    +--------+---------------+------------------------+
    | 0x28   | 00 00 00 01   | RootFS offset          |
    +--------+---------------+------------------------+
    |        |               | RootFS length          |
    | 0x2c   | 04 00 00 00   | Always 0x4, we check   |
    |        |               | UBI magic only         |
    +--------+---------------+------------------------+
    |        |               | RootFS checksum        |
    | 0x30   | 1c fc 55 2d   | htonl(~crc)            |
    |        |               | Const for UBI magic    |
    +--------+---------------+------------------------+
    | 0x34   | 00 00 00 00   | Constant               |
    +--------+---------------+------------------------+
    | 0x38   | ff ff ff ff … | Pad to 0x100           |
    +--------+---------------+------------------------+
    
    Signed-off-by: Mikhail Zhilkin <csharper2005 at gmail.com>
---
 scripts/sercomm-kernel-header.py | 121 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/scripts/sercomm-kernel-header.py b/scripts/sercomm-kernel-header.py
new file mode 100755
index 0000000000..bfb29c6fe0
--- /dev/null
+++ b/scripts/sercomm-kernel-header.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+"""
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# sercomm-kernel-header.py: Creates Sercomm kernel header
+#
+# Copyright © 2022 Mikhail Zhilkin
+"""
+
+import argparse
+import binascii
+import os
+import struct
+
+KERNEL_HEADER_SIZE = 0x100
+PADDING = 0xff
+ROOTFS_FAKE_HEADER = "UBI#"
+
+def auto_int(x):
+	return int(x, 0)
+
+def create_kernel_header(args):
+	out_file = open(args.header_file, "wb")
+	header = get_kernel_header(args)
+	out_file.write(header)
+	out_file.close()
+
+def get_kernel_header(args):
+	header = bytearray([PADDING] * KERNEL_HEADER_SIZE)
+
+	struct.pack_into('<L', header, 0xc, 0xffffff02)
+	struct.pack_into('<L', header, 0x1c, 0x0)
+	struct.pack_into('<L', header, 0x34, 0x0)
+	struct.pack_into('<L', header, 0x10, args.kernel_offset)
+	struct.pack_into('<L', header, 0x28, args.rootfs_offset)
+
+	if (args.rootfs_file):
+		if (args.rootfs_checking_size):
+			rootfs_size = args.rootfs_checking_size
+		else:
+			rootfs_size = os.path.getsize(args.rootfs_file)
+		buf = open(args.rootfs_file,'rb').read(rootfs_size)
+		crc = binascii.crc32(buf) & 0xffffffff
+	else:
+		rootfs_size = len(ROOTFS_FAKE_HEADER)
+		crc = binascii.crc32(str.encode(ROOTFS_FAKE_HEADER)) & \
+		      0xffffffff
+	struct.pack_into('<L', header, 0x2c, rootfs_size)
+	struct.pack_into('<L', header, 0x30, crc)
+
+	rootfs_end_offset = args.rootfs_offset + rootfs_size
+	struct.pack_into('<L', header, 0x4, rootfs_end_offset)
+
+	kernel_size = os.path.getsize(args.kernel_file)
+	struct.pack_into('<L', header, 0x14, kernel_size)
+
+	buf = open(args.kernel_file,'rb').read()
+	crc = binascii.crc32(buf) & 0xffffffff
+	struct.pack_into('<L', header, 0x18, crc)
+
+	crc = binascii.crc32(header) & 0xffffffff
+	struct.pack_into('<L', header, 0x8, crc)
+
+	struct.pack_into('<L', header, 0x0, 0x726553)
+
+	return header
+
+def main():
+	global args
+
+	parser = argparse.ArgumentParser(description='This script generates \
+		a kernel header for the Sercomm mt7621 devices')
+
+	parser.add_argument('--kernel-image',
+		dest='kernel_file',
+		action='store',
+		type=str,
+		help='Path to a Kernel binary image')
+
+	parser.add_argument('--kernel-offset',
+		dest='kernel_offset',
+		action='store',
+		type=auto_int,
+		help='Kernel offset')
+
+	parser.add_argument('--rootfs-offset',
+		dest='rootfs_offset',
+		action='store',
+		type=auto_int,
+		help='RootFS offset')
+
+	parser.add_argument('--output-header',
+		dest='header_file',
+		action='store',
+		type=str,
+		help='Output kernel header file')
+
+	parser.add_argument('--rootfs-image',
+		dest='rootfs_file',
+		action='store',
+		type=str,
+		help='Path to RootFS binary image (optional)')
+
+	parser.add_argument('--rootfs-checking-size',
+		dest='rootfs_checking_size',
+		action='store',
+		type=auto_int,
+		help='Bytes count for CRC calculation (optional)')
+
+	args = parser.parse_args()
+
+	if ((not args.kernel_file) or
+	    (not args.kernel_offset) or
+	    (not args.rootfs_offset) or
+	    (not args.header_file)):
+		parser.print_help()
+		exit()
+
+	create_kernel_header(args)
+
+main()




More information about the lede-commits mailing list