FreeBSD 的中文console

其实 FreeBSD 的 console 早就支持中文了,问题是默认没装中文字体,所以显示出来都是方块…… 系统提供了 vtfontcvt 工具,用来转换字体到系统需要的fnt格式。它吃俩格式,bdf和hex,我只认识bdf…… 于是尝试转换 wenquanyi 的位图字体。源文件是pcf的,先要找个东西转换成bdf,姑且在github找了个: https://github.com/ganaware/pcf2bdf (刚看了眼原来有port,当初搜pcftobdf没搜到……) 转完之后用vtfontcvt,冒出来了各种错误。先是说字符宽度不支持。 打开文件一看,这货好像对字体有很多假设,比如所有字符宽度不是目标宽度的2倍就是和目标一样(等宽字体?)。 wenquanyi 里面虽然中文都是一样的,但是其他英文什么的有各种宽度,比如10pt的字体,pixel宽度有2-13不等…… 于是先修vtfontcvt才行。这个vtfontcvt问题还真不少…… 除了前面那个假设之外,他还假设每个字符都和目标一样高,是不是写的时候连bdf格式描述都没读过,拿个样例文件就开搞了…… 他还忽略了字符的偏移位置…… 修完的vtfontcvt干了这么几个事情: × 读取FONTBOUNDINGBOX信息,了解全局的基线位置 × 读取字符的BBX信息,这个包括了这个字符多大和应该放哪儿 × 干掉了那个宽度假设。当然,太宽还是不行的…… 打算提交这个修改的时候,发现有个PR已经管了一部分问题: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205707 但是这个PR修的东西略少,也没管位置偏移之类的问题,于是还是把我修的版本交了上去(一开始还弄错一个版本……)。 之后在这个PR和我的patch的基础上又搞了搞,于是支持多字体叠起来了(wenquanyi的英文太丑了,还不等宽……)。 完整版patch:http://www.henryhu.net/vtfontcvt_full.patch 最后转了个Terminus+wenquanyi的字体出来,用vidcontrol -f弄进去,现在控制台终于可以原生显示中文啦! 转完的字体(Terminus 14pt + wenquanyi 10pt): http://www.henryhu.net/ter-wqy-8×14.fnt

又换了一家VPS提供商……

一开始是PhotonVPS,后来是linode,接着Amazon EC2,现在跑到了DigitalOcean…… 换linode因为PhotonVPS时常网络不好偶尔还重启,换EC2因为linode只有PV的虚拟机而FreeBSD一直不支持64位的PV,换DigitalOcean因为它终于支持FreeBSD了并且便宜性能好还有GitHub的100刀优惠…… 搬家倒是挺方便,把数据库、网页、配置打包拷过去就完了…… 这回能呆久一些就好了…… 毕竟搬家还是要费一些功夫的……

Code Keyboard在BSD下的多媒体快捷键配置

在之前买了个Das Keyboard之后,这回为了在家里用搞了个Code Keyboard。 Code Keyboard自带一堆多媒体键,不过要让这些多媒体键发挥作用还要费些功夫。 刚插上去的时候,多出来一个键盘和一个鼠标设备: ukbd2: <vendor 0x04d9 USB Keyboard, class 0/0, rev 1.10/1.10, addr 8> on usbus0 ums2: <vendor 0x04d9 USB Keyboard, class 0/0, rev 1.10/1.10, addr 8> on usbus0 作为一个键盘来说,有个鼠标设备还是很奇怪的,所以多半是用来给多媒体键的。Ports Tree里有个uhidd,https://wiki.freebsd.org/uhidd,可以用来处理这些多媒体键对应的hid事件。ukbd驱动不错,我们只要干掉ums驱动就可以了。为了这个,先配置uhidd让他干掉ums自己attach上去: 0x04d9:0x0169:0={ detach_kernel_driver=”NO” } 0x04d9:0x0169:1={ detach_kernel_driver=”YES” } 之后跑uhidd -h /dev/ugen0.7 (这里ugen0.7是这个键盘对应的ugen设备,-h启动HID类设备),就会发现/dev底下多了uvhid0。 跑系统自带的usbhidctl -f /dev/uvhid0 -l -a,然后按那些多媒体键,就能看见HID状态变化的事件,例如Volume_Increase从0变到1然后变回去之类。 之后,要让uhidd把这些事件翻译成键盘按键。在配置文件的0x04d9:0x0169:1那段里加一段: cc_keymap={ Play/Pause=”0x54″ Stop=”0x5a” Volume_Decrement=”0x62″ Volume_Increment=”0x63″ …

Continue reading ‘Code Keyboard在BSD下的多媒体快捷键配置’ »

在FreeBSD的Flash里输入中文

对其他系统用户这大概都不是什么问题,但是在BSD系统上有一堆问题…… 环境:FreeBSD 11, 打了个patch所以用的centos 6作为linux_base。 首先是glibc是否支持locale的问题。貌似linux_base-c6没有产生locale数据库,所以要跑build-locale-archive。 之后跑linux的locale应该就不会报错了。 其次看gtk的xim输入法模块是否启用了。找个gtk2-devel的包,从里面可以找到gtk-demo,跑他可以检验。 默认貌似只装了gtk2包,没装immodule…… 找到gtk2-immodules-xim包,把里面的im-xim.so装到/compat/linux/usr/lib/gtk-2.0/2.10.0/immodules里。这还没完,还要更新immodules列表。跑linux的gtk-query-immodules-2.0,把结果写到/compat/linux/etc/gtk-2.0/i386-redhat-linux-gnu/gtk.immodules里。之后开gtk-demo,找个文本框,右键菜单->输入法里应该有XIM了。 这时可能还是无法激活输入法。我写了个小程序检查XIM的情况: #include <X11/Xlib.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main() { Display *dpy = XOpenDisplay(NULL); if (!dpy) { printf("fail to open display\n"); exit(1); } if (XSupportsLocale()) { printf("Xlib supports current locale\n"); } char *p = XSetLocaleModifiers(""); printf("current locale modifier: %s\n", p); XIM im = …

Continue reading ‘在FreeBSD的Flash里输入中文’ »

DTrace

这两天搞了一把DTrace,貌似还挺有意思的。 DTrace是个动态跟踪工具,可以在动态环境下向内核/程序中插入探头(probe),收集处理以及显示一些信息。 其实本来搞DTrace是为了一个FreeBSD的bug。搞chromecast的时候发现,IP multicast的目标mac不对。不过后来分析代码大致定位到了出问题的文件,然后在最新代码里发现这个bug已经修了(PR 185395),于是纯粹就是学习DTrace了。 一开始在我的机子上DTrace还跑不起来,后来发现是因为我跑的UEFI分支里的内核路径有些特别,于是DTrace找不到符号。打了个补丁(dt_kernel_path.patch)之后,dtrace终于能用了。 DTrace脚本的主体是一堆事件处理函数。跑DTrace脚本的时候,系统碰到某个符合的事件,就调用对应的函数。这些函数用D语言(不是那个D语言,是DTrace自己的一种语言)写成,语法和C差不多。基本的赋值/比较都能干,不过没有循环,也没有if/then/else。能控制流程的,基本上就是每个事件自带的条件,和三元操作符,也就是?:。 虽然前面那个bug是修了,我还是搞了个简单脚本来试DTrace。我希望观察arpresolve函数的参数和返回结果,也就是那个返回IP对应mac地址的函数。 arpresolve的原型是 int arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, const struct sockaddr *dst, u_char *desten, struct llentry **lle)int arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, const struct sockaddr *dst, u_char *desten, struct llentry **lle) 我希望查看dst里的ip地址,和desten里返回的mac地址。 DTrace脚本如下: fbt::arpresolve:entry /execname == "ping" && arg4 != …

Continue reading ‘DTrace’ »

在bsd上跑ndk-build

bsd一直是个官方不咋支持的Android开发平台…… 不过靠着linux兼容层,还是可以混混的…… 首先是ndk-build会报不支持的os(FreeBSD)和arch(amd64),而且ndk-build并不会使用环境变量里定义的值。所以有两个办法: 1. 直接调用gmake env HOST_OS=linux HOST_ARCH=x86 gmake -f $NDK_DIR/build/core/build-local.mk 这样啥都不用改。 2. 修改ndk-build 把HOST_OS设置成linux,HOST_ARCH设置成x86,并且export出来。 再把GNUMAKE设置成gmake,否则会调自带的linux版gmake导致一些麻烦的事情…… 然后直接跑就行了。 跑了之后会碰到一个问题:ld会segmentation fault。看系统log可能是因为fallocate和fstatfs64系统调用没有实现的关系。 解决办法是,到ndk目录里的toolchains/*/prebuilt/linux-x86/…/bin/,如果有ld.gold,那把老的ld干掉,改成到ld.bfd的符号链接。老的ld就是ld.gold…… 其实就是gold那个新的ld调了一些新的bsd还没实现的linux的system call…… 用老的bfd里的ld就没事了……

在FreeBSD上装linux skype 4

折腾了一个晚上好歹是搞出来了…… 起因是把linux_base更新到了linux_base-c6,也就是CentOS 6。这是个相当新的版本,各种rpm找起来也比较容易。 但是问题是,ports里其他linux包基本都是老的,要么是fc4的,要么是f10的…… 反正用不了。于是统统删掉。但是这样linux程序基本就跑不了,缺很多包…… 于是就自己搞rpm来装。但是rpm这回又不好使,试了ports里rpm3/4/5貌似都不行。 怀疑是因为rpm调了cpio,而FreeBSD 8-STABLE里的cpio貌似还不支持xz? 因为CentOS那些新包是xz压缩的,于是就解不了。 后来干脆不管rpm了,搞个脚本: if [ ! -f $1 ]; then wget http://mirror.yandex.ru/centos/6.2/os/i386/Packages/$1 fi rpm2cpio $1 | unxz > ~/tmp cd /compat/linux sudo cpio -idv < ~/tmpif [ ! -f $1 ]; then wget http://mirror.yandex.ru/centos/6.2/os/i386/Packages/$1 fi rpm2cpio $1 | unxz > ~/tmp cd /compat/linux sudo cpio -idv < ~/tmp …

Continue reading ‘在FreeBSD上装linux skype 4’ »