Solaris Keyboard Howto

Recently I installed Solaris 11 Express in a VirtualBox VM on my MacBook Pro 3.1. Unfortunately my MacBook has a german keyboard (which is really strange BTW) and does not conform to the usual USB keyboards and thus there was no way to get the solid bar aka pipe symbol and some other essential signs printed on the command line (console). So I took some time to find out, how to make the keyboard behave as I want it to and here is, what I've found out.

Setting the default keyboard layout

If you have a standard keyboard, Solaris has usually all you need. If it did not find out automatically, what kind of keyboard is connected to the system, you may set it explictly by setting the keymap/layout property of the keymap:default service:

svccfg -s keymap:default setprop keymap/layout=German
svcadm refresh keymap

To choose another keyboard layout on the fly, one may use:

kbd -s

This tool shows you all available layout names (which can be used for the keymap/layout property of the keymap:default service as well) and lets you choose the one to use. The loadkeys command is required, to finally activate the new layout.

Another way to set the default keyboard layout is to set the appropriate eeprom/OBP property:

eeprom set keyboard-layout=German
# and to avoid confusion
svccfg -s keymap:default delprop keymap/layout
svcadm refresh keymap

This works, since the keymap service starter first looks at the eeprom/OBP settings for the keyboard-layout property, and if its value is valid, kbd -s $value is used to set the default keyboard layout. If it the keymap:default service property keymap/layout is also set, the starter uses kbd -i to set the keyboard layout according to property value (otherwise the currently set keyboard layout will be kept). Last but not least it does a loadkeys to activate the layout.

Further information can be found in:

Defining a new keyboard layout

As mentioned before, many laptops have their "own" keyboard layout, and thus using a default keyboard layout coming with Solaris is quite a pain. In this case it is the best to create a new keyboard layout map and use this one instead. All you need to do for this is to add your layout name and ID to the file kbd_layouts in the /usr/share/lib/keytables/type_6 directory (the type_6 directory hosts all layouts for USB keyboards) and to add the file layout_HexID, which contains your modifications to the default keyboard layout.

However, before you go ahead, you should read the man page for kbd and keytables, since I'm not going to explain/repeat every tiny detail.


The first thing to know wrt. defining a new keyboard layout are the scancodes, which are sent by each key. Usually each key sends always the same scancode, no matter which modifiers (CapsLock, Shift, Alt, AltGr, Meta, Command, etc.) are pressed down. However, some keyboards (especially laptops/notbooks) have special keys as well as a function key (fn), which cause some keys to emit a different scancode when they are pressed together. Also if no separate numeric keypad is available on the keyboard, there is usually a key combination, which lets you switch the keyboard into the numeric keypad mode, where some keys also emit different or no scancodes at all.

However, since scancodes are almost always an undocumented feature of the keyboard, keys are named different than in the USB specification 1.12, HID Usage Tables, KEYBOARD/KEYPAD PAGE (0X07), page 53ff., or keyboard emulation is buggy (as in VirtualBox 3.2.10 and 3.2.12), we need a reliable way to find them out. With Solaris it is easy to do that using the function probe provider of its wonder wappen dtrace:

dtrace -n 'fbt:kbtrans:kbtrans_translate:entry { printf("%d\n",arg2) }'

Now you can press every key in each different keyboard mode, to see whether and which scancode gets emitted. For the MacBookPro 3.1 with the default german keyboard layout it may look like this table.

keyboard type

To determine the correct directory, where one needs to put the new keyboard definition file, one needs to get the type of keyboard in use. kbd -l shows, what you need to know. For later use, we store the type into the env variable KT :

KT=`kbd -l | fgrep type= | cut -f2 -d=`

For USB keyboards you will usually get type 6.

keytables directory

Now you should change your current working directoy to the directory, which contains the layout definitions for the type of keyboard in use:

cd /usr/share/lib/keytables/type_$KT

If it does not exist, create it, using mkdir -p and cd to it.

set the layout to use

To avoid a lot of typing, one should now choose a keyboard layout, which matches best your physical keyboard layout:

kbd -s

activate layout

When the keyboard layout to use has been set, one needs to activate it:


You may verify, that the changes are active, by pressing one of the "non-standard" keys wrt. your country (e.g. characters with diaresis aka umlaut or accent grave/acute).

layout name

To be able to select your keyboard layout with kbd -s and also to set it as default in eeprom or keymap:default service, one need to give it a name. It should be not longer than 30 characters. Also to avoid trouble, it is highly recommended to use ASCII letters, digits, underlines and hyphens, only and of course a name, which is not already defined in the file kbd_layouts. For later use, we store that name in the env variable KNAME:

grep "$KNAME=" kbd_layouts

layout ID

Also you need to assign an ID to your new keyboard layout. Of course you need to make sure again, that the new ID is not already in use. E.g.:

fgrep = kbd_layouts  |sort -t= -k2n
KHEX=`printf '%02x' $KNUM`

For our convinience we store the new ID in the env variable KNUM and its hexadecimal value in the env variable KHEX.

dumping the active layout

Now dump the the keyboard layout, which is currently active, to the new layout file to use: it must have a name in the format layout_ID , whereby the ID must be the hexadecimal value with at least two digits of the layout ID you have choosen in the previous step. E.g.:

dumpkeys >layout_$KHEX

publish keyboard layout name and ID

A you probably already guessed, to make the new layout available to the kbd -s as well as the keymap:default service, one needs to "publish" its name and ID. This can be done by just adding a new entry to the kbd_layouts in the appropriate keyboard type directory. The format of the entry is simple: layoutName=ID. Obviously the layoutName is the name you have choosen for your new keyboard layout, and the ID is the ID of the layout - this time in decimal (see above). E.g.:

echo "$KNAME=$KNUM" >>kbd_layouts

Finally try, whether the previously dumped layout works, using the kbd -s and loadkeys command. If you see any errors, just comment out the line in question by inserting a # at the start of the line (i.e. column 0) and try again.

If it finally works without any error message, you have now a starting point and shoud be able to modify the layout as you like (see man page keytables) and set it as the default keyboard layout to use as described above.

Solaris 11 Express seems to have bug wrt. the swap number1 with number2 instruction: it assigns the values for keystation number1 to keystation number2, but keystation number1 is set to an empty value aka 'all hole' and not to the previous values of number2!

Function key names

When defining a new keyboard layout, you probably get curious, what strings to use for the top (tf), left (lf), bottom (bf) and right (rf) function keys or what these keys are actually supposed to be. Actually, under the hood this is a block of 4*16=64 scancodes, where lf(1) marks the start of the first, rf(1) the start of the second, tf(1) the start of the third and bf(1) the start of the last block (see /usr/include/sys/kbd.h and the man page for kb). The corresponding Escape Sequences start at 192 for lf(1) and stop at 255 for bf(15).

Unfortuetaly I haven't found a reliable source yet, which lets you determine easily, which function is assigned to the Escape Sequences mentioned above, and also no source, which defines, what ?f(n) to use for which "special key". So I took an original SUN keyboard, dumped its keyboard layout and assigned they names on those keys to the used ?f(n) code via their scancode:

Function Names and Scancodes for a SUN™ keyboard
KeyCodefn NameEscape Seq.Notes
Left Function block
Right Function block
Speaker toggle/Degauss127rf(4)^[[211z
Home / Pos 174rf(7)^[[214z
Home / Pos 195rf(7)^[[214zkeypad
Page Up75rf(9)^[[216z
Page Up97rf(9)^[[216zkeypad
93rf(11)^[[218zkeypad (on 5)
Page Down78rf(15)^[[222z
Page Down91rf(15)^[[222zkeypad
Top Function block
Bottom Function block
Volume/Contrast decrease129
Volume/Contrast increase128
arrow up82string+uparrow^[[A
arrow left81string+downarrow^[[B
arrow right79string+rightarrow^[[C
arrow left80string+leftarrow^[[D
Ctrl left224shiftkeys+leftctrl
Meta right231buckybits+metabit
Meta left227buckybits+metabit
Shift left225shiftkeys+leftshift
Shift right229shiftkeys+rightshift


Copyright (C) 2010 Jens Elkner (