MixOS Manual

Version 1.13.0


Preface

MixOS is not NixOS. It is a Nix OS: a minimal Linux system built with Nix, which boots with a single statically linked mixos executable and uses busybox for the system’s init, shell and coreutils.

A MixOS system is built from the module in module.nix, evaluated with mixosSystem from this flake:

{
  inputs.mixos.url = "github:jmbaur/mixos";

  outputs =
    { self, nixpkgs, mixos }:
    {
      mixosConfigurations.machine = mixos.lib.mixosSystem {
        modules = [
          (
            { pkgs, ... }:
            {
              nixpkgs.pkgs = nixpkgs.legacyPackages.x86_64-linux;
              packages = [ pkgs.hello ];
            }
          )
        ];
      };
    };
}

Configuration Options lists every option available in a base MixOS system.

Kernel Parameters

MixOS reads a few parameters of its own from the kernel command line. They are all spelled mixos.<name> in order to disambiguate parameters not meant for any other program.

The command line a kernel boots is left up to the user, since MixOS does not manage any details about boot (e.g. UEFI, FIT image, etc).

mixos.self_override

Makes the running mixos, stand in for the one in the store, so that the system runs the binary it was booted with rather than the one it was built with. This is mostly helpful for development purposes, to allow for simply carrying a newly built mixos through the entire system, and is not needed for normal usage. If you need to change the mixos package itself, use the dedicated option.

mixos.test_backdoor

Address for mixos test-backdoor to listen on. Without it the backdoor guesses the best listen address based on the running environment, for example choosing vsock if in a virtualized environment with a vsock host available.

Configuration Options

packages

Packages to be included in the runtime system and available in $PATH.

Type: list of package

Default:

[ ]

Declared by:

module.nix
_module.args

Additional arguments passed to each module in addition to ones like lib, config, and pkgs, modulesPath.

This option is also available to all submodules. Submodules do not inherit args from their parent module, nor do they provide args to their parent module or sibling submodules. The sole exception to this is the argument name which is provided by parent modules to a submodule and contains the attribute name the submodule is bound to, or a unique generated name if it is not bound to an attribute.

Some arguments are already passed by default, of which the following cannot be changed with this option:

  • lib: The nixpkgs library.

  • config: The results of all options after merging the values from all modules together.

  • options: The options declared in all modules.

  • specialArgs: The specialArgs argument passed to evalModules.

  • All attributes of specialArgs

    Whereas option values can generally depend on other option values thanks to laziness, this does not apply to imports, which must be computed statically before anything else.

    For this reason, callers of the module system can provide specialArgs which are available during import resolution.

    For NixOS, specialArgs includes modulesPath, which allows you to import extra modules from the nixpkgs package tree without having to somehow make the module aware of the location of the nixpkgs or NixOS directories.

    { modulesPath, ... }: {
      imports = [
        (modulesPath + "/profiles/minimal.nix")
      ];
    }
    

For NixOS, the default value for this option includes at least this argument:

  • pkgs: The nixpkgs package set according to the nixpkgs.pkgs option.

Type: lazy attribute set of raw value

Default:

{ }

Declared by:

<nixpkgs/lib/modules.nix>
boot.extraModulePackages

A list of additional packages supplying kernel modules.

Type: list of package

Default:

[ ]

Example:

[ config.boot.kernelPackages.nvidia_x11 ]

Declared by:

module.nix
boot.firmware

List of packages containing firmware files. Such files will be loaded automatically if the kernel asks for them (i.e., when it has detected specific hardware that requires firmware to function). If multiple packages contain firmware files with the same name, the first package in the list takes precedence. Note that you must rebuild your system if you add files to any of these directories.

Type: list of package

Default:

[ ]

Declared by:

module.nix
boot.initrd.prepend

Other initrd files to prepend to the initrd MixOS builds. The kernel unpacks the concatenated archives in order, each one either a plain cpio archive or a compressed one.

Since MixOS owns the initrd, this is how CPU microcode gets supplied. Microcode is the one thing here that must be an uncompressed cpio archive, and must come first (see lib.mkOrder), because the kernel scans for it in the raw initrd before unpacking any of it.

Type: list of absolute path

Default:

[ ]

Example:

[ "${pkgs.microcode-intel}/intel-ucode.img" ]

Declared by:

module.nix
boot.kernelModules

Kernel modules to load during early bootup.

Type: list of string

Default:

[ ]

Declared by:

module.nix
boot.kernelPackages

A kernel package-set containing a kernel attribute and optionally one or more kernel modules (à la pkgs.linuxPackagesFor …).

Type: raw value

Default:

"pkgs.linuxPackages_7_2"

Declared by:

module.nix
boot.kernelPatches

A list of additional patches to apply to the kernel. See NixOS documentation for more information.

Type: list of (attribute set)

Default:

[ ]

Declared by:

module.nix
boot.modprobe.alias

Extra module aliases, keyed by alias (shell-style wildcards allowed).

Type: attribute set of string

Default:

{ }

Example:

{
  "usb:v1D6Bp0001d*" = "my_driver";
}

Declared by:

module.nix
boot.modprobe.blacklist

Kernel modules that will not be loaded automatically. Note that this only prevents a module from being loaded by one of its aliases (e.g. by the mdev $MODALIAS rule); modprobing a module by its real name still loads it, use boot.modprobe.install with /bin/false to prevent that as well.

Type: attribute set of boolean

Default:

{ }

Example:

{
  nouveau = true;
}

Declared by:

module.nix
boot.modprobe.install

Commands to run instead of inserting a module into the kernel, keyed by module name.

Type: attribute set of string

Default:

{ }

Example:

{
  nouveau = "/bin/false";
}

Declared by:

module.nix
boot.modprobe.options

Module parameters to use when loading a module, keyed by module name. Definitions from multiple modules are joined with a space.

Type: attribute set of strings concatenated with " "

Default:

{ }

Example:

{
  i915 = "enable_psr=0";
}

Declared by:

module.nix
boot.modprobe.remove

Commands to run instead of removing a module from the kernel, keyed by module name.

Type: attribute set of string

Default:

{ }

Example:

{
  mymod = "/bin/rmmod --wait mymod";
}

Declared by:

module.nix
boot.modprobe.softdep

Soft dependencies to load alongside a module, keyed by module name. Unlike real dependencies, a soft dependency failing to load does not fail the module being loaded.

Type: attribute set of strings concatenated with " "

Default:

{ }

Example:

{
  hid_generic = "pre: hid_multitouch";
}

Declared by:

module.nix
boot.modprobe.weakdep

Weak dependencies of a module, keyed by module name. These are not loaded along with the module, they only record that the modules belong together for tooling that consumes the information.

Type: attribute set of strings concatenated with " "

Default:

{ }

Example:

{
  mymod = "mymod_helper";
}

Declared by:

module.nix
boot.requiredKernelConfig

Attribute set of kernel Kconfig options that must be included in the kernel provided to mixos. Values (from lib.kernel) are asserted against the configured kernel, where lib.kernel.module is satisfied with either ‘y’ or ‘m’. Non-tristate values (lib.kernel.freeform) are asserted for equality, ignoring any quoting of string values. Options marked as optional (lib.kernel.option) are not asserted.

Type: attribute set of raw value

Default:

{ }

Example:

''
  {
    TMPFS = lib.kernel.yes;
    OVERLAY_FS = lib.kernel.module;
    LOG_BUF_SHIFT = lib.kernel.freeform "18";
  }
''

Declared by:

module.nix
boot.watchdog.enable

Enable watchdog integration. This ensures if the boot process fails, the system doesn’t hang indefinitely.

Type: boolean

Default:

true

Declared by:

module.nix
boot.watchdog.timeout

Watchdog timeout.

Type: integer of at least 10

Default:

90

Declared by:

module.nix
etc

Files to place in /etc, keyed by their path relative to /etc. Each entry is either symlinked into the store or, if a mode is given, copied with that mode.

Type: attribute set of (submodule)

Default:

{ }

Example:

{ "hostname".source = pkgs.writeText "hostname" "my-machine"; }

Declared by:

module.nix
etc.<name>.mode

Copy file to destination with permissions, or symlink if null.

Type: null or string

Default:

null

Example:

"0400"

Declared by:

module.nix
etc.<name>.source

Path to place in /etc

Type: absolute path

Declared by:

module.nix
groups

Groups to create in /etc/group.

Type: attribute set of (submodule)

Default:

{ }

Declared by:

module.nix
groups.<name>.id

Group ID. There is no automatic allocation, so this must be chosen, and kept unique, by hand.

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Declared by:

module.nix
groups.<name>.name

Name of the group, as it appears in /etc/group. Defaults to the attribute name.

Type: string

Default:

"‹name›"

Declared by:

module.nix
hardware.graphics.enable

Whether to enable hardware accelerated graphics drivers.

Type: boolean

Default:

false

Example:

true

Declared by:

module.nix
hardware.graphics.package

The mesa package to use.

Type: package

Default:

pkgs.mesa

Declared by:

module.nix
hardware.graphics.extraPackages

Additional packages to add to the driver lookup path. This is how OpenCL, VA-API and VDPAU drivers are made available, among others.

Type: list of package

Default:

[ ]

Example:

[ pkgs.intel-media-driver ]

Declared by:

module.nix
init

Entries for busybox init’s /etc/inittab, keyed by a name used only for ordering with deps. Actions run in the order listed under action, not in the order entries are declared here.

Type: attribute set of (submodule)

Default:

{ }

Declared by:

module.nix
init.<name>.enable

Whether to enable this process.

Type: boolean

Default:

true

Declared by:

module.nix
init.<name>.action

sysinit actions are started first, and init waits for them to complete. wait actions are started next, and init waits for them to complete. once actions are started next (and not waited for).

askfirst and respawn are started next. For askfirst, before running the specified process, init displays the line “Please press Enter to activate this console” and then waits for the user to press enter before starting it.

shutdown actions are run on halt/reboot/poweroff, or on SIGQUIT. Then the machine is halted/rebooted/powered off, or for SIGQUIT, restart action is exec’ed (init process is replaced by that process). If no restart action specified, SIGQUIT has no effect.

ctrlaltdel actions are run when SIGINT is received (this might be initiated by Ctrl-Alt-Del key combination). After they complete, normal processing of askfirst / respawn resumes.

Type: one of “sysinit”, “wait”, “once”, “respawn”, “askfirst”, “shutdown”, “restart”, “ctrlaltdel”

Declared by:

module.nix
init.<name>.deps

Names of other init entries this one must be ordered after. Ordering only applies within a single action: every name listed here must name an enabled entry with the same action as this one, or evaluation fails.

Type: list of string

Default:

[ ]

Example:

[
  "mount-state"
]

Declared by:

module.nix
init.<name>.process

Specifies the process to be executed and it’s command line.

Type: string or package

Example:

"/bin/echo 'hello, world'"

Declared by:

module.nix
init.<name>.tty

This field is used by BusyBox init to specify the controlling tty for the specified process to run on. The contents of this field are appended to “/dev/” and used as-is. There is no need for this field to be unique, although if it isn’t you may have strange results. If this field is left blank, then the init’s stdin/out will be used.

Type: string

Default:

"null"

Example:

"tty1"

Declared by:

module.nix
mdev.rules

Rules to be interpreted by mdev, placed in /etc/mdev.conf.

Type: strings concatenated with “\n”

Declared by:

module.nix
mixos.package

The mixos package to use.

Type: package

Default:

"pkgs.mixos"

Declared by:

module.nix
mixos.osRelease

/etc/os-release contents.

Type: open submodule of attribute set of (atom (null, bool, int, float or string))

Default:

{ }

Declared by:

module.nix
mixos.osRelease.ID

The ID field of /etc/os-release, identifying the operating system.

Type: string

Default:

"mixos"

Declared by:

module.nix
mixos.osRelease.VERSION_ID

The VERSION_ID field of /etc/os-release.

Type: string

Default:

config.mixos.package.version

Declared by:

module.nix
mixos.storeUUID

UUID of the erofs image, fixed for reproducibility.

Type: string

Default:

"cb67e325-87bc-4235-b2fd-cd5d54efe14b"

Declared by:

module.nix
mixos.testing.enable

Whether to enable the mixos test backdoor service.

Type: boolean

Default:

false

Example:

true

Declared by:

module.nix
nixpkgs.pkgs

The pkgs module argument.

Type: Nixpkgs package set

Default:

{ }

Declared by:

module.nix
services

Long-running processes to supervise, keyed by service name. Each one becomes a service directory under /var/service, run by the runsvdir started from init.

Type: attribute set of (submodule)

Default:

{ }

Declared by:

module.nix
services.<name>.enable

Whether to enable this service.

Type: boolean

Default:

true

Declared by:

module.nix
services.<name>.run

Specifies the process to be executed for this service.

Type: absolute path

Example:

/bin/httpd

Declared by:

module.nix
state.enable

Whether to enable persistence of state.

Type: boolean

Default:

false

Example:

true

Declared by:

module.nix
state.fsType

The filesystem type of the state device.

Type: string

Example:

"ext4"

Declared by:

module.nix
state.init

Program to initialize state, for example for formatting disks, creating device-mapper devices, etc. This program will run on every boot, thus it should be idempotent if the backing device has already been initialized.

Type: null or absolute path

Default:

null

Example:

pkgs.writeScript "state-init" "mkfs.ext4 /dev/sda"

Declared by:

module.nix
state.options

The mount options to use when mounting the state device. Available options can usually be found in fs/<fstype>/super.c of the kernel source. In addition, any of the MOUNT_ATTR_* names can be used with name lowercased and the “MOUNT_ATTR_” prefix removed (see <linux.mount.h>).

Type: list of string

Default:

[ ]

Declared by:

module.nix
state.source

The device being mounted.

Type: string

Example:

"/dev/sda"

Declared by:

module.nix
system.build

Attribute set of derivations used to set up the system.

Type: open submodule of lazy attribute set of unspecified value

Default:

{ }

Declared by:

module.nix
users

Users to create in /etc/passwd.

Type: attribute set of (submodule)

Default:

{ }

Declared by:

module.nix
users.<name>.description

The GECOS field of the user’s /etc/passwd entry.

Type: string

Default:

""

Declared by:

module.nix
users.<name>.gid

ID of the user’s primary group. This is the raw ID rather than a name, so it must match the id of the intended entry in groups.

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Declared by:

module.nix
users.<name>.groups

Names of supplementary groups the user is a member of, on top of the primary group named by gid.

Type: list of string

Default:

[ ]

Declared by:

module.nix
users.<name>.home

The user’s home directory. Nothing creates it, so a directory that does not otherwise exist stays missing.

Type: string

Default:

"/var/empty"

Declared by:

module.nix
users.<name>.name

Name of the user, as it appears in /etc/passwd. Defaults to the attribute name.

Type: string

Default:

"‹name›"

Declared by:

module.nix
users.<name>.shell

The user’s login shell.

Type: absolute path

Default:

"/bin/nologin"

Declared by:

module.nix
users.<name>.uid

User ID. There is no automatic allocation, so this must be chosen, and kept unique, by hand.

Type: 16 bit unsigned integer; between 0 and 65535 (both inclusive)

Declared by:

module.nix