Using a Dvorak keyboard layout in FreeBSD

A guide to using any non-standard keyboard layout in FreeBSD.

Purpose of this page

To inform FreeBSD users on how to change keyboard layouts in FreeBSD, including single user mode. The information is relevant to users of FreeBSD 5, but may also apply to any higher or lower versions. If you're not using FreeBSD 5, make sure you check that the advice on this page still applies to the version you are using.

The keyboard layout that this document focuses on is the Dvorak layout, but the information applies equally to any of the keyboard layouts that FreeBSD offers. The layout files are stored in /usr/share/syscons/keymaps and include keymaps for Japanese keyboards; Norwegian, Danish, and Swedish keyboards; French, German, and Swiss-variant keyboards; UK keyboard layouts; layouts for some other areas of Europe and the world; and variants of the standard US keyboard, including my keyboard layout of choice: US Dvorak.

What is the Dvorak keyboard layout?

The Dvorak keyboard is a key layout that was designed over half-a-century after the QWERTY key layout that most keyboards still use in the US and Western Europe. It was designed to make typing more comfortable by reducing the amount of hand-gymnastics required to reach common letters and letter combinations.

This document is not really about the whys and whos of Dvorak, it's about getting the Dvorak layout to work for you in FreeBSD. Suffice to say that I changed from QWERTY to the Dvorak layout. It took me about three days to memorize the key locations of the new layout; about a fortnight to touch-type with it at better-than-frustrating speed; about a month to get up to my previous typing speed. I'm happy with the Dvorak layout. I have no intention of voluntarily returning to the QWERTY layout. If you would like to find out more about the Dvorak keyboard, its reasons, its history, and its naysayers, then try visiting Introducing the Dvorak Keyboard, and The Dvorak Keyboard.

Also, something I found recently on the wonderful Web, anyone interested in deciding whether the Dvorak layout will reduce the amount of finger gymnastics they perform should visit the Keyboard Compare Applet [no longer operative because Java applets are no longer supported within web pages]. Copy all the text from a typical page you'd normally type, then paste it into the textbox of this applet and hit 'Calculate', and the Keyboard Compare Applet will work out how far your fingers would have travelled if you'd typed that text using each of the keyboard layouts. It should let you know quickly whether your usual daily workload could be typed more efficiently using the Dvorak layout. For instance, I copied the raw HTML from this very page and stuck it into the Keyboard Compare Applet (at the time of typing this paragraph - future updates will cause the numbers to fluctuate, obviously). My fingers would have travelled an extra 176m (an extra 52%) if I'd typed this page using the QWERTY layout, and I'd have had to reach more often for keys away from the 'home row' (the keys in the middle row, easiest to hit because they're right under your fingers' resting position). Dvorak is certainly better for me, but you'd be wise to copy and paste some of your own common documents into the applet textbox to see how Dvorak would perform for you.

Keyboard layout in FreeBSD

FreeBSD's installer (from version 5.0 at least) allows a choice of keyboard layout, based on the contents of /usr/share/syscons/keymaps. Some of the keymap files, as of version 5.2, include

jp.106.kbd
A layout for the 106-key Japanese keyboard.
jp.106x.kbd
The same as jp.106, but with Caps Lock and Ctrl swapped.
fr.iso.kbd
A French key layout.
fr.dvorak.kbd
"a Dvorak-like layout for French".
norwegian.iso.kbd
A Norwegian keyboard layout.
norwegian.dvorak.kbd
A Dvorak-like layout for Norwegian users.
uk.iso.kbd
A layout for UK keyboards, including the British Pound sign.
us.iso.kbd
A layout for US keyboards.
us.emacs.kbd
Alternative US layout, optimized for using Emacs.
us.unix.kbd
US alternative, traditional UNIX workstation keyboard layout.
us.dvorak.kbd
The Dvorak keyboard layout that I use.

You can use any of these in FreeBSD. While installing or configuring FreeBSD from the sysintall program, you can easily access a graphical (well, colourful text) user interface that allows you to choose the keyboard layout that you prefer. Once you choose your preferred layout, FreeBSD will use that layout for the login screen and for the shell.

To get to this graphical selection screen, just type

/stand/sysinstall

when you are logged in as root. Then select keymap from the menu, using the up/down cursor keys, and hit enter. Look through the list of keymaps using the up/down cursor keys and select the one you want to use. Then hit enter on OK to get back to the main menu of sysinstall. Then use tab or the left/right cursor keys to select Exit Install, and hit enter to exit. This will add a line to your /etc/rc.conf file, such as keymap="us.dvorak" and from then on you will be using the chosen keymap, even if you reboot FreeBSD.

Another way to change the keymap is to use the kbdmap command. Type

kbdmap

from a virtual console (keep that phrase in mind) and you will presented with a similar graphical user interface for choosing a keymap. The kbdmap command, however, does not write anything to /etc/rc.conf, so if you reboot FreeBSD, the keymap will be set back to whatever /etc/rc.conf specifies, or the standard default.

The problem with single user mode

The problem with using Dvorak in single user mode is this: single user mode is not a virtual console. It's the only console available and virtual consoles are not permitted in single user mode (that's the whole point of single user mode). So the kbdmap command does not have any effect on which keymap is used.

What's more, single user mode loads nothing unnecessary, so it doesn't even look at /etc/rc.conf, so it has no idea what keyboard you normally use. So, by default, it will use whatever is built into the kernel, and FreeBSD's standard kernel uses the standard keyboard layout - not the one you have specified. So Dvorak users will grumpily curse at a keyboard response that they weren't expecting when they first enter single user mode.

You can still run sysinstall, but you have to make sure that the partition that contains it is mounted. You can be sure of doing this by typing

mount -a

and then doing the same as before:

/stand/sysinstall

and choose the keymap you want to use as before. However, this will also add a keymap line to your /etc/rc.conf file, which you might not want to happen, and will begin to make the file a real mess (as it will not remove the existing keymap line first).

A better way is to use the kbdcontrol command like this:

kbdcontrol -l "us.dvorak"

(where the swtich is l for lion, and the name in quotes is a full path to a keymap file, or the name of a keymap file already in /usr/share/syscons/keymaps, and if the file is in the keymaps folder, the .kbd suffix can be left out). You will need to make sure you have mounted the relevant filesystems using the mount command before you use this command.

The kbdcontrol command is like a non-graphical version of the kbdmap command — it will not write anything to the /etc/rc.conf file, and once you exit single user mode or reboot you will go back to whatever keymap is specified in /etc/rc.conf or the default.

(A tip: if you get the error Inappropriate ioctl for device then make sure you're not in a script-output-shell, the sort that is started by using the script command to record the output of a standard command shell. Exit from the script-output-shell and you should be able to successfully issue the kbdcontrol command.)

Of course, you may decide that having to tell single user mode what keymap you prefer, every time, is an insult to all people who have chosen to use a different keyboard layout. There is a more extreme solution to the single user mode problem.

Setting Dvorak to be your kernel's default keymap

The reason that single user mode is a nuisance for Dvorak users is that it does not load /etc/rc.conf to find out what your choice of keymap is. But single user mode does have to load the FreeBSD kernel each time it loads. And the FreeBSD kernel has a huge number of options in it. The default keymap is one of those options.

However, you can't just set the option in a file and have it take effect from the next reboot like you can with the /etc/rc.conf file. Any changes to the FreeBSD kernel have to be compiled in. This is a fairly lengthy, and potentially risky task which I won't describe here because it is described better elsewhere. See the FreeBSD Handbook (which is online, and comes as part of your FreeBSD system, in /usr/share/doc/handbook as HTML files) for details on building and installing a custom kernel and read the instructions very carefully. You'll probably have to build and install the whole 'world', and that has associated risks. Make sure you're aware of them.

Once you know all about building a custom kernel and installing a new world, you should check in a file called NOTES, found in /usr/src/sys/conf. In the NOTES file are all the options that your FreeBSD kernel can take. I know that version 5.2 contains the option we're interested in, but make sure to check your NOTES file to see that it is a valid option for your version of FreeBSD.

Search the NOTES file for the phrase "atkbd" which refers to AT keyboard, and you should jump to a section that looks like this:

#
# Mandatory devices:
#

# The keyboard controller; it controls the keyboard and the PS/2 mouse.
device          atkbdc
hint.atkbdc.0.at="isa"
hint.atkbdc.0.port="0x060"

# The AT keyboard
device          atkbd
hint.atkbd.0.at="atkbdc"
hint.atkbd.0.irq="1"

# Options for atkbd:
options         ATKBD_DFLT_KEYMAP       # specify the built-in keymap
makeoptions     ATKBD_DFLT_KEYMAP=jp.106

# These options are valid for other keyboard drivers as well.
options         KBD_DISABLE_KEYMAP_LOAD # refuse to load a keymap
options         KBD_INSTALL_CDEV        # install a CDEV entry in /dev

# `flags' for atkbd:
#       0x01    Force detection of keyboard, else we always assume a keyboard
#       0x02    Don't reset keyboard, useful for some newer ThinkPads
#       0x03    Force detection and avoid reset, might help with certain
#                   dockingstations
#       0x04    Old-style (XT) keyboard support, useful for older ThinkPads

These are the device hints and compile options for the atkbdc and atkbd, the controller and the keyboard. The section that interests us at the moment is the 'options for atkbd' section. It shows that ATKBD_DFLT_KEYMAP is a valid option for the FreeBSD kernel that this NOTES document refers to. If you can't find this in your NOTES file, then assume your version of FreeBSD does not support this option.

If, though, you're confident that ATKBD_DFLT_KEYMAP is a valid option for your kernel, and you know how to create, build and install a custom kernel, then you need to open your custom kernel file (do not edit the GENERIC kernel file) and search for the phrase "atkbd" and you should find a line that says

device			atkbd

If the option ATKBD_DFLT_KEYMAP is not already mentioned in the file, then add these lines below the device atkbd line:

options        ATKBD_DFLT_KEYMAP
makeoptions    ATKBD_DFLT_KEYMAP=us.dvorak

If the option is already mentioned in the file, then just change the value after the equals sign to the keymap file that you want to use. (Remember, you can leave the .kbd suffix out, so long as the keymap file is in /usr/share/syscons/keymaps.)

Now that you have specified a default keymap in the custom kernel file, the FreeBSD kernel must be built and installed. Once this has been done (and make sure you know what you're doing — it's a good idea to back up all of your files before doing an installworld), you should be left with a FreeBSD system that gives you your beloved Dvorak keyboard layout, even in single user mode.

Dvorak in X.org

X.org has mostly replaced XFree86 in FreeBSD, and I noticed today that my newly installed X.org 6.8.1 ignored the fact that my kernel was built to use Dvorak as standard. I think this is because X.org has changed to a new keyboard driver called kbd. (See `man kbd` to see details.)

Whatever the cause, it seems simple enough to set X.org to the correct keymap.

Open your xorg.conf file. You should be very familiar with xorg.conf if you're running X. If not, go read up so you know what you're doing. Find the InputDevice section for your keyboard. Below the Identifier and Device lines, add an Option line with a key value of "XkbLayout" and a target value of the keymap that suits you.

For example:

Section "InputDevice"
    Identifier    "Keyboard0"
    Driver        "kbd"
    Option        "XkbLayout" "us.dvorak"
EndSection

A target value of "us.dvorak" works for me, but I can't find a location for where the kbd driver reads these keymaps from. It may be exactly the same place as FreeBSD stores its keymaps, but the kbd man page does not clear this question up. If you use a map other than Dvorak, try the name of your keymap that you use in FreeBSD normally, and see if it works.

One important exception

The only place that seems absolutely bent on always, always using a standard keyboard layout is the loader prompt. You know when FreeBSD is booting and you get a message saying Booting in 9 secs... hit [Enter] to skip, or any other key to get boot prompt? Well, if you do hit any other key and get the boot prompt (usually an OK prompt), it will give you a standard keyboard layout, even if you have compiled a custom kernel with a custom default keymap setting.

There is, as far as I know, no way of changing the keymap used by the boot prompt.

A word of caution

It is not advisable to change the default keymap to anything other that the expected map for your region if you are not the only user your system will ever have. Because of the huge prevalence of QWERTY, I can type using the Dvorak keyboard without actually having a physical keyboard that has Dvorak labels on the keys, and I imagine most Dvorak users are fully able to do the same. It's possible to know the effective layout of your preferred keyboard without needing key labels. However, it does not work the other way around - if a QWERTY user stumbles upon a system configured for Dvorak, they will have no way of making sense of the keyboard if the physical board still has QWERTY labels. In fact, they'll probably think the machine is malfunctioning. If other people need to use your system without you present (or if you need someone to access your system for you in an emergency — it could happen), it's important that the system is not completely inaccessible to them because every key they press offers them a completely unexpected character. Or worse, only some of the keys present them with unexpected characters (such as the difference between European layouts), and they don't notice at first.

In such a case, it's a better idea to leave FreeBSD with an expected default for the keymap (i.e. QWERTY in the US and UK and a lot of other areas of the world), and just use the kbdcontrol command when you need to switch to another keymap, or place the command in the initialization file that your preferred shell runs when you login to your user account. It's also possible to specify the standard keyboard layout again after you logout, by adding the kbdcontrol command to a logout file. For the TCSH/CSH shell, modify your .login file to change to your keymap, and your .logout file to change back to the expected, both in your home directory. For the BASH shell, modify the .profile file to change to your keymap when you login, and the .bash_logout file to change back when you logout; both files are in each user's home directory.

I did try to write a script that would automatically detect which keymap was in use, and switch to the other keymap. Unfortunately, kbdcontrol offers no way of discovering the keymap name of the keymap in use. I was also unable to work out a way of storing a variable with a scope beyond the life of the script, so I could not get the system to remember which keymap to switch out of each time. So I'm currently unable to provide a short-named script which would jump back and forth gracefully.

Accessibility would be nice

The fact is, until system developers realise that the users of a system may not all want to use the same keyboard layout, it's going to be a pain in the fingers to try to type on a layout we aren't used to.

For example, FreeBSD could offer a way of adding easily-switchable keymap choices to every entryway into the system. The login screen, for instance, could be configured to display with a menu above it offering something like this:

[F1] UK QWERTY
[F2] US Dvorak

I'm sure it's very easy to do, but because the vast, vast majority of keyboard users currently use the QWERTY keyboard (or a regional version of it), there is little chance of such a helpful feature being added.

Microsoft Windows XP makes the same mistake, too. Once you're logged into the desktop, Windows XP offers all sorts of handy ways of changing from one keyboard language to another, from one language layout to another. But the login screen only allows the language to be changed. So if there are two English layouts setup for use, such as UK QWERTY and US Dvorak, then Windows XP offers no way of changing from one to the other. So I still have to login using a keyboard layout I don't want to use anymore (and can't really remember anymore). Why a bulky, feature-laden operating system like Windows XP Professional cannot remember which keyboard layout I always use, and apply it to my login and password boxes, I don't know. But I'm guessing it's because nobody at Microsoft uses anything other than the QWERTY keyboard.

It would be so easy to extend keymap options to system entry points like this, including the FreeBSD loader prompt, or at least the single user mode prompt.

I hope that fairly soon there will be more consideration for access to multiple keyboard layouts.

Thanks

Thanks to Stéphane Witzmann for drawing my attention to the default keymap option in the FreeBSD kernel NOTES file.