Xを使わないCUI環境でコンソールの解像度を変更する方法について覚書です。DRM/KMS対応ドライバの場合、それ以外の場合、さらに古いPC(Trident Cyberblade等)のドライバを有効にする方法を調べました。
環境
まだ動いているのかと言われそうな古いノートPCです(Windows98時代の一品)。こいつのTrident CyberBlade用フレームバッファドライバを動かすべく奮闘しました。
- PC:Toshiba Dynabook Satellite 1800
- OS:Debian 9 (stretch) 32bit
- CPU:Celeron 950MHz
- MEM:384MByte
- GPU:Trident CyberBlade Ai1
- HDD:40GByte
フレームバッファドライバをロードする
フレームバッファの状態を確認する
まず、コンソール(CUI)で解像度を変更するためにはフレームバッファを有効にする必要があります。環境によってまちまちだと思うので、まずは現在の環境でフレームバッファが有効になっているかどうか確認します。
以下のようにコマンドを実行してください。
# fbsetをインストール $ sudo apt install fbset $ fbset -i
"open /dev/fb0: No such file or directory"などとメッセージが出るなら有効になっていません。次のパターン2もしくはパターン3に進んでください。デバイスの情報が表示されるようであれば有効になっています。パターン1に進んでください。
(パターン1)GPUのドライバがDRM/KMSに対応している場合
比較的最近のGPU(nvidia,radeonやintel)が載っているPCが該当します。OSにDRM/KMS対応ドライバが組み込まれていて、何もしなくとも対応するドライバがロードされていると思います。
自分の環境でDRM/KMS対応ドライバが読み込まれているかどうかは、dmesgでkernelログを確認すれば分かります(以下はVMWare環境のものです)。
$ sudo dmesg … [ 2.139018] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013). [ 2.139107] [drm] No driver support for vblank timestamp query. [ 2.139196] [drm] Screen Target Display device initialized [ 2.139285] [drm] width 640 [ 2.139374] [drm] height 480 [ 2.139463] [drm] bpp 32 [ 2.139552] [drm] Fifo max 0x00040000 min 0x00001000 cap 0x0000077f [ 2.139730] [drm] Using command buffers with DMA pool. [ 2.139819] [drm] DX: no. [ 2.145362] fbcon: svgadrmfb (fb0) is primary device [ 2.150574] Console: switching to colour frame buffer device 100x37 [ 2.152303] [drm] Initialized vmwgfx 2.12.0 20170221 for 0000:00:0f.0 on minor 0 …
すでにフレームバッファも有効になっているのでfbsetで情報を見ることが出来ます。
$ fbset -i mode "800x600" geometry 800 600 2048 1920 32 timings 0 0 0 0 0 0 0 rgba 8/16,8/8,8/0,0/0 endmode Frame buffer device information: Name : svgadrmfb Address : 0 Size : 15728640 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 1 YPanStep : 1 YWrapStep : 0 LineLength : 8192 Accelerator : No
DRM/KMS対応ドライバが読み込まれている環境で解像度を変更したい場合は、grubの設定ファイルに表示したい解像度を記載します。
/etc/default/grub
- GRUB_GFXMODE=1024x768x32
- GRUB_GFXPAYLOAD_LINUX=keep
grubの設定を更新します。
$ sudo update-grub2
あとは再起動すればコンソールの解像度が変更されます。
$ fbset -i mode "1024x768" geometry 1024 768 2048 1920 32 timings 0 0 0 0 0 0 0 rgba 8/16,8/8,8/0,0/0 endmode Frame buffer device information: Name : svgadrmfb Address : 0 Size : 15728640 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 1 YPanStep : 1 YWrapStep : 0 LineLength : 8192 Accelerator : No
(パターン2)vesafbを使用する場合
DRM/KMS対応ドライバが無い場合、汎用ドライバであるvesafbを使用するのが最も簡単です。Debianではvesafbはkernelに組み込まれています。
DRM/KMS対応ドライバのパターンと同じようにGRUBの設定を以下のように変更します。解像度はご使用の環境にあわせてください。
/etc/default/grub
- GRUB_GFXMODE=1024x768x32
- GRUB_GFXPAYLOAD_LINUX=keep
# 設定ファイルを修正 $ sudo vim /etc/default/grub # grubの設定を更新 $ sudo update-grub2
あとは再起動すればOKです。
ただ、このままだと表示がもっさりと重く感じるかもしれません。その場合はカーネルオプションに”video=vesafb:ywrap,mtrr:3”を追加してみてください。そこそこ改善すると思います。
/etc/default/grub
- GRUB_CMDLINE_LINUX=”video=vesafb:ywrap,mtrr:3”
(パターン3)GPU固有のフレームバッファドライバを使用する場合
さて、15年以上前のレガシーなノートPCをどうにかして活用しようとする奇特な人(私です)にとって本命です。ただし、他のパターンより面倒です。
目的のドライバを探す
Linuxには古いGPU向けのフレームバッファドライバ(DRM/KMS非対応のkernelモジュール)が存在していて、これを使うとvesafbよりもパフォーマンスの向上が期待できるかもしれません。また、稀だとは思いますがvesafbが上手く動作しないという場合には最後の希望となります。
各ドライバの概要についてはLinux Kernelのドキュメントが参考になります。この中から目的のGPUに対応したものを探してください。
- kernel.org - Index of files in Documentation/fb
https://www.kernel.org/doc/Documentation/fb/00-INDEX
この記事では私の古いノートPCに対応した”tridentfb”を使用します。念の為、以下のようにして目的のドライバがあることを確認しておきます。
$ sudo modinfo tridentfb
前準備
目的のドライバを見つけたら、次に自分の環境で動作するか確認します。その前準備として別のフレームバッファドライバが読み込まれていないか再度確認してください。
$ fbset -i
vesafbが読み込まれている場合は必ず無効にしてください。以降のドライバをロードする際に失敗します。
/etc/default/grubの以下のオプションを削除します。
- GRUB_GFXMODE=
- GRUB_GFXPAYLOAD_LINUX=
kernelオプションで以下のものを指定している場合は削除します。
- vga=
- video=
設定を変更したら反映/再起動してフレームバッファが無効になったことを確認してください。
ドライバの動作確認を行う
次に、実際にドライバをロードして動作確認します。画面表示が乱れることがあるので、ssh接続で作業したほうが良いかもしれません。
一発で動作すればよいのですが、ドライバオプションの試行錯誤が必要になることもあります。フレームバッファドライバは一度ロードすると削除してもう一度読み込むのに手順が必要になります。
(step.1)まず、フレームバッファドライバをロードしていない状態で以下のコマンドを実行します。
$ su - # sudo vbetool vbestate save > ~/vga_state
(step.2)次に目的のドライバをロードします。ここではtridentfbを解像度1024x768、色調16bitに指定しています。上手くいけば解像度が切り替わります。fbsetでフレームバッファの情報も表示されるはずです。
# modprobe tridentfb mode=1024x768-16 # fbset -i mode "1024x768-60" # D: 65.003 MHz, H: 48.365 kHz, V: 60.006 Hz geometry 1024 768 1024 768 16 timings 15384 168 8 29 3 144 6 rgba 5/11,6/5,5/0,0/0 endmode Frame buffer device information: Name : Trident Address : 0xfc000000 Size : 16777216 Type : PACKED PIXELS Visual : TRUECOLOR XPanStep : 0 YPanStep : 1 YWrapStep : 0 LineLength : 2048 MMIO Address: 0xfbc00000 MMIO Size : 4194304 Accelerator : Trident BladeXP
(step.3)上手くいかない場合は、一旦ドライバを削除してオプションを見直します(dmesgに何かエラーログが出力されているかもしれません)。以下のようにコマンドを実行してください。しばらくすると画面の表示が元に戻ります。この状態になればドライバを削除出来ます。
# vbetool vbestate restore > ~/vga_state && echo 0 > /sys/class/vtconsole/vtcon1/bind # modprobe -r tridentfb
再びドライバオプションを変更してベストな設定を探します。各ドライバのオプションについては以下にあるドキュメントを参考にしてください。
- kernel.org - Index of /doc/Documentation/fb/
https://www.kernel.org/doc/Documentation/fb/
(step.4)上手く動作するオプションを見つけたら、modprobe.dに設定ファイルを追加して書き込みます。
$ sudo echo 'options tridentfb mode=1024x768-16' > /etc/modprobe.d/tridentfb.conf
起動時にドライバを読み込むよう設定する
最後にブート時にドライバを読み込むように設定します。標準ではtridentfbのようなフレームバッファドライバはブート時にロードしないようblacklist指定されているので、これを修正します。
debianの場合、modprobe.dが以下の2箇所に存在しています。このうちブート時に関係するのは"/lib/modprobe.d"です。このディレクトリはinitramfsに組み込まれます。
- /etc/modprobe.d
- /lib/modprobe.d
(step.1)以下のファイルを修正してください。ここでは tridentfbの行をコメントアウトします(トラブルの元になるので必要なドライバだけコメントアウトするのが無難だと思います)。
/lib/modprobe.d/fbdev-blacklist.conf
... blacklist tdfxfb #blacklist tridentfb blacklist vt8623fb
(step.2)initramfsを再構築します(元のinitramfsは念の為バックアップ)。
$ cd /boot $ sudo cp initrd.img-($uname -r) initrd.img-($uname -r).org $ sudo update-initramfs -u -k $(uname -r)
(step.3)PCを再起動してください。問題なく解像度が切り替われば成功です。
所感
始まりは古い古ーいDynabookを押入れから引っ張り出したことでした。スペックはディスプレイの面積以外で中古のスマートフォンにすら完敗していますが、画面はそこそこ大きいので実験机の棚に乗っけて簡単な自家製計測器をモニタするには丁度よさげだったのです。
どうせUSB/シリアルで繋いでやり取りするだけなんで、重いXなしでCUI環境にしよう、ということでコンソールの解像度を変更する方法を探しました。vesafbを使うのが一番簡単でしたが、Linuxカーネルの中にTridentのドライバを発見。折角なので使ってみようと試行錯誤の結果が本記事です。
正直なところ、こんな古い世代のボロいノートPCを持っている人は少ないでしょうし使おうとする人は更に稀だと思いますが、なぜか意地になっていました。そういえば学生時代(このDynabookも現役だった)に同じようにTridentのドライバを使おうとして頓挫したような記憶が薄っすらと・・・。十数年越しのリベンジとなりました。
参考
この記事は以下の内容を参考にさせていただきました。
- kernel.org - Index of /doc/Documentation/fb/
https://www.kernel.org/doc/Documentation/fb/ - kernel.org - The Framebuffer Console
https://www.kernel.org/doc/Documentation/fb/fbcon.txt - GDDDBLOG - console/tty (framebuffer?) too slow!!!
https://gddd.wordpress.com/2009/10/08/ad/ - archlinux - Kernel Mode Setting
https://wiki.archlinux.jp/index.php/Kernel_Mode_Setting - すらりん日記 - DRM/KMS についてメモ
http://blog.techlab-xe.net/archives/4291 - serverfault - Where to place modules settings, /etc/modprobe.d or /lib/modprobe.d?
https://serverfault.com/questions/908620/where-to-place-modules-settings-etc-modprobe-d-or-lib-modprobe-d - FATDOG64 - Kernel Command Line Parameters (aka Boot Options)
http://distro.ibiblio.org/fatdog/web/faqs/boot-options.html
Trident Cyber搭載のPentium(無印)搭載機を動かしているのですが、画面表示がまともにできず困ってたので助かりました!
ありがとうございます。