基于Linux系统核心的汉字显示尝试( 四 )


但是,由于Framebuffer的驱动很多,修改每一个驱动的xxxx_putc()函数和xxxx_putcs( )函数会是一项不小的工作,而且,改动驱动程序后,每种驱动的测试也是很麻烦的,尤其是对于有硬件加速的显卡,修改和测试会更不容易 。
那么,存不存在一种不需要修改显卡驱动程序的方法呢?
经过一番努力,我们发现,可以在调用xxxx_putcs( )或xxxx_putc()函数输出汉字之前,修改vga字库的指针使其指向所需显示的汉字在汉字字库中的位置,即把一个汉字当成两个vga ASCII字符输出 。也就是说,在内核中存在两个字库,一个是原有的vga字符字库,另一个是汉字字库,当我们需要输出汉字的时候,就把vga字库的指针指向汉字字库的相应位置,汉字输出完之后,再把该指针指向vga字库的原有位置 。
这样一来,我们只需要修改fbcon.c和console.c,其中console.c负责维护双倍缓冲区,把每一个字符的信息存入附加的缓冲区;而fbcon.c负责利用双倍缓冲区中附加的信息,调整vga字库的指针,调用底层的显示驱动程序 。
这里还有几个需要注意的地方∶
1. 由于屏幕重绘等原因,调用底层驱动xxxx_putc( )和xxxx_putcs()的地方有多处 。我们作了两个函数分别包装这两个调用,完成替换字库、调用xxxx_putcs( )或xxxx_putc( )、恢复字库等功能 。
2.为了实现向上滚屏(shift pageup)时也能看到汉字,我们需要作另外的修改 。
Linux在设计虚拟终端的时候,提供了回顾被卷出屏幕以外的信息的功能,这就是用热键来向上滚屏(shift pageup) 。当前被使用的虚拟终端拥有一个公共的缓冲区(soft back),用来存放被滚出屏幕以外的信息 。当切换虚拟终端的时候,公共缓冲区的内容会被清除而被新的虚拟终端使用 。向上滚屏的时候,显示的是公共缓冲区中的内容 。因此,如果我们想在向上滚屏的时候看到汉字,公共缓冲区也必须加倍,以确保没有信息丢失 。当滚出屏幕的信息向公共缓冲区填写的时候,必须把相应的附加信息也填写进公共缓冲区的附加区域 。这就要求fbcon.c必须懂得利用公共缓冲区的附加信息 。
当然,有另外一种偷懒的方法,那就是不允许用户向上滚屏,从而避免对公区缓冲区的处理 。
3.把不同的编码方式(GB、BIG5、日文和韩文)写成不同的module,以实现动态加载,从而使得扩展新的编码方式不需要重新编译核心 。
小结
通过这次针对Linux核心的探索,我们发现,目前Linux的核心设计中,完全没有考虑到双字节编码字符的显示 。我们在这种情况下摸索出一套解决核心下汉字显示的方法,并编码实现了该方案.
遵循核心的GPL版权声明,我们同时公布了实现这一技术的源代码,当然,这些改动仍然是GPL的.如果能对研究核心的朋友有所帮助,减少一些大家对核心的神秘感,将是我们最大的收获 。
但是对核心和中文化来说,这仅仅是一种尝试,远不是终点.这种改动多少带有一些hack的色彩,不太可能融合进权威的核心里去.我们仍在积极探索圆满解决这一问题的方法,相信这一结果必然需要通过国内外Linux群体的共同努力才能实现.我们也非常欢迎大家和我们共同讨论这一问题.
测试
本文实现的Kernel Patch文件(patch.kernel.chinese)可以从http://www.turbolinux.com.cn下载 。Cd /usr/src/(该目录下应有Linux核心源程序所在的目录linux/) patch -p0 -b < patch.kernel.chinese make menuconfig 请选择Console drivers选项中的

〔*〕 Double Byte Character Display Support(EXPERIMENTAL)
〔*〕 Double Byte GB encode (module only)
〔*〕 VESA VGA graphics console
<*> Virtual Frame Buffer support (ONLY FOR TESTING!)

推荐阅读