引言##
這個標題有點長,是為了在標題中就把問題說清楚,以便搜索引擎能夠把有需要的朋友准確地帶到我這里來。目前在網絡上,很多關於 Linux 方面的知識是過時的和錯誤的。我標題中指出的兩個知識點就是其中的重災區。(這兩個知識點,在某寶的某幾個牛人合著的《Linux就是這個范兒》這本書中講的都是錯的。)
先來說說開機進入字符界面的問題。網絡上的答案一邊倒的就是修改/etc/inittab
文件,須不知,Fedora 系統和 Radhat Enterprise Linux 系統早就將 init 程序從 SysVinit 更換成了 systemd,雖然/etc/inittab
文件還在,但是已經只具有提示意義了。而 Ubuntu 中更是根本就不存在/etc/inittab
文件,而且 Ubuntu 中的運行級別的意義也和傳統的 Redhat Linux 不一樣,在 Ubuntu 中,運行級別 2\3\4\5 都是進入圖形界面。不要問我是怎么知道的,后面我會講到。
再來說說開啟 FrameBuffer 以及設置 FrameBuffer 分辨率的問題,網絡上的方法也是早就過時了。網絡上都說要開啟 FrameBuffer,需要先修改/etc/modprobe.d
中的文件,以便加載 vesafb 內核模塊,還要修改 Grub 給 Linux 內核傳遞 vga=? 的參數。可實際上,目前的 Linux 版本早就默認加載 drm 驅動,自動開啟 FrameBuffer 了,根本就不存在開啟 FrameBuffer 這樣的說法。至於 vga=? 這樣的參數, Grub2 也是不支持的。那么究竟怎樣才能設置 FrameBuffer 的分辨率呢?還是請大家閱讀后面的正文。
讓 Linux 開機進入字符界面的方法##
先來說 Ubuntu,我用過的從 Ubuntu 12.04 到現在的 Ubuntu 14.10 都可以用我下面所說的方法,至於更早的版本我沒用過我就不亂說了。Ubuntu 使用的 init 程序是屬於 Upstart 軟件包的,系統啟動后,運行 init 程序,然后運行/etc/init
目錄下的腳本。系統啟動時,先運行/etc/init/rc-sysinit.conf
,將該文件打開看一下,如下圖:
從該文件中可以看出,如果存在/etc/inittab
文件的話,它還是會解析該文件獲得默認運行級別的,否則就從 Grub 傳遞給內核的參數解析命令行級別。問題在於,它認為運行級別 2\3\4\5 是一樣的,對於想給內核傳遞一個 3 作為參數進入字符界面的夢想一下子就破滅了。不過沒關系,我們還可以從啟動 X 系統的顯示管理器入手,Ubuntu 使用的顯示管理器是 lightdm,正好/etc/init
目錄下有一個lightdm.conf
文件,打開看一下,如下圖:
從該文件中很容易看出,它也解析傳遞給內核的參數,如果參數中有 text 的話,它就不啟動。那么結論出來了,如果要讓 Ubuntu 啟動時自動進入字符界面,給它傳遞 text 參數即可。
對於 Fedora 來說就簡單了,它的/etc/inittab
文件還在,看一下該文件就可以得到提示,然后按照提示運行systemctl set-default multi-user.target
即可讓系統開機進入字符界面,要恢復圖形界面,只需要運行systemctl set-default graphical.target
命令即可。該方法在我使用的 Fedora 19、Fedora 20 和 Fedora 21 中均適用,更早的版本我沒用過就不知道了。如下圖:
設置 FrameBuffer 的分辨率的方法##
在舊系統中,如果進入純字符界面,界面的大小只有 80×25,當然是不夠用的啦,如果要在字符界面下繪圖啊、顯示中文啊什么的那就更加不夠用了,所以需要另外打開 FrameBuffer。在新系統中,FrameBuffer 默認就是打開的,貌似不需要另外設置。但是很不幸,目前的顯示器分辨率太高了,想像一下在 1920×1080 的分辨率下使用字符界面時字體是多么的小,再想像一下 4K 分辨率的屏幕呢。所以需要重新設置 FrameBuffer 的分辨率。
新系統(比如這里的 Fedora 19\20\21 以及 Ubuntu 12\13\14)是不能使用 vga=? 這樣的參數的。其實 vga=? 從來都不是內核支持的參數,只不過 Grub 會解析這個參數,然后以特殊的協議將它傳遞給內核而已。可惜,在新系統中,都用的是 Grub 的第 2 版了,Grub2 不支持 vga=? 這樣的參數。我是在閱讀了內核源代碼中的Documentation/kernel-parameters.txt
后知道的。如下圖:
然后根據該文檔中的說明,要設置 FrameBuffer 的分辨率,需要給內核傳遞 video=? 這樣的參數,該參數可以取什么樣的值呢?再將Documentation/fb/modedb.txt
文件打開看一下,如下圖:
其實還有更簡單的辦法,那就是直接修改 GRUB 的配置文件,設置 GRUB_AFXMOD=1024x768x32 這樣的參數就可以了,或者設置 GRUB_AFXPAYLOAD_LINUX=1024x768x32 。但是設置的分辨率一定要是你的顯示器和顯卡支持的分辨率。至於你的顯示器和顯卡支持什么樣的分辨率,可以在進入 GRUB 啟動界面的時候,按 'c' 鍵,然后在 grub> 提示符后輸入 vbeinfo 查看。
關於FrameBuffer和內核模塊##
能否成功啟用 FrameBuffer 和硬件軟件都有關系,首先是顯卡需要支持 FrameBuffer,其次是要選擇合適的 FrameBuffer 驅動。我在前面講到現在較新的 Linux 發行版都是默認開啟 FrameBuffer 的,這一點也不是完全准確,因為總有意外。在我的筆記本電腦以及使用 Intel 集顯的 HP 工作站上,FrameBuffer 是默認打開的。在虛擬機中,FrameBuffer 也是開啟的,不過 Fedora 和 Ubuntu 支持的分辨率不一樣。但是在我自己的配備 Nvidia GTX 860 顯卡的台式機上,在安裝了 Nvidia 驅動的情況下,FrameBuffer 就失效了。
后來我仔細研究 FrameBuffer 有效和失效的情況,發現還是和驅動程序有關,也就是和內核模塊有關。反正網絡上說的那幾個內核模塊 fbcon、vesafb 和 vga16fb 是指望不上的。在使用集成顯卡時,或者使用虛擬機時,svgadrmfb 驅動運行得就不錯,如果使用的是獨立顯卡,nouveau 模塊中的 nouveaufb 運行得也不錯。但是如果安裝了 Nvidia 的顯卡驅動, FrameBuffer 就失敗了,因為 Nvidia 顯卡驅動會在/etc/modprobe.d
目錄下面加上一些 blacklist 配置,使得沒有合適的 FrameBuffer 驅動運行。雖然可以手動更改配置載入 nvidiafb 模塊,但是經過我測試,該模塊的運行是有問題的。
怎么判斷 FrameBuffer 是否開啟呢?方法是查看/dev/fb0
文件是否存在。怎么查看目前的 FrameBuffer 分辨率是多少,以及由哪個驅動程序提供支持呢?這需要一個小工具 fbset。該工具可以使用yum install
命令或apt-get install
命令安裝。查看 FrameBuffer 的細節如下圖:
至於怎樣去測試各個模塊,那就只有去修改/etc/modprobe.d
目錄下的文件,然后不斷地重啟機器了,每次修改文件后,還要記得更新 initramfs 文件哦。
總結##
知道了要給內核傳遞什么參數,剩下的就是修改 Grub 的配置文件了。在 Grub2 中,推薦的方法已經不是修改/boot/grub/grub.cfg
文件了,而是先修改/etc/default/grub
文件,然后運行sudo update-grub
命令自動生成/boot/grub/grub.cfg
文件。你問我是怎么知道的呢,因為我閱讀了 Grub2 的文檔。閱讀 Grub2 的文檔用info grub
命令。
在/etc/default/grub
文件中,修改GRUB_AFXMODE=...
這一行,寫成GRUB_AFXMODE=1024x768x32
。后來我發現只能在虛擬機中修改 Framebuffer 的分辨率,在物理主機中是沒有用的,它只能顯示為顯示器的最大分辨率。所以想通過修改分辨率來放大字體是行不通的。
最后,sudo update-grub
一下,重啟機器,一切搞定。
(京山游俠於2015-03-31發布於博客園,轉載請注明出處。)
最新進展##
從 Ubuntu 15.04 開始,Ubuntu 也開始采用 systemd 作為它的 init 程序,所以,讓 Ubuntu 啟動后進入字符界面的方法也變得和 Fedora 一樣了。都是使用 sudo systemctl set-default multi-user.target
命令。進入圖形模式都是使用 sudo systemctl set-default graphical.target
命令。而 Framebuffer 是自動開啟的,除非使用 Nvidia 驅動,因為 Nvidia 驅動不支持 Framebuffer。要設置 Framebuffer 的分辨率,只需要修改GRUB配置文件的 GRUB_AFXMODE=1024x768x32
參數就可以了。而且這種方法只適用於虛擬機中的 Linux。在物理及中,想通過修改分辨率來放大字體是行不通的。
(京山游俠於2016-08-21更新於博客園,轉載請注明出處。)