Monthly Archives: July 2010

更改console下的键盘keymap

我又开始折腾键盘了,都是被ThinkPad的键盘给惯坏了,它的键位安排是我用着最舒服的。而一般USB键盘都没有这样的键位安排,其实就是右ctrl的位置问题,在这篇文章里有对我这个怪癖的解释。

之前写过3篇左右的文章,进行各种映射,比如这篇是把Super_R映射成Control_R。但是这些方法都是只在Xwindow环境下才起作用的,用的是xmodmap这个工具。今天为了测试SSD在RHEL6下的一些优化特性,在台式机上装了个RHEL6,但是默认没有X环境,直接终端操作。现在终端下的分辨率也能自动设置的很好了,感觉直接在终端下用这个测试机也许也挺爽的,于是开始折腾。

既然之前的映射方法在没有X环境的情况下不能工作,那么就需要找其他方法了。有问题当然问google了。以“keyboard console keymap”为关键字进行搜索,找到了这篇文章,其主要方法就是用loadkeys命令更改keymap,而这个keymap是经过自己编辑的。

在RH系列中keymap文件是存放在/lib/kbd/keymaps目录中,而我能用到的是在/lib/kbd/keymaps/i386/qwerty这个目录中。目录中有很多keymap,可以通过查看/etc/sysconfig/keyboard文件(KEYTABLE选项)得到使用的是哪个keymap。一般默认的都是“us”。那么我们可以通过编辑/lib/kbd/keymaps/i386/qwerty/us.map.gz来达到更改映射的效果。打开这个文件可以发现,其实就是把Super_R的keycode指定为Control就可以了。那么关键就在如何找到与Super_R对应的keycode了。在X环境下可以使用xev,在终端下就需要用showkey这个命令了。运行showkey,按下右边的Windows徽标键,发现它的keycode是126(不同系统/键盘可能不同吧),然后修改us.map.gz,增加一行

keycode  126 = Control

再运行

loadkeys us

就可以了。如果不想修改原来的文件,可以cp出一份自己的,然后把/etc/sysconfig/keyboard文件中的KEYTABLE的值修改为自己的keycode文件名,比如us-my。重启系统之后设置也依然有效。

在终端下工作一段时间看看,当然这样就离不开笔记本了,只能是常规的测试工作可以在终端下进行。以后有时间的话可以折腾下终端下的email,还从来没用过。

初探binfmt_misc

为了使用qemu user mode来做opensuse的系统移植而接触到了binfmt_misc这个东西,但是不知道这东西具体是做什么的,所以现在来一探究竟。

要对一个陌生的事物或概念进行初步的了解当然是找wikipedia了。从binfmt_misc的wiki页面上可以得知,binfmt_misc是内核的一个模块,具有让内核执行任何文件类型的功能。具体来说就是用户通过binfmt_misc的接口向内核注册新的可执行文件类型的解释器,内核在运行这种新的可执行文件的时候就把这个文件当作注册进内核的解释器的一个参数来运行这个解释器(说的有点绕……)。比较常见的用法是让windows的exe程序通过wine在Linux中直接运行,要做到这点需要执行如下命令(没有wine,没验证):

# First load module if not loaded
if [ ! -d /proc/sys/fs/binfmt_misc ]; then
 /sbin/modprobe binfmt_misc
fi
if [ ! -f /proc/sys/fs/binfmt_misc/register ]; then
 mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
fi
# Register new executable file format
echo ':DOSWin:M::MZ::/usr/bin/wine:' > /proc/sys/fs/binfmt_misc/register
# Then you can launch exe file directly
chmod a+x /path/to/prog.exe
/path/to/prog.exe

现在简要说明下那一长串被echo进去的字符串吧。这个串是用来描述新格式和相应的解释器的(interpreter)。一共分为7个部分,之间用’:’分隔:

  1. name:新类型的名称,注册成功后会在/proc/sys/fs/binfmt_misc 目录下生成一个新文件,来描述这个新类型;
  2. type:注册的类型,有两个有效值’M’和’E’,M表示使用magic number来识别新类型,E表示用extention(扩展名)来识别新类型;
  3. offset:magic number/mask在文件中的偏移量,以byte为单位,这个不是必须的,默认是0,也可以省略,如 ‘:name:type::magic:mask:interpreter:flag’;
  4. magic:是binfmt_misc用来识别文件类型的byte串,相当于特征码(不同类型的文件如何得到特征码还不清楚),如果type是E那么这部分就填写扩展名;
  5. mask:mask部分于magic部分做按位与操作,然后再匹配与操作之后的串,一般都是一串’xff’,也就是都是1;
  6. interpreter:解释器,可执行文件作为解释器的第一个参数来执行,需要解释器的全路径名;
  7. flag:控制解释器行为的一些flag。

详细的说明可以看Documentation/binfmt_misc.txt。

现在可以玩一些好玩的东西了,比如让jpg文件变成可执行的,用eog打开查看:

echo ':jpg:E::jpg::/usr/bin/eog:' > /proc/sys/fs/binfmt_misc/register
chmod +x pic.jpg
./pic.jpg

这样在运行jpg文件的时候,就会用eog打开这个图片文件。

最后来说说binfmt_misc与使用qemu user mode进行opensuse移植的关系。使用qemu user mode可以在比如x86_64环境下直接运行mipsel的二进制可执行文件(前提是准备好相应的运行时库环境),那么就可以把mipsel的二进制文件的interpreter注册为qemu-mipsel,再结合chroot,就可能实现在x86_64环境下得到mipsel的运行环境,这个运行环境比运行qemu-system-mipsel要快很多,在这个环境下编译打包rpm会节省很多时间。这也是去年做opensuse@arm port gsoc项目的那个学生的做法,比我用system level emulator效率高了非常非常多,不用忍受编译gcc用4天时间这种痛苦了。

但是现在我还没运行成功这个chroot环境,需要进一步折腾,离qemu mips64el user mode就更遥远了。有进展了会写日志的。

心有灵犀同学的生日

很欢乐的一天。做饭很欢乐,六冲很欢乐,蛋糕很欢乐,散步很欢乐。

我们丰盛的菜,做的时候各种欢乐,可乐鸡翅酱油和可乐都放多了,鱼煮时间长了,毛豆没怎么入味,西红柿鸡蛋的葱花都黑了,中间那一大盆的水放的“哎呀妈呀,正好!”。不过都很好吃。

六冲,作为一种沈阳地区具有悠久历史的扑克玩法,深受广大一中同学的喜爱。

生日快乐!

修复nctwit与locale相关的一个bug

nctwit开发笔记中已经给nctwit写了雏形,基本可用了,反正能达到我个人的需求。但是近来遇到一个bug,那就是不能用颜色区分已读和未读消息了,所有消息标记为已读,而且不能设置当前时间戳。这个问题在自己的台式机和笔记本上都没有,只在公司的台式机上才有。

先说一下这里的逻辑。nctwit有维护两个时间戳,一个是记录在文件当中的最后一次按‘f’键时得到的当前最新消息的时间戳,用localtime表示,是time_t类型的变量;一个是更新时间线之后得到的最新的消息的时间戳,用latesttime表示。那么当我按一下’f’键,nctwit会获取当前latesttime,与从文件中读取到的localtime进行比较,如果当前时间大于localtime,那么就把当前时间戳写入文件,当作localtime。在显示tweets的时候把每个tweet的时间都与localtime进行比较,较新的tweet用红色显示,较旧的用绿色显示。这样就可以用颜色区分已读和未读了。

但是这里有一个地方需要进行转换,因为从twitter api获取的xml中的时间戳是字符串,形式如下“Fri Jul 09 06:49:23 +0000 2010″,而localtime是time_t类型,显然比较time_t类型的数据是方便的,那么就需要把时间字符串转换成time_t类型。nctwit中是用strptime这个函数来转换的。strptime这个函数有三个个参数,第一个是待转换的时间串,第二个是时间串的格式描述,比如与上边那个例子对应的格式描述就是“%a %b %d %H:%M:%S +0000 %Y“,第三个参数是一个指向struct tm类型变量的指针,函数会把转换后的时间存储在这里。具体用法就man吧。

经过debug,发现问题出现在strptime函数总是返回NULL,也就是函数出错,打印出的错误信息竟然是”Operation not permitted”,很是奇怪。在搜索相关错误的时候找到了GNU C library与时间相关的一系列函数说明,其中有一部分就是关于时间转换函数的,于是找到了与strptime功能相似的getdate及其变种getdate_r函数。getdate_r函数在出错的时候会返回错误代码,而在我这里返回的错误代码是7,表示“There is no line in the file that matches the input.“,竟然是格式不匹配。又仔细看了一下格式说明(man strptime能看到),忽然注意到了这么一句“The weekday name according to the current locale“,也就是说是跟current locale相关的,如果当前locale是中文,那么就肯定不能匹配英文的Fri和Jul了。于是在程序开始的地方添加如下代码

setlocale(LC_TIME, "en_US");

把LC_TIME改成英语,再编译运行程序,果然又能用颜色区分已读/未读了。

在自己的台式机和笔记本上我都自己export LC_TIME=en_US了,就是为了在使用date的时候不显示中文,而工作机还没设置,所以出现了这个bug。

铺垫了这么多,bug一句话就解决了……

Monthly pic 2010 06

6月好像没有太多户外活动,倒是公司的篮球羽毛球活动每次都不落。

公司世界环境日每人领养一个绿色植物

某个周末非常想出去happy,可是找不到人,只好晚上十点自己去买了份KFC

用xmodmap映射Super_R为Control_R

这个问题其实在之前这篇文章里已经解决了,那就是在~/.xmodmaprc中添加’add Control = Super_R’。可是这个方法在今天在台式机上重装成F13之后就不能用了,错误信息没有保存(现在很诡异的不能重现这个问题了……),总之是不认Super_R这个keysym。

经过一番折腾,试了各种xmodmap语句,改了键盘的布局,也没管用。最后使用如下配置才成功:

remove Control = Control_R
remove mod4 = Super_R
keysym Super_R = Control_R
add Control = Control_R

先用xmodmap -pm查看各个modifier里都有什么,然后再把Super_R从相应的modifier中去掉。

现在我也不太清除到底是因为改了什么才映射成功的,反正是好了,先记录在这吧。

让cvs up自动添加或删除目录

原来用svn多一些,基本没怎么用过cvs。现在公司里用的是cvs。其实我目前还用不到那么多高级特性,所以是cvs还是svn对我来说没什么差别。但是cvs有一个地方让我很不爽,就是它不跟踪目录的变化。

在使用svn的时候,如果A在工作目录下新建里一个子目录suba,并且commit了,那么当B在做svn up的时候,这个新目录就会自动创建。而cvs就不会这样,需要手动co出这个目录,相当麻烦。

而我又总是忘记如何在部分co的情况下co出新建的目录,每次都搜索查手册(不长记性……)。这次发现了一个一劳永逸的方法,说起来也是相当简单的,那就是在~/.cvsrc中添加一句配置:

update -d -P

这句话表示“When you do cvs update, create and prune directories as necessary.“

现在好了,在当前目录下尽情的up吧。

昌平邓庄十三陵骑行

第一次参加长途骑行活动,需要记录一下。

说起来这次活动还是因我而起的。上上周的时候不知道怎么心血来潮想骑车去昌平,回邓庄看看,回政法看看曾经打球很爽的羽毛球馆。于是在校内上更新了状态。然后一直想忽悠我参加活动的hzm表示,可以忽悠coly一起来,然后去十三陵,反正离昌平镇也不远了。我想这样也挺好的。

本来我想的是骑自己的菜车去的,后来hzm帮我借了一辆车,还有头盔。事实证明,我如果骑菜车去了,那很可能就要搭车回来了。感谢hzm帮我借车。还要感谢他的带队(在这一段里一起感谢了吧……)

周六早上6:50起床,爬起来洗漱迅速下楼,在公交站前买了个肉夹馍当早餐。前一次晚上空腹去奥体刷街让我知道了吃饭的重要性。不到7:30大部队已经到了,我的车也借来了。传说中喜欢迟到的xuejian果然7:40多的时候来了。然后大家图书馆前合影。哦,对了,这次是和去解字石的大部队一起集合出发的,因为都要到西关环岛的。7:50的时候大部队从西门出发,顺着学院路一路向北了。

先后到了四环五环西三旗然后上了八达岭高速辅路。一路上大车很多,红灯很多,路况不怎么样。还好这时候天气还不算很热。到西关环岛还算顺利,中途大部队休息了一次。到了西关环岛就开始兵分两路了。去解字石的一路,去十三陵的一路。

单说去十三陵的人员。我、hzm、smallr、coly、圈圈、frozen、很彪悍的德国MM(露背装)还有xuejian传说中的伴娘,还有coly老婆的闺蜜,还有一位不认识的,不知道什么时候加入我们的……大家在环岛旁边的桥下阴凉处休息了一会儿,我和hzm去镇里买了些水给大家补充。然后在我的煽动下大家一起跟我去邓庄寻找曾经的记忆去了。

在我的印象中,邓庄离西关环岛很近的,走路也就十几分钟。可是我们骑了快20分钟我也没找到邓庄,smallr也是在邓庄呆过的,我俩都没发现。最后都走到了陈庄了。我只好悲剧的宣布我找不到了……还好走出来不是很远。coly这时候有点体力问题,先独自回环岛阴凉处了。我们沿路返回,途经一处“北京交通职业技术学院”的富丽堂皇的大门,我怀疑就是这里,骑了进去发现很像。最后终于发现了传说中的教学楼和南食堂。原来门口的小胡同和一片的平房都被改造成了小桥流水的花园。怪不得我会找不到,这变化也太大了!

进到学校里后有点兴奋,和smallr到处寻找曾经的记忆,学四宿舍,旁边的水房,北边的澡堂和北边的北食堂,还有我经常和孙屎同学打羽毛球的教学楼后边。照了一些照片后在南食堂墙根下的阴凉处找到了休息的大部队。休息片刻后,大家骑回了环岛阴凉处。之后决定向十三陵进发。这个时候大概是10:30吧。

我们沿着南大街横穿了昌平镇,途径政法大学的时候本想还进去看看的,可是想起来政法可能进去需要学生证了,大家也都在赶路,就没再进去。大一下学期再来打球的时候就需要政法的mm们出来接我们了。

后来一路向北,就要到水库了,发现公路开始被管制。再上发现在进行女子铁人三项比赛,现在进行到骑车阶段,上水库的路都被封锁了。我们只好停下来等,希望能等她们结束后再上山,可是负责人说要骑八圈还是多少来着,反正需要不短的时间。于是coly建议大家先停下来休息,顺便看看铁三的mm们。当mm们快出现的时候coly建议大家一起喊加油,当mm们真的出现的时候,coly果然带头大喊,可是他喊的是“美女!!”然后我们喊加油。再一次被coly雷到了……

看了mm们白花花的大腿后(刚游完泳,都穿着泳装骑行呢)我们决定去觅食了。随便找了一家小馆子点菜吃饭。菜量挺足的,也不贵(8人吃了86),就是米饭很难吃。饭后1点了,无聊之余coly开始讲色情故事,讲了他当年在东莞是如何没有遇到小姐的(再次雷)。2点的时候实在无聊了,圈圈和hzm提议无聊到4点左右再出发,因为此时太阳实在是太毒了,而coly好像不能忍受了,决定现在就出发。于是我们又回到了西关环岛的阴凉处……休息,补充水。因为出了这个阴凉之后就不知道什么时候再有了。

回来的路上是相当痛苦的。首先是太阳非常毒辣,据说是40度高温;然后是路况不是很好,路上车很多;骑行时间长了胳膊和屁股都很疼;最后我觉得最痛苦的就是当了一路的马路吸尘器,各种烟尘和汽车尾气都被我们吸进来了,尤其快到五环的时候那一段路有点堵车,汽车的热量和尾气,加上太阳的晒,大卡车带起的灰尘,简直难受到要死,最后到城区都不敢大口吸气,感觉肺里特别痒,也不知道是什么原因。一路上我们休息了很多次,走走停停终于回到了学校。还车回家,马上洗澡,然后睡觉!我要瘫了!

后来看了大家的各种作业,都说我们这次去就是一悲剧,十三陵没上去,邓庄也差点没找到,被太阳晒个半死,冒着35+的高温骑行了一天。我的胳膊回来后也必然的变双截棍了(hzm一直等着我上照片呢……)。今天终于算是缓回来了,不过骑车上班腿还是有点酸累。以后夏天还是不出去了,要出去也是晚上刷奥体比较爽。

最后借用一下hzm的数据吧。

距离108.3公里,用时5:53,均速18。

第一次去奥体刷街

今年的一个目标就是买车然后参加些骑行活动。但是就算是一辆入门级山地车也要1.5k左右,一直不忍心买。所以后来买了个永久老字号的山地车用来通勤。

上个星期忽然很想会昌平看看,然后被hzm忽悠去十三陵了。最近两天在车版也开始不潜水了,开始小规模灌水。结果又被hzm忽悠来奥体公园刷街。

晚上6:45从公司出发,7:05到学校图书馆门前。发现已经有两位在停车等候了,其中一辆还是今天下午刚买的。过了一会儿又纷纷来了几个人,但是都不认识,一问才知道都是第一次来的新人。快6:20的时候hzm和smallr来了。我感受了下hzm的车,对比自己的菜车确实要好骑很多,至少车闸很灵。6:30的时候cc和圈圈也来了,然后大部队出发。我霸占了hzm的车跟随大部队骑到了奥体公园传说中的A点。

休息了一会儿大部队开始刷圈了。这一圈下来差不多6.5km,大牛只要8分钟左右。我继续骑hzm的车跟着圈圈开始第一圈刷奥体。平路的时候均速基本能达到29km/h,上坡的时候就要降到25左右了。最快的时候好像是34左右。好车的手拨(我终于知道什么是手拨了……)确实很好用,变速就像变档一样,不用再自己调整了,很顺畅,根据上下破和体力情况调整速度,能保持不变的踏频。

第一圈下来感觉很爽,回到A点已经满头是汗。休息了十分钟左右又忍不住刷第二圈了。这次骑的是圈圈的车(其实也是她借的),这辆车骑起来很轻,但是最大档没有hzm的车快。因为这次是跟着hzm走,所以速度也快了不少,开始的时候均速基本在32左右,有时能达到37以上。不过后来我想再次换高速档的时候,没想到齿轮从最高速档一下回到了最低速档,车一下就感觉踩空了,此时hzm的尾灯就越来越远了。当我调整好档之后又是连续两个上坡,体力有点跟不上了,只能看着hzm越来越远。好像是从五环转弯到奥体那个弯道之后我就看不到他了……还好smallr这个时候从后边赶上来了,我跟着他跑才不至于迷路。后边的速度由于体力下降,均速只有27左右了。回到A点腿疼屁股疼后背疼。

两圈过后,我们几个又去公园里边玩了一会儿,还有一个德国mm一个俄罗斯mm跟着frozen夫妇(好像是这个id)也过来玩了(其实就是换个地方聊天)。我由于晚上没吃晚饭,这个时候已经是9点多了,相当饿了。9:30开始撤退,路上杀进一家面馆,买个西瓜,然后开始吃瓜吃串。我要了一碗牛肉刀削面,味道还不错。

11点到家已经很累了,马上洗澡舒服一下。但是现在还是有点后背疼,也跟最近各种活动的活动量有点大有关吧。

开始攒钱吧,还是弄一辆车吧,挺好玩的。不知道周六去十三陵会怎样。