前のページ 次のページ 目次

7. grubの使い方

grub自体に関してはLinux98セットのdocument/の中にgrub98.txtというgrubを98に移植した高井さんにより作成された文書があります。

インストーラgrubinstについても、高井さんによって移植され、奥村さんによってマニュアルページが和訳されています。

この章では、それらの文書以外のgrubに関する色々な情報を寄せ集めました。

7.1 grubのインストールする手引(すごく古い文書なので、ひょっとするともはや、通用しないかも)

From: 田畑

mini HOWTOにのせるgrubのドキュメントらしいものを書きました。
高井君が次に部室に来るまでに配布開始するならば、このドキュメント
とstage1 , stage2 をつけて配布したら良いと思います。
でもこんな内容では質問が続出すると思います、、、
時間が許せば添削してください。

(井伊の注)
98grub は Gerd Knorr <kraxel@cs.tu-berlin.de>による以下のパッチがあたっている。
このパッチには bzimage, initrd の対応が含まれる:
From: kraxel@cs.tu-berlin.de (Gerd Knorr)
Newsgroups: comp.os.linux.announce
Subject: patches for grub (boot loader)
Date: Sat, 25 Oct 1997 00:08:53 GMT
Approved: linux-announce@news.ornl.gov (Lars Wirzenius)
Message-ID: <pycola.877738133.18624@liw.clinet.fi>
Keywords: boot grub
(/井伊の注)
-----------------------------------------------
この文章のはテンポラリーのものである、
grubの使いかたについて述べたものである。

PC9801用のgrub は高井によって移植されたものであるが、
たまたま今日、部室に来ていなかったので田畑が適当に書いた。
ソースは今公開できる状態にない。(GPL 違反)

それでは手順
1、バイナリーのstage1 と stage2 というファイルを準備する。
2、まず、これらのファイルを用いて、grubのブートディスクを作ります。
# 編集者注:CD-R で配っているブートディスクには grub が含まれますので、
# このディスクを使えば Ok です。

        ATや98のFreeBSD,Linuxが動いている環境でなら、
(1)     dd if=stage1 of=/dev/fd0 bs=512 count=1
(2)     dd if=stage2 of=/dev/fd0 bs=512 seek=1

(MS-DOS等が動いている環境ではrawrite.exeを使って次のようなことをします。
        copy /b stage1 + stage2 grub.raw
        rawrite grub.raw a:
未確認)
# 編集者注: でも CD-R で配ってるのは dd98.exe って名前じゃなかったっけ?

これからgrubを使うにはgrubをこのフロッピーから起動する方法と
ハードディスクにインストールする方法がありますが、
メニューを使用できるのはハードディスクにインストールした時だけです。
# 編集者注: フロッピーディスクでもメニューは使える。

3、次にgrubをハードディスクにインストールします、grubは
stage1をMBRもしくは、各パーティションの先頭にインストールできます、
MBRにインストールした場合は固定ディスク起動メニューを
消すことになります。
また、stage2はstage1と一緒にMBRにインストールする、もしくは
各パーティションにインストールすることができます。
後者の場合はそのパーティションは fat , ext2 , ufs ,(ffs ,未確認)
のいずれかであれば良いです。

4、インストールする前に適当なパーティションの
ファイルシステム上に/boot/grub/menu.lst(別に異なっても構いません)に
メニューエントリーを書きます、その形式については後述します。
また、stage1 と stage2 も /boot/grub/に入れておきます。

5、それでは今作ったgrubのブートディスクをFDDに差して起動します。
するとコマンドラインモードになります。

ここではinstall コマンドを使います。

install=(stage1のファイルの場所) [d] (stage1をインストールする対象デバイス)
(stage2のファイルの場所) (ロードアドレス) [p] (コンフィグファイル)

例
install=(hd1,0)/boot/grub/stage1 d (hd1,0) (hd1,0)/boot/grub/stage2 0x8000 p /boot/grub/menu.lst

ファイルの場所にはデバイス (hdx,y)でx+1番目のハードディスクの
y+1番目のパーティションを意味します、フロッピーの場合は(fdx)で
x+1番目のドライブを指します。(数字は0から始まります)

上の例では、
2台目のハードディスクの最初のパーティションから /boot/grub/stage1
を読み2台目のハードディスクの最初のパーティションに先頭のブロックに
stage1をインストールします。

stage1はstage2の(hd1,0)/boot/grub/stage2 に 0x8000にロードするように
書きこまれます、それから p 以降はコンフィギュレーションのファイル
です。

このようにハードディスクにインストールすればOKです。

6、menu.lstの書きかた。
#ではじまる行はコメントです。
これらのコマンドは基本的にコマンドラインモードで使われるものと
同じです。

# GRUB menu             <--- Comment
timeout= 10             <--- デフォルトのエントリが起動するまでの秒数
default= 0              <--- デフォルトのエントリは0番目

# Entry 0:
title=  GNU/Linux  version 2.0.33       <---そのエントリのコメント
root=   (hd0,0)                         <---ルートデバイス
kernel= /vmlinuz.2.0.33 mem=128M        <---カーネルのファイルとオプション

# Entry 1:
title=  GNU/Linux (music CD drain support?)
root=   (hd0,0)
kernel= /vmlinuz.takai mem=128M

# Entry 3:
title=  GNU/Linux (Kernel version 2.1.64)
root=   (hd0,0)
kernel= /vmlinux.2.1.64 mem=128M

7.2 grubとLinuxのパーティション指定方法の違いについて

bugs ML 505(岩井さん)より一部改変。

次にgrubでの起動ですけどここで結構悩みました
kernel=(0,1)/vmlinuz root=/dev/hda2 ide0=serialize
       ^^^^^              ^^^^^^^^^
kernelの所は (ハードディスク マイナス1, パーテーション マイナス1) で指定
rootはの所はLinuxで使用するそのままの値で指定する

私の場合ideのディスクですから

パーテーション      1        2       3       4       5       6
ディスク1台目    (0,0)    (0,1)   (0,2)   (0,3)   (0,4)   (0,5)
    2台目    (1,0)    (1,1)   (1,2)   (1,3)   (1,4)   (1,5)
    3台目    (2,0)    (2,1)   (2,2)   (2,3)   (2,4)   (2,5)

kernel=(hd0,1)/vmlinuz root=/dev/hda2 となりました。

7.3 root=

grub を移植した 高井幸輔@京大マイコンクラブ です。

# bugs には初めて出します。今後ともよろしくお願いします。

<owoh0kvw0z.fsf@kabocha.box2.kmc.kyoto-u.ac.jp>の記事において
北川 拓郎さんが書かれたことにちょっと補足します。

>> grub の root= は、単に以降の kernel= とかで(hdX,X) の指定を省略できる
>> ようになるだけです。

root= の指定は、FreeBSD/NetBSD の場合は起動パラメータとしてカーネルに
渡されます。また、 chainloader= で指定したチェーンローダを起動する
際にも、root= で指定されたドライブ/パーティションを
「起動されたドライブ/パーティション」であるかのように設定します。
(ただし、chainloader= で指定したチェーンローダ云々の機能は
 よくテストされていません。)

Linux の場合は root= による指定は北川さんが書かれたように
単にカレントドライブ/パーティションの指定になります。

>> Linux へのカーネルパラメータはみんな kernel= でカーネルイメージの後に
>> 続けて指定するのが正しいです。(initrdだけは別)

Linux に限らずカーネルパラメータは kernel= で指定します。

(例)
        command> kernel=/kernel.old -s

                FreeBSD のカーネル /kernel.old を
                シングルユーザモードで起動します。

カーネルパラメータを間違ったときに、パラメータだけ修正する機能は
ありません。カーネルイメージのロードからやり直してください。
(本家AT版からの仕様です)

>> install= で grub が何をやってるかというと、stage2 や menu.lst の
>> 実体のあるセクタを解析して MBR 内の stage1 のコピーに書き込んで
>> いるだけです。
>> # なので stage2 や menu.lst もインストール前に HDD上に
>> # 作っておく必要があるのです (PC98mini-HOWTO「[5]grubの使い方」参照)

ちょっと訂正。


install= では、設定ファイル(menu.lst) に関しては、そのファイル名を
stage2 の先頭セクタに書き込んでいるだけです。ファイルの存在も
チェックされません。したがって、インストールだけ先に済ませておいて
menu.lst を後から作っても構いません。

>> 従って後から menu.lst を多少手直しするくらいなら grub の再インストール
>> は不要です。
>> ただし、stage2 や menu.lst のHDD上の実体のセクタ構成が変わるようなこと
>> をした場合は再インストールしないと動かなくなってしまいます。

menu.lst は大幅に書き換えられてセクタ構成が変わろうが消されようが
全く問題ありません。
設定ファイルはちゃんとファイルシステムを見て読んでいます。
(設定ファイルがないときはメニューが出なくなります)

※ stage2 のセクタ構成が変わったときは再インストールが必要です。

>> バックアップの作り方がタコなエディタを使ったりすると危いかもしれません。

そんなわけで、エディタのバックアップなどには影響されません。

ちなみに、98版では設定ファイルを EUC-JP で書くことが出来ます。
EUC 半角カナを使用することもできます。いわゆる「2バイト半角」にも
対応しているつもりですが、これはテストされていません。

それから、98版 grub の既知のバグとして、
「メニューから e で編集モードに入った後、ESC で戻ろうとすると誤動作する」
ということが報告されています。

また、NetBSD/pc98 をブートできるかどうかについても、こちらでは
「モノ」がないので確認できていません。NetBSD/pc98 をお使いの方は、
テストをお願いします。

最後に、少しtipを:

        1.44 MB フロッピにべた書きされたカーネル(zdisk)を読み込む。

                command> kernel=(fd0)0+2880 root=/dev/hda1

        この方法によれば、 zdisk のカーネルにもパラメータを渡せます。

7.4 chainloader=

From: (TAKAI Kousuke)
Date: Wed, 18 Feb 1998 18:41:54 +0900 (JST)
Subject: [seraphim-bugs 267]Re: Installing problems 
>> チェーンローダは、何を指定したらいいのか分かっていないので、使っていません。
>> /boot/grub/menu.lst では、
>> 
>> title = FreeBSD(98) 2.2.5-RELEASE
>> kernel = (hd4,0)/kernel root=/dev/sde1 ide0=serialize

これは、FreeBSD(98)をブートしようとされているのだと思いますが、
FreeBSD の場合は root=... といったパラメータは渡すことができません。
{Free,Net}BSD の場合は、普通の(OS付属の)カーネルローダと同じように
ファイル名の後に -a、-c、-s などのフラグをつけることができます。
また、ルートデバイスは kernel= コマンドのパラメータとしてではなく、
(独立した)「root= コマンド」で設定します。

上の例は次のようになります。

        title = FreeBSD(98) 2.2.5-RELEASE
        root = (hd4,0)
        kernel = /kernel

(メニューから e で編集モードに入って、`kernel = /kernel' を
 `kernel = /kernel -s' に書き換えてブートすると、シングルユーザで
 立ち上げることができます)

また、`ide0=serialize' は Linux 独特のカーネルパラメータですので
FreeBSD では意味がありません。

…と、偉そうなことを書きましたが、実は {Free,Net}BSD の起動パラメータを
渡す部分にバグがあって(AT用のままになっている)、SCSIディスクをルートに
することができません。

ですが、 SCSI ディスクからでもチェーンローダを使えばブートすることが
(多分)できます。指定方法は、

        root = (hd4,0)
        chainloader = +2

です。`chainloader = +2' で、ハードディスクの指定されたパーティションの
先頭2セクタを読んで(ここには普通、OSに付属のIPLが入っています)、そこに
実行を移します。これを実行すると、FreeBSD の場合は
「>> FreeBSD BOOT @ ...」という(おなじみの)プロンプトが出てブートできます。

grub 本来の機能からすると綺麗ではない方法ですが、
開発中ということでお許しください。

なお、chainloader = の機能は、本来は DOS や Windows をブートするための
機能です (これらも上と同じ方法でブートできます)。

# grub のデバッグのために NetBSD/pc98 0.9 なんぞを読み込ませてみたら
# ロードするアドレスが小さすぎるなんてことを言われた。
## やっぱ古過ぎ?
(編集者注:現在 chainloader 機能自体がバグのため使用できないかも)
(次のは最近流れたメールより引用)
--------
chainloaderは復活しました(アホなバグだった...)。
Linux/98の新パーティションIDにも対応しました(古いIDには対応しなくなりました)。
{Net,Free}BSD の起動では SCSI ディスクを / に指定することがまだできません。
FreeBSD の IDE 起動は成功しています。一応パッケージ化してありますが
トップで make することが出来ません。

# バージョンアップといっても番号とかそんなものは全然ない (^^;

## 本家grub では 0.4.1 が出るそうです(もう出ているかも)
---------

7.5 install=時のdオプションについて

bugs 740より

高井です。

pessiさんは書きました。
>> higuchiさんは書きました。
>> >>    command> install=(hd0,0)/boot/grub/stage1 (hd0,0)
>> >>                                            ^^^  昔はここに”d”とあったと
>> >>                                                  思いますが?
>> >>         (hd0,0)/boot/grub/stage2 0x8000 p /boot/grub/menu.lst
>> >> 
>> >>   これって、あちこちで抜けてますが?なくなったのでしょうか?
>> 
>> grub98.txt ですよね。d はいらなくなったのでしょうか。

"d" はオプションで、これを指定すると
「stage1がどこにインストールされても、指定されたstage2しか読まない」
という意味になります。指定しないとstage1がロードされたドライブと
同じドライブから読む指定になります。

stage2をHD上に置いてstage1はFDを使うということでもするなら
便利な機能ですが、別に普通の使い方をする限り必要ではなさそう
(さらに、"d"を指定していると、ドライブ構成が変わってgrubの入っているHDが
 ずれたときに起動できなくなる)ですのでコマンド例では使わないようにしました。

ついでに "p" についてですが、これは /boot/grub/menu.lst (ここに他の
ファイルを指定した場合は、そのファイル) を読むパーティションを固定する
オプションです。このオプションを省略して、設定ファイルに
(hd0,2)/boot/grub/menu.lst などとパーティションを指定することもできますが、
上と同じようにドライブ構成の変更に対して柔軟性が少なくなってしまいます。

(例 1) install=(hd1,0)/boot/grub/stage1 (hd1,0) (hd1,0)/boot/grub/stage2
        0x8000 p /boot/grub/menu.lst

        ⇒ 2台目のHDのパーティション#1にある /boot/grub/stage{1,2} を
           stage1、stage2として使用し、同じパーティションの先頭に
           インストールします (このパーティションを
           「固定ディスク起動メニュー」で選択して起動すれば grub が
           起動することになります)。このとき、stage1は自身がロードされた
           ドライブからstage2をロードし(※)、またstage2は
           stage1がロードされたのと同じドライブ、パーティションから
           /boot/grub/menu.lst をロードします。

          (※) このコマンドラインで指定したstage2のドライブは関係ないこと
               に注意してください。インストールするドライブとstage2のある
               ドライブは同じでなければなりません(チェックはしていません)。
               同じドライブあればパーティションが違っても構いません。

(例 2) install=(hd0,2)/boot/grub/stage1 d (fd0) (hd0,2)/boot/grub/stage2
        0x8000 (hd0,2)/etc/grub.menu

        ⇒ 1台目のHDのパーティション#3にある /boot/grub/stage{1,2} を
           stage1、stage2として使用し、stage1はフロッピにインストールします。
           stage1はフロッピからブートされると *1台目のHDから* stage2を
           ロードします。またstage2は1台目のHDのパーティション#3から
           /etc/grub.menu をメニュー設定ファイルとしてロードします。

           ※ stage1をこのようにフロッピ上に置いたときは"p"を
              指定することはできません。(「stage1がロードされた
              パーティション」が無いためです)

(例 3) install=(hd0,0)/boot/grub/stage1 (hd0) (hd0,0)/boot/grub/stage2
        0x8000 (hd0,0)/boot/grub/menu.lst

        ⇒ 1台目のHDのパーティション#1にある /boot/grub/stage{1,2} を
           stage1、stage2として使用し、stage1は1台目のHDの
           (パーティションの先頭ではなく)マスタブートレコード(MBR)に
           インストールします(「固定ディスク起動メニュー」を吹飛ばします)。

           ※ このときも、(例 2)と同じ理由で、menu.lstのあるドライブ、
              パーティションを指定する必要があります。

7.6 grubがSJとなって止まってしまいます。

[投稿者] 中鉢さん
[日付] Mon, 25 May 1998 18:42:47 JST
[質問]
はじめまして、ちゅうばちです。 カメ&ポストですみませんがFTPサイト(ftp.kuis.kyoto-u.ac.jp)の /linux98-package/grub/stage?(04/27/98)付けを ダウンロードして組み込んでみたら、stage2でmenu.lstを 読み込まずにハングアップしてしまいます。 どなたか、作動していらっしゃいますでしょうか?

[回答]
高井@京大マイコンクラブ (grub移植者) です。

中鉢 信悦さんは書きました。

>> そう思いまして、過去のログも見ながら試してみたのですが症状は
>> 画面中央下左に "SJ"まで表示されて、フリーズします。

"SJ" まで表示されてフリーズするのは、たぶん stage2 の位置が
stage1 (ブートセクタ)に正しく書き込まれていないせいです。

ちなみに、"S" は stage1 の実行が始まったことを示し、 "J" は
stage2 (または、 stage1 が *そう思い込んでいる* データ)の先頭に
ジャンプしたことを示します。

# それぞれが Start / Jump の意味だと分かったのは最近です :-P

>> これってディスクに menu.lst が書き込まれていませんよね、タイトル&説明
>> からいきなり "command >" 表示で入力になるのが正常でしょうか?

「タイトル&説明からいきなり」というのが
どういうことをおっしゃっているのかちょっと分かりにくいのですが、
menu.lst がないときは、"SJ"の後、メニューが出ずにいきなり
"command> " プロンプトが表示されて入力待ちになるというのが正常です。

>> インストールディスクでは、上手く行きます。テストで次の様にやっても
>> install=(fd0)/grub/stage1 d (hd1,0) (fd0)/grub/stage2 0x8000 p
>> (hd1,0)/boot/grub/menu.lst[リターン] とか、
>> 同じインストールディスクを (fd1) 用にディスクコピーして、
>> install=(fd0)/grub/stage1 d (hd1,0) (fd1)/grub/stage2 0x8000 
>> (fd0)/grub/menu.lst[リターン] とか期待どうりの作動をしてくれます。
>> 
>> でもこれだと (fd?) の stage2 が menu.lst の在処を上書きされるだけですので、
>> インストールディスクは使われることになってしまいますよね?

その通りです。「ハードディスクだけでブートする」なら、 stage2 も
ハードディスクにコピーしておく必要があります。

中鉢さんの文脈から推察すると、

        command> install=(fd0)/grub/stage1 (hd1,0) (fd0)/grub/stage2 0x8000
        (hd1,0)/grub/menu.lst

のようなことをなさったのではないでしょうか? (違っていたらすみません)
これだと、ハードディスクのブートセクタにフロッピの /grub/stage2 の
位置が書き込まれ、かつ、 stage1 は自身がロードされたドライブから
stage2 を読み込もうとするため、フロッピ上の stage2 があった場所と
同じセクタ番号を持つハードディスク上のセクタに *たまたま* あった
データが読み込まれ、実行されます (まぁ99.9%フリーズするでしょう)。

「install コマンドは stage1 はコピーするが、 stage2 はコピーしない」
ということをもっと強調する必要がありそうですね。

>> 私、個人としてはインストールディスクの grub ファイルを Linux98 の HDD
>> パーティションにコピーするコマンドを grub に付加していただいた方が
>> うれしいですね。(要望をするつもりはありません)

どきっ。実は部内でも要望があって、作り *かけて* いるところです。

>> アルファー、テスターの身分で偉そうに言ってしまいました、ゴメンナサイ。

なんのなんの、アルファ・テスターの皆様には大変感謝しています。
これからもレポート、提案、コメントなどなど期待しています。

>> 私だけのようなので alpha CD-R のソースいじって調べてみるかなー。

大歓迎です。

# あ、betaはもう少し待ってください (^^;

[投稿者] 高井さん
[日付] Fri, 29 May 1998 09:15:44 JST
[コメント]
結局、

< ファイルの関係 >
stage1 : ブートセクタに install= によって書き込まれるファイル。
stage2 : stage1 によって、ディスク上のどこかから
        「直接(ファイルシステムを介さずに)」読み込まれるファイル。
         install= の際に d をつけると install= で指定したドライブから、
         つけないとブートしたドライブから読み込まれる。
menu.lst : stage2 によって、ディスク上のどこかから
         ファイルシステムを介して読み込まれる
         install= の際に p をつけると install= で指定したドライブから、
         つけないとブートしたドライブから読み込まれる。

< install= の動作 >
 1. 指定された stage1 のファイルを指定されたドライブのブートセクタに
    「コピーする」
 2. 指定された stage2 の「位置」を「絶対セクタ番号で」ブートセクタに
    記録する。(grub では block list とかいってましたっけ?)
    'd' オプションがついていた場合はドライブ番号も記録する。
   (d オプションがないときも記録はされるけど無視されるのかも)
 3. 指定された menu.lst の「位置」を「パスで」記録する。
    (どこに?)
   'p' オプションがついていた場合はドライブ番号も記録する。
   (これも p オプションがないときも記録はされるけど無視されるのかも)

ということで合っているでしょうか?
「ドライブ」はパーティション番号のほうは無視するんですよね?

# ...初心者には難しいかも

[投稿者] 北川さん
[日付] Sat, 30 May 1998 22:27:55 JST

7.7 grubの内部構造

中鉢さんによりバグ潰される

  お久しぶりー、中鉢@アルファ・テスターです。

私の PC9801RA21 + SCSI-HDD に grub/98 をインストール&HDD起動メニュー
から起動できない件のその後の報告をします(農作業に多忙でサボリまくり(^^;)

ようやく原因が解りソース(CD-R beta-006/gr98src.tgz)を少々変更し、
grub(FD) でインストールも、インストール後固定ディスクの起動メニュー
から、grub を起動できるように成りました。(^^)v

原因は、HDD 上の stage2 の先頭セクターに不正なデータが上書きされてしまっ
て、"SJ" と表示後、暴走してたんですね。

<sect2>変更箇所<p>

/shared_src/cmdline.c で
607:      if (*ptr)
608:            {
609:              char *str
610:                = ((char *) (SCRATCHADDR+STAGE2_VER_STR_OFFS));
611:
612:              write_stage2_sect++;
613:              while (*str++);      /* find string */
614:              while( (*str++ = *ptr++) );    /* do copy */
615:            }
616:
617:#ifdef      PC98x1
618:          filemax = stage2_size(SCRATCHADDR);
619:#endif
620:          read(0x100000, -1);
621:
622:          {
623:              unsigned int *p;
624:              printf("Block list:");

 619 行目まで SCRATCHADDR に stage2 の先頭セクターに書くデータがあるので
すが、 620 行目の処理で(意図が解らないのですが、きっとリトラクトか
再認識だと思ってる)下位の関数で壊してしまう (かもしれない) ようです。
これは、install コマンドの内容構成と、カレントfd又はパーティションで
ケースbyケースで起こる事が解りました。
で、下手に変更する訳にも行かず安易な考えで、前後に bcopy(...)
を入れて待避させたら install コマンドの何れの構成でも確実にインストール
&起動出来るように成った次第です。

内部の解説

高井@京大マイコンクラブです。

read() は普通のライブラリ関数と似て、ファイルからメモリに読み出す 関数です (同時に複数のファイルはオープンできないので、ファイル・ ディスクリプタはありません)。また長さ -1 は「ファイルが終るまで」を意味しま す。で、何をしているのかというと、上の方の 「debug_fs = debug_fs_blocklist_func;」という行がポイントで、 read によって実際のディスク上のセクタを読む時に 変数 debug_fs (関数へのポインタ) に設定した関数がそのセクタの番号を 引数として呼ばれます。(普通は NULL が入っており特に処理はされません。) ここで設定されている関数 debug_fs_blocklist_func() は渡されたセクタ番号を stage1 に書き込むブロック・リストに組み立てています。 したがって、この read() によって stage1 (この時点ではメモリ上の BOOTSEC_LOCATION にあります) に stage2 のディスク上の在処が書き込まれます。

で、このとき read の下位の関数が SCRATCHADDR を壊しているかも知れない、 ということですが、移植した際に SCRATCHADDR の位置を動かしたので 大いにありえます (ˆˆ;;

オリジナルでは SCRATCHADDR は 0x77E00 で、恐らく 0x80000 - セクタサイズ (ATだと常に512バイト) であると考えたので、 98版では 0x77800 (= 0x80000 - 2048 (BIOSがサポートする最大のセクタ長)) としました。 0x70000 からはディスクバッファ(先読みキャッシュ)が使っているので、 これと衝突しているのかも知れません。

その後の追跡

高井@京大マイコンクラブ です。

自己フォローです。

<199807130845.RAA09297@hasu.box2.kmc.kyoto-u.ac.jp>の記事において
私は書きました。

>> オリジナルでは SCRATCHADDR は 0x77E00 で、恐らく 0x80000 - セクタサイズ
                                                    ^^^^^^^
足し算を間違えてました。                            0x78000

>> (ATだと常に512バイト) であると考えたので、 98版では 0x77800
>> (= 0x80000 - 2048 (BIOSがサポートする最大のセクタ長)) としました。
      ^^^^^^^
      0780000

>> 0x70000 からはディスクバッファ(先読みキャッシュ)が使っているので、
>> これと衝突しているのかも知れません。

調べてみたら、やっぱり衝突してました。

grub では 0x70000 からを簡単な先読みキャッシュのバッファとして
使っていますが、この先読みする単位として、「1トラック」を使用しています。
この1トラックはBIOSから返される値を使っているため、実際の(物理的な)
ディスクのトラックとは一致しない場合もありますが、とにかく AT互換機では
ふつう 0x3F(63)セクタ/トラック となっています。これだと 0x70000 から
1トラック分読み出すと 0x77DFF までフルに使ってしまいます。

今までこれに気付かず適当に stage2 用のバッファをずらしていたのですが、
手元の98のBIOSはトラックあたりのセクタ数としてこれより少ない値を返すので
たまたまうまくいっていたようです。(PC-9821Xa7eのIDEのディスクの場合、
17セクタ/トラックとなっていました。)

しかし、藤田さんによれば古いSCSIインタフェースのBIOSには64セクタ/トラック
という値を返すものがあるそうで、この場合にインストールがうまくできない
みたいです。

そんなわけで、応急処置としては中鉢さんのとられた bcopy() で
対応していただく方法が一番簡単・確実でしょう。

こちらの対策としてはHDアクセスのLBA化の一環としてやりたいと考えています。

ご指摘ありがとうございました。

7.8 領域を最適化しても大丈夫?

[投稿者] 中鉢さん
[質問]
それから、気がかりなのが次の場合です、最初にこちらを疑いました。 仮に stage2 を FAT(ms-dos) パーティションに置いた場合、ファイルの保存され ているセクターが不連続になるかも知れませんし、領域の最適化で勝手に他の セクターに持って行かれたりしますけど、 ext2fs パーティションでその様な ことが無いのでしょうか? 参考までに解る方宜しく教授して下さいマセ。

[回答]
FATだけでなく ext2 でも不連続になる可能性はあります。しかし、
grub の install= コマンドでは、さきに書いたように stage2 のファイルを
最後まで辿って、そのセクタ番号をすべて stage1 に保存します。
したがって stage2 が不連続であっても問題ありません。
98版の install= コマンドを実行すると、

       Block list: 234+0x5000 348+0x3000

などというメッセージが出力されますが、これが stage2 のディスク上の在処です。
(この例では、セクタ(パーティションとは関係なくディスク上の絶対的な位置です)
 234 から連続して 0x5000 バイト、セクタ348から連続して 0x3000 バイトに
 stage2 が存在することになります)

# ちなみにこれはたぶん私が付けたデバッグメッセージです(近々消す予定)。

FATでも問題ないと思いますが、98版では stage1 内のセクタ番号(grub のソース
では block list と表現されています) の保存領域が少く、極端に不連続だと
領域が溢れてしまう可能性が高いです (この場合はエラーとなります)。

※ ただし、 stage1 を FAT パーティションの先頭にインストールすることは
   現状では *できません*。これは FAT パーティションのブートセクタに必要な
   BPB を格納する領域が stage1 に無いためです。

あと最適化ですが、基本的に(自動では)対処できません。最適化する度に install=
をやりなおす必要があります。 ext2 の deflag も同様です。

# だから、 Windows98 とは相性が悪いかもしれません。

7.9 ケーススタディ(もっときちんとしたタイトルを付けなくちゃ)

[投稿者] 寺本さん
[日付] Mon, 19 Oct 1998 09:32:10 JST
[質問]
 1台目IDEは「固定ディスク起動メニュ」で Linux 以外のOSを使い分けているとします。  2台目SCSIに grub をインストールする部分を 書いているのですが,動作環境がないために,確認が できません。次の設定でよろしいでしょうか。
(1) 2台目SCSIには Linux のみをインストールして,
  起動すると1台目IDEの「固定ディスク起動メニュ」
 が表示され,“2台目”を指定すると Linux が起動
 するようにしたい場合
 (“/”は第2パーティションとする)

 command> install=(sd0,1)/boot/grub/stage1 d (sd0) 
      (sd0,1)/boot/grub/stage2 0x8000 p
       /boot/grub/menu.lst

(2) 2台目SCSIにはWin95 と Linux がインストール
 されていて, 起動すると1台目IDEの「固定ディスク起動メニュ」
 が表示され,“2台目”を指定すると2台目SCSIの
 「固定ディスク起動メニュ」の中にWin95 と Linux が
 表示されるようにしたい場合
 (“/”は第3パーティションとする)

 command> install=(sd0,2)/boot/grub/stage1 d (sd0,2) 
      (sd0,2)/boot/grub/stage2 0x8000 p
       /boot/grub/menu.lst

  以上でよろしいでしょうか。欲張ったケース・スタディですが
よろしくお願いいたします。

[回答]
(1)は、できません (正確に言えば、インストールはできますが、使えません)。
というのは、「固定ディスク起動メニュー」には2台目以降のディスクのマスタ
ブートレコードを実行する機能が無いためです。

したがって、2台目以降のディスクにインストールするときは必ずどこかの
パーティションに grub/98 をインストールしてください (このときは、
「固定ディスク起動メニュー」から「SCSI固定ディスク#1」を選び、右側の
パーティション一覧から grub/98 をインストールしたパーティションを
選択することになります → つまり(2)と同じ)。

# ということは2台目をブチ抜きにするとそこからは起動できないのかな?
# (試してません。ごめんなさい)

(2)の場合2番目のパラメータ(「d」)はいらない (使わない方がよい) です。
「d」オプションは、stage1 と stage2 を別々のディスクにインストールする
場合 (たとえば、ブートセクタだけフロッピーから読み込む、など) に使う
もので、このように両方を同じディスクにインストールする場合は不要ですし、
(あまり無いとは思いますが) SCSI ID の変更などがあるとブートできなく
なってしまいます。

# 初心者の方には、ちょっと使いにくそうなオプションです。

[投稿者] 高井さん
[日付]
[コメント]
うちは、IDE のハードディスクが無い環境なので特別なのかも知れませんが、
2 台目の SCSI にインストールする時に
install=(hd1,0)/boot/grub/stage1 (hd1,0) (hd1,0)/boot/grub/stage2 0x8000 p /boot
/grub/menu.lst
のように hd で指定しました。

lx98pkg/document/grub/grub98.txt に、

>               ※ IDE、SCSI のディスクはこの順に続けて番号を振ります。

とあるので、2 台目の HDD なら SCSI でも (hd1,?) とすべきなのでは
ないでしょうか?(たぶん^_^;)

[投稿者] 坂井さん
[日付] Mon, 19 Oct 1998 14:46:46 JST

7.10 0x8000 ってなんですか?

[投稿者] 寺本さん
[日付] Mon, 19 Oct 1998 09:32:10 +0900
[質問]
SCSI でも“0x8000”で良いのかどうか

[回答]
普通に使う場合は 0x8000 で構いません。 0x8000 は stage2 の読み込み
アドレスなので、これを変えると動作しません。

ではなぜこんなパラメータが指定できるのかというと、 FreeBSD の FFS で
使うためなのです。 FFS は「カーネルローダ用」にディスク中の連続した
領域を予約しており、 grub ではここに stage1.5 を入れて使います (この
領域は stage2 が全部入るほど広くないので、 stage2 からコマンドライン
モードや FFS 以外のファイルシステムドライバを取り払った stage1.5 を
この領域に書き込み、次のようなシーケンスで grub を起動します:


  stage1        →      stage1.5        →      stage2
  (ブートセクタ)        (ローダ領域)            (通常ファイル)
        <論理セクタ番号>        <通常ファイルとしてアクセス>

このようなときは、インストール時に stage2 の代わりに stage1.5 を指定
するので、アドレスが 0x8000 ではなく 0x2000 (stage1.5 の読み込みアド
レス) になります)。

[投稿者] 高井さん
[日付] Mon, 19 Oct 1998 13:53:07 JST

7.11 grubで固定ディスク起動メニューを置き換える方法

高井さんの記事より引用。

# 危険を伴うので、あまりおすすめはしません。

《固定ディスク起動メニューのリプレースとして
  grub/98 をインストールする                》

  ※ 既にどこかのパーティション (または別のディスク) に Linux
     または 〜BSD をインストールして、使える状態にあるとします。

  ※ ハードディスクの1シリンダの容量 (セクタサイズ×トラックあたりの
     セクタ数×ヘッド数) が grub/98 の stage2 のサイズ + 1KB 以上あるか
     確認してください。これに足りないとインストールできません。

  1. まず、安全対策から…
        Linux または 〜BSD から、 IPL およびメニューのバックアップを
        取ります。

        # dd if=/dev/hda of=/boot/backup/hda.cyl0 bs=512 count=20
          (デバイス名、バックアップファイル名はお望みのように)

        ここでは、 IPL、パーティションテーブル、メニュー本体をまとめて
        1つのファイルに保存しています。

     ・適当なブートフロッピーの作成
        バックアップしたファイルにアクセスでき、しかも `dd' が
        使えるようなもの。レスキューディスクがいいです。

     ・または、以上の代わりにインストールするディスクに
       空きパーティションを一つ確保し、 MS-DOS のシステム + FORMAT.EXE
       + HDFORMAT.EXE の入ったフロッピーを用意してください。

  2. その他の用意
     ・grub/98 をブートできるフロッピーを用意してください。

  3. grub/98 の stage2 を書き込む
        いよいよ固定ディスク起動メニューを飛ばします。
        くれぐれも誤操作にご注意ください。

         # dd if=/boot/grub/stage2 of=/dev/hda bs=512 seek=2 count=80

        ※「seek=2」を忘れるとパーティションテーブルが飛びます。
          誤ったときはすぐにその場で修復してください。一旦マシンを
          落としたりすると非常に厄介です。

  4. 書き込んだら、 grub のフロッピーを挿入して再起動します。
     grub が起動したら、コマンドモードで次のコマンドを実行します。

        command> install=(hd0,0)/boot/grub/stage1 (hd0)
                (続き) (hd0)2+80 0x8000 (hd0,0)/boot/grub/menu.lst

        stage1、menu.lst のデバイス/パスは環境に合わせて変更してください。

  5. 以上でインストールは終了です。

 99. やっちゃってしまった時
        まだ Linux とか 〜BSD の世界にいるときはそのまま次のコマンドを
        実行してください。そうでないときは、用意したレスキューディスクな
        どを立ち上げ、バックアップファイルにアクセスできるように
        してください。

    (a) パーティションテーブルを飛ばしてしまった

        # dd if=/boot/backup/hda.cyl0 of=/dev/hda bs=512 seek=1 skip=1 count=1

    (b) 固定ディスク起動メニューを復活したい

        # dd if=/boot/backup/hda.cyl0 of=/dev/hda bs=512 count=1
        # dd if=/boot/backup/hda.cyl0 of=/dev/hda bs=512 seek=2 skip=2

        または、 MS-DOS の FORMAT コマンドでそのディスクの
        パーティションの領域確保・解放を行うと固定ディスク起動メニューが
        再インストールされます。


なお、 grub の stage2 をどこかのパーティションの中に置いたまま
IPL だけ固定ディスク起動メニューと代えることもできます (こちら
の方が簡単かつ安全性が高いです)。
この場合、 3. の代わりに適当な場所に stage2 を置き、 4. で
`(hd0)2+80' の代わりにその stage2 のデバイス/パスを指定してください。
この方法だと固定ディスク起動メニューの復活も IPL を書き戻すだけで
すみます。

7.12 liloconfig-colorみたいにLinuxから簡単にgrubをインストールできませんか?

[投稿者] 井伊(bugs ML 506)
[質問]
ベータリリースには grub を Linuxからメニュー形式でインストールできるとよいのですが。。。
このあたりはどうお考えですか? > 高井さん

[回答]
Linux上のコマンドから実行できる grub のインストーラはぜひ作りたいところです。
アプローチとしては

 (1) initrd パッチに付属のインストーラ(grubinst)を移植する
 (2) grub のソースを流用して(各ファイルシステムの解析ルーチンなど)新たに作る
 (3) EXT2-fs library などを使って作る

などと考えております。
今のところ(2)がいちばん簡単そうで、これで行こうと思っています。
(3)にした場合は「EXT2パーティションへのインストール専用」ということに
なります。

[投稿者] 高井さん(bugs ML 516)
[コメント]
  開発版の Debian 2.0 の grub_0.4-2 では、バイナリパッケージをインストー
ルすると幾つかの質問で自動的に grub の設定とインストールをやってくれる
スクリプトがついてきます。

+ >> 実は、grub の initrd、bzImageパッチ (98版には最初から組み込んでいます)
+ >> には、 grubinst というインストールプログラム(C言語)がついていて、
+ >> これを使うとコマンド一発でファイルシステム中にgrubをインストールできた
+ >> りしますが、現在のところ98版は作っていません。

  これも新しい分が出たようで。
  売りは起動デバイス以外への grub のインストールをサポートしているとの事。

see:  ftp://debian.mis.hiroshima-u.ac.jp/debian/project/experimental

[投稿者] 吉山さん(bugs ML 411)
[コメント]
高井@京大マイコンクラブ です。

お待たせいたしました。
grub/98 の Linux上のインストーラらしきものが出来たので
αリリースとして公開します。

……といっても、AT版 grubinst に対するパッチです。
(grubinst も grub-0.4 本体に付属するものではなく、
 grub の initrd/bzImage 対応パッチに付属するものです)

コンパイルするには、`-DPC98x1' を指定してください。
これを指定しないとAT版の grubinst ができますが、この場合でも
オリジナルの grubinst に比べて機能が次のように変更されています。

  1. 2台目以降のHDDにもインストールできる
        オリジナルではデバイスのリストをソース内に持っていましたが
        これを /dev の下のブロックデバイスを全てトラバースするように
        しました。よって /dev にノードさえあればインストールできます。

  2. 書き込み確認メッセージ
        grubinst では `-f' オプションを指定していないと実際にディスクに
        書き戻す前にユーザに確認を求めますが、この確認メッセージを
        e2fsck 風に、1回キーをタイプするだけでよいようにしました。

  3. GNUスタイルの長いオプション
        `--help'、`--force' などのGNUスタイルのオプションにも対応しました。
        ヘルプにも反映させています。ただしこの対応は `-DHAVE_GETOPT_LONG'
        を指定してコンパイルする必要があります。

なおこれらの機能はすべて98版でも共通です。

※ デフォルト・パーティションについて

        grub/98 では起動されたドライブがデフォルトドライブに
        なりますが、起動されたパーティションはデフォルト
        パーティションには反映されません。インストール時に
        書き込まれているデフォルトパーティションがそのまま
        使われます。grub の install= コマンドで「p」オプションを
        指定するか、grubinst でインストールすると、 stage2 のある
        パーティションがデフォルトになります。

        98版で、stage1 をパーティションの先頭にインストールした
        場合は、固定ディスク起動メニューからそのパーティションの
        オフセットを渡されるので、これを使ってデフォルトパーティションを
        設定することも可能ですが、フロッピーやHDのMBRからブート
        された場合と区別できないのでやっていません (何かいい
        方法はありませんか?)。

[投稿者] 高井さん
[日付] Sun, 26 Jul 1998 07:18:38 JST

7.13 Cyrix の CPU のキャッシュ制御

元記事はbugs1123。

[投稿者] 中鉢さん
[質問]
Cx486DCL でキャッシュ組込みではどうかに挑戦しようかと...

[回答]
ご参考までに、 grub/98 用の簡易Cx486キャッシュ制御コードを
このメールに添付します。よろしければご試用ください。

(使い方)
β配布パッケージ中に含まれる gr98src.tgz の
grub-0.4-pc98x1/shared_src/cmdline.c に対するパッチになっています。
このパッチを当てたら、 stage2/Makefile 中の CFLAGS に `-DCX486_SUPPORT'
を追加して再コンパイルしてください。コマンドラインモード (またはメニュー
ファイル) で使えるコマンドに

        cx486=on        (キャッシュを有効にする)
        cx486=off       (キャッシュを停止する)
        cx486=barb      (キャッシュをHOLDステートでフラッシュする
                         モードで有効にする)
        cx486=init      (リセット直後と同じ状態に初期化)
        cx486           (現在の状態を表示)

が増えます。NCR(キャッシュ禁止領域)などの指定はできません。一応
決め打ちでBIOS領域 (00080000H - 000FFFFFH) をキャッシュ禁止に
指定しています。

またCx486シリーズかどうかのチェックを入れていますが誤判定するかも
知れません。動作確認は PC-9801DA + Cx486DLC、PC-9801RX + Cx486SLC
で行い、IBM Cx486SLC2 などは未確認です。

>> # 参考になりそうな資料を探したが古いのしか見つけれなかった状態

Cyrix の 5x86 などのオンライン資料が参考になるかも知れません。
私は Cx486 の判定などはこれを参考にしました。

# Cx486シリーズの資料はオンラインでは無いようです。

[投稿者] 高井さん
[日付] 1998.10.31


前のページ 次のページ 目次