allocate_stack: Assertion `size != 0′ failed.

allocate_stack でエラーが出る場合

結論から申しますと「glibcの挙動が変? glibcのソース修正で回避」というメモ書きです

きっかけは普通に sortコマンドを実行しようとしたときに下記のようにエラーが出たことです

$ sort -u /etc/group
sort: allocatestack.c:463: allocate_stack: Assertion `size != 0' failed.
Aborted
$
 

allocate_stack() でのエラーの発生は 以下のコードで検証できました

#include <stdio.h>
#include <pthread.h>

static void* task ( void* p )
{
    return ( NULL );
}

int main ( int argc, char** argv )
{
    pthread_t t;
    pthread_attr_t attr;
    int status;

    status = pthread_attr_init ( &attr );
    if ( status )  return ( status );

    status = pthread_attr_setdetachstate ( &attr, PTHREAD_CREATE_DETACHED );
    if ( status )  return ( status );

    status = pthread_create ( &t, &attr, task, NULL );
    if ( status )  return ( status );

    status = pthread_join ( t, NULL );
    return ( status );
}
 

pthread_create() でスレッドを生成します スレッドは task() を実行して終了します
pthread_join() でスレッドの終了を待ってからメインのスレッドも終了する流れです

上記ソースコードを pthread.c のようなファイル名で保存して

$ gcc -o pthread -lpthread pthread.c
$ ./pthread
pthread: allocatestack.c:470: allocate_stack: Assertion `size != 0' failed.
中止
$
 

となる場合は 今回の事象かもしれません
ちなみに 環境は以下のとおり

OS Linux-2.6.37.1 (x86_64)
GCC gcc-4.5.2
glibc glibc-2.13.1

allocate_stack() は libpthreadにて定義されています つまり glibcです

ソースコードである nptl/allocatestack.c を見ると

460 
461       /* Adjust the stack size for alignment.  */
462       size &= ~__static_tls_align_m1;
463       assert (size != 0);
464 
 

まさしくここがエラーの出ていた部分です
462行目は 確保したいスタックサイズ size に対してアラインメントを取る処理ですが
既にこの時点で size=0 となっており 463行目のチェックに引っかかって異常終了したようです

なぜスタックサイズを size=0 で確保しようとするのか
しばらく glibcのソースを追いかけていましたが

スタックサイズの最小値を決める __defult_stacksize 変数が初期化されず 0 となっている
のが直接の原因のようでした

問題かと思われるのは glibcの libpthread.so です
該当のコードは nptl/nptl-init.c の __pthread_initialize_minimal_internal() です

/* Make sure it meets the minimum size that allocate_stack
   (allocatestack.c) will demand, which depends on the page size.  */
const uintptr_t pagesz = __sysconf (_SC_PAGESIZE);
const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
if (limit.rlim_cur < minstack)
  limit.rlim_cur = minstack;

/* Round the resource limit up to page size.  */
limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
__default_stacksize = limit.rlim_cur;

コードでは OSの PAGESIZE設定や その他パラメータを積み上げた値として
__default_stacksize = limit.rlim_cur
を決定しています

今回問題となっている glibcでは __pthread_initialize_minimal_internal() 自体が
呼び出されていない状態でした

結局 その後共有ライブラリの挙動を調べた結果
下記のように nptl/nptl-init.c に下記の修正を加えることで エラーが発生しなくなりました

    268 /* This can be set by the debugger before initialization is complete.  *    268 /
    269 static bool __nptl_initial_report_events __attribute_used__;
    270 
    271 void __attribute__((constructor))
    272 __pthread_initialize_minimal_internal (void)
    273 {
    274 #ifndef SHARED
    275   /* Unlike in the dynamically linked case the dynamic linker has not
    276      taken care of initializing the TLS data structures.  */
 

修正とは 271行目の部分に __attribute__((constructor)) を追記したことです
これにより libpthread.so がロードされたタイミングで
__pthread_initialize_minimal_internal() が呼び出され必要な初期化が行われるはずです

上記修正を加えて glibcを再ビルドした結果

$ ./pthread
$
$ sort -u /etc/group
adm::4:root,adm,daemon
audio::18:
bin::1:root,bin,daemon
cdrom::19:
cdrw::80:
console::17:
daemon::2:root,bin,daemon
dialout::20:root
disk::6:root,adm
floppy::11:root
kmem::9:
lp::7:lp
mail::12:mail
man::15:man
mem::8:
news::13:news
nobody::65534:
nofiles:x:200:
nogroup::65533:
portage::250:portage
root::0:root
smmsp:x:209:smmsp
sshd:x:22:
sys::3:root,bin,adm
tape::26:root
tty::5:
usb::85:
users::100:games,admin
utmp:x:406:
uucp::14:uucp
video::27:root
wheel::10:root
$
 

エラーが発生しなくなり スレッドもちゃんと生成されたようです

ちなみに 検証コード pthread.c にも問題があります
下記のように プログラム終了結果を表示すると実はプログラムが異常終了していることが分かります

$ ./pthread ; echo $?
22
$
 

正常終了を示す 0 が返らず エラーコードが表示されています
どこに問題があるのでしょうか
実は pthread_join() は既にスレッドが終了されている場合エラーを返すのです

スレッドの属性を PTHREAD_CREATE_DETACHED でなく PTHREAD_CREATE_JOINABLE とすると
プログラムは正常終了するようになります
PTHREAD_CREATE_JOINABLE は 親スレッドから pthread_join() が呼ばれるまで
リソースを確保しつづけるためです (たとえ先行終了したとしても)
逆に PTHREAD_CREATE_DETACHED はスレッドの終了時に直ちにリソースを解放してしまいます

このような動作の違いのため 下記に注意する必要があります

  • PTHREAD_CREATE_JOINABLE は pthread_join()忘れるとリソース枯渇の原因となる
  • PTHREAD_CREATE_DETACHED は pthread_join()でエラーが返る可能性がある

64bit Linux環境構築

64bit版 Linuxをスクラッチ構築して 32bit版 Linuxから移行する

ために 以下の手順を実行しました

  1. ターゲット環境の パーティションを設定する
  2. ターゲット環境に 64bitベース Linux環境をインストールする
  3. 32bit Linux上で動作する クロスコンパイラを構築する
  4. 32bit Linux上で 64bit版 Linuxカーネルをコンパイルする
  5. ターゲット環境に 64bitカーネルをコピーして環境を整える
  6. ターゲット環境で 64bit環境が起動することを確認
  7. インストール後のglibcの設定

2008年頃に試してみた Gentoo amd64 LiveCD版はインストーラに不具合があって
インストールが途中で停止するという苦い思い出があります

ただ 2011年となった今では 64bitディストリビューションも安定していて
わざわざ ゼロからコンパイルする必要はないかもしれません

今回は 32bitから64bit環境への本格移行が目的であるのと
スクラッチで OS環境を思い通りに構築したいという考えから
Linuxのスクラッチ構築を行い 手順をログとして残します

今回 検証した環境は次のとおり

検証環境
移行元32bit環境 移行先64bit環境
CPU Turion64 MT-37 (2GHz 1コア) PhenomII X4 905e (2.5GHz 4コア)
マザーボード K8N Neo Platinum GA-880GM-USB3
メモリ 1GB (DDR-400) 8GB (DDR3-1066)
HDD HDT722525DLAT80 (PATA 250GB) HDP725025GLA380 (SATA 250GB)
イーサネット nForce ethernet driver
(forcedeth GbE)
Realtek8111D
(R8168 GbE)
グラフィック nVidia GeForce6600GT Radeon HD 4250
オンボード
サウンド Sound Blaster Live! Audigy2
PCI
Realtek ALC892 codec (HD)
オンボード
Linuxカーネルバージョン 2.6.30.5 2.6.36.3

ターゲット環境の パーティションを設定する

ここでは ターゲットとなる 64bit構築予定のマシンで作業を行います
ハードディスクには 何も入ってない状態なので まず DVDからシステムを起動します

DVDは押入れをあさって出てきた Ubuntu-9.04 を使いました
メニューから 「端末」を立ち上げて

ubuntu@ubuntu:~$ uname -a
Linux ubuntu 2.6.28-11-generic #42-Ubuntu SMP Fri Apr 17 01:57:59 UTC 2009 i686 GNU/Linux
ubuntu@ubuntu:~$ sudo su
root@ubuntu:/home/ubuntu# fdisk /dev/sda

このディスクのシリンダ数は 484521 に設定されています。
間違いではないのですが、1024 を超えているため、以下の場合
に問題を生じうる事を確認しましょう:
1) ブート時に実行するソフトウェア (例. バージョンが古い LILO)
2) 別の OS のブートやパーティション作成ソフト
   (例. DOS FDISK, OS/2 FDISK)

コマンド (m でヘルプ): 

~
(省略)
~

コマンド (m でヘルプ): p

ディスク /dev/sda: 250.0 GB, 250059350016 バイト
ヘッド 16, セクタ 63, シリンダ 484521
Units = シリンダ数 of 1008 * 512 = 516096 バイト
Disk identifier: 0x90909090

デバイス ブート     始点        終点    ブロック   Id システム
/dev/sda1   *           1       20805    10485688+  a5  FreeBSD
/dev/sda2           20806      484521   233712864   83  Linux

コマンド (m でヘルプ): w
領域テーブルは交換されました!

ioctl() を呼び出して領域テーブルを再読込みします。
ディスクを同期させます。
root@ubuntu:/home/ubuntu#
 

250GBあるディスクのうち FreeBSD用に 10GB 割り当てました
残りの 240GBを Linux用に割り当てました

SWAPパーティションは作っていません
8GBもメモリを積んでいるので 不足することはない前提です

ちなみに FreeBSDには FreeBSD-8.1-release amd64 と grub2 をインストールしました

引き続いて 作成したばかりの /dev/sda2 を ext3 でフォーマットします

root@ubuntu:/home/ubuntu# mke2fs -j /dev/sda2
mke2fs 1.41.4 (27-Jan-2009)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
14614528 inodes, 58428216 blocks
2921410 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
1784 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
	   32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
	   4096000, 7962624, 11239424, 20480000, 23887872

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 22 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
root@ubuntu:/home/ubuntu#
 

ターゲット環境に 64bitベース Linux環境をインストールする

本当は インストールした FreeBSDから
Linuxパーティションに初期ファイルを転送するつもりでしたが
FreeBSDから ext3への書き込みの実績がなく
多少不安があったので このまま DVD Ubuntu上で作業を続けます

Gentoo Mirror-Site
インターネットから getntooのファイルシステムイメージを拾ってきます
Gentoo amd64 current-stage3
current-stage3 のディレクトリに 毎日のように更新されている
ファイルシステムイメージがありました

Gentoo とは Linuxディストリビュージョンの一種で有名です
初期構築手段として 上図にあるような stage3 という名前の tarボールが提供されています
中身は Linuxの最小限の環境で ls cp mv などの基本コマンドや ブートに必要な各種スクリプトが含まれます
X-Window や カーネル が含まれておらず カーネルは別途調達する必要があります

では この stage3 を先ほどフォーマットした /dev/sda2 に展開します

root@ubuntu:/home/ubuntu# mount -t ext3 /dev/sda2 /mnt
root@ubuntu:/home/ubuntu# cd /mnt
root@ubuntu:/mnt# tar -xjpf ~ubuntu/stage3-amd64-20110127.tar.bz2
root@ubuntu:/mnt# ls
bin   dev  home  lib32  lost+found  opt   root  sys  usr
boot  etc  lib   lib64  mnt         proc  sbin  tmp  var
root@ubuntu:/mnt# 
 

アーカイブを展開した状態では 起動する際にルートファイルシステムがマウントできません
/etc/fstab を編集します

#                                           

# NOTE: If your BOOT partition is ReiserFS, add the notail option to opts.
#/dev/BOOT              /boot           ext2            noauto,noatime  1 2
#/dev/ROOT              /               ext3            noatime         0 1
/dev/sda2               /               ext3            noatime         0 1
#/dev/SWAP              none            swap            sw              0 0
/dev/cdrom              /mnt/cdrom      auto            noauto,ro       0 0
#/dev/fd0               /mnt/floppy     auto            noauto          0 0

 

/dev/BOOT は別ファイルシステムをマウントする必要がないので コメントアウトします
/dev/ROOT が存在しないので代わりに 実際のファイルシステム /dev/sda2 を直接指定します
/dev/SWAP もコメントアウトします SWAPを使わない方針で進めてみます

また 初回は rootでログインする必要があるため
rootパスワードを 一旦無くします /etc/passwd を編集して

root::0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
adm:x:3:4:adm:/var/adm:/bin/false
lp:x:4:7:lp:/var/spool/lpd:/bin/false
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/bin/false
news:x:9:13:news:/usr/lib/news:/bin/false
uucp:x:10:14:uucp:/var/spool/uucppublic:/bin/false
operator:x:11:0:operator:/root:/bin/bash
man:x:13:15:man:/usr/share/man:/bin/false
postmaster:x:14:12:postmaster:/var/spool/mail:/bin/false
portage:x:250:250:portage:/var/tmp/portage:/bin/false
nobody:x:65534:65534:nobody:/:/bin/false
sshd:x:22:22:added by portage for openssh:/var/empty:/sbin/nologin
 

1行目 root の隣にあった 「x」の文字を削除します これでパスワード無ログインができます

ベース環境の初期状況は 以上です
これで Linux環境としては最低限度の環境で rootアカウントでログインができるはずです

ただし 心臓となる カーネルがまだ入ってないので まだシステムは起動しません
以降の節は カーネルを構築する話となります

root@ubuntu:/mnt# cd -
root@ubuntu:/home/ubuntu# umount /mnt
root@ubuntu:/home/ubuntu# 
 

ターゲットのハードディスクをアンマウントしたら
しばらく 64bit側のシステムにはおやすみいただきます

32bit Linux上で動作する クロスコンパイラを構築する

ここからは 環境構築済の移行元 32bit Linux環境で作業をします
まず 32bit Linuxで 64bitコンパイルができる クロスコンパイル環境を構築します

コンパイル環境とは 以下の 3パッケージが適切にインストールされて利用できる状態を指します

パッケージ
binutils アセンブラである as や リンカである ld が含まれます
アセンブルソースを実行可能なマシン語バイナリに翻訳する機能です
glibc C標準ライブラリです libc.a libc.so が含まれます
C言語の標準仕様にある libm (数学ライブラリ) や
stdio.h などの標準ヘッダも含まれます
gcc コンパイラです gccコマンドが含まれます
C言語などのさまざまなソースコードをアセンブルソースに変換
binutils や glibc と連携して 実行バイナリを作ります

ここでは これら3つを 「32bit Linux上で動作し 64bit用のコードを吐く」ように構築します
現在の 32bit Linux環境でのコンパイル環境は下記のとおりです

32bit コンパイル環境
パッケージ インストールパス ビルドオプション
binutils-2.17 /usr/binutils/2.17/i686 –prefix=/usr/binutils/2.17/i686
–host=i686-linux-gnu
–target=i686-linux-gnu
–program-prefix=i686-linux-gnu-
glibc-2.5 /usr/glibc/2.5/i686 –prefix=/usr/glibc/2.5/i686
–program-prefix=i686-linux-gnu-
–build=i686-linux-gnu
–host=i686-linux-gnu
–with-headers=/usr/src/linux/include
gcc-4.1.2 /usr/gcc/4.1.2/i686 –prefix=/usr/gcc/4.1.2/i686
–program-prefix=i686-linux-gnu-
–host=i686-linux-gnu
–target=i686-linux-gnu
–build=i686-linux-gnu
–enable-threads=posix
–enable-nls
–with-libiconv-prefix=/usr/glibc/2.5/i686
–with-as=/usr/binutils/2.17/i686/bin/i686-linux-gnu-as
–with-ld=/usr/binutils/2.17/i686/bin/i686-linux-gnu-ld
–with-dwarf2
–with-arch=i686
–enable-languages=c,c++,fortran,java

一般の ディストリビューションLinuxとインストールパスが異なりますが
ネイティブコンパイラであれ クロスコンパイラであれ インストールディレクトリを別けておくと
バージョンアップや 新しいターゲット構築などに便利です

今回のクロス環境構築においても /usr/gcc/4.5.2/amd64 をインストールパスにするような方針です

最初に Linuxカーネルのソースを展開します
カーネルソースの ヘッダファイルが必要なためです

Ring Server Projectのページから 「ソフトウェアライブラリ」「各種Linuxディストリビューション」
「Linux Kernel」「kernel」「v2.6」「」
と最新のバージョンをたどって 最新のソースコードをダウンロードします

検証時点では 2.6.36.3 でした この linux-2.6.36.3.tar.bz2 をビルド用のディレクトリ展開します
検証環境では /usr/src/ 以下に展開することにしました

$ su
# chown admin /usr/src
# exit
$ cd /usr/src
$ tar -xjf ~admin/linux-2.6.36.3.tar.bz2
$ cd linux-2.6.36.3/include
$ ln -s ../arch/x86/include/asm asm
$ 
 

展開後に lnコマンドで asm というシンボリックリンクを作っています
これは ../arch/適切なアーキテクチャ/include/asm ディレクトリのシンボリックリンクとしています
これは C言語の話になりますが #include <linux/asm/〜.h> が
適切なアーキテクチャのヘッダを引っ張れるようにする準備です

以上が カーネルの準備でした 続いて早速 binutilsから構築します

$ cd
$ tar -xjf binutils-2.21.tar.bz2
$ mkdir binutils-2.21-amd64-build
$ cd binutils-2.21-amd64-build
$
$ VPATH=../binutils-2.21 ../binutils-2.21/configure --prefix=/usr/binutils/2.21/amd64 --host=i686-linux-gnu --target=amd64-linux-gnu --program-prefix=amd64-linux-gnu-
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
〜
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether -fkeep-inline-functions is supported... yes
configure: creating ./config.status
config.status: creating Makefile
$
$ make
make[1]: Entering directory `/home/admin/binutils-2.21-amd64-build'
mkdir -p -- ./libiberty
Configuring in ./libiberty
configure: creating cache ./config.cache
checking whether to enable maintainer-specific portions of Makefiles... no
checking for makeinfo... makeinfo --split-size=5000000
〜
mv -f .deps/eelf_l1om.Tpo .deps/eelf_l1om.Po
/bin/sh ./libtool --tag=CC   --mode=link i686-linux-gnu-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -g -O2   -o ld-new ldgram.o ldlex-wrapper.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o ldfile.o ldcref.o plugin.o eelf_x86_64.o eelf_i386.o ei386linux.o eelf_l1om.o  ../bfd/libbfd.la ../libiberty/libiberty.a  -lz -ldl
libtool: link: i686-linux-gnu-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -g -O2 -o ld-new ldgram.o ldlex-wrapper.o lexsup.o ldlang.o mri.o ldctor.o ldmain.o ldwrite.o ldexp.o ldemul.o ldver.o ldmisc.o ldfile.o ldcref.o plugin.o eelf_x86_64.o eelf_i386.o ei386linux.o eelf_l1om.o  ../bfd/.libs/libbfd.a ../libiberty/libiberty.a -lz -ldl
make[4]: Leaving directory `/home/admin/binutils-2.21-amd64-build/ld'
make[3]: Leaving directory `/home/admin/binutils-2.21-amd64-build/ld'
make[2]: Leaving directory `/home/admin/binutils-2.21-amd64-build/ld'
make[1]: `all-target' に対して行うべき事はありません。
make[1]: Leaving directory `/home/admin/binutils-2.21-amd64-build'
$
$ su
# make install
make[1]: Entering directory `/home/admin/binutils-2.21-amd64-build'
/bin/sh ../binutils-2.21/mkinstalldirs /usr/binutils/2.21/amd64 /usr/binutils/2.21/amd64
mkdir -p -- /usr/binutils/2.21/amd64 /usr/binutils/2.21/amd64
〜
make[3]: `install' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/binutils-2.21-amd64-build/libiberty/testsuite'
make[2]: Leaving directory `/home/admin/binutils-2.21-amd64-build/libiberty'
make[1]: `install-target' に対して行うべき事はありません。
make[1]: Leaving directory `/home/admin/binutils-2.21-amd64-build'
#
# exit
$ ls /usr/binutils/2.21/amd64/bin/
amd64-linux-gnu-addr2line  amd64-linux-gnu-ld       amd64-linux-gnu-readelf
amd64-linux-gnu-ar         amd64-linux-gnu-ld.bfd   amd64-linux-gnu-size
amd64-linux-gnu-as         amd64-linux-gnu-nm       amd64-linux-gnu-strings
amd64-linux-gnu-c++filt    amd64-linux-gnu-objcopy  amd64-linux-gnu-strip
amd64-linux-gnu-elfedit    amd64-linux-gnu-objdump
amd64-linux-gnu-gprof      amd64-linux-gnu-ranlib
$
 

特にエラーや警告なく 64bitアセンブラがインストールできました
–program-prefix に amd64-linux-gnu- を指定したのでバイナリツール名の接頭子となっています
今後このアセンブラを活用していくことになります 続けて glibc と gcc をビルドしていきます

ただし glibc と gcc は互いに依存しあっているパッケージのため
両方を交互に構築進める形となり 結果複雑な手順となります

まずは glibc から gccがまだないのでヘッダファイル(.h)のみを作ります

最近の glibcは glibc-libidn (IDN(国際化ドメイン名)ライブラリ) を必須としています
glibcの配布場所と同じところに glibc-libidnパッケージが配布されていますのでこれも持ってきます

$ tar -xjf glibc-2.9.tar.bz2
$ cd glibc-2.9
$ tar -xjf ../glibc-libidn-2.9.tar.bz2
$ mv glibc-libidn-2.9 libidn
$ cd ..
$
$ mkdir glibc-2.9-amd64-build
$ cd glibc-2.9-amd64-build
$
$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ar RANLIB=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/glibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls --program-prefix=amd64-linux-gnu- --enable-stackguard-randomization --with-headers=/usr/src/linux-2.6.36.3-amd64/include --with-binutils=/usr/binutils/2.21/amd64/bin --enable-shared
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... i686-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
〜
configure: creating ./config.status
config.status: creating config.make
config.status: creating Makefile
config.status: creating config.h
config.status: executing default commands
$
 

configure時 –enable-shared を指定していますが これは不要かもしれません

make install-headers とコマンドを打ちます
また ヘッダファイルのインストールまで行ってくれるので root権限で実施します

$ su
# make install-headers
make -r PARALLELMFLAGS="" CVSOPTS="" -C ../glibc-2.9 objdir=`pwd` install-headers
make[1]: Entering directory `/home/admin/glibc-2.9'
〜
nptl/sysdeps/x86_64/tls.h:69:3: error: #error "TLS support is required."
make[1]: *** [/home/admin/glibc-2.9-amd64-build/Versions.v.i] エラー 1
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [install-headers] エラー 2
#
 

ついに というかやっぱりエラーが出てきました
「gccに TLSの機能が必須だよ」という意味だろうと思います

TLS(Thread Local Storage)は Wikipedia あたりが詳しいですが 「ふーん」という感じで読み飛ばして
今回のクロスコンパイラの機能とあまり関係なさそうなことが分かったので

# vi ../glibc-2.9/config.h.in
 

コンパイル環境を 下記のように書き換えて回避しました

126 /* Define if _rtld_local structure should be forced into .sdata section.  */
127 #undef  HAVE_SDATA_SECTION
128
129 /* Define if binutils support TLS handling.  */
130 #undef  HAVE_TLS_SUPPORT
          ------> ここを修正
    #define  HAVE_TLS_SUPPORT
131
132 /* Define if the compiler's exception support is based on libunwind.  */
133 #undef  HAVE_CC_WITH_LIBUNWIND
 

少し強引な方法ですが HAVE_TLS_SUPPORT 定数を有効化しました
(後でより大きなトラブルにならないことを祈って) さらにビルドを続けます

# make install-headers
make -r PARALLELMFLAGS="" CVSOPTS="" -C ../glibc-2.9 objdir=`pwd` install-headers
make[1]: Entering directory `/home/admin/glibc-2.9'
〜
/bin/install -c -m 644 link.h /usr/glibc/2.9/amd64/include/link.h
/bin/install -c -m 644 ../sysdeps/x86_64/bits/link.h /usr/glibc/2.9/amd64/include/bits/link.h
make[2]: Leaving directory `/home/admin/glibc-2.9/elf'
make[1]: Leaving directory `/home/admin/glibc-2.9'
#
# ls -R /usr/glibc/2.9/amd64/
/usr/glibc/2.9/amd64/:
include

/usr/glibc/2.9/amd64/include:
_G_config.h  errno.h         langinfo.h  netipx      sched.h      termio.h
a.out.h      error.h         lastlog.h   netiucv     scsi         termios.h
aio.h        execinfo.h      libgen.h    netpacket   search.h     tgmath.h
aliases.h    fcntl.h         libintl.h   netrom      semaphore.h  thread_db.h
alloca.h     features.h      libio.h     netrose     setjmp.h     time.h
ar.h         fenv.h          limits.h    nfs         sgtty.h      ttyent.h
argp.h       fmtmsg.h        link.h      nl_types.h  shadow.h     ucontext.h
argz.h       fnmatch.h       locale.h    nss.h       signal.h     ulimit.h
arpa         fpu_control.h   malloc.h    obstack.h   spawn.h      unistd.h
assert.h     fstab.h         math.h      paths.h     stab.h       ustat.h
bits         fts.h           mcheck.h    poll.h      stdint.h     utime.h
byteswap.h   ftw.h           memory.h    printf.h    stdio.h      utmp.h
complex.h    gconv.h         mntent.h    protocols   stdio_ext.h  utmpx.h
cpio.h       getopt.h        monetary.h  pthread.h   stdlib.h     values.h
crypt.h      glob.h          mqueue.h    pty.h       string.h     wait.h
ctype.h      gnu             net         pwd.h       strings.h    wchar.h
dirent.h     gnu-versions.h  netash      re_comp.h   stropts.h    wctype.h
dlfcn.h      grp.h           netatalk    regex.h     sys          wordexp.h
elf.h        iconv.h         netax25     regexp.h    syscall.h    xlocale.h
endian.h     ieee754.h       netdb.h     resolv.h    sysexits.h
envz.h       ifaddrs.h       neteconet   rpc         syslog.h
err.h        inttypes.h      netinet     rpcsvc      tar.h

/usr/glibc/2.9/amd64/include/arpa:
ftp.h  inet.h  nameser.h  nameser_compat.h  telnet.h  tftp.h

/usr/glibc/2.9/amd64/include/bits:
a.out.h         initspin.h       poll.h          sockaddr.h     syslog.h
byteswap.h      ioctl-types.h    posix1_lim.h    socket.h       termios.h
cmathcalls.h    ioctls.h         posix2_lim.h    socket2.h      time.h
confname.h      ipc.h            posix_opt.h     stab.def       types.h
dirent.h        ipctypes.h       printf-ldbl.h   stat.h         typesizes.h
dlfcn.h         libc-lock.h      pthreadtypes.h  statfs.h       uio.h
elfclass.h      libio-ldbl.h     resource.h      statvfs.h      unistd.h
endian.h        link.h           sched.h         stdio-ldbl.h   ustat.h
environments.h  local_lim.h      select.h        stdio-lock.h   utmp.h
errno.h         locale.h         sem.h           stdio.h        utmpx.h
error.h         mathcalls.h      semaphore.h     stdio2.h       utsname.h
fcntl.h         mathdef.h        setjmp.h        stdlib-ldbl.h  waitflags.h
fcntl2.h        mathinline.h     shm.h           stdlib.h       waitstatus.h
fenv.h          mman.h           sigaction.h     string.h       wchar-ldbl.h
fenvinline.h    monetary-ldbl.h  sigcontext.h    string2.h      wchar.h
huge_val.h      mqueue.h         siginfo.h       string3.h      wchar2.h
huge_valf.h     mqueue2.h        signum.h        stropts.h      wordsize.h
huge_vall.h     msq.h            sigset.h        sys_errlist.h  xopen_lim.h
in.h            nan.h            sigstack.h      syslog-ldbl.h  xtitypes.h
inf.h           netdb.h          sigthread.h     syslog-path.h

/usr/glibc/2.9/amd64/include/gnu:
lib-names.h  libc-version.h

/usr/glibc/2.9/amd64/include/net:
ethernet.h  if_arp.h     if_ppp.h     if_slip.h   ppp_defs.h
if.h        if_packet.h  if_shaper.h  ppp-comp.h  route.h

/usr/glibc/2.9/amd64/include/netash:
ash.h

/usr/glibc/2.9/amd64/include/netatalk:
at.h

/usr/glibc/2.9/amd64/include/netax25:
ax25.h

/usr/glibc/2.9/amd64/include/neteconet:
ec.h

/usr/glibc/2.9/amd64/include/netinet:
ether.h  if_ether.h  if_tr.h  in.h        ip.h   ip_icmp.h  udp.h
icmp6.h  if_fddi.h   igmp.h   in_systm.h  ip6.h  tcp.h

/usr/glibc/2.9/amd64/include/netipx:
ipx.h

/usr/glibc/2.9/amd64/include/netiucv:
iucv.h

/usr/glibc/2.9/amd64/include/netpacket:
packet.h

/usr/glibc/2.9/amd64/include/netrom:
netrom.h

/usr/glibc/2.9/amd64/include/netrose:
rose.h

/usr/glibc/2.9/amd64/include/nfs:
nfs.h

/usr/glibc/2.9/amd64/include/protocols:
routed.h  rwhod.h  talkd.h  timed.h

/usr/glibc/2.9/amd64/include/rpc:
auth.h       clnt.h       netdb.h      pmap_rmt.h  rpc_msg.h   types.h
auth_des.h   des_crypt.h  pmap_clnt.h  rpc.h       svc.h       xdr.h
auth_unix.h  key_prot.h   pmap_prot.h  rpc_des.h   svc_auth.h

/usr/glibc/2.9/amd64/include/rpcsvc:
bootparam.h       nfs_prot.x      nis_object.x  rquota.x    yp.h        ypupd.h
bootparam_prot.x  nis.h           nis_tags.h    rstat.x     yp.x
key_prot.x        nis.x           nislib.h      rusers.x    yp_prot.h
klm_prot.x        nis_callback.h  nlm_prot.x    sm_inter.x  ypclnt.h
mount.x           nis_callback.x  rex.x         spray.x     yppasswd.x

/usr/glibc/2.9/amd64/include/scsi:
scsi.h  scsi_ioctl.h  sg.h

/usr/glibc/2.9/amd64/include/sys:
acct.h      io.h           poll.h      shm.h        syslog.h       un.h
bitypes.h   ioctl.h        prctl.h     signal.h     sysmacros.h    unistd.h
cdefs.h     ipc.h          procfs.h    signalfd.h   termios.h      user.h
debugreg.h  kd.h           profil.h    socket.h     time.h         ustat.h
dir.h       kdaemon.h      ptrace.h    socketvar.h  timeb.h        utsname.h
epoll.h     klog.h         queue.h     soundcard.h  timerfd.h      vfs.h
errno.h     mman.h         quota.h     stat.h       times.h        vlimit.h
eventfd.h   mount.h        raw.h       statfs.h     timex.h        vt.h
fcntl.h     msg.h          reboot.h    statvfs.h    ttychars.h     vtimes.h
file.h      mtio.h         reg.h       stropts.h    ttydefaults.h  wait.h
fsuid.h     param.h        resource.h  swap.h       types.h        xattr.h
gmon.h      pci.h          select.h    syscall.h    ucontext.h
gmon_out.h  perm.h         sem.h       sysctl.h     uio.h
inotify.h   personality.h  sendfile.h  sysinfo.h    ultrasound.h
#
 

実際にファイルを眺めてみても 〜.h のヘッダファイルのみがインストールされた状態です

ヘッダファイルに不足があるので さらに下記の作業を行います

# cp bits/stdio_lim.h /usr/glibc/2.9/amd64/include/bits/
# touch /usr/glibc/2.9/amd64/include/gnu/stubs.h
# touch /usr/glibc/2.9/amd64/include/gnu/stubs-64.h
# exit
$ cd ..
$
 

上記を実施しないと後続作業の #include <〜> でエラーが出て失敗します

ここまでで一応ヘッダファイルまでは出来たので ようやく gccの足がかりとなります
ただし glibcのメインである libc や 標準ライブラリがまだ存在しないので
現段階では gccも完全に構築できません

ところで 最近の gccは 数学ライブラリである gmp や mpfr に依存しています
gcc-4.5.2 が必要とするバージョンの gmp と mpfr を導入しておきます

$ tar -xjf gmp-5.0.1.tar.bz2
$ cd gmp-5.0.1
$ ./configure --prefix=/usr/local
checking build system type... athlon64-pc-linux-gnu
checking host system type... athlon64-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
〜
config.status: linking mpn/generic/zero.c to mpn/zero.c
config.status: linking mpn/x86/umul.asm to mpn/umul.asm
config.status: linking mpn/x86/udiv.asm to mpn/udiv.asm
config.status: linking mpn/x86/invert_limb.asm to mpn/invert_limb.asm
config.status: linking mpn/x86/k7/gmp-mparam.h to gmp-mparam.h
config.status: executing libtool commands
$
$ make
gcc -std=gnu99 `test -f 'gen-fac_ui.c' || echo './'`gen-fac_ui.c -o gen-fac_ui
./gen-fac_ui 32 0 >mpz/fac_ui.h || (rm -f mpz/fac_ui.h; exit 1)
gcc -std=gnu99 `test -f 'gen-fib.c' || echo './'`gen-fib.c -o gen-fib
./gen-fib header 32 0 >fib_table.h || (rm -f fib_table.h; exit 1)
./gen-fib table 32 0 >mpn/fib_table.c || (rm -f mpn/fib_table.c; exit 1)
gcc -std=gnu99 `test -f 'gen-bases.c' || echo './'`gen-bases.c -o gen-bases -lm
./gen-bases header 32 0 >mp_bases.h || (rm -f mp_bases.h; exit 1)
〜
libtool: link: ranlib .libs/libgmp.a
libtool: link: rm -fr .libs/libgmp.lax
libtool: link: ( cd ".libs" && rm -f "libgmp.la" && ln -s "../libgmp.la" "libgmp.la" )
make[2]: Leaving directory `/home/admin/gmp-5.0.1'
make[1]: Leaving directory `/home/admin/gmp-5.0.1'
$
$ make check
make  check-recursive
make[1]: Entering directory `/home/admin/gmp-5.0.1'
Making check in tests
make[2]: Entering directory `/home/admin/gmp-5.0.1/tests'
Making check in .
make[3]: Entering directory `/home/admin/gmp-5.0.1/tests'
make  libtests.la t-bswap t-constants t-count_zeros t-gmpmax t-hightomask t-modlinv t-popc t-parity t-sub
make[4]: Entering directory `/home/admin/gmp-5.0.1/tests'
〜
make[2]: Entering directory `/home/admin/gmp-5.0.1/tune'
make[2]: `check' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/gmp-5.0.1/tune'
Making check in doc
make[2]: Entering directory `/home/admin/gmp-5.0.1/doc'
make[2]: `check' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/gmp-5.0.1/doc'
make[2]: Entering directory `/home/admin/gmp-5.0.1'
make[2]: `check-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/gmp-5.0.1'
make[1]: Leaving directory `/home/admin/gmp-5.0.1'
$
$ su
# make install
make  install-recursive
make[1]: Entering directory `/home/admin/gmp-5.0.1'
Making install in tests
make[2]: Entering directory `/home/admin/gmp-5.0.1/tests'
Making install in .
make[3]: Entering directory `/home/admin/gmp-5.0.1/tests'
make[4]: Entering directory `/home/admin/gmp-5.0.1/tests'
〜
make[4]: Entering directory `/home/admin/gmp-5.0.1'

+-------------------------------------------------------------+
| CAUTION:                                                    |
|                                                             |
| If you have not already run "make check", then we strongly  |
| recommend you do so.                                        |
|                                                             |
| GMP has been carefully tested by its authors, but compilers |
| are all too often released with serious bugs.  GMP tends to |
| explore interesting corners in compilers and has hit bugs   |
| on quite a few occasions.                                   |
|                                                             |
+-------------------------------------------------------------+

make[4]: Leaving directory `/home/admin/gmp-5.0.1'
make[3]: Leaving directory `/home/admin/gmp-5.0.1'
make[2]: Leaving directory `/home/admin/gmp-5.0.1'
make[1]: Leaving directory `/home/admin/gmp-5.0.1'
#
 

移行元環境の i686版のインストールでかまいません 続いて mpfr を

$ tar -xjf mpfr-3.0.0.tar.bz2
$ cd mpfr-3.0.0
$
$ ./configure --prefix=/usr/local
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to disable maintainer-specific portions of Makefiles... yes
〜
configure: creating ./config.status
config.status: creating Makefile
config.status: creating tests/Makefile
config.status: creating mparam.h
config.status: executing depfiles commands
config.status: executing libtool commands
$ make
Making all in tests
make[1]: Entering directory `/home/admin/mpfr-3.0.0/tests'
make[1]: `all' に対して行うべき事はありません。
make[1]: Leaving directory `/home/admin/mpfr-3.0.0/tests'
make[1]: Entering directory `/home/admin/mpfr-3.0.0'
/bin/sh ./libtool --tag=CC   --mode=compile gcc -std=gnu99 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_LOCALE_H=1 -DHAVE_WCHAR_H=1 -DHAVE_STDARG=1 -DHAVE_SYS_TIME_H=1 -DHAVE_STDINT_H=1 -DHAVE_VA_COPY=1 -DHAVE_SETLOCALE=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_LONG_LONG=1 -DHAVE_INTMAX_T=1 -DMPFR_HAVE_INTMAX_MAX=1 -DMPFR_HAVE_FESETROUND=1 -DHAVE_DENORMS=1 -DHAVE_ROUND=1 -DHAVE_TRUNC=1 -DHAVE_FLOOR=1 -DHAVE_CEIL=1 -DHAVE_NEARBYINT=1 -DHAVE_LDOUBLE_IEEE_EXT_LITTLE=1 -DLT_OBJDIR=\".libs/\" -DHAVE_ATTRIBUTE_MODE=1 -I.     -Wall -Wmissing-prototypes -Wpointer-arith -m32 -O2 -pedantic -fomit-frame-pointer -mtune=k8 -march=k8 -ffloat-store -MT exceptions.lo -MD -MP -MF .deps/exceptions.Tpo -c -o exceptions.lo exceptions.c
〜
libtool: link: ar cru .libs/libmpfr.a  exceptions.o extract.o uceil_exp2.o uceil_log2.o ufloor_log2.o add.o add1.o add_ui.o agm.o clear.o cmp.o cmp_abs.o cmp_si.o cmp_ui.o comparisons.o div_2exp.o div_2si.o div_2ui.o div.o div_ui.o dump.o eq.o exp10.o exp2.o exp3.o exp.o frac.o get_d.o get_exp.o get_str.o init.o inp_str.o isinteger.o isinf.o isnan.o isnum.o const_log2.o log.o modf.o mul_2exp.o mul_2si.o mul_2ui.o mul.o mul_ui.o neg.o next.o out_str.o printf.o vasprintf.o const_pi.o pow.o pow_si.o pow_ui.o print_raw.o print_rnd_mode.o reldiff.o round_prec.o set.o setmax.o setmin.o set_d.o set_dfl_prec.o set_exp.o set_rnd.o set_f.o set_prc_raw.o set_prec.o set_q.o set_si.o set_str.o set_str_raw.o set_ui.o set_z.o sqrt.o sqrt_ui.o sub.o sub1.o sub_ui.o rint.o ui_div.o ui_sub.o urandom.o urandomb.o get_z_exp.o swap.o factorial.o cosh.o sinh.o tanh.o sinh_cosh.o acosh.o asinh.o atanh.o atan.o cmp2.o exp_2.o asin.o const_euler.o cos.o sin.o tan.o fma.o fms.o hypot.o log1p.o expm1.o log2.o log10.o ui_pow.o ui_pow_ui.o minmax.o dim.o signbit.o copysign.o setsign.o gmp_op.o init2.o acos.o sin_cos.o set_nan.o set_inf.o set_zero.o powerof2.o gamma.o set_ld.o get_ld.o cbrt.o volatile.o fits_sshort.o fits_sint.o fits_slong.o fits_ushort.o fits_uint.o fits_ulong.o fits_uintmax.o fits_intmax.o get_si.o get_ui.o zeta.o cmp_d.o erf.o inits.o inits2.o clears.o sgn.o check.o sub1sp.o version.o mpn_exp.o mpfr-gmp.o mp_clz_tab.o sum.o add1sp.o free_cache.o si_op.o cmp_ld.o set_ui_2exp.o set_si_2exp.o set_uj.o set_sj.o get_sj.o get_uj.o get_z.o iszero.o cache.o sqr.o int_ceil_log2.o isqrt.o strtofr.o pow_z.o logging.o mulders.o get_f.o round_p.o erfc.o atan2.o subnormal.o const_catalan.o root.o sec.o csc.o cot.o eint.o sech.o csch.o coth.o round_near_x.o constant.o abort_prec_max.o stack_interface.o lngamma.o zeta_ui.o set_d64.o get_d64.o jn.o yn.o rem1.o get_patches.o add_d.o sub_d.o d_sub.o mul_d.o div_d.o d_div.o li2.o rec_sqrt.o min_prec.o buildopt.o digamma.o bernoulli.o isregular.o set_flt.o get_flt.o scale2.o set_z_exp.o ai.o gammaonethird.o
libtool: link: ranlib .libs/libmpfr.a
libtool: link: ( cd ".libs" && rm -f "libmpfr.la" && ln -s "../libmpfr.la" "libmpfr.la" )
make[1]: Leaving directory `/home/admin/mpfr-3.0.0'
$
$ su
# make install
Making install in tests
make[1]: Entering directory `/home/admin/mpfr-3.0.0/tests'
make[2]: Entering directory `/home/admin/mpfr-3.0.0/tests'
make[2]: `install-exec-am' に対して行うべき事はありません。
make[2]: `install-data-am' に対して行うべき事はありません。
〜
test -z "/usr/local/share/doc/mpfr" || /bin/mkdir -p "/usr/local/share/doc/mpfr"
/bin/mkdir -p '/usr/local/share/doc/mpfr/examples'
 /bin/install -c -m 644  examples/ReadMe examples/divworst.c examples/rndo-add.c examples/sample.c examples/version.c '/usr/local/share/doc/mpfr/examples'
 /bin/install -c -m 644  AUTHORS BUGS COPYING COPYING.LESSER FAQ.html NEWS TODO '/usr/local/share/doc/mpfr/.'
make[2]: Leaving directory `/home/admin/mpfr-3.0.0'
make[1]: Leaving directory `/home/admin/mpfr-3.0.0'
#
 

準備ができたのでようやく 64bitターゲットの gcc をビルドします
簡易版の gcc となります makeコマンドも make all-gcc と制限することになります

$ tar -xjf gcc-4.5.2.tar.bz2
$ mkdir  gcc-4.5.2-amd64-build
$ cd gcc-4.5.2-amd64-build
$
$ VPATH=../gcc-4.5.2 ../gcc-4.5.2/configure --prefix=/usr/gcc/4.5.2/amd64 --target=amd64-linux-gnu --enable-languages=c --disable-shared --with-gmp --with-mpfr --with-mpc --disable-threads --disable-libssp --with-as=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-as --with-ld=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
〜
checking where to find the target windmc... pre-installed
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether -fkeep-inline-functions is supported... yes
configure: creating ./config.status
config.status: creating Makefile
$
$ make all-gcc
〜
echo timestamp > gpl.pod
perl ../../gcc-4.5.2/gcc/../contrib/texi2pod.pl ../../gcc-4.5.2/gcc/doc/include/gpl_v3.texi > gpl.pod
echo timestamp > doc/gpl.7
(pod2man --center="GNU" --release="gcc-4.5.2" --section=7 gpl.pod > doc/gpl.7.T$$ && \
        mv -f doc/gpl.7.T$$ doc/gpl.7) || \
        (rm -f doc/gpl.7.T$$ && exit 1)
rm gcc.pod
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/gcc'
$
 

configureでは ほとんどのオプションを disable指定しています
また –enable-languages も c のみとして c++ や java なども指定せず 最小限の構築とします

$ su
# make install
make[1]: Entering directory `/home/admin/gcc-4.5.2-amd64-build'
/bin/sh ../gcc-4.5.2/mkinstalldirs /usr/gcc/4.5.2/amd64 /usr/gcc/4.5.2/amd64
mkdir -p -- /usr/gcc/4.5.2/amd64 /usr/gcc/4.5.2/amd64
make[2]: Entering directory `/home/admin/gcc-4.5.2-amd64-build/fixincludes'
rm -rf /usr/gcc/4.5.2/amd64/libexec/gcc/amd64-linux-gnu/4.5.2/install-tools
〜
fi
make[3]: Entering directory `/home/admin/gcc-4.5.2-amd64-build/libiberty/testsuite'
make[3]: `install' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/libiberty/testsuite'
make[2]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/libiberty'
/bin/sh: line 0: cd: amd64-linux-gnu/libmudflap: そのようなファイルやディレクトリはありません
make[1]: *** [install-target-libmudflap] エラー 1
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
make: *** [install] エラー 2
#
 

環境によっては 下記エラーが出ることがありますがとりあえず無視します

 /bin/sh: line 0: cd: amd64-linux-gnu/libstdc++-v3: そのようなファイルやディレクトリはありません
や
 /bin/sh: line 0: cd: amd64-linux-gnu/libmudflap: そのようなファイルやディレクトリはありません
 

インストールが不完全のために途中で止まったように見えますが
後続のサブディレクトリは libiberty/testsuite ぐらいなのでとりあえず問題ないと思います

もうひとつ specs ファイルをインストールしておきます
specsとは gcc の挙動を制御するためのの設定ファイルで
gccに与えられたオプションを解釈して 別のオプションを与えるといった動作をします

gccの挙動に重要な役割をもっていながらほとんど 隠しファイル的な扱いです
現在の(32bitの)環境で gcc -v を実行すると specsの在処が分かります

$ gcc -v
/usr/gcc/4.1.2/i686/lib/gcc/i686-linux-gnu/4.1.2/specs から spec を読み込み中
Target: i686-linux-gnu
コンフィグオプション: ../gcc-4.1.2/configure --prefix=/usr/gcc/4.1.2/i686 --program-prefix=i686-linux-gnu- --host=i686-linux-gnu --target=i686-linux-gnu --build=i686-linux-gnu --enable-threads=posix --enable-nls --with-libiconv-prefix=/usr/glibc/2.5/i686 --enable-languages=c,c++,fortran,java --with-as=/usr/binutils/2.17/i686/bin/i686-linux-gnu-as --with-ld=/usr/binutils/2.17/i686/bin/i686-linux-gnu-ld --with-dwarf2 : (reconfigured) ../gcc-4.1.2/configure --prefix=/usr/gcc/4.1.2/i686 --program-prefix=i686-linux-gnu- --host=i686-linux-gnu --target=i686-linux-gnu --build=i686-linux-gnu --enable-threads=posix --enable-nls --with-libiconv-prefix=/usr/glibc/2.5/i686 --with-as=/usr/binutils/2.17/i686/bin/i686-linux-gnu-as --with-ld=/usr/binutils/2.17/i686/bin/i686-linux-gnu-ld --with-dwarf2 --enable-languages=c,c++,fortran,java --with-arch=i686
スレッドモデル: posix
gcc バージョン 4.1.2
$
 

specsの場所は かなりディレクトリの奥深い部分にあります
ちなみに 上記のコマンドを実行したときに 「build-in specs」と表示されたら
適切な場所に specsが配置されていません(デフォルトの specsの挙動となる?)

今回の amd64 クロスコンパイラも同様の場所に specsを配置します
まずは make install 直後の状態から続けて

# vi gcc/specs 
 

今回 64bit環境の specsを作る上でポイントとなる部分があります
まず *link: の部分を確認してください

 %{!m32:-m elf_x86_64} %{m32:-m elf_i386}
 

これは -m32 が与えられていれば -m elf_i386 と解釈し そうでなければ -m elf_x86_64 と解釈します
つまり gcc に -m32 と与えれば 32bit用のコード そうでなければ 64bit用のコード を生成する動作となるのです

今回 specs の設定の主なポイントは -m32 とそうでない場合の振舞いの違いをどう記述するかになります
また specs に対して主にカスタマイズする部分は 3つです

  • インクルードパス (今回 標準的な /usr/include/ にインストールしないので)
  • glibc gcc の crt(C RunTime)ディレクトリ
  • glibc のライブラリパス (libgcc.a や libgcc_eh.a など)

ここではひとまず インクルードパスを設定しておきます

77 *version:
78 4.5.2
79 
80 *multiinclude:
81 %{!D__KERNEL__:%{!m32:-isystem /usr/glibc/2.9/amd64/include -isystem /usr/gcc/4.5.2/amd64/include -isystem /usr/src/linux-2.6.36.3/include} %{m32:-m32 -isystem /usr/binutils/2.17/i686/include -isystem /usr/glibc/2.5/i686/include -isystem /usr/gcc/4.1.2/i686/include -isystem /usr/src/linux-2.6.30.5/include}}
82 
83 *multilib:
84 . !m64 !m32;64:../lib64 m64 !m32;32:../lib !m64 m32;
85 
86 *multilib_defaults:
87 m64
88 
 

上記のように *multiinclude: という項目を追加しました (名称は適当です)

-m32 の場合とそれ以外とで場合分けを行い
それぞれ 32bit用 64bit用 のディレクトリを指定しているのがポイントです

また -isystemの記述がやたら多いですが
glibc gcc カーネル のヘッダファイルディレクトリを検索パスに追加しているのです

最後に全体を %{!D__KERNEL__:} で括っています
これを省略すると 後でカーネルをビルドしたときに
下記のようなエラーメッセージが表示され カーネルのビルドがうまくいかなかったためです

  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
arch/x86/kernel/head64.o: In function `x86_64_start_reservations':
head64.c:(.init.text+0x15): relocation truncated to fit: R_X86_64_32 against symbol `boot_params' defined in .init.data section in arch/x86/built-in.o
head64.c:(.init.text+0x26): relocation truncated to fit: R_X86_64_32 against symbol `boot_command_line' defined in .init.data section in init/built-in.o
head64.c:(.init.text+0x39): relocation truncated to fit: R_X86_64_32 against symbol `__bss_stop' defined in .bss section in .tmp_vmlinux1
head64.c:(.init.text+0x43): relocation truncated to fit: R_X86_64_32 against symbol `_text' defined in .text section in .tmp_vmlinux1
head64.c:(.init.text+0x50): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
head64.c:(.init.text+0x7b): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
arch/x86/kernel/head64.o: In function `x86_64_start_kernel':
head64.c:(.init.text+0xa1): relocation truncated to fit: R_X86_64_32 against symbol `__bss_stop' defined in .bss section in .tmp_vmlinux1
head64.c:(.init.text+0xb8): relocation truncated to fit: R_X86_64_32 against symbol `__bss_start' defined in .bss section in .tmp_vmlinux1
head64.c:(.init.text+0x10d): relocation truncated to fit: R_X86_64_32 against symbol `idt_table' defined in .bss section in arch/x86/kernel/head_64.o
head64.c:(.init.text+0x169): relocation truncated to fit: R_X86_64_32 against symbol `idt_descr' defined in .data section in arch/x86/built-in.o
head64.c:(.init.text+0x17e): additional relocation overflows omitted from the output
make: *** [.tmp_vmlinux1] エラー 1
 

カーネルのビルド時 -D__KERNEL__ が使われるため
このオプションを認識して -isystem を適用しないようにしました

美しい記述とは言えませんが これで コンパイル環境と カーネルのビルドまで確認できました

では 作成した *multiinclude: を C C++ の標準オプションに追加します
*cpp_options: *cc1_options: 部分に追記します

17 *cpp:
18 %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}
19 
20 *cpp_options:
21 %(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess} %(multiinclude)
22 
23 *cpp_debug_options:
24 %{d*}

32 *cc1:
33 %(cc1_cpu) %{profile:-p}
34 
35 *cc1_options:
36 %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{a*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)}  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}}  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage} %(multiinclude)
37 
38 *cc1plus:
39 
 

それぞれ最後尾に %(multiinclude) を追記しています
これにより C C++ のコンパイル時に -isystem の設定が利用されます

上記の編集でも推測できると思いますが specsは gccにとって重要な役割を持っていて
標準ライブラリパス 標準インクルードヘッダパス さらには -lc などの標準的なオプションが定義されていることが分かります

作成した specs をインストールしておきます

# cp gcc/specs /usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/
 

glibcを本格的に構築するのに必要な libgcc.a を構築しておきます
実は libgcc_eh.a も必要なのですが glibcが構築できていないため現段階では作れません

現在の gccのビルド状況は中途半端なままですが 進めるところまで構築を進めましょう
続けて makeコマンドを実施します

# exit
$ make
〜
checking for amd64-linux-gnu-gcc... /home/admin/gcc-4.5.2-amd64-build/./gcc/xgcc -B/home/admin/gcc-4.5.2-amd64-build/./gcc/ -B/usr/gcc/4.5.2/amd64/amd64-linux-gnu/bin/ -B/usr/gcc/4.5.2/amd64/amd64-linux-gnu/lib/ -isystem /usr/gcc/4.5.2/amd64/amd64-linux-gnu/include -isystem /usr/gcc/4.5.2/amd64/amd64-linux-gnu/sys-include
checking for C compiler default output file name...
configure: error: in `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libmudflap':
configure: error: C compiler cannot create executables
See `config.log' for more details.
make[1]: *** [configure-target-libmudflap] エラー 1
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
make: *** [all] エラー 2
$
 

エラーが出て途中でビルドが停止しています
config.log によると原因は libc や crti.o crt1.o が見付からないためで
つまり ここから先に構築を進めるには glibcが必要となっています

ここでの目的である libgcc.a が出来ていればOKです

$ find . -name '*libgcc*'
./amd64-linux-gnu/32/libgcc
./amd64-linux-gnu/32/libgcc/libgcc.a
./amd64-linux-gnu/libgcc
./amd64-linux-gnu/libgcc/libgcc.a
./gcc/32/libgcc.a
./gcc/libgcc.mvars
./gcc/libgcc.a
$
 

amd64-linux-gnu/ に入っている libgcc.a と gcc/ に入っている libgcc.a は同じようです
(バイナリレベルでは 別ものみたいですが詳細は分かりませんでした)
さらに 32bit版と 64bit版があることが分かります (32というディレクトリが 32bit版)
こういうところでも 32bit版と 64bit版の構築環境の違いが感じられます

共有ライブラリ用?の libgcc_eh.a も最終的に必要となりますが
glibcの crti.o や crtn.o を先に作る必要があるため 今の段階では作成できません
また configureにも –enable-shared が必要なため 結局 gcc を後で作り直すことになります

できあがった gcc/ を一旦ビルドディレクトリ外に退避します
(今の gcc のビルドディレクトリを 後で 一旦削除するためです)
また 退避した gcc/ ディレクトリを参照できるように specsにも設定をいれます

$ cp -r gcc ../
$ su
# vi /usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/specs
 

今回 specsには crtのあるディレクトリを設定します
specsには 既に *md_startfile_prefix: *md_startfile_prefix_1: という項目があり
未使用状態なのでこれを使わせてもらいます
((注) *md_startfile_prefix: *md_startfile_prefix_1: を使うのは間違った方法かも)

119 *md_exec_prefix:
120 
121 
122 *md_startfile_prefix:
123 %{!m32:/usr/glibc/2.9/amd64/lib/}%{m32:/usr/glibc/2.5/i686/lib/}
124 
125 *md_startfile_prefix_1:
126 %{!m32:/home/admin/gcc/}%{m32:/home/admin/gcc/32/}
127 
 

やはり -m32 かそうでないかで場合分けをしているところがポイントです

今回 specsに設定を入れるのは crtを設定している *startfile: *endfile: です
ここにある 〜.o 各ファイルのパスを設定します指定します

まず *endfile: から

46 
47 *endfile:
48 %{ffast-math|funsafe-math-optimizations:%(md_startfile_prefix_1)crtfastmath.o%s}    %{mpc32:%(md_startfile_prefix_1)crtprec32.o%s}    %{mpc64:%(md_startfile_prefix_1)crtprec64.o%s}    %{mpc80:%(md_startfile_prefix_1)crtprec80.o%s}    %{shared|pie:%(md_startfile_prefix_1)crtendS.o%s;:%(md_startfile_prefix_1)crtend.o%s}  %(md_startfile_prefix)crtn.o%s
49 
 

crtfastmath.o crtprec32.o crtprec64.o crtprec80.o crtendS.o crtend.o は gccの crtなので md_startfile_prefix_1 を指定します
crtn.o は glibcの crtです md_startfile_prefix を設定しておきます

*startfile: も同様です

67 
68 *startfile:
69 %{!shared: %{pg|p|profile:%(md_startfile_prefix)gcrt1.o%s;pie:%(md_startfile_prefix)Scrt1.o%s;:%(md_startfile_prefix)crt1.o%s %(md_startfile_prefix)crti.o%s %{static:%(md_startfile_prefix_1)crtbeginT.o%s;shared|pie:%(md_startfile_prefix_1)crtbeginS.o%s;:%(md_startfile_prefix_1)crtbegin.o%s}
70 
 

crtbeginT.o crtbeginS.o crtbegin.o は gccの crtなので md_startfile_prefix_1 を指定
gcrt1.o Scrt1.o crt1.o crti.o は glibcのファイルです これも今回設定しておきます

紛らわしい作業となるのでご注意ください
glibcのパスとして本命のディレクトリを指定していますが 現段階では crtファイルはありません

これで ようやく簡易版 gcc が動くようになりました いよいよ glibcを構築していきます
念のため glibcの既存ビルドディレクトリを削除した上で再構築します

# cd
# rm -rf glibc-2.9-amd64-build
# exit
$ mkdir glibc-2.9-amd64-build
$ cd glibc-2.9-amd64-build
$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/glibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls --program-prefix=amd64-linux-gnu- --enable-stackguard-randomization
configure: WARNING: If you wanted to set the --build type, don't use --host.
    If a cross compiler is detected then cross compile mode will be used.
checking build system type... i686-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
〜
checking for autoconf... autoconf
checking whether autoconf works... yes
configure: error:
*** These critical programs are missing or too old: as ld
*** Check the INSTALL file for required versions.
$
 

いきなり エラーが出て止まってしまいました
これは binutilsのバージョンが新し過ぎるために 許容バージョンとしてチェックされなかったものです

configure スクリプトを編集して回避することにします

$ vi ../glibc-2.9/configure
 

下記の部分に追加行を作って回避するようにします

4532   case $ac_prog_version in
4533     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
4534     2.1[3-9]*)
4535        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
4536     2.2[0-9]*)
4537        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
4538     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
〜
4597   case $ac_prog_version in
4598     '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
4599     2.1[3-9]*)
4600        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
4601     2.2[0-9]*)
4602        ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
4603     *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
 

追加行は 4535〜4536行目 4601〜4602行目 です
これで binutils-2.21 が許容範囲になります (強引ですね)

$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd6-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutls/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/gibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls -program-prefix=amd64-linux-gnu- --enable-stackguard-randomization
〜
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for long double... yes
checking size of long double... configure: error: cannot compute sizeof (long double)
See `config.log' for more details.
$
 

また エラーが出ました
原因は configure の中で検証されるテストプログラムがコンパイルに失敗したためです

glibcの構築に実害はないはずなので
configure スクリプトに ac_cv_sizeof_long_double=yes を渡すことで回避します

$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd6-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutls/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/gibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls -program-prefix=amd64-linux-gnu- --enable-stackguard-randomization ac_cv_sizeof_ong_double=yes
〜
checking size of long double... (cached) yes
running configure fragment for sysdeps/x86_64/elf
checking for x86-64 TLS support... yes
running configure fragment for nptl/sysdeps/pthread
checking for forced unwind support... no
configure: error: forced unwind support is required
$
 

次は unwind関連ですか libc_cv_forced_unwind=yes を渡して回避するようにします

$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd6-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutls/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/gibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls -program-prefix=amd64-linux-gnu- --enable-stackguard-randomization ac_cv_sizeof_ong_double=yes libc_cv_forced_unwind=yes
〜
checking size of long double... (cached) yes
running configure fragment for sysdeps/x86_64/elf
checking for x86-64 TLS support... yes
running configure fragment for nptl/sysdeps/pthread
checking for forced unwind support... (cached) yes
checking for C cleanup handling... no
configure: error: the compiler must support C cleanup handling
$
 

続けざまに引っかかっています
これも テストプログラムのコンパイルテストに失敗しただけで 特に何か不足しているとかないはずです
このテスト項目も libc_cv_c_cleanup=yes を渡して回避します

$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd6-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutls/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/gibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls -program-prefix=amd64-linux-gnu- --enable-stackguard-randomization ac_cv_sizeof_ong_double=yes libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes
〜
checking if -g produces usable source locations for assembler-with-cpp... yes
checking for old glibc 2.0.x headers... no
checking whether -fPIC is default... no
configure: creating ./config.status
config.status: creating config.make
config.status: creating Makefile
config.status: creating config.h
config.status: executing default commands
$
 

configureはとりあえず パスさせました

ちなみに 次のエラーメッセージが出た場合
checking for .preinit_array/.init_array/.fini_array support… no
configure: error: Need linker with .init_array/.fini_array support.
glibcの 標準スタートアップライブラリが認識されていないのが原因と思います
configure上で このチェックを迂回するには libc_cv_initfini_array=yes を指定します

いよいよ glibcのビルドです

$ make
〜
/bin/sh scripts/move-if-change /home/admin/glibc-2.9-amd64-build/gnu/lib-names.T /home/admin/glibc-2.9-amd64-build/gnu/lib-names.h
touch /home/admin/glibc-2.9-amd64-build/gnu/lib-names.stmp
/bin/install -c -m 644 include/limits.h /usr/glibc/2.9/amd64/include/limits.h
/bin/install: cannot remove `/usr/glibc/2.9/amd64/include/limits.h': 許可がありません
make[1]: *** [/usr/glibc/2.9/amd64/include/limits.h] エラー 1
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
$
 

エラーが出ました やはり強引な configure が問題だったかな
と思ったら原因は違っていました

最初に構築した make install-headers によるヘッダファイルを置き換えようとしていたようです
root権限がないためファイルの上書きができずエラーになったようです

古いファイルは make install時に消せばよくて 今消す必要はありません
configureに –disable-force-install オプションを追加して make 時の余計なインストール動作を抑制します

$ VPATH=../glibc-2.9 AR=/usr/binutils/2.21/amd64/bin/amd6-linux-gnu-ar CC=/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc RANLIB=/usr/binutls/2.21/amd64/bin/amd64-linux-gnu-ranlib ../glibc-2.9/configure --prefix=/usr/gibc/2.9/amd64  --host=amd64-linux-gnu --enable-add-ons=nptl,libidn --with-tls -program-prefix=amd64-linux-gnu- --enable-stackguard-randomization ac_cv_sizeof_ong_double=yes libc_cv_forced_unwind=yes libc_cv_c_cleanup=yes --disable-force-nstall
〜
checking whether -fPIC is default... no
configure: creating ./config.status
config.status: creating config.make
config.status: creating Makefile
config.status: creating config.h
config.status: config.h is unchanged
config.status: executing default commands
$ make
〜
a - elf/dl-profstub.os
a - elf/dl-libc.os
a - elf/dl-sym.os
a - elf/dl-tsd.os
a - elf/dl-vdso.os
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ranlib /home/admin/glibc-2.9-amd64-build/libc_pic.a
/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc   -nostdlib -nostartfiles -r -o /home/admin/glibc-2.9-amd64-build/elf/librtld.map.o '-Wl,-(' /home/admin/glibc-2.9-amd64-build/elf/dl-allobjs.os /home/admin/glibc-2.9-amd64-build/libc_pic.a -lgcc '-Wl,-)' -Wl,-Map,/home/admin/glibc-2.9-amd64-build/elf/librtld.mapT
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc
collect2: ld はステータス 1 で終了しました
make[2]: *** [/home/admin/glibc-2.9-amd64-build/elf/librtld.map] エラー 1
make[2]: Leaving directory `/home/admin/glibc-2.9/elf'
make[1]: *** [elf/subdir_lib] エラー 2
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
$
 

今度はかなり いいところまで進行しました けどエラーが出ました

-lgcc で libgcc.a が見付からず失敗しています
先ほど構築した libgcc.a は暫定のディレクトリにあるので これを glibcに伝える必要があります

ここは仕方ないので glibcの ソース Makefile内で強引にライブラリパスを指定して対応します

$ vi ../glibc-2.9/elf/Makefile
 
263 $(objpfx)librtld.map: $(objpfx)dl-allobjs.os $(common-objpfx)libc_pic.a
264         @-rm -f $@T
265         $(reloc-link) -o $@.o '-Wl,-(' $^ -lgcc -L/home/admin/gcc '-Wl,-)' -Wl,-Map,$@T
266         rm -f $@.o
267         mv -f $@T $@

292
293 $(objpfx)librtld.os: $(objpfx)dl-allobjs.os $(objpfx)rtld-libc.a
294         $(LINK.o) -nostdlib -nostartfiles -r -o $@ '-Wl,-(' $^ -lgcc -L/home/admin/gcc '-Wl,-)' \
295                   -Wl,-Map,$@.map
296
 

2箇所 -lgcc の直後に暫定 -L/home/admin/gcc を指定します

make を続行しますが もし次のようなエラーが出た場合

../sysdeps/unix/sysv/linux/accept.S:5:20: fatal error: socket.S: そのようなファ>イルやディレクトリはありません
コンパイルが中断されました。
 

glibc-2.9/sysdeps/unix/sysv/linux/x86_64/ には socket.S が提供されていないのが原因です
この場合 空の socket.S を用意してごまかしましょう

$ touch ../glibc-2.9/sysdeps/unix/sysv/linux/x86_64/socket.S
 

上記のエラーは環境によって出ないかもしれません
ともかく make を続行します

$ make
〜
/home/admin/glibc-2.9-amd64-build/elf/librtld.os: In function `_dl_start_final':
/home/admin/glibc-2.9/elf/rtld.c:294: undefined reference to `_begin'
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: /home/admin/glibc-2.9-amd64-build/elf/librtld.os: relocation R_X86_64_PC32 against undefined hidden symbol `_begin' can not be used when making a shared object
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: final link failed: Bad value
collect2: ld はステータス 1 で終了しました
make[2]: *** [/home/admin/glibc-2.9-amd64-build/elf/ld.so] エラー 1
make[2]: Leaving directory `/home/admin/glibc-2.9/elf'
make[1]: *** [elf/subdir_lib] エラー 2
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
 

やはり ここまで来ると いろいろ不都合が積もってきているのでしょうか…
謎なセリフを吐いてビルドが停止する現象が多発します

原因は ソースの不具合なのか結局分かりませんでしたが 解決策を発見しました

$ vi ../glibc-2.9/elf/Makefile
 

307行目を変更します

(変更前) -e 's/\. = 0 + SIZEOF_HEADERS;/& _begin = . - SIZEOF_H    EADERS;/' \
(変更後) -e 's/\. = .* + SIZEOF_HEADERS;/& _begin = . - SIZEOF_H    EADERS;/' \
 

気をとりなおしてビルドを続けます

$ make
/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc   -shared -static-libgcc -Wl,-O1  -Wl,-z,defs -Wl,-dynamic-linker=/usr/glibc/2.9/amd64/lib/ld-linux-x86-64.so.2  -B/home/admin/glibc-2.9-amd64-build/csu/  -Wl,--version-script=/home/admin/glibc-2.9-amd64-build/libc.map -Wl,-soname=libc.so.6 -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -nostdlib -nostartfiles -e __libc_main -L/home/admin/glibc-2.9-amd64-build -L/home/admin/glibc-2.9-amd64-build/math -L/home/admin/glibc-2.9-amd64-build/elf -L/home/admin/glibc-2.9-amd64-build/dlfcn -L/home/admin/glibc-2.9-amd64-build/nss -L/home/admin/glibc-2.9-amd64-build/nis -L/home/admin/glibc-2.9-amd64-build/rt -L/home/admin/glibc-2.9-amd64-build/resolv -L/home/admin/glibc-2.9-amd64-build/crypt -L/home/admin/glibc-2.9-amd64-build/nptl -Wl,-rpath-link=/home/admin/glibc-2.9-amd64-build:/home/admin/glibc-2.9-amd64-build/math:/home/admin/glibc-2.9-amd64-build/elf:/home/admin/glibc-2.9-amd64-build/dlfcn:/home/admin/glibc-2.9-amd64-build/nss:/home/admin/glibc-2.9-amd64-build/nis:/home/admin/glibc-2.9-amd64-build/rt:/home/admin/glibc-2.9-amd64-build/resolv:/home/admin/glibc-2.9-amd64-build/crypt:/home/admin/glibc-2.9-amd64-build/nptl -o /home/admin/glibc-2.9-amd64-build/libc.so -T /home/admin/glibc-2.9-amd64-build/shlib.lds /home/admin/glibc-2.9-amd64-build/csu/abi-note.o /home/admin/glibc-2.9-amd64-build/elf/soinit.os /home/admin/glibc-2.9-amd64-build/libc_pic.os /home/admin/glibc-2.9-amd64-build/elf/sofini.os /home/admin/glibc-2.9-amd64-build/elf/interp.os /home/admin/glibc-2.9-amd64-build/elf/ld.so -lgcc
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc
collect2: ld はステータス 1 で終了しました
make[1]: *** [/home/admin/glibc-2.9-amd64-build/libc.so] エラー 1
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
$
 

また -lgcc で失敗と出ています
対処療法的に対応していくしかありません

$ vi ../glibc-2.9/Makeconfig
 

下記の部分に修正を加えました -L/home/admin/gcc を追記しています 534行目です

532 gnulib := -lgcc $(libgcc_eh)
533 static-gnulib := -lgcc -lgcc_eh $(libunwind)
534 libc.so-gnulib := -lgcc -L/home/admin/gcc
535 endif
 

ひたすら make します

$ make
〜
/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc -nostdlib -nostartfiles -o /home/admin/glibc-2.9-amd64-build/iconv/iconvconfig  -Wl,-dynamic-linker=/usr/glibc/2.9/amd64/lib/ld-linux-x86-64.so.2   -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both /home/admin/glibc-2.9-amd64-build/csu/crt1.o /home/admin/glibc-2.9-amd64-build/csu/crti.o `/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc --print-file-name=crtbegin.o` /home/admin/glibc-2.9-amd64-build/iconv/iconvconfig.o /home/admin/glibc-2.9-amd64-build/iconv/strtab.o /home/admin/glibc-2.9-amd64-build/iconv/xmalloc.o /home/admin/glibc-2.9-amd64-build/iconv/hash-string.o  -Wl,-rpath-link=/home/admin/glibc-2.9-amd64-build:/home/admin/glibc-2.9-amd64-build/math:/home/admin/glibc-2.9-amd64-build/elf:/home/admin/glibc-2.9-amd64-build/dlfcn:/home/admin/glibc-2.9-amd64-build/nss:/home/admin/glibc-2.9-amd64-build/nis:/home/admin/glibc-2.9-amd64-build/rt:/home/admin/glibc-2.9-amd64-build/resolv:/home/admin/glibc-2.9-amd64-build/crypt:/home/admin/glibc-2.9-amd64-build/nptl /home/admin/glibc-2.9-amd64-build/libc.so.6 /home/admin/glibc-2.9-amd64-build/libc_nonshared.a -lgcc -lgcc_eh  `/usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc --print-file-name=crtend.o` /home/admin/glibc-2.9-amd64-build/csu/crtn.o
amd64-linux-gnu-gcc: crtbegin.o: そのようなファイルやディレクトリはありません
amd64-linux-gnu-gcc: crtend.o: そのようなファイルやディレクトリはありません
make[2]: *** [/home/admin/glibc-2.9-amd64-build/iconv/iconvconfig] エラー 1
make[2]: Leaving directory `/home/admin/glibc-2.9/iconv'
make[1]: *** [iconv/others] エラー 2
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
$
 

specsにわざわざ設定した crtbegin.o crtend.o のフルパス指定が無視されていますね
原因は 先ほどの Makeconfigファイルにありした

$ vi ../glibc-2.9/Makeconfig
 

crtbegin.o のパスを gcc –print-file-name=crtbegin.o コマンドで検索している箇所があります
このコマンドは crtbegin.o などのファイルが適切にインストールされてないと正しいパスを回答しません
つまり今回のエラーは オブジェクトを ~/gcc/ 内に暫定配置しているために発生したことになります

+prector と +postctor を直接修正します

(修正前)
+prector = `$(CC) --print-file-name=crtbegin.o`
+postctor = `$(CC) --print-file-name=crtend.o`
(修正後)
+prector = /home/admin/gcc/crtbegin.o
+postctor = /home/admin/gcc/crtend.o
 

さらに make を続けます

$ make
〜
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc_eh
collect2: ld はステータス 1 で終了しました
make[2]: *** [/home/admin/glibc-2.9-amd64-build/iconv/iconvconfig] エラー 1
make[2]: Leaving directory `/home/admin/glibc-2.9/iconv'
make[1]: *** [iconv/others] エラー 2
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
$
 

ここから先は libgcc_eh.a が必要となります ただし

$ ls *.so *.a
libc.a  libc.so  libc_nonshared.a  libc_pic.a
$ find . -name '*crt*.o'
./wcsmbs/wcrtomb.o
./signal/allocrtsig.o
./csu/gcrt1.o
./csu/Mcrt1.o
./csu/crtn.o
./csu/crti.o
./csu/Scrt1.o
./csu/crt1.o
./nptl/crtn.o
./nptl/crti.o
./debug/wcrtomb_chk.o
$
 

上記のように crti.o crtn.o libc.a libc.soが作成されているので
これを使って 共有ライブラリ版 gcc の構築を進めることができます

csu/ にある オブジェクトだけ先に手動インストールしておきます

$ su
# mkdir /usr/glibc/2.9/amd64/lib
# cp *.so /usr/glibc/2.9/amd64/lib/
# cp *.a /usr/glibc/2.9/amd64/lib/
# cp csu/*crt*.o /usr/glibc/2.9/amd64/lib/
# cp elf/ld.so /usr/glibc/2.9/amd64/lib/
# ln -s ld.so /usr/glibc/2.9/amd64/lib/ld-linux-x86-64.so.2
# exit
$ cd ..
 

一旦 glibcの構築を中断して gccのビルドに移りましょう
次の gcc構築の目的は libgcc_eh です

$ rm -rf gcc-4.5.2-amd64-build
$ mkdir gcc-4.5.2-amd64-build
$ cd gcc-4.5.2-amd64-build
$ VPATH=../gcc-4.5.2 ../gcc-4.5.2/configure --prefix=/usr/gcc/4.5.2/amd64 --target=amd64-linux-gnu --enable-languages=c,c++,java --enable-shared --with-gmp --with-mpfr --with-mpc --enable-threads=posix --enable-libssp --enable-nls --with-as=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-as --with-ld=/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
checking whether ln works... yes
〜
checking where to find the target strip... pre-installed
checking where to find the target windres... pre-installed
checking where to find the target windmc... pre-installed
checking whether to enable maintainer-specific portions of Makefiles... no
checking whether -fkeep-inline-functions is supported... yes
configure: creating ./config.status
config.status: creating Makefile
$
 

今度は configureの指定は 本命の設定です
ほとんどのオプションを有効化し –enable-languagesも c,c++,java を指定しています

ただし fortran はビルド途中でエラーが出て回避できなかったため今回はビルドをあきらめました
(64bit環境での問題?)

$ make
〜
../../../../gcc-4.5.2/libgcc/config/libbid/bid_decimal_globals.c:47:18: fatal error: fenv.h: そのようなファイルやディレクトリはありません
コンパイルが中断されました。 
make[4]: *** [bid_decimal_globals.o] エラー 1 
make[4]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/32/libgcc'
make[3]: *** [multi-do] エラー 1 
make[3]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgcc'
make[2]: *** [all-multi] エラー 2 
make[2]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgcc'
make[1]: *** [all-target-libgcc] エラー 2 
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
make: *** [all] エラー 2 
$
 

上記のエラーは glibc の fenv.hが見付からないエラーです
gccのビルドディレクトリから作りなおしているので 再度 specs の設定が必要です

$ vi gcc/specs
 

先ほどと同じく
*multiinclude: を追加して
*cpp_options: *cc1_options: に %(multiinclude) を追記するのと

*md_startfile_prefix: を設定して glibc系の crtパスを設定します

19 
20 *cpp_options:
21 %(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess} %(multiinclude)
22 

34 
35 *cc1_options:
36 %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{a*} %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)}  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}}  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{--help=*:--help=%(VALUE)} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage} %(multiinclude)
37 

46 
47 *endfile:
48 %{ffast-math|funsafe-math-optimizations:%(md_startfile_prefix_1)crtfastmath.o%s}    %{mpc32:%(md_startfile_prefix_1)crtprec32.o%s}    %{mpc64:%(md_startfile_prefix_1)crtprec64.o%s}    %{mpc80:%(md_startfile_prefix_1)crtprec80.o%s}    %{shared|pie:%(md_startfile_prefix_1)crtendS.o%s;:%(md_startfile_prefix_1)crtend.o%s} %(md_startfile_prefix)crtn.o%s
49
50 *link:
51 %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64 -L/usr/glibc/2.9/amd64/lib} %{m32:-m elf_i386 -L/usr/glibc/2.5/i686/lib}   %{shared:-shared}   %{!shared:     %{!static:       %{rdynamic:-export-dynamic}       %{m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and -muclibc used together}/lib/ld-uClibc.so.0;:/lib/ld-linux.so.2}}}       %{!m32:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mglibc and -muclibc used together}/lib/ld64-uClibc.so.0;:/lib64/ld-linux-x86-64.so.2}}}}     %{static:-static}}
52

67 
68 *startfile:
69 %{!shared: %{pg|p|profile:%(md_startfile_prefix)gcrt1.o%s;pie:%(md_startfile_prefix)Scrt1.o%s;:%(md_startfile_prefix)crt1.o%s}}    %(md_startfile_prefix)crti.o%s %{static:%(md_startfile_prefix_1)crtbeginT.o%s;shared|pie:%(md_startfile_prefix_1)crtbeginS.o%s;:%(md_startfile_prefix_1)crtbegin.o%s}
70 

79 
80 *multiinclude:
81 %{!D__KERNEL__:%{!m32:-isystem /usr/glibc/2.9/amd64/include -isystem /usr/gcc/4.5.2/amd64/include -isystem /usr/src/linux-2.6.36.3/include} %{m32:-m32 -isystem /usr/binutils/2.17/i686/include -isystem /usr/glibc/2.5/i686/include -isystem /usr/gcc/4.1.2/i686/include -isystem /usr/src/linux-2.6.30.5/include}}
82 

121 
122 *md_startfile_prefix:
123 %{!m32:/usr/glibc/2.9/amd64/lib/}%{m32:/usr/glibc/2.5/i686/lib/}
124 
125 *md_startfile_prefix_1:
126 %{!m32:/home/admin/gcc/}%{m32:/home/admin/gcc/32/}
127 
 

新しく設定した箇所は *link: 部分で
-m32 かそうでないか で glibcのライブラリパスを設定しています
これで -lc による libc.a がちゃんと見付かるように specsに教えているのです

参考情報ですが 今回の specsは –enable-shared を指定したことにより
*libgcc: 部分が変化していました

 %{static|static-libgcc:-lgcc -lgcc_eh}%{!static:%{!static-libgcc:%{!shared-libgcc:-lgcc --as-needed -lgcc_s --no-as-needed}%{shared-libgcc:-lgcc_s%{!shared: -lgcc}}}}
 

–disable-shared の時は -lgcc のみでしたが
libgcc_eh libgcc_s を使い分けるような記述が見られます

さて 本題に戻ってビルドを続けます

$ make
〜
checking for C compiler default output file name...
configure: error: in `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp':
configure: error: C compiler cannot create executables
See `config.log' for more details.
make[1]: *** [configure-target-libgomp] エラー 1
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
make: *** [all] エラー 2
$
 

いいところまで進みました ログ amd64-linux-gnu/libgomp/config.log を見ると
__libc_csu_fini や __libc_csu_init のシンボルが見付からないエラーとなっています

ちなみに 上記シンボルがどのオブジェクトで提供されているか確認すると

$ amd64-linux-gnu-nm /usr/glibc/2.9/amd64/lib/libc.a | grep libc_csu
0000000000000090 T __libc_csu_fini
0000000000000000 T __libc_csu_init
$ amd64-linux-gnu-nm /usr/glibc/2.9/amd64/lib/libc.so | grep libc_csu
$
 

スタティックライブラリ版 libc.a には含まれるが
共有ライブラリ版 libc には含まれていません

いずれにしても glibcを構築進める必要があります
とりあえずここまで作れた ライブラリを確認しましょう

$ find . -name '*libgcc*'
./amd64-linux-gnu/32/libgcc
./amd64-linux-gnu/32/libgcc/32/libgcc_s.so
./amd64-linux-gnu/32/libgcc/32/libgcc_s.so.1
./amd64-linux-gnu/32/libgcc/libgcc.map
./amd64-linux-gnu/32/libgcc/libgcc_eh.a
./amd64-linux-gnu/32/libgcc/libgcc.a
./amd64-linux-gnu/libgcc
./amd64-linux-gnu/libgcc/libgcc_s.so
./amd64-linux-gnu/libgcc/libgcc_s.so.1
./amd64-linux-gnu/libgcc/libgcc.map
./amd64-linux-gnu/libgcc/libgcc_eh.a
./amd64-linux-gnu/libgcc/libgcc.a
./gcc/libgcc_s.so
./gcc/libgcc_s.so.1
./gcc/32/libgcc_s.so
./gcc/32/libgcc_s.so.1
./gcc/32/libgcc_eh.a
./gcc/32/libgcc.a
./gcc/libgcc.mvars
./gcc/libgcc_eh.a
./gcc/libgcc.a
$
 

いい感じで増えてます 目的である libgcc_eh.a も作られています

これらライブラリを 暫定場所に退避しておきましょう

$ rm -rf ../gcc
$ cp -r gcc ../
$
 

specsファイルも インストールディレクトリの方に反映します

$ su
# cp gcc/specs /usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/
# exit
$ 
 

gccのライブラリもだいぶ揃って来ました
ここで再び glibcの構築に戻ります

先ほどエラーで glibcの構築を止めた原因の libgcc_eh.a も作成されています
glibcのビルドを継続するために libgcc_eh.a の場所を glibcに教えてあげる必要あります

$ cd ../glibc-2.9-amd64-build
$ vi ../glibc-2.9/Makeconfig
 

暫定ディレクトリを指定します 426行目 439行目 に -L/home/admin/gcc を追記します

424 # Command for linking programs with the C library.
425 ifndef +link
426 +link = $(CC) -nostdlib -nostartfiles -L/home/admin/gcc -o $@ \
427               $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)    ) \           $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \
429               $(addprefix $(csu-objpfx),$(start-installed-name)) \
430               $(+preinit) $(+prector) \
431               $(filter-out $(addprefix $(csu-objpfx),start.o \
432                                                      $(start-installed-name)    )\                         $(+preinit) $(link-extra-libs) \
434                            $(common-objpfx)libc% $(+postinit),$^) \
435               $(link-extra-libs) $(link-libc) $(+postctor) $(+postinit)
436 endif
437 # Command for statically linking programs with the C library.
438 ifndef +link-static
439 +link-static = $(CC) -nostdlib -nostartfiles -static -L/home/admin/gcc -o $@ \            $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
441               $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
442               $(+preinit) $(+prector) \
443               $(filter-out $(addprefix $(csu-objpfx),start.o \
444                                                      $(start-installed-name)    )\                         $(+preinit) $(link-extra-libs-static) \
446                            $(common-objpfx)libc% $(+postinit),$^) \
447               $(link-extra-libs-static) $(link-libc-static) $(+postctor) $(+    postinit)
 

glibcの構築を継続します

$ make
〜
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc_eh
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc
/usr/binutils/2.21/amd64/bin/amd64-linux-gnu-ld: cannot find -lgcc_eh
collect2: ld はステータス 1 で終了しました
make[2]: *** [/home/admin/glibc-2.9-amd64-build/locale/libBrokenLocale.so] エラ
ー 1
make[2]: Leaving directory `/home/admin/glibc-2.9/locale'
make[1]: *** [locale/others] エラー 2
make[1]: Leaving directory `/home/admin/glibc-2.9'
make: *** [all] エラー 2
 

またもや libgcc.a と libgcc_eh.a が見付からないエラーです
ともかくビルドを継続させるために 必要な箇所に暫定 gccライブラリパスを指定していきます

$ ../glibc-2.9/Makeconfig
 

LDFLAGSに -L/home/admin/gcc を設定します

410
411 relro-LDFLAGS = -Wl,-z,relro
412 LDFLAGS.so += $(relro-LDFLAGS) -L/home/admin/gcc
413 LDFLAGS-rtld += $(relro-LDFLAGS)
414
 

そして再び make

$ make
〜
make[2]: Leaving directory `/home/admin/glibc-2.9/elf'
make[1]: Leaving directory `/home/admin/glibc-2.9'
$
 

おお ついにー glibcのビルドが通ったぞー
喜びもひとしおです

早速インストールしますが 現在のディレクトリは一旦削除します

$ su
# rm -rf /usr/glibc/2.9/amd64
# make install
LANGUAGE=C LC_ALL=C; export LANGUAGE LC_ALL; \
make -r PARALLELMFLAGS="" CVSOPTS="" -C ../glibc-2.9 objdir=`pwd` install
make[1]: Entering directory `/home/admin/glibc-2.9'
./scripts/mkinstalldirs /usr/glibc/2.9/amd64/include
mkdir /usr/glibc/2.9/amd64
mkdir /usr/glibc/2.9/amd64/include
〜
if test -r /usr/glibc/2.9/amd64/include/gnu/stubs-64.h && cmp -s /home/admin/glibc-2.9-amd64-build/stubs.h /usr/glibc/2.9/amd64/include/gnu/stubs-64.h; \
then echo 'stubs.h unchanged'; \
else /bin/install -c -m 644 /home/admin/glibc-2.9-amd64-build/stubs.h /usr/glibc/2.9/amd64/include/gnu/stubs-64.h; fi
rm -f /home/admin/glibc-2.9-amd64-build/stubs.h
make[1]: Leaving directory `/home/admin/glibc-2.9'
#
# exit
$
 

ちなみに 32bit版と異なり 64bit用のライブラリディレクトリ /lib64/ が出来てます

$ ls -l /lib64/
-rwxr-xr-x  1 root root 783038  1月 27 01:19 ld-2.9.so
lrwxrwxrwx  1 root root      9  1月 27 01:20 ld-linux-x86-64.so.2 -> ld-2.9.so
$
 

つまり 64bit環境は 既存の 32bitライブラリと 64bitライブラリを 別ディレクトリに格納する設計です
(64bit環境では 32bitバイナリも実行できるための配慮か? おそらく)

ともかく glibcが完成したので gccもすぐに完成するでしょう
gccの構築を継続します

$ cd ../gcc-4.5.2-amd64-build
$ make
〜
true  DO=all multi-do # make
make[8]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/32/libgomp'
make[7]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/32/libgomp'
make[6]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/32/libgomp'
make[5]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[4]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[3]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[2]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
$
 

gccも構築できました
specsに設定している 暫定 gccパス(md_startfile_prefix_1)を削除します

$ vi gcc/specs
 

*endfile: *startfile: を修正し *md_startfile_prefix_1: の設定も空にします

46 
47 *endfile:
48 %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}    %{mpc32:crtprec32.o%s}    %{mpc64:crtprec64.o%s}    %{mpc80:crtprec80.o%s}    %{shared|pie:crtendS.o%s;:crtend.o%s} %(md_startfile_prefix)crtn.o%s
49 

67 
68 *startfile:
69 %{!shared: %{pg|p|profile:%(md_startfile_prefix)gcrt1.o%s;pie:%(md_startfile_prefix)Scrt1.o%s;:%(md_startfile_prefix)crt1.o%s}}    %(md_startfile_prefix)crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}
70 

124 
125 *md_startfile_prefix_1:
126 
127 
 

gccも 一旦現在のディレクトリを削除して正式にインストールします

$ su
# rm -rf /usr/gcc/4.5.2/amd64
# make install
〜
ldconfig: /usr/gcc/4.5.2/amd64/amd64-linux-gnu/lib/../lib64/libstdc++.so.6.0.14-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

----------------------------------------------------------------------
Libraries have been installed in:
   /usr/gcc/4.5.2/amd64/amd64-linux-gnu/lib/../lib64

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
test -z "/usr/gcc/4.5.2/amd64/share/info" || /bin/mkdir -p "/usr/gcc/4.5.2/amd64/share/info"
 /bin/install -c -m 644 ./libgomp.info '/usr/gcc/4.5.2/amd64/share/info'
 install-info --info-dir='/usr/gcc/4.5.2/amd64/share/info' '/usr/gcc/4.5.2/amd64/share/info/libgomp.info'
test -z "/usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/finclude" || /bin/mkdir -p "/usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/finclude"
test -z "/usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/include" || /bin/mkdir -p "/usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/include"
 /bin/install -c -m 644 omp.h '/usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/include'
make[4]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[3]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[2]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build/amd64-linux-gnu/libgomp'
make[1]: Leaving directory `/home/admin/gcc-4.5.2-amd64-build'
#
# cp gcc/specs /usr/gcc/4.5.2/amd64/lib/gcc/amd64-linux-gnu/4.5.2/
# exit
$ cd
$
 

かなり複雑な手順でしたが 64bitクロスコンパイル環境ができました
ここで テストとして Hello World プログラムをコンパイルしてみます

$ vi hello.c
 
#include <stdio.h>

int main ()
{
        printf ( "Hello World!\n" );
        return ( 0 );
}
 

32bit版 と 64bit版 のバイナリが作れることを確認します

$ /usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc -m32 -o hello32 hello.c
$ /usr/gcc/4.5.2/amd64/bin/amd64-linux-gnu-gcc -o hello64 hello.c
$
$ ./hello32
Hello World!
$ ./hello64
bash: ./hello64: cannot execute binary file
$ file hello*
hello.c: ASCII C program text
hello32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, dynamically linked (uses shared libs), not stripped
hello64: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.4.0, dynamically linked (uses shared libs), not stripped
$ ls -l hello*
-rw-r--r--  1 admin users   82  2月  2 12:02 hello.c
-rwxr-xr-x  1 admin users 7751  2月  2 12:03 hello32
-rwxr-xr-x  1 admin users 9884  2月  2 12:03 hello64
$
 

一応大丈夫でした 上記の確認ポイントは

  • 32bit環境で 64bitバイナリが実行できないこと
  • アーキテクチャが 32bit 64bit 正しく表示されること
  • バイナリファイルのサイズが 数Kバイトであること

特に最後の ファイルサイズですが 数Mバイト以上ある場合
スタティックリンク版のバイナリになっていて gcc もしくは glibc の構築が間違っている可能性が高いです

所々強引な手作業を入れたり かなり複雑な手順となりましたが
ようやくクロスコンパイル環境が作れました

32bit Linux上で 64bit版 Linuxカーネルをコンパイルする

ターゲット環境のマシンの電源が落ちたまま 数週間…経ってしまいました
(早く PhenomII のマシンで遊びたい…)
stage3 まで入っているので あとは カーネルと カーネルモジュールを入れればいいだけです

クロスコンパイル環境がやっと整ったので (その動作確認を兼ねて) 早速 カーネルをビルドしましょう

再度 32bit移行元のマシンで作業を続けます
カーネルのソースは先ほどの章で展開済で /usr/src/linux-2.6.36.3/ にあります

$ /usr/src/linux-2.6.36.3
$ make ARCH=x86_64 menuconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/docproc
  HOSTCC  scripts/basic/hash
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/kxgettext.o
〜
 

ARCH=x86_64 の指定は必須です
結果下記のような カーネルのコンフィグが出ます
linuxカーネルコンフィグ01
もしくは Xを使っている場合は ARCH=x86_64 make xconfig で GUIのコンフィグ画面が使えます

今回 ハードウェアが PhenomII CPUと マザーボードが GA-880GM-USB3 を意識して
設定ポイントは次のとおりです
linuxカーネルコンフィグ General Setup 1
まず General Setupですが
クロスコンパイルなので Cross-compiler tool prefix を amd64-linux-gnu- と指定します
この指定により amd64-linux-gnu-gcc が利用されます

あと SWAPを使わない方針としたので Support for paging of anonymous memory のチェックを外します
linuxカーネルコンフィグ Processor 1
Processor type and features で AMD CPU系の設定を入れます
Processor family は K8 を選択しました (PhenomIIは 正確には K10ですが選択肢がない)
linuxカーネルコンフィグ Bus options
Bus options では PCI Express support を有効にします
linuxカーネルコンフィグ Executable file formats
IA32 Emulation を有効にすれば 32bitバイナリも実行できそうです
linuxカーネルコンフィグ Device Drivers / SATA and PATA
Device Drivers の中の Serial ATA and Parallel ATA drivers です
SATAを使えるように設定します
linuxカーネルコンフィグ Device Drivers / Network device support
Device Drivers の中の Network device support です
ここだけは 後で再設定します NICのドライバがまだ収録されていないのです
linuxカーネルコンフィグ Device Drivers / Graphics support
Device Drivers の中の Graphics support です
ほとんど未設定です Xクライアントを動かす予定がないためです
Radeon HD 4250 相当のため Xを動かす場合 AMDから X用のドライバを入手する必要あります
linuxカーネルコンフィグ Device Drivers / Sound card support 1
Device Drivers の中の Sound card support です
ALSAを選択して さらにデバイスを指定する必要あります
linuxカーネルコンフィグ Device Drivers / Sound card support 2
さらにその中の PCI sound devices から Intel HD Audio を選択
Realtek の項目を選択します
linuxカーネルコンフィグ Device Drivers / USB support
Device Drivers の中の USB support です
USB3を持っているため USB3.0の項目を選択しておきます
linuxカーネルコンフィグ Device Drivers / Xen driver supoort
Device Drivers の中の Xen driver support です
Xenを使って 仮想環境をそのうち構築したいなぁとか考えているので
それっぽいデバイスを選択してみました
linuxカーネルコンフィグ File systems 1
File systems です
まず ターゲットマシンを ext3 で初期化しているため Ext3 は必須です
後は 用途に応じて必要なファイルシステムを選択します
linuxカーネルコンフィグ File systems 2
File systems の中の Miscellaneous filesystems です
Freebsdのパーティションがあるので UFSを選択しておきます
linuxカーネルコンフィグ File systems 3
File systems の中の Network File Systems です
あると便利な NFSと リモートWindowsのマウントもしたいので CIFSも選択しています
linuxカーネルコンフィグ File systems 4
File systems の中の Partition Types です
UFSを選択しただけでは足りず スライスを認識するために BSD disklabel が必要です
linuxカーネルコンフィグ File systems 5
File systems の中の Native language support です
今回から UFS8 をデフォルトとし UFS8ベースのシステムを構築したいと思ってます
今まで EUC-JPで記録した日本語ファイルがことごとくファイル名が文字化けするので
ファイル名の変換も必要になると思います (大変そう)
linuxカーネルコンフィグ Virtualization
Virtualization の状況です
仮想化を構築したいと考えているため オプションを設定しています
まず Xenを使う予定なので KVMのオプションは不要かもしれません

こんな感じで 設定をすすめたら Exit を選んで保存します

#
# configuration written to .config
#


*** End of Linux kernel configuration.
*** Execute 'make' to build the kernel or try 'make help'.

$
 

カレントディレクトリに .config 隠しファイルが作成されます
これがカーネルのコンフィグ設定ファイルになります 必要に応じてバックアップをとりましょう

ところで NICのドライバが未選択です
チップは Realtek 8111D ですが R8168ドライバが使えるとのことです (Googleによると…)
ドライバは Realtek から直接ダウンロードします
Realtek NICドライバダウンロードページ
ドライバは カーネルと別ディレクトリで カーネルモジュールにコンパイルできますが
今回は カーネルディレクトリに組み込む方法をとりました

手順は以下のとおりです まずダウンロードしたアーカイブを展開します

$ cd drivers/net
$ tar -xjvf ~/r8168-8.021.00.tar.bz2 r8168-8.021.00/src/*.c r8168-8.021.00/src/*.h --strip-path=2
r8168-8.021.00/src/r8168.h
r8168-8.021.00/src/rtl_eeprom.c
r8168-8.021.00/src/r8168_asf.h
r8168-8.021.00/src/rtl_eeprom.h
r8168-8.021.00/src/r8168_asf.c
r8168-8.021.00/src/r8168_n.c
r8168-8.021.00/src/rtltool.c
r8168-8.021.00/src/rtltool.h
 

上記作業により 8つのファイルが展開されています
同じディレクトリにある Kconfigを編集して コンフィグにドライバを追加します

$ vi Kconfig
 

下記の行を追加します R8169 の手前あたりでかまいません
追加内容も R8169を参考にしています

config R8168
        tristate "Realtek 8168 (8111D) gigabit ethernet support"
        depends on PCI
        select CRC32
        select MII
        ---help---
          Say Y here if you have a Realtek 8168 PCI Gigabit Ethernet adapter.

          To compile this driver as a module, choose M here: the module
          will be called r8168.  This is recommended.

config R8168_VLAN
        bool "VLAN support"
        depends on R8168 && VLAN_8021Q
        ---help---
          Say Y here for the r8168 driver to support the functions required
          by the kernel 802.1Q code.

          If in doubt, say Y.
 

Makefileにも追加します 作成すべきターゲットオブジェクトを指定します
これも 同様に r8169.o の手前の行でかまいません

obj-$(CONFIG_R8168) += r8168.o
r8168-objs := r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o
 

これだけです もう一度 カーネルのコンフィグ画面を開き直します

$ cd -
$ make ARCH=x86_68 menuconfig
 

linuxカーネルコンフィグ Device Drivers / Network device support 2
Device drivers の中の Network device support / Ethernet (1000 Mbit) を選択すると
上記のように R8168 が選択できるようになっています

選択し終えたら Exit して保存します
R8168ドライバは カーネルモジュールの形でなくカーネル組込みとしてビルドすることにしました

カーネルのビルドに入ります

$ make ARCH=x86_68
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/docproc
  HOSTCC  scripts/basic/hash
  CC      kernel/bounds.s
  GEN     include/generated/bounds.h
〜
  BUILD   arch/x86/boot/bzImage
Root device is (3, 4)
Setup is 12940 bytes (padded to 13312 bytes).
System is 3490 kB
CRC d5d86061
Kernel: arch/x86/boot/bzImage is ready  (#13)
  Building modules, stage 2.
  MODPOST 14 modules
  CC      arch/x86/kvm/kvm-amd.mod.o
  LD [M]  arch/x86/kvm/kvm-amd.ko
  CC      arch/x86/kvm/kvm.mod.o
  LD [M]  arch/x86/kvm/kvm.ko
  CC      drivers/media/video/cx2341x.mod.o
  LD [M]  drivers/media/video/cx2341x.ko
  CC      drivers/scsi/scsi_wait_scan.mod.o
  LD [M]  drivers/scsi/scsi_wait_scan.ko
  CC      drivers/virtio/virtio.mod.o
  LD [M]  drivers/virtio/virtio.ko
  CC      drivers/virtio/virtio_balloon.mod.o
  LD [M]  drivers/virtio/virtio_balloon.ko
  CC      drivers/virtio/virtio_pci.mod.o
  LD [M]  drivers/virtio/virtio_pci.ko
  CC      drivers/virtio/virtio_ring.mod.o
  LD [M]  drivers/virtio/virtio_ring.ko
  CC      drivers/xen/platform-pci.mod.o
  LD [M]  drivers/xen/platform-pci.ko
  CC      net/8021q/8021q.mod.o
  LD [M]  net/8021q/8021q.ko
  CC      net/ipv4/ip_gre.mod.o
  LD [M]  net/ipv4/ip_gre.ko
  CC      net/ipv4/ipip.mod.o
  LD [M]  net/ipv4/ipip.ko
  CC      net/l2tp/l2tp_core.mod.o
  LD [M]  net/l2tp/l2tp_core.ko
  CC      net/netfilter/xt_mark.mod.o
  LD [M]  net/netfilter/xt_mark.ko
$
 

カーネルと カーネルモジュールまでビルドできました

カーネルで必要なファイルは System.map と arch/x86_64/boot/bzImage の2ファイル
カーネルモジュールは 個々に取り出すのは面倒なため
一旦 現行の 32bitマシンにインストールしておきます

$ su
# make ARCH=x86_64 modules_install
Warning: you may need to install module-init-tools
See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt
  INSTALL arch/x86/kvm/kvm-amd.ko
  INSTALL arch/x86/kvm/kvm.ko
  INSTALL drivers/media/video/cx2341x.ko
  INSTALL drivers/scsi/scsi_wait_scan.ko
  INSTALL drivers/virtio/virtio.ko
  INSTALL drivers/virtio/virtio_balloon.ko
  INSTALL drivers/virtio/virtio_pci.ko
  INSTALL drivers/virtio/virtio_ring.ko
  INSTALL drivers/xen/platform-pci.ko
  INSTALL net/8021q/8021q.ko
  INSTALL net/ipv4/ip_gre.ko
  INSTALL net/ipv4/ipip.ko
  INSTALL net/l2tp/l2tp_core.ko
  INSTALL net/netfilter/xt_mark.ko
  DEPMOD  2.6.36.3
#
 

これでカーネルモジュールは /lib/modules/2.6.36.3/ 配下にコピーされています

カーネルができあがったので 64bit環境に必要なファイルは揃ったことになります
次は いよいよターゲットマシンを起動して 64bit Linux環境が起動するところまで確認します

ターゲット環境に 64bitカーネルをコピーして環境を整える

ターゲット環境へ いよいよインストール作業を再開します
先ほど作成した カーネル と カーネルモジュール を転送するだけです

ターゲット環境をブートするのに DVDの Linux環境を使いたかったが
面倒なところがあったので 結局 インストール済の FreeBSDから起動してしまいました

FreeBSD/amd64 (phenom) (pts/0)

login: admin
Password:
Last login: Thu Feb  3 07:53:55 from 192.168.1.3
Copyright (c) 1992-2010 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.

FreeBSD 8.1-RELEASE (ADMIN) #1: Mon Jan 10 23:39:00 JST 2011

Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

o  Security advisories and updated errata information for all releases are
   at http://www.FreeBSD.org/releases/ - always consult the ERRATA section
   for your release first as it's updated frequently.

o  The Handbook and FAQ documents are at http://www.FreeBSD.org/ and,
   along with the mailing lists, can be searched by going to
   http://www.FreeBSD.org/search/.  If the doc distribution has
   been installed, they're also available formatted in /usr/share/doc.

If you still have a question or problem, please take the output of
`uname -a', along with any relevant error messages, and email it
as a question to the questions@FreeBSD.org mailing list.  If you are
unfamiliar with FreeBSD's directory layout, please refer to the hier(7)
manual page.  If you are not familiar with manual pages, type `man man'.

You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

> su
Password:
# mount -t ext2fs /dev/ad4s2 /mnt
#
 

stage3イメージを導入済のパーティションを ext2fs でマウントします
(FreeBSDは ext3をサポートしていないので多少の不安が残ります)

コピー元の 32bit linux環境に戻って転送準備を行います

$ su
# cd /lib/modules
# tar -czf ~/modules.tar.gz 2.6.36.3/
#
 

こんな感じで作られた modules.tar.gz と bzImage と System.map を FreeBSD側に転送して
(FTPなど使ってください)

再び FreeBSDで書き戻す作業を行います

# cd /mnt/boot
# mv ~/System.map System.map-2.6.36.3
# ln -s System.map-2.6.36.3 System.map
# mv ~/bzImage vmlinuz-2.6.36.3
# ln -s vmlinuz-2.6.36.3 vmlinuz
# cd /mnt/lib/modules
# tar -xzf modules.tar.gz
#
# ls /mnt/boot/
.keep                   System.map-2.6.36.3     vmlinuz
System.map              boot                    vmlinuz-2.6.36.3
# ls -R /mnt/lib64/modules/2.6.36.3/
build           kernel          modules.builtin modules.order   source

/mnt/lib64/modules/2.6.36.3/kernel:
arch    drivers net

/mnt/lib64/modules/2.6.36.3/kernel/arch:
x86

/mnt/lib64/modules/2.6.36.3/kernel/arch/x86:
kvm

/mnt/lib64/modules/2.6.36.3/kernel/arch/x86/kvm:
kvm-amd.ko      kvm.ko

/mnt/lib64/modules/2.6.36.3/kernel/drivers:
media   scsi    virtio  xen

/mnt/lib64/modules/2.6.36.3/kernel/drivers/media:
video

/mnt/lib64/modules/2.6.36.3/kernel/drivers/media/video:
cx2341x.ko

/mnt/lib64/modules/2.6.36.3/kernel/drivers/scsi:
scsi_wait_scan.ko

/mnt/lib64/modules/2.6.36.3/kernel/drivers/virtio:
virtio.ko               virtio_pci.ko
virtio_balloon.ko       virtio_ring.ko

/mnt/lib64/modules/2.6.36.3/kernel/drivers/xen:
platform-pci.ko

/mnt/lib64/modules/2.6.36.3/kernel/net:
8021q           ipv4            l2tp            netfilter

/mnt/lib64/modules/2.6.36.3/kernel/net/8021q:
8021q.ko

/mnt/lib64/modules/2.6.36.3/kernel/net/ipv4:
ip_gre.ko       ipip.ko

/mnt/lib64/modules/2.6.36.3/kernel/net/l2tp:
l2tp_core.ko

/mnt/lib64/modules/2.6.36.3/kernel/net/netfilter:
xt_mark.ko
#
 

うまく転送されていることを確認したら
Grub2 の設定も行います 設定ファイルは /boot/grub/grub.cfg です


insmod terminal
insmod gfxterm
insmod vbe
insmod vga
insmod tga

set gfxmode=640x480
set root=(hd0,1,a)

background_image /boot/grub/bg1.tga
set menu_color_normal=white/black
set menu_color_highlight=white/green

set default=1
set timeout=20

terminal gfxterm

menuentry "FreeBSD" {
 set root=(hd0,1,a)
 kfreebsd /boot/loader
}

menuentry "Linux-2.6.36.3" {
 set root=(hd0,2)
 linux /boot/vmlinuz-2.6.36.3 root=0802
}
 

Grubの背景画像に /boot/grub/bg1.tga を指定しました
bg1.tga は 640*480 のTGA形式の画像をあらかじめ準備しておく必要があります
(ただし 検証の環境では背景画像は写りませんでした なんで?)

FreeBSDをリブートして いよいよ Linuxのパーティションをブートします

# cd
# umount /mnt
# shutdown -r now
 

うまく ブートしてきて ログインプロンプトが表示されたら

root
 

と叩いてください パスワードなしでログインできるはずです
ログインできたら手始めに何をしましょうか

次回以降システムをブートしたとき ネットワークが適切に設定され
adminアカウントでリモートから sshログインできるところまでの環境設定を目標とします

Gentooのベースシステムのため 初期設定は Gentoo Linux x86 ハンドブック が参考になります
ます admin アカウントの作成から

# useradd -m -g wheel -G users -s /bin/bash -u 1000 admin
# id admin
uid=1000(admin) gid=10(wheel) groups=10(wheel),100(users)
#
 

ネットワークを初回は 手動で設定します 各自の LANの構成にもよりますが
192.168.1.254 を割り当て デフォルトルートは 192.168.1.1 とします

# ifconfig eth0 192.168.1.254 netmask 255.255.255.0 up
# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 〜  
          inet addr:192.168.1.254  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: 〜/64 Scope:Global
          inet6 addr: fe80::〜/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:809 errors:0 dropped:0 overruns:0 frame:0
          TX packets:627 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:86770 (84.7 KiB)  TX bytes:72918 (71.2 KiB)
          Interrupt:41 Base address:0x6000 
# route add default gw 192.168.1.1
# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     *               255.255.255.0   U     0      0        0 eth0
loopback        *               255.0.0.0       U     0      0        0 lo
default         192.168.1.1     0.0.0.0         UG    0      0        0 eth0
#
 

NICのドライバもうまく動作しているようです
OCNのプロバイダを使っていて IPv6 のグローバルが割り当てられているのもポイントです
上記の設定がリブート後も有効になるように 各設定ファイルをカスタマイズします

# nano /etc/hosts
 

一番最後の行に 自前のホスト名を設定しておきます

192.168.1.254     phenom phenom.mydomain
 

ホスト名も設定します

# nano /etc/conf.d/hostname
 
# /etc/conf.d/hostname

# Set to the hostname of this machine
HOSTNAME="phenom"
 

NICの設定も設定ファイルに落とし込みます

# nano /etc/conf.d/net
 
# This blank configuration will automatically use DHCP for any net.*
# scripts in /etc/init.d.  To create a more complete configuration,
# please review /etc/conf.d/net.example and save your configuration
# in /etc/conf.d/net (this file:]!).
dns_domain_lo="mydomain"
config_eth0=( "192.168.1.254 netmask 255.255.255.0 brd 192.168.1.255")
routes_eth0=( "default via 192.168.1.1" )
 

最後に遠隔からログインできるように 設定します
Gentooベースのシステムでは SSHが標準で提供されています

# rc-update add sshd default
#
 

これで次回起動から sshdが有効になります
ただし sshdの設定も必要です

# nano /etc/ssh/sshd_config
 

設定を変えた部分のみ抜粋します

Protocol 2,1
RSAAuthentication yes
PubkeyAuthentication no
AuthorizedKeysFile .ssh/authorized_keys
ChallengeResponseAuthentication no
 

RSA鍵認証によるログインをベースとしました
ここから sshdを起動して RSA鍵を作成します

# /etc/init.d/sshd start
 * Caching service dependencies ...                 [ ok ]
 * Generating RSA1-Hostkey...
〜
 * Starting sshd ...                                [ ok ]
#
 

初回稼働のため 自動的に鍵ペアが生成されたようです
それとは関係なく RSA鍵ペアを手動で作成しておきます

# su - admin
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/admin/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/admin/.ssh/id_rsa.
Your public key has been saved in /home/admin/.ssh/id_rsa.pub.
The key fingerprint is:
〜
$
 

これで ~/.ssh/ に id_rsa (秘密鍵) と id_rsa.pub (公開鍵) が作成されました
パスフレーズを空白とすればパスワードなしログインできます
公開鍵は サーバである phenom側に登録します

# cat .ssh/id_rsa.pub >> .ssh/authorized_keys
# chmod 600 .ssh/authorized_keys
#
 

秘密鍵は 何らかの手段で ログイン元である クライアント端末へ運んだ後
他人に中身が見られないように 属性を変えて保存します
(検証環境では FTPを使ってしまいましたが)

$ mv id_rsa .ssh/id_rsa.phenom
$ chmod 600 .ssh/id_rsa.phenom
$
 

64bitサーバ側へログインするときに その秘密鍵を使うように設定します

$ vi .ssh/config
 

下記の行を追加します


Host phenom
 Hostname 192.168.1.254
 Port 22
 User admin
 Identityfile ~/.ssh/id_rsa.phenom
 RSAAuthentication yes
 RhostsAuthentication no
 HostbasedAuthentication no
 PasswordAuthentication no
 Protocol 2,1

 

早速 リモートクライアントから サーバ側へログインしてみましょう

$ ssh phenom
The authenticity of host '192.168.1.254 (192.168.1.254)' can't be established.
RSA key fingerprint is 〜.
Are you sure you want to continue connecting (yes/no)? yes
$
$ uname -a
Linux localhost 2.6.36.3 #13 SMP Fri Feb 18 07:38:05 JST 2011 x86_64 AMD Phenom(tm) II X4 905e Processor AuthenticAMD GNU/Linux
$
 

初回ログインなので fingerprintの確認を求められています 確認できたら yes をタイプします
うまくログインできるようになったら 先ほど作成した鍵ペアは不要なので削除します

$ rm .ssh/id_rsa .ssh/id_rsa.pub
$ su
#
# passwd
New password: 
Retype new password: 
passwd: password updated successfully
#
 

念のために rootにスイッチできるところまで確認し
rootのパスワードを設定します

ターゲットマシンをリブートして ネットワークが再設定され SSHでログインできれば OKです
以上で 64bit Linuxマシンを初期設定して 最小限の設定まで完了しました

ここでは触れませんが 今後ネイティブの 64bitコンパイル環境を整え
自分の好みのソフトウェアでシステムの構築を進めてもよいですし

また Gentooにどっぷり浸かりたいなら Gentoo Linux x86 ハンドブックを読み進めて
ebuildが管理する 無数のパッケージを試すことも自由です

インストール後のglibcの設定

ここでは glibcインストール後に必要になる設定を行います
ロケールとタイムゾーンです これらは glibcに含まれている機能のため再設定が必要となります

まずロケールから 必要なロケールデータは既に glibcに含まれているので必要なデータを展開します

# cd /usr/glibc/2.9/amd64/share/i18n/charmaps/
# ls
ANSI_X3.110-1983.gz    IBM1129.gz        ISO-IR-90.gz
ANSI_X3.4-1968.gz      IBM1132.gz        ISO_10367-BOX.gz
ARMSCII-8.gz           IBM1133.gz        ISO_10646.gz
ASMO_449.gz            IBM1160.gz        ISO_11548-1.gz
BIG5-HKSCS.gz          IBM1161.gz        ISO_2033-1983.gz
BIG5.gz                IBM1162.gz        ISO_5427-EXT.gz
BRF.gz                 IBM1163.gz        ISO_5427.gz
BS_4730.gz             IBM1164.gz        ISO_5428.gz
BS_VIEWDATA.gz         IBM256.gz         ISO_646.BASIC.gz
CP10007.gz             IBM273.gz         ISO_646.IRV.gz
CP1125.gz              IBM274.gz         ISO_6937-2-25.gz
CP1250.gz              IBM275.gz         ISO_6937-2-ADD.gz
CP1251.gz              IBM277.gz         ISO_6937.gz
CP1252.gz              IBM278.gz         ISO_8859-1,GL.gz
CP1253.gz              IBM280.gz         ISO_8859-SUPP.gz
CP1254.gz              IBM281.gz         IT.gz
CP1255.gz              IBM284.gz         JIS_C6220-1969-JP.gz
〜
HP-ROMAN9.gz           ISO-8859-4.gz     T.61-8BIT.gz
HP-THAI8.gz            ISO-8859-5.gz     TCVN5712-1.gz
HP-TURKISH8.gz         ISO-8859-6.gz     TIS-620.gz
IBM037.gz              ISO-8859-7.gz     TSCII.gz
IBM038.gz              ISO-8859-8.gz     UTF-8.gz
IBM1004.gz             ISO-8859-9.gz     VIDEOTEX-SUPPL.gz
IBM1026.gz             ISO-8859-9E.gz    VISCII.gz
IBM1047.gz             ISO-IR-197.gz     WINDOWS-31J.gz
IBM1124.gz             ISO-IR-209.gz
#
 

ここに各国語のロケールデータが収まっています 必要な分だけ解凍しましょう

# gunzip ISO-8859-1
# gunzip UTF-8.gz
 

ロケールをコンパイルする localedef コマンドを使いますが その前にヘルプを確認します

# localedef --help
Usage: localedef [OPTION...] NAME
  or:  localedef [OPTION...] [--add-to-archive|--delete-from-archive] FILE...
  or:  localedef [OPTION...] --list-archive [FILE]
Compile locale specification

 Input Files:
  -f, --charmap=FILE         Symbolic character names defined in FILE
  -i, --inputfile=FILE       Source definitions are found in FILE
  -u, --repertoire-map=FILE  FILE contains mapping from symbolic names to UCS4
                             values

〜

System's directory for character maps :
/usr/glibc/2.9/amd64/share/i18n/charmaps
                       repertoire maps: /usr/glibc/2.9/amd64/share/i18n/repertoiremaps
                       locale path    :
/usr/glibc/2.9/amd64/lib/locale:/usr/glibc/2.9/amd64/share/i18n
For bug reporting instructions, please see:
.
#
 

locale path の欄にロケールデータ格納ディレクトリ /usr/glibc/2.9/amd64/lib/locale
が表示されていますが このディレクトリが存在しないため localedef はエラーを返します
ディレクトリを作成してから 実行しましょう

# mkdir /usr/glibc/2.9/amd64/lib/locale
# localedef -i en_US -f ISO-8859-1 en_US
# localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
# ls -l /usr/glibc/2.9/amd64/lib/locale/
total 1228
-rw-r--r-- 1 root root 1322672 Apr 24 14:47 locale-archive
#
 

locale-archive という単一ファイルに格納される仕組みのようです

では 作成した ja_JP.UTF-8 に切り替えてみましょう
locale -a で ja_JP.UTF-8 の存在を確認した上で
LANG環境変数を設定して localeコマンドで反映させます

# locale -a
C
POSIX
en_US
en_US.iso88591
ja_JP.utf8
# export LANG=ja_JP.utf8
# locale
LANG=ja_JP.utf8
LC_CTYPE="ja_JP.utf8"
LC_NUMERIC="ja_JP.utf8"
LC_TIME="ja_JP.utf8"
LC_COLLATE="ja_JP.utf8"
LC_MONETARY="ja_JP.utf8"
LC_MESSAGES="ja_JP.utf8"
LC_PAPER="ja_JP.utf8"
LC_NAME="ja_JP.utf8"
LC_ADDRESS="ja_JP.utf8"
LC_TELEPHONE="ja_JP.utf8"
LC_MEASUREMENT="ja_JP.utf8"
LC_IDENTIFICATION="ja_JP.utf8"
LC_ALL=
# ls -l /usr/glibc/2.9/amd64/lib/locale/
合計 1228
-rw-r--r-- 1 root root 1322672  4月 24 14:47 locale-archive
#
 

ls の表示も日本語に切り替わっています
後は LANG環境変数が ログイン時に自動設定されるようにしておけばよいだけです

次に タイムゾーンを設定します
タイムゾーン情報は elsie.nci.nih.gov で配布されています
ここの tzdata ファイルをダウンロードしましょう
timezone : elsie.nci.nih.gov
この中から必要なファイルだけ展開します ここでは asia と leapseconds が必要です

$ tar -tzf tzdata2011f.tar.gz
africa
antarctica
asia
australasia
europe
northamerica
southamerica
pacificnew
etcetera
backward
systemv
factory
solar87
solar88
solar89
iso3166.tab
zone.tab
leapseconds
yearistype.sh
$ tar -xzf tzdata2011f.tar.gz asia leapseconds
$
 

leapsecondsは うるう秒を補正する情報です うるう秒が発生する毎に更新されます
zicコマンドでこれらのファイルをコンパイルします

$ su
# zic -d /usr/glibc/2.9/amd64/share/zoneinfo -L leapseconds asia
# ls /usr/glibc/2.9/amd64/share/zoneinfo/
Asia  Europe  Indian  iso3166.tab  zone.tab
#
 

Asia や Indian といったディレクトリが作られています Asia/Tokyo があれば OKです

タイムゾーンの切り替え方ですが 2通りあります
まず TZ環境変数を設定する方法です

# date
2011年  4月 24日 日曜日 16:55:45 UTC
# export TZ=Asia/Tokyo
# date
2011年  4月 25日 月曜日 01:55:34 JST
#
 

9時間ほど進んで 東京のタイムゾーンに切り替わりました

もうひとつの方法は localtime ファイルを作成する方法で
システムデフォルトのタイムゾーンが設定されます

# ln -s /usr/glibc/2.9/amd64/share/zoneinfo/Asia/Tokyo /etc/localtime
#
 

localtime は タイムゾーンファイルへのシンボリックリンクとして作成するのが一般的です

サーバ管理者の仕事としては うるう秒がアナウンスされたときに
あらかじめそれが適用された leapseconds を入手して zicコマンドで反映するだけです

 

IPv6クライアントツール

ひとまず Windowsで IPv6対応状況を確認

まず意識しておかなければいけないのが 下記の点
「ツールが IPv6対応している必要がある」
ツールを作る人が 「IPv6対応」でプログラムしてくれている必要があります

OSの IPv6対応について

Windowsについては WindowsXP以降は確実に IPv6対応されています

Windowsのネットワーク設定の画面を開いて 下記のようになっていれば OKです
Windows IPv6 ネットワーク設定
「TCP/IPv6」にチェックが入っている必要があります

Windowsで IPv6が有効になっていると Windowsが IPv6アドレスを自動取得します
それを確認するには コマンドプロンプトを立ち上げて
「netsh interface ipv6 show address」と打ち込んで Enterを叩きます
Windows IPv6アドレス確認
netshコマンドは Windowsのネットワーク関連を設定するツールですが
IPアドレスを確認するだけなら ipconfigコマンドでも見れます

いくつか IPv6アドレスが割り当てられているのが確認できますが
Temporaryや Publicの ところにある 2408:**** というアドレスが重要です
これは プロバイダから割り当てられたグローバルな IPv6アドレスである証拠です
筆者の環境は フレッツ光+OCNプロバイダ を利用していますが
NTTから借りているルータが既に IPv6対応となっていることが分かります

プロバイダが IPv6対応でなくても fe80:**** のアドレスは自動でもらえますが
あくまで自宅内のローカルアドレスとなってしまい インターネットは見れません

Linuxについては
カーネルのコンフィグで IPv6 シンボルを有効化していれば IPv6対応されます
ただし古いディストリビューションんでは ifconfig arp route netstat などのコマンドが
IPv6対応されておらず 必要な情報が見れなかったりするので注意

下記は /proc 内部に記録されている IPv6ルーティングテーブルを直接参照する方法です

$ cat /proc/net/ipv6_route
00000000000000000000000000000001 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 00000002 80200001       lo
2******************************2 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 000000cc 80200001       lo
2**********200000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 0000000a 004c0001     eth0
f******************************2 80 00000000000000000000000000000000 00 00000000000000000000000000000000 00000000 00000001 00000034 80200001       lo
fe800000000000000000000000000000 40 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000000 00000001     eth0
ff020000000000000000000000000001 80 00000000000000000000000000000000 00 ff020000000000000000000000000001 00000000 00000000 00000001 01000001     eth0
ff000000000000000000000000000000 08 00000000000000000000000000000000 00 00000000000000000000000000000000 00000100 00000000 00000000 00000001     eth0
00000000000000000000000000000000 00 00000000000000000000000000000000 00 fe8000000000000002*************9 00000400 00000000 00000308 00450003     eth0
00000000000000000000000000000000 00 00000000000000000000000000000000 00 00000000000000000000000000000000 ffffffff 00000001 00000001 00200200       lo
$
 

ネットワーク基本ツールの IPv6対応について

OSによって何かと多少方言がある下記の ネットワーク設定ツールでの IPv6対応状況です

arp について (IPv6対象外)
MACアドレス と IPアドレス の紐付け管理ですが
「IPv6での ARPはどうやって確認するの?」という質問は多少的を外しています
IPv4では ARPプロトコルでMACアドレスを解決していましたが
IPv6では NS(近隣要請) NA(近隣通知) プロトコルでMAC解決します
従って arpコマンドは元々 IPv6対応するつもりなしです

Windows Vistaを例に IPv6のNDテーブルを確認する方法を紹介します
netshコマンドで LAN内の近隣ノードの IPアドレスが分からなくなった場合に確認できます
netsh interface ipv6 show neighbors

arp相当のIPv6対応
Linux ip -6 neigh show
ipコマンド 未インストールのため未確認
Solaris netstat -p
Solarisは ARPテーブルに NDPエントリも登録
FreeBSD/MacOSX ndp -a
Windows netsh interface ipv6 show neighbor

route について
IPアドレス と ホスト名 の紐付け管理です こちらは多くのシステムがIPv6対応しています
Linuxを例に取ると 下記のように -A inet6 オプションを付けるだけです

$ route -A inet6
Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
::1/128                        ::                         Un   0   1    54 lo
2408:**:***2:0:1***:****:****:***a/128 ::                         Un   0   1     0 lo
2408:**:***2::/64              ::                         UAe  256 0    80 eth0
fe80::1***:****:****:***a/128  ::                         Un   0   1 83310 lo
fe80::/64                      ::                         U    256 0     0 eth0
ff00::/8                       ::                         U    256 0     0 eth0
::/0                           fe80::2***:****:****:***9   UGDAe 1024 0     1 eth0
::/0                           ::                         !n   -1  1     1 lo
$
 
ルーティング情報の IPv6対応
Linux routeコマンドに -A inet6 オプションを指定
Solaris routeコマンドに -inet6 オプションを指定
テーブルの表示は netstat -r で
FreeBSD/MacOSX routeコマンドに -inet6 オプションを指定
Windows netsh interface ipv6 show route (WinXP)

IPv6になって 方言がさらに進行したような
でも IPv6が浸透するにつれて統一化が図られるかもしれません

DHCPについて
IPv4の時代では DHCPの主な目的は 「IPv4アドレスの自動設定」でした
IPv6では IPv6ルータからの RAにより IPv6アドレスを自動生成できます
しかし「DHCPv6 は不要か?」というとそうではなく使い分けの判断が必要です

RAではまだ DNSサーバを通知する仕組みが整っていません
つまり IPv6ノード複数持つような環境で IPv6 DNSを運営が必要な場合
IPv6ルータ以外に DNSサーバを通知する仕組み(現状 DHCPv6)が必要です
Windowsでは RA と DHCPv6 の併用状況を設定する 2つのフラグを設定します

Mフラグ と Oフラグ
Mフラグ 管理された(Managed)アドレス
このフラグが有効の場合 IPアドレスを DHCPv6により構成する
netsh interface ipv6 set interface 番号 managedaddress=enabled/disabled
で設定
Oフラグ その他(Other)設定
このフラグが有効の場合 DNSサーバや ゲートウェイルータアドレスを DHCPv6により取得する
netsh interface ipv6 set interface 番号 otherstateful=enabled/disabled
で設定

デフォルトは Mフラグ=disabled Oフラグ=disabled の状態で
IPv6アドレスのみを ルータ RAから構成する動作です
自宅のマシン構成は IPv6プレフィックスはルータ経由で取得しているので
しばらく Mフラグ=disabled 必要です
ただし DNSサーバを構築しているので Oフラグ=enabled としています

C:\Windows\system32>netsh interface ipv6 show interface 10

インターフェイス ローカル エリア接続 パラメーター
----------------------------------------------
IfLuid                             : ethernet_6
IfIndex                            : 10
状態                               : connected
メトリック                         : 10
リンク MTU                         : 1500 バイト
到達可能な時間                     : 33000 ミリ秒
基本の到達可能な時間               : 30000 ミリ秒
再転送間隔                         : 1000 ミリ秒
DAD 転送                           : 1
サイト プレフィックスの長さ        : 64
サイト ID                          : 1
転送                               : disabled
アドバタイズ                       : disabled
近隣探索                           : enabled
近隣到達不可能性検出               : enabled
ルーター発見                       : enabled
管理されたアドレス構成             : disabled
その他のステートフル構成           : enabled
脆弱なホストによる送信             : enabled
脆弱なホストによる受信             : disabled
自動メトリックの使用               : enabled
既定ルートを無視                   : disabled
アドバタイズされたルーターの有効期間: 1800 秒
既定ルートのアドバタイズ           : disabled
現在のホップ制限                   : 64
ARPND スリープ解除パターンの強制   : disabled
指定の MAC スリープ解除パターン    : disabled
 

「管理されたアドレス構成」が Mフラグです
「その他のステートフル構成」が Oフラグです
あとは DHCPv6サーバが DNSサーバアドレスを広報するように設定すれば完了です

DNSについて
IPv6名前解決についても 多くのシステムで対応されています
IPv6通信に対応している DNSサーバがあればそのアドレスを指定します

DNSの IPv6対応
Linux /etc/resolv.conf を設定

domain mydomain
search mydomain

nameserver fe80::1***:****:****:***a%eth0
nameserver 2408:**:****:****:****:****:****:***9
nameserver ***.***.***.**3
nameserver 2**.***.***.**7
   

fe80:: で指定しているアドレスは 自宅に立てたDNSサーバです
リンクローカルアドレスを利用しているので %eth0 を後ろにつけています

残りの nameserverの指定はプロバイダから割り当てらたアドレスです
自宅DNSが使えない時でも とりあえずインターネットが使えるようにするためのものです

Solaris
FreeBSD/MacOSX
Windows ネットワーク設定アイコンのプロパティを開いて設定します
Windows IPv6 ネットワークプロパティ
使用するプロトコルに TCP/IPv6 があることを確認して
そのプロパティを設定します
Windows TCP/IPv6プロパティ
次のDNSサーバのアドレスを使う を選択します
画面では 2つまでしか指定できないので「詳細設定」で設定します
Windows TCP/IPv6詳細
DNSサーバのアドレスを手動設定できます
また 自動付与されるドメインや 自マシンのドメインも指定できます

   

各種ツールの IPv6対応について

クライアントOS の IPv6対応状況を確認したところで 代表的なツールの IPv6対応を確認します
サーバはとりあえずインターネットではなく 自宅にあるUNIXサーバで検証しました

名前解決について
(Linux/FreeBSD)
resolv.conf はIPv6対応されていますが注意点があります
nameserverにリンクローカルアドレスが指定されていると
host nslookup dig コマンドがうまく動作しません

domain mydomain
search mydomain
nameserver ::1
 

上記の場合 ::1 つまり自サーバが DNSサービスを提供している環境では
下記のように問題なく host nslookup digコマンドが動作します

$ host -t AAAA turion
turion.local has IPv6 address fe80::2***:****:****:***2
$ nslookup -type=AAAA turion
Server:         ::1
Address:        ::1#53

turion.local    has AAAA address fe80::2***:****:****:***2

$ dig dig AAAA turion.local

; <<>> DiG 9.8.1 <<>> AAAA turion.mydomain
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12168
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;turion.mydomain.                  IN      AAAA

;; ANSWER SECTION:
turion.mydomain.           3600    IN      AAAA    fe80::2***:****:****:***2

;; AUTHORITY SECTION:
mydomain.                  3600    IN      NS      phenom4.mydomain.

;; ADDITIONAL SECTION:
phenom4.mydomain.          3600    IN      A       192.168.1.254

;; Query time: 0 msec
;; SERVER: ::1#53(::1)
;; WHEN: Sun Nov  6 11:53:22 2011
;; MSG SIZE  rcvd: 96

$
 

次のように リンクローカルアドレスを指定すると全くトンチンカンな応答になります

domain mydomain
search mydomain
nameserver fe80::1***:****:****:***a%eth0
 
$ host -t AAAA turion
turion.local has no AAAA record
$ nslookup -type=AAAA turion
Server:         127.0.0.1
Address:        127.0.0.1#53

*** Can't find turion: No answer

$ dig AAAA turion.mydomain

; <<>> DiG 9.4.2 <<>> AAAA turion.mydomain
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54935
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;turion.mydomain.                  IN      AAAA

;; AUTHORITY SECTION:
mydomain.                  3600    IN      SOA     turion.mydomain. admin.mydomain. 2011010501 10800 3600 604800 86400

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sun Nov  6 12:07:24 2011
;; MSG SIZE  rcvd: 71

$
 

bind9付属の host nslookup dig が nameserver行の %インターフェース指定に未対応のためです
libc付属の libresolvはインターフェース指定のフォーマットに対応しているため
その他の ping6 や Firefox といったツールは問題なく動作します

pingについて
ネットワーク疎通確認の定番

(Windows)
ping6

(Linux)
これも ping6が対応しています

$ ping6 fe80::1***:****:****:***a
PING fe80::1***:****:****:***a (fe80::1***:****:****:***a): 56 data bytes
64 bytes from fe80::1***:****:****:***a%eth0: icmp_seq=0 ttl=64 time=1.144 ms
64 bytes from fe80::1***:****:****:***a%eth0: icmp_seq=1 ttl=64 time=0.093 ms
^C--- fe80::1***:****:****:***a ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.093/0.618/1.144/0.526 ms
$
 

(FreeBSD)
これも ping6が対応していますが IPv6アドレスの直後に %インターフェース指定が必要でした

 > ping6 fe80::2***:****:****:***2%re0
PING6(56=40+8+8 bytes) fe80::1***:****:****:***a%re0 --> fe80::2***:****:****:***2%re0
16 bytes from fe80::2***:****:****:***2%re0, icmp_seq=0 hlim=64 time=0.078 ms
16 bytes from fe80::2***:****:****:***2%re0, icmp_seq=1 hlim=64 time=0.080 ms
^C
--- fe80::2***:****:****:***2%re0 ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.078/0.079/0.080/0.001 ms

>
 

telnet/SSHクライアントについて
サーバにログインできないと話にならないので最初にこのツールが出てきます

(Windows)
有名な TeraTermの後継でありIPv6化した TeraTerm Project が使えます
TeraTerm Project
SSHプロトコルも UTF8日本語コードも対応しているので一安心です
IPv6アドレスを指定するときは 大括弧[] で括って指定する必要があります

(Linux)
愛用している inetutils 付属の telnetコマンドは IPv6対応されています

$ telnet fe80::1***:****:****:***a%eth0
Trying fe80::1***:****:****:***a%eth0...
Connected to fe80::1***:****:****:***a%eth0.
Escape character is '^]'.

FreeBSD/amd64 (phenom) (pts/1)

login: *****
password: 
 

(FreeBSD)
これも telnetが普通に IPv6対応されています

> telnet *******
Trying fe80::1***:****:****:***a...
Connected to *******.
Escape character is '^]'.
Trying SRA secure login:
User (******): ******
Password: 
[ SRA accepts you ]

FreeBSD/amd64 (*******) (pts/1)

Last login: Tue Aug 30 04:14:00 from fe80::1***:****:
 

OpenSSHも普通に IPv6対応しています

> ssh *******
The authenticity of host '[********.mydomain]:22 ([fe80::2***:****:****:***2%re0]:22)' can't be established.
RSA1 key fingerprint is 02:**:**:**:**:**:**:**:**:**:**:**:**:**:**:a4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[*******.mydomain]:22' (RSA1) to the list of known hosts.
Last login: Tue Aug 30 04:10:31 2011 from fe80::1***:****:****:***a%eth0
$
 
 

ftpクライアントについて
ファイル転送もしたいので ここも確認が必要です

(Windows)
これも ほとんどのフリーソフトが IPv6非対応のなか Filezillaが IPv6対応されています
Filezilla
これもホストに IPv6アドレスを指定する場合は 大括弧[] で括って指定します

(Linux)
同じ inetutils パッケージなのに収録されている ftpコマンドは IPv6未対応です
従って別途 IPv6実装されている ftpクライアントを探すと

NcFTP が対応されているようです
正確は IPv4しか使えない NcFTPに KAMEプロジェクトから IPv6対応パッチが提供された形です
こちらで確認できたのは ncftp-3.2.3 で (ここで見つけました)
また IPv6化パッチは KDDラボにありました ncftp-323-v6-20091109.diff.gz あたりを拾ってきます

$ tar -xzf /mnt/dos/temp/ncftp-3.2.3-src.tar.gz
$ cd ncftp-3.2.3
$ zcat ../ncftp-323-v6-20091109.diff.gz | patch -p 1
patching file README.v6
patching file config.h.in
patching file configure
patching file configure.in
patching file libncftp/addrinfo.h
patching file libncftp/ftp.c
patching file libncftp/getaddrinfo.c
patching file libncftp/getnameinfo.c
patching file libncftp/ncftp.h
patching file libncftp/syshdrs.h
patching file ncftp/cmds.c
patching file ncftp/syshdrs.h
patching file ncftp/util.c
patching file sh_util/ncftpbatch.c
patching file sh_util/ncftpget.c
patching file sh_util/ncftpls.c
patching file sh_util/ncftpput.c
patching file sh_util/syshdrs.h
patching file sio/SAccept.c
patching file sio/SConnect.c
patching file sio/SConnectByName.c
patching file sio/SRecvfrom.c
patching file sio/SSendto.c
patching file sio/SSendtoByName.c
patching file sio/StrAddr.c
patching file sio/sio.h
patching file sio/syshdrs.h
patching file vis/syshdrs.h
$ ./configure --enable-ipv6 --prefix=/usr/local
creating cache ./config.cache
checking if you set and exported the environment variable CC... no (you may want to do that since configure scripts look for gcc first)
checking for environment variable CFLAGS... no (we will choose a default set for you)
checking for environment variable CPPFLAGS... no
checking for environment variable LDFLAGS... no
checking for environment variable LIBS... no
checking version of C library... glibc2.5
〜
creating ./config.status
creating Makefile
creating Makefile.bin
creating ncftp/Makefile
creating libncftp/Makefile
creating Strn/Makefile
creating sio/Makefile
creating sh_util/Makefile
creating vis/Makefile
creating config.h
$ make
make[1]: Entering directory `/home/admin/ncftp-3.2.3/Strn'
Compiling DStrCat.c:                                                  [OK]     
Compiling DStrFree.c:                                                 [OK]     
Compiling Dynscpy.c:                                                  [OK]     
Compiling Strncpy.c:                                                  [OK]     
〜
Done making NcFTP full-screen utilities.
make[1]: Leaving directory `/home/admin/ncftp-3.2.3/vis'
合計 992
-rwxr-xr-x  1 admin users 252436  1月 13 00:13 ncftp
-rwxr-xr-x  1 admin users 163580  1月 13 00:13 ncftpbatch
-rwxr-xr-x  1 admin users 115484  1月 13 00:13 ncftpbookmarks
-rwxr-xr-x  1 admin users 155928  1月 13 00:13 ncftpget
-rwxr-xr-x  1 admin users 132004  1月 13 00:13 ncftpls
-rwxr-xr-x  1 admin users 157856  1月 13 00:13 ncftpput
lrwxrwxrwx  1 admin users     10  1月 13 00:13 ncftpspooler -> ncftpbatch
Done.

** Please report any problems to http://www.NcFTP.com/contact/ **
$ su
# make install
make[1]: Entering directory `/home/admin/ncftp-3.2.3/ncftp'
Done making NcFTP.
make[1]: Leaving directory `/home/admin/ncftp-3.2.3/ncftp'
make[1]: Entering directory `/home/admin/ncftp-3.2.3/sh_util'
〜
/usr/local/bin:
  -rwxr-xr-x  1 root root 252436  1月 13 00:43 ncftp
  -rwxr-xr-x  2 root root 163580  1月 13 00:43 ncftpbatch
  -rwxr-xr-x  1 root root 115484  1月 13 00:43 ncftpbookmarks
  -rwxr-xr-x  1 root root 155928  1月 13 00:43 ncftpget
  -rwxr-xr-x  1 root root 132004  1月 13 00:43 ncftpls
  -rwxr-xr-x  1 root root 157856  1月 13 00:43 ncftpput
  -rwxr-xr-x  2 root root 163580  1月 13 00:43 ncftpspooler

Done installing NcFTP.
#
 

メールクライアントについて
(Linux)
GNU Mailutilsに付属の mailコマンドはシンプルなコマンドライン動作のメールツールです
ローカルでの メール送信 受信メールの確認 ができ Maildir形式にも対応しています
結論としては 「ローカルホストでの送受信は可能だが IPv6には未対応」となります

mailコマンドを使った 送受信のデモを下記にお見せします

$ mail -s "test" "admin@mydomain"
Cc: (Enter)
test mail.
(Ctrl+D)
$
$ mail
"maildir:///home/deer/Maildir": 1 message 1 new
>N   1 admin@mydomain                        13/376   test
? 1
Return-Path: 
X-Original-To: admin@mydomain
Delivered-To: admin@mydomain
Received: by phenom.mydomain (Postfix, from userid 500)
        id 0984C24092; Sun,  4 Sep 2011 18:45:11 +0000 (UTC)
Subject: test
To: 
X-Mailer: mail (GNU Mailutils 2.2)
Message-Id: <20110904184511.0984C24092@phenom.mydomain>
Date: Sun,  4 Sep 2011 18:45:11 +0000 (UTC)
From: admin@mydomain

test mail.
? exit
$
 

普通に 送信 受信 ができているように見えますが
mailコマンドによる送信は 自ホストの sendmailコマンドを呼び出しているだけ
mailコマンドによるメール確認は 自ホストのメールディレクトリを表示しているだけ
の動作のため 実はmailコマンド自体は IPv6通信を一切使っていません

(またソースを見る限り IPv6に対応している形跡がなかったため IPv4のみと結論しています)

Sylpheedについては IPv6に対応していました
configureオプションも --enable-ldap のみで IPv6に関するオプションは不要です
メールのIPv6対応 Sylpheed 3.1.3 設定画面
送受信サーバに IPv6アドレスを指定することができます
ただし IPv6ホスト名で指定することができませんでした (何か特別な記述の仕方が必要なのかも)
メールのIPv6対応 Sylpheed 3.1.3 メイン画面
IMAP4s での接続ですが問題なくメール読み書きできます

Windowsでは Outlookがメーラとして一番動作しました
メールのIPv6対応 Outlook2010 画面
Outlook2010です 初期状態では個人的にレイアウトが見づらいため
カスタマイズする必要がありました
メールのIPv6対応 Outlook2010 設定1
アカウント設定の画面です
送受信メールサーバを指定する欄に直接 IPv6アドレスを指定しています
大括弧でアドレスを括る必要があります
メールのIPv6対応 Outlook2010 設定2
送信サーバ設定の画面です SMTP認証を使ってるのでその設定を入れてます
メールのIPv6対応 Outlook2010 設定3
詳細設定のところで ポート番号など細かい指定ができます
暗号化通信を設定しています

Thunderbirdで検証しました
メールのIPv6対応 Thunderbird17 通信エラー
IPv6対応していると言われていますが 結果うまく動作しませんでした
メールのIPv6対応 Thunderbird17 設定
「サーバ名」に IPv6アドレスを指定しようとしましたがうまく認識されません
検証した環境では DNSがIPv6未対応のため IPv6ホスト名を指定すれば動作するのかもしれません

Sylpheedでも試してみました
メールのIPv6対応 Sylpheed3.3.0 画面
メールのヘッダ一覧までは取れたのですが
メールの本文がうまくとれずエラーメッセージが出ています
メールの中身が読めないという 不思議な状況でした
メールのIPv6対応 Sylpheed3.3.0 設定
設定は IPv6アドレスを直接指定する方式でいけました
メール送信は正しく動作したので間違いはないと思います

SMBクライアントについて

 

Webブラウザについて
ブラウザは激しいシェア争いが続いていますが
IPv6対応は 二の次といった感じで既に対応済です

下記検証は 自宅内に構築した Apache(httpd-2.2.21)のデフォルトページの表示結果です
Webサーバは www.mydomain IPv6ホストです (Apache構築ページを参照ください)

(Windows IE9)
Windowsが IPv6有効化されていれば普通に扱えます
ブラウザのIPv6対応 Windows InternetExplorer9
(Windows Firefox7)
これも問題ありません
ブラウザのIPv6対応 Windows Firefox7.0.1
(Linux Firefox3.5)
ブラウザのIPv6対応 Linux Firefox3.5 URL失敗
URL欄に www と入力したら 勝手に www. と .com が補完されてうまく表示できません
ブラウザの fixup機能が有効化しているためです
ブラウザのIPv6対応 Linux Firefox3.5 IPv6アドレス入力
IPv6アドレスの直指定では うまく表示されました
ブラウザ自体は IPv6通信に対応していることは確認できました
ブラウザのIPv6対応 Linux Firefox3.5 about:config設定
Firefoxでは URLに「about:config」と入力すると各種パラメータの設定画面が現れます
browser.fixup.alternate.enabled の項目で fixupを無効化できますが
結局真っ白なページのままでした IPv6ホスト名からアドレスに変換できていないように見えます

 

IPv6トップへ戻る

util-linux は Linuxの基本コマンドが納められています

util-linuxとは

util-linuxとは パッケージ名で 以下の基本コマンドのソースコードが含まれています

fdisk
getopt
hwclock
mount umount
disk-utils/
blockdev elvtune fdformat fsck isosize mkfs mkswap raw setfdprm
login-utils/
chfn chsh lst login mesg newgrp passwd wall
agetty fastboot fasthalt initctl reboot shutdown simpleinit vigr vipw
misc-utils/
cal ddate kill logger look mcookie namei rename
reset script setterm whereis write
sys-utils/
arch flock readprofile
ctrlaltdel cytune dmesg ipcrm ipcs ramsize rdev
renice rootflags sln tunelp vidmode
text-utils/
clear col colcrt clrm column hexdump more od pg rev tailf ul

fdisk や mount など重要な基本ツールが含まれています
どの Linuxディストリビューションにも最初から含まれているため
通常リコンパイルすることはありません

今回 util-linuxの話題になった理由は

$ passwd
passwd: error while loading shared libraries: libdb-4.5.so: cannot open shared object file: No such file or directory
$
というエラーが出て パスワードが変更できなくなったためです
Berkley-DB を最新版にしたタイミングで 古い libdb を削除してしまったのが原因です

util-linuxのダウンロードとビルド

今回 passwd コマンドをリコンパイルするために
Ringサーバプロジェクトより 以下のように最新のソースコードを取得します

Ring ソフトウェアライブラリ

Ringの ソフトウェアライブラリより Linux Kernel を選択

Ring Linux Kernel

kernel/ には Linuxカーネルのソースがありますが utils/ を選択します

Ring linux/utils/

util-linux-ng/ という次世代版? が見えます これは最近の Linuxでは標準となっています
chrt や taskset といった マルチCPU環境にうれしいコマンドが追加されています
が passwdコマンドは除外されています

util-linux/ を選択します

Ring linux/utils/util-linux/

util-linuxの最新版があるので ダウンロードしてアーカイブを展開します
$ tar -tjvf util-linux-2.12r.tar.bz2
$ cd util-linux-2.12r
$ ls
HISTORY     README         fdisk     login-utils    partx      text-utils
INSTALL     VERSION        getopt    misc-utils     po
MAINTAINER  configure      hwclock   mkinstalldirs  rescuept
MCONFIG     disk-utils     lib       mkminix-0.1    sys-utils
Makefile    example.files  licenses  mount          testincl
今回 passwd のコンパイルだけなので login-utils/ 内で作業すればよいですが
共通作業として システム環境を configureスクリプトに収集させる必要あります

この configureは 一般にある configure ; make ; make install のものとは
違うものらしく –prefix= 指定が効きません

$ CC=gcc ./configure

configuring util-linux-2.12r

You don't have <scsi/scsi.h>
You have <linux/blkpg.h>
You have <linux/kd.h>
You have <locale.h>
You have <langinfo.h>
You have <sys/user.h>
You have <uuid/uuid.h>
You have <rpcsvc/nfs_prot.h>
You have <asm/types.h>
You have <linux/raw.h>
You have <stdint.h>
You have <sys/io.h>
You have inet_aton()
You have fsync()
You have getdomainname()
You have nanosleep()
You have personality()
You have updwtmp()
You have fseeko()
You have lchown()
You have rpmatch()
You have <term.h>
You have ncurses. Using <ncurses.h>.
You don't have termcap
You need -lcrypt
You have <libintl.h> and gettext()
You have __progname
You have <pty.h> and openpty()
You have wide character support
You have SYS_pivot_root
You have a tm_gmtoff field in struct tm
Your rpcgen output does not compile - using pregenerated code
You have zlib
You have blkid
$
通常の configure と同じく環境調査を行ってくれているようですが
以下のように 2箇所エラーが出ています
<scsi/scsi.h> がない
termcap がない

<scsi/scsi.h> がない件については
Linuxカーネルの ヘッダファイルの仕様変更の影響のようです
以下のように書き換えれば当面回避できます

110 #
111 # H1. For fdisk/fdisksunlabel.c: is <scsi/scsi.h> available?
112 #     Some kernels have <scsi/scsi.h> that uses u_char
113 #     But maybe there is already a typedef. Let us use a #define
114 #
115 echo "
116 #define u_char      unsigned char
117 #include <scsi/scsi.h>
118 #undef u_char
119 int main(){ exit(0); }
120 " > conftest.c

↓

110 #
111 # H1. For fdisk/fdisksunlabel.c: is <scsi/scsi.h> available?
112 #     Some kernels have <scsi/scsi.h> that uses u_char
113 #     But maybe there is already a typedef. Let us use a #define
114 #
115 echo "
116 #define u8      unsigned char
117 #include <scsi/scsi.h>
118 #undef u8
119 int main(){ exit(0); }
120 " > conftest.c
u_char を u8 に書き換えるだけです
configureは通りますが fdiskのコンパイルで u8 のキーワードで同様なエラーが出ます
今回 passwd だけコンパイルしたいので 深く考えないことにします

termcapがない問題については
util-linuxが 古い libtermcap をリンクしようとしていて仕様が古いためです
これも configureを一部修正します

451 #
452 # 3. Some systems have /usr/lib/termcap.so -> /usr/lib/termcap.so.2
453 # where however the latter file does not exist. When termcap does
454 # not exist, we can try to compile more with curses instead.
455 #
456 echo '
457 #include <termcap.h>
458 int main(){ exit(0); tgetnum("li"); }
459 ' > conftest.c
460 LIBS=-ltermcap
461 eval $compile
462 LIBS=

↓

451 #
452 # 3. Some systems have /usr/lib/termcap.so -> /usr/lib/termcap.so.2
453 # where however the latter file does not exist. When termcap does
454 # not exist, we can try to compile more with curses instead.
455 #
456 echo '
457 #include <termcap.h>
458 int main(){ exit(0); tgetnum("li"); }
459 ' > conftest.c
460 LIBS=
461 eval $compile
462 LIBS=
-ltermcap の部分を空欄にします
termcap は 改行といった端末画面制御を(様々なシステムに対応できるように)切り替える仕組みです
現在 termcapは terminfoに置き換えられていて libtermcapは不要となり libncursesを使います
n
$ CC=gcc ./configure

configuring util-linux-2.12r

You have <scsi/scsi.h>
You have <linux/blkpg.h>
You have <linux/kd.h>
You have <locale.h>
You have <langinfo.h>
You have <sys/user.h>
You have <uuid/uuid.h>
You have <rpcsvc/nfs_prot.h>
You have <asm/types.h>
You have <linux/raw.h>
You have <stdint.h>
You have <sys/io.h>
You have inet_aton()
You have fsync()
You have getdomainname()
You have nanosleep()
You have personality()
You have updwtmp()
You have fseeko()
You have lchown()
You have rpmatch()
You have <term.h>
You have ncurses. Using <ncurses.h>.
You have termcap
You need -lcrypt
You have <libintl.h> and gettext()
You have __progname
You have <pty.h> and openpty()
You have wide character support
You have SYS_pivot_root
You have a tm_gmtoff field in struct tm
Your rpcgen output does not compile - using pregenerated code
You have zlib
You have blkid
$
You need -lcrypt のメッセージは
「あなたは libcrypt を持っていません」という意味ではなく
「gcc のオプションに -lcrypt が必要なので追加します」 程度の意味なので気にせず先に進みます
$ cd login-utils
$ make passwd
gcc -c -pipe -O2 -mtune=i486 -fomit-frame-pointer -I../lib -Wall -Wmissing-prototypes -Wstrict-prototypes -DNCH=1   -D_FILE_OFFSET_BITS=64 -DSBINDIR=\"/sbin\" -DUSRSBINDIR=\"/usr/sbin\" -DLOGDIR=\"/var/log\" -DVARPATH=\"/var\" -DLOCALEDIR=\"/usr/share/locale\" -O2 passwd.c -o passwd.o
gcc -c -pipe -O2 -mtune=i486 -fomit-frame-pointer -I../lib -Wall -Wmissing-prototypes -Wstrict-prototypes -DNCH=1   -D_FILE_OFFSET_BITS=64 -DSBINDIR=\"/sbin\" -DUSRSBINDIR=\"/usr/sbin\" -DLOGDIR=\"/var/log\" -DVARPATH=\"/var\" -DLOCALEDIR=\"/usr/share/locale\" -O2 islocal.c -o islocal.o
gcc -c -pipe -O2 -mtune=i486 -fomit-frame-pointer -I../lib -Wall -Wmissing-prototypes -Wstrict-prototypes -DNCH=1   -D_FILE_OFFSET_BITS=64 -DSBINDIR=\"/sbin\" -DUSRSBINDIR=\"/usr/sbin\" -DLOGDIR=\"/var/log\" -DVARPATH=\"/var\" -DLOCALEDIR=\"/usr/share/locale\" -O2 setpwnam.c -o setpwnam.o
gcc -s -o passwd passwd.o islocal.o setpwnam.o ../lib/env.o ../lib/xstrncpy.o -lcrypt
$ ls -l passwd*
-rwxr-xr-x  1 admin users 12816 12月 13 00:05 passwd
-rw-r--r--  1 admin users  3178  7月  9  1999 passwd.1
-rw-r--r--  1 admin users 10661  3月  9  2002 passwd.c
-rw-r--r--  1 admin users  8112 12月 13 00:05 passwd.o
うまくコンパイルできました
先ほどの話通り configure に prefix情報が渡せないので インストールは手動で行います
既存の passwd はバックアップをとったほうがよいかもしれません
$ su
# cp passwd /bin/passwd
# chmod 755 /bin/passwd
# cp passwd.1 /usr/share/man/man1/
動作確認もしておきます
# passwd -o mysql
mysql のパスワードを変更します
新パスワードを入力してください。
新パスワードをもう一度入力してください: 
パスワードは変更されました。
# exit
$ make clean
rm -f *.o *~ core  agetty simpleinit shutdown initctl \
        last mesg wall passwd chfn chsh newgrp \
        vipw login
$

MySQLを試してみる

MySQLは 高速性が定評の RDBMS(データベース)です

Linuxへのインストールと実際の利用状況をレポートします
ちなみに 64bit環境の検証や IPv6対応検証を兼ねていますが
結論から言って IPv6対応はしていません

検証環境
2009年
CPU AMD Turion 64 MT-37 (2GHz)
メモリ 1GB
OS Gentoo-1.4.16ベース Linux-2.6.30.5 EUC-JP
コンパイラ gcc-4.1.2
Cライブラリ glibc-2.5
MySQL mysql-5.1.41
Berkley DB db-4.8.24.NC
2011年
CPU AMD PhenomII X4 905e (2.5GHz 4コア)
メモリ 16GB
OS Gentoo-1.12.14ベース Linux-3.0 UTF-8
コンパイラ gcc-4.5.2
Cライブラリ glibc-2.13
MySQL Community Server 5.5.15
MySQL Workbench 5.2.34
Berkley DB db-5.1.25.NC

MySQLとは

有名で高性能なデータベースです
MySQL AB社 → SUNOracle と買収されて 結局 Oracleの一員となってしまっています
オープンソースですが 企業の巨大データベースなどに使わないのであれば 十分な性能を持っています

日本では PostgreSQLと同じくらい有名です

インストール

ここでのインストール作業は 主に以下の流れを解説しています
  • MySQLソースパッケージのダウンロード
  • ソースコードからのビルドと MySQLバイナリファイル郡のインストール
  • my.cnf環境設定 start/stop起動スクリプトの設定
  • データベース領域の新規作成
  • mysqldの起動
  • MySQL管理者権限のアクセス権限設定
早速 MySQLサイトからソースコードをダウンロードします
MySQLサイト 2009年
上記は 2009年のときのWeb構成です
Communication Server というのが GPL版の MySQL本体となります

OSが RPM系などパッケージシステムであれば 各バイナリパッケージもあるので
そちらを活用したほうがよいでしょう
(今回扱いませんが 商用ライセンスとして Enterprise版 が存在します)
MySQLサイト 2011年
2011年に訪れたときは オープンソース版のバリエーションが拡充され充実したイメージがあります
Enterprise版の表記はなくなっていました (商用サポートを受けられる契約は残っているようです)

Community Server というのが今回ダウンロードする対象です
Clusterは 文字どおりクラスタ構成で可用性を向上させるのに特化したパッケージです
Workbenchは データベースモデリングツールで GUIでテーブル設計 MySQLへのDB化が可能です
Proxyは サーバクライアント間に介在しモニタリング機能やロードバランス機能を提供します
Connectorsは ODBCや JDBCと互換のデータベースドライバです
Installerは 上記のWindows版を 1パックにまとめたものです
これだけ見ても 個人/商用どちらにも耐えられそうなラインナップです
MySQLサイト Community Server 2011年
検証環境では Community Serverをソースからインストールしました
GAリリースタブで Platformを Source Codeに設定すると Generic Linux版が見えます

下記は mysql-5.1.41版でのビルド設定ログです

$ tar -xzf mysql-5.1.41.tar.gz
$ cd mysql-5.1.41
$ ls
BUILD               Makefile.in     configure     libmysqld   regex          tests
CMakeLists.txt      README          configure.in  ltmain.sh   scripts        unittest
COPYING             aclocal.m4      dbug          man         server-tools   vio
ChangeLog           client          depcomp       missing     sql            win
Docs                cmd-line-utils  extra         mysql-test  sql-bench      ylwrap
EXCEPTIONS-CLIENT   config          include       mysys       sql-common     zlib
INSTALL-SOURCE      config.guess    install-sh    netware     storage
INSTALL-WIN-SOURCE  config.h.in     libmysql      plugin      strings
Makefile.am         config.sub      libmysql_r    pstack      support-files
$
 

通常の configure系のアプリケーションと同じくビルドできそうです

$ ./configure --prefix=/usr/local --with-charset=ujis --with-extra-charsets=utf8 --with-mysqld-user=mysql
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking target system type... i686-pc-linux-gnu
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking "character sets"... default: ujis, collation: ujis_japanese_ci; compiled in: ujis latin1 utf8 utf8
…
…
config.status: creating include/mysql_version.h
config.status: creating plugin/Makefile
config.status: creating win/Makefile
config.status: creating include/config.h
config.status: executing depfiles commands
config.status: executing libtool commands
/bin/rm: cannot remove `libtoolT': No such file or directory
config.status: executing default commands

MySQL has a Web site at http://www.mysql.com/ which carries details on the
latest release, upcoming features, and other information to make your
work or play with MySQL more productive. There you can also find
information about mailing lists for MySQL discussion.

Remember to check the platform specific part of the reference manual for
hints about installing MySQL on your platform. Also have a look at the
files in the Docs directory.

Thank you for choosing MySQL!

$
 

文字コードは 各自のOSの環境に合わせて設定します
検証の環境では EUC-JP なので ujis を その他として(念のため?) UTF-8 も指定しています
また MySQL専用のユーザアカウント mysql:mysql を指定しています

下記は mysql-5.5.15版でのビルド設定ログです

$ tar -xzf mysql-5.5.15.tar.gz
$ cd mysql-5.5.15
$ ls -F
BUILD/              VERSION          include/      plugin/      support-files/
BUILD-CMAKE         client/          libmysql/     regex/       tests/
CMakeLists.txt      cmake/           libmysqld/    scripts/     unittest/
COPYING             cmd-line-utils/  libservices/  sql/         vio/
Docs/               config.h.cmake   man/          sql-bench/   win/
INSTALL-SOURCE      configure.cmake  mysql-test/   sql-common/  zlib/
INSTALL-WIN-SOURCE  dbug/            mysys/        storage/
README              extra/           packaging/    strings/
$
 

mysql-5.5系からは cmakeによる構築が推奨されています

$ cmake -DCMAKE_INSTALL_PREFIX=/usr/mysql -DMYSQL_DATADIR=/var/db/mysql -DSYSCONFDIR=/usr/mysql/etc -DWITH_READLINE=ON .
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++

〜

-- Check size of pthread_t
-- Check size of pthread_t - done
-- Performing Test HAVE_PEERCRED
-- Performing Test HAVE_PEERCRED - Success
-- Configuring done
-- Generating done
-- Build files have been written to: /home/admin/mysql-5.5.15
$
 

以上で Makefileが生成されました
後は make と make install でインストールされます

configure に –help をつけるか cmake -L で分かりますが
MySQLではデータベースストレージ方式が自由に選択できます 以下一部紹介します

エンジン 説明
MyISAM トランザクションが使えない デフォルトのエンジン
InnoDB 元々 Innobase社が開発していたエンジン トランザクションが使える
Memory 全部メモリに展開 速そう
Merge 複数の MyISAMを 1つのデータベースグループとして扱う
Federated 分散配置されたサーバでの利用 分散データベースを実現
NDB クラスタデータベース 耐障害性はよいかも
CSV CSVを直接扱う?

他にも Blackhole(格納されたデータは破棄?)といった 開発向けとしか思えないエンジンなど
ありますが MyISAM以外は未検証です

 

bin/ には以下のコマンドが追加されます

innochecksum       mysql_convert_table_format  mysql_zap      mysqlhotcopy
msql2mysql         mysql_find_rows             mysqlaccess    mysqlimport
my_print_defaults  mysql_fix_extensions        mysqladmin     mysqlshow
myisam_ftdump      mysql_fix_privilege_tables  mysqlbinlog    mysqlslap
myisamchk          mysql_install_db            mysqlbug       mysqltest
myisamlog          mysql_secure_installation   mysqlcheck     perror
myisampack         mysql_setpermission         mysqld_multi   replace
mysql              mysql_tzinfo_to_sql         mysqld_safe    resolve_stack_dump
mysql_client_test  mysql_upgrade               mysqldump      resolveip
mysql_config       mysql_waitpid               mysqldumpslow
 

libexec/ には次のサーバプログラムが追加されます

mysqld  mysqlmanager
 

lib/ 以下には以下のように データベースエンジンのライブラリが追加されます

/usr/local/lib/mysql/:
libdbug.a         libmysqlclient.la         libmysqlclient_r.la         libmysys.a
libheap.a         libmysqlclient.so         libmysqlclient_r.so         libvio.a
libmyisam.a       libmysqlclient.so.16      libmysqlclient_r.so.16      plugin
libmyisammrg.a    libmysqlclient.so.16.0.0  libmysqlclient_r.so.16.0.0
libmysqlclient.a  libmysqlclient_r.a        libmystrings.a

/usr/local/lib/mysql/plugin:
ha_archive.a           ha_example.so.0.0.0    ha_innodb_plugin.so.0
ha_archive.la          ha_federated.a         ha_innodb_plugin.so.0.0.0
ha_archive.so          ha_federated.la        libdaemon_example.a
ha_archive.so.0        ha_federated.so        libdaemon_example.la
ha_archive.so.0.0.0    ha_federated.so.0      libdaemon_example.so
ha_blackhole.a         ha_federated.so.0.0.0  libdaemon_example.so.0
ha_blackhole.la        ha_innodb.a            libdaemon_example.so.0.0.0
ha_blackhole.so        ha_innodb.la           mypluglib.a
ha_blackhole.so.0      ha_innodb.so           mypluglib.la
ha_blackhole.so.0.0.0  ha_innodb.so.0         mypluglib.so
ha_example.a           ha_innodb.so.0.0.0     mypluglib.so.0
ha_example.la          ha_innodb_plugin.a     mypluglib.so.0.0.0
ha_example.so          ha_innodb_plugin.la
ha_example.so.0        ha_innodb_plugin.so
 

また mysql-test/ sql-bench/ といった
性能評価に関するディレクトリが追加されます

続いて my.cnf 設定ファイルを作成します次の設定を行うためです

  • データベースディレクトリの場所を /usr/local/var/mysql/ から /var/db/mysql/ にカスタマイズ
  • PID情報ファイルの置き場所を /usr/local/var/ホスト名.pid から /var/run/mysql.pid にカスタマイズ
  • エラーログファイルの置き場所を /usr/local/var/ホスト名.err から /var/log/mysql.err にカスタマイズ
  • 一時ディレクトリの場所も /tmp/ 以下にカスタマイズ

/etc/my.cnf を以下の内容で作成しました

[mysqld]
user=mysql
datadir=/var/db/mysql
socket=/tmp/mysql.sock
tmpdir=/tmp/mysql
pid-file=/var/run/mysql.pid
log-error=/var/log/mysql
max_connections=10
thread_concurrency=1
query_cache_size=0
key_buffer=32M
sort_buffer=512K
myisam_sort_buffer_size=64M
 

バッファ(メモリ)サイズの設定も行っていますが 最小限度の設定です
業務や Web公開などで MySQLを本格的に使うには さらにカスタマイズする必要あります

tmpdir のカスタマイズには注意点があります
指定したディレクトリが 存在しなかったり mysql権限でアクセスできないと不具合が出ます
また データベースの初期化に失敗したり SELECT等の DDL処理に失敗します
ディレクトリの場所を変更したため 以下のように tmpdir を作成します

# mkdir /tmp/mysql
# chown mysql /tmp/mysql
# chmod 700 /tmp/mysql
# 
 

続いて データベースを初期化します root権限で実施します

# mysql_install_db --user=mysql --datadir=/var/db/mysql
Installing MySQL system tables...
OK
Filling help tables...
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

/usr/local/bin/mysqladmin -u root password 'new-password'
/usr/local/bin/mysqladmin -u root -h myhost.mydomain password 'new-password'

Alternatively you can run:
/usr/local/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:
cd /usr/local ; /usr/local/bin/mysqld_safe &

You can test the MySQL daemon with mysql-test-run.pl
cd /usr/local/mysql-test ; perl mysql-test-run.pl

Please report any problems with the /usr/local/bin/mysqlbug script!

The latest information about MySQL is available at http://www.mysql.com/
Support MySQL by buying support/licenses from http://shop.mysql.com/

# ls -R /var/db/mysql/
/var/db/mysql/:
mysql  test

/var/db/mysql/mysql:
columns_priv.MYD   help_relation.frm     slow_log.CSV
columns_priv.MYI   help_topic.MYD        slow_log.frm
columns_priv.frm   help_topic.MYI        tables_priv.MYD
db.MYD             help_topic.frm        tables_priv.MYI
db.MYI             host.MYD              tables_priv.frm
db.frm             host.MYI              time_zone.MYD
event.MYD          host.frm              time_zone.MYI
event.MYI          ndb_binlog_index.MYD  time_zone.frm
event.frm          ndb_binlog_index.MYI  time_zone_leap_second.MYD
func.MYD           ndb_binlog_index.frm  time_zone_leap_second.MYI
func.MYI           plugin.MYD            time_zone_leap_second.frm
func.frm           plugin.MYI            time_zone_name.MYD
general_log.CSM    plugin.frm            time_zone_name.MYI
general_log.CSV    proc.MYD              time_zone_name.frm
general_log.frm    proc.MYI              time_zone_transition.MYD
help_category.MYD  proc.frm              time_zone_transition.MYI
help_category.MYI  procs_priv.MYD        time_zone_transition.frm
help_category.frm  procs_priv.MYI        time_zone_transition_type.MYD
help_keyword.MYD   procs_priv.frm        time_zone_transition_type.MYI
help_keyword.MYI   servers.MYD           time_zone_transition_type.frm
help_keyword.frm   servers.MYI           user.MYD
help_relation.MYD  servers.frm           user.MYI
help_relation.MYI  slow_log.CSM          user.frm

/var/db/mysql/test:
#
 

この作業で データ格納領域の初期化が完了します
領域はディレクトリ /var/db/mysql/ を指定しています

mysql-5.5系では mysql_initall_db は scripts/ の中に入っているので

# cd /usr/mysql
# scripts/mysql_install_db --user=mysql --datadir=/var/db/mysql
 

とする必要があります

mysqlデータベース (MySQLのシステムテーブルが入る) と testデータベース(空) が確認できます
ディレクトリには 3種類のファイルが データベーステーブル毎に作成されています
.frm はテーブル定義 .MYD はデータ内容 .MYI はインデックスデータ を保持します
(これらファイルは ISAMデータベース形式によるもの)

ちなみに データベース領域の削除方法は
mysqld が停止した状態で ディレクトリ削除(rm -r)するだけです

いよいよ データベースサーバ(mysqld)の起動です
ここでは 主に mysql-5.5.15 (2011年9月検証)での動作状況を記載します

mysqld を起動/停止できる start/stopスクリプトが support-files/mysql.server
として準備されてるので 必要なら OS起動時に start引数付で呼ばれるようにします

検証の環境の例では Gentooベースなので
以下の内容で /etc/init.d/mysql (root:root 0755) を作成しました

#!/sbin/runscript
# Copyright 1999-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header$

depend() {
        need net.eth0
        after apache
        provide mysql
}

start() {
        ebegin "Starting MySQL"
        /usr/local/share/mysql/mysql.server start
        eend $?
}

stop() {
        ebegin "Stopping MySQL"
        /usr/local/share/mysql/mysql.server stop
        eend $?
}

restart() {
        ebegin "Restarting MySQL"
        /usr/local/share/mysql/mysql.server restart
        eend $?
}

status() {
        /usr/local/share/mysql/mysql.server status
        exit $?
}
 

mysqldの環境設定は etc/my.cnf で設定済です
(mysql.server の呼び出しでオプション –pid-file= が使えるらしいですが
検証環境では 効果が確認できませんでした)

start/stopスクリプトの準備ができたので 間違いなく動くか確認します

# /etc/init.d/mysql start
 * Starting MySQL ...
Starting MySQL.. SUCCESS!                                                 [ ok ]
# /etc/init.d/mysql status
 * status:  started
 SUCCESS! MySQL running (22777)
# /etc/init.d/mysql stop
 * Stopping MySQL ...
Shutting down MySQL. SUCCESS!                                             [ ok ]
# /etc/init.d/mysql status
 * status:  stopped
 ERROR! MySQL is not running
# /etc/init.d/mysql start
 * Starting MySQL ...
Starting MySQL.. SUCCESS!                                                 [ ok ]
#
 

次にアクセス権限の設定を行います
まず次の操作を試してみて アクセス権限の有無が調査できます

$ mysql -u root -e 'select Host,User,Password,Select_priv from mysql.user;'
+-----------+------+----------+-------------+
| Host      | User | Password | Select_priv |
+-----------+------+----------+-------------+
| localhost | root |          | Y           |
| phenom    | root |          | Y           |
| 127.0.0.1 | root |          | Y           |
| ::1       | root |          | Y           |
| localhost |      |          | N           |
| phenom    |      |          | N           |
+-----------+------+----------+-------------+
$ mysql -u root -e 'select Host,Db,User,Select_priv from mysql.db;'
+------+---------+------+-------------+
| Host | Db      | User | Select_priv |
+------+---------+------+-------------+
| %    | test    |      | Y           |
| %    | test\_% |      | Y           |
+------+---------+------+-------------+
$ 
 

アクセス権限は mysqlデータベース内のシステムテーブルで管理されています
上記は その一部のテーブルの内容を表示してみたものです

mysql.user は 「どの接続元から どのアカウントでアクセスしてきたとき どのパスワードで どんなデータベース管理操作を許可するか」
mysql.db は 「どのアカウントに対して どのデータベーステーブルへの どんな操作を許可するか」
を管理しています

上記のように当初から設定させれている権限は mysql_install_db時に自動設定されたものです
User が空白になっているのは 「アカウント指定なしでの接続 もしくは 間違った指定がされた」場合に該当します

ここでの注意点は

  • 他ホストからの接続について 許可設定がないので接続できない
  • rootアカウントに対して パスワードが設定されてない
  • testデータベースに対して アカウントが省略された状態でも 自由にデータ操作ができてしまう
  • Hostに phenom(IPv6ホスト名) や ::1 があるのでIPv6対応を期待させるが 実は対応していない

IPv6については mysqldが IPv6のプロトコルでlistenしていません 下記の通りです

$ netstat -ln -Ainet6
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp6       0      0 :::389                  :::*                    LISTEN     
tcp6       0      0 :::139                  :::*                    LISTEN     
tcp6       0      0 :::22                   :::*                    LISTEN     
tcp6       0      0 ::1:25                  :::*                    LISTEN     
$
 

MySQLのサービスポートである tcp6/3306 がそもそも開いていません
(ただし IPv4射影IPv6を有効にすると tcp46/3306 が開いたため
IPv4射影IPv6で環境が作れるかもしれません 時間が作れれば実験してみます)

アカウントについては実際の運用で rootアカウントに対してパスワードを設定する必要があるのと
testデータベースが 無アカウント に対して自由に操作できてしまう部分を検討する必要があります

$ mysqladmin -u root password 'root'
$ mysql -u root -p -e 'select Host,User,Password,Select_priv from mysql.user;'
Enter password:
+-----------+------+-------------------------------------------+-------------+
| Host      | User | Password                                  | Select_priv |
+-----------+------+-------------------------------------------+-------------+
| localhost | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y           |
| phenom    | root |                                           | Y           |
| 127.0.0.1 | root |                                           | Y           |
| ::1       | root |                                           | Y           |
| localhost |      |                                           | N           |
| phenom    |      |                                           | N           |
+-----------+------+-------------------------------------------+-------------+
$ 
 

パスワード設定後 rootアカウントで接続する場合はパスワード入力が必須となるので
以後mysqlに -p オプションをつけて パスワードも通知する必要がでてきます

mysql.userテーブルで rootパスワードが反映されているのは Host=’localhost’ and User=’root’ の行のみです

127.0.0.1 の行は 内部で 'localhost'として扱われてしまっていて
(localhost=127.0.0.1 と扱われるのは MySQLの仕様なのか Linuxの仕様なのかは分かりません)
mysql -h 127.0.0.1 -u root で接続しようとしても localhost のパスワードが使われます
従ってこの行自体 存在する必要性はありません

また phenom や ::1 もそれぞれ IPv6のホスト名とアドレスなので
これも現時点では必要性はありません

データベース利用

下記内容を具体的に実践してみます

  • アカウントの作成
  • データベースの作成
  • サンプルデータの投入
  • 投入されたデータの確認
  • Webとの連携

アカウントの作成

gamer というアカウント を gamer というパスワードで作成し
games というデータベースに TVゲームのデータを格納するのが目的です

通常のアカウントの作成方法は

$ mysql -p -u root
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> grant select,update,insert,delete,create,drop on test.* to gamer;
Query OK, 0 rows affected (0.00 sec)

mysql> set password for gamer = password ( 'gamer' );
Query OK, 0 rows affected (0.00 sec)

mysql> 
 

ですが 別の方法も紹介します SQL文だけで同等のアカウント権限処理ができます

$ mysql -p -u root
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 40
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> insert into mysql.user ( host, user, password ) values ( 'localhost', 'gamer', password ( 'gamer' ) );
Query OK, 1 row affected, 3 warnings (0.00 sec)

mysql> insert into mysql.db ( host, db, user, select_priv, insert_priv, update_priv, delete_priv, create_priv, drop_priv, references_priv, index_priv, alter_priv, create_tmp_table_priv, lock_tables_priv, create_view_priv, show_view_priv, create_routine_priv, alter_routine_priv, execute_priv, event_priv, trigger_priv ) values ( '%', 'games', 'gamer', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y' );
Query OK, 1 row affected (0.00 sec)

mysql >
 

上記は 直接システムテーブルを修正することで grant文と同等の権限付与を行っています
結果として MySQLのシステムテーブルは下記の通り gamerエントリが追加されています

mysql> select host, user, password, select_priv, insert_priv, update_priv, delete_priv from mysql.user;
+-----------+-------+-------------------------------------------+-------------+
| Host      | User  | Password                                  | Select_priv |
+-----------+-------+-------------------------------------------+-------------+
| localhost | root  | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y           |
| phenom    | root  | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y           |
| 127.0.0.1 | root  |                                           | Y           |
| ::1       | root  |                                           | Y           |
| localhost |       |                                           | N           |
| phenom    |       |                                           | N           |
| localhost | gamer | *2EFB46DA4D8A878D81274BD79E0830422C170CC1 | N           |
+-----------+-------+-------------------------------------------+-------------+
7 rows in set (0.00 sec)

mysql> select host, db, user, select_priv, insert_priv, update_priv, delete_priv from mysql.db;
+------+---------+-------+-------------+-------------+-------------+-------------+
| host | db      | user  | select_priv | insert_priv | update_priv | delete_priv |
+------+---------+-------+-------------+-------------+-------------+-------------+
| %    | test    |       | Y           | Y           | Y           | Y           |
| %    | test\_% |       | Y           | Y           | Y           | Y           |
| %    | games   | gamer | Y           | Y           | Y           | Y           |
+------+---------+-------+-------------+-------------+-------------+-------------+
3 rows in set (0.00 sec)

mysql> \q
$ mysqladmin -p -u root flush-privileges
Enter password: 
$ 
 

最後に mysqladmin flush-privileges で権限関連の設定をシステムに反映させる必要があります
これで localhostから gamerアカウントで接続が可能になっています

1つ目の insertだけでも mysql mysqlshow mysqladmin の接続が可能になります
(mysql.userテーブルの設定一覧で 全デフォルト操作が禁止されていますが
testデータベースへはアクセスできます)
2つ目の insertが長いですが 上記 gamerに対して gamesデータベースで GRANT REVOKE 以外の操作を許可しています
(mysql.dbテーブルの設定一覧で user=” の行で
testデータベースへのアクセス許可設定が入っているので
gamerアカウントでも testへのアクセスが可能です)
最後に アクセス権限に関するデータを直接修正しているので
mysqladmin flush-privileges コマンドで データの内容を MySQLに反映させる必要があります

データベースの作成

事前確認として mysqlshowコマンドを使って 現在のデータベースを一覧表示してみます

$ mysqlshow -p -u gamer
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
+--------------------+
$
 

information_schema は MySQLの動作ステータス情報をデータベース化したものです
MEMORYエンジンのため MySQLのサーバ終了と共に消えます
mysql や performance_schemaデータベースが一覧にないのは アクセス権限がないためです


gamerアカウントには既に gamesデータベースへの create drop 権限が設定されているので

$ mysql -p -u gamer
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 68
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database games default character set utf8;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| games              |
| test               |
+--------------------+
3 rows in set (0.00 sec)

mysql> \q
Bye
$ 
 

games データベースの存在が確認できました
showコマンドは 標準のSQL構文ではなく MySQL独自の文法です

またcreate database をする際に default character set utf8 をつけないと
文字化けする可能性があります
(show variables; で表示される下記 文字コードパラメータが不一致だと
mysqlが文字コード変換をかけようとするため注意が必要です
character_set_connection
character_set_database )


次に テーブルを作りますが その前にテーブルのフォーマットを検討するために
サンプルデータ tvgames.zip を用意しました (EUC-JPのテキストです)
サンプルデータの先頭 10行を確認します

$ unzip tvgames.zip
Archive:  tvgames.zip
  inflating: tvgames.txt             
$ head -n 10 tvgames.txt
ドンキーコング,FC,任天堂,4500,1983-07-15
ドンキーコングJR.,FC,任天堂,4500,1983-07-15
ポパイ,FC,任天堂,4500,1983-07-15
五目ならべ [連珠],FC,任天堂,4500,1983-08-27
麻雀,FC,任天堂,4500,1983-08-27
マリオブラザーズ,FC,任天堂,4500,1983-09-09
ポパイの英語遊び,FC,任天堂,4500,1983-11-22
ベースボール,FC,任天堂,4500,1983-12-07
ドンキーコングJR. の算数遊び,FC,任天堂,4500,1983-12-12
テニス,FC,任天堂,4500,1984-01-14
$ 
 

テレビゲームの歴代タイトルが納められたテキストです ファミコン以外にもあります
テキストは カンマ区切りで タイトル,プラットホーム,メーカー,値段,発売日 となっています

(サンプルデータは インターネット上の某所から拾ったものですが どこからかは忘れてしまいました)

テーブルもこのフォーマットに合わせて作ることにしますが
その前に このテキストを変換します sedコマンドを使って正規表現による置換を行います

$ sed "s/'/\\\\\\\\'/g" tvgames.txt | sed "s/^\\(.*\\),\\(.*\\),\\(.*\\),\\(.*\\),\\(.*\\)$/insert into tvgames ( name, plathome, company, price, release_date ) values ( '\\1', '\\2', '\\3', \\4, '\\5' );/" | iconv -f euc-jp -t utf-8 > tvgame_insert.txt
$ head -n 10 tvgame_insert.txt
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ドンキーコング', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ドンキーコングJR.', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ポパイ', 'FC', '任天堂', 4500, '1983-07-15' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '五目ならべ [連珠]', 'FC', '任天堂', 4500, '1983-08-27' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( '麻雀', 'FC', '任天堂', 4500, '1983-08-27' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'マリオブラザーズ', 'FC', '任天堂', 4500, '1983-09-09' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ポパイの英語遊び', 'FC', '任天堂', 4500, '1983-11-22' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ベースボール', 'FC', '任天堂', 4500, '1983-12-07' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'ドンキーコングJR. の算数遊び', 'FC', '任天堂', 4500, '1983-12-12' );
insert into tvgames ( name, plathome, company, price, release_date ) values ( 'テニス', 'FC', '任天堂', 4500, '1984-01-14' );
$ 
作成した tvgame_insert.txt を流し込む形でテーブルを作成します
$ mysql -p -u gamer
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 69
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.

mysql> use games
Database changed
mysql> create table tvgames ( name text, plathome text, company text, price int, release_date date );
Query OK, 0 rows affected (0.00 sec)

mysql> show columns from tvgames;
+--------------+---------+------+-----+---------+-------+
| Field        | Type    | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+-------+
| name         | text    | YES  |     | NULL    |       |
| plathome     | text    | YES  |     | NULL    |       |
| company      | text    | YES  |     | NULL    |       |
| price        | int(11) | YES  |     | NULL    |       |
| release_date | date    | YES  |     | NULL    |       |
+--------------+---------+------+-----+---------+-------+
5 rows in set (0.00 sec)

mysql> \\. tvgame_insert.txt
Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

…

mysql> 
 

うまくいけば 総数 11429レコード分のデータが投入されているはずです

投入したデータはいろいろな SQL文で検索が可能となります

mysql> select * from tvgames limit 10;
+------------------------------+----------+---------+-------+--------------+
| name                         | plathome | company | price | release_date |
+------------------------------+----------+---------+-------+--------------+
| ドンキーコング               | FC       | 任天堂  |  4500 | 1983-07-15   |
| ドンキーコングJR.            | FC       | 任天堂  |  4500 | 1983-07-15   |
| ポパイ                       | FC       | 任天堂  |  4500 | 1983-07-15   |
| 五目ならべ [連珠]            | FC       | 任天堂  |  4500 | 1983-08-27   |
| 麻雀                         | FC       | 任天堂  |  4500 | 1983-08-27   |
| マリオブラザーズ             | FC       | 任天堂  |  4500 | 1983-09-09   |
| ポパイの英語遊び             | FC       | 任天堂  |  4500 | 1983-11-22   |
| ベースボール                 | FC       | 任天堂  |  4500 | 1983-12-07   |
| ドンキーコングJR. の算数遊び | FC       | 任天堂  |  4500 | 1983-12-12   |
| テニス                       | FC       | 任天堂  |  4500 | 1984-01-14   |
+------------------------------+----------+---------+-------+--------------+
10 rows in set (0.00 sec)

mysql>
 

データベース上の先頭から 10件
ファミコンが発売された当時 ドンキーコング と ドンキーコングJr. のクオリティの高さに驚きました

mysql> select * from tvgames where release_date between '1995-4-1' and '1995-5-1';
+-------------------------------------------------------------+--------------------+------------------------------------------+-------+--------------+
| name                                                        | plathome           | company                                  | price | release_date |
+-------------------------------------------------------------+--------------------+------------------------------------------+-------+--------------+
| EMIT Vol.2〜命がけの旅〜                                    | SS                 | 光栄                                     |  8800 | 1995-04-01   |
| EMIT Vol.3〜私にさよならを〜                                | SS                 | 光栄                                     |  8800 | 1995-04-01   |
| デイトナUSA                                                 | SS                 | セガ                                     |  6800 | 1995-04-01   |
| レディーストーカー〜過去からの挑戦〜                        | SFC                | タイトー                                 |  9980 | 1995-04-01   |
| Dの食卓                                                     | 3DO                | 三栄書房                                 |  8800 | 1995-04-01   |
| 蒼き伝説シュート!                                           | GB                 | バンプレスト                             |  3980 | 1995-04-07   |
| THE クイズ ギアファイト!                                    | GG                 | セガ                                     |  3800 | 1995-04-07   |
| クイズ キング・オブ・ファイターズ                           | NG(CD)             | ザウルス                                 |  5800 | 1995-04-07   |
| 得点王3                                                     | NG                 | SNK                                      | 29800 | 1995-04-07   |
| フォーメーションサッカー95 della セリエA                    | PCE(SCDR2)(AC対応) | ヒューマン                               |  9800 | 1995-04-07   |
| 全日本プロレス2 3・4武闘館                                  | SFC                | 日本コンピュータシステム                 | 10800 | 1995-04-07   |
| ドラえもん 友情伝説                                         | 3DO                | 小学館                                   |  7800 | 1995-04-07   |
| SD飛龍の拳外伝                                              | GB                 | カルチャーブレーン                       |  4700 | 1995-04-14   |
| 勝馬予想 競馬貴族EX'95                                      | GB                 | キングレコード                           |  6900 | 1995-04-14   |
| ワールドヒーローズ2                                         | NG(CD)             | ADK                                      |  5800 | 1995-04-14   |
| パチ夫くん パチンコランド大冒険                             | PS                 | ココナッツジャパン                       |  6800 | 1995-04-14   |
| 柿木将棋                                                    | SS                 | アスキー                                 |  7800 | 1995-04-14   |
| ぱずるんでス!                                               | SFC                | 日本物産                                 |  8980 | 1995-04-14   |
| RES ARCANA                                                  | SFC                | ココナッツジャパン                       |  9500 | 1995-04-14   |
| EMIT Vol.1 時の迷子                                        | 3DO                | 光栄                                     |  8800 | 1995-04-14   |
| デビルズコース                                              | 3DO                | 松下電器                                 |  8800 | 1995-04-14   |
| パドックノート’95                                          | 3DO                | フジテレビジョン                         |  8800 | 1995-04-14   |
| MYST                                                        | 3DO                | マイクロキャビン                         |  7800 | 1995-04-14   |
| Jリーグ ライブ'95                                           | GB                 | エレクトロニック・アーツ・ビクター       |  5980 | 1995-04-21   |
| カオティクス                                                | 32X                | SEGA                                     |  7800 | 1995-04-21   |
| 餓狼伝説3 ROAD TO THE FINALVICTORY                          | NG                 | SNK                                      | 32000 | 1995-04-21   |
| ギャラクシーファイト UNIVERSAL WARRIORS                     | NG(CD)             | サンソフト                               |  7800 | 1995-04-21   |
| サイバーリップ                                              | NG(CD)             | SNK                                      |  5800 | 1995-04-21   |
| ファイヤースープレックス                                    | NG(CD)             | SNK                                      |  5800 | 1995-04-21   |
| ベースボールスターズプロフェッショナル                      | NG(CD)             | SNK                                      |  4800 | 1995-04-21   |
| ロボアーミー                                                | NG(CD)             | SNK                                      |  5800 | 1995-04-21   |
| 金沢将棋'95                                                 | PS                 | セタ                                     |  7900 | 1995-04-21   |
| ママレード・ボーイ                                          | SFC                | バンダイ                                 |  9800 | 1995-04-21   |
| 魔法陣グルグル                                              | SFC                | エニックス                               | 10800 | 1995-04-21   |
| タクティカルサッカー                                        | SFC                | エレクトロニックアーツビクター           |  9800 | 1995-04-21   |
| なつきクライシスバトル                                      | SFC                | エンジェル                               | 10800 | 1995-04-21   |
| 真・聖刻                                                    | SFC                | ユタカ                                   |  9800 | 1995-04-21   |
| 真SD戦国伝 大将軍列伝                                       | SFC                | ベック                                   |  9800 | 1995-04-21   |
| スーパーリアル麻雀P5 パラダイス オールスター4人打ち         | SFC                | セタ                                     |  9800 | 1995-04-21   |
| リジョイス〜アレサ王国の彼方〜                              | SFC                | やのまん                                 |  9900 | 1995-04-21   |
| 宮路社長のパチンコファン勝利宣言2                           | SFC                | POW                                      |  9800 | 1995-04-21   |
| スーパートランプコレクション                                | SFC                | ボトムアップ                             |  8900 | 1995-04-21   |
| 紺碧の艦隊                                                  | 3DO                | 徳間書店                                 |  8800 | 1995-04-21   |
| ぼのぐらし                                                  | 3DO                | アミューズ/バンダイビジュアル           |  8800 | 1995-04-21   |
| ポリスノーツ パイロットディスク                             | 3DO                | コナミ                                   |  2980 | 1995-04-21   |
| パズルボブル                                                | NG(CD)             | タイトー                                 |  6800 | 1995-04-27   |
| 赤ずきんチャチャ                                            | GB                 | トミー                                   |  3900 | 1995-04-28   |
| 空想科学少年ガリバーボーイ 空想科学パズル プリッとポン      | GB                 | バンダイ                                 |  3980 | 1995-04-28   |
| チキチキ天国                                                | GB                 | J・ウイング                              |  3900 | 1995-04-28   |
| パチ夫くん3                                                 | GB                 | ココナッツジャパン                       |  4800 | 1995-04-28   |
| 魔法陣グルグル 勇者とククリの大冒険                         | GB                 | タカラ                                   |  3980 | 1995-04-28   |
| TEMPO Jr.                                                   | GG                 | セガ                                     |  3800 | 1995-04-28   |
| テイルスのスカイパトロール                                  | GG                 | セガ                                     |  3800 | 1995-04-28   |
| テレビアニメスラムダンク 強豪真っ向対決!                    | MD                 | バンダイ                                 |  8800 | 1995-04-28   |
| トゥルーライズ                                              | MD                 | アクレイムジャパン                       |  7800 | 1995-04-28   |
| 餓狼伝説3 ROAD TO THE FINALVICTORY                          | NG(CD)             | SNK                                      |  8800 | 1995-04-28   |
| スロット勝負師                                              | PCE(SCDR2)         | 日本物産                                 |  8500 | 1995-04-28   |
| ガンナーズ ヘブン                                           | PS                 | ソニー・コンピュータエンタテインメント   |  5800 | 1995-04-28   |
| ぐっすんおよよ                                              | PS                 | エクシング                               |  6800 | 1995-04-28   |
| ジャンピングフラッシュ!アロハ男爵ファンキー大作戦の巻       | PS                 | ソニー・コンピュータエンタテインメント   |  5800 | 1995-04-28   |
| ミスランド まちがい探しゲーム                               | PS                 | アルトロン                               |  5800 | 1995-04-28   |
| ヴァーチャル ハイドライド                                   | SS                 | セガ                                     |  5800 | 1995-04-28   |
| アイルトン・セナ パーソナルトーク〜Message for the future〜 | SS                 | セガ                                     |  8800 | 1995-04-28   |
| 輝水晶伝説アスタル                                          | SS                 | セガ                                     |  5800 | 1995-04-28   |
| 三國志4                                                     | SS                 | 光栄                                     | 14800 | 1995-04-28   |
| スーパーボンバーマン3                                       | SFC                | ハドソン                                 |  8900 | 1995-04-28   |
| スーパーパチンコ大戦                                        | SFC                | バンプレスト                             |  6900 | 1995-04-28   |
| 牌勢麻雀 凌駕                                               | SFC                | アスキー                                 | 12800 | 1995-04-28   |
| プラネットチャンプ TG3000                                   | SFC                | ケムコ                                   |  9500 | 1995-04-28   |
| Jリーグエキサイトステージ'95                                | SFC                | エポック社                               |  9800 | 1995-04-28   |
| 川のぬし釣り2                                               | SFC                | パックインビデオ                         | 10800 | 1995-04-28   |
| シミュレーションプロ野球                                    | SFC                | ヘクト                                   | 12800 | 1995-04-28   |
| トゥルーライズ                                              | SFC                | アクレイムジャパン                       | 10900 | 1995-04-28   |
| 3次元格闘ボールズ                                           | SFC                | メディアリング                           |  9800 | 1995-04-28   |
| タロットミステリー                                          | SFC                | ヴィジット                               |  9800 | 1995-04-28   |
| 初段位認定 初段プロ麻雀                                     | SFC                | ギャップス                               |  9800 | 1995-04-28   |
| バーチャルカメラマンPart3                                   | 3DO                | ナグザット                               |  8800 | 1995-04-28   |
| ワールドカップ スーパースタジアム                           | 3DO                | テレビ東京/ギャガ・コミュニケーションズ |  6800 | 1995-04-28   |
+-------------------------------------------------------------+--------------------+------------------------------------------+-------+--------------+
78 rows in set (0.01 sec)

mysql>

1995年4月1日〜5月1日 の間に発売されたソフトです (78本も)
当時はちょうど 新旧ハードの世代交替の時期であり 多種のハードが入り混じっています

mysql> select plathome, count( name ) from tvgames group by plathome;
+------------------------+---------------+
| plathome               | count( name ) |
+------------------------+---------------+
| 32X                    |            18 |
| 3DO                    |           215 |
| 64DD                   |             7 |
| ARCADE CARD専用        |            12 |
| FC                     |          1042 |
| FCD                    |           195 |
| FC周辺ソフト           |             9 |
| GB                     |           767 |
| GBC                    |           142 |
| GB&GBC                |           201 |
| GG                     |           196 |
| MCD                    |           110 |
| MD                     |           416 |
| N64                    |           200 |
| NG                     |           117 |
| NG(CD)                 |            99 |
| PCE                    |           229 |
| PCE(CDR2)              |            92 |
| PCE(CDR2)(S対応)       |            12 |
| PCE(SCDR2)             |           235 |
| PCE(SCDR2)(AC対応)     |            16 |
| PCE(SG)                |             4 |
| PS                     |          4439 |
| SFC                    |          1391 |
| SFC(NP)                |            33 |
| SS                     |          1212 |
| VB                     |            19 |
| ※バーコードボーイ同梱 |             1 |
+------------------------+---------------+
28 rows in set (0.14 sec)

mysql>
 

SQLの group by 構文で集計を行えます
上記は プラットホーム毎のソフト本数の集計です
PlayStationが圧倒的です

最後に tvgamesテーブルを 2つ結合して検索をかける複雑な検索の例です

名称の先頭部分が一致することを条件にして 5作以上シリーズ化されているゲームを抜き出そうとしてます
例えば「ドラゴンクエスト」をベース名として「ドラゴンクエスト2」「ドラゴンクエスト3」…
を抜き出そうとしています

mysql> select gbase.name, gelement.name, gelement.release_date, gelement.plathome, gelement.price from ( select distinct name from  tvgames ) as gbase, tvgames gelement where octet_length( gbase.name ) > 3 and left( gelement.name, char_length( gbase.name ) ) = gbase.name and ( select count( name ) from tvgames gsub where gbase.name != gsub.name and left( gsub.name, char_length( gbase.name ) ) = gbase.name ) >= 4 order by gbase.name, gelement.release_date;

〜
〜

| 高橋名人の冒険島                                            | 高橋名人の冒険島3                                                                                                                                           | 1993-02-26   | GB                 |  3800 |
| 高橋名人の冒険島                                            | 高橋名人の冒険島4                                                                                                                                           | 1994-06-24   | FC                 |  5800 |
| 魔導物語                                                    | 魔導物語 1 3つの魔導球                                                                                                                                      | 1993-12-03   | GG                 |  5500 |
| 魔導物語                                                    | 魔導物語 2 アルル16歳                                                                                                                                       | 1994-05-20   | GG                 |  5500 |
| 魔導物語                                                    | 魔導物語 3 究極女王様                                                                                                                                       | 1994-11-25   | GG                 |  5500 |
| 魔導物語                                                    | 魔導物語A ドキドキばけ〜しょん                                                                                                                              | 1995-11-24   | GG                 |  5500 |
| 魔導物語                                                    | 魔導物語〜はなまる大幼稚園児〜                                                                                                                              | 1996-01-12   | SFC                |  9900 |
| 魔導物語                                                    | 魔導物語I 炎の卒園児                                                                                                                                        | 1996-12-13   | ARCADE CARD専用    |  7800 |
| 魔導物語                                                    | 魔導物語                                                                                                                                                    | 1998-07-23   | SS                 |  5800 |
| 麻雀                                                        | 麻雀                                                                                                                                                        | 1983-08-27   | FC                 |  4500 |
| 麻雀                                                        | 麻雀                                                                                                                                                        | 1986-02-21   | FCD                |  4900 |
| 麻雀                                                        | 麻雀悟空 プロフェッショナル                                                                                                                                 | 1986-12-25   | FCD                |  2900 |
| 麻雀                                                        | 麻雀家族                                                                                                                                                    | 1987-08-04   | FCD                |  2980 |
| 麻雀                                                        | 麻雀大会                                                                                                                                                    | 1989-10-31   | FC                 |  7800 |
| 麻雀                                                        | 麻雀学園 東間宗四郎登場                                                                                                                                     | 1989-11-24   | PCE                |  7980 |
| 麻雀                                                        | 麻雀刺客列伝 麻雀ウォーズ                                                                                                                                   | 1990-02-01   | PCE                |  5400 |
| 麻雀                                                        | 麻雀学園MILD                                                                                                                                                | 1990-06-29   | PCE                |  7980 |
| 麻雀                                                        | 麻雀倶楽部永田町 総裁戦                                                                                                                                     | 1991-04-25   | FC                 |  9700 |
| 麻雀                                                        | 麻雀狂列伝 西日本編                                                                                                                                         | 1991-07-01   | NG                 | 15800 |
| 麻雀                                                        | 麻雀覇王伝カイザークエスト                                                                                                                                  | 1992-02-28   | PCE                |  7200 |
| 麻雀                                                        | 麻雀大戦                                                                                                                                                    | 1992-05-20   | FC                 |  6400 |
| 麻雀                                                        | 麻雀飛翔伝 哭きの龍                                                                                                                                         | 1992-12-25   | SFC                |  9800 |
| 麻雀                                                        | 麻雀クリニックスペシャル                                                                                                                                    | 1993-09-24   | PCE(SCDR2)         |  7800 |
| 麻雀                                                        | 麻雀オンザビーチ                                                                                                                                            | 1993-09-30   | PCE(SCDR2)         |  7800 |
| 麻雀                                                        | 麻雀レモンエンジェル                                                                                                                                        | 1994-02-25   | PCE(SCDR2)         |  8800 |
| 麻雀                                                        | 麻雀悟空 天竺                                                                                                                                               | 1994-06-25   | 3DO                |  7800 |
| 麻雀                                                        | 麻雀狂時代 AVギャル制服編                                                                                                                                   | 1994-07-20   | 3DO                |  9800 |
| 麻雀                                                        | 麻雀悟空 天竺                                                                                                                                               | 1994-08-19   | SFC                |  9800 |
| 麻雀                                                        | 麻雀狂列伝 西日本編                                                                                                                                         | 1994-09-09   | NG(CD)             |  4800 |
| 麻雀                                                        | 麻雀戦国物語                                                                                                                                                | 1994-09-23   | SFC                |  9300 |
| 麻雀                                                        | 麻雀大会2                                                                                                                                                   | 1994-09-30   | SFC                |  9800 |
| 麻雀                                                        | 麻雀悟空 天竺                                                                                                                                               | 1994-11-22   | SS                 |  5800 |
| 麻雀                                                        | 麻雀悟空 天竺                                                                                                                                               | 1994-12-03   | PS                 |  5800 |
| 麻雀                                                        | 麻雀ステーションMAZIN〜麻神〜                                                                                                                               | 1994-12-03   | PS                 |  6000 |
| 麻雀                                                        | 麻雀倶楽部                                                                                                                                                  | 1994-12-22   | SFC                |  4980 |
| 麻雀                                                        | 麻雀巌流島                                                                                                                                                  | 1995-03-10   | SS                 |  6800 |
| 麻雀                                                        | 麻雀巌流島                                                                                                                                                  | 1995-07-07   | PS                 |  6800 |
| 麻雀                                                        | 麻雀繁盛記                                                                                                                                                  | 1995-07-28   | SFC                |  6800 |
| 麻雀                                                        | 麻雀海岸物語〜麻雀狂時代 セクシーアイドル編〜                                                                                                               | 1995-08-04   | SS                 |  6800 |
| 麻雀                                                        | 麻雀狂時代 コギャル放課後編                                                                                                                                 | 1995-10-18   | 3DO                |  9800 |
| 麻雀                                                        | 麻雀飛翔伝 真 哭きの巻                                                                                                                                      | 1995-10-27   | SFC                |  8900 |
| 麻雀                                                        | 麻雀狂時代 コギャル放課後編                                                                                                                                 | 1996-01-12   | SS                 |  8800 |
| 麻雀                                                        | 麻雀ハイパーリアクションR                                                                                                                                   | 1996-03-08   | SS                 |  6800 |
| 麻雀                                                        | 麻雀天使エンジェルリップス                                                                                                                                  | 1996-03-29   | SS                 |  6800 |
| 麻雀                                                        | 麻雀同級生Special                                                                                                                                           | 1996-03-29   | SS                 |  5800 |
| 麻雀                                                        | 麻雀同級生Special                                                                                                                                           | 1996-03-29   | SS                 |  8800 |
| 麻雀                                                        | 麻雀狂時代 Cebu Island'96                                                                                                                                   | 1996-07-19   | SS                 |  8800 |
| 麻雀                                                        | 麻雀四姉妹 若草物語                                                                                                                                         | 1996-09-27   | SS                 |  8800 |
| 麻雀                                                        | 麻雀大会2 Special                                                                                                                                           | 1996-10-04   | SS                 |  6800 |
| 麻雀                                                        | 麻雀大会2Special                                                                                                                                            | 1996-11-29   | PS                 |  6800 |
| 麻雀                                                        | 麻雀 MASTER                                                                                                                                                 | 1996-12-20   | N64                |  9800 |
| 麻雀                                                        | 麻雀64                                                                                                                                                      | 1997-04-04   | N64                |  7800 |
| 麻雀                                                        | 麻雀放浪記CLASSIC                                                                                                                                           | 1997-08-01   | N64                |  7900 |
| 麻雀                                                        | 麻雀学園祭                                                                                                                                                  | 1997-11-06   | SS                 |  6800 |
| 麻雀                                                        | 麻雀学園祭                                                                                                                                                  | 1997-11-06   | SS                 |  8800 |
| 麻雀                                                        | 麻雀幼稚園 たまご組                                                                                                                                         | 1998-03-12   | PS                 |  5800 |
| 麻雀                                                        | 麻雀倶楽部                                                                                                                                                  | 1998-04-09   | PS                 |  4800 |
| 麻雀                                                        | 麻雀学園祭DX〜前日にまつわる奮戦記〜                                                                                                                        | 1998-09-23   | SS                 |  5800 |
| 麻雀                                                        | 麻雀クエスト                                                                                                                                                | 1998-12-23   | GB&GBC            |  3980 |
| 麻雀                                                        | 麻雀やろうぜ!                                                                                                                                               | 1999-04-28   | PS                 |  3800 |
| 麻雀                                                        | 麻雀悟空 天竺 99                                                                                                                                            | 1999-06-03   | PS                 |  1800 |
| 麻雀                                                        | 麻雀幼稚園たまご組R                                                                                                                                         | 2000-01-13   | PS                 |  1500 |
| 麻雀                                                        | 麻雀鳥頭紀行                                                                                                                                                | 2000-02-24   | PS                 |  5800 |
| 麻雀                                                        | 麻雀女王                                                                                                                                                    | 2000-04-28   | GB&GBC            |  3980 |
| 麻雀                                                        | 麻雀幼稚園たまご組2 0からの麻雀                                                                                                                             | 2000-09-28   | PS                 |  3800 |
| 麻雀                                                        | 麻雀占い フォルトゥーナ 〜月の女神達〜                                                                                                                      | 2001-02-01   | PS                 |  3800 |
+-------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+--------------------+-------+
1750 rows in set (2 min 18.77 sec)

mysql>
 

1万本 × 1万本 の全組み合わせを計算しにかかるので 相当な検索負荷となります
クアッドコア 2.5GHzの検証システムでは 2分20秒ほどかかりました
シングルコア 2GHzの時では 5分近くかかったのを考えるとシステム処理能力に応じた結果です

トラブルシューティング

実際に遭遇したトラブルです

「Access Denied」とやたら出て データベース操作ができない

1. tmpdir が存在しないか確認
/etc/my.cnf の内容から tmpdir の場所を確認します
例えば tmpdir=/tmp/mysql となっていた場合
/tmp/mysql/ ディレクトリが mysql(MySQL管理者権限)でアクセス可能か調べてください

$ ls -l /tmp | grep mysql
drwx------  2 mysql users     4096 12月 13 14:04 mysql
srwxrwxrwx  1 mysql mysql        0 12月 13 14:04 mysql.sock
$
 

tmpdirディレクトリが存在しなかったり アクセス権限が不適切だと
mysql_install_db 時にいろいろ文句を言われているはずです

tmpdirディレクトリが未作成だった場合
一旦 mysqld を停止させて tmpdirディレクトリを作成すれば回復すると思います

2. MySQLでの権限設定に失敗していた
必要なアクセス権限許可が削除されていた場合などです

既にデータベースには重要なデータが入っていて mysql_install_db しなおすのは面倒な場合
次の方法で アクセス権限を設定してみてください

2-a. 現行の mysqld を停止させる

2-b. mysqld を以下の方法で起動させる

$ su
# /usr/local/libexec/mysqld --skip-grant
 

プロンプトが帰ってきませんが フォアグラウンドで mysqldが起動しているためです
認証が無効化されていて セキュリティ上危険な状態ですので 権限設定を素早く行います
別の端末から

$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.

mysql>
 

これで接続ができるので mysql.user や mysql.db などへ必要な修正を行います
(mysql-5.5系は –skip-grant 中に set password 命令が使えなくなっています)

終わったら 素早く mysqldを shutdownします (mysqladmin shutdown を使う)
フォアグラウンドで動いていた mysqldが終了してプロンプトが帰ってくるはずです

3. ローカルホストでは接続できる(-hオプションなし) のに TCP接続(-h 自ホスト名) で接続できない
これは mysql.user テーブルの権限設定ミスです

この場合 mysql.user テーブル上では host が 「myhost.mydomain」となっているのに
MySQLへの接続時のエラーメッセージが 「ERROR 1130 (HY000): Host ‘myhost’ is not allowed 〜」
と 「.mydomain」 の有無で食い違っていることで確認できます

以下の作業で mysql.user や mysql.db テーブルを更新することで
自ホストへ TCP接続できるようになります

$ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.15 Source distribution

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.

mysql> update mysql.user set host = 'myhost' where host='myhost.mydomain'
Query OK, 2 rows affected (0.01 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> update mysql.db set host = 'myhost' where host = &aposmyhost.mydomain'
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> quit
Bye
$ mysqladmin -u root -p flush-privileges
Enter password:
$

mysqladmin flush-privileges により mysqlデータベースの更新が反映されます