Merge pull request #5995 from ts468/qemu-vm
Update QEMU Nixos Virtual Machine
This commit is contained in:
commit
6daf9aa922
@ -36,13 +36,28 @@ let
|
||||
${toString config.virtualisation.diskSize}M || exit 1
|
||||
fi
|
||||
|
||||
# Create a directory for exchanging data with the VM.
|
||||
# Create a directory for storing temporary data of the running VM.
|
||||
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then
|
||||
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
|
||||
fi
|
||||
cd $TMPDIR
|
||||
# Create a directory for exchanging data with the VM.
|
||||
mkdir -p $TMPDIR/xchg
|
||||
|
||||
${if cfg.useBootLoader then ''
|
||||
# Create a writable copy/snapshot of the boot disk
|
||||
# A writable boot disk can be booted from automatically
|
||||
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 -b ${bootDisk}/disk.img $TMPDIR/disk.img || exit 1
|
||||
|
||||
${if cfg.useEFIBoot then ''
|
||||
# VM needs a writable flash BIOS
|
||||
cp ${bootDisk}/bios.bin $TMPDIR || exit 1
|
||||
chmod 0644 $TMPDIR/bios.bin || exit 1
|
||||
'' else ''
|
||||
''}
|
||||
'' else ''
|
||||
''}
|
||||
|
||||
cd $TMPDIR
|
||||
idx=2
|
||||
extraDisks=""
|
||||
${flip concatMapStrings cfg.emptyDiskImages (size: ''
|
||||
@ -52,7 +67,6 @@ let
|
||||
'')}
|
||||
|
||||
# Start QEMU.
|
||||
# "-boot menu=on" is there, because I don't know how to make qemu boot from 2nd hd.
|
||||
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \
|
||||
-name ${vmName} \
|
||||
-m ${toString config.virtualisation.memorySize} \
|
||||
@ -63,8 +77,11 @@ let
|
||||
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
|
||||
${if cfg.useBootLoader then ''
|
||||
-drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
||||
-drive index=1,id=drive2,file=${bootDisk}/disk.img,if=virtio,readonly \
|
||||
-boot menu=on \
|
||||
-drive index=1,id=drive2,file=$TMPDIR/disk.img,media=disk \
|
||||
${if cfg.useEFIBoot then ''
|
||||
-pflash $TMPDIR/bios.bin \
|
||||
'' else ''
|
||||
''}
|
||||
'' else ''
|
||||
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
||||
-kernel ${config.system.build.toplevel}/kernel \
|
||||
@ -74,7 +91,8 @@ let
|
||||
$extraDisks \
|
||||
${qemuGraphics} \
|
||||
${toString config.virtualisation.qemu.options} \
|
||||
$QEMU_OPTS
|
||||
$QEMU_OPTS \
|
||||
$@
|
||||
'';
|
||||
|
||||
|
||||
@ -98,23 +116,44 @@ let
|
||||
''
|
||||
mkdir $out
|
||||
diskImage=$out/disk.img
|
||||
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "32M"
|
||||
bootFlash=$out/bios.bin
|
||||
${pkgs.qemu_kvm}/bin/qemu-img create -f qcow2 $diskImage "40M"
|
||||
${if cfg.useEFIBoot then ''
|
||||
cp ${pkgs.OVMF-CSM}/FV/OVMF.fd $bootFlash
|
||||
chmod 0644 $bootFlash
|
||||
'' else ''
|
||||
''}
|
||||
'';
|
||||
buildInputs = [ pkgs.utillinux ];
|
||||
QEMU_OPTS = if cfg.useEFIBoot
|
||||
then "-pflash $out/bios.bin -nographic -serial pty"
|
||||
else "-nographic -serial pty";
|
||||
}
|
||||
''
|
||||
# Create a single /boot partition.
|
||||
${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
|
||||
${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
|
||||
. /sys/class/block/vda1/uevent
|
||||
mknod /dev/vda1 b $MAJOR $MINOR
|
||||
# Create a /boot EFI partition with 40M
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -G /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -A 1:set:1 /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -A 2:set:2 /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -h 2 /dev/vda
|
||||
${pkgs.gptfdisk}/sbin/sgdisk -C /dev/vda
|
||||
${pkgs.utillinux}/bin/sfdisk /dev/vda -A 2
|
||||
. /sys/class/block/vda2/uevent
|
||||
mknod /dev/vda2 b $MAJOR $MINOR
|
||||
. /sys/class/block/vda/uevent
|
||||
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
|
||||
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
|
||||
${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
|
||||
export MTOOLS_SKIP_CHECK=1
|
||||
${pkgs.mtools}/bin/mlabel -i /dev/vda2 ::boot
|
||||
|
||||
# Mount /boot.
|
||||
# Mount /boot; load necessary modules first.
|
||||
${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_cp437.ko || true
|
||||
${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/nls/nls_iso8859-1.ko || true
|
||||
${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/fat.ko || true
|
||||
${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/fat/vfat.ko || true
|
||||
${pkgs.module_init_tools}/sbin/insmod ${pkgs.linux}/lib/modules/*/kernel/fs/efivarfs/efivarfs.ko || true
|
||||
mkdir /boot
|
||||
mount /dev/vda1 /boot
|
||||
mount /dev/vda2 /boot
|
||||
|
||||
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
|
||||
mkdir /boot/grub
|
||||
@ -287,6 +326,17 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.useEFIBoot =
|
||||
mkOption {
|
||||
default = false;
|
||||
description =
|
||||
''
|
||||
If enabled, the virtual machine will provide a EFI boot
|
||||
manager.
|
||||
useEFIBoot is ignored if useBootLoader == false.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = {
|
||||
@ -379,8 +429,8 @@ in
|
||||
};
|
||||
} // optionalAttrs cfg.useBootLoader
|
||||
{ "/boot" =
|
||||
{ device = "/dev/disk/by-label/boot";
|
||||
fsType = "ext4";
|
||||
{ device = "/dev/vdb2";
|
||||
fsType = "vfat";
|
||||
options = "ro";
|
||||
noCheck = true; # fsck fails on a r/o filesystem
|
||||
};
|
||||
@ -413,6 +463,7 @@ in
|
||||
|
||||
# Wireless won't work in the VM.
|
||||
networking.wireless.enable = mkVMOverride false;
|
||||
networking.connman.enable = mkVMOverride false;
|
||||
|
||||
# Speed up booting by not waiting for ARP.
|
||||
networking.dhcpcd.extraConfig = "noarp";
|
||||
|
@ -1,4 +1,4 @@
|
||||
{ stdenv, edk2, nasm, iasl }:
|
||||
{ stdenv, edk2, nasm, iasl, seabios, openssl, secureBoot ? false }:
|
||||
|
||||
let
|
||||
|
||||
@ -14,14 +14,36 @@ in
|
||||
stdenv.mkDerivation (edk2.setup "OvmfPkg/OvmfPkg${targetArch}.dsc" {
|
||||
name = "OVMF-2014-12-10";
|
||||
|
||||
buildInputs = [nasm iasl];
|
||||
# TODO: properly include openssl for secureBoot
|
||||
buildInputs = [nasm iasl] ++ stdenv.lib.optionals (secureBoot == true) [ openssl ];
|
||||
|
||||
unpackPhase = ''
|
||||
for file in \
|
||||
"${edk2.src}"/{OvmfPkg,UefiCpuPkg,MdeModulePkg,IntelFrameworkModulePkg,PcAtChipsetPkg,FatBinPkg,EdkShellBinPkg,MdePkg,ShellPkg,OptionRomPkg,IntelFrameworkPkg};
|
||||
"${edk2.src}"/{UefiCpuPkg,MdeModulePkg,IntelFrameworkModulePkg,PcAtChipsetPkg,FatBinPkg,EdkShellBinPkg,MdePkg,ShellPkg,OptionRomPkg,IntelFrameworkPkg};
|
||||
do
|
||||
ln -sv "$file" .
|
||||
done
|
||||
'';
|
||||
|
||||
${if (seabios == false) then ''
|
||||
ln -sv ${edk2.src}/OvmfPkg .
|
||||
'' else ''
|
||||
cp -r ${edk2.src}/OvmfPkg .
|
||||
chmod +w OvmfPkg/Csm/Csm16
|
||||
cp ${seabios}/Csm16.bin OvmfPkg/Csm/Csm16/Csm16.bin
|
||||
''}
|
||||
|
||||
${if (secureBoot == true) then ''
|
||||
ln -sv ${edk2.src}/SecurityPkg .
|
||||
ln -sv ${edk2.src}/CryptoPkg .
|
||||
'' else ''
|
||||
''}
|
||||
'';
|
||||
|
||||
buildPhase = if (seabios == false) then ''
|
||||
build ${if secureBoot then "-DSECURE_BOOT_ENABLE=TRUE" else ""}
|
||||
'' else ''
|
||||
build -D CSM_ENABLE -D FD_SIZE_2MB ${if secureBoot then "-DSECURE_BOOT_ENABLE=TRUE" else ""}
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Sample UEFI firmware for QEMU and KVM";
|
||||
|
44
pkgs/applications/virtualization/seabios/default.nix
Normal file
44
pkgs/applications/virtualization/seabios/default.nix
Normal file
@ -0,0 +1,44 @@
|
||||
{ stdenv, fetchurl, iasl, python }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
|
||||
name = "seabios-${version}";
|
||||
version = "1.7.5.2";
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://code.coreboot.org/p/seabios/downloads/get/${name}.tar.gz";
|
||||
sha256 = "1syd3gi5gq0gj2pjvmdis64xc3j1xf0jgy49ngymap0pdpm0cmh0";
|
||||
};
|
||||
|
||||
buildInputs = [ iasl python ];
|
||||
|
||||
configurePhase = ''
|
||||
# build SeaBIOS for CSM
|
||||
cat > .config << EOF
|
||||
CONFIG_CSM=y
|
||||
CONFIG_QEMU_HARDWARE=y
|
||||
CONFIG_PERMIT_UNALIGNED_PCIROM=y
|
||||
EOF
|
||||
|
||||
make olddefconfig
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp out/Csm16.bin $out/Csm16.bin
|
||||
'';
|
||||
|
||||
meta = with stdenv.lib; {
|
||||
description = "Open source implementation of a 16bit X86 BIOS";
|
||||
longDescription = ''
|
||||
SeaBIOS is an open source implementation of a 16bit X86 BIOS.
|
||||
It can run in an emulator or it can run natively on X86 hardware with the use of coreboot.
|
||||
SeaBIOS is the default BIOS for QEMU and KVM.
|
||||
'';
|
||||
homepage = http://www.seabios.org;
|
||||
license = licenses.lgpl3;
|
||||
maintainers = [ maintainers.tstrobel ];
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
}
|
||||
|
@ -8133,7 +8133,11 @@ let
|
||||
|
||||
oracleXE = callPackage ../servers/sql/oracle-xe { };
|
||||
|
||||
OVMF = callPackage ../applications/virtualization/OVMF { };
|
||||
OVMF = callPackage ../applications/virtualization/OVMF { seabios=false; openssl=null; };
|
||||
OVMF-CSM = callPackage ../applications/virtualization/OVMF { openssl=null; };
|
||||
#WIP: OVMF-secureBoot = callPackage ../applications/virtualization/OVMF { seabios=false; secureBoot=true; };
|
||||
|
||||
seabios = callPackage ../applications/virtualization/seabios { };
|
||||
|
||||
pgpool92 = callPackage ../servers/sql/pgpool/default.nix {
|
||||
postgresql = postgresql92;
|
||||
|
Loading…
Reference in New Issue
Block a user