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.
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 loadkeys
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:
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.
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.
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.
To avoid a lot of typing, one should now choose a keyboard layout, which matches best your physical keyboard layout:
kbd -s
When the keyboard layout to use has been set, one needs to activate it:
loadkeys
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).
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:
KNAME='German-MacBook-Pro' grep "$KNAME=" kbd_layouts
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 KNUM=333 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.
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
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!
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:
Key | Code | fn Name | Escape Seq. | Notes |
---|---|---|---|---|
Left Function block | ||||
Stop | 120 | buckybits+systembit | ||
Again | 121 | lf(2) | ^[[193z | |
Props | 118 | lf(3) | ^[[194z | |
Undo | 122 | lf(4) | ^[[195z | |
Front | 119 | lf(5) | ^[[196z | |
Copy | 124 | lf(6) | ^[[197z | |
Open | 116 | lf(7) | ^[[198z | |
Paste | 125 | lf(8) | ^[[199z | |
Find | 126 | lf(9) | ^[[200z | |
Cut | 123 | lf(10) | ^[[201z | |
Help | 117 | lf(16) | ^[[207z | |
Right Function block | ||||
Pause | 72 | rf(1) | ^[[208z | |
70 | rf(2) | ^[[209z | ||
ScrollLock | 71 | rf(3) | ^[[210z | |
Speaker toggle/Degauss | 127 | rf(4) | ^[[211z | |
: | 84 | rf(5) | ^[[212z | keypad |
* | 85 | rf(6) | ^[[213z | keypad |
Home / Pos 1 | 74 | rf(7) | ^[[214z | |
Home / Pos 1 | 95 | rf(7) | ^[[214z | keypad |
Page Up | 75 | rf(9) | ^[[216z | |
Page Up | 97 | rf(9) | ^[[216z | keypad |
93 | rf(11) | ^[[218z | keypad (on 5) | |
End | 77 | rf(13) | ^[[220z | |
End | 89 | rf(13) | ^[[220z | keypad |
Page Down | 78 | rf(15) | ^[[222z | |
Page Down | 91 | rf(15) | ^[[222z | keypad |
Top Function block | ||||
F1 | 58 | tf(1) | ^[[224z | |
F2 | 59 | tf(2) | ^[[225z | |
F3 | 60 | tf(3) | ^[[226z | |
F4 | 61 | tf(4) | ^[[227z | |
F5 | 62 | tf(5) | ^[[228z | |
F6 | 63 | tf(6) | ^[[229z | |
F7 | 64 | tf(7) | ^[[230z | |
F8 | 65 | tf(8) | ^[[231z | |
F9 | 66 | tf(9) | ^[[232z | |
F10 | 67 | tf(10) | ^[[233z | |
F11 | 68 | tf(11) | ^[[234z | |
F12 | 69 | tf(12) | ^[[235z | |
Bottom Function block | ||||
Ins | 73 | bf(8) | ^[[247z | |
Ins | 98 | bf(8) | ^[[247z | keypad |
Del | 99 | bf(10) | ^[[249z | keypad |
Enter | 88 | bf(11) | ^[[250z | keypad |
Sleep/Suspend | 102 | bf(13) | ^[[252z | |
+ | 87 | bf(14) | ^[[253z | keypad |
- | 86 | bf(15) | ^[[254z | keypad |
Other | ||||
Volume/Contrast decrease | 129 | |||
Volume/Contrast increase | 128 | |||
NumLock | 83 | shiftkeys+numlock | ||
arrow up | 82 | string+uparrow | ^[[A | |
arrow left | 81 | string+downarrow | ^[[B | |
arrow right | 79 | string+rightarrow | ^[[C | |
arrow left | 80 | string+leftarrow | ^[[D | |
Del | 76 | '\177' | ||
Ctrl left | 224 | shiftkeys+leftctrl | ||
Alt | 226 | shiftkeys+alt | ||
Meta right | 231 | buckybits+metabit | ||
Meta left | 227 | buckybits+metabit | ||
Compose | 101 | 0x309 | ||
AltGr | 230 | shiftkeys+altgraph | ||
Esc | 41 | ^[ | ||
Tab | 43 | '\t' | ||
CapsLock | 57 | shiftkeys+capslock | ||
Shift left | 225 | shiftkeys+leftshift | ||
Shift right | 229 | shiftkeys+rightshift | ||
Enter | 40 | '\r' | ||
Backspace | 42 | '\b' |
Copyright (C) 2010 Jens Elkner (jel+mac@cs.uni-magdeburg.de)