Architecture: client and server

The Hurd console's implementation is broken into two pieces each running on it's own process, the console client and server.

The console client is also split into modules (input driver, display driver, speaker, ...) but they all run in the same process.

The console server puts itself as a translator on top of /dev/vcs folder presenting the following hierarchy:

   + /dev/vcs
     +- 1
          +- console
          +- input
          +- display
     +- ..
     +- n

where the numbered nodes represent virtual consoles and their contents are all alike.

As the following graph shows, the console, input and display nodes are the interfaces used by the terminal server, input driver and display drivers respectively.

   +------------------+                                 +-----------------+
   |   Input driver   |                                 | Terminal Server |
   |                  |                                 |                 |
   |      pc-kbd      |                                 |                 |
   +------------------+                                 +-----------------+
            | _cons_vcons_input                                 |
            | writes to                                   reads |
            | vcs/i/input                         vcs/i/console |
            |                +-----------------+                |
            |                | Console Server  |                |
            |                |  /hurd/console  |                |
            |  input_enqueue | --------------- | input_dequeue  |
            +--------------->|   Input Queue   |>---------------+
                             | --------------- |
            +--------------->|  Output Buffer  |>---------------+
            |                +-----------------+                |
            |                                                   |
            | writes                                      reads |
            | vcs/i/console                       vcs/i/display |
            |                                                   |
   +----------------+                                   +-----------------+
   | Teminal Server |                                   | Display driver  |
   |                |                                   |                 |
   |   /hurd/term   |                                   |      vga        |
   +----------------+                                   +-----------------+

The input driver takes scancodes from the in-kernel kbd queue, translates them into characters and writes them to the input node. Then the terminal server reads the console node taking the characters out of the console server.

Each of theese actions is actually an RPC handled by the translator on /dev/vcs. Writes to input nodes are handled by calling input_enqueue to put the character into a queue. And reads from console nodes are handled by calling input_dequeue which takes out charecters from the queue and gives them to the reader.

It's important to note here that both input_enqueue and input_dequeue are blocking operations and a blocked input_dequeue necessarily needs an input_enqueue call to continue.

RPCs are handled by the console server with the help of libports' ports_manage_multithreaded API.

Old stuff

open issue documentation: cleanup needed.

The below is a reworked version of Marcus Brinkmann's letter to the debian-hurd list. It describes how to setup the new console server for the Hurd. I am testing this right now, so this document is a work in progress.

-- ?JoachimNilsson - 21 Jan 2003

Many of the shortcomings of the console are not true anymore. I've updated the page to match the state as it is in CVS.

-- ?MarcoGerards - 28 May 2004

The latest Hurd package in Debian has all that is needed to run (dunno about hurd.ti though). The native-install script sets up all the necessary nodes, so all you really need is to run:

console -d vga -d pc_kbd --repeat=kbd -d pc_mouse --repeat=mouse \
        -d generic_speaker -c /dev/vcs

-- ?JoachimNilsson - 17 Apr 2005

Additional information about the console can be found in the Hurd Console Tutorial

What is the new console?

The new Hurd console features:

A console server, which provides a number of virtual consoles to term servers, with a full set of terminal capabilities.

The console server supports any encoding supported by iconv, but uses Unicode internally. The default encoding is ISO8859-1, another useful variant is UTF-8.

The console server provides an arbitrary number of virtual consoles (numbered starting from 1, but the numbers don't need to be consecutive), which are created dynamically. A virtual console is not automatically displayed, for this you need a console client program which attaches to the virtual console you want to use.

You can attach any number of console clients to the same virtual console, and detach them at any time.

The console server provides a scrollback buffer for each virtual console. Currently, this is about one and a half screen full in addition to the screen. This should be configurable, of course, but isn't right now.

libcons, a library that makes it easy to write console clients that attach to the console server.

The client interface of the server is quite complicated, because it is based on shared memory and broadcasts the data to potentially many clients without blocking. It also includes a notification scheme so that clients remain idle when there is no console activity. This saves cpu power (compared to the alternative which would be polling).

The default console client, which you will normally use to use a virtual console in a console server. Rather than writing many similar console client programs, I decided to write only one initially and make it extensible via dynamically loaded modules called "drivers".

The console client uses libcons, of course. There are a number of drivers that exists already:

  • The ncursesw driver. You can use this if you log in from a remote unicode-capable console to attach to the local console server and use virtual console over the telnet/ssh session or similar. The ncursesw driver contains an output, input and bell driver components, so it is the only driver you need to get full access.

  • The vga driver. The VGA driver can be used locally to display a virtual console on a VGA card device. This driver provides a number of exciting features, and all of them are available in the fast text mode, and do not require a graphical framebuffer:

  • BDF font support. Load any BDF font with a Unicode encoding and a size from 8x13 up to 9x15 (recommended).

  • Dynamic glyph allocation. You can use up to 512 glyphs at any time. This means you can display cyrillic, greek, english runes, thai, etc. often at the same time, up to 512 different glyphs on the screen in parallel. The 512 is not a fixed set, they are chosen automatically out of the font you have loaded. This means that we only need one font for all users, regardless of the locale.

  • Dynamic color allocation. Because the above 512 glyph modus is only available with a reduced amount of colors, you can use only up to 8 different colors, but which of the 16 colors are available is chosen dynamically based on the colors actually used.


  • Support for multiple fonts at the same time. The VGA driver supports italic and real bold (not bright color) mode. This will hopefully be used in emacs font lock mode and other applications.

  • The pc_kbd driver. This is a hack for a PC eyboard with an american keymap. We all want configurable keyboard layouts of course, but I had to set priorities, and extracting xkb (so we can reuse the X keymaps) is on the TODO list. For now, this driver with a fixed US keymap is available for immediate use. Although it is only considered to be a temporary solution, it provides all features you need (except changing the keymap):

    • All keys of a standard 102(?) keys keyboard, including Ctrl, LeftAlt, RightAlt, CapsLock, NumLock, Keypad, cursor block, function keys are supported and have a sensible default value.
    • LeftAlt + Function key N switches the virtual console N.
    • LeftAlt + ArrowRight or ArrowLeft switches to previous or next virtual console.
    • RightShift + PageUp or PageDown scrolls back or forward in the scrollback buffer by half pages.
    • LeftAlt + ArrowUp or ArrowDown scroll back or forward one line.
    • LeftCtrl + LeftAlt + Backspace terminates the console client, and reverts the VGA card etc to its original state.
    • RightAlt + Keypad enables you to directly enter unicode characters in hexadecimal numbers. 0-9 have their standard meaning, and NumLock is 0xa, Keypad / is 0xb, * is 0xc, - is 0xd, + is 0xe and the enter key at the lower right of the keypad is 0xf. Up to four digits are memorized, if you type more, the earlier ones are forgotten. This allows to cover up typing mistakes.

For example:AltGr + (Keypad 4, Keypad 1) = 0x41 = 'A'.
AltGr + (Keypad 2, 6, 3, NumLock) = 0x263a = smiley. You can get unicode tables from

  • The generic_speaker driver supports the speaker commonly found in PCs and other computers. It is good enough for a simple bell tone or a small melody. I have several default bell styles implemented, but currently there is no configuration option to access them at run time, sorry! Load this module to make the console beep on ^G.

How do I install the new Hurd console?

Setting up for older hurd packages

You either need the latest .deb of the Hurd, version 20020918-1 or later, or you need current CVS sources and compile them yourself.

Then, the console server is in /hurd/console, the client in /bin/console. The installation is painless.

First, make some device files:

# cd /dev
# ./MAKEDEV vcs tty1 tty2 tty3 tty4 tty5 tty6

The above six ttys are only suggestions. You might want to give or take a few, depending on your needs.

You need the terminal description. This is not yet in the ncurses package, because I am not finished yet. But you can download hurd.ti from CVS. Please add it with

# tic -x hurd.ti

Then you should add the terminals to ttys, so you get a login session on them at boot time. Edit the file /etc/ttys, and add the following lines (or similar if you made more/less ttys):

tty1    "/libexec/getty 38400"   hurd   on   secure trusted console
tty2    "/libexec/getty 38400"   hurd   on   secure trusted console
tty3    "/libexec/getty 38400"   hurd   on   secure trusted console
tty4    "/libexec/getty 38400"   hurd   on   secure trusted console
tty5    "/libexec/getty 38400"   hurd   on   secure trusted console
tty6    "/libexec/getty 38400"   hurd   on   secure trusted console

This is all. If you now reboot, you will get six virtual consoles with a login prompt on each. But of course, the console client is not started automatically yet, so you don't see them.

Activating the console

Login at the normal system console, and try to attach to the console server, either with the ncursesw driver or with the vga/pc_kbd driver:

# console -d ncursesw /dev/vcs


# console -d vga -d pc_kbd -d generic_speaker /dev/vcs

That should work. The ncursesw driver supports console switching via C-w C-1 (or 2, 3, ...) and you can exit it with C-w x. However, the VGA client is more suitable on the local console.

If you want repeater support (needed for X):

# console -d vga -d pc_kbd --repeat=kbd -d generic_speaker \
  -d pc_mouse --repeat=mouse --protocol=ps/2 -c /dev/vcs

Available mouse protocols are:

  • mousesystem
  • microsoft
  • ps/2
  • nomouse
  • logitech
  • mouse7

Setting up encoding

The virtual consoles you are now running on are providing an ISO8859-1 environment (also known as latin1), which is good enough for the USA and some countries in Europe. If you require a different encoding for your locale (like, let's say, ISO8859-2), you can specify this as an argument to the console server. I am sorry to say that fsysopts doesn't do the trick yet, so you have to set the option with settrans -fg, which will terminate all your login sessions and restart the console server.

To do this, first exit the client. It will get disconnected anyway (and doesn't attempt to reconnnect yet in such a case). Then do a

# settrans -fg /dev/vcs /hurd/console --encoding=ISO8859-2


# settrans -fg /dev/vcs /hurd/console --encoding=UTF-8

or similar. A list of supported locales is not easily available, but you can poke into /share/i18n/SUPPORTED to get an idea what is expected for your locale, and you can also check out /share/i18n/charmaps. Theoretically all of these encodings are "supported". In the file SUPPORTED, you see the locale (what you should export in the LANG environment variable, and enable in /etc/locale.gen) and the corresponding encoding.

If you actually try this, you will notice two problems:

  1. You can not enter the letters in your locale, because the keyboard doesn't have the right layout. See above. Keyboard maps come later. For now, you have to help yourself with the direct input with RightAlt. Maybe I will put a simple compose key feature in the pc_kbd driver, so that some western locales can be used more easily.
  2. If you bother to look up the unicode hex code and enter it with AltGr, the font can not display it! If you are using the ncursesw driver, do you use it while you are logged in from a working UTF-8 terminal? If not, then this is your problem. An ncurses driver for non-UTF-8 terminals is on the TODO list. But if you use the VGA driver, you need to load a different font.

This is because by default, the vga driver just reads the VGA card memory and takes the font that is stored there. This font has a limited characterset (256 characters, many graphical symbols among that), so you won't get more than a few western characters with that.

Unicode support

But you want it all. You want to read Middle Old English. You want to read Thai. Your Korean spam. Georgian script. Hebrew. And you can have it.

First you have to set the encoding to UTF-8:

# settrans -fg /dev/vcs /hurd/console --encoding=UTF-8

Then you need a Unicode font. There are good ones provided by Markus Kuhn, the UCS fonts. See also the web page.

Now, load the font by providing it with the --font option to the vga driver. I suggest only the 8x13 and the 9x15 fonts, but feel free to try others, too. Note that the VGA text mode can not really display 9 pixel wide characters. But as most characters have the ninth column empty, and the VGA text mode can display an empty column between two adjacent character cells, this trick allows us to display most of the 9x15 font correctly. So you won't notice a difference until you come to very broad characters or special symbols, where you will see that the last column is cut off. (BTW, I wrote the dynafont code carefully to still support horizontal line graphic characters properly in 9 pixel wide fonts. This is done by exploiting some special modes in the VGA hardware. This is why in 512 (256) glyph mode and 9 pixel wide fonts, you are limited to 448 (224) normal characters: 64 (32) slots are reserved for the horizontal line graphic characters so they are drawn continuously.)

So, try the following:

# console -d vga --font 8x13.bdf -d pc_kbd -d generic_speaker /dev/vcs


# console -d vga --font 9x15.bdf -d pc_kbd -d generic_speaker /dev/vcs

If you are satisfied, copy your default font to /lib/hurd/fonts/vga-system.bdf, where it will be picked up automatically in favor to the graphic card's font.

More about fonts

While we are talking about fonts, try also the 8x13O font with --font-italic and 8x13B or 9x15B font with --font-bold. You can save them in /lib/hurd/fonts/vga-system-bold.bdf and /lib/hurd/fonts/vga-system-italic.bdf, too.

To activate those fonts on your virtual console, try the following:

# echo `tput sitm` Hello slanted world. `tput ritm`


# echo `tput gsbom` Hello bold world. `tput grbom`

I hope you like what you see. Imagine this in emacs font-lock mode.

Unicode, finally

There are a few more steps necessary to make your Unicode environment ready:

Install the locales package. The current version does want a newer glibc than we have in the archive, but this can be overridden with the --force-depends option to dpkg. The old glibc is good enough.

Add a Unicode locale to /etc/locale.gen, and generate the locale information for that! For example, I am living in Germany, and normally use de_DE with the encoding ISO8859-1. My Unicode locale is de_DE.UTF-8, so I am adding that to /etc/locale.gen:

de_DE.UTF-8 UTF-8

and rerun locale-gen:

# locale-gen

See also /share/i18n/SUPPORTED. You can also do this more conveniently with

# dpkg-reconfigure locales

Once you generated this, make it your default locale:

# export LANG=de_DE.UTF-8

If you have also loaded the unicode font above, you are set up. Try for example to view the examples/ files in the ucs-fonts package with less.

# less fonts/examples/UTF_8-demo.txt

You should see most of that file with the 9x15 font (a bit less with the 8x13 font).

You should be able to do the above process with other encodings than UTF-8. But you should always use a Unicode font, because the console client uses Unicode internally fo everything.

Application specific notes

If you enter unicode characters at the shell, libreadline loses track of the number of characters displayed (it is not aware of multi-byte encodings like UTF-8). This is fixed in readline 4.3 (which is not yet in Debian).

If you use mutt, install mutt-utf8 package. For lynx, edit /etc/lynx.cfg, making sure that CHARACTER_SET is set to utf-8.

If you use other applications, try to search with google for "application-name utf8" or "application-name unicode". Often you find what you need. The issues are the same for the GNU/Hurd and GNU/Linux systems, so most of the information can be shared, except how to setup the system console to support Unicode, of course.

The console-server watches for new hurdio terms (devices translated with /hurd/term) and adds them to /dev/vcs automatically. What this means is, if you create a new tty with MAKEDEV, and then attach something to it, it will now appear in /dev/vcs. When a term is disconnected from, it disappears from /dev/vcs. /libexec/getty is what is usually attached to a term. You can see this automatic adding and removing of terms from the console-server by typing the following:

# cd /dev
# ls vcs/
1  2  3  4  5  6
# MAKEDEV tty7
# cat > tty7 &
[1]+  Stopped                 cat > tty7
# ls vcs/
1  2  3  4  5  6  7
# kill %1
# ls vcs/
1  2  3  4  5  6

Known problems and important missing features

Squeezed at the end so nobody sees it ;)

console server: Is probably too lax in permission checking. Does not implement settable tab stops. Does not allow to change encoding at run time. Does not allow any other screen size but 80x25.

Combining characters is not supported.

libcons/console-client: If you have one virtual console active, and another one receives a bell character, you don't hear the bell. This is because only the active virtual console is watched for anything interesting to happen. I think that is ok, but you might be surprised if you are used to how it works on GNU/Linux.

Copy & Paste not supported.

vga driver: Does not recalculate the mode lines if the font height is changed. This makes font heights below 13 or over 16 infeasible.

Should support other text modes (integrate svgatextmode?)

pc_kbd driver: No keyboard layout but US supported! Maybe in some cases left/right shift/ctrl/alt is allowed where both left and right should be allowed. Keyboard LEDs are only supported when using OSKIT-Mach or the CVS branch gnumach-1-branch of GNU Mach.

ncursesw driver: Doesn't work properly on other terminals but UTF-8. Should not use C-w, this should be configurable. Does not support use of scroll back buffer.

Other programs: Readline doesn't support multibyte encodings (4.2 and earlier). term doesn't either (all versions).

Here's a June 2002 status report

In September 2002 there was a request for testers. There's been quite a bit of discussion on about updates, test results and changes.

-- ?GrantBow - 22 Oct 2002

There are several patches for the console on savannah to deal with the shortcommings described in Marcus' email. Patches for broadcasting the bell event, for setting other text modes and a patch to make it possible to start XFree from the console can be found on savannah.

An experimental plugin to load XKB keymaps exists, although it is alpha quality.

-- ?MarcoGerards - 28 May 2004

Added examples that use repeaters needed by X.

-- ?OgnyanKulev - 18 Sep 2004

IRC, freenode #hurd, 2012-04-23

<Tekk_> is there any way to get copy/paste in hurd?
<Tekk_> with the console server
<Tekk_> like you get with gpm
<youpi> Tekk_: by implementing it
<antrik> Tekk_: that's something for the console client, not the server
<antrik> (or perhaps both? not entirely sure)
<Tekk_> antrik: I'm not entirely sure how the client works
<Tekk_> does it start a new client with each tty?
<Tekk_> or one client handles all of them?
<youpi> the client only should be enough
<youpi> it handles all input already anyway
<youpi> the client handles all ttys
<youpi> it just hops over them according to alt-Fx shortcuts
<antrik> Tekk_: there is only one client for all, but a separate console
  *server* for each tty
<Tekk_> antrik: ah, the ever confusing X scheme
<antrik> no
<antrik> the client handles multiplexing and actual terminal I/O
<antrik> the servers handle the state of the virtual terminals, and provide
  the device nodes
<antrik> this doesn't fit with the X scheme in any way
<antrik> (where everything is basically in one big monolithic server
<Tekk_> antrik: I mean that you're running multiple servers and there's one
  big client running on the other end
<Tekk_> which always pretty well confuses everyone to start with
<antrik> I totally fail to see the connection
<antrik> there is usually one X server, with potentially many clients
<Tekk_> nevermind
<Tekk_> doesn't really matter to anything
<Tekk_> so yeah, copy/paste would be in the client?
<antrik> unless you mean a termial server, running actual client programs,
  connected to various terminals, running X servers... which is where it
  gets confusing in a way ;-)
<antrik> but there is really no relation at all here
<Tekk_> antrik: exactly ;)
<Tekk_> I meant in the traditional sense, where you're on a thin client
  running an X server and the remote server is running X clients
<Tekk_> copy/paste probably isn't really too bad
<antrik> applications are also clients of the terminal server processes;
  but having a completely different role (and using completely different
  requests) than the console client
<Tekk_> you have a buffer, when something is highlighted you strncpy the
  highlighted text into the buffer. when middle click happens you send the
  text to the right virtual terminal
<antrik> right. what I was considering is whether the pasting (and possibly
  also grabbing) the text might be done through some separate protocol
  implemented in the console server, rather than the ordinary console
  client interfaces... but probably no need for that
<Tekk_> nah, as long as you have a way of getting a highlighted area and
  then the text contained in it
<Tekk_> and then of course a way to insert text where the cursor is, but
  I'm pretty sure you can safely assume that one :P
<antrik> well, the client has a way to send keystrokes to the server,
  obviously. the question here is whether pretending the pasting is
  keystrokes is good enough, or whether it might be useful to have an
  explicit way to push the pasted stuff to the server
<antrik> (the cursor position is relevant only for echo)
<Tekk_> antrik: I'll try to grab the console source some time this week and
  take a look
<Tekk_> maybe I can try to get it working
<antrik> good luck :-)
<antrik> it's probably not too hard
<Tekk_> I'm sure I'll need it :)
<antrik> the whole console machinery is quite hard to grasp (and I still
  find myself confused sometimes, although I gained a pretty good
  understanding I think when writing my thesis)
<antrik> but for this specific task, not much knowlegde should be needed
  about the various confusing aspects
<Tekk_> hmm. looks like copy/paste won
<Tekk_> 't be a quick thing, actually
<Tekk_> wait, no. there must be a way to get mouse events
<Tekk_> how else could you move the mouse..
<Tekk_> (with by moving your mouse, not cons_mouse_move)
<Tekk_> by moving your mouse*
<Tekk_> started typing something different

IRC, freenode #hurd, 2013-11-28

<Gerhard> I see a mouse cursor, but I'm not able to copy and paste. gpm is
  not in the repository, right?
<youpi> copy/paste is not actually implemented yet
<youpi> so you can move the mouse, but clicks don't do anything :o)
<teythoon> ^^
<Gerhard> ok, thx for the feedback.
<teythoon> i always wondered if it was just me >,<

Graphics/Higher Resolution

IRC, freenode #hurd, 2012-04-24

<Tekk_> does the console support higher resolutions yet?
<youpi> no
<youpi> it's just textonly
<antrik> Tekk_: the main reason why I originally started on the KGI work
  was to get a graphical console... but I never finished that part
<antrik> (since KGI is obsolete anyways)
<antrik> BTW, there is a KMS-based userspace console now for Linux... I
  guess it should be easy to adapt to other systems having KMS support
<antrik> I don't think it actually makes much sense for Linux, as it's one
  of the hardest and least profitable things to move out of a monolithic
<antrik> well, not hardest I guess; but most problematic