This is an old revision of the document!


Kernel Graphics Interface (KGI) is the kernel side of the General Graphics Interface (GGI).

KGI was initially a Linux project with the goal of being a multi-OS subsystem. GGI was aiming to be the new generation Linux console subsystem alone. As GGI was progressing, it became clear that an explicit separation between kernel and user spaces was necessary. Steffen Seeger was maybe the most convinced of this: he rewrote KGI in 1998/1999 resulting in the version we have today both under Linux and FreeBSD.

KGI Project Website

It is being ported to FreeBSD in the kgi4BSD Project.

The KGI project aims at providing the kernel of modern Unixes with general purpose APIs (grouped as KgiAPI) for the implementation of:

  • a console (KGC) with:
    • text (not yet) and graphic modes
    • multi-head (HW multi input and output)
    • virtual terminals (KgiFocus)
    • TERM emulation (KgcXterm)
    • font support (not yet)

A KGI device is not what we are used to think of e.g a peripheral or anything related to HW. Instead, a KGI device is a piece of code and data using / sharing KgiResources with other KGI devices.

Everything that uses the HW resources of a KgiDisplay (mode setting, framebuffer, HW pointers, palettes…) must register itself as a KGI device.

Maybe this layer of KGI was wrongly called devices because /dev/graphic and /dev/event which are the general KGI and KII user entrypoints are from Unix point of view called devices…

Different KGI devices are known currently:

  • KgiGraphic, the kernel/user limit for the support of userland ioctl's including mode setting
  • KgcRender, the rendering engines of KGC

The visible effect of mapping a KgiDevice to a KgiDisplay is the change of mode on that display. Before mapping a device, a mode must have been negociated with its display. When the device is mapped, the display is requested by KGI to set the mode previously negociated. When the device is unmapped, the display is asked to unset the mode before another device is mapped and so on.

Device mapping / unmapping is performed typically when:

  • console events occur (special key hit for example) on the KgiFocus the device's display is attached to
  • an application sets a mode, it is supposed to take control of the screen: the device, allocated when opening the /dev/graphic Unix device, is then mapped with the mode just negociated
  • the console enters DDB (the debugger), the currently mapped KGI device (graphic app or whatelse) is unmapped and the console's KGI device is mapped

The device methods (hooks) enable the device for example to redraw the screen when mapped or to block anything being performed on the display when unmapped.

See KgiDeviceAPI for details of programming a KgiDevice.

A KGI display is a graphic backend. It is an object composed of data and methods allocated at display registration. A display registration occurs for example when you load a KgimDriver.

Other kind of displays exists, kgi4BSD provides one based on the FreeBSD VESA driver.

See the KgiDisplayAPI for details about programming a KgiDisplay.

KGIM stands for Kernel Graphic Interface Module.

This is the API for writing graphic module drivers. KGIM is implemented in KGI as a KgiDisplay.

Drivers using the KgimAPI are known as KgimDrivers.

KII stands for Kernel Input Interface. It is known as the kernel side of GII the General Input Interface (part of the GGI project).

It provides KgiInput with declarations and registrations routines to connect to a KgiFocus.

Currently, KII is on top of FreeBSD keyboard drivers. The main benefit is to get immediately FreeBSD keyboards supported by KII and KGI.

In the long term FreeBSD current kbd abstraction should be discardedand true KII drivers should be written.

The original kbd (atkbd or usbkbd) is a KII input connected to focus 0. Moused events are redirect to focus 0 by mean of another KII input (made by ioctls) and finally a KII client is given to provide the /dev/sysmouse interface to user apps. Hmm, little graphic:

/dev/consolectl -----------+
                           |
      ttyv1 <--------+     v
                     |- focus 0 <------ kbd
      ttyv2 <--------+     |
                           |
/dev/sysmouse <------------+

KGI Input

A KgiInput is basically anything capable of providing KII with events. KgiInput are typically input drivers that convert HW events (mouse move, buttons, key-press…) into KII events.

The KgiInput must register itself to KII using the KgiInputAPI. Once done, it may be polled by the KII engine or send itself events to KII.

KGI Focus

The KgiFocus is the central place in KGI where KgiInput are connected to KgiDisplay.

When you hit a key on your keyboard, you want it to go to the console you are working on and application(s) running on that console should get the event delivered.

Other applications running on other consoles should not get the event (for obvious security reasons).

When you want to switch to another physical (dual-head) or virtual (also known as VTs) console, you press a key combination to switch and then want now your chars to be sent to the right console.

In other words, you need the system manages the focus for you in a convenient, deterministic and safe manner.

These connections are at the same time dynamic and static. Static because the relationship between display and input instances is predefined. Dynamic because you can register any KgiInput (ps/2, usb mouse or keyboards) or KgiDisplay to the KgiFocus.

So what is predefined relationship? Let's have a look at the following:

device 0 on focus 0, display 0, console 0
device 1 on focus 0, display 0, console 1
device 2 on focus 0, display 1, console 2
device 3 on focus 0, display 1, console 3
device 4 on focus 0, display 1, console 4
device 5 on focus 0, display 1, console 5
device 6 on focus 0, display 1, console 6
device 7 on focus 0, display 1, console 7
device 8 on focus 0, display 1, console 8
device 9 on focus 0, display 1, console 9
device 10 on focus 0, display 1, console 10
device 11 on focus 0, display 1, console 11
device 12 on focus 1, display 2, console 0
device 13 on focus 1, display 2, console 1
device 14 on focus 1, display 2, console 2
device 15 on focus 1, display 2, console 3
device 16 on focus 1, display 2, console 4
device 17 on focus 1, display 2, console 5
device 18 on focus 1, display 2, console 6
device 19 on focus 1, display 2, console 7
device 20 on focus 1, display 2, console 8
device 21 on focus 1, display 2, console 9
device 22 on focus 1, display 2, console 10
device 23 on focus 1, display 2, console 11

It presents the case of 2 keyboards (represented by 2 focuses) for which one has 3 screens. Each focus can reach 12 consoles (typically what you get with a PC keyboard with F1..F12). Focus 1 is totally linked to display 2 (1 keyboard + 1 screen wired config) and focus 1 can either control consoles 0 and 1 through display 0 and others through display 1. It means that with focus 0, when you hit ALT+F1 you edit commands on display 0, ALT-F3 : you edit on display 1, ALT-F1 you change VT on display 0 and ALT-F4 to ALT-F12 : you switch to VTs on display 1.

kgi4BSD is a port of KGI for FreeBSD.

After the port of GGI to FreeBSD vgl(4) library at the of 2000, I decided to port KGI. Actually, KGI was my original challenge but what to do with KGI without GGI?

Before the kgi4BSD site was created, KGI/FreeBSD was a private project shared among KGI developers. Now kgi4BSD becomes more popular and this is a good thing. kgi4BSD is currently the only kernel graphic solution for the BSDs. It currently targets only FreeBSD but DragonfyBSD, OpenBSD and NetBSD (for its VM) could be planned.

It's a dual-licensed MIT-X / GPL project made 100% on spare time by very few people. If you like kernel development and graphics it's definitely a project for you ;)

We use the concept of condvar(9) with mutex(9) to implement something like the wait_event I found in KGI. I wonder why the condvar API is not part of the mutex one since a cv is nothing else than a mutex with a waitqueue. So I decided to merge FreeBSD condvar and mutexes in the KgiMutex implementation.

In KGI Linux code, page mapping is performed for a set of pages and not only on pagefault occurrence. I have to check whether this is also possible with FreeBSD VM. This is certainly possible using something like vm_fault_additional_pages() which is currently bypassed when getting OBJT_DEVICE or OBJT_KGI pages.

For KgiAccel, we have to change the protection of pages to provoke pagefaults on them. But pagefaults on resident pages is only expected to happen on COW pages. getpages is only used to allocation non resident pages and no flag in the prototype of getpages allow passing some flag. Faults on resident pages shall occur typically when a process being not mapped anymore attempts to access an KgiMmio or KgiAccel. By the way, pages must not be FICTITIOUS otherwise they have no corresponding PTE and thus the MMU entries can't be release by any means other than through pmaps! Currently I use my own page allocator and don't use the paging one. FreeBSD VM implementation seems completely inappropriate to alternative VM policies other than the paging one :(

What about adding a new method to pagers: .pgo_checkpages to handle faults on resident pages?

About SMP, I think excluding concurrent access to the kgi device structure could be a first attempt. Especially to manage atomic map / unmap of devices.

I'm wondering how to block a process performing graphics on a device that is unmapped. I'm not happy with any signal scheme and would really prefer a blocking thread. This implies some programming style, threading oriented with for example a thread for drawing (I mean accessing the HW resources) and others do the rest of the application. The main drawback is that programmers may not be aware of this and existing applications may not fit…

  • suppress the STRICT_ANSI in types.h
  • remove the kgi_s_t and kgi_u_t types??

The KGI API includes:

  • The unique identifier of the device
kgi_u_t			id;
  • The identifier of the KgiDisplay the device interacts with
kgi_u_t			dpy_id;
  • Various flags
kgi_device_flags_t	flags;
  • Currently set mode for the device
kgi_mode_t		*mode;
  • Per device instance private data
kgi_private_t		priv;

The three methods of a KGI device are callbacks called by KGI on KGI events:

  • When the device is mapped to its display
kgi_device_map_device_fn	*MapDevice;
  • When the device is unmapped from its display
kgi_device_unmap_device_fn	*UnmapDevice;
  • When a KiiEvent has to be delivered to the KGI device
kgi_device_handle_event_fn	*HandleEvent;

The KgimAPI is part of KGI but strictly speaking, it is a lower level API interfaced to KGI thanks to the KgiDisplayAPI.


  • nicholassouchu/kernelgraphicsinterface.1654827949.txt.gz
  • Last modified: 2022/06/10 02:25
  • by KubilayKocak