| # -*- mode: python -*- |
| # virtme-configkernel: Configure a kernel for virtme |
| # Copyright © 2014 Andy Lutomirski |
| # Licensed under the GPLv2, which is available in the virtme distribution |
| # as a file called LICENSE with SHA-256 hash: |
| # 8177f97513213526df2cf6184d8ff986c675afb514d4e68a404010521b880643 |
| |
| from typing import Optional |
| |
| import argparse |
| import os |
| import shlex |
| import shutil |
| import subprocess |
| import multiprocessing |
| from .. import architectures |
| |
| uname = os.uname() |
| |
| def make_parser(): |
| parser = argparse.ArgumentParser( |
| description='Configure a kernel for virtme', |
| ) |
| |
| parser.add_argument('--arch', action='store', metavar='ARCHITECTURE', |
| default=uname.machine, |
| help='Target architecture') |
| |
| g = parser.add_argument_group(title='Mode').add_mutually_exclusive_group() |
| |
| g.add_argument('--allnoconfig', action='store_true', |
| help='Overwrite configuration with a virtme-suitable allnoconfig (unlikely to work)') |
| |
| g.add_argument('--defconfig', action='store_true', |
| help='Overwrite configuration with a virtme-suitable defconfig') |
| |
| g.add_argument('--update', action='store_true', |
| help='Update existing config for virtme') |
| |
| return parser |
| |
| _ARGPARSER = make_parser() |
| |
| def arg_fail(message): |
| print(message) |
| _ARGPARSER.print_usage() |
| exit(1) |
| |
| _GENERIC_CONFIG = [ |
| '# Generic', |
| 'CONFIG_UEVENT_HELPER=n', # Obsolete and slow |
| 'CONFIG_VIRTIO=y', |
| 'CONFIG_VIRTIO_PCI=y', |
| 'CONFIG_VIRTIO_MMIO=y', |
| 'CONFIG_NET=y', |
| 'CONFIG_NET_CORE=y', |
| 'CONFIG_NETDEVICES=y', |
| 'CONFIG_NETWORK_FILESYSTEMS=y', |
| 'CONFIG_INET=y', |
| 'CONFIG_NET_9P=y', |
| 'CONFIG_NET_9P_VIRTIO=y', |
| 'CONFIG_9P_FS=y', |
| 'CONFIG_VIRTIO_NET=y', |
| 'CONFIG_CMDLINE_OVERRIDE=n', |
| 'CONFIG_BINFMT_SCRIPT=y', |
| 'CONFIG_SHMEM=y', |
| 'CONFIG_TMPFS=y', |
| 'CONFIG_UNIX=y', |
| 'CONFIG_MODULE_SIG_FORCE=n', |
| 'CONFIG_DEVTMPFS=y', |
| 'CONFIG_TTY=y', |
| 'CONFIG_VT=y', |
| 'CONFIG_UNIX98_PTYS=y', |
| 'CONFIG_EARLY_PRINTK=y', |
| '', |
| '# virtio-scsi support', |
| 'CONFIG_BLOCK=y', |
| 'CONFIG_SCSI_LOWLEVEL=y', |
| 'CONFIG_SCSI=y', |
| 'CONFIG_SCSI_VIRTIO=y', |
| 'CONFIG_BLK_DEV_SD=y', |
| '', |
| '# virt-serial support', |
| 'CONFIG_VIRTIO_CONSOLE=y', |
| '', |
| '# watchdog (useful for test scripts)', |
| 'CONFIG_WATCHDOG=y', |
| 'CONFIG_WATCHDOG_CORE=y', |
| 'CONFIG_I6300ESB_WDT=y', |
| ] |
| |
| def main(): |
| args = _ARGPARSER.parse_args() |
| |
| if not os.path.isfile('scripts/kconfig/merge_config.sh') and \ |
| not os.path.isfile('source/scripts/kconfig/merge_config.sh'): |
| print('virtme-configkernel must be run in a kernel source/build directory') |
| return 1 |
| |
| arch = architectures.get(args.arch) |
| |
| conf = (_GENERIC_CONFIG + |
| ['# Arch-specific options'] + |
| arch.config_base()) |
| |
| archargs = ['ARCH=%s' % shlex.quote(arch.linuxname)] |
| |
| if shutil.which('%s-linux-gnu-gcc' % arch.gccname): |
| archargs.append('CROSS_COMPILE=%s' % shlex.quote("%s-linux-gnu-" % arch.gccname)) |
| |
| maketarget: Optional[str] |
| |
| if args.allnoconfig: |
| maketarget = 'allnoconfig' |
| updatetarget = 'silentoldconfig' |
| elif args.defconfig: |
| maketarget = arch.defconfig_target |
| updatetarget = 'olddefconfig' |
| elif args.update: |
| maketarget = None |
| updatetarget = 'olddefconfig' |
| else: |
| arg_fail('No mode selected') |
| |
| # TODO: Get rid of most of the noise and check the result. |
| |
| # Set up an initial config |
| if maketarget: |
| subprocess.check_call(['make'] + archargs + [maketarget]) |
| |
| config = '.config' |
| |
| # Check if KBUILD_OUTPUT is defined and if it's a directory |
| config_dir = os.environ.get('KBUILD_OUTPUT', '') |
| if config_dir and os.path.isdir(config_dir): |
| config = os.path.join(config_dir, config) |
| |
| with open(config, 'ab') as conffile: |
| conffile.write('\n'.join(conf).encode('utf-8')) |
| |
| subprocess.check_call(['make'] + archargs + [updatetarget]) |
| |
| print("Configured. Build with 'make %s -j%d'" % |
| (' '.join(archargs), multiprocessing.cpu_count())) |
| |
| return 0 |
| |
| if __name__ == '__main__': |
| exit(main()) |