Changed my keyboard layout in hardware to colemak!

YES! So glad somebody’s using this stuff.

Ah, you’re in for a surprise! :smile:

These modifications will survive in EC RAM until the EC reboots. When you power off the machine, the EC loses power about 30 seconds later. You’ll want to apply this on each boot.

I wrote an EFI driver to remap Caps to Esc before the OS starts; perhaps we can do something similar here? Imagine! A pre-OS driver that applies a saved keyboard layout no matter what it is.

FYI: the remap command can take up to 21 (EDIT: NOPE! 32) (good job Dustin with that hex value) key positions and scancodes, which could make your script much shorter/faster at the cost of some clarity.

4 Likes

Hah, I was impatient and only tested a 10 sec or so shutdown. I’ll put it as a systemd service & suspend wakeup script (for hibernation resume)

I’ll keep it as is, simply to have the little readability that I do have :stuck_out_tongue: I timed it, it only takes 1.05 sec to run the commands, and I could shorten it by getting rid of keys that are the same for both layouts. If I were to figure out your EFI driver thing, it could be compressed into a single command to keep it simple for adapting it there.

Here’s me removing a keycap: https://www.youtube.com/watch?v=p8tTETq-WGE

Turn up sound to hear the clicks from the clips on top disconnecting. Don’t try to pry from the bottom, because the clips there go behind the keyswitch, so it would probably break the keycap. the clips in the top though are basically just friction based, as long as you pull in the general direction of up they will come off. If the ones on the bottom are still connected after you disconnect the top ones, just wiggle the cap forward and back a bit.

I won’t post a video of me typing for now because 1) I don’t have a good way to mount my phone, 2) my phone camera and mic is waterlogged (the waterproof seals gave up on me) so it looks like shit as you can see above, and 3) despite picking this keyboard layout, I’m not actually a very good typer. It’s just colemak is a little better than QWERTY for me. when I get my new phone soon I might take a video.

3 Likes

And here’s my systemd script. After enabling it, it runs both after resuming from hibernate, and during a normal boot. /usr/local/bin/fw-ec-setup is just a script that runs my remap script as well as a little light sequence with the LEDs to let me know it worked.

$ cat /etc/systemd/system/fw-ec.service 
[Unit]
Description=Setup EC for keyboard layout, lights, etc.
After=hibernate.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/fw-ec-setup
RemainAfterExit=false
StandardOutput=journal

[Install]
WantedBy=multi-user.target hibernate.target
1 Like

Very interested in using this to get a native Colemak layout, have there been any problems in the interim?
I don’t completely understand what ectool does, but does this introduce any extra latency in key presses, even just theoretically?

1 Like

I’ve not heard of any problems caused by people remapping their keys. This method overwrites the key lookup tables in memory on the keyboard controller[^1], so it almost provably does not introduce any extra latency.

[^1]: really the Embedded Controller, but it is also acting as the keyboard controller.

@DHowett @shark Thanks for all the work y’all have put in on this topic.

I need a little help,
I am trying write a bash script to remap several keys at startup. I have been reading both of your blogs and posts for guidance.

The main issue is that I dont know what to do for FN Key.

This is what I have so far

#!/bin/bash

# Remap Lctrl to Lalt
sudo fw-ectool 0x3E0C d1,d1,b1,bc,w56

# Remap Lalt to FN
sudo fw-ectool 0x3E0C d1,d1,b1,b3,????

# Remap FN to Rctrl
sudo fw-ectool raw 0x3E0C d1,d1,b2,b2,w97

My goal is for the bottom row of my keyboard to be as follows:

| Ctrl | Alt | Meta | Ctrl | Space Bar | Alt | Fn | :arrow_backward: | :arrow_up: / :arrow_down: | :arrow_forward: |

I used a macbook for many years and got used to using the command key which does some of what ctrl does on other systems so I like having ctrl next to the spacebar. the Fn key would be nice to have next to the arrow keys for easily jumping around the the terminal.

I use a lot of virtual machines also so I would like to have a method to setup the keyboard system wide.

Any help would be much appreciated.

1 Like

As of today, Fn has the scancode 0xFF.

You can remap the key in Left Alt’s position to emit Fn with ectool raw 0x3e0c d1,d1,b1,b3,wff

Don’t forget the raw on those first few commands!

EDIT: Though, reading over your proposal I don’t think that you’ll get what you’re looking for with the commands you have.

The key mapping host command maps positions to new scancodes and not the other way around.

In the line you’ve commented “Remap FN to Rctrl,” what you’re doing is remapping the key at position 2,2 to emit the scancode for Right Ctrl; this will effectively make the key labelled Fn into a Right Ctrl key.

The first one is also unexpected. It will remap the key at position 1, 12 (labelled Left Ctrl) to emit scancode 0x56 (I do not believe that this is a valid 8042 scancode.).

2 Likes

You can achieve what you’re looking for with the following mappings:

sudo fw-ectool raw 0x3e0c d7,d1,b1,bC,w14, \
                                b2,b2,w11, \
                                b3,b1,wE01F, \
                                b1,b3,wE014, \
                                b1,b4,w29, \
                                b0,b3,wE011, \
                                b0,bC,wFF
# This will remap:
# R, C
# 1, 12 (LCtrl) -> LCtrl (Unchanged)
# 2,  2 (Fn)    -> Alt
# 3,  1 (LMeta) -> LMeta (Unchanged)
# 1,  3 (LAlt)  -> RCtrl
# 1,  4 (Space) -> Space (unchanged)
# 0,  3 (RAlt)  -> RAlt (unchanged)
# 0, 12 (RCtrl) -> Fn

Wow, it is really hard to get used to this mapping!

5 Likes

@ DHowett Thanks for the quick response.

Yeah I think my head was spinning when I 1st attempted to write the script. I really appreciate you making sense of it.

I didn’t realize my layout was so strange. Now that I think about it though it probably is because I used parallels on mac to run linux VMs for years which mapped keys oddly. cmd as ctrl and alt as meta.

The FN on the right was an idea I got from another post which made sense to me.

having ctrl under shift also makes sense for a lot of shortcuts.

But I guess it is pretty odd now that I tried to justify it.

Thanks Again!

3 Likes

for mapping itself - yes, but the whole “cmd” button in macOS puts much less strain on you left hand. i used windows then linux for 9 years before trying macOS for the first time. it took me 4 days to get used to cmd+c/v/x/etc combinations and now I can’t go back to ctrl+stuff the reason is simple: your left thumb in resting position will be approximately between space and “cmd” (alt on windows standard keyboards) and your pinky will be in area of caps lock and tab. your thumb so called “strong” finger, while your pinky is “weak” finger. because of that generally cmd-based combinations put muuuch lest strain on your hand. i strongly recommend trying that yourself :slight_smile: the only inconvenience outside macOS is the fact that apps and OS are not unified and in 99% use ctrl-based shortcuts exclusively. this gets annoying with copy/paste conflicting with terminal shortcuts

1 Like

I also prefer Mac keyboard layout and I configure my laptop to have the following order of bottom keys: ctrl, fn, alt, logo, space, logo, alt. Logo key is then used for ctrl shortcuts in X11 (so logo key is mapped to ctrl, while ctrl key is mapped to super key). While I patch Ubuntu/Gnome Terminal to use super key as ctrl key, so that visually you press ctrl-c and it sends super-c to Terminal which then interprets it as ctrl-c (and you send and interrupt). If you press logo-c, that sends ctrl-c to Terminal and window program copies selection to a clipboard.

I would love if Framework could support a custom keyboard layout like this, including making a keyboard cover which would match those keys.

3 Likes

Will this run before LUKS so that my LUKS password will be typed using the remapped keys?

Cc @DHowett

Here’s Dvorak with the Caps mapped to Escape

#!/bin/env bash
# Framework en-us dvorak

ectool raw 0x3E0C d1,d1,b3,b2,w0d # Tab > Tab
ectool raw 0x3E0C d1,d1,b0,b2,w52 # q > '
ectool raw 0x3E0C d1,d1,b6,b5,w41 # w > ,
ectool raw 0x3E0C d1,d1,b2,b4,w49 # e > .
ectool raw 0x3E0C d1,d1,b6,b6,w4d # r > p
ectool raw 0x3E0C d1,d1,b3,b6,w35 # t > y
ectool raw 0x3E0C d1,d1,b3,b7,w2b # y > f
ectool raw 0x3E0C d1,d1,b6,b7,w34 # u > g
ectool raw 0x3E0C d1,d1,b6,ba,w21 # i > c
ectool raw 0x3E0C d1,d1,b3,b8,w2d # o > r
ectool raw 0x3E0C d1,d1,b5,bd,w4b # p > l
ectool raw 0x3E0C d1,d1,b6,bd,w4a # [ > /
ectool raw 0x3E0C d1,d1,b6,be,w55 # ] > =
ectool raw 0x3E0C d1,d1,b2,b8,w5d # \ > \

ectool raw 0x3E0C d1,d1,b4,b4,w76 # Caps > Escape
ectool raw 0x3E0C d1,d1,b7,b2,w1c # a > a
ectool raw 0x3E0C d1,d1,b4,b5,w44 # s > o
ectool raw 0x3E0C d1,d1,b7,be,w24 # d > e
ectool raw 0x3E0C d1,d1,b7,b6,w3c # f > u
ectool raw 0x3E0C d1,d1,b2,b6,w43 # g > i
ectool raw 0x3E0C d1,d1,b2,b7,w23 # h > d
ectool raw 0x3E0C d1,d1,b7,b7,w33 # j > h
ectool raw 0x3E0C d1,d1,b7,ba,w2c # k > t
ectool raw 0x3E0C d1,d1,b7,b8,w31 # l > n
ectool raw 0x3E0C d1,d1,b7,bd,w1b # ; > s
ectool raw 0x3E0C d1,d1,b0,be,w4e # ' > -

ectool raw 0x3E0C d1,d1,b1,b5,w4c # z > ;
ectool raw 0x3E0C d1,d1,b0,b5,w15 # x > q
ectool raw 0x3E0C d1,d1,b0,b0,w3b # c > j
ectool raw 0x3E0C d1,d1,b0,b6,w42 # v > k
ectool raw 0x3E0C d1,d1,b1,b6,w22 # b > x
ectool raw 0x3E0C d1,d1,b1,b7,w32 # n > b
ectool raw 0x3E0C d1,d1,b0,b7,w3a # m > m
ectool raw 0x3E0C d1,d1,b0,ba,w1d # , > w
ectool raw 0x3E0C d1,d1,b0,b8,w2a # . > v
ectool raw 0x3E0C d1,d1,b0,bd,w1a # / > z
3 Likes

For all my colemak-dh lovers out there. (ANSI variant). With caps lock replaced with backspace.

#!/bin/bash
# Framework en-us qwerty >>> colemak-dh (caps lock changed to backspace) 

ectool raw 0x3E0C d1,d1,b3,b2,w0d # Tab > Tab
ectool raw 0x3E0C d1,d1,b0,b2,w15 # q > q
ectool raw 0x3E0C d1,d1,b6,b5,w1d # w > w
ectool raw 0x3E0C d1,d1,b2,b4,w2b # e > f
ectool raw 0x3E0C d1,d1,b6,b6,w4d # r > p
ectool raw 0x3E0C d1,d1,b3,b6,w32 # t > b
ectool raw 0x3E0C d1,d1,b3,b7,w3b # y > j
ectool raw 0x3E0C d1,d1,b6,b7,w4b # u > l
ectool raw 0x3E0C d1,d1,b6,ba,w3c # i > u
ectool raw 0x3E0C d1,d1,b3,b8,w35 # o > y
ectool raw 0x3E0C d1,d1,b5,bd,w4c # p > ;
ectool raw 0x3E0C d1,d1,b6,bd,w54 # [ > [
ectool raw 0x3E0C d1,d1,b6,be,w5b # ] > ]
ectool raw 0x3E0C d1,d1,b2,b8,w5d # \ > \

ectool raw 0x3E0C d1,d1,b4,b4,w66 # Caps > Bkspc
ectool raw 0x3E0C d1,d1,b7,b2,w1c # a > a
ectool raw 0x3E0C d1,d1,b4,b5,w2d # s > r
ectool raw 0x3E0C d1,d1,b7,be,w1b # d > s
ectool raw 0x3E0C d1,d1,b7,b6,w2c # f > t
ectool raw 0x3E0C d1,d1,b2,b6,w34 # g > g
ectool raw 0x3E0C d1,d1,b2,b7,w3a # h > m
ectool raw 0x3E0C d1,d1,b7,b7,w31 # j > n
ectool raw 0x3E0C d1,d1,b7,ba,w24 # k > e
ectool raw 0x3E0C d1,d1,b7,b8,w43 # l > i
ectool raw 0x3E0C d1,d1,b7,bd,w44 # ; > o
ectool raw 0x3E0C d1,d1,b0,be,w52 # ' > '

ectool raw 0x3E0C d1,d1,b1,b5,w22 # z > x
ectool raw 0x3E0C d1,d1,b0,b5,w21 # x > c
ectool raw 0x3E0C d1,d1,b0,b0,w23 # c > d
ectool raw 0x3E0C d1,d1,b0,b6,w2a # v > v
ectool raw 0x3E0C d1,d1,b1,b6,w1a # b > z
ectool raw 0x3E0C d1,d1,b1,b7,w42 # n > k
ectool raw 0x3E0C d1,d1,b0,b7,w33 # m > h
ectool raw 0x3E0C d1,d1,b0,ba,w41 # , > ,
ectool raw 0x3E0C d1,d1,b0,b8,w49 # . > .
ectool raw 0x3E0C d1,d1,b0,bd,w4a # / > /

So does this approach work to remap the airplane mode key on F10, which seems to be the only function key that you can’t change from the OS? (Disabling Flight Mode / Airplane Mode Function Key F10 - is it possible?).
I’m a bit confused by some of the complex ins and outs of this low level system-dependent stuff.
I concur with the poster there that the Airplane key is obsolete, and my goal would be:

remap the Airplane mode key on my Framework to “Home” (so “Home” is airplane key and “End” is the Framework cog, since I have no use for physical buttons for those features)

In particular, does anyone have an example that would do that, on a Framework 13, that I can run on Linux (Ubuntu 22.04).

I think not, as I understand it: You would need to have these remaps run in your initrd image as I believe that is what is providing the environment for you to type your LUKS password. Your normal systemd system services wouldn’t be run until after your LUKS partition has been decrypted.

(Same sort of thing as having an ssh server setup in your initrd so you can type your LUKS password remotely after a reboot - I may give doing remaps in initrd a try in my NixOS config at some point as nix should make automating this pretty easy). Presumably with this arrangement you could drop running these remaps during the system start and just run them on resume from sleep as they should persist in the EC’s memory after having been set by the initrd image which would always happen when booting.

This is the code here: EmbeddedController/board/hx20/keyboard_customization.c at 553827caae7134d45a0617af9c201e333eab9a26 · FrameworkComputer/EmbeddedController · GitHub

It works by checking if Fn is pressed and then calling a different function for HID stuff. I think all you have to do is move the F10 and the rfkill/airplane mode would move with it but I could be wrong. There is only the hid enum and no scancode listed so I am pretty sure.

I see that it is possible to change the key map/matrix temporarily until the EC reboots with commands. Why not just modify the EC code directly and flash the modified version so that it lasts until next update? This way a systemd job is not needed on every reboot.
Is modifying the keymap in EC firmware source code possible?

Havent tried it, but absolutely should be possible.

Drawbacks; will be wiped during BIOS update

could mess up your EC during flashing process - if you do, everything like e.g. the power button won’t work and the laptop can’t boot anymore. Would have to use clip-on programmer maybe to restore it.

Current method in this post is much safer.

1 Like

Minor addition, with at least on one FWL13 version (if not all) it’s a WSON 6x5mm chip. Less convenient than using a clip-on. You need to hold a pogo pin jig down on the chip during the process.

1 Like