at 16.09-beta 9.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 kernel = config.boot.kernelPackages.kernel; 8 9 kernelModulesConf = pkgs.writeText "nixos.conf" 10 '' 11 ${concatStringsSep "\n" config.boot.kernelModules} 12 ''; 13 14in 15 16{ 17 18 ###### interface 19 20 options = { 21 22 boot.kernelPackages = mkOption { 23 default = pkgs.linuxPackages; 24 # We don't want to evaluate all of linuxPackages for the manual 25 # - some of it might not even evaluate correctly. 26 defaultText = "pkgs.linuxPackages"; 27 example = literalExample "pkgs.linuxPackages_2_6_25"; 28 description = '' 29 This option allows you to override the Linux kernel used by 30 NixOS. Since things like external kernel module packages are 31 tied to the kernel you're using, it also overrides those. 32 This option is a function that takes Nixpkgs as an argument 33 (as a convenience), and returns an attribute set containing at 34 the very least an attribute <varname>kernel</varname>. 35 Additional attributes may be needed depending on your 36 configuration. For instance, if you use the NVIDIA X driver, 37 then it also needs to contain an attribute 38 <varname>nvidia_x11</varname>. 39 ''; 40 }; 41 42 boot.kernelParams = mkOption { 43 type = types.listOf types.str; 44 default = [ ]; 45 description = "Parameters added to the kernel command line."; 46 }; 47 48 boot.consoleLogLevel = mkOption { 49 type = types.int; 50 default = 4; 51 description = '' 52 The kernel console log level. Log messages with a priority 53 numerically less than this will not appear on the console. 54 ''; 55 }; 56 57 boot.vesa = mkOption { 58 type = types.bool; 59 default = false; 60 description = '' 61 Whether to activate VESA video mode on boot. 62 ''; 63 }; 64 65 boot.extraModulePackages = mkOption { 66 type = types.listOf types.package; 67 default = []; 68 example = literalExample "[ pkgs.linuxPackages.nvidia_x11 ]"; 69 description = "A list of additional packages supplying kernel modules."; 70 }; 71 72 boot.kernelModules = mkOption { 73 type = types.listOf types.str; 74 default = []; 75 description = '' 76 The set of kernel modules to be loaded in the second stage of 77 the boot process. Note that modules that are needed to 78 mount the root file system should be added to 79 <option>boot.initrd.availableKernelModules</option> or 80 <option>boot.initrd.kernelModules</option>. 81 ''; 82 }; 83 84 boot.initrd.availableKernelModules = mkOption { 85 type = types.listOf types.str; 86 default = []; 87 example = [ "sata_nv" "ext3" ]; 88 description = '' 89 The set of kernel modules in the initial ramdisk used during the 90 boot process. This set must include all modules necessary for 91 mounting the root device. That is, it should include modules 92 for the physical device (e.g., SCSI drivers) and for the file 93 system (e.g., ext3). The set specified here is automatically 94 closed under the module dependency relation, i.e., all 95 dependencies of the modules list here are included 96 automatically. The modules listed here are available in the 97 initrd, but are only loaded on demand (e.g., the ext3 module is 98 loaded automatically when an ext3 filesystem is mounted, and 99 modules for PCI devices are loaded when they match the PCI ID 100 of a device in your system). To force a module to be loaded, 101 include it in <option>boot.initrd.kernelModules</option>. 102 ''; 103 }; 104 105 boot.initrd.kernelModules = mkOption { 106 type = types.listOf types.str; 107 default = []; 108 description = "List of modules that are always loaded by the initrd."; 109 }; 110 111 system.modulesTree = mkOption { 112 type = types.listOf types.path; 113 internal = true; 114 default = []; 115 description = '' 116 Tree of kernel modules. This includes the kernel, plus modules 117 built outside of the kernel. Combine these into a single tree of 118 symlinks because modprobe only supports one directory. 119 ''; 120 # Convert the list of path to only one path. 121 apply = pkgs.aggregateModules; 122 }; 123 124 system.requiredKernelConfig = mkOption { 125 default = []; 126 example = literalExample '' 127 with config.lib.kernelConfig; [ 128 (isYes "MODULES") 129 (isEnabled "FB_CON_DECOR") 130 (isEnabled "BLK_DEV_INITRD") 131 ] 132 ''; 133 internal = true; 134 type = types.listOf types.attrs; 135 description = '' 136 This option allows modules to specify the kernel config options that 137 must be set (or unset) for the module to work. Please use the 138 lib.kernelConfig functions to build list elements. 139 ''; 140 }; 141 142 }; 143 144 145 ###### implementation 146 147 config = mkIf (!config.boot.isContainer) { 148 149 system.build = { inherit kernel; }; 150 151 system.modulesTree = [ kernel ] ++ config.boot.extraModulePackages; 152 153 # Implement consoleLogLevel both in early boot and using sysctl 154 # (so you don't need to reboot to have changes take effect). 155 boot.kernelParams = 156 [ "loglevel=${toString config.boot.consoleLogLevel}" ] ++ 157 optionals config.boot.vesa [ "vga=0x317" ]; 158 159 boot.kernel.sysctl."kernel.printk" = config.boot.consoleLogLevel; 160 161 boot.kernelModules = [ "loop" "atkbd" ]; 162 163 boot.initrd.availableKernelModules = 164 [ # Note: most of these (especially the SATA/PATA modules) 165 # shouldn't be included by default since nixos-hardware-scan 166 # detects them, but I'm keeping them for now for backwards 167 # compatibility. 168 169 # Some SATA/PATA stuff. 170 "ahci" 171 "sata_nv" 172 "sata_via" 173 "sata_sis" 174 "sata_uli" 175 "ata_piix" 176 "pata_marvell" 177 178 # Standard SCSI stuff. 179 "sd_mod" 180 "sr_mod" 181 182 # Standard IDE stuff. 183 "ide_cd" 184 "ide_disk" 185 "ide_generic" 186 187 # SD cards and internal eMMC drives. 188 "mmc_block" 189 190 # Support USB keyboards, in case the boot fails and we only have 191 # a USB keyboard. 192 "uhci_hcd" 193 "ehci_hcd" 194 "ehci_pci" 195 "ohci_hcd" 196 "ohci_pci" 197 "xhci_hcd" 198 "xhci_pci" 199 "usbhid" 200 "hid_generic" "hid_lenovo" 201 "hid_apple" "hid_logitech_dj" "hid_lenovo_tpkbd" "hid_roccat" 202 203 # Misc. stuff. 204 "pcips2" "atkbd" 205 206 # To wait for SCSI devices to appear. 207 "scsi_wait_scan" 208 209 # Needed by the stage 2 init script. 210 "rtc_cmos" 211 ]; 212 213 boot.initrd.kernelModules = 214 [ # For LVM. 215 "dm_mod" 216 ]; 217 218 # The Linux kernel >= 2.6.27 provides firmware. 219 hardware.firmware = [ kernel ]; 220 221 # Create /etc/modules-load.d/nixos.conf, which is read by 222 # systemd-modules-load.service to load required kernel modules. 223 environment.etc = singleton 224 { target = "modules-load.d/nixos.conf"; 225 source = kernelModulesConf; 226 }; 227 228 systemd.services."systemd-modules-load" = 229 { wantedBy = [ "multi-user.target" ]; 230 restartTriggers = [ kernelModulesConf ]; 231 serviceConfig = 232 { # Ignore failed module loads. Typically some of the 233 # modules in ‘boot.kernelModules’ are "nice to have but 234 # not required" (e.g. acpi-cpufreq), so we don't want to 235 # barf on those. 236 SuccessExitStatus = "0 1"; 237 }; 238 }; 239 240 lib.kernelConfig = { 241 isYes = option: { 242 assertion = config: config.isYes option; 243 message = "CONFIG_${option} is not yes!"; 244 configLine = "CONFIG_${option}=y"; 245 }; 246 247 isNo = option: { 248 assertion = config: config.isNo option; 249 message = "CONFIG_${option} is not no!"; 250 configLine = "CONFIG_${option}=n"; 251 }; 252 253 isModule = option: { 254 assertion = config: config.isModule option; 255 message = "CONFIG_${option} is not built as a module!"; 256 configLine = "CONFIG_${option}=m"; 257 }; 258 259 ### Usually you will just want to use these two 260 # True if yes or module 261 isEnabled = option: { 262 assertion = config: config.isEnabled option; 263 message = "CONFIG_${option} is not enabled!"; 264 configLine = "CONFIG_${option}=y"; 265 }; 266 267 # True if no or omitted 268 isDisabled = option: { 269 assertion = config: config.isDisabled option; 270 message = "CONFIG_${option} is not disabled!"; 271 configLine = "CONFIG_${option}=n"; 272 }; 273 }; 274 275 # The config options that all modules can depend upon 276 system.requiredKernelConfig = with config.lib.kernelConfig; [ 277 # !!! Should this really be needed? 278 (isYes "MODULES") 279 (isYes "BINFMT_ELF") 280 ]; 281 282 # nixpkgs kernels are assumed to have all required features 283 assertions = if config.boot.kernelPackages.kernel ? features then [] else 284 let cfg = config.boot.kernelPackages.kernel.config; in map (attrs: 285 { assertion = attrs.assertion cfg; inherit (attrs) message; } 286 ) config.system.requiredKernelConfig; 287 288 }; 289 290}