at 25.11-pre 8.8 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.console; 9 10 makeColor = i: lib.concatMapStringsSep "," (x: "0x" + lib.substring (2 * i) 2 x); 11 12 isUnicode = lib.hasSuffix "UTF-8" (lib.toUpper config.i18n.defaultLocale); 13 14 optimizedKeymap = 15 pkgs.runCommand "keymap" 16 { 17 nativeBuildInputs = [ pkgs.buildPackages.kbd ]; 18 LOADKEYS_KEYMAP_PATH = "${consoleEnv pkgs.kbd}/share/keymaps/**"; 19 preferLocalBuild = true; 20 } 21 '' 22 loadkeys -b ${lib.optionalString isUnicode "-u"} "${cfg.keyMap}" > $out 23 ''; 24 25 # Sadly, systemd-vconsole-setup doesn't support binary keymaps. 26 vconsoleConf = pkgs.writeText "vconsole.conf" '' 27 KEYMAP=${cfg.keyMap} 28 ${lib.optionalString (cfg.font != null) "FONT=${cfg.font}"} 29 ''; 30 31 consoleEnv = 32 kbd: 33 pkgs.buildEnv { 34 name = "console-env"; 35 paths = [ kbd ] ++ cfg.packages; 36 pathsToLink = [ 37 "/share/consolefonts" 38 "/share/consoletrans" 39 "/share/keymaps" 40 "/share/unimaps" 41 ]; 42 }; 43in 44 45{ 46 ###### interface 47 48 options.console = { 49 enable = lib.mkEnableOption "virtual console" // { 50 default = true; 51 }; 52 53 font = lib.mkOption { 54 type = with lib.types; nullOr (either str path); 55 default = null; 56 example = "LatArCyrHeb-16"; 57 description = '' 58 The font used for the virtual consoles. 59 Can be `null`, a font name, or a path to a PSF font file. 60 61 Use `null` to let the kernel choose a built-in font. 62 The default is 8x16, and, as of Linux 5.3, Terminus 32 bold for display 63 resolutions of 2560x1080 and higher. 64 These fonts cover the [IBM437][] character set. 65 66 [IBM437]: https://en.wikipedia.org/wiki/Code_page_437 67 ''; 68 }; 69 70 keyMap = lib.mkOption { 71 type = with lib.types; either str path; 72 default = "us"; 73 example = "fr"; 74 description = '' 75 The keyboard mapping table for the virtual consoles. 76 ''; 77 }; 78 79 colors = lib.mkOption { 80 type = with lib.types; listOf (strMatching "[[:xdigit:]]{6}"); 81 default = [ ]; 82 example = [ 83 "002b36" 84 "dc322f" 85 "859900" 86 "b58900" 87 "268bd2" 88 "d33682" 89 "2aa198" 90 "eee8d5" 91 "002b36" 92 "cb4b16" 93 "586e75" 94 "657b83" 95 "839496" 96 "6c71c4" 97 "93a1a1" 98 "fdf6e3" 99 ]; 100 description = '' 101 The 16 colors palette used by the virtual consoles. 102 Leave empty to use the default colors. 103 Colors must be in hexadecimal format and listed in 104 order from color 0 to color 15. 105 ''; 106 107 }; 108 109 packages = lib.mkOption { 110 type = lib.types.listOf lib.types.package; 111 default = [ ]; 112 description = '' 113 List of additional packages that provide console fonts, keymaps and 114 other resources for virtual consoles use. 115 ''; 116 }; 117 118 useXkbConfig = lib.mkOption { 119 type = lib.types.bool; 120 default = false; 121 description = '' 122 If set, configure the virtual console keymap from the xserver 123 keyboard settings. 124 ''; 125 }; 126 127 earlySetup = lib.mkOption { 128 default = false; 129 type = lib.types.bool; 130 description = '' 131 Enable setting virtual console options as early as possible (in initrd). 132 ''; 133 }; 134 135 }; 136 137 ###### implementation 138 139 config = lib.mkMerge [ 140 { 141 console.keyMap = 142 with config.services.xserver; 143 lib.mkIf cfg.useXkbConfig ( 144 pkgs.runCommand "xkb-console-keymap" { preferLocalBuild = true; } '' 145 '${pkgs.buildPackages.ckbcomp}/bin/ckbcomp' \ 146 ${ 147 lib.optionalString ( 148 config.environment.sessionVariables ? XKB_CONFIG_ROOT 149 ) "-I${config.environment.sessionVariables.XKB_CONFIG_ROOT}" 150 } \ 151 -model '${xkb.model}' -layout '${xkb.layout}' \ 152 -option '${xkb.options}' -variant '${xkb.variant}' > "$out" 153 '' 154 ); 155 } 156 157 (lib.mkIf cfg.enable ( 158 lib.mkMerge [ 159 { 160 environment.systemPackages = [ pkgs.kbd ]; 161 162 # Let systemd-vconsole-setup.service do the work of setting up the 163 # virtual consoles. 164 environment.etc."vconsole.conf".source = vconsoleConf; 165 # Provide kbd with additional packages. 166 environment.etc.kbd.source = "${consoleEnv pkgs.kbd}/share"; 167 168 boot.initrd.preLVMCommands = lib.mkIf (!config.boot.initrd.systemd.enable) ( 169 lib.mkBefore '' 170 kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console 171 printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console 172 loadkmap < ${optimizedKeymap} 173 174 ${lib.optionalString (cfg.earlySetup && cfg.font != null) '' 175 setfont -C /dev/console $extraUtils/share/consolefonts/font.psf 176 ''} 177 '' 178 ); 179 180 boot.initrd.systemd.contents = { 181 "/etc/vconsole.conf".source = vconsoleConf; 182 # Add everything if we want full console setup... 183 "/etc/kbd" = lib.mkIf cfg.earlySetup { 184 source = "${consoleEnv config.boot.initrd.systemd.package.kbd}/share"; 185 }; 186 # ...but only the keymaps if we don't 187 "/etc/kbd/keymaps" = lib.mkIf (!cfg.earlySetup) { 188 source = "${consoleEnv config.boot.initrd.systemd.package.kbd}/share/keymaps"; 189 }; 190 }; 191 boot.initrd.systemd.additionalUpstreamUnits = [ 192 "systemd-vconsole-setup.service" 193 ]; 194 boot.initrd.systemd.storePaths = 195 [ 196 "${config.boot.initrd.systemd.package}/lib/systemd/systemd-vconsole-setup" 197 "${config.boot.initrd.systemd.package.kbd}/bin/setfont" 198 "${config.boot.initrd.systemd.package.kbd}/bin/loadkeys" 199 "${config.boot.initrd.systemd.package.kbd.gzip}/bin/gzip" # Fonts and keyboard layouts are compressed 200 ] 201 ++ lib.optionals (cfg.font != null && lib.hasPrefix builtins.storeDir cfg.font) [ 202 "${cfg.font}" 203 ] 204 ++ lib.optionals (lib.hasPrefix builtins.storeDir cfg.keyMap) [ 205 "${cfg.keyMap}" 206 ]; 207 208 systemd.additionalUpstreamSystemUnits = [ 209 "systemd-vconsole-setup.service" 210 ]; 211 212 systemd.services.reload-systemd-vconsole-setup = { 213 description = "Reset console on configuration changes"; 214 wantedBy = [ "multi-user.target" ]; 215 restartTriggers = [ 216 vconsoleConf 217 (consoleEnv pkgs.kbd) 218 ]; 219 reloadIfChanged = true; 220 serviceConfig = { 221 RemainAfterExit = true; 222 ExecStart = "${pkgs.coreutils}/bin/true"; 223 ExecReload = "/run/current-system/systemd/bin/systemctl restart systemd-vconsole-setup"; 224 }; 225 }; 226 } 227 228 (lib.mkIf (cfg.colors != [ ]) { 229 boot.kernelParams = [ 230 "vt.default_red=${makeColor 0 cfg.colors}" 231 "vt.default_grn=${makeColor 1 cfg.colors}" 232 "vt.default_blu=${makeColor 2 cfg.colors}" 233 ]; 234 }) 235 236 (lib.mkIf (cfg.earlySetup && cfg.font != null && !config.boot.initrd.systemd.enable) { 237 boot.initrd.extraUtilsCommands = '' 238 mkdir -p $out/share/consolefonts 239 ${ 240 if lib.substring 0 1 cfg.font == "/" then 241 '' 242 font="${cfg.font}" 243 '' 244 else 245 '' 246 font="$(echo ${consoleEnv pkgs.kbd}/share/consolefonts/${cfg.font}.*)" 247 '' 248 } 249 if [[ $font == *.gz ]]; then 250 gzip -cd $font > $out/share/consolefonts/font.psf 251 else 252 cp -L $font $out/share/consolefonts/font.psf 253 fi 254 ''; 255 }) 256 ] 257 )) 258 ]; 259 260 imports = [ 261 (lib.mkRenamedOptionModule [ "i18n" "consoleFont" ] [ "console" "font" ]) 262 (lib.mkRenamedOptionModule [ "i18n" "consoleKeyMap" ] [ "console" "keyMap" ]) 263 (lib.mkRenamedOptionModule [ "i18n" "consoleColors" ] [ "console" "colors" ]) 264 (lib.mkRenamedOptionModule [ "i18n" "consolePackages" ] [ "console" "packages" ]) 265 (lib.mkRenamedOptionModule [ "i18n" "consoleUseXkbConfig" ] [ "console" "useXkbConfig" ]) 266 (lib.mkRenamedOptionModule [ "boot" "earlyVconsoleSetup" ] [ "console" "earlySetup" ]) 267 (lib.mkRenamedOptionModule [ "boot" "extraTTYs" ] [ "console" "extraTTYs" ]) 268 (lib.mkRemovedOptionModule [ "console" "extraTTYs" ] '' 269 Since NixOS switched to systemd (circa 2012), TTYs have been spawned on 270 demand, so there is no need to configure them manually. 271 '') 272 ]; 273}