Skip to content
Navid Mafi edited this page Aug 17, 2026 · 18 revisions

On-screen Keyboard

Most distros currently don't include an onscreen keyboard in initramfs for the disk encryption passphrase dialog. The Microsoft-provided OSK that one might encounter in the UEFI Configuration/EFI Shell does not carry over beyond the EFI environment and it will be the job of initramfs to provide one.

You can use the unl0kr module included in BuffyBox from postmarketOS to set this up:

  • Back up your current /boot/initramfs-*.img files in case this doesn't work first try to be able to edit your cmdline on GRUB before boot and recover.
  • Install the unl0kr package from your distribution repositories. It provides /usr/bin/unl0kr, /usr/bin/unl0kr-agent, and initcpio hooks and install scripts.
  • Modify /etc/mkinitcpio.conf and include either sd-unl0kr or unl0kr depending on whether you use sd-encrypt or encrypt, respectively, before filesystems. For example:
HOOKS=( base systemd autodetect microcode modconf block keyboard sd-encrypt sd-unl0kr filesystems )
  • Make sure you include the corresponding required kernel modules required for touch support on your device in the MODULES line of your configuration.
# This list is not exhaustive. Solely an starting point:
MODULES=( hid_multitouch i2c_hid i2c_hid_acpi <...and keyboard modules. don't lock yourself out!> )
  • Rebuild your initramfs image (by running mkinitcpio -P or whatever else your distro provides) and reboot.

More information: https://github.com/linux-surface/linux-surface/issues/400 and https://github.com/linux-surface/linux-surface/issues/1001

Input via the Surface Aggregator Module

On devices where the keyboard is connected via the Surface Aggregator Module, i.e. the Surface Laptop 1, 2, 3, and 4, the Surface Book 3, as well as the Surface Laptop Studio, you need to ensure that the required drivers are included in the initramfs/initrd.

To do this, you need to ensure that the following modules are included in the initramfs/initrd (e.g. by editing mkinitcpio.conf or alike depends on your used OS distribution):

  • surface_aggregator, surface_aggregator_registry, surface_aggregator_hub, surface_hid_core
  • 8250_dw (required for communication with the embedded controller)

Depending on your Surface model:

  • surface_hid (Surface Laptop 3/Surface Book 3 and later)
  • surface_kbd (Surface Laptop 1 and 2).

Depending on whether GPIO support was compiled into your kernel, you may also need to include the following module (this module should be listed before the above modules):

  • pinctrl_amd (only on the AMD models)
  • intel_lpss and intel_lpss_pci (only on the Intel models)
  • pinctrl_icelake for Ice Lake Intel CPUs (Surface Laptop 3/Surface Book 3)
  • pinctrl_tigerlake for Tiger Lake Intel CPUs or later (Surface Laptop 4/Surface Laptop Studio/Surface Laptop Studio 2)

Example for adding input drivers to Fedora 41 (run as root):

# this will create a file with parameters for adding modules to initramfs
# from this below, replace list of your modules inside below double-quoted text, and using space for separate each modules, and then finally prefixed with `add_drivers+=\" ` and suffixed with `\" ` to break the double quote
echo "add_drivers+=\" surface_aggregator surface_aggregator_registry surface_hid_core surface_hid surface_aggregator_hub \"" > /etc/dracut.conf.d/surface.conf
# this rebuilds the initramfs for all kernel version
dracut --force --regenerate-all

Example for adding input drivers to Fedora 35 (run as root):

# this will create a file with parameters for adding modules to initramfs
# from this below, replace list of your modules inside below double-quoted text, and using space for separate each modules, and then finally prefixed with `add_drivers+=\042 ` and suffixed with `\042 `
echo "add_drivers+=\042 surface_hid_core surface_hid surface_aggregator_registry surface_aggregator \042 " > /etc/dracut.conf.d/surface.conf
# this rebuilds the initramfs for all kernel version
dracut --force --regenerate-all

Example for adding input drivers to Debian (run as root):

# this will add required modules to initramfs-tools module list
# from this below, replace list of your modules inside below double-quoted text, and using `\n` for separate each modules
echo -e "8250_dw\nsurface_hid_core\nsurface_hid\nsurface_aggregator_registry\nsurface_aggregator_hub\nsurface_aggregator" >> /etc/initramfs-tools/modules
# this rebuilds the initramfs for all kernel version
update-initramfs -u -k all

It is important to remember that all manipulations to rebuild initramfs and add surface modules are done on a system booted from the linux-surface kernel.

IPTS Touch Input

Whether touchscreen support is needed in the initramfs depends on how the touchscreen is exposed by the particular Surface model. Some Surface devices (e.g. Surface Go) provide a touchscreen through a conventional HID path that is available early enough without additional initramfs configuration. Others, such as the Surface Pro series for example, use the Intel Precise Touch & Stylus (IPTS) path, where the touchscreen depends on both hardware and userspace components that must be available for touch input to properly work.

Generally, the install hook of your chosen method (e.g. unl0kr) ensures that the required IPTS kernel module, daemon, firmware, and configuration files are baked to the initramfs and initialized at the appropriate stage (and possibly cleaned up to not have duplicate virtual mapped inputs later when the kernel boots).

Clone this wiki locally