20文字ごとに改行して、行数と文字数を数え上げる ruby スクリプト。

#!/usr/local/bin/ruby
# txt ファイルを読み取り、KetaSuu 文字ごとに改行を行い、
# 最後に字数や行数や段落数などの情報をつけたして出力するスクリプト。
#
# いわゆる全角文字・半角文字も、すべて一文字と数える。
# 手元に高機能なワープロソフトなどがない場合に、
# 原稿用紙換算で、何文字くらいかを数え上げたい場合に。
#
# 将来的には禁則処理などをつけくわえると良いと思う。
# たとえば、20文字ごとに切り分けた結果、
# 21文字目に "、" や "。" や "」" が来た場合には、
# その "、" や "。" や "」" の文字を出力したあとで改行するなど。

$KCODE = 'u';
require 'jcode'


KetaSuu = 20
lineNumber = 0
charctersNumber = 0
paragraphNumber = 1
isZenkakuHankakuConvert = true

while (line = ARGF.gets)

        # 段落分けのための空行は、行数にカウントしない。
        if ( line != "\n")
                lineNumber += 1
        else
                paragraphNumber += 1
        end

        # もし isZenkakuHankakuConvert が true なら、
        # 半角の英数字や記号を全角に変換する。
        if ( isZenkakuHankakuConvert)
                line = line.tr('0-9', '0-9')
                line = line.tr('a-z', 'a-z')
                line = line.tr('A-Z', 'A-Z')
                line = line.tr('(-)', '(-)')
                line = line.tr('[-]', '[-]')
                line = line.tr('?', '')
                line = line.tr('!', '')
                line = line.tr('.', '')
                line = line.tr(',', '')
                line = line.tr('-', '')
                line = line.tr('+', '')
                line = line.tr('=', '')
        end


        # 文字列 line の文字数が KetaSuu よりも多いのであれば
        # KetaSuu 文字ごとに出力しては改行することを繰り返す。
        while ( KetaSuu + 1 < line.split(//u).size) do
                print line.split(//u)[0, KetaSuu] ,  "\n"

                line = line.split(//u)[KetaSuu, line.split(//u).size].join
                lineNumber += 1
        end
        print line

        charctersNumber = (lineNumber - 1) * KetaSuu + line.split(//u).size
end

print "1行", KetaSuu, "",  "", lineNumber, ""

# 最後の eof を字数からマイナスするために -1 
print "", charctersNumber - 1, "文字\n"

print "", paragraphNumber, "段落\n"

FreeBSD 8.0 で、Windows の chm ファイルを閲覧する方法

 Windows の .chm 形式のファイルを、unix 系の OS で閲覧したいと思った。検索してみた結果、arCHMage というソフトウェアがあることがわかった。これを使えば、.chm 形式のファイルを、.html 形式のファイルに変換することができるようだ。

インストール方法

 FreeBSD の ports のなかに見つけたので、さっそくインストールしてみた。

# portupgrade -R -P -N textproc/archmage

その使用方法と、設定方法

 試しに、手元にあった windows.chm という名前のファイルを arCHMage で、html ファイルに変換してみよう。以下のように入力すれば、output というディレクトリが作成されて、そのディレクトリのなかに、いくつかの html ファイルが作成されるはずだ。

> archmage windows.chm output

 だが、うまくいかなかった。実際に実行してみたところ、下のような結果になった。どうやら、arch.conf という設定用のファイルを、あらかじめ /etc/archmage/ ディレクトリに配置しておく必要があるようだ。

> archmage windows.chm output
/usr/local/lib/python2.6/site-packages/archmod/Cached.py:14: DeprecationWarning: object.__new__() takes no parameters
  __instance = object.__new__(classtype, *args, **kwargs)
Traceback (most recent call last):
  File "/usr/local/bin/archmage", line 169, in 
    main()
  File "/usr/local/bin/archmage", line 152, in main
    CHMFile(options.chmfile) or CHMDir(options.chmfile)
  File "/usr/local/lib/python2.6/site-packages/archmod/CHM.py", line 37, in __init__
    execfile(archmod.config, self.__dict__)
IOError: [Errno 2] No such file or directory: '/etc/archmage/arch.conf'
> 

 探してみたところ、/usr/local/etc/archmage/ ディレクトリに、arch.conf というファイルがあることがわかった。では、この arch.conf ファイルをさっそく、/etc/archmage/ ディレクトリ上にコピーしてみよう。

 ルートになったうえで、まず /etc/ ディレクトリ上に、archmage/ ディレクトリを作成する。

# mkdir /etc/archmage

 おなじく、ルートのまま、さきほど見つけた /usr/local/etc/archmage/arch.conf ファイルを、いま作った /etc/archmage/ ディレクトリにコピー。

# cp -i /usr/local/etc/archmage/arch.conf /etc/archmage/arch.conf


 このようにしてから、archmage を実行したところ、すべてうまくいった。一行、DeprecationWarning という警告らしきものは表示されているようだが。まああまり気にしないことにしよう。

> archmage windows.chm output
/usr/local/lib/python2.6/site-packages/archmod/Cached.py:14: DeprecationWarning: object.__new__() takes no parameters
  __instance = object.__new__(classtype, *args, **kwargs)
> 

 output ディレクトリに作成されたファイルは、すべて html になっている。なので、この html ファイルを Web ブラウザ搭載の携帯電話などにコピーしてあげると、外出先でも .chm ファイルが読めるようになって便利。

そのほかの閲覧ソフト

 FreeBSD の ports のなかから、名前に "chm" が付くソフトをざっと抜き出してみただけでも、多分、以下のようなものが使えそう。

  • /usr/ports/converters/chmview/
  • /usr/ports/deskutils/chmsee/
  • /usr/ports/deskutils/gnochm/
  • /usr/ports/deskutils/kchm/
  • /usr/ports/deskutils/kchmviewer/
  • /usr/ports/deskutils/kchmviewer-kde4/
  • /usr/ports/deskutils/xchm/

参考にしたページ

Home Page | arCHMage

FreeBSD 8.0 で SOTEC C103 のタッチパッドを hald を用いて設定する方法

xorg をインストールし、/etc/rc.conf を編集

 Xorg を ports や packages からインストールすれば、その依存関係によって、hald や dbus などもインストールされたと思う。xorg をインストールし終わったら、まず、/etc/rc.conf に以下の二行を記述する。これで、マシンの起動時に hald や dbus が起動するようになる。

hald_enable="YES"
dbus_enable="YES"

 ところで去年、FreeBSD 7.2 をインストールしたときに、packages から xorg などもいっしょにインストールしたのだけど、haldaemon などのユーザが /etc/passwd に作られていなかったような記憶がある。もしこれらのユーザが、/etc/passwd に存在せずに、そのために不具合がでるようなら、手動でこれらのユーザを作成する必要があるかもしれない。

x11/libsynaptics と x11-drivers/xf86-input-synaptics のインストール。

 もうこれだけでも、マシンを再起動して、その後 startx などで X を起動すれば、タッチパッドやキーボードなどの最低限の機能は有効になっていたように思う。しかし、これからさらに色々な設定するためには、以下の二つの ports/packages をインストールする必要があったような気がする。 x11/libsynaptics x11-drivers/xf86-input-synaptics

 というわけで、以上の二つをインストールしたことを前提に先に進もう。

mouse-sysmouse.fdi の作成。

 hald に読み込ませるための /usr/local/etc/hal/fdi/information/mouse-sysmouse.fdi というファイルを作成。その中身は以下のようにした。

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.capabilities" contains="input.mouse">
      <match key="info.udi" string="/org/freedesktop/Hal/devices/psm_0">
        <merge key="info.capabilities" type="strlist">input</merge>
        <append key="info.capabilities" type="strlist">input.touchpad</append>
      </match>
    </match>
  </device>
</deviceinfo>

x11-synaptics.fdi ファイルの作成。

 つぎに hald に読み込ませるためのファイル /usr/local/etc/hal/fdi/policy/x11-synaptics.fdi を作成する。ここにタッチパッドの設定を記述する。その中身は、私は以下のようにしてみた。

<?xml version="1.0" encoding="ISO-8859-1"?>
<deviceinfo version="0.2">
  <device>
    <match key="info.capabilities" contains="input.touchpad">
      <merge key="input.x11_options.Protocol" type="string">psm</merge>

      <merge key="input.x11_options.LeftEdge" type="string">1300</merge>
      <merge key="input.x11_options.RightEdge" type="string">5500</merge>
      <merge key="input.x11_options.TopEdge" type="string">1300</merge>
      <merge key="input.x11_options.BottomEdge" type="string">4800</merge>

      <merge key="input.x11_options.FingerLow" type="string">25</merge>
      <merge key="input.x11_options.FingerHigh" type="string">30</merge>

      <merge key="input.x11_options.MaxTapTime" type="string">180</merge>
      <merge key="input.x11_options.MaxTapMove" type="string">220</merge>

      <merge key="input.x11_options.VertEdgeScroll" type="string">true</merge>
      <merge key="input.x11_options.HorizEdgeScroll" type="string">true</merge>

      <merge key="input.x11_options.VertScrollDelta" type="string">100</merge>
      <merge key="input.x11_options.HorizScrollDelta" type="string">100</merge>

      <merge key="input.x11_options.MinSpeed" type="string">0.06</merge>
      <merge key="input.x11_options.MaxSpeed" type="string">0.06</merge>
      <merge key="input.x11_options.AccelFactor" type="string">0.0010</merge>

      <merge key="input.x11_options.ScrollButtonRepeat" type="string">100</merge>
      <merge key="input.x11_options.UpDownScrolling" type="string">true</merge>
      <merge key="input.x11_options.UpDownRepeat" type="string">true</merge>
      <merge key="input.x11_options.LeftRightScrolling" type="string">true</merge>
      <merge key="input.x11_options.LeftRightRepeat" type="string">true</merge>

      <!-- "SHMConfig on" seems good works with synclient(1).  But this
           options is insecure.  I recommended "off" as default. -->
      <merge key="input.x11_options.SHMConfig" type="string">true</merge>
      <!-- If you use circular touchpad, uncomment them. -->
      <merge key="input.x11_options.CircularPad" type="string">true</merge>
      <merge key="input.x11_options.CircularScrolling" type="string">true</merge>
      <merge key="input.x11_options.CircScrollTrigger" type="string">8</merge>
    </match>
  </device>
</deviceinfo>

/boot/loader.conf の設定。

 つぎに /boot/loader.conf に以下の一行を追加する。

hw.psm.synaptics_support=1

あとは再起動して、X を起動するだけ。

 これで、マシンを再起動し、startx などで X を起動するだけでタッチパッドが使用できるようになっていると思う。

SHMConfig を有効にしているのなら、X を起動後、動的にタッチパッドの挙動を変更することができる。

 X の起動後、タッチパッドの挙動が気に入らなければ、synclient コマンドで、各値を動的に変更することができる。

> synclient LeftEdge=0

 上の例では、LeftEdge に 0 の値を動的に設定している。ただ、この synclient コマンドによる動的な設定を使用するためには、あらかじめ上の x11-synaptics.fdi のファイル上で、SHMConfig の値を有効にしておく必要がある。

 この SHM を用いた動的な設定は、便利ではあるが危険もともなうそうだ。この SHMConfig を有効にしていると、ルートにならなくても、一般のユーザがタッチパッドの各値を動的に好きなように変更できる。なので、多人数で一台のマシンを共用しているときは、オフにしておいたほうが良いようだ。*1

 またもう一つの注意点としては、この synclient によって動的に変更した値は、上記の x11-synaptics.fdi という xml ファイルに保存されるわけではない。なので、X を再起動したりすると、すべて xml ファイルに記述した値に戻ってしまう。

 なので、満足のいく設定ができたら、以下の -l オプションで、現在の状態を出力し、その出力結果を参考に、xml ファイルを書き換えると良いと思う。

> synclient -l

 出力結果は、リダイレクトなどを使って、ファイルに保存しておくのも良いかもしれない。

> synclient -l > mySynclientList.txt

 下のように awk を使って、出力結果を整形してやれば、xml ファイルに反映させるときに便利かもしれない。

> synclient -l | awk '/=/{printf "      <merge key=\"input.x11_options.%s\" type=\"string\">%s</merge>\n",$1,$3}'

 なお、X だけを再起動したとしても、hald を再起動していなければ、書き換えた xml ファイルの値は、有効にならない。xml ファイルに設定した値を有効にするためには、以下のコマンドで hald を再起動させよう。そうすれば、hald は変更後の xml ファイルを読み込んでくれる。(もっと簡単な方法があるかもしれないけれど、よくわからない)

# /usr/local/etc/rc.d/hald restart

 hald を再起動させたあとで、X を起動すれば、変更後の xml の値も有効になる。でも一番、単純明快な方法は、マシン自体を再起動させてしまうことかもしれない。

タッチパッドの微調整。synclient -m を利用する。

 以下のコマンドを用いれば、タッチパッドの現在の状態を50ミリ秒ごとに監視できる。

> synclient -m 50

 これを参考にしながら、設定すると良いかもしれない。この機能を使用するときも、SHMConfig を有効にしておく必要がある。

付録・SOTEC C103 における Xorg 7.4 の設定。

 最後に、Xorg 自体の設定方法についても少しだけ。hald と DBus を有効にしておけば、とくに /etc/X11/xorg.conf ファイルを作成する必要もないようだ。私は xfce4 や gnome2 を portupgrade でインストールしたのちに、ホームディレクトリに ~/.xinitrc というファイルを作った。ファイルの中には、このように記述した。

export LANGUAGE=ja
export LANG=ja_JP.UTF-8

export XMODIFIERS='@im=SCIM'
scim -d &

startxfce4
#gnome-session
#exec startkde

 上記は、xfce4 をデスクトップ環境にするための設定。gnome2 を起動したい場合には、上記の startxfce4 の行の先頭に # をつけてコメントアウトし、かわりに現在コメントアウトしている #gnome-session の行の先頭についている # の文字を削除する。kde を起動したいときも、おなじように startxfce4 の先頭に # をつけてコメントアウトし、かわりに #exec startkde の行の # の文字を削除。

 なお、私は日本語を入力するために japanese/scim-anthy をインストールしている。scim -d & の行はなくても gtk2 を用いた大部分のソフトウェアで日本語を入力できるけれど、この行で scim をデーモン・モードで起動しておくと、たとえば Java の swing を使ったソフトウェアなどでも日本語を入力できるようになるようだ。

 上記のようなファイルを用意し、以下のように入力すれば、Xorg が起動する。

> startx

 X については、以下のページなどを見ると良いと思う。
X Window System
The X Window System

*1:以下は、synclient(1) から抜粋。"WARNING: The SHM mechanism is not secure if you are in an untrusted multiuser environment. All local users can change the parameters at any time." 以下、その意訳。"注意: もしあなたが複数のユーザとマシンを共有しているのなら、この SHM メカニズムは安全ではありません。ローカルユーザなら誰でも、これらのパラメータをいつでも好きなように変更することができるからです。"

FreeBSD 8.0 で SOTEC C103 の無線 LAN (Atheros AR928X) を有効にする手順

現状と下準備

 一応、FreeBSD 8.0-RELEASE-p2 で起動時に、ath0 というデバイスは表示されるものの、私ではこれをうまく設定することができなかった。そこで今回も、ndis0 を使用することにした。とりあえず参考までにうまくいかなかった例も、この記事の末尾に示した。

 まず、windows 用のドライバである athw.sys と oem26.inf を用意して、ndis 用のデバイスドライバを作成する。その手順は、FreeBSD 7.2 で SOTEC C103 の無線 LAN を有効にする手順 - r_coppeliaの日記 に記述したので今回は省略。

ndis を使用する例。

athw_sys.ko の生成と /boot/loader.conf の設定。

 上の blog の手順に従って、athw_sys.ko というファイルを生成し、それを下のようにして /boot/kernel/ ディレクトリなどに配置。

# cp -i athw_sys.ko /boot/kernel/

 そして /boot/loader.conf に、下記の一行を書き加えた。この一行によって、FreeBSD が起動時に、自動的にこの作成したデバイス・ドライバが読み込まれる。

athw_sys_load="YES"
/etc/rc.conf の設定と、パスワードのために /etc/wpa_supplicant.conf を設定する。

 つぎは、/etc/rc.conf の設定と、パスワードなどの設定。まず /etc/rc.conf の末尾に、下記の二行を書き加える。これで(無線 LAN ルータなどで DHCP が有効になっているのなら) FreeBSD を起動したさいに、wlan0 というデバイスに、IP アドレスなどが割り振られることになる。

wlans_ndis0="wlan0"
ifconfig_wlan0="WPA DHCP"


 また、/etc/wpa_supplicant.conf というファイルを作成した。ここにパスワードなどを記述する。
その中身は以下の通り。

ctrl_interface=/var/run/wpa_supplicant
ap_scan=2

network={
	ssid=" この中には ssid キーが入っている。 "
	bssid= ここにも bssid を入力
	scan_ssid=1
	key_mgmt=WPA-PSK
	psk=" この中には、psk のキーが入ってる。"
}
再起動

 あとは再起動。再起動後に ifconfig などと入力すれば、ndis0 と wlan0 というデバイスが生成されているはず。そして wlan0 に IP アドレスなどが割り振られているはず。割り振られていたら、めでたしめでたし。

再起動後の ifconfig wlan0 の出力結果
> ifconfig wlan0
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether 省略
	media: IEEE 802.11 Wireless Ethernet OFDM/54Mbps mode 11g
	status: associated
	ssid 省略 channel 3 (2422 Mhz 11g) bssid 省略
	country US authmode WPA2/802.11i privacy OFF powersavemode CAM
	powersavesleep 100 txpower 0 bmiss 7 mcastrate 6 mgmtrate 6
	scanvalid 60 protmode CTS roaming MANUAL bintval 0

参考までに、 ndis を使わず、うまくいかなかった例その1

その設定。

 /boot/loader.conf には以下の一行を記述。

if_ath_load="YES"

 /etc/rc.conf には以下の二行を記述。

wlans_ath0="wlan0"
ifconfig_wlan0="WPA DHCP"
再起動時の dmesg
> dmesg | grep ath
module ath already present!
ath0: <Atheros 9280> mem 0xd0000000-0xd000ffff irq 16 at device 0.0 on pci2
ath0: [ITHREAD]
ath0: AR9280 mac 128.2 RF5133 phy 13.0
ifconfig wlan0 と ifconfig ath0 の出力結果。
# ifconfig wlan0
wlan0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
	ether (この記述は省略。)
	media: IEEE 802.11 Wireless Ethernet autoselect (autoselect)
	status: no carrier
	ssid "" channel 1 (2412 Mhz 11b)
	regdomain 96 indoor ecm authmode WPA2/802.11i privacy ON
	deftxkey UNDEF txpower 20 bmiss 7 scanvalid 450 bgscan bgscanintvl 300
	bgscanidle 250 roam:rssi 7 roam:rate 1 wme burst roaming MANUAL
	bintval 0
#
# ifconfig ath0
ath0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 2290
	ether (この記述は省略。)
	media: IEEE 802.11 Wireless Ethernet autoselect (autoselect)
	status: no carrier
# 
さらに wpa_supplicant を手動で実行した結果

 起動後、一応、念のためにさらに wpa_suuplicant を wlan0 と ath0 に対して、手動で実行してみたときの実行結果。

# wpa_supplicant -c/etc/wpa_supplicant.conf -iwlan0
ctrl_iface exists and seems to be in use - cannot override it
Delete '/var/run/wpa_supplicant/wlan0' manually if it is not used anymore
Failed to initialize control interface '/var/run/wpa_supplicant'.
You may have another wpa_supplicant process already running or the file was
left by an unclean termination of wpa_supplicant in which case you will need
to manually remove this file before starting wpa_supplicant again.

ioctl[SIOCS80211, op 26, arg 0x0]: Operation not supported
Failed to disable WPA in the driver.
ELOOP: remaining socket: sock=4 eloop_data=0x28406140 user_data=0x2840d040 handler=0x8069f40
# 
# wpa_supplicant -c/etc/wpa_supplicant.conf -iath0
ioctl[SIOCG80211, op 98, len 32]: Invalid argument
Failed to initialize driver interface
ELOOP: remaining socket: sock=4 eloop_data=0x28406140 user_data=0x2840d040 handler=0x8069f40
# 

うまくいかなかった例その2。/etc/rc.conf に ifconfig_ath0="WPA DHCP" と記述した例。

設定

 /boot/loader.conf はその1と同じ。/etc/rc.conf は、以下のように記述。

ifconfig_ath0="WPA DHCP"
wpa_supplicant を手動で実行した結果

 起動後、一応、念のために wpa_suuplicant を手動で実行してみたときの実行結果。

# wpa_supplicant -c/etc/wpa_supplicant.conf -iath0
ioctl[SIOCG80211, op 98, len 32]: Invalid argument
Failed to initialize driver interface
ELOOP: remaining socket: sock=4 eloop_data=0x28406140 user_data=0x2840d040 handler=0x8069f40
# 

HDD のパーティションの一つを ZFS にして、その ZFS に、FreeBSD 8.0 をインストールする手順。

注意

 この文章は、あくまでも私がおこなった作業の個人的な記録として作成したものです。その内容の大部分は、裏付けのない個人的な推測や妄想などによって構成されています。事実の誤認や、不適切な処理や、誤った翻訳なども含んでいるかと思われます。

 もし万が一にも、このような信頼のできない文章を何かの参考にしようとしたり、その記述に何らかの事実が含まれていると誤認してしまったために、損害を被ったとしても、私にその責任は負えません。

はじめに

なにをしようとしているのか。

 これからやろうとしていることは、二つ。まず一つは、SOTEC C103 というノートパソコンの HDD の空き領域の一つを、ブート可能な ZFS ファイルシステムとする。そして二つは、その ZFS ファイルシステム上に、FreeBSD 8.0 をインストールする。

 なお、このノートパソコン SOTEC C103 の HDD は、過去に FreeBSD 7.2 をインストールしたときに、パーティションを四つほどに区切ってある。先頭の二つは、Windows XP のリカバリ領域と、Windows XP の領域。三つめは、何か他の OS などを使ってみたくなったときのために開けてある未使用の領域。四つめは、FreeBSD 7.2 をインストールした領域。

 今回は、この四番目の領域を更地にして、ここに ZFS ファイルシステムを構築し、FreeBSD 8.0 をインストールしてみようと思う。

 インストールが無事に完了したら、第二パーティションにすでにインストールずみの Windows XP と、これから四番目のパーティションにインストールする FreeBSD 8.0 とあわせて、デュアルブートになるだろう。

その手順の大雑把な説明。

 大雑把に四つの手順から成る。

0. 下準備
まず、8.0-RELEASE-i386-memstick.img というファイルを USB メモリに書き込み、起動可能な USB メモリを作成する。完成する USB メモリは、FreeBSD 8.0 i386 版のインストールディスクとなる。
1. ブート可能な ZFS ファイルシステムを構築する。(1. Creating a bootable ZFS Filesystem)
下準備で作成した USB メモリを用いて SOTEC C103 を起動する。そしてこの C103 の HDD の四番目のパーティションに、ブート可能な ZFS ファイルシステムを作成する。
2. ZFS filesystem に FreeBSD 8.0 をインストールする。(2. Installing FreeBSD to the ZFS filesystem)
作成した ZFS ファイルシステム上に、FreeBSD 8.0 をインストールする。
3. 最後の総仕上げ。(3. Finish install)
最後にこまごまとした設定を行ないインストールを完了し、再起動。

 なお、ここで言う「パーティション」とは、FreeBSD の用語に従えば「スライス」ということになるそうだ。*1

 以下の私の文章でも、この FreeBSD の語法に従うことにした。なので以降の文中に登場する「スライス」は MS-DOS などでいう「パーティション」を指す。また以降の文中で「パーティション」という言葉があれば、それは「スライス」の中をさらにいくつかに区切った小領域のことを指す。(小領域といっても、優に 90GB はあるが)


作業環境と用意したもの。
  • ノートパソコン。SOTEC C103 (CPU Atom N270, メモリ 1GB, HDD 160GB. この HDD は過去に GParted Live によって、四つほどにパーティションを区切ってある。)
  • 1GB の USB メモリ
  • 8.0-RELEASE-i386-memstick.img ファイル。
  • すでに FreeBSD をインストールずみのデスクトップパソコン一台。(Windows 機や、Linux 機などでも可)

 8.0-RELEASE-i386-memstick.img は、Bittorrent を用いてダウンロード()し、FreeBSD 8.0-RELEASE Announcement のページで Checksum を確認。

0. 下準備

 この下準備では、以下の二つのことを行なう。

  1. まず、起動可能な USB メモリを作成し、
  2. つぎにそのUSB メモリからノートパソコン C103 を起動する。
起動可能な USB メモリを作成

 あらかじめダウンロードしておいた 8.0-RELEASE-i386-memstick.img を USB メモリに書き込む。この作業は、ノートパソコンとは別のデスクトップパソコンで行なった。

 まず、USB メモリをデスクトップパソコンに挿入。 dmesg などのコマンドで、この USB メモリが /dev/da0 として認識されていることを確認。

 ルートになって、dd コマンドを用いて、 /dev/da0 に対して、 8.0-RELEASE-i386-memstick.img を書き込む。

# dd if=8.0-RELEASE-i386-memstick.img of=/dev/da0 bs=10240 conv=sync

 これで、起動可能な USB メモリができあがった。今回は、FreeBSD マシンで行なったが、起動可能な USB メモリを作成できるのであれば、Linux でも、Windows でも、どんなマシンを使ってもかまわない。

USB メモリから C103 を起動

 完成した USB メモリを SOTEC C103 に差し込み、BIOS を設定し、USB メモリからブート。これであとは、キーボードなどの設定画面を経ると、以下のような FreeBSD 8.0 のインストール画面(sysinstall)に進むことになるだろう。

┌───────── FreeBSD/i386 8.0-RELEASE-p2 - sysinstall Main Menu ──┐
│ Welcome to the FreeBSD installation and configuration tool.  Please      │
│ select one of the options below by using the arrow keys or typing the    │
│ first character of the option name you're interested in.  Invoke an      │
│ option with [SPACE] or [ENTER].  To exit, use [TAB] to move to Exit.     │
│ ┌──────────────────────────────────┐ │
│ │   Usage         Quick start - How to use this menu system          │ │
│ │  Standard       Begin a standard installation (recommended)        │ │
│ │  Express        Begin a quick installation (for experts)           │ │
│ │   Custom        Begin a custom installation (for experts)          │ │
│ │  Configure      Do post-install configuration of FreeBSD           │ │
│ │  Doc            Installation instructions, README, etc.            │ │
│ │  Keymap         Select keyboard type                               │ │
│ │  Options        View/Set various installation options              │ │
│ │  Fixit          Repair mode with CDROM/DVD/floppy or start shell   │ │
│ │  Upgrade        Upgrade an existing system                         │ │
│ │  Load Config..  Load default install configuration                 │ │
│ │  Index          Glossary of functions                              │ │
│ └──────────────────────────────────┘ │
├─────────────────────────────────────┤
│                        [ Select ]    X Exit Install                      │
└─────────────────────────────────────┘

 ここから先の作業手順はすべて基本的には、以下の URL に従った。
http://wiki.freebsd.org/RootOnZFS/ZFSBootPartition

 以下の文章も、そのほとんどは上記の wiki に提示されていた処理を、逐次的に実行した結果を記録したもの。上記の記事中で、途中、何ヶ所か、私の環境にあわない記述に関しては、その都度、読み替えて実行した。

1. ブート可能な ZFS ファイルシステムを構築する。(1. Creating a bootable ZFS Filesystem)

 さて、この FreeBSD のインストール画面から、Fixit というオプションを選択し、ここから手動で HDD のジオメトリをいじりつつ、ブート可能な ZFS ファイルシステムをつくりあげていくことになる。

 ここでは、以下の6つの作業を順番に行なっていく。これら6つが完了したら、2. ZFS filesystem に FreeBSD 8.0 をインストールするに進むことになる。なお括弧内には、上記 wiki の対応する項目を記述した。

手順
  1. C103 の四番目のスライスの全パーティションを、削除する。
  2. 四番目のスライスに、二つパーティションを作成する。一つは ZFS 用に。一つは swap 用に。(6. Create partitions (ad0s3a and ad0s3b) )
  3. つぎに、ZFS kernel module を load する。(7. Load ZFS kernel module)
  4. ZFS Pool zroot を作成する。(8. Create ZFS Pool zroot)
  5. boot マネージャのインストール。(9. Install boot Manager )
  6. ZFS boot のインストール。(10. Install ZFS boot)
1. C103 の四番目のスライスの全パーティションを、削除する。

 さて。私のノートパソコン C103 は、その内蔵 HDD の四番目のスライスに、FreeBSD 7.2 をインストールしている。

 いまからこの四番目のスライスの中身をぜんぶ削除して、ここに FreeBSD 8.0 をインストールしようと思う。そのため上記 wiki 中の、"3. Create MBR disk" と "4. Create Slice using gpart" の手順は省略した。

 まず、 ls /dev コマンドなどで、この内蔵 HDD が、/dev/ad4 と認識されていることを確認した。つぎに、この /dev/ad4 の四番目のスライスである ad4s4 の構成を gpart show コマンドで確認してみよう。

Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		1048576		1	freebsd-ufs	(512M)
	1048576		8388608		2	freebsd-swap	(4.0G)
	9437184		4141056		4	freebsd-ufs	(2.0G)
	13578240	8388608		5	freebsd-ufs	(4.0G)
	21966848	176939020	6	freebsd-ufs	(84G)


 つぎに、gpart delete で 以上の ad4s4 スライス内の全パーティションを消してしまう。

Fixit# gpart delete -i 1 ad4s4
Fixit# gpart delete -i 2 ad4s4
Fixit# gpart delete -i 4 ad4s4
Fixit# gpart delete -i 5 ad4s4
Fixit# gpart delete -i 6 ad4s4


 消えたかどうか gpart show で確認してみよう。

Fixit# gpart show ad4s4
=>	0	198905868	ad4s4	BSD		(95G)
	0	198905868		- free -	(95G)

 どうやら無事に消えて、かわりに 95GB の空き領域が生まれたようだ。

2. 四番目のスライスに、二つパーティションを作成する。一つは ZFS 用に、一つは swap 用に。(6. Create partitions (ad0s3a and ad0s3b) )

 では、この 95GB の空き領域のある ad4s4 スライス内に、あらためて ad4s4a と ad4s4b の二つのパーティションを作成しよう。そしてそのうちの一つを ZFS 用の領域にしよう。もう一つは、スワップ用の領域にしよう*2。とりあえずスワップ領域には 4GB もあればいいと思う。

 なぜなら、このノートパソコンが搭載できるメモリが最大で 2GB であるので、その2倍ということで、4GB にすることにした。また、上記 wiki 中の例でも、4GB として、8380811セクタを割り当てていることであるし。*3

 さて、ではこの ad4s4 の空き領域 95GB から、まず ZFS 用の領域を割り当てよう。swap 用の領域に 4GB を割り当てることにしたわけだから、4GB 分を残して、91GB をぜんぶ ZFS 用に割り当てることになる。

 割り当ては gpart コマンドを用いて、セクタ数で指定しているようだ。wiki の記述によれば、1セクタが、512バイトらしい。

 私の HDD の空き容量は、さきほどの gpart show で示されたように、95 GB の 198905868 セクタ。ここから、swap 用に 4GB の 8380811 セクタを引いて計算すると、198905868 - 8380811 = 190525057 となる。

 なので、さっそく以下のコマンドで、190525057 セクタを ZFS 用に割り当てよう。実行後は、gpart show コマンドで、その結果を確認してみよう。

Fixit# gpart add -i 1 -b 0 -s 190525057 -t freebsd-zfs ad4s4
ad4s4a added
Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		190525057	1	freebsd-zfs	(91G)
	190525057	8380811			- free -	(4.0G)

 これで上記の出力結果が示しているように、8380811 セクタこと、4.0GB の空き領域が残った。あとはこの残りの 190525057 番目のセクタから、残余の 8380811 個のセクタを、以下のコマンドで swap 領域に割り当てる。やはりここでも実行後は、gpart show で、その結果を確認している。

Fixit# gpart add -i 2 -b 190525057 -s 8380811 -t freebsd-swap ad4s4
ad4s4b added
Fixit# gpart show ad4s4
=>	0		198905868	ad4s4	BSD		(95G)
	0		190525057	1	freebsd-zfs	(91G)
	190525057	8380811		2	freebsd-swap	(4.0G)

Fixit#

 これで上記の出力結果が示しているように、無事に、ZFS に 91GB、swap に 4.0GB の領域が設定できた。このあとは基本的に、上記 wiki とほぼ同じ手順をたどることになる。

3. つぎに、ZFS kernel module を load する。(7. Load ZFS kernel module)
Fixit# kldload /mnt2/boot/kernel/opensolaris.ko
Fixit# kldload /mnt2/boot/kernel/zfs.ko

 FreeBSD のカーネルは、モジュール化に対応しているそうだ。つまり動作中のカーネルに、何か別のモジュール(部品)を取り付けてやれば、そのカーネルはその取り付けたモジュールが提供するいろいろな機能を新たに実行できるようになるらしい。

 上記の kldload コマンドが、そのモジュールをカーネルに取り付けるためのコマンド。上記の kldload を実行することによって、このカーネルは、zfs.ko や opensolaris.ko というモジュールが提供する ZFS 機能を使用できるようになった。

4. ZFS Pool zroot を作成する。(8. Create ZFS Pool zroot)

 まずはじめに、下の zpool create zroot /dev/ad4s4a というコマンドによって、zroot という名前の ZFS pool を作成している。(この /dev/ad4s4a の部分は、自分の環境にあわせて読み替えることを忘れずに。)

Fixit# mkdir /boot/zfs
Fixit# zpool create zroot /dev/ad4s4a
Fixit# zpool set bootfs=zroot zroot

 ZFS pool とは、ZFS ファイルシステムの記憶領域。

 ZFS というファイルシステムは、実際のさまざまな種類のディスクデバイスなどをいくつかまとめあげて、まずプール (pool) という記憶領域をつくり、この記憶領域の上にデータセット (dataset) というファイルシステムを構築し、そしてそこに対してデータの読み書きなどを行なうという考え方のシステムらしい。

 上の例では、そのプールは、/dev/ad4s4a (ad4 というハードディスク・デバイスの、四番目のスライスの、aというパーティション)によって実際には担われることになる。

 また、man zpool コマンドによれば、プールはいくつかのプロパティを持っているそうだ。上記三行目の zpool set というコマンドによって、いま作ったばかりの zroot という名前のプールに対して、プロパティを設定している。具体的にいえば、zroot プールの bootfs というプロパティに、zroot という値を設定している。

 この bootfs というプロパティは、デフォルトのブート可能な dataset を指定するためのものだそうだ。なお、dataset というのは、pool の上に構築される ZFSファイルシステムのことを指すようだ。(以上は、man コマンドの zpool(1M) より)


 なにがなんだか、よくわからないので検索してみた。下のようなページが見つかった。

Booting from a ZFS file system differs from booting from UFS file system because with ZFS, a device specifier identifies a storage pool, not a single root file system. A storage pool can contain multiple bootable datasets or ZFS root file systems. When booting from ZFS, you must specify a boot device and a root file system within the pool that was identified by the boot device.

Oracle Documentation

かなりあやふやな翻訳:(ZFS ファイルシステムからブートするということは、UFS ファイルシステムからブートするということとは、違う。なにが違うのかといえば、ZFS では、ストレージ・プールを起動デバイスとして指定できる。そしてストレージ・プールは、複数のブート可能なデータセットや、複数の ZFS ルート・ファイルシステムなどから構成され得る。つまり ZFS は、単一のルート・ファイルシステムだけからなるようなシステムとは違う。

 なので、ZFS からブートさせる場合は、あなたは、どのデバイスからブートさせるのかをまず指定しなければならないし、それだけではなくさらに、そのブートデバイスが指定するストレージ・プールのなかのどのファイルシステムをルート・ファイルシステムとするのかも指定してやる必要がある。)

 というわけで、この bootfs というプロパティは、zroot プール内の、どのファイルシステム(どのデータセット)からブートさせるのか(つまりどのデータセットを、デフォルトのルートファイルシステムとするのか)を、指定するためのプロパティのようだ。ここでは「bootfs=zroot」と入力しているので、デフォルトではこの zroot プールのそのトップディレクトリ(という表現が正確なのかわからないが)からブートし、そのトップディレクトリをルートとするように設定したということになるのだろうか。

5. boot マネージャのインストール。(9. Install boot Manager )

 私のノートパソコン C103 には、すでに boot マネージャがインストールされている。以前、FreeBSD 7.2 をインストールしたさいに、boot マネージャをインストールしたのだ。なので下の gpart bootcode -b の手順は省略し、つぎの6. ZFS boot のインストール(10. Install ZFS boot)に進んだ。

Fixit# gpart bootcode -b /mnt2/boot/boot0 ad4
ad4 has bootcode
6. ZFS boot のインストール。(10. Install ZFS boot)

 boot コードをインストールする前に、まず zroot を export しよう。下のコマンドによって、先ほど作成した zroot という名前のプールが、export される。(おそらく、これからこの zroot を実装しているハードディスク・スライス (ad4s4) に直接書き込みを行なうので、その書き込みの前に zroot を unmount しておくような感じだろうか)

Fixit# zpool export zroot

 つぎは、dd コマンドを用いて boot1 stage をインストールする。dd コマンドに渡してやるデバイス名 (/dev/ad4s4) は、自分の環境に応じて読み替えることを忘れずに。(この of=/dev/ad4s4 は、どのディスクにデータを書き込むかを指定している。この指定を間違えると、意図しないディスクにデータを書き込むことになる。)

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s4 count=1
1+0 records in
1+0 records out
512 bytes transferred in 0.004847 secs (105631 bytes/sec)
Fixit# 

 私は、無事に /dev/ad4s4 に、ブート用コードである boot1 stage を書き込むことができた。もし以下のようなエラーが表示されて、書き込みに失敗した場合は、sysctl コマンドを実行すると良いらしい。

This may fail with an "operation not permitted" error message, since the kernel likes to protect critical parts of the disk. If this happens for you, run:

Fixit# sysctl kern.geom.debugflags=0x10

翻訳:(もしかしたら、"operation not permitted" というエラーメッセージが表示されて、dd コマンドの実行に失敗するかもしれない。なぜ失敗するかといえば、カーネルは、ディスクの重要な部分を保護したがるからだ。もし失敗した場合は、以下を実行すると良い。)

Fixit# sysctl kern.geom.debugflags=0x10


 私はうまくいったので、上記の sysctl の手順は無視して、先にすすむ。つぎは boot2 zfs stage を インストール。

Install the boot2 zfs stage into the convienient hole in the ZFS filesystem on-disk format which is located just after the ZFS metadata (this is the seek=1024).

翻訳:( boot2 zfs stage をインストールしよう。どこにインストールするのかといえば、ZFS metadata のすぐあとに。つまり 1024 以降に)

 以下の dd コマンドを実行するときも、やはり /dev/ad4s4a を自分の環境にあわせて読み替えることを忘れずに。

Fixit# dd if=/mnt2/boot/zfsboot of=/dev/ad4s4a skip=1 seek=1024
64+0 records in
64+0 records out
32768 bytes transferred in 0.010192 secs (3215021 bytes/sec)
Fixit# 

 さて、これで ZFS boot (ZFS の起動コード)をインストールしおわった。起動可能な ZFS ファイルシステムの構築はこれで完了である。あとはさきほど一度 export した zroot を以下のコマンドで import したら、つぎに進もう。

Fixit# zpool import zroot

2. ZFS filesystem に FreeBSD 8.0 をインストールする。(2. Installing FreeBSD to the ZFS filesystem)

 さて、前記の手順によって、ad4s4a に、起動可能な ZFS が構築できたので、こんどは、この ZFS 内に FreeBSD 8.0 をインストールする。なかなか面倒な作業だった。つぎにインストールするときまでには、全部、自動化してると嬉しいなと思った。

手順
  1. ZFS ファイルシステムのヒエラルキーを作成する。(1.Create ZFS filesystem hierarchy)
  2. zroot プールに FreeBSD をインストールする。(2. Install FreeBSD to zroot)
  3. /var/empty ディレクトリを readonly にする。(3.Make /var/empty readonly)
  4. chroot コマンドで、/zroot ディレクトリを一時的にルートディレクトリにする。(4.chroot into /zroot)
  5. /etc/rc.conf を作成。(5.Create /etc/rc.conf)
  6. /boot/loader.conf を作成する。(6. Create /boot/loader.conf)
  7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストール。(7.Install ZFS aware /boot/loader (Required for 8.0-RELEASE and 7.{0-2}-RELEASE) )
  8. root のパスワードを設定。(8. Change root's password)
  9. 時間の設定。(9. Set the local time zone)
  10. Create /etc/mail/aliases.db
  11. chroot を終了して /zroot から抜ける。(11. Exit from the /zroot)
  12. Install zpool.cache to the ZFS filesystem
1. ZFS ファイルシステムのヒエラルキーを作成する。(1.Create ZFS filesystem hierarchy)

 この手順において、zroot プールのなかに、さまざまなファイルシステム(データセット)を作成している。プールのなかのファイルシステム(データセット)とは、旧来のパーティションのようなものだと考えれば良いのだろうか。またここではファイルシステム(データセット)の作成と同時に、各ファイルシステムの圧縮率をどのくらいにするかなども設定している。私はすべて wiki 中にあるサンプル例に従った。

 もし、CPU の計算速度がそれなりに早くて、HDD の容量が乏しいマシンなら、圧縮率を高めに指定すると良いと思う。

 またもし、今後、この FreeBSD マシンをファイルの保存用サーバや、ファイルのアップローダとして使用するのであれば、そしてそれらのファイルが、zip ファイルなどの圧縮ずみのファイルばかりなのであれば、それらのファイルを保存しておく予定のディレクトリは、圧縮設定を off にしておくと良いのだろう。(圧縮ずみのファイルを圧縮しても、あまりファイルのサイズは小さくならないため。圧縮を行なうための計算機資源が無駄になる。)

 実際、wiki のサンプル例においても、/usr/ports/distfiles や /usr/ports/packages ディレクトリは、圧縮しないように指定している。(基本的に、これら二つのディレクトリには、圧縮ずみファイルが配置されることになるため。)

Fixit# zfs set checksum=fletcher4 zroot
Fixit# zfs create -o compression=on    -o exec=on      -o setuid=off   zroot/tmp
Fixit# chmod 1777 /zroot/tmp
Fixit# zfs create  zroot/usr
Fixit# zfs create  zroot/usr/home
Fixit# cd /zroot ; ln -s /usr/home home
Fixit# zfs create -o compression=lzjb -o setuid=off   zroot/usr/ports
Fixit# zfs create -o compression=off   -o exec=off     -o setuid=off   zroot/usr/ports/distfiles
Fixit# zfs create -o compression=off   -o exec=off     -o setuid=off   zroot/usr/ports/packages
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/usr/src
Fixit# zfs create  zroot/var
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/var/crash
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/db
Fixit# zfs create -o compression=lzjb  -o exec=on      -o setuid=off   zroot/var/db/pkg
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/empty
Fixit# zfs create -o compression=lzjb  -o exec=off     -o setuid=off   zroot/var/log
Fixit# zfs create -o compression=gzip  -o exec=off     -o setuid=off   zroot/var/mail
Fixit# zfs create                      -o exec=off     -o setuid=off   zroot/var/run
Fixit# zfs create -o compression=lzjb  -o exec=on      -o setuid=off   zroot/var/tmp
Fixit# chmod 1777 /zroot/var/tmp
2.Install FreeBSD to zroot

 下のスクリプトの kernels のところは wiki では lib32 となっていた。だが、スクリプトの実行前に ls コマンドで確認してみた結果、私の環境では lib32 というディレクトリが存在しなかった。かわりに、kernels というディレクトリがあったので、lib32 のかわりに kernels と入力してスクリプトを実行した。

 だが、おそらくここで kernels と入力したのは間違いだったと思われる。なぜなら、このしばらくあとの手順で、kernels ディレクトリに別個に移動し、必要な引数をあたえたうえで、install.sh スクリプトを実行しているからだ。(幸い、この私の間違いは、これまでのところ、とくに大きな問題を生じていないようではあるが。)

 なお、lib32 ディレクトリが私の環境下で存在していないのは、おそらく私のインストールしようとしている FreeBSD 8.0 が i386 用のものだからだと思う。amd64 用の FreeBSD 8.0 などなら、lib32 が存在しているのだろうと思う。

Fixit# cd /dist/8.0-RELEASE
Fixit# export DESTDIR=/zroot
Fixit# for dir in base catpages dict doc games info kernels manpages ports; \
          do (cd $dir ; ./install.sh) ; done
You are about to extract the base distribution into /zroot - are you SURE you want to do this over your installed system (y/n)? y
You are about to extract the doc distribution into /zroot - are you SURE you want to do this over your installed system (y/n)? y
You must specify which kernel to extract.
Extracting ports tarball into /zroot/usr
Fixit#

 スクリプトの実行中には、Yes か No かで、同意を求められるので、これには y で回答した。

 とりあえず、上記の "for dir in" 云々というスクリプトについて、私の理解の及ぶ範囲で解説すると、まず /dist/8.0-RELEASE/base ディレクトリに移動し、そのディレクトリ中にある install.sh スクリプトを実行。

 その実行が終わったら、つぎに /dist/8.0-RELEASE/catpages ディレクトリに移動し、そのディレクトリ中にある install.sh スクリプトを実行。

 以下、同様に /dist/8.0-RELEASE/dict や、/dist/8.0-RELEASE/doc や、/dist/8.0-RELEASE/games や、/dist/8.0-RELEASE/info や、/dist/8.0-RELEASE/kernels や、/dist/8.0-RELEASE/manpages や、/dist/8.0-RELEASE/ports ディレクトリに移動して、その各ディレクトリの install.sh スクリプトを順番に実行している。

 なお、 /dist/8.0-RELEASE/kernels ディレクトリ中の install.sh スクリプトは、どうも実行するときは、引数を与えてやる必要があるようだ。そのために上記の出力結果に "You must specify which kernel to extract." (どのカーネルを解凍するのかちゃんと指定してください) という表示が出ているのだろう。やはり、上記で kernels を入力したのは間違いだったのだろう。幸い、とくに問題は引き起こしていないようであるが。


 つぎは、以下のように、src ディレクトリに移動し、install.sh スクリプトを実行。おそらくこれで、$DESTDIR が指し示すディレクトリ(つまり /zroot ディレクトリ配下のディレクトリ)に、 src ディレクトリの中身が解凍されていくのだろう。

Fixit# cd src ; ./install.sh all
  Extracting source component: base
  Extracting source component: bin
  Extracting source component: cddl
  Extracting source component: contrib
  Extracting source component: crypto
  Extracting source component: etc
  Extracting source component: games
  Extracting source component: gnu
  Extracting source component: include
  Extracting source component: krb5
  Extracting source component: lib
  Extracting source component: libexec
  Extracting source component: release
  Extracting source component: rescue
  Extracting source component: sbin
  Extracting source component: secure
  Extracting source component: share
  Extracting source component: sys
  Extracting source component: tools
  Extracting source component: ubin
  Extracting source component: usbin
Done extracting sources.
Fixit#

 さて、上記の処理がおわったら、こんどこそ先ほど間違えた /dist/8.0-RELEASE/kernels ディレクトリ中の install.sh スクリプトをただしく実行しよう。以下のようにして、ディレクトリを移動したうえで、引数に generic を与えて、install.sh スクリプトを実行する。

 そしてスクリプトの実行後は、cd /zroot/boot コマンドで、 /zroot/boot ディレクトリに移動し、そのディレクトリ内にある GENERIC ディレクトリの中身を、/zroot/boot/kernel/ ディレクトリにコピーしよう。

Fixit# cd ../kernels ; ./install.sh generic
Fixit# cd /zroot/boot ; cp -Rlp GENERIC/* /zroot/boot/kernel/
3. /var/empty ディレクトリを readonly にする。(3.Make /var/empty readonly)
Fixit# zfs set readonly=on zroot/var/empty
4. chroot into /zroot する。(4.chroot into /zroot)

 chroot コマンドで、 /zroot ディレクトリをルートディレクトリに設定しよう。

Fixit# chroot /zroot
5. /etc/rc.conf を作成。(5.Create /etc/rc.conf)

 以下の echo コマンドは、早い話が echo を使って /etc/rc.conf を作成しているにすぎない。なお、さきほど chroot /zroot コマンドを実行したので、実際には zroot 上の /etc に rc.conf ファイルが作成されることになる。(つまり /zroot/etc/rc.conf が実際には作成される。)

 なお実行の前に、下記の re0 や "beastie.mydomain.local" の記述は、自分の環境に応じて、読み替えることを忘れてはいけない。re0 のところでは、ネットワークインターフェイスのデバイス名を指定している。"beastie.mydomain.local" では、このマシンにネットワーク上で、どのような名前を与えるかを設定している。

(まあここで肝心なのは、zfs_enable="YES" だけだと思う。hostname と ifconfig の設定は、書き間違えたとしても、起動後にネットワークに接続できないだけで、OS 自体は、おそらく起動すると思う。なので起動後に、sysinstall コマンドなどであらためて設定しても良いかもしれない。よくわからないときは、sysinstall の操作方法について解説しているサイトや、/etc/rc.conf ファイルの書き方について解説しているサイトや、man コマンドなどで、あらためて確認してみると良いと思う。)

Fixit# echo 'zfs_enable="YES"' > /etc/rc.conf
Fixit# echo 'hostname="beastie.mydomain.local"' >> /etc/rc.conf
Fixit# echo 'ifconfig_re0="DHCP"' >> /etc/rc.conf

 入力間違いなどがなければ、以下のような内容のファイルが作成されたと思う。念のため、cat /etc/rc.conf などと入力し、内容を確認しておくと良いと思う。

zfs_enable="YES"
hostname="beastie.mydomain.local"
ifconfig_re0="DHCP"

 もし入力間違いがあったときは、あらためて上記の三行からなる echo コマンドを入力しなおし、そして cat コマンドで中身を確認すれば良いはず。(なにか間違った場所に、rc.conf ファイルを作成してしまったときは、それを削除してからやりなおせば、多分どうにかなるはず)

6. /boot/loader.conf を作成する。(6. Create /boot/loader.conf)

 つぎも同じように echo コマンドを用いて、/boot/loader.conf を作成しよう。

Fixit# echo 'zfs_load="YES"' > /boot/loader.conf
Fixit# echo 'vfs.root.mountfrom="zfs:zroot"' >> /boot/loader.conf

 完成する /boot/loader.conf ファイルは以下のようになるはずだ。cat /boot/loader.conf コマンドなどで中身を確認し、もし間違いがあれば、また上記二行の echo コマンドを入力して、作成しなおせば良いと思う。

zfs_load="YES"
vfs.root.mountfrom="zfs:zroot"
7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストール。(7.Install ZFS aware /boot/loader (Required for 8.0-RELEASE and 7.{0-2}-RELEASE) )

 もしインストールしようとしている OS のバージョンが、8.0-RELEASE や 7.0〜7.2-RELEASE なら、この手順を実行しよう。もし、それ以降の 8.0-STABLE や 7.2-STABLE などの新しいバージョンをインストールしようとしているのら、この手順は飛ばして、つぎの8. root のパスワードを設定。(8. Change root's password)に行こう。


 さて、私のインストールしようとしているのは FreeBSD 8.0-RELEASE なので、以下を実行することで、 ZFS aware /boot/loader をインストールする必要があるようだ。それ以降の FreeBSD 8.0-STABLE や 7.2-STABLE では、もはやこの手順は必要ないそうだ。(なぜなら、それらの最新版では、ZFS aware boot loader こと /boot/zfsloader なるものをデフォルトでインストールしているためだそうだ。)

 私のわかる範囲で下記の手順を解説すると、まず /etc/src.conf というファイルを作成(実際には、chroot を実行中なので /zroot/etc/src.conf だが)。その内容は LOADER_ZFS_SUPPORT=YES という一行だけのもの。

 つぎに、周辺機器を取り扱えるようにするために、/dev をマウント。(いま現在は、chroot を実行中なので、/dev にアクセスすることもできなくなっている。これを以下の mount -t devfs devfs /dev コマンドによって、再び周辺機器にアクセスできるようにしているのだと思う。)

 つぎに /usr/src/sys/boot ディレクトリに移動し、make obj と入力することで、boot 用のコードをコンパイルする。このコンパイルでは、さきほど /etc/src.conf というファイルを作成したので、その src.conf ファイル中の記述によって、LOADER_ZFS_SUPPORT が有効になる。よって、ZFS を認識できる boot コードがコンパイルされる、という仕組みなのだろう。

Fixit# echo 'LOADER_ZFS_SUPPORT=YES' > /etc/src.conf
Fixit# mount -t devfs devfs /dev
Fixit# export DESTDIR=""
Fixit# cd /usr/src/sys/boot/
Fixit# make obj
Fixit# make depend
Fixit# make

make はけっこう時間がかかるので、お茶でも飲みながら、ゆっくり見守ると良いと思う。無事にコンパイルが完了したら、以下のコマンドでディレクトリを移動し、make install と入力することで、コンパイルずみの boot コードなどのファイルをインストール。

Fixit# cd i386/loader
Fixit# make install
8. root のパスワードを設定。(8. Change root's password)

 以下の passwd コマンドを実行して、root のパスワードを設定しよう。パスワードは、確認のために、二回入力する必要があったと思う。もし入力をうっかり間違えた場合でも、いま現在は、ルートになったままなので、また再び passwd コマンドを入力すれば、何度でもパスワードを再設定できたと思う。

Fixit# passwd
9. タイムゾーンの設定。(9. Set the local time zone)

 以下の tzsetup コマンドで時刻を設定しよう。過去に数回、FreeBSD をインストールしてみたことがあれば、おなじみの画面だと思う。この tzsetup の設定は、ここで行なわなくても、再起動後にあらためて、sysinstall から実行しても問題ないと思う。

Fixit# tzsetup

 ここでは以下のように尋ねられるので、とりあえず私は No と答えた。

Is this machine's CMOS clock set to UTC?

 あとは、5 番の Asia を選び、そこから、18 の Japan を選択した。とくに重要な設定ではないので、適当にすませれば良いと思う。(もちろん適当に設定すれば、時刻の表示は変になるが、OS が起動しなくなるというほどの重要さではないと思う。)

10. Create /etc/mail/aliases.db
Fixit# cd /etc/mail
Fixit# make aliases
11. Exit from the /zroot

 exit コマンドで、chroot を終了しよう。これによってルートディレクトリは、/zroot から、もとの / に戻ることになる。

 ところでもしかしたら exit の前の umount /dev というコマンドは、7. FreeBSD 8.0-RELEASE や 7.0〜7.2-RELEASE なら、ZFS aware /boot/loader をインストールを実行していない場合は、必要ないものかもしれない。私は 7. の手順を実行したので、未確認だが。

Fixit# umount /dev
Fixit# exit
12. Install zpool.cache to the ZFS filesystem
Fixit# cp /boot/zfs/zpool.cache /zroot/boot/zfs/zpool.cache

3. 最後の総仕上げ。(3. Finish install)

 さて、ここまでくれば、あとは細々とした作業を残すのみ。最後の手順は以下の通り。

  1. /etc/fstab を作成。(1. Create /etc/fstab)
  2. 環境変数 LD_LIBRARY_PATH を設定。(2. export LD_LIBRARY_PATH)
  3. すべての zfs ファイルシステムを unmount しよう。(3. Unmount all zfs filesystems)
  4. Change mount points for zroot pool
  5. Fixit mode を終了して、sysinstall 画面に戻り、sysinstall も終了して、再起動しよう。(5. Exit Fixit mode, and then sysinstall. Remove the FreeBSD install DVD/Memstick and the system will boot using the ZFS root.)
1. /etc/fstab を作成。(1. Create /etc/fstab)

 以下のように、cat とヒアドキュメントを用いて、/etc/fstab ファイルを作成しよう。多分、これも echo などで作成しても良いと思う。ad4s4b は、自分の環境にあわせて読み替えることを忘れずに。

Fixit# cat << EOF > /zroot/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/ad4s4b none swap sw 0 0
EOF

 ただしく入力できたなら、以下のようなファイルが作成されていることだと思う。これも cat /zroot/etc/fstab などで確認してもいいかもしれない。もし内容に間違いがあれば、またあらためて上記の cat コマンドを入力すれば良いと思う。

# Device Mountpoint FStype Options Dump Pass#
/dev/ad4s4b none swap sw 0 0
2. 環境変数 LD_LIBRARY_PATH を設定。(2. export LD_LIBRARY_PATH)

 以下で、環境変数 LD_LIBRARY_PATH に /mnt2/lib を設定。

Fixit# export LD_LIBRARY_PATH=/mnt2/lib 
3. すべての zfs ファイルシステムを unmount しよう。(3. Unmount all zfs filesystems)

 wiki の記述に従い、以下のように zfs unmount -a を実行したのだが、 Device busy と言われてしまった。

Fixit# zfs unmount -a
cannot unmount '/zroot': Device busy

 もしかしたら、どこかで私が何かの手順を飛ばしたのかもしれない。まあこれは、下のように、cd / コマンドによって root ディレクトリに移動してから、あらためて上記の unmount コマンドを実行することで、無事に unmount することができた。蛇足ながら、その手順は以下の通り。

Fixit# pwd
/zroot/boot
Fixit# cd /
Fixit# zfs unmount -a
4. Change mount points for zroot pool
Fixit# zfs set mountpoint=legacy zroot
Fixit# zfs set mountpoint=/tmp zroot/tmp
Fixit# zfs set mountpoint=/usr zroot/usr
Fixit# zfs set mountpoint=/var zroot/var
5. Fixit mode を終了して、sysinstall 画面に戻り、sysinstall も終了して、再起動しよう。(5. Exit Fixit mode, and then sysinstall. Remove the FreeBSD install DVD/Memstick and the system will boot using the ZFS root.)

 インストールは以上で終了。あとは、たしか exit コマンドを入力して、Fixit mode を抜けよう。すると多分 sysinstall 画面に戻ったような気がするので、それも "Exit Install" を選択して終了し、パソコンを再起動しよう。

 インストールが正しく完了しているのであれば、再起動によって、まずブートマネージャが起動するだろう。そのマネージャから、今回 zfs をインストールしたスライスを指定してやれば、FreeBSD 8.0 が起動することだろう。なお、再起動時には、USB メモリを外しておくことを忘れずに。

 これでインストール作業は終了であるけれど、i386 用の FreeBSDZFS を安定的に動かすためには、このあといくつか微調整を行なう必要がある。その微調整をしていないと、ちょっと重たい仕事をさせたりすると、メモリ不足などにより、フリーズしたり、リブートしたりすることになると思う。

 その微調整については、以下を参照。
ZFSTuningGuide - FreeBSD Wiki

*1:[http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/disk-organization.html:title]

*2:swap 用の領域も、ZFS Pool 上に作成することは可能だが、上記 wiki によれば、その場合は crash dump が作成されなくなるそうだ。"While a ZFS Swap Volume can be used instead of the freebsd-swap partition, crash dumps can't be created on the ZFS Swap Volume." [http://wiki.freebsd.org/RootOnZFS/ZFSBootPartition:title] より引用。

*3:ところで、上記 wiki 中の "Fixit# gpart add -i 1 -b 0 -s 40663421 -t freebsd-zfs ad0s3" という記述にある "40663421" という数字は、"406631421" の誤植だと思う

FreeBSD 7.2 で SOTEC C103 の無線 LAN を有効にする手順

ndisgen を用いて、Windows 用のドライバを FreeBSD 用に変換する

 FreeBSD には、Windows 用に作られたネットワークインターフェイスのドライバを FreeBSD 用のドライバに変換してしまう機能がある。それを使ってみることにした。

必要なファイル

 まず Windows XPSOTEC C103 を起動し、どのファイルが 無線 LAN 用のドライバなのかを確認。

 どうやって確認したのかは覚えていないが、たしか c:\WINDOWS\system32\athw.sys が、そのファイルだったと思う。

 つぎに、もう一つ inf ファイルも必要なので、適切な inf ファイルも探し出さなければならない。これは確か、c:\WINDOWS\inf フォルダのなかから、まず拡張子 inf のファイルを選んで、つぎにそれらのファイルのうちで "athw.sys" という文字がファイル内に記述されているファイルを検索したのだったと思う。

 すると唯一 oem26.inf というファイルのなかにのみ、"athw.sys" という文字があったので、この oem26.inf が必要なファイルだろうと判断することにした。

 この二つを使えば、FreeBSD 用のドライバが生成できるようだ。

FreeBSD を起動し、Windows 領域をマウント

 あらためて C103 を FreeBSD で起動。私の C103 はデュアルブートにしてある。つまり、一つの HDD を複数に区切って、そのうちの一区画には Windows XP をインストールし、もう一つの区画には FreeBSD 7.2 をインストールしているというわけだ。

 なので、その HDD のなかの Windows XP の領域をマウントすることで、FreeBSD からアクセスできるようにすることにした。

まず、mount するためのディレクトリを作成
> sudo mkdir /dos 
つぎに Windows XP が入っている HDD の領域を表しているデバイスファイルを指定してマウント

 うちの場合、そのデバイスファイルは /dev/ad4s2 であるので引数に /dev/ad4s2 を指定。

> sudo mount -t ntfs /dev/ad4s2 /dos
> 

 これで、FreeBSD を起動中に、Windows XP のファイルにアクセスできるようになった。

無事に mount できたので、必要なファイルを適当な作業用のディレクトリにコピー

 とりあえず作業用のディレクトリとして tmp というディレクトリを作成することにした。

> mkdir ~/tmp

 つぎに、このディレクトリに、さきほど確認した二つのファイルをコピー。

> cp /dos/WINDOWS/inf/oem26.inf ~/tmp
> cp /dos/WINDOWS/system32/athw.sys ~/tmp


 あとは、この tmp ディレクトリに移動して、ndisgen を起動し、表示される英文を確認しつつ、順次、リターンキーを押していくだけ。これでうまくいけば、FreeBSD 用の無線 LAN ドライブである athw_sys.ko を生成することができるはずなのだが。

> cd ~/tmp
> ndisgen oem26.inf athw.sys

 しかし、最後に syntax error と表示されてしまった。私が必要としている FreeBSD 用の無線 LAN ドライバを生成することはできなかった。

	==================================================================
	------------------ Windows(r) driver converter -------------------
	==================================================================

			Driver file conversion

	The script will now try to convert the .INF and .SYS files
	using the ndiscvt(1) utility. This utility can handle most
	.INF files; however, occasionally it can fail to parse some files
	due to subtle syntax issues: the .INF syntax is very complex,
	and the Windows(r) parser will sometimes allow files with small
	syntax errors to be processed correctly which ndiscvt(1) will
	not. If the conversion fails, you may have to edit the .INF
	file by hand to remove the offending lines.

	Press enter to try converting the files now: 
ndiscvt: line 3163: : syntax error.
CONVERSION FAILED
>

 まあしかたがないので、しょんぼりしつつ、vim を起動し、その inf ファイルを開いて、なんとなくコメント行を一行削除してみたり、コメントを書き加えてみたりしたあとに、再度 ndisgen を実行してみた。すると無事に FreeBSD 用の無線 LAN ドライバとなる athw_sys.ko を生成することができた。もしかしたら改行コードの違いなどが原因なのかもしれない。

 その後、確認をかねて、もとの athr.sys と netathr.inf ファイルを再度、用意し、vim で一行だけ空行を挿入し、その空行を削除したあとに、その変更を保存して、vim を終了。そのあとに、ndisgen を実行したところ、やはり同じように問題なく athw_sys.ko を生成することができた。

ndisgen が成功したとき時の画面の出力

> ndisgen oem26.inf athw.sys

	==================================================================
	------------------ Windows(r) driver converter -------------------
	==================================================================

			INF file validation

	This .INF file appears to be ASCII.

	Press return to continue... 
	==================================================================
	------------------ Windows(r) driver converter -------------------
	==================================================================

			Driver file validation

	This .SYS file appears to be in Windows(r) PE format.

	Press return to continue... 
	==================================================================
	------------------ Windows(r) driver converter -------------------
	==================================================================

			Driver file conversion

	The script will now try to convert the .INF and .SYS files
	using the ndiscvt(1) utility. This utility can handle most
	.INF files; however, occasionally it can fail to parse some files
	due to subtle syntax issues: the .INF syntax is very complex,
	and the Windows(r) parser will sometimes allow files with small
	syntax errors to be processed correctly which ndiscvt(1) will
	not. If the conversion fails, you may have to edit the .INF
	file by hand to remove the offending lines.

	Press enter to try converting the files now: 

	Conversion was successful.

 以上のように、上手くいけば、ただリターンキーを押していくだけで、athw_sys.ko を生成することができる。

athw_sys.ko の設定方法

 とりあえず、起動時にこの無線 LAN ドライバが有効になるように設定してしまおう。

 まずさきほど作成した athw_sys.ko を /boot/kernel/ ディレクトリにコピー。

> sudo cp -i athw_sys.ko /boot/kernel/
Password:
>

 そして、次のような設定を行なった。

 まず /boot/loader.conf に、下記の一行を書き加えた。

athw_sys_load="YES"

 つぎに /etc/rc.conf の末尾に、下記の一行を書き加えた。この設定により、FreeBSD を起動したさいに、DHCP によって、IP アドレスなどが、割り当てられる。

ifconfig_ndis0="WPA DHCP"


 また、/etc/wpa_supplicant.conf というファイルを作成した。
その中身は以下の通り。

network={
        ssid=" この中には ssid キーが入っている。 "
        key_mgmt=WPA-PSK
        psk=" この中には、psk のキーが入ってる。"
}

 あとは、
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-wireless.htmlhttp://www.freebsd.org/cgi/man.cgi?query=wpa_supplicant.conf&sektion=5 にしたがって、

> sudo /etc/rc.d/netif start

 を実行した。

 これで、無線 LAN の基地局などが DHCP を有効にしているのなら、このノートパソコンの無線 LAN デバイスに IP アドレスが割り振られるはず。

 無事に IP アドレスが割り振られたかどうか、ifconfig などで確認してみると良いと思う。

CD ドライブなどのないノートパソコンに FreeBSD 7.2 をインストールしたときの手順

ノートパソコン SOTEC C103 に FreeBSD 7.2 をインストールしたときの手順。

 このノートパソコンには、CD-ROM ドライブがついていない。私の手元には、このノートパソコンの BIOS が起動用のドライブとして認識してくれるような USB 接続の CD-ROM ドライブも無い。しかし幸いなことに、このノートパソコンは、USB メモリや SD カードから、起動することができる。

 そこで FreeBSD 7.2 のフロッピー用のイメージを USB メモリに書き込んで、その USB メモリから ノートパソコンを起動し、ネットワーク経由で、そのノートパソコンの HDD に FreeBSD 7.2 をインストールすることにした。

 (現在の FreeBSD 8.0 ならば、今回のような複雑な手順を踏まなくても、USB メモリ用のイメージがあらかじめ用意されているので、その用意された USB メモリ用イメージをダウンロードして、USB メモリに適切に書き込んで、その USB メモリからノートパソコンを起動するだけで良いようだ。)

 以下が、その手順。

用意したもの

  • 1GB の USB メモリ。(今回、この USB メモリに保存するのは、フロッピー用のイメージ数枚分にすぎないので、もっとずっと小さい容量でかまわない。)
  • FreeBSD 7.2 をすでにインストールずみのデスクトップパソコン。
  • そして SOTEC C103 (すでに gparted などを用いて、内蔵 HDD に十分な空きパーティションを作成ずみ)

作業を行なった環境

 以下の作業は、すでに FreeBSD をインストールずみのデスクトップパソコン(Celeron 600MHz, メモリ 1024 MB)で行なった。

手順

これから行なうこと全体の大雑把な説明。

 上記のデスクトップパソコンで、FreeBSD 7.2 のフロッピー用のイメージファイルをいくつかダウンロード。USB メモリを初期化して、先ほどダウンロードしたイメージを順次、USB メモリに書き込んでいく。これで、FreeBSD 7.2 を起動するための USB メモリができあがる。という手順。

まず必要なファイルをダウンロード

 以下の URL から
ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/7.2-RELEASE/floppies/

 などのファイルをダウンロード。ダウンロードしたファイルは、ハッシュなどを確認したあと、とりあえず /tmp ディレクトリに保存した。

USB メモリを初期化。うちのマシンでは、この USB メモリは /dav/da0 というデバイスになった
> sudo dd if=/dev/zero of=/dev/da0 bs=512 count=32
Password:
32+0 records in
32+0 records out
16384 bytes transferred in 0.213564 secs (76717 bytes/sec)
>

> sudo fdisk -v -BI da0
******* Working on device /dev/da0 *******
fdisk: invalid fdisk partition table found
parameters extracted from in-core disklabel are:
cylinders=968 heads=64 sectors/track=32 (2048 blks/cyl)

parameters to be used for BIOS calculations are:
cylinders=968 heads=64 sectors/track=32 (2048 blks/cyl)

Information from DOS bootblock is:
1: sysid 165 (0xa5),(FreeBSD/NetBSD/386BSD)
    start 32, size 1982432 (967 Meg), flag 80 (active)
        beg: cyl 0/ head 1/ sector 1;
        end: cyl 967/ head 63/ sector 32
2: <UNUSED>
3: <UNUSED>
4: <UNUSED>
fdisk: Geom not found: "da0"
>


> sudo dd if=/dev/zero of=/dev/da0s1 bs=512 count=32
32+0 records in
32+0 records out
16384 bytes transferred in 0.207940 secs (78792 bytes/sec)
>

> sudo bsdlabel -w -B da0s1
> sudo bsdlabel -r da0s1
# /dev/da0s1:
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  a:  1982416       16    unused        0     0
  c:  1982432        0    unused        0     0         # "raw" part, don't edit
>

> sudo newfs /dev/da0s1a
/dev/da0s1a: 968.0MB (1982416 sectors) block size 16384, fragment size 2048
        using 6 cylinder groups of 183.77MB, 11761 blks, 23552 inodes.
super-block backups (for fsck -b #) at:
 160, 376512, 752864, 1129216, 1505568, 1881920
>

> sudo mount /dev/da0s1a /media/
>

 このあとのことは、ログを紛失して、正確な手順はよく覚えていない。後述のサイトを参考にしたので、そちらで確認すると良いとおもう。後述のサイトと違う点は、FreeBSD 7.2 では、書き込むべきイメージファイルが一つ増えていたことぐらいだったと思う。

> sudo mdconfig -a -t vnode -f /tmp/boot.flp
> sudo mdconfig -a -t vnode -f /tmp/kern1.flp
> sudo mdconfig -a -t vnode -f /tmp/kern2.flp
> sudo mdconfig -a -t vnode -f /tmp/kern3.flp

蛇足として、FreeBSD 7.2 をインストールした理由

 その数日前、上記の古いデスクトップ PC(マザーボード MX36LE-UI) に、xubuntu 9.04 や ubuntu 9.04 をインストールしようとしたものの、このハードとの相性が良くないのか、ことごとくインストールに失敗。PC-BSD などもダウンロードして試してみたもののインストール途中でフリーズ。

 そこで、FreeBSD 7.2 を試してみたところ、あっさりとインストールに成功。そして、手元のノートパソコンにも一台、同じ環境を構築しておきたいという理由から、SOTEC C103 に同じ FreeBSD 7.2 をインストールしたという流れ。

半年ほど FreeBSD 7.2 を SOTEC C103 で使用してみての感想

 色々と馴れないことはあったものの、ndis で内蔵無線 LAN を使用することもできたし、タッチパッドも動かすことができた。Web カメラの設定方法は、いまだに確認していないが、内蔵マイクを用いて Skype での音声チャットもできた。

 他に、Java も不自由なくインストールできたし、WILLCOMad[es] こと WS011SH をモデムに用いたデータ通信や、WILLCOM CORE3G でのデータ通信もできたので、この半年間、とくに不自由することなく快適に使用することができた。そのうち、このノートパソコンには、FreeBSD 8.0 をインストールし、zfs を使用してみようと思う。