Linux内核输出中文字符的案例

  

小编给大家分享一下Linux内核输出中文字符的案例,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

你在Windows/MacOS的登录Linux的SSH终端上很容易输入中文并且获得中文输出,比如下面这样:

Linux内核输出中文字符的案例

但是却几乎不可能将中文显示在Linux自身的 虚拟终端 上:

[root@localhost font]# echo 皮鞋 >/dev/tty2

Linux内核输出中文字符的案例

显示了两个问号,显然Linux内核并不能识别中文。

为什么说是Linux内核不能识别中文呢?这里需要理清一个关系:

  • 你在远程SSH终端上的输入和显示输出的行为,都是SSH终端的宿主机完成的,比如Windows,MacOS,和Linux无关。

  • 你在Linux本地虚拟终端,比如/dev/tty1上的输入和显示输出行为,则是由Linux内核自己处理的。

比如,我在MacOS用iTerm SSH连接到了一个远程CentOS Linux,iTerm上的所有的键盘输入,显示器输出行为都是iTerm的这台MacOS宿主机完成的。

相反,如果你直接在这台CentOS Linux的虚拟终端上输入并且企图获得输出,那么这个输入输出则必须由Linux内核自身来处理。

基本上就这些。至于说为什么Linux内核不支持中文,那要了解Linux内核处理虚拟终端输入输出时是如何对待unicode的逻辑,这要涉及一大堆的理论知识,非常烦人。

反正我这里就是无法输出中文,我也不是做这个的,显然这不是一个必然要完成的工作任务,所以,我只是玩玩。

本文的目标就是要让Linux的虚拟终端可以输出中文。

仅仅是输出中文,哪怕是一个中文汉字也好。具体来讲,就是 当我在键盘敲入'A'字符时,显示器回显出来的是一个汉字。

所以说,本文并不打算 让Linux内核大规模完备地支持中文 ,这种事已经有很多人和社区做了,但是可玩性并不高,毕竟这种事是可以当私活儿赚钱的,只要是赚钱的活儿,可玩性就不高,因为要快嘛。

不需要懂冗长枯燥的unicode编码,不需要懂枯燥的font字体格式,看看怎么玩。

先展示效果吧,下面是一个8×168\times 168×16的点阵例子:

Linux内核输出中文字符的案例

不是很好看,于是就做了下面一个28×1628\times 1628×16的点阵:

Linux内核输出中文字符的案例

下面说一下这是如何实现的。

从你敲键盘的某个按键开始,到某个字符最终显示在虚拟终端的显示器上,这期间其实有两个映射:

键盘和字符集的映射

将某个按键事件转换为某个字符集里的某个码,比如当按下'A'键时,将其映射到0x41。

字符集和字体的映射

将某个字符集的码字映射到某个点阵用来显示。比如将0x41映射到能让人看出来是一个字符'A'的样子的8×168\times 168×16点阵。

Linux的console并不能识别超过0x00ff的字符集码字,因此就不能处理码字超过0x00ff的unicode,如果希望它能做到,这就要改内核代码了。

刚才说了,修改内核代码大规模全面支持中文,这是可以赚钱的事,不但没意思,也没人会分享。

所以我尝试去修改上面的两个映射来解决问题。由于只是显示,所以我不会去修改 键盘和字符集的映射 ,因为那样仍然会碰到字符集码字超过0x00ff的处理问题。

这意味着要想显示中文,只剩下一条路,那就是修改 字符集和字体的映射

这个映射肯定是保存在内核内存或者文件系统的某个地方。我可以在当前内核的config文件里找到如下的信息:

[root@localhost font]# cat /boot/config-3.10.0-862.11.6.el7.x86_64 |grep FONT
  #,CONFIG_FONTS  is  not 集
  CONFIG_FONT_8x8=y
  CONFIG_FONT_8x16=y 

Linux内核输出中文字符的案例