2018-10-03 11:49:50 +02:00
|
|
|
{ lib, config, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
mergeFalseByDefault = locs: defs:
|
|
|
|
if defs == [] then abort "This case should never happen."
|
2020-04-01 03:20:33 +02:00
|
|
|
else if any (x: x == false) (getValues defs) then false
|
2018-10-03 11:49:50 +02:00
|
|
|
else true;
|
|
|
|
|
|
|
|
kernelItem = types.submodule {
|
|
|
|
options = {
|
|
|
|
tristate = mkOption {
|
linux: make sure all config options have the same value
Currently, kernel config options whose value is "yes" always override
options whose value is "no".
This is not always desired.
Generally speaking, if someone defines an option to have the value
"no", presumably they are disabling the option for a reason, so it's
not always OK to silently enable it due to another, probably unrelated
reason.
For example, a user may want to reduce the kernel attack surface and
therefore may want to disable features that are being enabled in
common-config.nix.
In fact, common-config.nix was already silently enabling options that
were intended to be disabled in hardened/config.nix for security
reasons, such as INET_DIAG.
By eliminating the custom merge function, these config options will
now use the default module option merge functions which make sure
that all options with the highest priority have the same value.
A user that wishes to override an option defined in common-config.nix
can currently use mkForce or mkOverride to do so, e.g.:
BINFMT_MISC = mkForce (option no);
That said, this is not going to be necessary in the future, because
the plan is for kernel config options defined in nixpkgs to use a
lower priority by default, like it currently happens for other module
options.
2020-05-29 14:25:48 +02:00
|
|
|
type = types.enum [ "y" "m" "n" null ];
|
2018-10-03 11:49:50 +02:00
|
|
|
default = null;
|
|
|
|
internal = true;
|
|
|
|
visible = true;
|
|
|
|
description = ''
|
|
|
|
Use this field for tristate kernel options expecting a "y" or "m" or "n".
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
freeform = mkOption {
|
|
|
|
type = types.nullOr types.str // {
|
|
|
|
merge = mergeEqualOption;
|
|
|
|
};
|
|
|
|
default = null;
|
|
|
|
example = ''MMC_BLOCK_MINORS.freeform = "32";'';
|
|
|
|
description = ''
|
|
|
|
Freeform description of a kernel configuration item value.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
optional = mkOption {
|
|
|
|
type = types.bool // { merge = mergeFalseByDefault; };
|
|
|
|
default = false;
|
|
|
|
description = ''
|
2020-07-04 15:15:26 +02:00
|
|
|
Whether option should generate a failure when unused.
|
2020-04-01 03:20:33 +02:00
|
|
|
Upon merging values, mandatory wins over optional.
|
2018-10-03 11:49:50 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
mkValue = with lib; val:
|
|
|
|
let
|
|
|
|
isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
|
|
|
|
|
|
|
|
in
|
|
|
|
if (val == "") then "\"\""
|
|
|
|
else if val == "y" || val == "m" || val == "n" then val
|
|
|
|
else if all isNumber (stringToCharacters val) then val
|
|
|
|
else if substring 0 2 val == "0x" then val
|
|
|
|
else val; # FIXME: fix quoting one day
|
|
|
|
|
|
|
|
|
|
|
|
# generate nix intermediate kernel config file of the form
|
|
|
|
#
|
|
|
|
# VIRTIO_MMIO m
|
|
|
|
# VIRTIO_BLK y
|
|
|
|
# VIRTIO_CONSOLE n
|
|
|
|
# NET_9P_VIRTIO? y
|
|
|
|
#
|
|
|
|
# Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
|
|
|
|
# returns a string, expr should be an attribute set
|
|
|
|
# Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa
|
|
|
|
# use the identity if you don't want to override the configured values
|
|
|
|
generateNixKConf = exprs:
|
|
|
|
let
|
|
|
|
mkConfigLine = key: item:
|
|
|
|
let
|
|
|
|
val = if item.freeform != null then item.freeform else item.tristate;
|
|
|
|
in
|
|
|
|
if val == null
|
|
|
|
then ""
|
|
|
|
else if (item.optional)
|
|
|
|
then "${key}? ${mkValue val}\n"
|
|
|
|
else "${key} ${mkValue val}\n";
|
|
|
|
|
|
|
|
mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
|
|
|
|
in mkConf exprs;
|
|
|
|
|
|
|
|
in
|
|
|
|
{
|
|
|
|
|
|
|
|
options = {
|
|
|
|
|
|
|
|
intermediateNixConfig = mkOption {
|
|
|
|
readOnly = true;
|
|
|
|
type = types.lines;
|
|
|
|
example = ''
|
|
|
|
USB? y
|
|
|
|
DEBUG n
|
|
|
|
'';
|
|
|
|
description = ''
|
|
|
|
The result of converting the structured kernel configuration in settings
|
|
|
|
to an intermediate string that can be parsed by generate-config.pl to
|
|
|
|
answer the kernel `make defconfig`.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
settings = mkOption {
|
|
|
|
type = types.attrsOf kernelItem;
|
2021-10-03 18:06:03 +02:00
|
|
|
example = literalExpression '' with lib.kernel; {
|
2018-10-03 11:49:50 +02:00
|
|
|
"9P_NET" = yes;
|
2020-04-01 03:20:33 +02:00
|
|
|
USB = option yes;
|
2018-10-03 11:49:50 +02:00
|
|
|
MMC_BLOCK_MINORS = freeform "32";
|
|
|
|
}'';
|
|
|
|
description = ''
|
|
|
|
Structured kernel configuration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = {
|
|
|
|
intermediateNixConfig = generateNixKConf config.settings;
|
|
|
|
};
|
|
|
|
}
|