Ubuntu 10.4で端末をシリアルポートにしてみた

Ubuntu 10.4をインストールしたPC/AT互換機を、端末としてシリアルポートを使うように設定してみた。最近はクライアント環境としてはMacBook Proを専ら使っていて、他のマシンにはSSH経由で入ることが多いので、ディスプレイやキーボードは邪魔なだけだ。メンテするときもUnixワークステーションの類はMacにUSB-Serialアダプタを挿してシリアルで繋ぐので、PC/AT互換機もそれに合わせたい。

基本的には Remote Serial Console HOWTO に従う。

  • 設定をミスしたときのためのブートディスクは作らなかったけど、安全を期すならやっぱり作った方が良い。
  • このマシンのBIOSはシリアルポートに出力する機能が見あたらなかった。BIOSをシリアル経由で扱うのは諦める。
  • このマシンにはシリアルポート3は存在しないので、ttyS2を無効化する手順は必要なかった。
  • ブートローダーが問題だ。HOWTOにはGRUB 1の設定例が載っているけど、GRUB 2はちょっと勝手が違う。
  • カーネルへに引き渡す引数はそのままで問題ない。問題は、それをGRUBの設定のどこに書くのか。
  • getty設定もHOWTOとはちょっと流儀が違う。

変数設定

結論から言えば、シリアルポートを使用する仕組み自体はGRUB2の設定テンプレートに含まれていた。概ね、 /etc/default/grub の設定値だけを弄れば十分である。次の値を設定した。

GRUB_CMDLINE_LINUX_DEFAULT="quiet console=tty0 console=ttyS0,9600n8"

GRUB_TERMINAL_INPUT="serial console"
GRUB_TERMINAL_OUTPUT="serial console"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=9600 --word=8 --parity=no --stop=1"

/boot/grub/grub.cfg においては設定 terminal_input , termianl_output はHOWTOに書かれている terminal *1 と同じく、複数の値を取れるようだ。しかし、 grub.cfg を生成するための /usr/sbin/grub-mkconfig/etc/grub.d/00_header は複数の値を受けとることを想定していない。そこで、次のパッチを当てる。設定値の中に gfxterm を含むとこれでもうまくないが、私の設定は "serial console" だから気にしない。

--- grub-mkconfig.orig  2010-06-21 16:25:32.373592706 +0900
+++ grub-mkconfig       2010-06-21 16:28:57.453592511 +0900
@@ -127,7 +127,8 @@
   GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
 fi

-case x${GRUB_TERMINAL_OUTPUT} in
+for grub_terminal_output_entry in "${GRUB_TERMINAL_OUTPUT}"; do
+case x${grub_terminnal_output_entry} in
   x | xgfxterm)
     # If this platform supports gfxterm, try to use it.
     if test -e ${grub_prefix}/gfxterm.mod ; then
@@ -144,9 +145,11 @@
   xconsole | xserial | xofconsole) ;;
   *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
 esac
+done

 # check for terminals that require fonts
-case ${GRUB_TERMINAL_OUTPUT} in
+for grub_terminal_output_entry in "${GRUB_TERMINAL_OUTPUT}"; do
+case ${grub_terminal_output_entry} in
   gfxterm)
     if [ -n "$GRUB_FONT" ] ; then
       if is_path_readable_by_grub ${GRUB_FONT} > /dev/null ; then
@@ -181,6 +184,7 @@
     # make sure all our children behave in conformance with ascii..
     export LANG=C
 esac
+done

 # These are defined in this script, export them here so that user can
 # override them.
--- 00_header.orig      2010-06-21 16:33:22.945593418 +0900
+++ 00_header   2010-06-21 16:33:29.805593524 +0900
@@ -65,7 +65,7 @@
 EOF

 case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in
-  serial:* | *:serial)
+  serial*:* | *:serial*)
     if ! test -e ${grub_prefix}/serial.mod ; then
       echo "Serial terminal not available on this platform." >&2 ; exit 1
     fi

getty

最後にgettyを設定する。Ubuntuに含まれているgettyはagettyなのか? ともあれ、manを参考にしながら設定する。

gettyの起動設定は、 /etc/init を見ると tty1.conf やら tty2.conf やらが並んでいるのでこれだろう。 tty1.conf をコピーして次のような ttyS0.conf を作った。

# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on runlevel [23]
stop on runlevel [!23]

respawn
exec /sbin/getty -8 9600 ttyS0

生成

以上で、 update-grub2 して再起動したところ、VGA出力+キーボードとシリアルポートの両方を端末として利用できるようになった。ま、実際には一気にやらないでgrub, kernel, gettyと順番に順次再起動して試しながらやったんだけどね。

*1:こちらは古い設定項目のようだ