en pt

Debian 9.1 (stretch) with proprietary nvidia-driver and uvesafb

2017-08-12 6 min read English Howto Ricardo

So it’s 2017 and I can’t believe I had to get my hands this dirty to put this to work, but it finally works: I have high resolution text console while using the proprietary nvidia-driver! Don’t get me wrong: the steps are easy, but the mere fact I had to do this is what annoys me. Why don’t the proprietary nvidia-drivers deliver a beautiful framebuffer console out-of-the-box like nouveau does? Anyway…

If you got to this post, chances are you have done your fair share of searches, tried different suggestions from many different Forums and/or Stack Overflow answers but is still strugling. Also, if you know what this post is related to, chances are you actually need/want a framebuffer console, so I assume you can get around the console and editing system files. That being said, I’ll keep this tutorial very straightforward and not get into many details explaining how to do basic stuff.

Well let’s get to it, then!

NOTE:

I usually do these things on a root console, so you won’t see me use sudo on my commands. If you don’t feel comfortable doing that, just remember to put sudo before every command you see here.

Commands have dark background and begin with a # indicating that I’m on a root shell. Anything else is either the output of a command or the content of a file and have white background.

You’ll need two packages: v86d and hwinfo. Since this tutorial is for Debian:

# apt update
# apt install v86d hwinfo -y

After that, run:

# hwinfo --framebuffer

The output in my case was:

 1# hwinfo --framebuffer
 202: None 00.0: 11001 VESA Framebuffer
 3[Created at bios.459]
 4Unique ID: rdCR.XCOohx2LF9A
 5Hardware Class: framebuffer
 6Model: "NVIDIA GP104 Board"
 7Vendor: "NVIDIA Corporation"
 8Device: "GP104 Board"
 9SubVendor: "NVIDIA"
10SubDevice:
11Revision: "Chip Rev"
12Memory Size: 16 MB
13Memory Range: 0xd1000000-0xd1ffffff (rw)
14Mode 0x0301: 640x480 (+640), 8 bits
15Mode 0x0303: 800x600 (+800), 8 bits
16Mode 0x0305: 1024x768 (+1024), 8 bits
17Mode 0x0307: 1280x1024 (+1280), 8 bits
18Mode 0x0311: 640x480 (+1280), 16 bits
19Mode 0x0312: 640x480 (+2560), 24 bits
20Mode 0x0314: 800x600 (+1600), 16 bits
21Mode 0x0315: 800x600 (+3200), 24 bits
22Mode 0x0317: 1024x768 (+2048), 16 bits
23Mode 0x0318: 1024x768 (+4096), 24 bits
24Mode 0x031a: 1280x1024 (+2560), 16 bits
25Mode 0x031b: 1280x1024 (+5120), 24 bits
26Mode 0x0345: 1600x1200 (+1600), 8 bits
27Mode 0x0346: 1600x1200 (+3200), 16 bits
28Mode 0x034a: 1600x1200 (+6400), 24 bits
29Mode 0x034b: 3840x2160 (+3840), 8 bits
30Mode 0x034c: 3840x2160 (+7680), 16 bits
31Config Status: cfg=new, avail=yes, need=no, active=unknown

Take note of the resolution and color depth you want for your console. Even though my screen is 3840x2160 (4K) I went with a combination of 1600x1200-16 for GRUB (line 27) and 3840x2160-16 for the console itself (line 30). For the console I applied a bigger font so I could actually go with the native resolution for my screen. More on this later, keep reading!

Next step is to create a new file and edit two existing ones.

First of all, create the file /etc/initramfs-tools/conf.d/splash with the following content:

FRAMEBUFFER=y

Next, edit /etc/initramfs-tools/modules and append this, but with the resolution you chose for your console. In my case:

# List of modules that you want to include in your initramfs.
# They will be loaded at boot time in the order below.
#
# Syntax:  module_name [args ...]
#
# You must run update-initramfs(8) to effect this change.
#
# Examples:
#
# raid1
# sd_mod
uvesafb mode_option=3840x2160-16 mtrr=3 scroll=ywrap

Now let’s set the configuration on the GRUB file both for the Kernel and for GRUB itself. Edit the file /etc/default/grub and look for the highlighted lines below. Input the info as you see, respecting the resolution you chose for GRUB and the one for the Linux Console.

 1# If you change this file, run 'update-grub' afterwards to update
 2# /boot/grub/grub.cfg.
 3# For full documentation of the options in this file, see:
 4#   info -f grub -n 'Simple configuration'
 5
 6GRUB_DEFAULT=0
 7GRUB_TIMEOUT=5
 8GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
 9GRUB_CMDLINE_LINUX_DEFAULT="quiet"
10GRUB_CMDLINE_LINUX="video=uvesafb:mode_option=3840x2160-16,mtrr=3,scroll=ywrap"
11GRUB_BACKGROUND="/usr/share/wallpapers/asus_rog.png"
12
13# Uncomment to enable BadRAM filtering, modify to suit your needs
14# This works with Linux (no patch required) and with any kernel that obtains
15# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
16#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
17
18# Uncomment to disable graphical terminal (grub-pc only)
19#GRUB_TERMINAL=console
20
21# The resolution used on graphical terminal
22# note that you can use only modes which your graphic card supports via VBE
23# you can see them in real GRUB with the command `vbeinfo'
24# GRUB_GFXMODE=3840x2160x16
25GRUB_GFXMODE=1600x1200x16
26GRUB_GFXPAYLOAD_LINUX=3840x2160x16
27
28# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
29#GRUB_DISABLE_LINUX_UUID=true
30
31# Uncomment to disable generation of recovery mode menu entries
32#GRUB_DISABLE_RECOVERY="true"
33
34# Uncomment to get a beep at grub start
35#GRUB_INIT_TUNE="480 440 1"

Line 10 is for the Kernel, instructing it to use uvesafb and giving it the same parameters we put on the initramfs file before.

Line 25 is the resolution for the GRUB screen itself (where you choose the operating system to boot). As I previously said, I went with 1600x1200 (16 bits) because it looks better for me (and for some reason 24 bits didn’t work here and it fallback to VESA 640x480). Choose whatever you want, based on what is available at your system.

Line 26 is the resolution GRUB will apply when handing control over to Linux. Keep in mind that many tutorials about improving the console resolution will tell you to use keep on this parameter. That is for when you want to use the same resolution you put on GRUB_GFXMODE.

Attention: note that the syntax for uvesafb both on the initramfs file and on line 10 above use a dash to separate the resolution and color depth, while on GRUB_GFXMODE and GRUB_GFXPAYLOAD_LINUX you must use x.

Ok, now that we must instruct initramfs and GRUB that those files were modified. To do this, run:

# update-initramfs -k all -u
# update-grub2

Output will be something like this, depending on your Kernel version, operating systems you have installed on your computer and other GRUB settings, so bare in mind your mileage may vary:

# update-initramfs -k all -u
update-initramfs: Generating /boot/initrd.img-4.9.0-3-amd64

# update-grub2
Generating grub configuration file ...
Found background: /usr/share/wallpapers/asus_rog.png
Found background image: /usr/share/wallpapers/asus_rog.png
Found linux image: /boot/vmlinuz-4.9.0-3-amd64
Found initrd image: /boot/initrd.img-4.9.0-3-amd64
Found Windows 10 on /dev/nvme0n1p1
done

And that’s it. You can go on and reboot and see both GRUB and your text console with high resolution!

But before I consider this tutorial finished, let me give you a tip if you also used a very high resolution on your console like I did and now you have tiny fonts there: to solve this, reconfigure your console and tell it to use a different, bigger font.

To do that, run:

# dpkg-reconfigure console-setup

Given I am using 3840x2160 on the text console, here is my suggestion for answers to the questions you’ll be asked when running above command in case you use the same resolution:

  • Encoding to use on the console: UTF-8
  • Character set to support: Latin1 and Latin5  (choose what fits your case best)
  • Font for the console: TerminusBold
  • Font size: 12x24 (framebuffer only)

Settings are applied immediately. Enjoy! 😎