at 16.09-beta 4.3 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 makeColor = n: value: "COLOR_${toString n}=${value}"; 8 makeColorCS = 9 let positions = [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ]; 10 in n: value: "\\033]P${elemAt positions (n - 1)}${value}"; 11 colors = concatImapStringsSep "\n" makeColor config.i18n.consoleColors; 12 13 isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale); 14 15 optimizedKeymap = pkgs.runCommand "keymap" { 16 nativeBuildInputs = [ pkgs.kbd ]; 17 LOADKEYS_KEYMAP_PATH = "${kbdEnv}/share/keymaps/**"; 18 } '' 19 loadkeys -b ${optionalString isUnicode "-u"} "${config.i18n.consoleKeyMap}" > $out 20 ''; 21 22 # Sadly, systemd-vconsole-setup doesn't support binary keymaps. 23 vconsoleConf = pkgs.writeText "vconsole.conf" '' 24 KEYMAP=${config.i18n.consoleKeyMap} 25 FONT=${config.i18n.consoleFont} 26 ${colors} 27 ''; 28 29 kbdEnv = pkgs.buildEnv { 30 name = "kbd-env"; 31 paths = [ pkgs.kbd ] ++ config.i18n.consolePackages; 32 pathsToLink = [ "/share/consolefonts" "/share/consoletrans" "/share/keymaps" "/share/unimaps" ]; 33 }; 34 35 setVconsole = !config.boot.isContainer; 36in 37 38{ 39 ###### interface 40 41 options = { 42 43 # most options are defined in i18n.nix 44 45 # FIXME: still needed? 46 boot.extraTTYs = mkOption { 47 default = []; 48 type = types.listOf types.str; 49 example = ["tty8" "tty9"]; 50 description = '' 51 Tty (virtual console) devices, in addition to the consoles on 52 which mingetty and syslogd run, that must be initialised. 53 Only useful if you have some program that you want to run on 54 some fixed console. For example, the NixOS installation CD 55 opens the manual in a web browser on console 7, so it sets 56 <option>boot.extraTTYs</option> to <literal>["tty7"]</literal>. 57 ''; 58 }; 59 60 boot.earlyVconsoleSetup = mkOption { 61 default = false; 62 type = types.bool; 63 description = '' 64 Enable setting font as early as possible (in initrd). 65 ''; 66 }; 67 68 }; 69 70 71 ###### implementation 72 73 config = mkMerge [ 74 (mkIf (!setVconsole || (setVconsole && config.boot.earlyVconsoleSetup)) { 75 systemd.services."systemd-vconsole-setup".enable = false; 76 }) 77 78 (mkIf setVconsole (mkMerge [ 79 { environment.systemPackages = [ pkgs.kbd ]; 80 81 # Let systemd-vconsole-setup.service do the work of setting up the 82 # virtual consoles. 83 environment.etc."vconsole.conf".source = vconsoleConf; 84 # Provide kbd with additional packages. 85 environment.etc."kbd".source = "${kbdEnv}/share"; 86 87 boot.initrd.preLVMCommands = mkBefore '' 88 kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console 89 printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console 90 loadkmap < ${optimizedKeymap} 91 92 ${optionalString config.boot.earlyVconsoleSetup '' 93 setfont -C /dev/console $extraUtils/share/consolefonts/font.psf 94 ''} 95 96 ${concatImapStringsSep "\n" (n: color: '' 97 printf "${makeColorCS n color}" >> /dev/console 98 '') config.i18n.consoleColors} 99 ''; 100 } 101 102 (mkIf (!config.boot.earlyVconsoleSetup) { 103 # This is identical to the systemd-vconsole-setup.service unit 104 # shipped with systemd, except that it uses /dev/tty1 instead of 105 # /dev/tty0 to prevent putting the X server in non-raw mode, and 106 # it has a restart trigger. 107 systemd.services."systemd-vconsole-setup" = 108 { wantedBy = [ "sysinit.target" ]; 109 before = [ "display-manager.service" ]; 110 after = [ "systemd-udev-settle.service" ]; 111 restartTriggers = [ vconsoleConf kbdEnv ]; 112 }; 113 }) 114 115 (mkIf config.boot.earlyVconsoleSetup { 116 boot.initrd.extraUtilsCommands = '' 117 mkdir -p $out/share/consolefonts 118 ${if substring 0 1 config.i18n.consoleFont == "/" then '' 119 font="${config.i18n.consoleFont}" 120 '' else '' 121 font="$(echo ${kbdEnv}/share/consolefonts/${config.i18n.consoleFont}.*)" 122 ''} 123 if [[ $font == *.gz ]]; then 124 gzip -cd $font > $out/share/consolefonts/font.psf 125 else 126 cp -L $font $out/share/consolefonts/font.psf 127 fi 128 ''; 129 }) 130 ])) 131 ]; 132 133}