Enhancing kernel graphics
Current Linux systems have several design problems in the area of graphics architecture. In particular, several features are either missing or unnecessarily difficult in the current system:
- suspend/resume of graphics state
- output of oops/panic messages while graphical apps are running
- use of graphics devices without X
- overweight VT switch Many of these problems are caused or exacerbated by the fact that several drivers compete for control of graphics devices in Linux systems: the kernel VGA driver, kernel framebuffer drivers, kernel DRM drivers, userspace X drivers, userspace DRI drivers, and other userspace drivers (e.g. svgalib). Each of them wants to exclusively "own" the graphics device they correspond to, due to the lack of proper interfaces between the different layers of functionality.
Suspend and Resume Functionality
Currently, suspend/resume of graphics devices in Linux is woefully incomplete, and doesn't work at all on many Linux systems. If the system firmware fails to reinitialize graphics devices prior to handing control back to the kernel, your system is very likely to hang on resume, or in the best case, come back up but without graphics support.
Full suspend/resume logic for graphics devices belongs in the kernel for several reasons:
- system graphics should come back as quickly as possible
- platforms may or may not provide reinitialization support
- users may not be running X, and therefore can't rely on their X driver to fully reinitialize their graphics device(s)
- some support for reinitialization is necessary for featureful power management Therefore, the proposed DRM enhancements include full suspend/resume logic at the DRM layer (though this could be moved to a GPU layer shared between FB and DRM drivers).
Panic and Oops Messages
On current systems, if a graphical application is running in KD_GRAPHICS mode (owning graphics for the selected VT), any kernel output, even if it's critical in nature, will be invisible to the user. Generally, this means that panics are manifested as unexplained hangs in X sessions, with no easy way of seeing what happened short of rebooting and hoping the message was captured somewhere.
The enhancements outlined here include a new VT mode (KD_KERNEL_GRAPHICS or similar) that includes support for displaying emergency messages directly on the currently active framebuffer. So, while still unfortunate, at least the user will know that a panic occurred and may be able to take action to prevent it from happening again.
Freedom from X
Since the X server comes with fairly featureful drivers for many graphics devices, and the difficulty of developing new drivers is fairly high, developers are faced with either developing their graphical applications for X, using minimally featured FB based applications, or writing their own driver stack.
Moving graphics device configuration and modesetting into the kernel, as these enhancements do, will allow fairly sophisticated applications to be developed independent of X, and should make it easier to port OpenGL stacks to standalone operation (à la EGL), making even complex 3D applications possible without using X.
Currently, the kernel relies on an external program to restore the graphics state when a VT switch occurs. This doesn't always work, with similar results to the suspend/resume case: an apparently hung or unusable machine. Of course, the kernel can't unconditionally preempt the graphics device to set a new mode, but having modesetting in the kernel will give it a much better chance of coordinating with the DRM command dispatch code to find a good time to set a new mode.
Need to describe lightweight DRM based VT switch mechanism here.
There are several aspects to the new design:
- DRM internal interface and initialization changes
- External, userspace visible APIs for graphics device management
- New userspace applications for detecting available modes and loading them into the kernel
DRM internal changes
Current DRM drivers are mostly initialized by DRM clients in userspace (like X). In order to fully support the features outlined here, DRM drivers will need to perform full initialization at module load time (which would ideally be at kernel boot time) and include other features, including:
- register mapping
- irq registration
- setup initial device state (e.g. setup ring buffers, enable device, etc.)
- detect outputs
- initial configuration setup (either storing current configuration into an "initial mode" structure, or setting an initial mode, depending on platform)
- suspend/resume hooks
The new system provides graphics device configuration and modesetting APIs:
- Configuration and output management
- Modesetting on a per-output basis
Configuration and Output Management
The enhancements here include a new set of device nodes for graphics device management:
- /dev/dri/0c - for listing outputs, crtcs, and binding them together
- /dev/dri/0[x] - corresponding to each crtc configured with outputs, allows fine grained sharing and per-session control
- DRM_IOCTL_MODE_GETRESOURCES - get number of CRTCs, FBs
- DRM_IOCTL_MODE_GETCRTC - get info about a given CRTC
- DRM_IOCTL_MODE_GETOUTPUT - get info about a given output
- DRM_IOCTL_MODE_SETCRTC - set CRTC parameters
- DRM_IOCTL_MODE_ADDFB - add a new FB object
- DRM_IOCTL_MODE_RMFB - remove an FB object
- DRM_IOCTL_MODE_GETFB - get info about an FB object These ioctls would typically be done against the /dev/drm node, which would create new /dev/drmN nodes for applications to attach to.
Development is ongoing in the master branch of git://git.freedesktop.org/git/mesa/drm and various kernel git trees.
Short Term TODO items: (things to do to replace current Intel DDX with a kernel one)
- expose output properties (sysfs later on)
- finish edid parsing and monitor support
- implement DRM control/slave device node scheme
- re-do ioctl commands against control/slave device node scheme
Finish intel driver hardware support Long Term TODO items:
port other drivers (e.g. radeon, nouveau) to the tree
- create mode verification and loading application (including CVT and GTF mode generation) for fixing up broken EDID data
- add hotplug support (some devices can generate interrupts on monitor plug/unplug)
- expose output controls (e.g. DPMS, display brightness) somehow, maybe via existing DRM param interface or new ioctl
- add more advanced power management to drivers
- add sysfs interface for interesting information (e.g. crtc->output configuration, available modes, etc.)
- port existing apps to the new interfaces (starting with X drivers)
- share more with FB layer (factor out common code into GPU layer) (?)