This patch has been generated by applying flynt to the gem5 repo (ext has been excluded) JIRA: https://gem5.atlassian.net/browse/GEM5-831 Change-Id: I0935db6223d5426b99515959bde78e374cbadb04 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68957 Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
419 lines
11 KiB
Python
Executable File
419 lines
11 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (c) 2020 ARM Limited
|
|
# All rights reserved.
|
|
#
|
|
# The license below extends only to copyright in the software and shall
|
|
# not be construed as granting a license to any other intellectual
|
|
# property including but not limited to intellectual property relating
|
|
# to a hardware implementation of the functionality of the software
|
|
# licensed hereunder. You may use the software subject to the license
|
|
# terms below provided that you ensure that this notice is replicated
|
|
# unmodified and in its entirety in all distributions of the software,
|
|
# modified or unmodified, in source code or in binary form.
|
|
#
|
|
# Copyright (c) 2017-2018 Metempsy Technology Consulting
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met: redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer;
|
|
# redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution;
|
|
# neither the name of the copyright holders nor the names of its
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
|
from subprocess import call
|
|
from platform import machine
|
|
from distutils import spawn
|
|
from glob import glob
|
|
|
|
import sys
|
|
import os
|
|
|
|
|
|
def run_cmd(explanation, working_dir, cmd, stdout=None):
|
|
print(f"Running phase '{explanation}'")
|
|
sys.stdout.flush()
|
|
|
|
# some of the commands need $PWD to be properly set
|
|
env = os.environ.copy()
|
|
env["PWD"] = working_dir
|
|
|
|
return_code = call(cmd, cwd=working_dir, stdout=stdout, env=env)
|
|
|
|
if return_code == 0:
|
|
return
|
|
|
|
print(
|
|
"Error running phase %s. Returncode: %d" % (explanation, return_code)
|
|
)
|
|
sys.exit(1)
|
|
|
|
|
|
def linux_clone():
|
|
kernel_vexpress_gem5_dir = os.path.join(
|
|
args.dest_dir, "linux-kernel-vexpress_gem5"
|
|
)
|
|
|
|
run_cmd(
|
|
"clone linux kernel for VExpress_GEM5_V1 platform",
|
|
args.dest_dir,
|
|
[
|
|
"git",
|
|
"clone",
|
|
"https://gem5.googlesource.com/arm/linux",
|
|
kernel_vexpress_gem5_dir,
|
|
],
|
|
)
|
|
|
|
|
|
def linux64():
|
|
kernel_vexpress_gem5_dir = os.path.join(
|
|
args.dest_dir, "linux-kernel-vexpress_gem5"
|
|
)
|
|
|
|
linux_bin = os.path.join(binaries_dir, "vmlinux.vexpress_gem5_v1_64")
|
|
|
|
with open(revisions_dir + "/linux", "w+") as rev_file:
|
|
run_cmd(
|
|
"write revision of linux-kernel-vexpress_gem5 repo",
|
|
kernel_vexpress_gem5_dir,
|
|
["git", "rev-parse", "--short", "HEAD"],
|
|
rev_file,
|
|
)
|
|
|
|
run_cmd(
|
|
"configure kernel for arm64",
|
|
kernel_vexpress_gem5_dir,
|
|
[
|
|
"make",
|
|
"ARCH=arm64",
|
|
"CROSS_COMPILE=aarch64-linux-gnu-",
|
|
"gem5_defconfig",
|
|
make_jobs_str,
|
|
],
|
|
)
|
|
run_cmd(
|
|
"compile kernel for arm64",
|
|
kernel_vexpress_gem5_dir,
|
|
[
|
|
"make",
|
|
"ARCH=arm64",
|
|
"CROSS_COMPILE=aarch64-linux-gnu-",
|
|
make_jobs_str,
|
|
],
|
|
)
|
|
run_cmd(
|
|
"copy arm64 vmlinux",
|
|
kernel_vexpress_gem5_dir,
|
|
["cp", "vmlinux", linux_bin],
|
|
)
|
|
run_cmd(
|
|
"cleanup arm64 kernel compilation",
|
|
kernel_vexpress_gem5_dir,
|
|
["make", "distclean"],
|
|
)
|
|
|
|
|
|
def linux32():
|
|
kernel_vexpress_gem5_dir = os.path.join(
|
|
args.dest_dir, "linux-kernel-vexpress_gem5"
|
|
)
|
|
|
|
linux_bin = os.path.join(binaries_dir, "vmlinux.vexpress_gem5_v1")
|
|
|
|
run_cmd(
|
|
"configure kernel for arm",
|
|
kernel_vexpress_gem5_dir,
|
|
[
|
|
"make",
|
|
"ARCH=arm",
|
|
"CROSS_COMPILE=arm-linux-gnueabihf-",
|
|
"gem5_defconfig",
|
|
],
|
|
)
|
|
run_cmd(
|
|
"compile kernel for arm",
|
|
kernel_vexpress_gem5_dir,
|
|
[
|
|
"make",
|
|
"ARCH=arm",
|
|
"CROSS_COMPILE=arm-linux-gnueabihf-",
|
|
make_jobs_str,
|
|
],
|
|
)
|
|
run_cmd(
|
|
"copy arm vmlinux",
|
|
kernel_vexpress_gem5_dir,
|
|
["cp", "vmlinux", linux_bin],
|
|
)
|
|
|
|
|
|
def linux():
|
|
"""
|
|
Checkout and build linux kernel for VExpress_GEM5_V1 (arm and arm64)
|
|
"""
|
|
linux_clone()
|
|
linux64()
|
|
linux32()
|
|
|
|
|
|
def dtbs():
|
|
"""
|
|
Build DTBs for VExpress_GEM5_V1
|
|
"""
|
|
dt_dir = gem5_dir + "/system/arm/dt"
|
|
run_cmd(
|
|
"compile DTBs for VExpress_GEM5_V1 platform",
|
|
dt_dir,
|
|
["make", make_jobs_str],
|
|
)
|
|
run_cmd(
|
|
"copy DTBs", dt_dir, ["cp"] + glob(dt_dir + "/*dtb") + [binaries_dir]
|
|
)
|
|
|
|
|
|
def bootloaders():
|
|
"""
|
|
Build bootloaders arm64/arm
|
|
"""
|
|
|
|
bootloader_arm64_dir = gem5_dir + "/system/arm/bootloader/arm64"
|
|
run_cmd("compile arm64 bootloader", bootloader_arm64_dir, ["make"])
|
|
run_cmd(
|
|
"copy arm64 bootloader",
|
|
bootloader_arm64_dir,
|
|
["cp", "boot.arm64", "boot_emm.arm64", "boot_v2.arm64", binaries_dir],
|
|
)
|
|
|
|
bootloader_arm_dir = gem5_dir + "/system/arm/bootloader/arm"
|
|
run_cmd("compile arm bootloader", bootloader_arm_dir, ["make"])
|
|
run_cmd(
|
|
"copy arm bootloaders",
|
|
bootloader_arm_dir,
|
|
["cp", "boot.arm", "boot_emm.arm", binaries_dir],
|
|
)
|
|
|
|
|
|
def m5():
|
|
"""
|
|
Build m5 binaries
|
|
"""
|
|
m5_dir = gem5_dir + "/util/m5"
|
|
run_cmd("compile arm64 m5", m5_dir, ["make", "-f", "Makefile.aarch64"])
|
|
run_cmd(
|
|
"copy arm64 m5", m5_dir, ["cp", "m5", binaries_dir + "/m5.aarch64"]
|
|
)
|
|
run_cmd(
|
|
"clean arm64 m5", m5_dir, ["make", "clean", "-f", "Makefile.aarch64"]
|
|
)
|
|
run_cmd("compile arm m5", m5_dir, ["make", "-f", "Makefile.arm"])
|
|
run_cmd("copy arm m5", m5_dir, ["cp", "m5", binaries_dir + "/m5.aarch32"])
|
|
|
|
|
|
def xen():
|
|
"""
|
|
Build Xen for aarch64
|
|
"""
|
|
xen_dir = os.path.join(args.dest_dir, "xen")
|
|
bootwrapper_dir = os.path.join(args.dest_dir, "bootwrapper")
|
|
linux_cmdline = "console=hvc0 root=/dev/vda rw mem=1G"
|
|
xen_cmdline = (
|
|
"dtuart=/uart@1c090000 console=dtuart no-bootscrub "
|
|
+ "dom0_mem=1G loglvl=all guest_loglvl=all"
|
|
)
|
|
|
|
run_cmd(
|
|
"clone Xen",
|
|
args.dest_dir,
|
|
["git", "clone", "git://xenbits.xen.org/xen.git", xen_dir],
|
|
)
|
|
|
|
run_cmd(
|
|
"clone boot-wrapper-aarch64",
|
|
args.dest_dir,
|
|
[
|
|
"git",
|
|
"clone",
|
|
"git://git.kernel.org/pub/"
|
|
+ "scm/linux/kernel/git/mark/boot-wrapper-aarch64.git",
|
|
bootwrapper_dir,
|
|
],
|
|
)
|
|
|
|
# Need to compile arm64 Linux
|
|
linux_dir = os.path.join(args.dest_dir, "linux-kernel-vexpress_gem5")
|
|
linux_bin = os.path.join(linux_dir, "arch", "arm64", "boot", "Image")
|
|
if not os.path.exists(linux_bin):
|
|
linux_clone()
|
|
linux64()
|
|
|
|
# Need to compile DTBs
|
|
dtb_bin = os.path.join(binaries_dir, "armv8_gem5_v2_1cpu.dtb")
|
|
if not os.path.exists(dtb_bin):
|
|
dtbs()
|
|
|
|
# Building Xen
|
|
run_cmd(
|
|
"building xen for aarch64",
|
|
xen_dir,
|
|
[
|
|
"make",
|
|
"dist-xen",
|
|
"XEN_TARGET_ARCH=arm64",
|
|
"CROSS_COMPILE=aarch64-linux-gnu-",
|
|
"CONFIG_EARLY_PRINTK=vexpress",
|
|
make_jobs_str,
|
|
],
|
|
)
|
|
|
|
# Building boot-wrapper-aarch64
|
|
run_cmd(
|
|
"autoreconf boot-wrapper-aarch64",
|
|
bootwrapper_dir,
|
|
["autoreconf", "-i"],
|
|
)
|
|
run_cmd(
|
|
"configure boot-wrapper-aarch64",
|
|
bootwrapper_dir,
|
|
[
|
|
"./configure",
|
|
"--host=aarch64-linux-gnu",
|
|
f"--with-kernel-dir={linux_dir}",
|
|
f"--with-dtb={dtb_bin}",
|
|
f"--with-cmdline='{linux_cmdline}'",
|
|
f"--with-xen-cmdline='{xen_cmdline}'",
|
|
f"--with-xen={os.path.join(xen_dir, 'xen', 'xen')}",
|
|
"--enable-psci",
|
|
"--enable-gicv3",
|
|
],
|
|
)
|
|
run_cmd("build boot-wrapper-aarch64", bootwrapper_dir, ["make"])
|
|
|
|
# Copying the final binary
|
|
run_cmd(
|
|
"copy xen binary",
|
|
bootwrapper_dir,
|
|
["cp", "xen-system.axf", binaries_dir],
|
|
)
|
|
|
|
with open(os.path.join(revisions_dir, "xen"), "w+") as rev_file:
|
|
run_cmd(
|
|
"write revision of xen repo",
|
|
xen_dir,
|
|
["git", "rev-parse", "--short", "HEAD"],
|
|
rev_file,
|
|
)
|
|
|
|
|
|
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
|
|
gem5_dir = os.path.dirname(script_dir)
|
|
|
|
all_binaries = {
|
|
"linux": linux,
|
|
"dtbs": dtbs,
|
|
"bootloaders": bootloaders,
|
|
"m5": m5,
|
|
"xen": xen,
|
|
}
|
|
|
|
parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter)
|
|
|
|
parser.add_argument(
|
|
"--gem5-dir",
|
|
default=gem5_dir,
|
|
metavar="GEM5_DIR",
|
|
help="gem5 root directory to be used for bootloader and "
|
|
"VExpress_GEM5_V1 DTB sources. The default value is the gem5 root "
|
|
"directory of the executed script",
|
|
)
|
|
parser.add_argument(
|
|
"--dest-dir",
|
|
default="/tmp",
|
|
metavar="DEST_DIR",
|
|
help="Directory to use for checking out the different kernel "
|
|
"repositories. Generated files will be copied to "
|
|
"DEST_DIR/binaries (which must not exist)",
|
|
)
|
|
parser.add_argument(
|
|
"-j",
|
|
"--make-jobs",
|
|
type=int,
|
|
default=1,
|
|
metavar="MAKE_JOBS",
|
|
help="Number of jobs to use with the 'make' commands.",
|
|
)
|
|
parser.add_argument(
|
|
"-b",
|
|
"--fs-binaries",
|
|
action="append",
|
|
choices=list(all_binaries.keys()),
|
|
default=[],
|
|
help="List of FS files to be generated. Defaulting to all",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if not os.path.isdir(args.dest_dir):
|
|
print(f"Error: {args.dest_dir} is not a directory.")
|
|
sys.exit(1)
|
|
|
|
if not os.path.isdir(args.gem5_dir):
|
|
print(f"Error: {args.gem5_dir} is not a directory.")
|
|
sys.exit(1)
|
|
|
|
if machine() != "x86_64":
|
|
print("Error: This script should run in a x86_64 machine")
|
|
sys.exit(1)
|
|
|
|
binaries_dir = args.dest_dir + "/binaries"
|
|
|
|
if os.path.exists(binaries_dir):
|
|
print(f"Error: {binaries_dir} already exists.")
|
|
sys.exit(1)
|
|
|
|
revisions_dir = args.dest_dir + "/revisions"
|
|
|
|
if os.path.exists(revisions_dir):
|
|
print(f"Error: {revisions_dir} already exists.")
|
|
sys.exit(1)
|
|
|
|
os.mkdir(binaries_dir)
|
|
os.mkdir(revisions_dir)
|
|
|
|
make_jobs_str = "-j" + str(args.make_jobs)
|
|
|
|
rev_file = open(revisions_dir + "/gem5", "w+")
|
|
run_cmd(
|
|
"write revision of gem5 repo",
|
|
gem5_dir,
|
|
["git", "rev-parse", "--short", "HEAD"],
|
|
rev_file,
|
|
)
|
|
rev_file.close()
|
|
|
|
binaries = args.fs_binaries if args.fs_binaries else list(all_binaries.keys())
|
|
for fs_binary in binaries:
|
|
all_binaries[fs_binary]()
|
|
|
|
print(f"Done! All the generated files can be found in {binaries_dir}")
|
|
|
|
sys.exit(0)
|