[メールアドレス保護]

ちょっと必要にせまられて, /boot/loaderで拡張スライス(パーティション)を正し
く取り扱えるようにしたパッチを作成してみました. 私のところの環境では動いて
いるというレベルのadhocなパッチなので, テストしてみていただけないでしょう
か.

従来のloaderでは拡張スライスを認識できなかった(正確には最初のもの以外の拡
張スライスを認識できなかった)のですが, このパッチを適応したloaderでは全て
の拡張スライスおよびその中に作られたBSDパーティションを認識して取り扱うこ
とができます. これにより従来は基本スライスにインストールしたFreeBSD以外か
らは立ち上げることができなかったのが, 拡張スライスにインストールした物から
も立ち上げられるようになります.

普通にFreeBSDを使っている分にはあまり必要の無い機能だとは思いますが(そう
じゃなきゃこんな単純なバグが放っておかれるわけない), 開発や評価で複数バー
ジョンのFreeBSDを取っ替え引っ替えして使うような人には, 一つのディスクで済
ませることもできるので便利かもしれません.

ただ, 実際に使うためには386BSD用の拡張スライスを作らなくてはいけませんが,
現在のFreeBSDのfdiskでは拡張スライスが作成できません. portsの
sysutil/linuxfdiskもgeom対応していないので, KNOPPIXか何かを使って作ること
になります. その後, 作成した拡張スライスにbsdlabelコマンドを使ってパーティ
ションを切りインストールという手順をとるので, 決して初心者向けではありませ
ん.

添付のパッチは6-stable用とcurrent用(多分7-stableでもOKのはず)で, /usr/src
を起点としたdiffになっていますから

cd /usr/src
patch < (/some/dir/)biosdisk.c.patch        # 6-stable用
patch < (/some/dir/)biosdis.c.current.patch # current用

としてから, 通常と同じように

make buildworld
make installworld

とすればOKです. このパッチで変更される対象は /boot/loader のみですので, そ
れだけを作成・インストールしても良いです.

インストール後, 再立ち上げして起動メニューからloaderプロンプトに抜け

lsdev

と入力して全ての拡張スライスが表示されれば正しくインストールされています.
注意点としては, 使用されるloaderやloader.rcはそのディスクの最初のBSDスライ
スにあるものが使われるので, インストールする場所によっては効果なしなんてこ
ともあります.

ここまでくれば, あとはloaderでcurrdevやrootdevといった変数を設定してbootす
れば拡張スライスから立ち上げられるようになります. これらの設定はloaderプロ
ンプトから手動で設定することもできますが, ちょっとばかり面倒くさいので
loader用の4thプログラムにしておくのが便利です. 標準の/boot/beastie.4thを改
造したlocal.4thを添付しておきますので参考にしてみてください.

以上

-- 
Katsurajima "Raven" Naoto(桂島 直人)
Family Emblem: Circle and Left 3 Clove-TOMOE(丸に左三つ丁子巴)
e-mail: 
[&#x30E1;&#x30FC;&#x30EB;&#x30A2;&#x30C9;&#x30EC;&#x30B9;&#x4FDD;&#x8B77;]

--- sys/boot/i386/libi386/biosdisk.c.orig	2007-12-09 18:15:49.000000000 +0900
+++ sys/boot/i386/libi386/biosdisk.c	2007-12-13 21:05:49.000000000 +0900
@@ -84,6 +84,7 @@
     struct disklabel		od_disklabel;
     int				od_nslices;	/* slice count */
     struct dos_partition	od_slicetab[NEXTDOSPART];
+    u_int			od_extbase;	/* extended slice base */
 };
 
 /*
@@ -471,6 +472,7 @@
     od->od_flags = bdinfo[od->od_dkunit].bd_flags;
     od->od_boff = 0;
     od->od_nslices = 0;
+    od->od_extbase = 0;
     error = 0;
     DEBUG("open '%s', unit 0x%x slice %d partition %c",
 	     i386_fmtdev(dev), dev->d_kind.biosdisk.unit, 
@@ -654,6 +656,8 @@
 		DEBUG("no magic in extended table");
 		goto done;
 	}
+	if (od->od_extbase == 0)
+		od->od_extbase = dp->dp_start;
 	base = dp->dp_start;
 	dp = (struct dos_partition *)(&buf[DOSPARTOFF]);
 	for (i = 0; i < NDOSPART; i++, dp++) {
@@ -661,7 +665,10 @@
 			continue;
 		if (od->od_nslices == NEXTDOSPART)
 			goto done;
-		dp->dp_start += base;
+		if (dp->dp_typ == DOSPTYP_EXT)
+			dp->dp_start += od->od_extbase;
+		else
+			dp->dp_start += base;
 		bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp));
 		od->od_nslices++;
 	}

--- sys/boot/i386/libi386/biosdisk.c.orig	2007-11-13 08:53:43.000000000 +0900
+++ sys/boot/i386/libi386/biosdisk.c	2007-12-25 17:59:45.000000000 +0900
@@ -96,6 +96,7 @@
 	    struct disklabel		mbr_disklabel;
 	    int				mbr_nslices;	/* slice count */
 	    struct dos_partition	mbr_slicetab[NEXTDOSPART];
+	    u_int			mbr_extbase;
 	} _mbr;
 	struct {
 	    int				gpt_nparts;		
@@ -107,6 +108,7 @@
 #define	od_disklabel		_data._mbr.mbr_disklabel
 #define	od_nslices		_data._mbr.mbr_nslices
 #define	od_slicetab		_data._mbr.mbr_slicetab
+#define	od_extbase		_data._mbr.mbr_extbase
 #define	od_nparts		_data._gpt.gpt_nparts
 #define	od_partitions		_data._gpt.gpt_partitions
 
@@ -601,6 +603,7 @@
      * Find the slice in the DOS slice table.
      */
     od->od_nslices = 0;
+    od->od_extbase = 0;
     if (bd_read(od, 0, 1, buf)) {
 	DEBUG("error reading MBR");
 	return (EIO);
@@ -748,6 +751,8 @@
 		DEBUG("no magic in extended table");
 		goto done;
 	}
+	if (od->od_extbase == 0)
+		od->od_extbase = dp->dp_start;
 	base = dp->dp_start;
 	dp = (struct dos_partition *)(&buf[DOSPARTOFF]);
 	for (i = 0; i < NDOSPART; i++, dp++) {
@@ -755,7 +760,10 @@
 			continue;
 		if (od->od_nslices == NEXTDOSPART)
 			goto done;
-		dp->dp_start += base;
+		if (dp->dp_typ == DOSPTYP_EXT)
+			dp->dp_start += od->od_extbase;
+		else
+			dp->dp_start += base;
 		bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp));
 		od->od_nslices++;
 	}

Attachment: local.4th
Description: Binary data

メールによる返信