summary refs log tree commit diff
path: root/nixos/modules/tasks/kbd.nix
diff options
context:
space:
mode:
authorNikolay Amiantov <ab@fmap.me>2016-07-13 03:55:12 +0300
committerNikolay Amiantov <ab@fmap.me>2016-07-13 03:56:07 +0300
commitd9aafc885fe9424689ae30b11736b214be3cf9c2 (patch)
tree6082625e4bb0f59d1a3b0a9e241c03eb4170d553 /nixos/modules/tasks/kbd.nix
parent1848bfc92d247feff132f92b5580613eec9419d3 (diff)
parent9e48baa716f17385b4850377f11e16c33d75cac1 (diff)
downloadnixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar.gz
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar.bz2
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar.lz
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar.xz
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.tar.zst
nixlib-d9aafc885fe9424689ae30b11736b214be3cf9c2.zip
Merge branch 'early-kbd' into staging
Diffstat (limited to 'nixos/modules/tasks/kbd.nix')
-rw-r--r--nixos/modules/tasks/kbd.nix94
1 files changed, 73 insertions, 21 deletions
diff --git a/nixos/modules/tasks/kbd.nix b/nixos/modules/tasks/kbd.nix
index dd89804d43a7..8cdd34ef174c 100644
--- a/nixos/modules/tasks/kbd.nix
+++ b/nixos/modules/tasks/kbd.nix
@@ -5,8 +5,21 @@ with lib;
 let
 
   makeColor = n: value: "COLOR_${toString n}=${value}";
+  makeColorCS =
+    let positions = [ "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" ];
+    in n: value: "\033]P${elemAt position n}${value}";
   colors = concatImapStringsSep "\n" makeColor config.i18n.consoleColors;
 
+  isUnicode = hasSuffix "UTF-8" (toUpper config.i18n.defaultLocale);
+
+  optimizedKeymap = pkgs.runCommand "keymap" {
+    nativeBuildInputs = [ pkgs.kbd ];
+  } ''
+    cd ${kbdEnv}/share/keymaps
+    loadkeys -b ${optionalString isUnicode "-u"} "${config.i18n.consoleKeyMap}" > $out
+  '';
+
+  # Sadly, systemd-vconsole-setup doesn't support binary keymaps.
   vconsoleConf = pkgs.writeText "vconsole.conf" ''
     KEYMAP=${config.i18n.consoleKeyMap}
     FONT=${config.i18n.consoleFont}
@@ -44,36 +57,75 @@ in
       '';
     };
 
+    boot.earlyVconsoleSetup = mkOption {
+      default = false;
+      type = types.bool;
+      description = ''
+        Enable setting font and keymap as early as possible (in initrd).
+      '';
+    };
+
   };
 
 
   ###### implementation
 
   config = mkMerge [
-    (mkIf (!setVconsole) {
+    (mkIf (!setVconsole || (setVconsole && config.boot.earlyVconsoleSetup)) {
       systemd.services."systemd-vconsole-setup".enable = false;
     })
 
-    (mkIf setVconsole {
-      environment.systemPackages = [ pkgs.kbd ];
-
-      # Let systemd-vconsole-setup.service do the work of setting up the
-      # virtual consoles.
-      environment.etc."vconsole.conf".source = vconsoleConf;
-      # Provide kbd with additional packages.
-      environment.etc."kbd".source = "${kbdEnv}/share";
-
-      # This is identical to the systemd-vconsole-setup.service unit
-      # shipped with systemd, except that it uses /dev/tty1 instead of
-      # /dev/tty0 to prevent putting the X server in non-raw mode, and
-      # it has a restart trigger.
-      systemd.services."systemd-vconsole-setup" =
-        { wantedBy = [ "multi-user.target" ];
-          before = [ "display-manager.service" ];
-          after = [ "systemd-udev-settle.service" ];
-          restartTriggers = [ vconsoleConf kbdEnv ];
-        };
-    })
+    (mkIf setVconsole (mkMerge [
+      { environment.systemPackages = [ pkgs.kbd ];
+
+        # Let systemd-vconsole-setup.service do the work of setting up the
+        # virtual consoles.
+        environment.etc."vconsole.conf".source = vconsoleConf;
+        # Provide kbd with additional packages.
+        environment.etc."kbd".source = "${kbdEnv}/share";
+      }
+
+      (mkIf (!config.boot.earlyVconsoleSetup) {
+        # This is identical to the systemd-vconsole-setup.service unit
+        # shipped with systemd, except that it uses /dev/tty1 instead of
+        # /dev/tty0 to prevent putting the X server in non-raw mode, and
+        # it has a restart trigger.
+        systemd.services."systemd-vconsole-setup" =
+          { wantedBy = [ "sysinit.target" ];
+            before = [ "display-manager.service" ];
+            after = [ "systemd-udev-settle.service" ];
+            restartTriggers = [ vconsoleConf kbdEnv ];
+          };
+      })
+
+      (mkIf config.boot.earlyVconsoleSetup {
+        boot.initrd.extraUtilsCommands = ''
+          mkdir -p $out/share/consolefonts
+          ${if substring 0 1 config.i18n.consoleFont == "/" then ''
+            font="${config.i18n.consoleFont}"
+          '' else ''
+            font="$(echo ${kbdEnv}/share/consolefonts/${config.i18n.consoleFont}.*)"
+          ''}
+          if [[ $font == *.gz ]]; then
+            gzip -cd $font > $out/share/consolefonts/font.psf
+          else
+            cp -L $font $out/share/consolefonts/font.psf
+          fi
+        '';
+
+        boot.initrd.preLVMCommands = mkBefore ''
+          kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console
+          printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console
+          loadkmap < ${optimizedKeymap}
+
+          setfont -C /dev/console $extraUtils/share/consolefonts/font.psf
+
+          ${concatImapStringsSep "\n" (n: color: ''
+            printf "${makeColorCS n color}" >> /dev/console
+          '') config.i18n.consoleColors}
+        '';
+      })
+    ]))
   ];
 
 }