From 9181d69098a20583fce7d114cb05633bc0fefa5d Mon Sep 17 00:00:00 2001 From: "Brian C. Lane" Date: Wed, 9 Aug 2017 10:52:49 -0700 Subject: [PATCH] Add mk-s360-cdboot utility (#1478448) Add a utility to concatenate the kernel and initrd, and edit the kernel. This is based on: https://github.com/rhinstaller/anaconda/blob/rhel6-branch/utils/mk-s390-cdboot.c It takes into account byteorder and it wipes the cmdline area before writing the parmfile into the kernel. Related: rhbz#1478448 (cherry picked from commit 6007b35096d7429f9a3b3deccbc6a3d29c9bf13f) --- src/bin/mk-s390-cdboot | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100755 src/bin/mk-s390-cdboot diff --git a/src/bin/mk-s390-cdboot b/src/bin/mk-s390-cdboot new file mode 100755 index 00000000..38d5430a --- /dev/null +++ b/src/bin/mk-s390-cdboot @@ -0,0 +1,113 @@ +#!/usr/bin/python +# +# mk-s390-cdboot +# +# Copyright (C) 2017 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +from __future__ import print_function + +import argparse +import os +import shutil +from struct import pack +import sys + + +INITRD_START = 0x0000000000800000 +START_PSW_ADDRESS = 0x80010000 +KERNEL_PSW_ADDRESS = 0x04 +KERNEL_INITRD_START = 0x10408 +KERNEL_INITRD_SIZE = 0x10410 +KERNEL_CMDLINE = 0x10480 +# See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/s390/include/uapi/asm/setup.h +KERNEL_CMDLINE_SIZE = 896 + + +def setup_parser(): + """ Setup the cmdline parser""" + parser = argparse.ArgumentParser(description="Create s390 boot image") + parser.add_argument("-i", dest="kernel", required=True, metavar="KERNEL", + help="The kernel.img file") + parser.add_argument("-r", dest="ramdisk", required=True, metavar="RAMDISK", + help="The initrd.img file") + parser.add_argument("-p", dest="parmfile", required=True, metavar="PARMFILE", + help="The parm file") + parser.add_argument("-o", dest="outfile", required=True, metavar="OUTFILE", + help="The output image file") + return parser + + +def copy_kernel(kernel, outfile): + """ Copy the kernel to the outfile""" + shutil.copy2(kernel, outfile) + + +def append_ramdisk(ramdisk, outfile): + """ Append the ramdisk to the kernel and return its size""" + with open(ramdisk, "rb") as ram_fd: + with open(outfile, "r+b") as out_fd: + out_fd.seek(INITRD_START) + out_fd.write(ram_fd.read()) + return os.stat(ramdisk).st_size + + +def configure_kernel(outfile, parmfile, size): + """ Configure the kernel with the ramdisk start address and size.""" + with open(outfile, "r+b") as out_fd: + # Change the start PSW address + out_fd.seek(KERNEL_PSW_ADDRESS) + out_fd.write(pack(">L", START_PSW_ADDRESS)) + + # Write the initrd start and size + out_fd.seek(KERNEL_INITRD_START) + out_fd.write(pack(">Q", INITRD_START)) + out_fd.seek(KERNEL_INITRD_SIZE) + out_fd.write(pack(">Q", size)) + + # Erase the previous COMMAND_LINE, write zeros + out_fd.seek(KERNEL_CMDLINE) + out_fd.write("\0" * KERNEL_CMDLINE_SIZE) + + # Write the first line of the parmfile + cmdline = open(parmfile, "r").readline().strip() + out_fd.seek(KERNEL_CMDLINE) + out_fd.write(cmdline) + + +def main(): + parser = setup_parser() + args = parser.parse_args() + + errors = [] + for f in [args.kernel, args.ramdisk, args.parmfile]: + if not os.path.exists(f): + errors.append("ERROR: %s is missing" % f) + if errors: + map(print, errors) + sys.exit(1) + + print("Creating bootable CD-ROM image...") + print("kernel is : %s" % args.kernel) + print("ramdisk is : %s" % args.ramdisk) + print("parmfile is: %s" % args.parmfile) + print("outfile is : %s" % args.outfile) + + copy_kernel(args.kernel, args.outfile) + size = append_ramdisk(args.ramdisk, args.outfile) + configure_kernel(args.outfile, args.parmfile, size) + +if __name__ == '__main__': + main()