Debian on USB Memory

このページでは、DebianをUSBメモリ上にインストールするための方法を説明する(予定

って、Ubuntuつかえば、まさか速攻完成?

目次

編集履歴

2006/08/05 ベース文章を作成
2006/08/06 未完に気づくが未修正(SATA-HDDとか/dev/sda認識の可能性があるデバイスがついているマシンは問題あり)
2006/08/07 ほぼコレで動くという所まで来たので、清書。後はカスタマイズの域でしょう。

はじめに

  • 私はあまりlinuxのことを知りません。
  • BIOSのboot orderとか、そもそもUSBブートできるのか否か、チェックしてから。
  • Sargeを入れます。

まずは公式ドキュメントを読む

ドキュメントはsargeのようにコードネーム表記ではない。なので、現在のstableの状況と合わせ、どのバージョンのドキュメントを読んでいるかぐらいは念頭に。
http://www.jp.debian.org/releases/stable/installmanual

公式ドキュメントではsyslinuxというパーティションブートレコードにインストールするタイプのブートローダーを利用しているが、なぜかドキュメント通りに行っても

MBR
Boot failed

と出て進まない。よってこの先はGRUBを利用したバージョンを記述します。

ただ、mkdosfsやcfdiskを用いたパーティショニングなどは有用なので、必ず目を通して、普通に使えるようになっておくこと。

何の役に立つの?

先生が「Vistaになったら使えないかもしれないからロボットの60万のソフト、Debian Sarge用買っちゃった」とか、「Sargeのために毎度HDD切りなおすのやだよねー」とか言うので、必要に迫られました。

ぶっちゃけ人の研究なので誰にも頼まれてないけど、自分の研究がつまんなくなってきたので、ちょっとお遊びでやります。

方法1

USBメモリからインストーラーを起動、USBメモリ上にインストール

http://lists.debian.or.jp/debian-users/200504/msg00146.html

殆ど上記のとおりでOK。ファイルフォーマットはext3でも大丈夫。

後は普通にUSBメモリからブートして、インストール場所をUSBメモリの別の空き領域に設定すればふつーにインストール可能。

と、書きましたが、実は問題は山積しているものと思われます。下記の[方法2]で触れています。読んでください。もちろん、マシン構成によっては何の苦労も無く起動するでしょうけど。

一応、より良いmenu.lstの肝心なところをベタ書きしておきます。

title     Debian GNU/Linux, kernel 2.4
root      (hd0,0)
kernel    /linux ramdisk_size=9650 root=/dev/rd/0 init=/sbin/init devfs=mount,dall rw
initrd    /initrd.gz
boot

title     Debian GNU/Linux, kernel 2.4 Expert
root      (hd0,0)
kernel    /linux DEBCONF_PRIORITY=low vga=normal ramdisk_size=9650 root=/dev/rd/0 init=/sbin/init devfs=mount,dall rw
initrd    /initrd.gz
boot

title     Debian GNU/Linux, kernel 2.6
root      (hd0,0)
kernel    /linux26 ramdisk_size=10396 root=/dev/rd/0 init=/sbin/init devfs=mount,dall rw
initrd    /initrd26.gz
boot

title     Debian GNU/Linux, kernel 2.6 Expert
root      (hd0,0)
kernel    /linux DEBCONF_PRIORITY=low vga=normal ramdisk_size=10396 root=/dev/rd/0 init=/sbin/init devfs=mount,dall rw
initrd    /initrd26.gz
boot

障害報告

VAIO UX90(ゼロスピンドルモデル)

Expertでプロセスをトレースすれば分かるが、デバイス認識のためのカーネルモジュールロードの所で、VAIO UX90がUSBを認識しなくなる。(ランプが消える)
ということは、USBメモリ上においてあるインストーラーのisoも読めなくなるので、インストールを継続することは出来ない。

そして、その後、あんまし検証してない。

testing/sidだったり、カーネルに直接モジュールを埋め込んだり、最新カーネルを配置すれば動くかもしれないけど、他に気を使うことが多そうだし、保留。

http://www.vaio.sony.co.jp/Products/UX1/spec_ownermade_hdd.html

方法2

debootstrapでuserlandをUSBメモリにインストール

下記を軽く読んでおく。
http://www.daionet.gr.jp/~knok/trac/trac.cgi/wiki/VaioTypeU+USB+Debian
終わり。

でも、もっとちゃんと書きます。上記だけじゃ動かないことも多いはずだから。

下準備

USBメモリが(あえて)sdbで認識され、更に最初のパーティションsdb1を/mntにマウントし、そこにuserlandを作成しようとしていることを念頭に。
つまり、scsiデバイスやSATAデバイスが存在するマシン構成です。

mkdosfsやcfdiskを利用してパーティションを切る。ext3でフォーマットする。Primaryパーティション1つで全容量を使用しているとする。作ってみればわかるけど、Xとか導入しなければ256MBでも事足りるサイズだと思う。サイズの大きなUSBメモリを使えば、パーティションを複数作って環境を分けたり/rootとか/homeを共有したりできますね。

debootstrap

# mount /dev/sdb1 /mnt
# debootstrap --arch i386 sarge /mnt

これで/mnt以下にuserlandのインストール完了。

userlandにkernelの導入

apt-lineとリゾルバ設定をホストシステムからコピーします。これでchrootした時でもaptが利用できる。ネットワーク設定はホストシステムのものを利用するようなので不要。

# cp /etc/apt/sources.list /mnt/etc/ (ホストシステムのapt-lineを間借り)
# cp /etc/resolv.conf /mnt/etc (ホストシステムのリゾルバを間借り)

linuxに疎いので詳しくは知らないけど、

# mount -t proc none /mnt/proc

としてchroot環境にも/procをマウントしておかないとkernelのインストール時に起こられる。

ホストシステムにgrubがインストールされているなら、

# grub-install --root-directory=/mnt /dev/sdb1

としておく。/dev/sdb1のブートレコードと/mnt/boot/grubに必要なファイルが書き込まれる。

chroot環境に入ります。apt-lineとresolv.confが正しく設定されているかも試す。

# chroot /mnt
# apt-get update

エラーがでたらapt-lineを修正してください。

上記でファイルはコピーしているかもしれないけど、grubをuserlandに導入するために下記。

# apt-get install grub

ホストシステム上からgrub-installを実行していない場合は下記

# mkdir /boot/grub
# cp /lib/grub/i386-pc/* /boot/grub
# grub --no-floppy
grub> device (hd0) /dev/sdb
grub> root (hd0,0)
grub> setup (hd0,0)
grub> quit

実は、この辺り、正しいのか良くわかっていない。chroot環境とホストシステムの関係が分かってないから。
たぶんUSBメモリはchroot環境でも/dev/sdb認識だから、これで良いと思うんだけど。ただ、指定が誤っていたとしても、後に修正できるので気にしない。

さらにホストシステムに合わせて作成された/boot/grub/device.mapも編集して、少なくとも下記一行を含むようにする。(必要は無いかも?)

(hd0) /dev/sda (ブート時はUSBメモリが/dev/sdaになるはず)

次はkernelのインストール。/etc/fstabを編集しないと、なぜか怒られる。

# /etc/fstab
/dev/sda1     /       ext3        defaults,errors=remount-ro   0    1
proc          /proc   proc        defaults                     0    0

また、ホストシステムで

# mount -t proc none /mnt/proc

を実行していなければ、chroot環境をいったん抜けて、実行。入りなおす。

さぁkernelインストール。一応2.6入れときましょう。

# apt-get install kernel-image-2.x (好きなものを)

もしかしたら/vmlinuzとか/initrd.imgといったシンボリックリンク関連で文句を言われるかもしれないが、インストール自体は完了する。文句を解決したければ、

/vmlinuz -> /boot/vmlinuz-2.x (kernel実体) (同様にvmlinuz.old)
/initrd.img -> /boot/initrd.img-2.x (initrd実体) (同様にinitrd.img.old)

というシンボリックリンクを張っておく。超最新のマシンにも対応したいなら、自分でモジュールを増やしてカーネル再構築しなきゃだめですね。

次は/boot/grub/menu.lstを作る。

# update-grub

により自動生成。ただし!ホストシステム側からのデバイス認識順で生成しているっぽいので修正が必要。

root      (hd0,0)
kernel    ・・・ root=/dev/sda1 ・・・(ブート時はUSBメモリが/dev/sdaになるはず)

次にデバイス作成。下記ページを見つけてその必要性を無視して実行したけど、ちゃんとできたので、やってしまえ!
http://www.argv.org/~inoue/debian/debian-debootstrap.html

# cd /dev
# ./MAKEDEV generic

と思ったけど、ターゲットシステムべったりでなければ、devfsdとかudev+halでなんとかしてくれそうな気がするので、やらなくても良いと思う。

さらに、一応mbrを作っておきましょ。

# apt-get install mbr
# install-mbr /dev/sdb

自動認識という甘い言葉に誘われて、色々も入れておきましょ。はて、kernel 2.6.13からは完全にdevfsがudevで置き換えられたと言う話も聞いたが。

# apt-get install discover1 hotplug devfsd udev hal

日本語keymapにしたい人は

/usr/share/keymaps/i386/qwerty/jp106.kmap.gzを/etc/console/boottime.kmap.gzにコピーしておけば、/etc/initrd/keymap.shが起動時に勝手にやってくれる。

実は、まだ動かないかも

USBメモリの認識と、マウントのタイミング問題

initrdでusbをscsiエミュレーションで認識して、/dev/sdaデバイスとして利用可能になるタイミングと、initrd RAMディスク(仮root)から実root(/dev/sda)をマウントしに行くタイミングがマシンによっては逆転してしまう。なので、chroot環境での/etc/mkinitrd/mkinitrd.conf中の変数DELAY=5として、仮rootにてモジュールを読み込んだ後/dev/sdaをきちんと認識させるために遅延を与えておく。

これにより、kernelパッケージをインストールしたとき(dpkg-reconfigureでも可)のインストールスクリプトにより生成されるinitrdイメージ中に、DELAY=5という値が反映されるようになる。

USBメモリを押しのけて/dev/sda認識されるデバイスの問題

SATAとかSCSIのディスクとかを積んでいるマシンはUSBメモリよりも先に/dev/sdaを認識してしまうことがある。なので、initrd RAMディスクの時点で、確実にUSBメモリを先に認識させ、/dev/sdaを確保する必要がある。

因みに、debianのinitrdイメージはgzip圧縮ではないので、世の中にあふれている方法ではマウントできない。

# mount -t cramfs -o loop /boot/initrd.img /initrd

のようにすればマウントできる。しかしこれではRead Onlyなので、直接編集は不可能。

どうしても編集したいので、ちょっと変則的なやり方だが、/etc/mkinitrd/mkinitrd.conf中の、

MKIMAGE='mkcramfs %s %s > /dev/null'

MKIMAGE='mkext2fs %s %s > /dev/null'

とすれば、ext2フォーマットでinitrdイメージが作成されるので直接マウントして編集できます。ただし、mkext2fsはKNOPPIX関連のMLに投げられた?スクリプトらしい。
http://d.hatena.ne.jp/uronim1/20050220
一応全文載せとく。

#!/bin/bash
# similar to mkcramfs (for use with debian mkinitrd)
# mkext2fs dirname outfile
# 
# no options are parsed
#
# 	Written by: Fabian Franz <mkext2fs@fabian-franz.de>
#
# GPL v.2 - See: `locate gpl.txt`

if [ $# -lt 2 ]
then
  echo "Usage: $(basename $0) dirname outfile"
  exit 1
fi

TMPDIR=/tmp/$(basename $0).$$
mkdir $TMPDIR
function clean_exit
{
  umount $TMPDIR 2>/dev/null
  rm -rf $TMPDIR
}

trap clean_exit EXIT

COUNT=$[$(du -s $1 | awk '{ print $1 }' )*2+1000]
dd if=/dev/zero of=$TMPDIR/image count=$COUNT
mke2fs -F $TMPDIR/image
mount -o loop $TMPDIR/image $TMPDIR
cp -a $1/* $TMPDIR
umount $TMPDIR
cat $TMPDIR/image | gzip - > $2

これをchroot環境の/usr/local/binあたりに突っ込んでおいて、dpkg-reconfigureとするとcramfsではなくext2(+gzip圧縮)のinitrd.imgができるので、解凍してloopbackマウント。中身を編集して再圧縮。そのままcramfsのinitrd.imgを置き換えてもdebianではモジュールが足りないのかext2+gzipのinitrd.imgを読めないので、カーネル再構築するか、

# mkcramfs [initrdのマウントポイント] initrd.img

としてcramfsに再変換すれば良し。

実際の編集内容。とりあえず[initrdのマウントポイント]/lib/modules/2.x/kernel/drivers/usb/hostに/lib/modules/2.x/kernel/drivers/usb/hostから

  • ehci-hcd
  • ohci-hcd
  • uhci-hcd

をコピーしておく。この際modprobe --show-depends モジュール名 とするとモジュールの依存関係が分かるので便利。

更に、[initrdのマウントポイント]/loadmodulesの内容を編集し、一番上に

modprobe -k  ehci-hcd
modprobe -k  ohci-hcd
modprobe -k  uhci-hcd
modprobe -k  usb-storage
sh -c "sleep 5"

と記述する。これによりinitrdがマウントされ、linuxrcが実行され、initrd上の/sbin/initが実行され、loadmodulesが実行される時に、他のscsiデバイスを認識するよりも先にUSBメモリを認識させることができる。

あまり、美しい方法でない気がするので、本当はmkinitrdの使い方を覚えたほうが良いのでしょう。

参考になったドキュメント

特に最後のリンク先の、

  1.  lilo によるブート
  2. カーネルの起動
  3. 仮ルートファイルシステムとして initrd のマウント
  4. /linuxrc 実行 (起動時のルートファイルシステム=initrd と本当のルートファイルシステムが異なるときのみ実行される。ふつうは違うはず)
  5. 本当のルートファイルシステムをマウント
  6. /sbin/init 実行

ところが、Debian では違うの。

  1. lilo によるブート
  2. カーネルの起動
  3. 仮ルートファイルシステムとして initrd のマウント
  4. /linuxrc 実行 (ここまではいっしょ)

        1. 本当のルートファイルシステム(のデバイス番号)を /tmp/root に保存
        2. 本当のルートファイルシステムを initrd と設定

  5. 本当のルートファイルシステム(=initrd) をマウント
  6. /sbin/init 実行

        1. 各デバイスの準備
        2. /script 実行(これは call による呼び出しなので、/script 側から /sbin/init 内部で定義された変数や関数を利用できるの)
        3. ディレクトリ /scripts 内にある各スクリプトを実行
        4. コマンド /sbin/pivot_root を使ってルートファイルシステムを /tmp/root に保存した本当のルートファイルシステムに変更
        5. /sbin/init 再実行

Debian ユーザが変更してもよさげな部分は、スクリプト /script と、あとはディレクトリ /scripts 内に配置した各スクリプトくらいかな。

は欲しい情報そのままという感じ。勉強になります。

起動!

つないでUSBメモリからブートして、GRUBが起動する。初回はsingleモード(kernelラインにsingle追加)で起動して、rootログインで、まずはパスワードを設定して。
その後はbase-config newを走らせて各種設定を行いましょう。

この辺りの記述は、すげーいろんなことやって回避してたので、この通りやってもうまくいかないことがあるかもしれない。

これで、Debian on USB Memoryは完成するはず!厳密に試してないけど!


トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2007-05-29 (火) 19:10:19 (1192d)