summary refs log tree commit diff
path: root/nixos/modules/system/boot/modprobe.nix
blob: 8b2762e2526dd551b69637cff0c5bb0c77909696 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
{ config, pkgs, ... }:

with pkgs.lib;

{

  ###### interface

  options = {

    system.sbin.modprobe = mkOption {
      internal = true;
      default = pkgs.writeTextFile {
        name = "modprobe";
        destination = "/sbin/modprobe";
        executable = true;
        text =
          ''
            #! ${pkgs.stdenv.shell}
            export MODULE_DIR=/run/current-system/kernel-modules/lib/modules

            # Fall back to the kernel modules used at boot time if the
            # modules in the current configuration don't match the
            # running kernel.
            if [ ! -d "$MODULE_DIR/$(${pkgs.coreutils}/bin/uname -r)" ]; then
                MODULE_DIR=/run/booted-system/kernel-modules/lib/modules/
            fi

            exec ${pkgs.kmod}/sbin/modprobe "$@"
          '';
      };
      description = ''
        Wrapper around modprobe that sets the path to the modules
        tree.
      '';
    };

    boot.blacklistedKernelModules = mkOption {
      default = [];
      example = [ "cirrusfb" "i2c_piix4" ];
      description = ''
        List of names of kernel modules that should not be loaded
        automatically by the hardware probing code.
      '';
    };

    boot.extraModprobeConfig = mkOption {
      default = "";
      example =
        ''
          options parport_pc io=0x378 irq=7 dma=1
        '';
      description = ''
        Any additional configuration to be appended to the generated
        <filename>modprobe.conf</filename>.  This is typically used to
        specify module options.  See
        <citerefentry><refentrytitle>modprobe.conf</refentrytitle>
        <manvolnum>5</manvolnum></citerefentry> for details.
      '';
      type = types.lines;
    };

  };


  ###### implementation

  config = {

    environment.etc = singleton
      { source = pkgs.writeText "modprobe.conf"
          ''
            ${flip concatMapStrings config.boot.blacklistedKernelModules (name: ''
              blacklist ${name}
            '')}
            ${config.boot.extraModprobeConfig}
          '';
        target = "modprobe.d/nixos.conf";
      };

    environment.systemPackages = [ config.system.sbin.modprobe pkgs.kmod ];

    boot.blacklistedKernelModules =
      [ # This module is for debugging and generates gigantic amounts
        # of log output, so it should never be loaded automatically.
        "evbug"

        # This module causes ALSA to occassionally select the wrong
        # default sound device, and is little more than an annoyance
        # on modern machines.
        "snd_pcsp"

        # The cirrusfb module prevents X11 from starting.  FIXME:
        # Ubuntu blacklists all framebuffer devices because they're
        # "buggy" and cause suspend problems.  Maybe we should too?
        "cirrusfb"
      ];

    system.activationScripts.modprobe =
      ''
        # Allow the kernel to find our wrapped modprobe (which searches
        # in the right location in the Nix store for kernel modules).
        # We need this when the kernel (or some module) auto-loads a
        # module.
        echo ${config.system.sbin.modprobe}/sbin/modprobe > /proc/sys/kernel/modprobe
      '';

    environment.variables.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules";

  };

}