mirror of
https://github.com/ilyakooo0/nixpkgs.git
synced 2024-09-20 20:20:26 +03:00
Update QEMU Nixos Virtual Machine
The Nixos Qemu VM that are used for VM tests can now start without boot menu even when using a bootloader. The Nixos Qemu VM with bootloader can emulate a EFI boot now.
This commit is contained in:
parent
b9cc04329b
commit
80afabd5b5
@ -36,13 +36,28 @@ let
|
|||||||
${toString config.virtualisation.diskSize}M || exit 1
|
${toString config.virtualisation.diskSize}M || exit 1
|
||||||
fi
|
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
|
if [ -z "$TMPDIR" -o -z "$USE_TMPDIR" ]; then
|
||||||
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
|
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
|
||||||
fi
|
fi
|
||||||
cd $TMPDIR
|
# Create a directory for exchanging data with the VM.
|
||||||
mkdir -p $TMPDIR/xchg
|
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
|
idx=2
|
||||||
extraDisks=""
|
extraDisks=""
|
||||||
${flip concatMapStrings cfg.emptyDiskImages (size: ''
|
${flip concatMapStrings cfg.emptyDiskImages (size: ''
|
||||||
@ -52,7 +67,6 @@ let
|
|||||||
'')}
|
'')}
|
||||||
|
|
||||||
# Start QEMU.
|
# 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 \
|
exec ${pkgs.qemu_kvm}/bin/qemu-kvm \
|
||||||
-name ${vmName} \
|
-name ${vmName} \
|
||||||
-m ${toString config.virtualisation.memorySize} \
|
-m ${toString config.virtualisation.memorySize} \
|
||||||
@ -63,8 +77,11 @@ let
|
|||||||
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
|
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
|
||||||
${if cfg.useBootLoader then ''
|
${if cfg.useBootLoader then ''
|
||||||
-drive index=0,id=drive1,file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
-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 \
|
-drive index=1,id=drive2,file=$TMPDIR/disk.img,media=disk \
|
||||||
-boot menu=on \
|
${if cfg.useEFIBoot then ''
|
||||||
|
-pflash $TMPDIR/bios.bin \
|
||||||
|
'' else ''
|
||||||
|
''}
|
||||||
'' else ''
|
'' else ''
|
||||||
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
-drive file=$NIX_DISK_IMAGE,if=virtio,cache=writeback,werror=report \
|
||||||
-kernel ${config.system.build.toplevel}/kernel \
|
-kernel ${config.system.build.toplevel}/kernel \
|
||||||
@ -74,7 +91,8 @@ let
|
|||||||
$extraDisks \
|
$extraDisks \
|
||||||
${qemuGraphics} \
|
${qemuGraphics} \
|
||||||
${toString config.virtualisation.qemu.options} \
|
${toString config.virtualisation.qemu.options} \
|
||||||
$QEMU_OPTS
|
$QEMU_OPTS \
|
||||||
|
$@
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
||||||
@ -98,23 +116,44 @@ let
|
|||||||
''
|
''
|
||||||
mkdir $out
|
mkdir $out
|
||||||
diskImage=$out/disk.img
|
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 ];
|
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.
|
# Create a /boot EFI partition with 40M
|
||||||
${pkgs.parted}/sbin/parted /dev/vda mklabel msdos
|
${pkgs.gptfdisk}/sbin/sgdisk -G /dev/vda
|
||||||
${pkgs.parted}/sbin/parted /dev/vda -- mkpart primary ext2 1M -1s
|
${pkgs.gptfdisk}/sbin/sgdisk -a 1 -n 1:34:2047 -c 1:"BIOS Boot Partition" -t 1:ef02 /dev/vda
|
||||||
. /sys/class/block/vda1/uevent
|
${pkgs.gptfdisk}/sbin/sgdisk -a 512 -N 2 -c 2:"EFI System" -t 2:ef00 /dev/vda
|
||||||
mknod /dev/vda1 b $MAJOR $MINOR
|
${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
|
. /sys/class/block/vda/uevent
|
||||||
${pkgs.e2fsprogs}/sbin/mkfs.ext4 -L boot /dev/vda1
|
${pkgs.dosfstools}/bin/mkfs.fat -F16 /dev/vda2
|
||||||
${pkgs.e2fsprogs}/sbin/tune2fs -c 0 -i 0 /dev/vda1
|
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
|
mkdir /boot
|
||||||
mount /dev/vda1 /boot
|
mount /dev/vda2 /boot
|
||||||
|
|
||||||
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
|
# This is needed for GRUB 0.97, which doesn't know about virtio devices.
|
||||||
mkdir /boot/grub
|
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 = {
|
config = {
|
||||||
@ -379,8 +429,8 @@ in
|
|||||||
};
|
};
|
||||||
} // optionalAttrs cfg.useBootLoader
|
} // optionalAttrs cfg.useBootLoader
|
||||||
{ "/boot" =
|
{ "/boot" =
|
||||||
{ device = "/dev/disk/by-label/boot";
|
{ device = "/dev/vdb2";
|
||||||
fsType = "ext4";
|
fsType = "vfat";
|
||||||
options = "ro";
|
options = "ro";
|
||||||
noCheck = true; # fsck fails on a r/o filesystem
|
noCheck = true; # fsck fails on a r/o filesystem
|
||||||
};
|
};
|
||||||
@ -413,6 +463,7 @@ in
|
|||||||
|
|
||||||
# Wireless won't work in the VM.
|
# Wireless won't work in the VM.
|
||||||
networking.wireless.enable = mkVMOverride false;
|
networking.wireless.enable = mkVMOverride false;
|
||||||
|
networking.connman.enable = mkVMOverride false;
|
||||||
|
|
||||||
# Speed up booting by not waiting for ARP.
|
# Speed up booting by not waiting for ARP.
|
||||||
networking.dhcpcd.extraConfig = "noarp";
|
networking.dhcpcd.extraConfig = "noarp";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, edk2, nasm, iasl }:
|
{ stdenv, edk2, nasm, iasl, seabios, openssl, secureBoot ? false }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
@ -14,14 +14,36 @@ in
|
|||||||
stdenv.mkDerivation (edk2.setup "OvmfPkg/OvmfPkg${targetArch}.dsc" {
|
stdenv.mkDerivation (edk2.setup "OvmfPkg/OvmfPkg${targetArch}.dsc" {
|
||||||
name = "OVMF-2014-12-10";
|
name = "OVMF-2014-12-10";
|
||||||
|
|
||||||
buildInputs = [nasm iasl];
|
# TODO: properly include openssl for secureBoot
|
||||||
|
buildInputs = [nasm iasl] ++ stdenv.lib.optionals (secureBoot == true) [ openssl ];
|
||||||
|
|
||||||
unpackPhase = ''
|
unpackPhase = ''
|
||||||
for file in \
|
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
|
do
|
||||||
ln -sv "$file" .
|
ln -sv "$file" .
|
||||||
done
|
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 = {
|
meta = {
|
||||||
description = "Sample UEFI firmware for QEMU and KVM";
|
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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -8058,7 +8058,11 @@ let
|
|||||||
|
|
||||||
oracleXE = callPackage ../servers/sql/oracle-xe { };
|
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 {
|
pgpool92 = callPackage ../servers/sql/pgpool/default.nix {
|
||||||
postgresql = postgresql92;
|
postgresql = postgresql92;
|
||||||
|
Loading…
Reference in New Issue
Block a user