日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

基于Linux系統(tǒng)核心的漢字顯示嘗試

在闡述基于Linux核心的漢字顯示的技術(shù)細(xì)節(jié)之前,有必要介紹一下原有l(wèi)inux的工作機(jī)制 。這里主要涉及到兩部分的知識(shí),就是Linux下終端和幀緩沖的實(shí)現(xiàn) 。
控制臺(tái)(console)
通常我們?cè)趌inux下看到的控制臺(tái)(console)是由幾個(gè)設(shè)備完成的 。分別是/dev/ttyN(其中tty0就是/dev/console,tty1,tty2就是不同的虛擬終端(virtual console)).通常使用熱鍵alt Fn來(lái)在這些虛擬終端之間進(jìn)行切換 。所有的這些tty設(shè)備都是由linux/drivers/char/console.c和vt.c對(duì)應(yīng) 。其中console.c負(fù)責(zé)繪制屏幕上的字符,vt.c負(fù)責(zé)管理不同的虛擬終端,并且負(fù)責(zé)提供console.c需要繪制的內(nèi)容 。Vt.c把不同虛擬終端下需要交給console.c繪制的內(nèi)容放到不同的緩存中去 。Vt.c管理著這樣一個(gè)緩沖區(qū)的數(shù)組,并且負(fù)責(zé)在其間切換,以指定哪一個(gè)緩沖區(qū)是被激活的 。你所看到的虛擬終端就對(duì)應(yīng)著被激活的緩沖區(qū) 。Console.c同時(shí)也負(fù)責(zé)接收終端的輸入,然后把接收到的輸入放到緩沖區(qū) 。
幀緩沖(framebuffer)
Framebuffer是把顯存抽象后的一種設(shè)備,可以通過(guò)這個(gè)設(shè)備的讀寫直接對(duì)顯存進(jìn)行操作 。這種操作是抽象的,統(tǒng)一的 。用戶不必關(guān)心物理顯存的位置、換頁(yè)機(jī)制等等具體細(xì)節(jié) 。這些都是由Framebuffer設(shè)備驅(qū)動(dòng)來(lái)完成的 。
Framebuffer對(duì)應(yīng)的源文件在linux/drivers/video/目錄下 。總的抽象設(shè)備文件為fbcon.c,在這個(gè)目錄下還有與各種顯卡驅(qū)動(dòng)相關(guān)的源文件 。在使用幀緩沖時(shí),Linux是將顯卡置于圖形模式下的 。
試驗(yàn)
我們以一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明字符顯示的過(guò)程 。我們假設(shè)是在虛擬終端1(/dev/tty1)下運(yùn)行一個(gè)如下的簡(jiǎn)單程序 。

main ( )
{
puts("hello, world.n");
}
puts函數(shù)向缺省輸出文件(/dev/tty1)發(fā)出寫的系統(tǒng)調(diào)用write(2) 。系統(tǒng)調(diào)用到linux核心里面對(duì)應(yīng)的核心函數(shù)是console.c中的con_write(),con_write()最終會(huì)調(diào)用do_con_write( ) 。在do_con_write( )中負(fù)責(zé)把"hello, world.n"這個(gè)字符串放到tty1對(duì)應(yīng)的緩沖區(qū)中去 。
do_con_write( )還負(fù)責(zé)處理控制字符和光標(biāo)的位置 。讓我們來(lái)看一下do_con_write()這個(gè)函數(shù)的聲明 。

static int do_con_write(struct tty_struct * tty, int
from_user, const unsigned char *buf, int count)
其中tty是指向tty_struct結(jié)構(gòu)的指針,這個(gè)結(jié)構(gòu)里面存放著關(guān)于這個(gè)tty的所有信息(請(qǐng)參照l(shuí)inux/include/linux/tty.h) 。Tty_struct結(jié)構(gòu)中定義了通用(或高層)tty的屬性(例如寬度和高度等) 。
在do_con_write( )函數(shù)中用到了tty_struct結(jié)構(gòu)中的driver_data變量 。driver_data是一個(gè)vt_struct指針 。在vt_struct結(jié)構(gòu)中包含這個(gè)tty的序列號(hào)(我們正使用tty1,所以這個(gè)序號(hào)為1) 。Vt_struct結(jié)構(gòu)中有一個(gè)vc結(jié)構(gòu)的數(shù)組vc_cons,這個(gè)數(shù)組就是各虛擬終端的私有數(shù)據(jù) 。

static int do_con_write(struct tty_struct * tty, int
from_user,const unsigned char *buf, int count)
{
struct vt_struct *vt = (struct vt_struct *)tty->
driver_data;//我們用到了driver_data變量
. . . . .
currcons = vt->vc_num; file://我們?cè)谶@里的vc_nums就是1
. . . . .
}
要訪問(wèn)虛擬終端的私有數(shù)據(jù),需使用vc_cons〔currcons〕.d指針 。這個(gè)指針指向的結(jié)構(gòu)含有當(dāng)前虛擬終端上光標(biāo)的位置、緩沖區(qū)的起始地址、緩沖區(qū)大小等等 。"hello, world.n"中的每一個(gè)字符都要經(jīng)過(guò)conv_uni_to_pc( ) 這個(gè)函數(shù)轉(zhuǎn)換成8位的顯示字符 。這要做的主要目的是使不同語(yǔ)言的國(guó)家能把16位的UniCode碼映射到8位的顯示字符集上,目前還是主要針對(duì)歐洲國(guó)家的語(yǔ)言,映射結(jié)果為8位,不包含對(duì)雙字節(jié)(double byte)的范圍 。
這種UNICODE到顯示字符的映射關(guān)系可以由用戶自行定義 。在缺省的映射表上,會(huì)把中文的字符映射到其他的字符上,這是我們不希望看到也是不需要的 。所以我們有兩個(gè)選擇∶

推薦閱讀