make-disk-image: add binfmt emulation
This commit is contained in:
172
lib/binfmt.nix
Normal file
172
lib/binfmt.nix
Normal file
@@ -0,0 +1,172 @@
|
||||
{ lib, diskoLib, pkgs, imagePkgs, ... }:
|
||||
|
||||
let
|
||||
# from https://github.com/NixOS/nixpkgs/blob/851f7fc119e9597c26cc43e10938ce7272d0af9d/nixos/modules/system/boot/binfmt.nix
|
||||
makeBinfmtLine =
|
||||
{ name
|
||||
, recognitionType
|
||||
, offset
|
||||
, magicOrExtension
|
||||
, mask
|
||||
, preserveArgvZero
|
||||
, openBinary
|
||||
, matchCredentials
|
||||
, fixBinary
|
||||
, interpreter
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
type = if recognitionType == "magic" then "M" else "E";
|
||||
offset' = toString offset;
|
||||
mask' = toString mask;
|
||||
flags = with lib;
|
||||
if !(matchCredentials -> openBinary) then
|
||||
throw "boot.binfmt.registrations.${name}: you can't specify openBinary = false when matchCredentials = true."
|
||||
else
|
||||
optionalString preserveArgvZero "P"
|
||||
+ optionalString (openBinary && !matchCredentials) "O"
|
||||
+ optionalString matchCredentials "C"
|
||||
+ optionalString fixBinary "F";
|
||||
in
|
||||
":${name}:${type}:${offset'}:${magicOrExtension}:${mask'}:${builtins.trace interpreter interpreter}:${flags}";
|
||||
magics = {
|
||||
armv6l-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
armv7l-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
aarch64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\x00\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
aarch64_be-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
i386-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
i486-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
i586-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
i686-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
x86_64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
alpha-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
sparc64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
sparc-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x12'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
powerpc-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
powerpc64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
powerpc64le-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x15\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\x00'';
|
||||
};
|
||||
mips-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'';
|
||||
};
|
||||
mipsel-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00'';
|
||||
};
|
||||
mips64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
mips64el-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
mips64-linuxabin32 = {
|
||||
magicOrExtension = ''\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20'';
|
||||
};
|
||||
mips64el-linuxabin32 = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00'';
|
||||
};
|
||||
riscv32-linux = {
|
||||
magicOrExtension = ''\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
riscv64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
loongarch64-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'';
|
||||
};
|
||||
wasm32-wasi = {
|
||||
magicOrExtension = ''\x00asm'';
|
||||
mask = ''\xff\xff\xff\xff'';
|
||||
};
|
||||
wasm64-wasi = {
|
||||
magicOrExtension = ''\x00asm'';
|
||||
mask = ''\xff\xff\xff\xff'';
|
||||
};
|
||||
s390x-linux = {
|
||||
magicOrExtension = ''\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16'';
|
||||
mask = ''\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'';
|
||||
};
|
||||
x86_64-windows.magicOrExtension = "MZ";
|
||||
i686-windows.magicOrExtension = "MZ";
|
||||
};
|
||||
in
|
||||
{
|
||||
binfmtRegistration =
|
||||
let
|
||||
system = imagePkgs.stdenv.hostPlatform.system;
|
||||
enabled = system != pkgs.stdenv.hostPlatform.system;
|
||||
elaborated = lib.systems.elaborate { inherit system; };
|
||||
useStaticEmulator = true; # needed for chroot
|
||||
interpreter = elaborated.emulator (if useStaticEmulator then pkgs.pkgsStatic else pkgs);
|
||||
|
||||
inherit (elaborated) qemuArch;
|
||||
isQemu = "qemu-${qemuArch}" == baseNameOf interpreter;
|
||||
in makeBinfmtLine (
|
||||
{
|
||||
name = system;
|
||||
inherit interpreter;
|
||||
recognitionType = "magic";
|
||||
offset = null;
|
||||
openBinary = false;
|
||||
matchCredentials = false;
|
||||
|
||||
preserveArgvZero = isQemu;
|
||||
|
||||
fixBinary = useStaticEmulator;
|
||||
}
|
||||
// (magics.${system} or (throw "Cannot create binfmt registration for system ${system}"))
|
||||
);
|
||||
systemsAreDifferent = imagePkgs.stdenv.hostPlatform.system != pkgs.stdenv.hostPlatform.system;
|
||||
}
|
@@ -905,6 +905,7 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
binfmt = import ./binfmt.nix;
|
||||
} // outputs;
|
||||
in
|
||||
diskoLib
|
||||
|
@@ -3,6 +3,7 @@
|
||||
, lib
|
||||
, extendModules
|
||||
, options
|
||||
, imagePkgs
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
@@ -12,6 +13,12 @@ let
|
||||
checked = diskoCfg.checkScripts;
|
||||
|
||||
configSupportsZfs = config.boot.supportedFilesystems.zfs or false;
|
||||
binfmt = diskoLib.binfmt { inherit diskoLib lib pkgs imagePkgs; };
|
||||
binfmtSetup = lib.optionalString (cfg.enableBinfmt && binfmt.systemsAreDifferent) ''
|
||||
mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
|
||||
${pkgs.systemdMinimal}/lib/systemd/systemd-binfmt <(echo ${lib.strings.escapeShellArg binfmt.binfmtRegistration})
|
||||
'';
|
||||
|
||||
vmTools = pkgs.vmTools.override
|
||||
({
|
||||
rootModules = [
|
||||
@@ -124,7 +131,7 @@ in
|
||||
postVM = cfg.extraPostVM;
|
||||
inherit (diskoCfg) memSize;
|
||||
}
|
||||
(partitioner + installer));
|
||||
(binfmtSetup + partitioner + installer));
|
||||
|
||||
system.build.diskoImagesScript = diskoLib.writeCheckedBash { inherit checked pkgs; } cfg.name ''
|
||||
set -efu
|
||||
|
10
module.nix
10
module.nix
@@ -14,6 +14,15 @@ in
|
||||
|
||||
options.disko = {
|
||||
imageBuilder = {
|
||||
enableBinfmt = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = ''
|
||||
enable emulation of foreign architecture binaries in the builder.
|
||||
Makes it possible to build disk images for a foreign architecture in a VM with native performance.
|
||||
Required for the bootloader installation step, which chroots into the target environment.
|
||||
'';
|
||||
default = false;
|
||||
};
|
||||
qemu = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
description = ''
|
||||
@@ -222,6 +231,7 @@ in
|
||||
}
|
||||
];
|
||||
|
||||
_module.args.imagePkgs = pkgs;
|
||||
_module.args.diskoLib = import ./lib {
|
||||
inherit lib;
|
||||
rootMountPoint = config.disko.rootMountPoint;
|
||||
|
Reference in New Issue
Block a user