Hardware Hacking on Linux

一些增加生活质量的, 软件层面的硬件使用:

Keyboard Mapping

CapsLock 是个大 bug, 十分不常用 (其实是完全可以不用), 但占了一块好位置, 还比别的键大, 简直不能忍.

尽管 BIOS 里能将 Left Ctrl 与 Fn 互换, 如果能把 CapsLock 映射到 Ctrl 的话, 对生活质量仍然是有极大提高的, 毕竟 Ctrl 太常用了, 对不写代码的人也是一样 (但是不写代码的人不用 Linux 吧..). 我们可以用xmodmap 工具来实现这一点.

xmodmap 是用于在 X 中改变 keymap 的工具. 它有一个丑陋的图形化前端 xkeycaps, 但是由于过于丑陋了所以还是用命令行好了.

利用xmodmap -pke 命令可以查看当前的键盘映射表, 输出大概会长这个样子:

keycode   9 = Escape NoSymbol Escape
keycode 10 = 1 exclam 1 exclam
keycode 11 = 2 at 2 at
keycode 12 = 3 numbersign 3 numbersign
keycode 13 = 4 dollar 4 dollar
keycode 14 = 5 percent 5 percent
keycode 15 = 6 asciicircum 6 asciicircum
...

xmodmap 的映射语法是, "keycode x = y" 或 "keysym x = y", 将左边的 keycode 或 keysym 映射成右边的. 另外, shift, capslock, control, alt 等 modifier 以 group 的形式被接受, 可以用 add/remove 命令添加新的键. 在 X 启动时 xmodmap 会自动~/.Xmodmap 文件, 因此可以在此文件中写入如下几行:

keysym Caps_Lock = Control_L
remove lock = Caps_Lock (或clear Lock)
add control = Control_L

不过说不准有时候还要用 CapsLock, 比如 CapsLock 在执行 map 之前已经被打开了就麻烦了.. 所以我把完全不会用到的 PrintScreen 映射到了 CapsLock 上.

上张照片以便更好理解:

另外, ThinkPadT420 上, 方向键旁边有两个奇怪的键, 在 windows 中貌似是前进 / 后退.. 由于 T420 的 PageUp/PageDown 在右上角最偏远的地方, 因此我把这两个没用的键 map 到了 PageUp/PageDown 上.

keycode 107 = Caps_Lock
keycode 167 = Next
keycode 166 = Prior

keycode 的获取可以通过xev 命令: 它会打开一个小窗口, 捕捉 X event, 在其窗口中按键能在命令行看到这样的输出:

KeyPress event, serial 39, synthetic NO, window 0x3c00001,
root 0x8d, subw 0x0, time 6242012, (744,255), root:(2113,279),
state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False

这样就能找到一个键对应的 keycode, keysym 了.


对于 vimer 来说, 还有一个严重的历史问题: 在 vim 出现的时候, 那时的键盘上的 Esc 大约在 Tab 的位置, 而如今大多数电脑上 Esc 都离手很远, 因此不方便在 vim 中切换 normal 模式.

这个问题当然有不少解决方案, 例如 vim 中将其他键映射成 Esc,

我的vim配置中就有几个这样的map.

一个全局的解决方案是: 充分剥削 CapsLock (也即现在的 Control) 作为 modifier 的剩余价值, 因为它的位置实在太好了.

xcape 就是这样的一个小工具. xcape -e "Control_L=Escape" 命令可以使得短按 Left Control 或 CapsLock 时产生一个 Esc 事件, 而与其他键组合使用时行为正常.

Keyboard Speed

xset 工具可以调整按住一个键时, 键盘事件的触发频率, 也即让键盘更灵了. 另外还有一些 vim 插件可以实现键盘加速, 这些我在Work Faster 中都提到过.

TouchPad

我的 TouchPad 在一次进水之后就出了奇怪的问题: 偶尔会触发一个鼠标持续按下的事件. 这对电脑的正常使用显然有很大影响.

我最初的解决方案是把 TouchPad 完全禁用掉, 只用 joystick (触摸区域上面的按键属于 joystick, 下面的属于 TouchPad, 功能冗余了):

xinput disable 13		(其中13是我的TouchPad的device id, 可通过 xinput | grep -o "TouchPad.*id=[0-9]*" |grep -o "[0-9]*" 获取)

当然这样太暴力了, 而且 joystick 小红点的鼠标移动还是没有 TouchPad 方便. 希望的解决方案是, 只禁用它发出的按键事件, 而保留移动功能.

首先观察设备的状态:

$ watch -n 0.5 xinput query-state 13
ButtonClass
button[1]=up
button[2]=up
button[3]=down
button[4]=up
button[5]=up
button[6]=up
button[7]=up
button[8]=up
button[9]=up
button[10]=up
button[11]=up
button[12]=up
ValuatorClass Mode=Relative Proximity=In
valuator[0]=4416
valuator[1]=2245
valuator[2]=0
valuator[3]=776

输出里可以看到若干个 button 和 valuator, button 是布尔值, valuator 是个数值, 它们表达了 TouchPad 的当前状态. 我发现当我的设备异常时, 2,3 号 button 可能会出现持续按下 (状态为 down) 的情况, 而 TouchPad 上的左右两个键都会导致 1 号 button 被触发. 因此我可以禁用 2 号和 3 号 button:

xinput set-button-map 13 1 0 0

这样做了之后相当于我只损失了右键的功能 (也包括触摸屏上双指同时按触发的右键), 用 joystick 代替就好, 损失并不大.

Finger Print

Linux 对我的笔记本上的指纹装置 (位于图上方向键下方) 有很好的支持, 安装 fprintd 之后直接就可以使用. 通过fprintd-enroll 进行注册, fprintd-verify 进行验证.

如果仅仅将指纹用于登陆实在是太鸡肋了, 而且恐怕我的登陆管理器 (slim) 也未必支持. 但是在 Linux 里一遍遍的敲 sudo 密码想必让很多人头疼, 尤其是在一些特殊情况下 (键盘不好、 周围有人等). 要更改 sudo 验证方式, 可以在配好 fprintd 之后编辑/etc/pam.d/sudo, 将其改成如下内容:

auth		required	pam_env.so
auth sufficient pam_fprintd.so
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth required pam_nologin.so
auth required pam_deny.so

这样 sudo 的时候, 会先扫指纹, 失败或超时了再敲密码. 摆脱了快要敲烦了的密码, 而且可以在命令行狂敲不止时获得短暂的休息.

这样的一个损失是, ssh 的话无法扫指纹, sudo 会先失败一下. 不过反正我几乎不会 ssh 到自己的电脑上.

CPU Frequency

以前通过设定 governer 来调整频率:

sudo cpupower frequency-set -g powersave

但是最近发现即使是 powersave 模式, CPU 频率还是挺高. 为了断电后能够用的久一点, 可以直接调整最大频率:

sudo cpupower frequency-set -u 1000000

Fan

可以通过/proc/acpi/ibm/ 下的文件直接控制喇叭, 键盘灯, 风扇等硬件. 其中风扇支持如下操作:

$ cat /proc/acpi/ibm/fan
status: enabled
speed: 1952
level: auto
commands: level <level> (<level> is 0-7, auto, disengaged, full-speed)
commands: enable, disable
commands: watchdog <timeout> (<timeout> is 0 (off), 1-120 (seconds))

可以通过sudo bash -c 'echo 3 > fan' 来设置风扇转速为 3 级. 默认是 auto.

对 auto 的设置不满意时, 可以利用这个文件来自己控制, 或者使用 thinkfan 工具. 比如我的风扇常常在温度不高时也转的很快, thinkfan 可以指定温度在某区间内时所使用的风扇转速等级.

Comments