pmb.qemu: use current device instead of requiring --arch (!1886)
When using pmbootstrap, you usually select the device you want to work on using 'pmbootstrap init', generate the rootfs and can then run more commands in the context of the device. The same needs to be done before using QEMU (to generate the rootfs). But for some reason 'pmbootstrap qemu' requires setting the --arch parameter when running QEMU for a foreign architecture, even when the device is still selected in pmbootstrap. Even more confusing is that setting "--arch arm" always selects device-qemu-vexpress, but this is not immediately clear from the name. Let's make this a lot more intuitive by making sure there is a QEMU device selected when running 'pmbootstrap qemu'. We can then use the device information to infer the architecture automatically.
This commit is contained in:
parent
32dca18eb6
commit
f536fd9cb9
|
@ -113,42 +113,3 @@ def cpu_emulation_required(args, arch):
|
||||||
|
|
||||||
# No match: then it's required
|
# No match: then it's required
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def uname_to_qemu(arch):
|
|
||||||
"""
|
|
||||||
Convert the most common architectures returned by 'uname' to those
|
|
||||||
used by the QEMU binary
|
|
||||||
"""
|
|
||||||
mapping = {
|
|
||||||
"aarch64": "aarch64",
|
|
||||||
"arm": "arm",
|
|
||||||
"armeb": "arm",
|
|
||||||
"armel": "arm",
|
|
||||||
"armhf": "arm",
|
|
||||||
"armv7l": "arm",
|
|
||||||
"x86_64": "x86_64",
|
|
||||||
"amd64": "x86_64",
|
|
||||||
}
|
|
||||||
if arch in mapping:
|
|
||||||
return mapping[arch]
|
|
||||||
|
|
||||||
raise ValueError("Can not map host architecture '" + arch + "'"
|
|
||||||
" to the right QEMU value")
|
|
||||||
|
|
||||||
|
|
||||||
def qemu_to_pmos_device(arch):
|
|
||||||
"""
|
|
||||||
Convert the architecture used in the QEMU binary to the aport name in
|
|
||||||
postmarketOS defining the device
|
|
||||||
"""
|
|
||||||
mapping = {
|
|
||||||
"arm": "qemu-vexpress",
|
|
||||||
"aarch64": "qemu-aarch64",
|
|
||||||
"x86_64": "qemu-amd64",
|
|
||||||
}
|
|
||||||
if arch in mapping:
|
|
||||||
return mapping[arch]
|
|
||||||
|
|
||||||
raise ValueError("Can not map QEMU value '" + arch + "'"
|
|
||||||
" to the right postmarketOS device")
|
|
||||||
|
|
|
@ -114,11 +114,8 @@ def arguments_initfs(subparser):
|
||||||
|
|
||||||
def arguments_qemu(subparser):
|
def arguments_qemu(subparser):
|
||||||
ret = subparser.add_parser("qemu")
|
ret = subparser.add_parser("qemu")
|
||||||
ret.add_argument("--arch", choices=["aarch64", "arm", "x86_64"],
|
|
||||||
help="emulate a different architecture")
|
|
||||||
ret.add_argument("--cmdline", help="override kernel commandline")
|
ret.add_argument("--cmdline", help="override kernel commandline")
|
||||||
ret.add_argument(
|
ret.add_argument("--image-size", help="set rootfs size (e.g. 2048M or 2G)")
|
||||||
"--image-size", help="set rootfs size (e.g. 2048M or 2G)")
|
|
||||||
ret.add_argument("-m", "--memory", type=int, default=1024,
|
ret.add_argument("-m", "--memory", type=int, default=1024,
|
||||||
help="guest RAM (default: 1024)")
|
help="guest RAM (default: 1024)")
|
||||||
ret.add_argument("-p", "--port", type=int, default=2222,
|
ret.add_argument("-p", "--port", type=int, default=2222,
|
||||||
|
|
|
@ -13,26 +13,20 @@ import pmb.chroot.apk
|
||||||
import pmb.chroot.other
|
import pmb.chroot.other
|
||||||
import pmb.chroot.initfs
|
import pmb.chroot.initfs
|
||||||
import pmb.config
|
import pmb.config
|
||||||
import pmb.helpers.devices
|
|
||||||
import pmb.helpers.run
|
import pmb.helpers.run
|
||||||
import pmb.parse.arch
|
import pmb.parse.arch
|
||||||
|
|
||||||
|
|
||||||
def system_image(args, device):
|
def system_image(args):
|
||||||
"""
|
"""
|
||||||
Returns path to rootfs for specified device. In case that it doesn't
|
Returns path to rootfs for specified device. In case that it doesn't
|
||||||
exist, raise and exception explaining how to generate it.
|
exist, raise and exception explaining how to generate it.
|
||||||
"""
|
"""
|
||||||
path = args.work + "/chroot_native/home/pmos/rootfs/" + device + ".img"
|
path = args.work + "/chroot_native/home/pmos/rootfs/" + args.device + ".img"
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
logging.debug("Could not find rootfs: " + path)
|
logging.debug("Could not find rootfs: " + path)
|
||||||
img_command = "pmbootstrap install"
|
raise RuntimeError("The rootfs has not been generated yet, please "
|
||||||
if device != args.device:
|
"run 'pmbootstrap install' first.")
|
||||||
img_command = ("pmbootstrap config device " + device +
|
|
||||||
"' and '" + img_command)
|
|
||||||
message = "The rootfs '{0}' has not been generated yet, please" \
|
|
||||||
" run '{1}' first.".format(device, img_command)
|
|
||||||
raise RuntimeError(message)
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,12 +66,11 @@ def create_gdk_loader_cache(args):
|
||||||
return rootfs_native + custom_cache_path
|
return rootfs_native + custom_cache_path
|
||||||
|
|
||||||
|
|
||||||
def command_qemu(args, arch, device, img_path):
|
def command_qemu(args, arch, img_path):
|
||||||
"""
|
"""
|
||||||
Generate the full qemu command with arguments to run postmarketOS
|
Generate the full qemu command with arguments to run postmarketOS
|
||||||
"""
|
"""
|
||||||
deviceinfo = pmb.parse.deviceinfo(args, device=device)
|
cmdline = args.deviceinfo["kernel_cmdline"]
|
||||||
cmdline = deviceinfo["kernel_cmdline"]
|
|
||||||
if args.cmdline:
|
if args.cmdline:
|
||||||
cmdline = args.cmdline
|
cmdline = args.cmdline
|
||||||
logging.debug("Kernel cmdline: " + cmdline)
|
logging.debug("Kernel cmdline: " + cmdline)
|
||||||
|
@ -85,7 +78,7 @@ def command_qemu(args, arch, device, img_path):
|
||||||
port_ssh = str(args.port)
|
port_ssh = str(args.port)
|
||||||
port_telnet = str(args.port + 1)
|
port_telnet = str(args.port + 1)
|
||||||
|
|
||||||
suffix = "rootfs_" + device
|
suffix = "rootfs_" + args.device
|
||||||
rootfs = args.work + "/chroot_" + suffix
|
rootfs = args.work + "/chroot_" + suffix
|
||||||
if args.flavor:
|
if args.flavor:
|
||||||
flavor = args.flavor
|
flavor = args.flavor
|
||||||
|
@ -129,8 +122,8 @@ def command_qemu(args, arch, device, img_path):
|
||||||
]
|
]
|
||||||
command += ["-show-cursor"]
|
command += ["-show-cursor"]
|
||||||
|
|
||||||
if deviceinfo["dtb"] != "":
|
if args.deviceinfo["dtb"] != "":
|
||||||
dtb_image = rootfs + "/usr/share/dtb/" + deviceinfo["dtb"] + ".dtb"
|
dtb_image = rootfs + "/usr/share/dtb/" + args.deviceinfo["dtb"] + ".dtb"
|
||||||
if not os.path.exists(dtb_image):
|
if not os.path.exists(dtb_image):
|
||||||
raise RuntimeError("DTB file not found: " + dtb_image)
|
raise RuntimeError("DTB file not found: " + dtb_image)
|
||||||
command += ["-dtb", dtb_image]
|
command += ["-dtb", dtb_image]
|
||||||
|
@ -167,11 +160,7 @@ def command_qemu(args, arch, device, img_path):
|
||||||
command += ["-smp", str(smp)]
|
command += ["-smp", str(smp)]
|
||||||
|
|
||||||
# Kernel Virtual Machine (KVM) support
|
# Kernel Virtual Machine (KVM) support
|
||||||
native = True
|
native = args.arch_native == args.deviceinfo["arch"]
|
||||||
if args.arch:
|
|
||||||
arch1 = pmb.parse.arch.uname_to_qemu(args.arch_native)
|
|
||||||
arch2 = pmb.parse.arch.uname_to_qemu(args.arch)
|
|
||||||
native = (arch1 == arch2)
|
|
||||||
if native and os.path.exists("/dev/kvm"):
|
if native and os.path.exists("/dev/kvm"):
|
||||||
command += ["-enable-kvm"]
|
command += ["-enable-kvm"]
|
||||||
else:
|
else:
|
||||||
|
@ -247,17 +236,18 @@ def run(args):
|
||||||
"""
|
"""
|
||||||
Run a postmarketOS image in qemu
|
Run a postmarketOS image in qemu
|
||||||
"""
|
"""
|
||||||
# Get arch, device, img_path
|
if not args.device.startswith("qemu-"):
|
||||||
arch = pmb.parse.arch.uname_to_qemu(args.arch_native)
|
raise RuntimeError("'pmbootstrap qemu' can be only used with one of "
|
||||||
if args.arch:
|
"the QEMU device packages. Run 'pmbootstrap init' "
|
||||||
arch = pmb.parse.arch.uname_to_qemu(args.arch)
|
"and select the 'qemu' vendor.")
|
||||||
device = pmb.parse.arch.qemu_to_pmos_device(arch)
|
arch = pmb.parse.arch.alpine_to_qemu(args.deviceinfo["arch"])
|
||||||
img_path = system_image(args, device)
|
|
||||||
|
img_path = system_image(args)
|
||||||
if not args.host_qemu:
|
if not args.host_qemu:
|
||||||
install_depends(args, arch)
|
install_depends(args, arch)
|
||||||
logging.info("Running postmarketOS in QEMU VM (" + arch + ")")
|
logging.info("Running postmarketOS in QEMU VM (" + arch + ")")
|
||||||
|
|
||||||
qemu, env = command_qemu(args, arch, device, img_path)
|
qemu, env = command_qemu(args, arch, img_path)
|
||||||
|
|
||||||
# Workaround: QEMU runs as local user and needs write permissions in the
|
# Workaround: QEMU runs as local user and needs write permissions in the
|
||||||
# rootfs, which is owned by root
|
# rootfs, which is owned by root
|
||||||
|
|
Loading…
Reference in New Issue