1#!/usr/bin/env python2.7 2 3# Copyright (c) 2017-2018 Metempsy Technology Consulting 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are 8# met: redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer; 10# redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution; 13# neither the name of the copyright holders nor the names of its 14# contributors may be used to endorse or promote products derived from 15# this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28# 29# Authors: Pau Cabre 30 31from optparse import OptionParser 32from subprocess import call 33from platform import machine 34from distutils import spawn 35from glob import glob 36 37import sys 38import os 39 40def run_cmd(explanation, working_dir, cmd, stdout = None): 41 print "Running phase '%s'" % explanation 42 sys.stdout.flush() 43 44 # some of the commands need $PWD to be properly set 45 env = os.environ.copy() 46 env['PWD'] = working_dir 47 48 return_code = call(cmd, cwd = working_dir, stdout = stdout, 49 env = env) 50 51 if return_code == 0: 52 return 53 54 print "Error running phase %s. Returncode: %d" % (explanation, return_code) 55 sys.exit(1) 56 57script_dir = os.path.dirname(os.path.abspath(sys.argv[0])) 58gem5_dir = os.path.dirname(script_dir) 59 60parser = OptionParser() 61 62parser.add_option("--gem5-dir", default = gem5_dir, 63 metavar = "GEM5_DIR", 64 help = "gem5 root directory to be used for bootloader and " 65 "VExpress_GEM5_V1 DTB sources. The default value is the gem5 root " 66 "directory of the executed script (%default)") 67parser.add_option("--dest-dir", default = "/tmp", 68 metavar = "DEST_DIR", 69 help = "Directory to use for checking out the different kernel " 70 "repositories. Generated files will be copied to " 71 "DEST_DIR/binaries (which must not exist). The default " 72 "value is %default") 73parser.add_option("--make-jobs", type = "int", default = 1, 74 metavar = "MAKE_JOBS", 75 help = "Number of jobs to use with the 'make' commands. Default value: " 76 "%default") 77 78(options, args) = parser.parse_args() 79 80if args: 81 print "Unrecognized argument(s) %s." % args 82 sys.exit(1) 83 84if not os.path.isdir(options.dest_dir): 85 print "Error: %s is not a directory." % options.dest_dir 86 sys.exit(1) 87 88if not os.path.isdir(options.gem5_dir): 89 print "Error: %s is not a directory." % options.gem5_dir 90 sys.exit(1) 91 92if machine() != "x86_64": 93 print "Error: This script should run in a x86_64 machine" 94 sys.exit(1) 95 96binaries_dir = options.dest_dir + "/binaries" 97 98if os.path.exists(binaries_dir): 99 print "Error: %s already exists." % binaries_dir 100 sys.exit(1) 101 102revisions_dir = options.dest_dir + "/revisions" 103 104if os.path.exists(revisions_dir): 105 print "Error: %s already exists." %revisions_dir 106 sys.exit(1) 107 108# Some basic dependency checking 109needed_programs = [ 110 "make", 111 "aarch64-linux-gnu-gcc", 112 "arm-linux-gnueabihf-gcc", 113 "aarch64-linux-gnu-gcc-4.8", 114 "arm-linux-gnueabihf-gcc-4.8", 115 "gcc", 116 "bc", 117 "dtc", 118 "arm-linux-gnueabi-gcc" 119] 120 121for program in needed_programs: 122 if not spawn.find_executable(program): 123 print "Error: command %s not found in $PATH" % program 124 print ("If running on an Debian-based linux, please try the following " 125 "cmd to get all the necessary packages: ") 126 print ("sudo apt-get install -y make gcc bc gcc-aarch64-linux-gnu " 127 "gcc-4.8-aarch64-linux-gnu gcc-4.8-arm-linux-gnueabihf " 128 "gcc-arm-linux-gnueabihf device-tree-compiler " 129 "gcc-arm-linux-gnueabi") 130 sys.exit(1) 131 132os.mkdir(binaries_dir); 133os.mkdir(revisions_dir); 134 135make_jobs_str = "-j" + str(options.make_jobs) 136 137rev_file = open(revisions_dir + "/gem5", "w+") 138run_cmd("write revision of gem5 repo", 139 gem5_dir, 140 ["git", "rev-parse", "--short", "HEAD"], 141 rev_file) 142rev_file.close() 143 144# Checkout and build linux kernel for VExpress_GEM5_V1 (arm and arm64) 145kernel_vexpress_gem5_dir = options.dest_dir + "/linux-kernel-vexpress_gem5" 146run_cmd("clone linux kernel for VExpress_GEM5_V1 platform", 147 options.dest_dir, 148 ["git", "clone", "https://gem5.googlesource.com/arm/linux", 149 kernel_vexpress_gem5_dir]) 150rev_file = open(revisions_dir + "/linux", "w+") 151run_cmd("write revision of linux-kernel-vexpress_gem5 repo", 152 kernel_vexpress_gem5_dir, 153 ["git", "rev-parse", "--short", "HEAD"], 154 rev_file) 155rev_file.close() 156run_cmd("configure kernel for arm64", 157 kernel_vexpress_gem5_dir, 158 ["make", "ARCH=arm64", "CROSS_COMPILE=aarch64-linux-gnu-", 159 "gem5_defconfig", make_jobs_str]) 160run_cmd("compile kernel for arm64", 161 kernel_vexpress_gem5_dir, 162 ["make", "ARCH=arm64", "CROSS_COMPILE=aarch64-linux-gnu-", make_jobs_str]) 163run_cmd("copy arm64 vmlinux", 164 kernel_vexpress_gem5_dir, 165 ["cp", "vmlinux", binaries_dir + "/vmlinux.vexpress_gem5_v1_64"]) 166run_cmd("cleanup arm64 kernel compilation", 167 kernel_vexpress_gem5_dir, 168 ["make", "distclean"]) 169run_cmd("configure kernel for arm", 170 kernel_vexpress_gem5_dir, 171 ["make", "ARCH=arm", "CROSS_COMPILE=arm-linux-gnueabihf-", 172 "gem5_defconfig"]) 173run_cmd("compile kernel for arm", 174 kernel_vexpress_gem5_dir, 175 ["make", "ARCH=arm", "CROSS_COMPILE=arm-linux-gnueabihf-", make_jobs_str]) 176run_cmd("copy arm vmlinux", 177 kernel_vexpress_gem5_dir, 178 ["cp", "vmlinux", binaries_dir + "/vmlinux.vexpress_gem5_v1"]) 179 180# Checkout and build linux kernel and DTB for VExpress_EMM64 181kernel_vexpress_emm64_dir = options.dest_dir + "/linux-kernel-vexpress_emm64" 182run_cmd("clone linux kernel for VExpress_EMM64 platform", 183 options.dest_dir, 184 ["git", "clone", "https://gem5.googlesource.com/arm/linux-arm64-legacy", 185 kernel_vexpress_emm64_dir]) 186rev_file = open(revisions_dir + "/linux-arm64-legacy", "w+") 187run_cmd("write revision of linux-kernel-vexpress_emm64 repo", 188 kernel_vexpress_emm64_dir, 189 ["git", "rev-parse", "--short", "HEAD"], 190 rev_file) 191rev_file.close() 192run_cmd("configure kernel", 193 kernel_vexpress_emm64_dir, 194 ["make", "ARCH=arm64", "CROSS_COMPILE=aarch64-linux-gnu-", 195 "CC=aarch64-linux-gnu-gcc-4.8", "gem5_defconfig"]) 196run_cmd("compile kernel", 197 kernel_vexpress_emm64_dir, 198 ["make", "ARCH=arm64", "CROSS_COMPILE=aarch64-linux-gnu-", 199 "CC=aarch64-linux-gnu-gcc-4.8", make_jobs_str]) 200run_cmd("copy vmlinux", 201 kernel_vexpress_emm64_dir, 202 ["cp", "vmlinux", binaries_dir + "/vmlinux.vexpress_emm64"]) 203run_cmd("copy DTB", 204 kernel_vexpress_emm64_dir, 205 ["cp", "arch/arm64/boot/dts/aarch64_gem5_server.dtb", binaries_dir]) 206 207# Checkout and build linux kernel and DTBs for VExpress_EMM 208kernel_vexpress_emm_dir = options.dest_dir + "/linux-kernel-vexpress_emm" 209run_cmd("clone linux kernel for VExpress_EMM platform", 210 options.dest_dir, 211 ["git", "clone", "https://gem5.googlesource.com/arm/linux-arm-legacy", 212 kernel_vexpress_emm_dir]) 213rev_file = open(revisions_dir + "/linux-arm-legacy", "w+") 214run_cmd("write revision of linux-kernel-vexpress_emm64 repo", 215 kernel_vexpress_emm_dir, 216 ["git", "rev-parse", "--short", "HEAD"], 217 rev_file) 218rev_file.close() 219run_cmd("configure kernel", 220 kernel_vexpress_emm_dir, 221 ["make", "ARCH=arm", "CROSS_COMPILE=arm-linux-gnueabihf-", 222 "CC=arm-linux-gnueabihf-gcc-4.8", "vexpress_gem5_server_defconfig"]) 223run_cmd("compile kernel", 224 kernel_vexpress_emm_dir, 225 ["make", "ARCH=arm", "CROSS_COMPILE=arm-linux-gnueabihf-", 226 "CC=arm-linux-gnueabihf-gcc-4.8", make_jobs_str]) 227run_cmd("copy vmlinux", 228 kernel_vexpress_emm_dir, 229 ["cp", "vmlinux", binaries_dir + "/vmlinux.vexpress_emm"]) 230run_cmd("rename DTB for 1 CPU", 231 kernel_vexpress_emm_dir, 232 ["cp", "arch/arm/boot/dts/vexpress-v2p-ca15-tc1-gem5.dtb", 233 binaries_dir + "/vexpress-v2p-ca15-tc1-gem5_1cpus.dtb"]) 234run_cmd("copy DTBs", 235 kernel_vexpress_emm_dir, 236 ["cp"] + glob(kernel_vexpress_emm_dir + "/arch/arm/boot/dts/*gem5_*dtb") + 237 [binaries_dir]) 238 239# Build DTBs for VExpress_GEM5_V1 240dt_dir = gem5_dir + "/system/arm/dt" 241run_cmd("compile DTBs for VExpress_GEM5_V1 platform", 242 dt_dir, 243 ["make", make_jobs_str]) 244run_cmd("copy DTBs", 245 dt_dir, 246 ["cp"] + glob(dt_dir + "/*dtb") + [binaries_dir]) 247 248# Build bootloaders arm64 249bootloader_arm64_dir = gem5_dir + "/system/arm/aarch64_bootloader" 250run_cmd("compile arm64 bootloader", 251 bootloader_arm64_dir, 252 ["make"]) 253run_cmd("copy arm64 bootloader", 254 bootloader_arm64_dir, 255 ["cp", "boot_emm.arm64", binaries_dir]) 256 257# Build bootloaders arm 258bootloader_arm_dir = gem5_dir + "/system/arm/simple_bootloader" 259run_cmd("compile arm bootloader", 260 bootloader_arm_dir, 261 ["make"]) 262run_cmd("copy arm bootloaders", 263 bootloader_arm_dir, 264 ["cp", "boot.arm", "boot_emm.arm", binaries_dir]) 265 266# Build m5 binaries 267m5_dir = gem5_dir + "/util/m5" 268run_cmd("compile arm64 m5", 269 m5_dir, 270 ["make", "-f", "Makefile.aarch64"]) 271run_cmd("copy arm64 m5", 272 m5_dir, 273 ["cp", "m5", binaries_dir + "/m5.aarch64"]) 274run_cmd("clean arm64 m5", 275 m5_dir, 276 ["make", "clean", "-f", "Makefile.aarch64"]) 277run_cmd("compile arm m5", 278 m5_dir, 279 ["make", "-f", "Makefile.arm"]) 280run_cmd("copy arm m5", 281 m5_dir, 282 ["cp", "m5", binaries_dir + "/m5.aarch32"]) 283 284print "Done! All the generated files can be found in %s" % binaries_dir 285 286sys.exit(0) 287 288