Hi,

I have had this font loading problem with all versions of Debian since
version 9. I have seen the font selected in '/etc/default/console-setup'
be loaded on a very few system boots when using a normal kernel, but never
when using a PREEMPT_RT kernel [in real hardware, not VMs]. I have also
confirmed that whenever the plymouth package is installed and the system
is configured to boot with the graphical boot splash, the selected font
can not be loaded while the splash is visible, but can be loaded if the
splash is hidden for a small period of time (just enough for setfont to
work it's magic).

In my humble opinion, there are two main reasons that cause the font
loading problem:

1) The rules implemented in file '/lib/udev/rules.d/90-console-setup.rules'
   violate one of the udev conditions for the RUN assignment option as
   expressed in the udev manpage:

   --- content of file '/lib/udev/rules.d/90-console-setup.rules' ---
   ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon*",
RUN+="/etc/console-setup/cached_setup_font.sh"
   ACTION=="add", SUBSYSTEM=="vc", KERNEL=="vcs[1-9]|vcs[1-9][0-9]",
TEST=="/run/console-setup/font-loaded",
RUN+="/etc/console-setup/cached_setup_terminal.sh %k"
   --- end of content ---

   --- extract from the udev manpage (Debian 9) ---
   (...)
   RUN{type}
   (...)
   This can only be used for very short-running foreground tasks.
   (...)
   Starting daemons or other long-running processes is not appropriate for udev;
   the forked processes, detached or not, will be unconditionally killed
   (...)
   --- end of extract ---

   --- extract from udev manpage (Debian 12) ---
   (...)
   RUN{type}
   (...)
   This can only be used for very short-running foreground tasks.
   (...)
   Starting daemons or other long-running processes is not allowed; the forked
   processes, detached or not, will be unconditionally killed
   (...)
   In order to activate long-running processes from udev rules,
provide a service unit
   (...)
   --- end of extract ---

   The usual solution for this is to create a systemd service to run
   the script.

2) The script that loads the font is started at inconvenient times, like
   when the plymouth daemon is showing the graphical boot splash. This
   can only be resolved with a dependency based solution like systemd
   provides, which would only load the font after the plymouth daemon
   finished (meaning after 'plymouth-quit-wait.service') and before the
   first instance of getty started (meaning before 'getty@tty1.service'
   started and 'getty.target' is reached). Such solution would not,
   however, be appropriate for people that have encrypted volumes,
   because the prompt for the encryption password is displayed early in
   the boot process, in the initramfs stage.

========================================================================
To attempt to solve these problems, I recently developed a solution based
on two initramfs-tools scripts, which I attached to this e-mail:
========================================================================

   - File 'etc-initramfs_tools-hooks-font.sh' contains the script to be
     executed in the hooks stage of the initramfs-tools, when doing an
     'update-initramfs';

   - File 'etc-initramfs_tools-scripts-font.sh' contains the script to
     be executed in the scripts stage of the initramfs image, when the
     system is booting.

==============================================
Follow the steps below to install the scripts:
==============================================

0) Download the scripts to a temp directory you have created. Lets assume
   it is '/tmp/scripts'. Make sure that the preferred font has been selected
   in file '/etc/default/console-setup'. For this example, lets assume
   it is the Terminus Bold 20x10 font. In this case, the contents of
   the file '/etc/default/console-setup' should look like:

   --- contents of file '/etc/default/console-setup' ---
   ACTIVE_CONSOLES="/dev/tty[1-6]"
   CHARMAP="UTF-8"
   CODESET="Lat15"
   FONTFACE="TerminusBold"
   FONTSIZE="20x10"
   VIDEOMODE=
   --- end of file contents ---

   IMPORTANT: Before changing the initramfs image that is used to boot
   the system, make sure you have an alternative way of booting the
   system, like a Debian Live CD/DVD or USB pen drive, or another
   kernel installed in the system.

1) Install first file 'etc-initramfs_tools-hooks-font.sh' to the 'hooks'
   directory of initramfs-tools:
$ sudo cp etc-initramfs_tools-hooks-font.sh /etc/initramfs-tools/hooks/font
$ sudo chmod 755 /etc/initramfs-tools/hooks/font

2) Install the second file 'etc-initramfs_tools-scripts-font.sh' to the
   'scripts/init-top' directory of initramfs-tools:
$ sudo cp etc-initramfs_tools-scripts-font.sh
/etc/initramfs-tools/scripts/init-top/font
$ sudo chmod 755 /etc/initramfs-tools/scripts/init-top/font

3) Update the initramfs image for your currently booted kernel:
$ sudo update-initramfs -u -k $(uname -r)

   --- example output of command above ---
   update-initramfs: Generating /boot/initrd.img-4.19.0-0.bpo.19-rt-amd64
   W: mdadm: /etc/mdadm/mdadm.conf defines no arrays.
   W: Plymouth graphical boot splash is enabled at boot.
   While the boot splash is visible, it is impossible to set a custom
console font. The font used is, in this case, selected by the plymouth
theme. The custom font loader script tries to hide the boot splash for
a small period of time so that a font can be loaded, but this may
fail.
   You can disable the boot splash by changing the kernel command line
with one of the options below:
       (a) Remove the word 'splash';
       (b) Replace 'splash' with 'nosplash';
       (c) Replace 'splash' with 'plymouth.enable=0';
   If none of these options work, check the plymouth docs for help.
   I: setupcon has already updated the console-setup font cache files
   N: You can force a font cache update by running the command 'touch
/etc/default/console-setup'.
   W: cached font file
'/etc/console-setup/cached_Lat15-TerminusBold20x10.psf.gz' is older
than '/etc/default/console-setup'
   N: cached font file
'/etc/console-setup/cached_Lat15-TerminusBold20x10.psf.gz' will be
installed to the initramfs
   --- end of example output ---

   NOTE: If successfull, this command should output the name of the
   console-setup cached font file selected for installation in the
   initramfs image. In the above example, for Debian 9.13 using a
   backports kernel 4.19, the selected font file was
   '/etc/console-setup/cached_Lat15-TerminusBold20x10.psf.gz'. The
   message about the font file being older than '/etc/default/console-setup'
   is because of a bug in this version of console-setup (1.164) that does
   not always update the font file.

4) Confirm that the required files have been installed to the initramfs image:
$ lsinitramfs /boot/initrd.img-$(uname -r) | less

   You need to check that the binary 'setfont', the script named 'font',
   and the console-setup cached font file that was selected in step 3 are
   listed in the initramfs image. The output of the command above should
   look similar to:

   --- example output of 'lsinitramfs /boot/initrd.img-$(uname -r) | less' ---
   kernel
   kernel/x86
   kernel/x86/microcode
   kernel/x86/microcode/.enuineIntel.align.0123456789abc
   kernel/x86/microcode/GenuineIntel.bin
   .
   bin
   (...)
   bin/plymouth
   (...)
   bin/setfont
   (...)
   etc/console-setup
   etc/console-setup/cached_Lat15-TerminusBold20x10.psf.gz
   (...)
   sbin/plymouthd
   (...)
   bin/gzip
   bin/gunzip
   (...)
   scripts/init-top/udev
   (...)
   scripts/init-top/keymap
   scripts/init-top/font
   (...)
   scripts/init-premount/plymouth
   (...)
   --- end of example output ---

   This assumes that '/etc/console-setup/cached_Lat15-TerminusBold20x10.psf.gz'
   was the console-setup cached font file selected for installation in the
   initramfs image (see the output of the command in step 3).

5) Disable the console-setup service.
   $ sudo systemctl disable console-setup.service
   $ sudo systemctl stop console-setup.service

6) Disable the console-setup udev rules that configure the
   consoles (in file '/lib/udev/rules.d/90-console-setup.rules'), by
   creating an empty file in '/etc/udev/rules.d' with the same name.
   $ sudo touch /etc/udev/rules.d/90-console-setup.rules

7) Reboot your system.
   This last step completes the installation procedures and when the
   system boots and the initramfs image is loaded, the font should be
   changed to the selected font, which in this example is
   'Terminus Bold 20x10'.

I hope that the steps are clear enough for everyone.


Best regards,

-- Pedro Dias

Attachment: etc-initramfs_tools-hooks-font.sh
Description: application/shellscript

Attachment: etc-initramfs_tools-scripts-font.sh
Description: application/shellscript

Reply via email to