婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Linux內核如何輸出中文字符的方法示例

Linux內核如何輸出中文字符的方法示例

熱門標簽:虛假地圖標注 靈圖uu電子寵物店地圖標注 濮陽好的聯通400電話申請 地圖標注黃河的位置 山東企業外呼系統公司 地圖標注如何改成微信號 400電話號碼辦理多少錢 百度地圖標注公司位置要多少錢 承德地圖標注公司

你在Windows/MacOS的登錄Linux的SSH終端上很容易輸入中文并且獲得中文輸出,比如下面這樣:

但是卻幾乎不可能將中文顯示在Linux自身的 虛擬終端 上:

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

顯示了兩個問號,顯然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的點陣例子:

不是很好看,于是就做了下面一個28×1628\times 1628×16的點陣:

下面說一下這是如何實現的。

從你敲鍵盤的某個按鍵開始,到某個字符最終顯示在虛擬終端的顯示器上,這期間其實有兩個映射:

鍵盤和字符集的映射

將某個按鍵事件轉換為某個字符集里的某個碼,比如當按下'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 set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y

再去看/proc/kallsyms里有什么:

[root@localhost font]# cat /proc/kallsyms |grep font.*8x
ffffffffb006a3e0 R font_vga_8x8
ffffffffb006a420 r fontdata_8x8
ffffffffb006ac20 R font_vga_8x16
ffffffffb006ac60 r fontdata_8x16
ffffffffb0307a10 r __ksymtab_font_vga_8x16
ffffffffb03234b8 r __kcrctab_font_vga_8x16
ffffffffb034246e r __kstrtab_font_vga_8x16

嗯,這就是內核里保存的字體:

[root@localhost rh]# ll ./drivers/video/console/font_8x*
-rw-r--r--. 1 root root 95976 Sep 17 2018 ./drivers/video/console/font_8x16.c
-rw-r--r--. 1 root root 50858 Sep 17 2018 ./drivers/video/console/font_8x8.c

這里不再分析這兩個文件。這里僅僅是確認了一個事實, 內核在初始化的時候會使用自己的字體 ,這個時候畢竟除了內核本身,什么都沒有。

問題是到了用戶態,這個字體是可以被改變的,可以被改的花里胡哨的,這些個字體可不是僅僅兩個8x8和8x16就能hold住的…

這個時候就需要找我們安裝在發行版里面的字體文件了。我們要找到它,然后改掉里面的某個字體的形狀,將其變成中文!就這么簡單。

不必去搜這個字體文件安裝保存在什么地方,通過執行strace setfont命令就能找到它。

[root@localhost ~]# strace -F -e trace=open setfont
...
strace: Process 6276 attached
[pid 6276] open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4
...
[pid 6276] open("/lib/kbd/consolefonts/default8x16.psfu.gz", O_RDONLY|O_NOCTTY|O_NONBLOCK) = 4
[pid 6276] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=6276, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

就是它了, /lib/kbd/consolefonts/default8x16.psfu.gz

也不必去搜psfu格式的字體的format,通過模式識別就能找到特定的字符。

我準備先找到 ‘A',然后把它后面的'B'和'C'改成我的名字“趙”和“亞”。

首先我要把“趙”和“亞”字做出來,形成一個點陣。以下是我的作品“趙”:

00000000
00000000
00100000
11111000
00100101 
00100101
11111010
00100011 
00111010 
01100101 
01100000
10011000
10000111
00000000
00000000
00000000

下面就要用這個點陣替換'B'的點陣,同時制作一個“亞”字,替換'C'的點陣,

在下面的站點可以找到該default font的對應點陣圖解:
https://www.zap.org.au/software/fonts/console-fonts-distributed/psftx-centos-7.5/default8x16.psfu.large.pdf

我們就可以得到該'A'字符的點陣數組,然后在default8x16.psfu文件里匹配這個數組就可以了。代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <string.h>

unsigned char zhaoya[32] = {
			// 第一行為“趙”
			0x00, 0x00, 0x20, 0xf8, 0x25, 0x25, 0xfa, 0x23, 0x3a, 0x65, 0x60, 0x98, 0x87, 0x00, 0x00, 0x00,
			// 第二行為亞
			0x00, 0x00, 0x00, 0x7e, 0x24, 0x24, 0x24, 0xa5, 0xa5, 0x66, 0x24, 0x24, 0x7e, 0x00, 0x00, 0x00
};


int main(int argc, char **argv)
{
	int i = 0;
	unsigned char buf[16];
	off_t offset = 0;
	int s = 0;

	int fd = open("default8x16.psfu", O_RDWR);
	i = pread(fd, buf, 8, offset);
	while (1) {
		i = pread(fd, buf, 16, offset);
		if (s == 2) { // 替換'C'
			memcpy (buf, &zhaoya[16], 16);
			i = pwrite(fd, buf, 16, offset);
			break;
		}
		if (s == 1) { // 替換'B'
			memcpy (buf, &zhaoya[0], 16);
			pwrite(fd, buf, 16, offset);
			s = 2;
		}
		// 簡易的方法識別到'A'
		if (buf[0] == 0x00 && buf[1] == 0x00 &&
			buf[2] == 0x10 && buf[3] == 0x38) {
			printf("A found at %d !\n", offset);
			s = 1;
		}
		offset += 16;
	}
}

直接編譯執行,然后將這個default8x16.psfu作為參數set到內核即可:

[root@localhost font]# setfont ./default8x16.psfu

此時進入Linux的虛擬終端tty2,當敲鍵盤的大寫'B'時,就會出現一個“趙”字。

雖然16×816\times 816×8甚至8×88\times 88×8也能做出復雜的中文點陣,但是這也太難看了。

于是我要找一個更高分辨率的font。我在Ubuntu上找到了一個高分辨率的28×1628\times 1628×16點陣 Arabic-VGA28x16.psf.gz 。修改它的方法和前面這個完全一樣,它的點陣圖如下:
https://www.zap.org.au/software/fonts/console-fonts-distributed/psftx-debian-9.4/Lat7-VGA28x16.psf.pdf

我不需要自己做28×1628\times 1628×16的點陣了,我只要用GNU uifont的現成的即可。直接在 unifont_sample-12.1.01.hex 里面按照“趙”和“亞”的unicode碼字就能索引到點陣。關于任意字符的unicode碼字的查詢,可以參見:
https://graphemica.com/

替換font的代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include "zhao"

#define L	28*2
int fd;

int main(int argc, char **argv)
{
	unsigned char buf[L];
	off_t offset = 0;
	// 這個0x0e60 就是模式匹配獲得的偏移。
	offset += 0x0e60;

	fd = open("Lat7-VGA28x16.psf", O_RDWR);
	pread(fd, buf, L, offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[0], 32);
	pwrite(fd, buf, L, offset);

	offset += L;
	pread(fd, buf, L, offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[32], 32);
	pwrite(fd, buf, L, offset);

	offset += L;
	pread(fd, buf, L, offset);
	memset(buf, 0, L);
	memcpy(buf+8, &code[64], 32);
	pwrite(fd, buf, L, offset);
}

然后它的效果就是:

還不錯。

其實本文的內容僅僅就是:

  1. 做一個蹩腳的點陣;
  2. keyboard,ascii/unicode,font之間的映射關系;
  3. 什么細節都不懂的情況下定位分析問題的方法;
  4. 越簡單越好,越復雜越糟糕。

嗯,其實第三點和第四點是最重要的。

最后,如果你想知道你當前的虛擬終端支持那些字體,輸入:

[root@localhost font]# showconsolefont

就會顯示:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

標簽:德宏 泰安 上海 淮安 福州 鷹潭 安康 樂山

巨人網絡通訊聲明:本文標題《Linux內核如何輸出中文字符的方法示例》,本文關鍵詞  Linux,內核,如何,輸出,中文,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Linux內核如何輸出中文字符的方法示例》相關的同類信息!
  • 本頁收集關于Linux內核如何輸出中文字符的方法示例的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    色噜噜狠狠色综合中国| 亚洲bt欧美bt精品777| 久久99久久精品欧美| 中文字幕不卡三区| 久久这里只精品最新地址| 亚洲一级二级三级| 日本一区二区在线不卡| 国产欧美精品一区二区三区四区| 在线亚洲人成电影网站色www| 综合激情网...| 91麻豆蜜桃一区二区三区| 国产精品一二三区在线| 一区二区三区欧美日| 亚洲美腿欧美偷拍| 国产喂奶挤奶一区二区三区| 91老司机福利 在线| 成人三级在线视频| 国内精品免费**视频| 亚洲一区二区五区| 亚洲一区二区三区小说| 26uuu精品一区二区三区四区在线| 91久久免费观看| 成人网在线播放| 久久99精品久久久久久动态图| 精品一区中文字幕| 99精品国产99久久久久久白柏| 色综合久久综合| 精品国产免费一区二区三区香蕉| 欧美日产在线观看| 99久久久国产精品| 99re8在线精品视频免费播放| 一本到一区二区三区| 日韩三级视频在线观看| 日韩欧美国产高清| av亚洲精华国产精华| 粉嫩av一区二区三区在线播放| 欧美专区亚洲专区| 久久综合av免费| 欧美一区二区视频网站| 日本丶国产丶欧美色综合| 欧美一卡在线观看| 日韩电影在线观看电影| 99精品视频一区| 91老司机福利 在线| 国产美女久久久久| 国产综合色视频| 国产午夜精品久久久久久免费视| 国产精品无遮挡| 国产99久久久久久免费看农村| 欧美精品乱人伦久久久久久| 久久麻豆一区二区| 亚洲欧美色图小说| 亚洲va韩国va欧美va| 欧美美女一区二区三区| 亚洲自拍偷拍图区| 91免费版在线看| 久久久激情视频| 亚洲一区二区三区小说| 一本到不卡精品视频在线观看| 一区二区不卡在线播放| 7777精品久久久大香线蕉| 久久精品99国产精品日本| 欧美一级久久久久久久大片| 亚洲欧美国产毛片在线| 国产麻豆精品在线| 久久久久久亚洲综合影院红桃| 1000部国产精品成人观看| 日韩中文字幕91| 日韩欧美一区二区免费| 精品中文字幕一区二区 | 蜜臀久久99精品久久久久久9| 7777精品伊人久久久大香线蕉的| 亚洲人成网站色在线观看| 99久久国产综合精品女不卡| 91福利精品第一导航| 亚洲一二三级电影| 在线观看一区不卡| 国产精品66部| 日韩精品成人一区二区在线| 91在线视频网址| 亚洲国产精品欧美一二99| 国产精品国产三级国产aⅴ入口| 日韩视频在线永久播放| 99视频一区二区| 亚洲国产中文字幕在线视频综合| 国产亚洲一区字幕| 日韩一区二区三区在线视频| 韩国av一区二区三区四区| 日韩一区中文字幕| 成人app网站| 亚洲欧美综合网| 在线一区二区三区做爰视频网站| 国产精品1区2区| 久久99久久久久久久久久久| 亚洲国产sm捆绑调教视频| 日韩精品一区二区三区老鸭窝 | 成人午夜激情片| 成人小视频在线观看| 日韩精品亚洲专区| 亚洲综合av网| 97se亚洲国产综合在线| 五月天久久比比资源色| 99精品黄色片免费大全| 国产久卡久卡久卡久卡视频精品| 亚洲一二三区在线观看| 中文字幕在线播放不卡一区| 日韩亚洲欧美一区| 欧美精品1区2区| av成人动漫在线观看| 粉嫩在线一区二区三区视频| 日韩欧美你懂的| 久久精品亚洲一区二区三区浴池 | 中文字幕av免费专区久久| 精品国产1区二区| 国产精品婷婷午夜在线观看| 亚洲一区二区三区四区在线| 日韩avvvv在线播放| 国产麻豆视频精品| 成人av免费网站| 日韩精品在线网站| 国产日产欧美一区二区视频| 亚洲综合激情小说| 国产成a人亚洲| 91麻豆精品国产91久久久| 4438x成人网最大色成网站| 国产亚洲综合色| 国产成人av电影在线观看| 精品国产乱码久久久久久图片| 一本色道久久综合亚洲91| 国产亚洲女人久久久久毛片| 波多野洁衣一区| 美女性感视频久久| 欧美日韩亚洲高清一区二区| 日韩理论片在线| 亚洲免费观看高清完整版在线| 奇米888四色在线精品| 蜜臀av一区二区| 精品99一区二区三区| 久草这里只有精品视频| 日韩西西人体444www| 日韩精彩视频在线观看| 色狠狠桃花综合| 亚洲午夜影视影院在线观看| 欧美日韩亚洲综合一区二区三区| 国产精品正在播放| 久久久久国产精品免费免费搜索| 国产在线视视频有精品| 欧美久久一二区| www.色综合.com| 日本在线播放一区二区三区| 精品久久久三级丝袜| 国产一区二区三区电影在线观看| 日韩手机在线导航| 成人午夜碰碰视频| 美女视频黄a大片欧美| 亚洲色图丝袜美腿| 黄色资源网久久资源365| 一区在线播放视频| 中文字幕中文字幕一区二区| 欧美不卡一二三| 国产亚洲欧美日韩俺去了| 久久久久久9999| 亚洲欧美另类在线| 日本不卡在线视频| 一区二区三区蜜桃网| 欧美午夜宅男影院| 蜜桃一区二区三区在线| 成人免费av网站| 欧美成人女星排名| 亚洲mv在线观看| 欧洲亚洲国产日韩| 欧美大黄免费观看| 亚洲精品一二三| 精品一区二区在线观看| 99久久国产综合精品麻豆| 97精品国产露脸对白| 欧美精品在线一区二区| 久久综合九色综合97婷婷女人| 亚洲人亚洲人成电影网站色| 奇米影视7777精品一区二区| 国产成人亚洲精品狼色在线| 欧美在线播放高清精品| 国产亚洲欧洲一区高清在线观看| 久久久久九九视频| 26uuu精品一区二区三区四区在线 26uuu精品一区二区在线观看 | 蜜桃视频一区二区三区在线观看| 91亚洲大成网污www| 亚洲人成网站在线| 国产精品99久| 午夜视黄欧洲亚洲| 国产成人亚洲综合a∨婷婷图片| 亚洲色大成网站www久久九九| 国产精品电影一区二区| 国产一区二区三区四| 日韩一级成人av| 美腿丝袜亚洲三区| 欧美xxxxx裸体时装秀| 麻豆国产欧美日韩综合精品二区| 欧美一区二区三区不卡| 蜜桃av一区二区|