萬盛學電腦網

 萬盛學電腦網 >> 服務器教程 >> 如何改造 Linux 虛擬終端顯示文字

如何改造 Linux 虛擬終端顯示文字

  簡介: 本文就 CJKTTY 補丁如何讓 linux 虛擬終端顯示漢字的原理進行了討論,為此介紹了 Linux 虛擬終端和其依賴的硬件的工作原理。過程中我們分析了 Linux 字符終端的不足之處,並向讀者介紹前沿的 Wayland system compositor 是什麼以及為什麼 需要它。

  CJKTTY 補丁是什麼,為什麼我寫了它

  當你不使用 X 的時候,打開電腦,你就在使用虛擬終端。這麼多年來它工作的很好,直到它來到了中國。包含中文字符的文件名無法正確顯示,中文文檔無法閱讀。當然可以使用 X , 但是我為什麼不能讓終端也能顯示漢字呢?如果在 X 下我能讓屏幕顯示漢字,終端下一定也能。為此我開始了 internet 上的搜尋。 我找到了 fbterm,這是個可以利用 /dev/fb0 實現的終端模擬器,和 XTERM 一樣,只不過 XTERM 利用的 X 繪制文字,而 fbterm 直接寫入 /dev/fb0。

  /dev/fb0 是什麼?

  幀緩沖區設備。幀緩沖區是一塊存儲區域(內存或者顯存或者其他的輸出設備的存儲空間),內核將其抽象為一個設備。通過訪問該設備就能訪問幀緩沖區。幀緩沖區的內容既是屏幕映像。由輸出設備不停的掃描幀緩沖區生成顯示設備的控制信號。

  然而我似乎總是忘記登錄後開啟 fbterm,對我來說,等看到亂碼的時候突然想起沒有開啟 fbterm 並不是那麼愉快的經歷。這只是其中一個缺點。fbterm 占用了幀緩沖區設備,導致 w3m 這類使用幀緩存繪制圖像的終端 www 浏覽器不能正常工作。許多依賴幀緩沖區設備的終端程序都不能被 fbterm 良好的兼容。 於是我繼續尋找,找到了 youbest 寫的中文補丁。 我有個喜歡使用最新內核的習慣,當內核升級導致 youbest 的補丁再也不能使用的時候,我開始到 youbest 發布補丁的頁面留言,希望 youbest 百忙中能修改一下他的補丁。

  Youbest 似乎很忙,在新內核的誘惑下,我決定自己在修改。那個時候我才真正的開始看內核的代碼。終於了解了虛擬終端的工作原理後,我開始修改內核。由於內核內部結 構變動導致 youbest 的補丁無法應用,我幾乎是從頭開始了開發而不是簡單的將無法應用的部分進行修整。唯一得到保留的就是 youbest 補丁中的點陣字庫。我將其命名為 CJKTTY , 取能顯示 CJK 的 TTY 之意。

  從那裡獲得中文顯示補丁呢?

  我將補丁托管在了 http://repo.or.cz/w/linux-2.6/cjktty.git,依據你使用的內核版本,簽出內核版本 -utf8 分支就可以。

  控制台是如何顯示文字呢?

  那麼,為了能在控制台下顯示出漢字到底需要做什麼樣的修改麼?在開始前,我想先介紹一些名字,並介紹一些控制台在硬件上是如何進行文字顯示的。 首先我解釋一下幾個名詞,知道的人可以到這裡開始閱讀。

  UNICODE

  為每一個字符分配全球唯一的一個數字,但是並沒有規定這個數字的表示方法。數字的表示方法由 UTF 規范規定。UTF-16 使用 2 個字節表示一個 UNICODE 數字,但是對於 >=216的數字使用 4 字節來表達。UTF-8 則對於 <127 的數字采取單字節表示,大於 127 的數字要根據其大小選擇 2~6 個字節進行表示。UNICODE 在程序內部則簡單的使用 unsigned long 即可表示一個字符。

  GLYPH

  GLYPH 指的是字體裡的字形。字符總是要在特定的字體下表示的,該表示就是字形。比如一個只包含 26 個大小寫字母的字體,只包含了 52 個字形,如果該字體是先大寫後小寫排列的,那麼數字 0 就表示字形 'A' , 數字 1 就表示字形 'B'。UNICODE 或者 ASCII 到 GLYPH 的映射是由一個稱作 CMAP 的映射表做的。如果字體裡字符就是按照 UNICODE 排列的,則其 CMAP 就是 UNICODE CMAP。同理也有 ASCII CMAP。 VGA 自帶字體沒有提供 CMAP,操作系統假定它的 CMAP 是 ASCII CMAP。事實上也是如此。

  TTY

  內核為終端提供的接口,對應用程序而言就是 TTY 設備。通常是使用 stdin stdout 來訪問。TTY 提供各種 IOCTL 用來設置終端的模式。TTY 也提供了用戶控制程序的方法,比如 Ctrl-C 終止當前程序。 TTY 可以是顯示器 + 鍵盤構成的控制台,也可以是串口(可以通過貓鏈接到電話線上),可以通過 pts 模擬。XTERM 即利用 pts 為裡面運行的程序提供的模擬的終端 , 對應的設備文件 /dev/pts/* 由模擬終端程序動態創建。

  控制台 (CONSOLE)

  控制台特指由顯示器 + 鍵盤構成的終端。其中顯示器由顯卡控制,而且當前 VGA 兼容顯卡有兩種模式,文字模式和圖形模式。Linux 即可以使用文字模式也可以使用圖形模式。

  控制台對於程序是無法訪問的,程序只能通過虛擬終端使用控制台

  虛擬終端 (VT)

  如果你的電腦只有一個終端,那將是多麼乏味。一個需要長時間執行的任務就能導致你什麼也做不了,Linux 的多任務機制的好處蕩然無存。所以,你需要更多的終端。Linux 內核使用復用機制,將一個控制台復用為多個終端 (63 個,/dev/tty1 到 dev/tty63)。 按鍵 Alt+F1-F12 ( 如果當前在 X 中,需要再按下 Ctrl 鍵 ) 能在 12 個終端中進行切換。事實上你擁有 63 個終端,鍵盤只能切換其中的 12 個,其他的終端你可以通過 chvt 命令進行切換。

  當前擁有顯示器和鍵盤的虛擬終端被稱為活動終端或者當前終端。

  TTY、控制台和虛擬終端有啥區別和聯系?

  當你按下 Ctrl-C 的時候,當前執行的程序會被終止。因為 Linux 發送了 SIGTERM 信號給此終端的前台程序。該信號並不是由 Shell 產生,而是內核。不論是在虛擬終端下,還是在 X 裡的終端模擬器裡,這個功能都是一樣的。終端的一大功能就是進行任務控制,另一個功能是輸入輸出。輸入輸出模式下,還可以選擇行編輯模式,回顯模式,設置 終端速率等等。不管你使用的是何種終端,這些功能都是存在的,因為他們都是一個類型的設備。內核將他們抽象為 TTY 設備。也就是說,應用程序都是在和 TTY 這個抽象層打交道,而不是和具體的設備打交道。 能作為 TTY 的設備除了控制台外,還有串口。將兩台電腦的串口連接起來,其中一台電腦為串口打開登錄程序(執行 /sbin/agetty ttyS0 38400),另一台就能通過可以進行串口通信的程序 ( 比如 putty、minicom) 登錄對方。 控制台可以作為 TTY 設備,但是一台電腦一般只有一個屏幕,也就使用一個控制台,所以 Linux 在控制台和 TTY 之間加了一層虛擬終端。由虛擬終端將控制台復用,這樣就可以使用多個終端而不是只有一個了。多個虛擬終端設備合作使用一個控制台。 除了串口和虛擬終端,這些都是在內核實現的 TTY 設備,內核還提供了一個叫 PTY 的為終端設備,XTERM 之類的程序利用 PTY 提供的功能可以在程序裡實現 TTY 的功能。 那麼,虛擬終端就是利用控制台復用出了多個 TTY 。TTY 邏輯由 TTY 子系統完成,復用邏輯由虛擬終端實現,而具體的顯示則交給控制台完成。如果說這是一個觀察者模型的話,控制台就是觀察者,它將虛擬終端的內容呈現到屏幕 上。 在 Linux 下,控制台分文字模式控制台(vgacon)和圖形模式控制台 (fbcon)。

  文字模式控制台 (VGA 文字模式 )

  文字模式控制台使用 VGA 兼容顯卡的文字模式實現 VGA 兼容顯卡初始化時默認就處於文字模式,能顯示 80x25 個字符。

  在文字模式下,顯卡雖然輸出給顯示器的是圖像,但是顯卡提供給內核的卻只能顯示文字功能。要顯示一個字符,內核將要顯示的字符的代碼和屬性寫入字符緩沖區相應地址即可。緩沖區如下面所示:

  圖 1. 緩沖區

  表 1. 每個字符的格式

屬性字節 字符字節 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 閃爍 背景色 前景色 GLYPH

  VGA 顯卡處於文字模式時,物理地址 0xB8000 即文字緩沖區起始地址,大小由其文字模式決定,最大 32KB 。VGA 顯卡內建字符發生器,不斷的掃描字符緩沖區並將文字轉換為圖形驅動顯示器顯示。其 GLYPH 即為字符的 ASCII 碼。

  字符發生器和字體

  字符發生器內建一個或者多個位圖字體。使用何種字體取決於設置的文字模式代碼。Linux 默認使用 80x25 字符 16 色模式 , 每字符 8x16 點陣。 字符發生器的

copyright © 萬盛學電腦網 all rights reserved