Nice booting with non-free Debian Stretch NVIDIA drivers

Nice booting with non-free Debian Stretch NVIDIA drivers

Hi again people...
So, this week I readed that, finally, NVIDIA proprietary linux drivers do enable DRM from kernel initial module load stages, and so, setting bootsplash animation during boot will no longer require legacy framebuffer tricky hacks...

Unfortunately, driver version involved seems to be from 364.12, which is definitely far even from sid's non-free NVIDIA driver version at the time of this writing (352.79)...
Therefore, realizing that there is still loooong time to wait, even using Stretch, before having drm available before reaching user space, I decided to give up and get my Stretch non-free NVIDIA driven desktop to nicely boot (so yes, I'll go framebuffer).

After noting down all the commands, file edits and so involved in the process, I will share here it all...
This covers the whole process from Grub2 background image change, plymouth bootsplash setup, lightdm background setup, and desktop-base default background setup (this last one does not refer to your session desktop background, but the one used as a kind of "default background" during session transitions, animations, some screensaving, etc...)

Gathering GPU's framebuffer capabilities info.

Remember, all this stuff is related to Debian packaged, non-free, proprietary NVIDIA drivers. If you use drivers directly downloaded from NVIDIA and installed through their script, you'll surely have up-to-date DRM kernel boot time capable drivers.
Same applies if you are using Debian default provided, open source, Nouveau alterative NVIDIA drivers: they provide DRM support from boot and all this is unnecessary!!!!

If you use non-free NVIDIA stuff... you can check your GPU detect and driver needs by using nvidia-detect packaged program:

root@santroc:/home/alex# nvidia-detect
Detected NVIDIA GPUs:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GK208 [GeForce GT 730] [10de:1287] (rev a1)

Checking card:  NVIDIA Corporation GK208 [GeForce GT 730] (rev a1)
Your card is supported by the default drivers and legacy driver series 340.
It is recommended to install the
    nvidia-driver
package.

 
And by asking to install nvidia-driver package (since I got it already installed) I got the following piece of info:

root@santroc:/home/alex# apt-get install nvidia-driver
Reading package lists... Done
Building dependency tree       
Reading state information... Done
nvidia-driver is already the newest version (352.79-10).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

 
Since we will use the legacy framebuffer capabilities of our card (since they are available from almost the very beginning of the booting process) to go beyond text and "draw" animations during boot we need to know exactly what framebuffer resolutions our hardware provides.

To do so, I'll use the already "classic" way: using hwinfo.
So, provide you don't have it installed, do so, and also the v86d BIOS code exec backend...

apt-get install hwinfo v86d

 
And, once we got it, we are ready to test.
Here is an example of what my system capabilities are (of course, probably yours may differ):

root@santroc:/home/alex# hwinfo --framebuffer
02: None 00.0: 11001 VESA Framebuffer                           
  [Created at bios.459]
  Unique ID: rdCR.Ht0VobcpMr1
  Hardware Class: framebuffer
  Model: "NVIDIA GK208 Board - 2131_0010_302"
  Vendor: "NVIDIA Corporation"
  Device: "GK208 Board - 2131_0010_302"
  SubVendor: "NVIDIA"
  SubDevice: 
  Revision: "Chip Rev"
  Memory Size: 14 MB
  Memory Range: 0xe9000000-0xe9dfffff (rw)
  Mode 0x0300: 640x400 (+640), 8 bits
  Mode 0x0301: 640x480 (+640), 8 bits
  Mode 0x0303: 800x600 (+800), 8 bits
  Mode 0x0305: 1024x768 (+1024), 8 bits
  Mode 0x0307: 1280x1024 (+1280), 8 bits
  Mode 0x030e: 320x200 (+640), 16 bits
  Mode 0x030f: 320x200 (+1280), 24 bits
  Mode 0x0311: 640x480 (+1280), 16 bits
  Mode 0x0312: 640x480 (+2560), 24 bits
  Mode 0x0314: 800x600 (+1600), 16 bits
  Mode 0x0315: 800x600 (+3200), 24 bits
  Mode 0x0317: 1024x768 (+2048), 16 bits
  Mode 0x0318: 1024x768 (+4096), 24 bits
  Mode 0x031a: 1280x1024 (+2560), 16 bits
  Mode 0x031b: 1280x1024 (+5120), 24 bits
  Mode 0x0330: 320x200 (+320), 8 bits
  Mode 0x0331: 320x400 (+320), 8 bits
  Mode 0x0332: 320x400 (+640), 16 bits
  Mode 0x0333: 320x400 (+1280), 24 bits
  Mode 0x0334: 320x240 (+320), 8 bits
  Mode 0x0335: 320x240 (+640), 16 bits
  Mode 0x0336: 320x240 (+1280), 24 bits
  Mode 0x033d: 640x400 (+1280), 16 bits
  Mode 0x033e: 640x400 (+2560), 24 bits
  Config Status: cfg=new, avail=yes, need=no, active=unknown

 
Now you have to choose one of those resolutions.
If necessary, note it down, since all the following configs will adapt to it.
It is important to note the color depth too...

Consider your main screen capabilities, and choose the one you prefer.
In this post I'll show the one I chose: 1280x1024 at 24bit color depth.
It is the best 16:9 resolution it offers to me, and fits in my 1680x1050 screen.

Customize Grub2 background

This is the very first thing we see, so I'll go for it first.

By default, Grub2 background image for desktop-enabled Debian Stretch is the one we see in Jessie...
Changing it is very easy, but, to do it even easier, we can install the grub2-splashimages package that provides a set of nice .tga background files in /usr/share/images/grub ready to go, so we do not need to care about correct format and size images, file paths or permissions.

apt-get install grub2-splashimages

 
Now, edit grub configuration by editing /etc/default/grub file, and add (by default, there is none) or edit the GRUB_BACKGROUND stanza.
Theoretically, you may point it to whatever image file in the filesystem of your liking, issuing its absolute path, but read Grub2 documentation relating to supported file formats, sizes, resolutions and so, or it may not work.

My /etc/default/grub, for instance, has the following added GRUB_BACKGROUND line (pointing to a cool Apollo 17 image provided by grub2-splashimages package):
GRUB_BACKGROUND="/usr/share/images/grub/Apollo_17_The_Last_Moon_Shot_Edit1.tga"

 
Finally, apply changes on config file by issuing either update-grub or update-grub2 commands (update-grub is a link to update-grub2 both residing in /usr/sbin):

root@santroc:/home/alex# update-grub
Generating grub configuration file ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-4.6.0-1-amd64
Found initrd image: /boot/initrd.img-4.6.0-1-amd64
Found linux image: /boot/vmlinuz-4.5.0-2-amd64
Found initrd image: /boot/initrd.img-4.5.0-2-amd64
Found Windows 7 (loader) on /dev/sda1
done

 
...you're done, you'll enjoy your new grub2 background upon next boot.

Adding booting animation with Plymouth

This is the second thing we see after Grub2 goes by and our Debian system loads. So, if we want to replace the text kernel messages by a cool animation (what is commonly refered as "bootsplash") there are several options, but mainly, we end up in plymouth

Although plymouth is more than just a bootsplash enabling program, its main usage and interest is just that.
Debian includes it in its repository, along with several, ready to use animations or "themes". So, we proceed with installing:

apt-get install plymouth plymouth-themes

 
Here com the most tricky part of this post.
Configuration depends system to system (NVIDIA with packaged non-free drivers in our case), and even involves choosing a resolution from several possibilities, so Debian maintainers do not try to add autoconfigure scripts with plymouth... it is up to the system admin, knowing its system, to do so.

Since animation shows precisely as the system loads, it means that there should be enough graphic support at that stage to show an animation on screen.
This involves our graphic card to provide support beyond the very basic VESA/VGA standard support it provides at early power-on (for instance, to go into BIOS, or to see BIOS boot messages or Grub2 later).

A common solution to this is to use Direct Rendering capabilities of GPU cards through the Direct Rendering Manager that is supported as kernel modules early load in boot. But, as commented earlier in this post, and unlike ATI's or Intel's cards (or Nouveau driven NVIDIA cards) we will still not have DRM at that stage of boot, since DRM is available too late for us in the boot process... We will need to circumvent this.
The solution is technically not elegant (implies loading two drivers on the same card) but works... It consists on using the following strategy:

  1. Enable animation drawing to our card by using its framebuffer capabilities when it is in its legacy VESA mode in early booting (initramfs) stages... to do so, we will include a parametrized (resolution, color, etc) loading of the uvesafb module in initramfs configuration.
  2. We will take profit of this by modifying booting parameters of our system kernel accordingly, so we will need to modify grub2.
  3. With our kernel booting with adequate options (including splash option that will try to use plymouth), We just need to configure plymouth with our preferred theme.

Remember, in the examples bellow, you'll see 1280x1024 or 24 since this is the resolution and color depth I chose. Be careful: Do not forget to adapt the examples to your real values!

Step 1.

We will edit /etc/initramfs-tools/modules file and add the following line:

uvesafb mode_option=1280x1024-24 mtrr=3 scroll=ywrap

 
Here is we are instructing to add this kernel module, and with a correct setup, in the initramfs image.
Also, create or modify /etc/initramfs-tools/conf.d/splash file and add the following line:

FRAMEBUFFER=y

 
This instructs the usage of framebuffer to draw the splash animation.

Step 2.

We will edit grub configuration in /etc/default/grub.
Look for the parameter GRUB_CMDLINE_LINUX_DEFAULT and modify it by adding the splash nomodeset key words followed by video config parameters, be carefull, video parameters go unspaced... here's how mine looks like:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash nomodeset video=uvesafb:mode_option=1280x1024-24,mtrr=3,scroll=ywrap"

 
Look for the parameter (or add it, or comment it out) GRUB_GFXMODE and, again, tune it to your chosen resolution. So, the resulting line would look like this:

GRUB_GFXMODE=1280x1024

 
Done with the Grub2 part.

Step 3.

Take a look at the available themes list by executing the plymouth-set-default-theme command with just the --list modifier, like so:

root@santroc:/home/alex# plymouth-set-default-theme --list
details
fade-in
glow
joy
lines
script
solar
spacefun
spinfinity
spinner
text
tribar

 
You can google around to see how every single theme looks like... I prefer "solar" theme, so I configure plymouth with solar them like this:

root@santroc:/home/alex# plymouth-set-default-theme solar

 
Finally, we need to update initramfs and grub from their modified config files, this is done with the update-grub command and the umpdate-initramfs command, like this:

root@santroc:/home/alex# update-grub
Generating grub configuration file ...
Found background image: /usr/share/images/desktop-base/desktop-grub.png
Found linux image: /boot/vmlinuz-4.6.0-1-amd64
Found initrd image: /boot/initrd.img-4.6.0-1-amd64
Found linux image: /boot/vmlinuz-4.5.0-2-amd64
Found initrd image: /boot/initrd.img-4.5.0-2-amd64
Found Windows 7 (loader) on /dev/sda1
done
root@santroc:/home/alex# update-initramfs -u
update-initramfs: Generating /boot/initrd.img-4.6.0-1-amd64
root@santroc:/home/alex#

 
Done! now upon next reboot you should have your boot splash working.

Customize LightDM login screen background

Continuing the start-up sequence on our system, after booting, we expect to reach a cool login screen.
Since I don't like heavy stuff I use lightdm session manager wherever I can, and here's how easy is to change its background.

Being lightdm a system process, I would recommend, once you choose what background image you like (consider its size, format, and so on) or a collection of images, to copy it/them as root to /usr/share/images/desktop-base folder, since there is where such kind of stuff is stored in our Debian installation.
Also, check proper ownership and permissions and set them accordingly if necessary.

Then, you just need to edit /etc/lightdm/lightdm-gtk-greeter.conf config file.
Look for a [Greeter] section, and look inside for the background config item.
Comment it out and give it as value the full path to your selected image file... mine looks like this

....
[greeter]
background=/usr/share/images/desktop-base/lightdm_backgrund1.jpg
....

 
That's it... provide the chosen file is valid and reachable, you'll get rid of the old Debian Jessie's "joy-wallpaper" background on Debian Stretch.

Setting desktop-base default background

It is quite annoying that, having your lightdm background changed, you still see Debian 8 default background for a moment after login, just before your desktop background loads.
Same applies in several moments, and, in general, depends on how fast your system is. On non SSD driven systems it is easy to see the Default Debian 8 background occasionaly, during login, logout, after sleep, etc...

This is caused by the fact that, although users desktop session background takes preference, the "default" background to show is still unchanged, and set at the default image.

To change it, we should use Debian update-alternatives facility. First, we will see what available backgrounds do we have by using the --list modifier against desktop-background:

root@santroc:/home/alex# update-alternatives --list desktop-background
/usr/share/images/desktop-base/joy-inksplat-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/joy-wallpaper_1280x1024.svg
/usr/share/images/desktop-base/joy-wallpaper_1600x1200.svg
/usr/share/images/desktop-base/joy-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/joy-wallpaper_1920x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_1280x1024.svg
/usr/share/images/desktop-base/lines-wallpaper_1600x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/lines-wallpaper_1920x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_2560x1080.svg
/usr/share/images/desktop-base/moreblue-orbit-wallpaper-widescreen.svg
/usr/share/images/desktop-base/moreblue-orbit-wallpaper.svg
/usr/share/images/desktop-base/spacefun-wallpaper-widescreen.svg
/usr/share/images/desktop-base/spacefun-wallpaper.svg

 
As you see, /usr/share/images/desktop-base is the system folder where desktop-base background files are expected to be.
As root, copy there your background file/es, and adjust ownership and permissions accordingly.

If you have already put files there, chances are that they do not appear on the list. This is because we have to make update-alternatives aware of the new files, updating it with the --install command.
If, for example, you added a file background1.jpg, you have to issue the following command:

update-alternatives --install /usr/share/images/desktop-base/desktop-background desktop-background /usr/share/images/desktop-base/background1.jpg 65

 
It basically registers /usr/share/images/desktop-base/background1.jpg as a link candidate to /usr/share/images/desktop-base/desktop-background file, for the desktop-backgroud facility, with a priority of 65 (but you could use any other number).
So, if we do list again:

root@santroc:/home/alex# update-alternatives --list desktop-background
/usr/share/images/desktop-base/background1.jpg
/usr/share/images/desktop-base/joy-inksplat-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/joy-wallpaper_1280x1024.svg
/usr/share/images/desktop-base/joy-wallpaper_1600x1200.svg
/usr/share/images/desktop-base/joy-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/joy-wallpaper_1920x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_1280x1024.svg
/usr/share/images/desktop-base/lines-wallpaper_1600x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_1920x1080.svg
/usr/share/images/desktop-base/lines-wallpaper_1920x1200.svg
/usr/share/images/desktop-base/lines-wallpaper_2560x1080.svg
/usr/share/images/desktop-base/moreblue-orbit-wallpaper-widescreen.svg
/usr/share/images/desktop-base/moreblue-orbit-wallpaper.svg
/usr/share/images/desktop-base/spacefun-wallpaper-widescreen.svg
/usr/share/images/desktop-base/spacefun-wallpaper.svg

 
Now, we need to use the --config modifier to use update-alternatives interactive selection menu. We will simply need to type the number at the bottom prompt, that corresponds to the list item we want to select, and press ENTER.
An asterisk at the left marks the currently selected item.
In this case, it is showing the default background is selected at item 5, but I'm selecting item number 1 at the prompt, since 1 corresponds to my custom background:

root@santroc:/home/alex# update-alternatives --config desktop-background
There are 15 choices for the alternative desktop-background (providing /usr/share/images/desktop-base/desktop-background).

  Selection    Path                                                                       Priority   Status
------------------------------------------------------------
  0            /usr/share/images/desktop-base/lines-wallpaper_1920x1080.svg               70        auto mode
  1            /usr/share/images/desktop-base/background1.jpg                             65        manual mode
  2            /usr/share/images/desktop-base/joy-inksplat-wallpaper_1920x1080.svg        60        manual mode
  3            /usr/share/images/desktop-base/joy-wallpaper_1280x1024.svg                 60        manual mode
  4            /usr/share/images/desktop-base/joy-wallpaper_1600x1200.svg                 60        manual mode
* 5            /usr/share/images/desktop-base/joy-wallpaper_1920x1080.svg                 60        manual mode
  6            /usr/share/images/desktop-base/joy-wallpaper_1920x1200.svg                 60        manual mode
  7            /usr/share/images/desktop-base/lines-wallpaper_1280x1024.svg               65        manual mode
  8            /usr/share/images/desktop-base/lines-wallpaper_1600x1200.svg               65        manual mode
  9            /usr/share/images/desktop-base/lines-wallpaper_1920x1080.svg               70        manual mode
  10           /usr/share/images/desktop-base/lines-wallpaper_1920x1200.svg               65        manual mode
  11           /usr/share/images/desktop-base/lines-wallpaper_2560x1080.svg               65        manual mode
  12           /usr/share/images/desktop-base/moreblue-orbit-wallpaper-widescreen.svg     40        manual mode
  13           /usr/share/images/desktop-base/moreblue-orbit-wallpaper.svg                40        manual mode
  14           /usr/share/images/desktop-base/spacefun-wallpaper-widescreen.svg           50        manual mode
  15           /usr/share/images/desktop-base/spacefun-wallpaper.svg                      50        manual mode

Press <enter> to keep the current choice[*], or type selection number: 1
update-alternatives: using /usr/share/images/desktop-base/background1 to provide /usr/share/images/desktop-base/desktop-background (desktop-background) in manual mode

 
So... that's all folks.
This is what I'm using to have my Stretch driven NVIDIA PCs fully customized, hope it may be useful to someone else!