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