forked from DGNum/liminix
bootable aarch64 liminux with qemu
I may have broken the run-liminix-vm command a bit for MIPS due to necessary changes in how we pass the command line. If CI isn't green for this commit and youre trying the worked examples, I suggest reverting to the commit before this one.
This commit is contained in:
parent
9f87fd8625
commit
be22fbbb0a
5 changed files with 131 additions and 12 deletions
69
devices/qemu-aarch64/default.nix
Normal file
69
devices/qemu-aarch64/default.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# This "device" generates images that can be used with the QEMU
|
||||||
|
# emulator. The default output is a directory containing separate
|
||||||
|
# kernel ("Image" format) and root filesystem (squashfs or jffs2)
|
||||||
|
# images
|
||||||
|
{
|
||||||
|
system = {
|
||||||
|
crossSystem = {
|
||||||
|
config = "aarch64-unknown-linux-musl";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {pkgs, config, ... }: {
|
||||||
|
imports = [ ../../modules/arch/aarch64.nix ];
|
||||||
|
kernel = {
|
||||||
|
src = pkgs.pkgsBuildBuild.fetchurl {
|
||||||
|
name = "linux.tar.gz";
|
||||||
|
url = "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.15.71.tar.gz";
|
||||||
|
hash = "sha256-yhO2cXIeIgUxkSZf/4aAsF11uxyh+UUZu6D1h92vCD8=";
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
VIRTUALIZATION = "y";
|
||||||
|
PCI_HOST_GENERIC="y";
|
||||||
|
|
||||||
|
MTD = "y";
|
||||||
|
MTD_BLOCK2MTD = "y";
|
||||||
|
MTD_BLKDEVS = "y";
|
||||||
|
MTD_BLOCK = "y";
|
||||||
|
|
||||||
|
VIRTIO_MENU = "y";
|
||||||
|
PCI = "y";
|
||||||
|
VIRTIO_PCI = "y";
|
||||||
|
BLOCK = "y";
|
||||||
|
VIRTIO_BLK = "y";
|
||||||
|
NETDEVICES = "y";
|
||||||
|
VIRTIO_NET = "y";
|
||||||
|
|
||||||
|
SERIAL_EARLYCON_ARM_SEMIHOST = "y"; # earlycon=smh
|
||||||
|
SERIAL_AMBA_PL011 = "y";
|
||||||
|
SERIAL_AMBA_PL011_CONSOLE = "y";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hardware =
|
||||||
|
let
|
||||||
|
mac80211 = pkgs.mac80211.override {
|
||||||
|
drivers = ["mac80211_hwsim"];
|
||||||
|
klibBuild = config.system.outputs.kernel.modulesupport;
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
defaultOutput = "vmroot";
|
||||||
|
loadAddress = "0x0";
|
||||||
|
entryPoint = "0x0";
|
||||||
|
rootDevice = "/dev/mtdblock0";
|
||||||
|
|
||||||
|
flash.eraseBlockSize = "65536"; # c.f. pkgs/mips-vm/mips-vm.sh
|
||||||
|
networkInterfaces =
|
||||||
|
let inherit (config.system.service.network) link;
|
||||||
|
in {
|
||||||
|
wan = link.build { ifname = "eth0"; };
|
||||||
|
lan = link.build { ifname = "eth1"; };
|
||||||
|
|
||||||
|
wlan_24 = link.build {
|
||||||
|
ifname = "wlan0";
|
||||||
|
dependencies = [ mac80211 ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
|
@ -49,6 +49,7 @@
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
defaultOutput = "vmroot";
|
defaultOutput = "vmroot";
|
||||||
|
rootDevice = "/dev/mtdblock0";
|
||||||
flash.eraseBlockSize = "65536"; # c.f. pkgs/run-liminix-vm/run-liminix-vm.sh
|
flash.eraseBlockSize = "65536"; # c.f. pkgs/run-liminix-vm/run-liminix-vm.sh
|
||||||
networkInterfaces =
|
networkInterfaces =
|
||||||
let inherit (config.system.service.network) link;
|
let inherit (config.system.service.network) link;
|
||||||
|
|
16
modules/arch/aarch64.nix
Normal file
16
modules/arch/aarch64.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ lib, pkgs, config, ...}:
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
kernel.config = {
|
||||||
|
CPU_LITTLE_ENDIAN= "y";
|
||||||
|
CPU_BIG_ENDIAN= "n";
|
||||||
|
# CMDLINE_FROM_BOOTLOADER availability is conditional
|
||||||
|
# on CMDLINE being set to something non-empty
|
||||||
|
CMDLINE="\"console=ttyAMA0\"";
|
||||||
|
CMDLINE_FROM_BOOTLOADER = "y";
|
||||||
|
};
|
||||||
|
boot.commandLine = [
|
||||||
|
"console=ttyAMA0,38400"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,6 +7,12 @@
|
||||||
let
|
let
|
||||||
inherit (lib) mkOption types concatStringsSep;
|
inherit (lib) mkOption types concatStringsSep;
|
||||||
inherit (pkgs) liminix callPackage writeText;
|
inherit (pkgs) liminix callPackage writeText;
|
||||||
|
arch = let s = pkgs.stdenv; in
|
||||||
|
if s.isAarch64
|
||||||
|
then "aarch64"
|
||||||
|
else if s.isMips
|
||||||
|
then "mips"
|
||||||
|
else throw "can't determine arch";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -76,13 +82,26 @@ in
|
||||||
inherit dtb;
|
inherit dtb;
|
||||||
};
|
};
|
||||||
# could use trivial-builders.linkFarmFromDrvs here?
|
# could use trivial-builders.linkFarmFromDrvs here?
|
||||||
vmroot = pkgs.runCommand "qemu" {} ''
|
vmroot =
|
||||||
|
let
|
||||||
|
cmdline = builtins.toJSON (concatStringsSep " " config.boot.commandLine);
|
||||||
|
makeBootableImage = pkgs.runCommandCC "objcopy" {}
|
||||||
|
(if pkgs.stdenv.isAarch64
|
||||||
|
then "${pkgs.stdenv.cc.targetPrefix}objcopy -O binary -S ${kernel} $out"
|
||||||
|
else "cp ${kernel} $out");
|
||||||
|
in pkgs.runCommandCC "vmroot" {} ''
|
||||||
mkdir $out
|
mkdir $out
|
||||||
cd $out
|
cd $out
|
||||||
ln -s ${config.system.outputs.rootfs} rootfs
|
ln -s ${config.system.outputs.rootfs} rootfs
|
||||||
ln -s ${kernel} vmlinux
|
ln -s ${kernel} vmlinux
|
||||||
ln -s ${manifest} manifest
|
ln -s ${manifest} manifest
|
||||||
ln -s ${kernel.headers} build
|
ln -s ${kernel.headers} build
|
||||||
|
echo ${cmdline} > commandline
|
||||||
|
cat > run.sh << EOF
|
||||||
|
#!${pkgs.runtimeShell}
|
||||||
|
CMDLINE=${cmdline} run-liminix-vm --arch ${arch} ${makeBootableImage} ${config.system.outputs.rootfs}
|
||||||
|
EOF
|
||||||
|
chmod +x run.sh
|
||||||
'';
|
'';
|
||||||
|
|
||||||
manifest = writeText "manifest.json" (builtins.toJSON config.filesystem.contents);
|
manifest = writeText "manifest.json" (builtins.toJSON config.filesystem.contents);
|
||||||
|
|
|
@ -12,6 +12,12 @@ usage(){
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arch="mips"
|
||||||
|
if test "$1" = "--arch" ; then
|
||||||
|
arch=$2
|
||||||
|
shift;shift
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$1" = "--background" ; then
|
if test "$1" = "--background" ; then
|
||||||
statedir=$2
|
statedir=$2
|
||||||
if test -z "$statedir" || ! test -d $statedir ; then
|
if test -z "$statedir" || ! test -d $statedir ; then
|
||||||
|
@ -39,13 +45,21 @@ if test -n "$3"; then
|
||||||
initramfs="-initrd $3"
|
initramfs="-initrd $3"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
case "$arch" in
|
||||||
|
mips)
|
||||||
|
QEMU="qemu-system-mips -M malta"
|
||||||
|
;;
|
||||||
|
aarch64)
|
||||||
|
QEMU="qemu-system-aarch64 -M virt -semihosting -cpu cortex-a72"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
INIT=${INIT-/bin/init}
|
INIT=${INIT-/bin/init}
|
||||||
echo $QEMU_OPTIONS
|
set -x
|
||||||
qemu-system-mips \
|
$QEMU \
|
||||||
-M malta -m 256 \
|
-m 256 \
|
||||||
-echr 16 \
|
-echr 16 \
|
||||||
-append "liminix default console=ttyS0,38400n8 panic=10 oops=panic init=$INIT loglevel=8 root=/dev/mtdblock0 block2mtd.block2mtd=/dev/vda,65536" \
|
-append "$CMDLINE liminix root=/dev/mtdblock0 block2mtd.block2mtd=/dev/vda,65536" \
|
||||||
-drive file=$rootfs,format=raw,readonly=off,if=virtio,index=0 \
|
-drive file=$rootfs,format=raw,readonly=off,if=virtio,index=0 \
|
||||||
${initramfs} \
|
${initramfs} \
|
||||||
-netdev socket,id=access,mcast=230.0.0.1:1234,localaddr=127.0.0.1 \
|
-netdev socket,id=access,mcast=230.0.0.1:1234,localaddr=127.0.0.1 \
|
||||||
|
|
Loading…
Reference in a new issue