Linux Console Keymaps
To change the keymaps for the virtual terminals ( alt+f1 - alt+f6 ) you use loadkeys. This only effects the virtual terminal logins and will not change keymaping in X or X terminal apps like Xterm or urxvt.
The loadkeys command needs to be run as root or you will get the following error:
Couldn't get a file descriptor referring to the console
To swap escape and caps_lock you would do the following:
# echo keycode 58 = Escape | loadkeys -
# echo keycode 1 = Caps_Lock | loadkeys -
Another option is to remap the Caps_Lock to shift + Scroll Lock
# echo keycode 69 = Num_Lock Caps_Lock | loadkeys -
The format of the keymaps can be a little confusing. It using a weighting system depending on which modifiers that are pressed. ( Ctrl, Alt, Shift, etc ). As an example from the man page for keymaps.
keycode 30 = a A VoidSymbol VoidSymbol VoidSymbol .....
When the shift and a is pressed we do the action in the second column because shift has a weighting of 1. control on the other hand has a weighting of four.
This can cause problems when mapping modifiers. Take for instance if a keycodes first and only column is control as its action. Now the weighting since you pressed it is now 4 and when you release the key it the control is not show released because the 5th column action is now to be performed but it has no action defined. So the control key is never released.
This is why most modifiers have no other action assigned. If only one action is defined in the keyboard mapping then it is applied to all actions.
I have played around trying to work around this but have only ever got inconsistent results. Sometimes the modifier releases, sometimes it does not.
Changing the Caps Lock to perform as either escape or as control works great with this method. Mapping to both, not so much.
If you screw up your keymap do the following to reset it.
# loadkeys -d