Kernel mode setting

Related articles
ATI
Intel graphics
Nouveau
This article or section needs expansion.
Reason:
KMS and rootless X (1.16), see
Talk:Kernel mode setting
and
Xorg#Rootless Xorg
. (Discuss in
Talk:Kernel mode setting
)
Kernel
Mode Setting
(KMS) is a method for setting display resolution and depth in the kernel space rather than user space.
The Linux kernel's implementation of KMS enables native resolution in the framebuffer and allows for instant console (tty) switching.  KMS also enables newer technologies (such as
DRI2
) which will help reduce artifacts and increase 3D performance, even kernel space power-saving.
Note
The proprietary
NVIDIA
driver (since 364.12) also implements kernel mode-setting, but it does not use the built-in kernel implementation and a fbdev driver for the high-resolution console is only present as an opt-in experimental feature (since 545.29)
Background
Previously, setting up the video card was the job of the X server. Because of this, it was not easily possible to have fancy graphics in
virtual consoles
. Also, each time a switch from X to a virtual console was made (
Ctrl+Alt+F2
), the server had to give control over the video card to the kernel, which was slow and caused flickering. The same "painful" process happened when the control was given back to the X server (
Alt+F7
when X runs in VT7).
With Kernel Mode Setting (KMS), the kernel is now able to set the mode of the video card. This makes fancy graphics during bootup, virtual console and X fast switching possible, among other things.
Configuration
At first, note that for
any
method you use, you should
always
disable:
Any
vga=
options in your
boot loader
as these will conflict with the native resolution enabled by KMS.
Any
video=
lines that enable a framebuffer that conflicts with the driver.
This article or section is out of date.
Reason:
Arch
officially supported kernels
have
simpledrm
KMS driver inbuilt
[1]
for years now. Which means Arch users
always
have early KMS start. So this section is more about "when
simpledrm
transfers control to another driver". (Discuss in
Talk:Kernel mode setting
)
This article or section needs expansion.
Reason:
Mention
simpledrm
and its ability to work as a generic graphics driver. (Discuss in
Talk:Kernel mode setting
)
Late KMS start
Intel
,
Nouveau
,
ATI
and
AMDGPU
drivers already enable KMS automatically for all chipsets, so you do not need to do anything.
The proprietary
NVIDIA
driver supports KMS (since 364.12), which has to be
manually enabled
.
Early KMS start
Tip
If you encounter problems with the resolution, you can check whether
enforcing the mode
helps.
KMS is typically initialized after the
initramfs stage
. However, it is possible to enable KMS already during the initramfs stage. Add the required module for the
video driver
to the initramfs configuration file:
amdgpu
for
AMDGPU
, or
radeon
when using the legacy
ATI
driver.
i915
for
Intel graphics
.
nouveau
for the open-source
Nouveau
driver.
nvidia nvidia_modeset nvidia_uvm nvidia_drm
for the out-of-tree
NVIDIA
drivers. See
NVIDIA#DRM kernel mode setting
for details.
mgag200
for Matrox graphics.
Depending on
QEMU
graphics in use (
qemu
option
-vga
type
or
libvirt
<video><model type='
type
'>
[2]
):
bochs
for
std
(
qemu
) and
vga
/
bochs
(
libvirt
),
virtio-gpu
for
virtio
,
qxl
for
qxl
,
vmwgfx
for
vmware
(
qemu
) and
vmvga
(
libvirt
),
cirrus
for
cirrus
.
Depending on
VirtualBox
graphics controller:
vmwgfx
for VMSVGA,
vboxvideo
for VBoxVGA or VBoxSVGA.
Initramfs configuration instructions are slightly different depending on the initramfs generator you use.
mkinitcpio
For in-tree modules, either use
kms
in the HOOKS array in
/etc/mkinitcpio.conf
(the default since
mkinitcpio v33
) or place the module names in the MODULES array.
For the out-of-tree NVIDIA modules, you must place the module names in the MODULES array as follows:
/etc/mkinitcpio.conf
MODULES=(... nvidia nvidia_modeset nvidia_uvm nvidia_drm ...)
Note
If you use
PRIME
Graphics Processing Unit (GPU) with Intel Integrated Graphics Processors (IGP) being your primary GPU and AMD as the discrete one,
intel_agp
may lead to troubles when resuming from hibernation (monitor gets no signal). See
[3]
for details.
If you are using the
#Forcing modes and EDID
method, you should embed the custom file into
initramfs
as well:
/etc/mkinitcpio.conf
FILES=(/usr/lib/firmware/edid/
your_edid
.bin)
Then
regenerate the initramfs
.
Booster
If you use
Booster
, you can load required modules with this config change:
/etc/booster.yaml
modules_force_load: i915
If you are using the
#Forcing modes and EDID
method, you should embed the custom file into your booster images as well:
/etc/booster.yaml
extra_files: /usr/lib/firmware/edid/
your_edid
.bin
Then
regenerate the booster images
.
Dracut
Dracut
enables early loading (at the initramfs stage, via
modprobe
) through its
--force_drivers
command or
force_drivers+=""
config entry line. For example:
/etc/dracut.conf.d/myflags.conf
# ...
force_drivers+=" amdgpu "
# ...
If you are using the
#Forcing modes and EDID
method, you should embed the custom file as well:
/etc/dracut.conf.d/myflags.conf
install_items+=" /usr/lib/firmware/edid/
your_edid
.bin "
Then
regenerate the dracut images
.
Troubleshooting
My fonts are too tiny
See
Linux console#Fonts
for how to change your console font to a large font. The Terminus font (
terminus-font
) is available in many sizes, such as
ter-132b
which is larger.
Alternatively,
disabling modesetting
might switch to lower resolution and make fonts appear larger.
Forcing modes and EDID
If your native resolution is not automatically configured or no display at all is detected, then your monitor might send none or just a skewed
EDID
file. The kernel will try to catch this case and will set one of the most typical resolutions.
In case you have the EDID file for your monitor, you merely need to explicitly enforce it (see below). However, most often one does not have direct access to a sane file and it is necessary to either extract an existing one and fix it or to generate a new one.
Generating new EDID binaries for various resolutions and configurations is possible during kernel compilation by following the
upstream documentation
(also see
here
for a short guide). Other solutions are outlined in details in this
article
.
Extracting an existing one is in most cases easier, e.g. if your monitor works fine under Windows, you might have luck extracting the EDID from the corresponding driver, or if a similar monitor works which has the same settings, you may use
get-edid(1)
from the
read-edid
package. You can also try looking in
/sys/class/drm/*/edid
.
After having prepared your EDID, place it in a directory, e.g. called
edid
under
/usr/lib/firmware/
and copy your binary into it.
To load it at boot, specify the following in the
kernel command line
:
drm.edid_firmware=edid/your_edid.bin
In order to apply it only to a specific connector, use:
drm.edid_firmware=VGA-1:edid/your_edid.bin
If you want to set multiple edid files, use:
drm.edid_firmware=VGA-1:edid/your_edid.bin,VGA-2:edid/your_other_edid.bin
If you are doing
early KMS
, you must
include the custom EDID file in the initramfs
, otherwise you will run into problems.
The value of the
drm.edid_firmware
parameter may also be altered after boot by writing to
/sys/module/drm/parameters/edid_firmware
:
# echo edid/your_edid.bin > /sys/module/drm/parameters/edid_firmware
This will only take effect for newly plugged in displays, already plugged-in screens will continue to use their existing EDID settings. For external displays, replugging them is sufficient to see the effect however.
To load an EDID after boot, you can use debugfs instead of a kernel command line parameter if the kernel is not in
lockdown mode
.  This is very useful if you swap the monitors on a connector or just for testing.  Once you have an EDID file as above, run:
# cat correct-edid.bin > /sys/kernel/debug/dri/0/HDMI-A-2/edid_override
And to disable:
# echo -n reset > /sys/kernel/debug/dri/0/HDMI-A-2/edid_override
If your monitor supports hotplugging, you can also trigger a hotplug to make the monitor use the new EDID you just loaded (e.g. into
edid_override
), so you don't have to physically replug the monitor nor reboot:
# echo 1 > /sys/kernel/debug/dri/0/HDMI-A-2/trigger_hotplug
Forcing modes
Note
The method described below is somehow imperfect because e.g.
Xorg
does not take into account the resolution specified, so users are encouraged to use the method described above. However, specifying resolution with
video=
command line is useful for all
Wayland compositors
.
From
the nouveau wiki
:
A mode can be forced on the kernel command line. Unfortunately, the command line option video is poorly documented in the DRM case. Bits and pieces on how to use it can be found in
https://docs.kernel.org/fb/modedb.html
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/drm_fb_helper.c
The format is:
video=<driver>:<conn>:<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
<driver>
: Specify a video mode at bootup.
<conn>
: Specifies the video connection type, such as VGA, DVI, HDMI, etc., see
/sys/class/drm/
for available connectors
<xres>
: The horizontal resolution in pixels.
<yres>
: The vertical resolution in pixels.
[M]
: Enables the use of VESA Coordinated Video Timings (CVT) to calculate the video mode timings instead of looking up the mode from a database
[R]
: Enables reduced blanking calculations for digital displays when using CVT. This reduces the horizontal and vertical blanking intervals to save bandwidth.
[-<bpp>]
: Specifies the color depth or bits per pixel (e.g., -24 for 24-bit color).
[@<refresh>]
: Specifies the refresh rate in Hz.
[i]
: Enables interlaced mode.
[m]
: Adds margins to the CVT calculation (1.8% of xres rounded down to 8 pixels and 1.8% of yres)
[e]
: output forced to on
[D]
: digital output forced to on (e.g. DVI-I connector)
[d]
: output forced to off
You can override the modes of several outputs using
video=
several times, for instance, to force
DVI
to
1024x768
at
85 Hz
and
TV-out
off:
video=DVI-I-1:1024x768@85 video=TV-1:d
Options can also be passed after the mode, using commas as separator:
video=DVI-I-1:720x480,rotate=180
Valid options are:
margin_top
,
margin_bottom
,
margin_left
,
margin_right
(integer): Number of pixels in the margins, typically to deal with overscan on TVs
reflect_x
(boolean): Perform an axial symmetry on the X axis
reflect_y
(boolean): Perform an axial symmetry on the Y axis
rotate
(integer): Rotate the initial framebuffer by x degrees. Valid values are 0, 90, 180 and 270.
tv_mode
: Analog TV mode. One of "NTSC", "NTSC-443", "NTSC-J", "PAL", "PAL-M", "PAL-N", or "SECAM".
panel_orientation
, one of "normal", "upside_down", "left_side_up", or "right_side_up". For KMS drivers only, this sets the "panel orientation" property on the kms connector as hint for kms users.
To get the name and current status of connectors, you can use the following shell oneliner:
$ for p in /sys/class/drm/*/status; do con=${p%/status}; echo -n "${con#*/card?-}: "; cat $p; done
DVI-I-1: connected
HDMI-A-1: disconnected
VGA-1: disconnected
Disabling modesetting
You may want to disable KMS for various reasons. To disable KMS, add
nomodeset
as a kernel parameter. See
Kernel parameters
for more info.
Along with the
nomodeset
kernel parameter, for an Intel graphics card, you need to add
i915.modeset=0
, and for an Nvidia graphics card, you need to add
nouveau.modeset=0
. For Nvidia Optimus dual-graphics system, you need to add all the three kernel parameters (i.e.
"nomodeset i915.modeset=0 nouveau.modeset=0"
).
Note
Some
Xorg
drivers will not work with KMS disabled. See the wiki page on your specific driver for details.