Skip to content

Commit

Permalink
scripts: add support for Sercomm kernel header
Browse files Browse the repository at this point in the history
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@gmail.com>
  • Loading branch information
csharper2005 authored and hauke committed Jul 3, 2022
1 parent 442708d commit 87092b3
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions 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()

0 comments on commit 87092b3

Please sign in to comment.