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