GR-SAKURA2

GR-SAKURA2

GR-SAKURAII というマイコンボードと開発キットを入手しました。
GR-SAKURAII は ルネサス製32bit MCUである RX63Nを搭載しています。

写真の左にある E2 emulator lite というのは、JTAGデバッガです。
CS+ for CC の統合開発環境から、デバッグ開発したり
フラッシュへのファームウェア書き込みができたりします。

GR-SAKURAII-FULL パッケージ
次の写真は、パッケージの中身です。

右側の桜色のボードが本体で、日本製を強調した感じです
日本製マイコンボードながら Arduino互換ピン配置で
未検証ですが、 IDE for GR による、
Arduino-IDEに近い開発スタイルも利用可能のようです。

左側が E2 emulator liteです。 これを経由してPCとUSB接続します。
GR-SAKURAII-FULL パッケージ

Visual Studioで開発

Visual Studioで Windows開発

Visual Studioは Microsoft社製の IDE(統合開発環境)で
VisualBasic VisualC++ VisualC# など複数の言語を使って Windowsアプリを開発できます

昔は 数万円の高価なソフトでしたが 最近の iOS や Android のビジネスモデルに圧されているのか
Express版というフリーなバージョンが使えたりします

Visual Studio 2012 Express

Visual Studio 2012 版を紹介 記事は途中です
Visual Studio 2012 Express インストール
Visual Studio 2012 Express版をダウンロードしてインストールする画面です
Visual Studio 2012 Express 画面概要
Visual Studio 2012 Express版の起動時の画面です
Windowsストアアプリ対応の WPFプラットフォームも利用可能です
Visual Studio 2012 Express コマンドラインでの環境設定
Windowsのコマンドラインにて Visual Studioのツール群を使えるようにするには
写真のように vcvarsall.bat にアーキテクチャの引数をつけて実行します

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コマンドで反映するだけです

 

Xine メディアプレーヤー

Xine インストールログ

Linuxでも 動画や DVDを見る環境がだいぶ充実しました
Xine(クシーン? ザイン?)を紹介します
これがあれば 動画再生は満ち足りるというほど充実してます
検証環境
CPU AMD Turion-MT37 2GHz
メモリ 1GB
グラフィック nVidia GeForce6600
DVD BenQ DVD DC DW1670
OS Linux 2.6.30.5
ウィンドウシステム Xorg-1.5.1 + fluxbox-1.1.1
OpenGL Mesa-7.5 + NVIDIA-Linux-x86-185.18.14
GCC gcc-4.1.2
Cライブラリ glibc-2.5
Firefox 3.5
Xineの特徴としては

  • DVD VCD AVIファイル Mpegファイル DivX Win32codec など幅広いフォーマットに対応
  • 入出力(ファイルやビデオ)をプラグイン化することで拡張性が高い
  • xine-lib(各種 コーデック プラグイン) と UIが分離している
  • さまざまな UIがある

従って 流れとしては

  1. コーデック 必要なライブラリ を別途入手して インストール
  2. xine-libをインストール
  3. UIをインストール

totemスクリーンショット
いろいろなインターフェースがあります 上の図は Ubuntuに採用されている totemです

コーデックのインストール

実は Xineは Windowsのコーデックを無理矢理 Linuxで使うというようなことをやってます
コーデックのパックが配布されているところがあるので 各種 .dll を拝借します

リンク元が分からないため 私が拾ってきたコーデックパックを ここに載せます
essential-20071007.tar.bz2 (MPlayer のサイトで配布されていたものだと思います)

$ su
# cd /usr/local/lib
# mkdir win32
# cd win32
# tar -xjf ~admin/essential-20071007.tar.bz2 --strip-path=1
# ls
AvidQTAVUICodec.qtx          cook.so.6.0   l3codeca.acm  qtmlClient.dll  vmnc.dll
BeHereiVideo.qtx             ctadp32.acm   l3codecx.ax   rt32dcmp.dll    voxmsdec.ax
CLRVIDDC.DLL                 ddnt.so.6.0   lhacm.acm     scg726.acm      vp31vfw.dll
CtWbJpg.DLL                  divx.dll      lsvxdec.dll   sipr.so.6.0     vp4vfw.dll
DECVW_32.DLL                 divx_c32.ax   m3jp2k32.dll  sp5x_32.dll     vp5vfw.dll
LCMW2.dll                    divxa32.acm   m3jpeg32.dll  tm20dec.ax      vp6vfw.dll
LCODCCMW2E.dll               divxc32.dll   m3jpegdec.ax  tokf.so.6.0     vp7vfw.dll
LCodcCMP.dll                 divxdec.ax    mcdvd_32.dll  tokr.so.6.0     vssh264.dll
QuickTime.qts                dnet.so.6.0   mcmjpg32.dll  tsccvid.dll     vssh264core.dll
QuickTimeEssentials.qtx      drv2.so.6.0   mi-sc4.acm    tsd32.dll       vssh264dec.dll
QuickTimeInternetExtras.qtx  drv3.so.6.0   mpg4c32.dll   tssoft32.acm    vsshdsd.dll
VDODEC32.dll                 drv4.so.6.0   mpg4ds32.ax   tvqdec.dll      vsslight.dll
ViVD2.dll                    drvc.so       msadp32.acm   ubv263d+.ax     vsswlt.dll
acelpdec.ax                  dspr.so.6.0   msg711.acm    ubvmp4d.dll     wma9dmod.dll
alf2cd.acm                   huffyuv.dll   msgsm32.acm   ultimo.dll      wmadmod.dll
aslcodec_dshow.dll           i263_32.drv   msh261.drv    vdowave.drv     wmsdmod.dll
aslcodec_vfw.dll             iac25_32.ax   msms001.vwp   vgpix32d.dll    wmspdmod.dll
asusasv2.dll                 iccvid.dll    msnaudio.acm  vid_3ivX.xa     wmv8ds32.ax
asusasvd.dll                 icmw_32.dll   msrle32.dll   vid_cvid.xa     wmv9dmod.dll
ativcr2.dll                  imaadp32.acm  msscds32.ax   vid_cyuv.xa     wmvadvd.dll
atrac3.acm                   imc32.acm     msvidc32.dll  vid_h261.xa     wmvdmod.dll
atrc.so.6.0                  ir32_32.dll   mvoiced.vwp   vid_h263.xa     wmvds32.ax
avimszh.dll                  ir41_32.dll   nsrt2432.acm  vid_iv32.xa     wnvplay1.dll
avizlib.dll                  ir50_32.dll   pclepim1.dll  vid_iv41.xa     wnvwinx.dll
clrviddd.dll                 ivvideo.dll   qdv.dll       vid_iv50.xa     wvc1dmod.dll
cook.so                      jp2avi.dll    qpeg32.dll    vivog723.acm    xanlib.dll
#

ライブラリのインストール

DVDを見るには libdvdcss が必要です
解凍後
./configure –prefix=/usr/local
make
su
make install
でインストールされます
これは DVDの画像に施されている 暗号化を解除するためのライブラリです

他にも libogg や libvorbis などの必要なライブラリを入れます
(詳細は 忘れてしまいましたが 後述の Xineのビルド時にチェックできます)

xine-libのインストール

いよいよ Xineの核となる xine-lib です
$ tar -xjf xine-lib-1.1.16.2.tar.bz2
$ cd xine-lib-1.1.16.2
$ $ ./configure --enable-directfb --enable-static --with-w32-path=/usr/loc
al/lib/win32 --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 build system type... i686-pc-linux-gnu
…
…
xine-lib summary:
----------------
 * input plugins:
   - file          - net
   - stdin_fifo    - rtp
   - http          - mms
   - pnm           - rtsp
   - dvb
   - dvd (internal libs)
   - vcd (internal libs)
   - vcdo
   - cdda
   - gnome-vfs
   - v4l

 * demultiplexer plugins:
   - avi           - mpeg
   - mpeg_block    - mpeg_audio
   - mpeg_elem     - mpeg_pes
   - mpeg_ts       - qt/mpeg-4
   - film          - roq
   - fli           - smjpeg
   - idcin         - wav
   - wc3 mve       - voc
   - vqa           - aiff
   - cdda          - snd/au
   - yuv4mpeg2     - real/realaudio
   - ea wve        - raw dv
   - interplay mve - psx str
   - ws aud        - pva
   - vox
   - nsv           - 4xm
   - FLAC          - aac
   - iff           - matroska
   - vmd           - flv
   - nsf
   - ogg
   - ac3 (internal library)

 * video decoder plugins:
   - MPEG 1,2         - Amiga Bitplane
   - Raw RGB          - Raw YUV
   - ffmpeg (internal library):
     - MPEG-4 (ISO, Microsoft, DivX*, XviD)
     - Creative YUV    - Motion JPEG
     - Cinepak         - MS Video-1
     - FLI/FLC         - MS RLE
     - Id RoQ          - Id Cin
     - Apple Graphics  - Apple Video
     - Apple Animation - Interplay Video
     - Westwood VQA    - Origin Xan
     - H.263           - Intel Indeo 3
     - SVQ1            - SVQ3
     - Real Video 1.0  - Real Video 2.0
     - 4X Video        - Sierra Video
     - Asus v1/v2      - HuffYUV
     - On2 VP3         - DV
     - 8BPS            - Duck TrueMotion v1
     - ATI VCR1        - Flash Video
     - ZLIB            - MSZH
   - dxr3_video
   - w32dll
   - gdk-pixbuf

 * audio decoder plugins:
   - GSM 06.10       - linear PCM
   - ffmpeg (internal library):
     - Windows Media Audio v1/v2
     - DV            - logarithmic PCM
     - 14k4          - 28k8
     - MS ADPCM      - IMA ADPCM
     - XA ADPCM      - Game DPCM/ADPCM
     - Mace 3:13     - Mace 6:1
     - FLAC
   - Nosefart (NSF)
   - vorbis
   - w32dll
   - MAD (MPG 1/2/3) (internal library)
   - DTS (internal library)
   - A52/ra-dnet (internal library)
   - MusePack (internal library)

 * subtitle decoder plugins:
   - spu             - spucc
   - spucmml         - sputext
   - spudvb
   - dxr3_spu

 * post effect plugins:
  * planar video effects:
   - invert          - expand
   - eq              - eq2
   - boxblur         - denoise3d
   - unsharp         - tvtime
  * SFX:
   - goom            - oscope
   - fftscope        - mosaico

 * video driver plugins:
   - XShm (X11 shared memory)
   - SyncFB (for Matrox G200/G400 cards)
   - Xv (XVideo *shared*)
   - OpenGL
   - xcb-shm (X shared memory using XCB)
   - xcb-xv (XVideo using XCB)
   - aa (Ascii ART)
   - fb (Linux framebuffer device)
   - sdl (Simple DirectMedia Layer)
   - dxr3 (Hollywood+ and Creative dxr3, mpeg video only)
   - vidix (X11 and framebuffer support)

 * audio driver plugins:
   - oss (Open Sound System)
   - alsa
---
最後にでる xine-lib summary というのが重要です
xine-libの ビルドで使えるようになると思われる プラグインが表示されます
上記のは 実際の今回検証環境のもので DVD avi mpg DivX あらかたのものが再生できます

上記を参考にいただいて 足りない環境があれば 個別にそろえてください

$ make
…
…
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../../../../include -I../../../../src/input/vcd/libcdio -I../../../../include -I../../../../lib -I../../../../lib -D_REENTRANT -D_FILE_OFFSET_BITS=64 -DXINE_COMPILE -mtune=pentiumpro -O3 -pipe -fomit-frame-pointer -falign-functions=4 -falign-loops=4 -falign-jumps=4 -fexpensive-optimizations -fschedule-insns2 -ffast-math -finline-functions -Wpointer-arith -g -O2 -Wall -Wchar-subscripts -Wnested-externs -Wcast-align -Wmissing-declarations -Wmissing-prototypes -Wmissing-format-attribute -Wno-pointer-sign -Wformat=2 -Wno-format-zero-length -Wstrict-aliasing=2 -DNDEBUG -MT _cdio_linux.lo -MD -MP -MF .deps/_cdio_linux.Tpo -c _cdio_linux.c  -fPIC -DPIC -o .libs/_cdio_linux.o
In file included from _cdio_linux.c:66:
/usr/src/linux/include/scsi/scsi.h:145: error: expected specifier-qualifier-list before 'u8'
/usr/src/linux/include/scsi/scsi.h: In function 'scsi_varlen_cdb_length':
/usr/src/linux/include/scsi/scsi.h:156: error: 'struct scsi_varlen_cdb_hdr' has no member named 'additional_cdb_length'
_cdio_linux.c: In function '_read_mode2_sector_linux':
_cdio_linux.c:724: 警告: dereferencing type-punned pointer might break strict-aliasing rules
make[5]: *** [_cdio_linux.lo] エラー 1
make[5]: Leaving directory `/home/admin/xine-lib-1.1.16.2/src/input/vcd/libcdio'
make[4]: *** [all-recursive] エラー 1
make[4]: Leaving directory `/home/admin/xine-lib-1.1.16.2/src/input/vcd/libcdio'
make[3]: *** [all-recursive] エラー 1
make[3]: Leaving directory `/home/admin/xine-lib-1.1.16.2/src/input/vcd'
make[2]: *** [all-recursive] エラー 1
make[2]: Leaving directory `/home/admin/xine-lib-1.1.16.2/src/input'
make[1]: *** [all-recursive] エラー 1
make[1]: Leaving directory `/home/admin/xine-lib-1.1.16.2/src'
make: *** [all-recursive] エラー 1
$
私の環境では 「u8 が未定義」 だと怒られました
linux-kernel によると typedef unsigned char u8; は asm-generic/int-ll64.h で定義されていますが
gccに -D__KERNEL__ が必要になるため u8自体 そもそもカーネルモジュール用の型と思われます

以下のように src/input/vcd/libcdio/_cdio_linux.c へ定義を追加して 回避しました (64行目に typedef 文追加)

  55 
  56 #include 
  57 #include 
  58 #include 
  59 #include 
  60 #include 
  61 #include 
  62 #include 
  63 
  64 typedef unsigned char u8;
  65 #include 
  66 #include 
  67 #include 
  68 #include 
  69 #include 
  70 
$ make
…
…
Making all in win32
make[1]: Entering directory `/home/admin/xine-lib-1.1.16.2/win32'
Making all in include
make[2]: Entering directory `/home/admin/xine-lib-1.1.16.2/win32/include'
make[2]: `all' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/xine-lib-1.1.16.2/win32/include'
make[2]: Entering directory `/home/admin/xine-lib-1.1.16.2/win32'
make[2]: `all-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/xine-lib-1.1.16.2/win32'
make[1]: Leaving directory `/home/admin/xine-lib-1.1.16.2/win32'
make[1]: Entering directory `/home/admin/xine-lib-1.1.16.2'
make[1]: `all-am' に対して行うべき事はありません。
make[1]: Leaving directory `/home/admin/xine-lib-1.1.16.2'
$ su
# make install
…
…
find . -name \*.so | \
  xargs strings -a | \
  /bin/grep -E '^([-a-z]+/[-+.a-z0-9]+:[^:]+:[^;]+;[ \t]*)+' | \
  sed -e 's/:[^;]\+;/\n/g' | \
  sort -u | \
  sed -e '1 d' >/usr/local/lib/xine/plugins/1.25/mime.types
make[3]: Leaving directory `/home/admin/xine-lib-1.1.16.2'
test -z "/usr/local/share/doc/xine-lib" || /bin/mkdir -p "/usr/local/share/doc/xine-lib"
 /bin/install -c -m 644 'COPYING' '/usr/local/share/doc/xine-lib/COPYING'
 /bin/install -c -m 644 'NEWS' '/usr/local/share/doc/xine-lib/NEWS'
 /bin/install -c -m 644 'README' '/usr/local/share/doc/xine-lib/README'
 /bin/install -c -m 644 'TODO' '/usr/local/share/doc/xine-lib/TODO'
 /bin/install -c -m 644 'CREDITS' '/usr/local/share/doc/xine-lib/CREDITS'
 /bin/install -c -m 644 'ChangeLog' '/usr/local/share/doc/xine-lib/ChangeLog'
make  install-data-hook
make[3]: Entering directory `/home/admin/xine-lib-1.1.16.2'
make[3]: Leaving directory `/home/admin/xine-lib-1.1.16.2'
make[2]: Leaving directory `/home/admin/xine-lib-1.1.16.2'
make[1]: Leaving directory `/home/admin/xine-lib-1.1.16.2'
#
足りない環境に必要なライブラリを探して インストールする方にむしろ時間がかかると思います

UIのインストール

次に UIですが いくつか選択肢があります

  • xine-ui は標準で用意されてます これでも十分使えます
  • gxine も xine-uiと同じ場所で配布されています
  • totem も Ubuntuなどに採用されている人気のある UIです

xine-ui 不具合版

上の絵は 私の環境の古い xine-ui-0.99.4 ですが
Xorgを入れ替えたタイミングで コントロールパネルがバグって使いものになりません

xine-ui コントロールパネル

本来ならこんな感じのパネルが使えます
ファイルや DVDを開いたり 画像の拡大 アスペクト比変更 ほとんどできます

gxine では Mozilla(Firefox?)用プラグインがある
という話なので 今回こちらの使用感をレポートします
$ tar -xjf gxine-0.5.903.tar.bz2
$ cd gxine-0.5.903
$ ./configure
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
…
config.status: executing po-directories commands
config.status: creating misc/po/POTFILES
config.status: creating misc/po/Makefile
config.status: creating po/POTFILES
config.status: creating po/Makefile
config.status: executing default commands
$ make
Makefile:764: 警告: ターゲット `dist' へのコマンドを置き換えます
Makefile:546: 警告: ターゲット `dist' への古いコマンドは無視されます
exec > gxine.desktop; cat gxine.desktop.in; /usr/local/bin/xine-list-1.1; echo
make  all-recursive
make[1]: Entering directory `/home/admin/gxine-0.5.903'
Makefile:764: 警告: ターゲット `dist' へのコマンドを置き換えます
Makefile:546: 警告: ターゲット `dist' への古いコマンドは無視されます
Making all in m4
mv -f .deps/console_output.Tpo .deps/console_output.Po
gcc -DHAVE_CONFIG_H -I. -I../include -I../include -I../include -I/usr/local/include -I../pixmaps    -std=gnu99 -I/usr/local/include   -I/usr/X11R7/include -I/usr/local/include/gtk-2.0 -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/atk-1.0 -I/usr/local/include/cairo -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/freetype2 -I/usr/local/include/libpng12 -I/usr/X11R7/include   -pthread -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include   -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/local/include/hal -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include    -DXP_UNIX -DJS_THREADSAFE -I/usr/local/include/xulrunner-1.9.1.3/stable   -DLOCALEDIR=\"/usr/local/share/locale\"  -MT desktop_integration.o -MD -MP -MF .deps/desktop_integration.Tpo -c -o desktop_integration.o desktop_integration.c
globals.h:39 から include されたファイル中,
                 desktop_integration.c:27 から:
script_engine.h:34:19: error: jsapi.h: そのようなファイルやディレクトリはありません
In file included from globals.h:39,
                 from desktop_integration.c:27:
script_engine.h:40: 警告: type defaults to 'int' in declaration of 'JSErrorReport'
script_engine.h:40: error: expected ';', ',' or ')' before '*' token
script_engine.h:59: error: expected specifier-qualifier-list before 'JSContext'
script_engine.h:75: error: expected specifier-qualifier-list before 'JSFunction'
script_engine.h:119: error: expected specifier-qualifier-list before 'JSObject'
script_engine.h:146: 警告: type defaults to 'int' in declaration of 'JSErrorReport'
script_engine.h:146: error: expected ';', ',' or ')' before '*' token
script_engine.h:151: error: expected declaration specifiers or '...' before 'se_error_cb_t'
script_engine.h:155: error: expected declaration specifiers or '...' before 'JSInt32'
script_engine.h:156: error: expected declaration specifiers or '...' before 'JSFloat64'
script_engine.h:157: error: expected declaration specifiers or '...' before 'JSBool'
script_engine.h:158: error: expected declaration specifiers or '...' before 'JSInt32'
script_engine.h:159: error: expected declaration specifiers or '...' before 'JSFloat64'
script_engine.h:179: error: expected specifier-qualifier-list before 'JSNative'
script_engine.h:186: error: expected declaration specifiers or '...' before 'JSNative'
script_engine.h:186: error: expected declaration specifiers or '...' before 'uintN'
script_engine.h:186: error: expected declaration specifiers or '...' before 'uintN'
script_engine.h:242: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'se_warn_initialisation'
make[2]: *** [desktop_integration.o] エラー 1
make[2]: Leaving directory `/home/admin/gxine-0.5.903/src'
make[1]: *** [all-recursive] エラー 1
make[1]: Leaving directory `/home/admin/gxine-0.5.903'
make: *** [all] エラー 2
$
という エラーに遭遇しました jsapi.h が見つからないというものです
これは Firefox(というより XULRunner)の問題のようです
jsapi.hは 実際は /usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h にあるのに
XULRunnerのビルドでインストールされた /usr/local/lib/pkgconfig/mozilla-js.pc を見ると
prefix=/usr/local
sdkdir=/usr/local/lib/xulrunner-devel-1.9.1.3
includedir=/usr/local/include/xulrunner-1.9.1.3

Name: JavaScript
Description: The Mozilla JavaScript Library
Version: 1.9.1.3
Requires: mozilla-nspr >= 4.8.0
Libs: -L${sdkdir}/lib -lmozjs
Cflags: -I${includedir}/stable -DXP_UNIX -DJS_THREADSAFE
/usr/local/include/xulrunner-1.9.1.3/stable にしか インクルードパスが張られていません
ここでは gxineソースディレクトリ側を修正して
Makefile
src/Makefile
の JS_LIBS の設定にインクルードパスを直接追加しました
JS_CFLAGS = -DXP_UNIX -DJS_THREADSAFE -I/usr/local/include/xulrunner-1.9.1.3/stable -I /usr/local/include/xulrunner-1.9.1.3/unstable
-I /usr/local/include/xulrunner-1.9.1.3/unstable が追加部分です
(unstable というディレクトリ名が引っかかるところです)
$ make
…
…
make[3]: Leaving directory `/home/deer/admin/Xine/gxine-0.5.903/include'
make[2]: Leaving directory `/home/deer/admin/Xine/gxine-0.5.903/include'
Making all in src
make[2]: Entering directory `/home/deer/admin/Xine/gxine-0.5.903/src'
gcc -DHAVE_CONFIG_H -I. -I../include -I../include -I../include -I/usr/local/include -I../pixmaps    -std=gnu99 -I/usr/local/include   -I/usr/X11R7/include -I/usr/local/include/gtk-2.0 -I/usr/local/lib/gtk-2.0/include -I/usr/local/include/atk-1.0 -I/usr/local/include/cairo -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/freetype2 -I/usr/local/include/libpng12 -I/usr/X11R7/include   -pthread -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include   -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/local/include/hal -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include    -DXP_UNIX -DJS_THREADSAFE -I/usr/local/include/xulrunner-1.9.1.3/stable  -I/usr/local/include/xulrunner-1.9.1.3/unstable -DLOCALEDIR=\"/usr/local/share/locale\"  -MT desktop_integration.o -MD -MP -MF .deps/desktop_integration.Tpo -c -o desktop_integration.o desktop_integration.c
In file included from script_engine.h:34,
                 from globals.h:39,
                 from desktop_integration.c:27:
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:87: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:87: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:94: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:94: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:101: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:101: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:108: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:108: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:115: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:115: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:122: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:122: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:129: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:129: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:179: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:179: error: expected identifier or '(' before ')' token
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:186: error: expected ')' before '__attribute__'
/usr/local/include/xulrunner-1.9.1.3/unstable/jsapi.h:186: error: expected identifier or '(' before ')' token
make[2]: *** [desktop_integration.o] エラー 1
make[2]: Leaving directory `/home/deer/admin/Xine/gxine-0.5.903/src'
make[1]: *** [all-recursive] エラー 1
make[1]: Leaving directory `/home/deer/admin/Xine/gxine-0.5.903'
make: *** [all] エラー 2
$
なんと jsapi.h 自体がエラーとなりました (さすが unstable ディレクトリ…)
/usr/local/include/xulrunner-1.9.1.3/unstable/jstypes.h で定義されている
JS_ALWAYS_INLINE のエラーのようです
168 #ifndef JS_INLINE
169 # if defined __cplusplus
170 #  define JS_INLINE          inline
171 # elif defined _MSC_VER
172 #  define JS_INLINE          __inline
173 # elif defined __GNUC__
174 #  define JS_INLINE          __inline__ 
175 # else
176 #  define JS_INLINE          inline
177 # endif
178 #endif
179 
180 #ifndef JS_ALWAYS_INLINE
181 # if defined DEBUG
182 #  define JS_ALWAYS_INLINE   JS_INLINE
183 # elif defined _MSC_VER
184 #  define JS_ALWAYS_INLINE   __forceinline
185 # elif defined __GNUC__
186 #  define JS_ALWAYS_INLINE   __attribute__((always_inline)) JS_INLINE
187 # else
188 #  define JS_ALWAYS_INLINE   JS_INLINE
189 # endif
190 #endif
私の gcc 環境では __attribute__((always_inline)) がうまく使えません
(これは Cの関数定義をインライン化するためのコンパイラ指示のようですが)
inline なら認識されますので 以下のように jstypes.h を修正しました
168 #ifndef JS_INLINE
169 # if defined __cplusplus
170 #  define JS_INLINE          inline
171 # elif defined _MSC_VER
172 #  define JS_INLINE          __inline
173 # elif defined __GNUC__
174 //#  define JS_INLINE          __inline__ 
175 #  define JS_INLINE          inline
176 # else
177 #  define JS_INLINE          inline
178 # endif
179 #endif
180 
181 #ifndef JS_ALWAYS_INLINE
182 # if defined DEBUG
183 #  define JS_ALWAYS_INLINE   JS_INLINE
184 # elif defined _MSC_VER
185 #  define JS_ALWAYS_INLINE   __forceinline
186 # elif defined __GNUC__
187 //#  define JS_ALWAYS_INLINE   __attribute__((always_inline)) JS_INLINE
188 #  define JS_ALWAYS_INLINE   JS_INLINE
189 # else
190 #  define JS_ALWAYS_INLINE   JS_INLINE
191 # endif
192 #endif
強引ですがビルドを継続します
$ make
…
…
Making all in po
make[2]: Entering directory `/home/admin/gxine-0.5.903/po'
make[2]: `all' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/gxine-0.5.903/po'
make[2]: Entering directory `/home/admin/gxine-0.5.903'
Makefile:764: 警告: ターゲット `dist' へのコマンドを置き換えます
Makefile:546: 警告: ターゲット `dist' への古いコマンドは無視されます
make[2]: `all-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/gxine-0.5.903'
make[1]: Leaving directory `/home/admin/gxine-0.5.903'
$ su
# make install
Makefile:764: 警告: ターゲット `dist' へのコマンドを置き換えます
Makefile:546: 警告: ターゲット `dist' への古いコマンドは無視されます
make  install-recursive
make[1]: Entering directory `/home/admin/gxine-0.5.903'
Makefile:764: 警告: ターゲット `dist' へのコマンドを置き換えます
Makefile:546: 警告: ターゲット `dist' への古いコマンドは無視されます
Making install in m4
…
…
test -z "/usr/local/share/applications" || /bin/mkdir -p "/usr/local/share/applications"
 /bin/install -c -m 644 'gxine.desktop' '/usr/local/share/applications/gxine.desktop'
make[3]: Leaving directory `/home/admin/gxine-0.5.903'
make[2]: Leaving directory `/home/admin/gxine-0.5.903'
make[1]: Leaving directory `/home/admin/gxine-0.5.903'
#
多少の工夫が必要でしたが インストールは可能です

使い勝手の検証

gxine を使ってみて xine-ui と使い勝手を比較してみました

gxine初期画面

初回起動すると ~/.config/gxine/ が作成されコンフィグを初期設定してくれます
検証の環境では CD/DVD を /dev/cdroms/cdrom0 となるように udevをカスタマイズしているため
gxineが見つけてくれず CD と DVD デバイスが認識されませんでした

通常のディストリビューションを使って入れば問題ないでしょう

gxine起動時

gxine起動時の画面です
画像のズームや ウィンドウサイズの変更など 基本的な設定はメニュー化されています

ただし 検証の環境では 再生ウィンドウをドラッグして任意倍ズームするのが
思ったとおりのサイズにズームされず使い勝手がよろしくなかったです (fluxboxのせい?)

gxine aviファイル再生

あらかたの動画形式は視聴できます

インターネット配信(.asx)も
.asxファイルを一旦ローカルディスクにダウンロードして gxineから開く ことで再生できました

ただし Mozillaプラグイン導入の指定をしたのにも関わらず
Firefoxでクリックして再生ウィンドウが開く とう期待通りの設定はされませんでした
また ファイル名 動画タイトル などが文字化けしています
これは 検証のシステムが EUC-JP系だからかもしれません (UTF-8なら問題なし?)

gxine DVD再生

CD DVD デバイスを認識させるために ~/.config/gxine/config を編集して
以下の各行を適切に設定すれば CD DVD の視聴が可能です

media.audio_cd.device:/dev/cdroms/cdrom0
media.dvd.device:/dev/cdroms/cdrom0
media.vcd.device:/dev/cdroms/cdrom0

↑で再生されている 某メイドアニメDVD を見て分かるとおり
DVDのメニューについてもマウスで操作可能で 完璧な仕上りぶり

と思われましたが
コントロールパネルに チャプタージャンプ や タイトルジャンプ などのジャンプメニューありません
(xine-ui にはあります)

gxine xine-ui 比較結果

gxineの優位な点 メニューが日本語 (ただし EUC-JP環境では苦しい表示も)
ファイル選択画面が使い易い (EUC-JPも問題なし)
CD DVD 環境の自動設定 (初回起動時)
早送り機能がある (ただし 動画形式によっては不具合も)
Mozillaプラグイン (ただし 検証の環境では確認できず)
xine-uiの優位な点 再生ウィンドウをマウスドラッグで任意倍拡大ができる (gxineは 使い心地が悪い)
ファイル選択画面は一応日本語可能 (gxineに比べると使い勝手は悪い)
DVD のジャンプメニューがある (ただしチャプター番号指定してジャンプする部分が反応しないことあり)
早送り 巻戻し 機能がある (ただし 動画形式によっては不具合も)


結局 xine-ui使うことにしました
(期待していた Mozillaプラグインが空振りしたのと DVDでタイトル画面が呼べないのが痛い)

xine-ui DVD再生

xine-ui の DVD観賞はこんな感じです
「メニュー切り替え」とか「ルート」を選択すると 一発でタイトルに飛びます
マウスによる メニュー選択もばっちりOK

ただし 番号を押してそのチャプターに飛ぼうとしたとき
うまく 飛んでくれる場合と反応がない場合があり いまいち使い勝手が悪い

あと
xine-uiをビルドするときに注意点があります
ソースコードをそのままビルドすると 日本語が文字化けしてしまいます

xine-uiは フォントのXLFD名をソースコード内にハードコードしているので
-*-*-*-*-*-*-14-*-*-*-*-*-jisx0208.1983-* のように日本語フォントに全置換してあげます
xine-ui-0.99.5用のパッチ を作ってみました参考にしてださい

$ tar -xzf xine-ui-0.99.5.tar.gz
$ cd xine-ui-0.99.5
$ zcat ../xine-ui-0.99.5-japanese.patch.gz | patch -p1
patching file src/xitk/event_sender.c
patching file src/xitk/file_browser.c
patching file src/xitk/help.c
patching file src/xitk/kbindings.c
patching file src/xitk/mediamark.c
patching file src/xitk/post.c
patching file src/xitk/setup.c
patching file src/xitk/skins/xinetic/skinconfig
patching file src/xitk/skins.c
patching file src/xitk/stream_infos.c
patching file src/xitk/tvset.c
patching file src/xitk/viewlog.c
patching file src/xitk/xine-toolkit/font.h
patching file src/xitk/xine-toolkit/test.c
$ ./configure --prefix=/usr/local --disable-xft
…
…
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing default-1 commands
config.status: creating src/xitk/xine-toolkit/po/POTFILES
config.status: creating src/xitk/xine-toolkit/po/Makefile
config.status: creating po/POTFILES
config.status: creating po/Makefile
config.status: executing default commands
$ make
…
…
make[3]: Leaving directory `/home/admin/xine-ui-0.99.5/src/fb'
make[3]: Entering directory `/home/admin/xine-ui-0.99.5/src'
make[3]: `all-am' に対して行うべき事はありません。
make[3]: Leaving directory `/home/admin/xine-ui-0.99.5/src'
make[2]: Leaving directory `/home/admin/xine-ui-0.99.5/src'
make[2]: Entering directory `/home/admin/xine-ui-0.99.5'
make[2]: Leaving directory `/home/admin/xine-ui-0.99.5'
make[1]: Leaving directory `/home/admin/xine-ui-0.99.5'
$ su
# make install
…
…
make[2]: `install-exec-am' に対して行うべき事はありません。
make[2]: `install-data-am' に対して行うべき事はありません。
make[2]: Leaving directory `/home/admin/xine-ui-0.99.5'
make[1]: Leaving directory `/home/admin//xine-ui-0.99.5'
#
検証の環境では –disable-xft もしないと日本語が表示されませんでした

LDAP認証統合 nss_ldap と pam_ldap を導入

実は UNIX系システムは 認証の仕組みを柔軟に切り替えられます

認証の仕組みというのは アカウントやパスワードを格納するバックエンドです
慣例として アカウントやパスワードの設定方法といえば
  • アカウント情報は /etc/passwd に格納されている
  • アカウント情報は vipw のコマンドで編集する
  • グループ情報は /etc/group に格納されている
  • グループ情報は vigr のコマンドで編集する
  • アカウントのパスワードは passwd コマンドにより修正する
通常は アカウントや グループなどの管理/運用は 名前解決(NS)と呼ばれ
/etc/ 以下のファイルで行われるのが通常です
名前解決は 実は nsswitch という libcの機構があり バックエンドを切り替えることができます

名前解決 nsswitchの構成

名前解決を行うのは getentコマンドなど libcの get〜()関数を利用するツールです
具体的には gethostbyname() getpwuid() getpwnam() getaddrinfo() などの列挙関数です
これらの関数は libnss_〜.soプラグインを切り替えて使えるように設計されています

例えば libnss_files.so は アカウント情報を /etc/passwd から取ってきます
例えば libnss_ldap.so は アカウント情報を LDAPから取ってきます
今回の目的は 通常使う filesのバックエンド以外にも LDAPのバックエンドを追加することで
telnetで LDAPアカウントのログインができることを目標にします

絵でいえば 赤い libnss_ldap.so と pam_ldap.so が追加になります
なぜ pam_ldap.so も追加する必要があるかというと telnetd や login といった
実際のアプリケーションが 認証に PAM(公式でないがここが詳しい)を利用しているためです
$ ldd `which login`
    linux-gate.so.1 =>  (0xb7fc0000)
    libpam_misc.so.0 => /usr/local/lib/libpam_misc.so.0 (0xb7fbc000)
    libpam.so.0 => /usr/local/lib/libpam.so.0 (0xb7fb0000)
    libdl.so.2 => /usr/glibc/2.5/i686/lib/libdl.so.2 (0xb7fab000)
    libc.so.6 => /lib/libc.so.6 (0xb7e7e000)
    libprelude.so.2 => /usr/local/lib/libprelude.so.2 (0xb7e0e000)
    libgnutls.so.13 => /usr/local/lib/libgnutls.so.13 (0xb7d7c000)
    libgcrypt.so.11 => /usr/local/lib/libgcrypt.so.11 (0xb7d2b000)
    libgpg-error.so.0 => /usr/local/lib/libgpg-error.so.0 (0xb7d27000)
    librt.so.1 => /usr/glibc/2.5/i686/lib/librt.so.1 (0xb7d11000)
    /lib/ld-linux.so.2 (0xb7fc1000)
    libpthread.so.0 => /usr/glibc/2.5/i686/lib/libpthread.so.0 (0xb7cfa000)
    libnsl.so.1 => /usr/glibc/2.5/i686/lib/libnsl.so.1 (0xb7ce4000)
    libz.so.1 => /usr/local/lib/libz.so.1 (0xb7cd0000)
で分かるように libpam.so が使われており PAMによる認証が行われていることが分かります
結局 今回の作業の流れとしては
  • LDAPの導入と アカウント情報の登録
  • libnss_ldap.so の導入
  • pam_ldap.so の導入
となります

LDAPの導入と アカウント情報の登録

LDAPとは ディレクトリサービスを提供するいわばデータベースです
Windowsでは Windows2000から ActiveDirectory という LDAPに準じた機能があり
その意味で UNIX Windows 統合バックエンドとしての可能性に脚光が集まりました
ここでは OpenLDAP の導入手順を紹介します
(OpenLDAPのソフトウェア構成)

  • slapd OpenLDAPの常駐サービスです
  • slurp LDAPのレプリケーション構築用常駐ツールです スレーブLDAPに同期情報を転送します
  • ldapsearch ldapadd ldapdelete ldapmodify クライアントツール データ操作を行います
  • slapd.conf slapdの設定ファイルです
  • ldap.conf /etc/ 以下に置かれるクライアント設定ファイル
  • 〜.schema データフォーマットを定義するスキーマファイル 用途に応じていくつかあります

OpenLDAP 自身のインストールについては省略します
パッケージからインストールするか ソースファイルをビルドしてインストールすることもできます

slapdの基本設定

slapd.confの設定です

# (1) スキーマインクルード
include         /usr/local/etc/openldap/schema/core.schema
include         /usr/local/etc/openldap/schema/cosine.schema
include         /usr/local/etc/openldap/schema/ppolicy.schema
include         /usr/local/etc/openldap/schema/nis.schema

# (2) ディレクトリ情報の基本設定
suffix          "dc=local"
rootdn          "cn=Manager,dc=local"
rootpw          testpass

# (3) バックエンドの基本設定
database        bdb
directory       /usr/local/var/openldap-data
pidfile         /var/run/slapd.pid
argsfile        /var/run/slapd.args

# (4) データへのアクセス権
access to attrs=userPassword
    by self write
    by dn="cn=Manager,dc=local" write
    by anonymous auth
    by * none

access to *
    by self write
    by dn="cn=Manager,dc=local" write
    by * read
 

(1)のインクルードファイルは OpenLDAPインストール時は core.schema のみですが
今回の アカウント管理用のスキーム定義 nis.schema を入れるための必要なスキーマを追加しています

(2)の設定においては
LDAPが 分散ディレクトリ管理(ネットワーク経由で 各LDAPサーバが管理情報を分散して管理)であること
に由来します つまりグローバルなネットワークにおける 自分自身の DN(ドメインみたいなもの) を決める必要があります
今回の LDAPの使いかたはグローバルにさらさない ローカル用途のみですので
DNを 「dc=local」 としました 気を使って「dc=ldaproot,dc=xxx-coopation,dc=co,dc=jp」みたいな
混み合った名称にする必要ありません

また rootdn とは LDAPの管理者アカウントです ここでは 「cn=Manager,dc=local」を設定しています
もっとセンスのよい名前でもよいでしょう

(3)はデータベースファイルの指定や プロセスのPID情報の書きだし先を指定します
特にインストール時の設定のままで修正する必要はありません

(4)はデータに対する 読み書きアクセス権限の設定です
今回導入する アカウント情報の管理において userPassword属性だけは参照もできないようにします
文法としては
「access to」 で データエントリ条件毎に設定します
「by アクセス元指定 write(読書可)|read(読のみ)|auth(認証)|none(アクセス不可)」
で アクセス元毎にアクセス可否を設定します
アクセス元には 以下のいずれかを指定します
「dn=”指定”」 (LDAPアカウント指定)
「self」 (アクセスアカウント)
「users」 (認証済)
「anonymous」 (認証前)
「*」 (その他)
「access to 〜 by 〜」は複数指定でき 最初に条件が一致したルールが適用されます

slapd.confの設定が終わったら ためしに slapdを起動してみます

$ su
# /usr/local/libexec/slapd
# ps ax | grep slapd
/usr/local/libexec/slapd
 

登録するデータは レコード単位で エントリと呼ばれます

  • エントリの IDキーにあたるものは DN(Distinguished Name)と呼ばれ ‘ou=People,dc=local’ のような名前を与えます
  • エントリは DNの名付けかたにより階層構造(親子の関係)をとることができます
  • エントリには dn以外に属性を与えることができます
  • 属性名や属性フォーマット は スキーマと呼ばれる定義ファイルで規定されます
  • エントリは (どのスキーマに属するかの)クラス情報を(複数)持てます objectClass と呼ばれる属性で設定します

エントリを 1つ追加してみます ldapaddコマンドを使います

$ ldapadd -D 'cn=Manager,dc=local' -w testpass
dn: dc=local
objectClass: dcObject
objectClass: organization
dc: local
o: local
description: LDAP Root Directory
(ここで 空行を入れる)
adding new entry "dc=local"
(ここで Ctrl+D を入れる)
$
 

ldapadd の オプションは以下の通りです ldapsearch ldapdelete ldapmodify でも共通です

-D ‘DN指定’ slapdにバインドするアカウントを指定します
-w パスワード 上記アカウントに対するパスワードです

登録したのは 「dc=local」つまりルートエントリです
ldapadd を実行すると 標準入力が開いて テキスト文章を直接入力することができます
複数行を入力していますが dn: が DN名 残りの行が属性設定となります
エントリに必要な情報を入力終えたら 空行 を1行入れることで 実際に LDAPへの登録が行われます

この後 続けて 別エントリのデータを入力することができます
このように 空白行がエントリ区切りとなるフォーマットを LDIF (LDAP Data Interchange Format) と言います

登録されたことを ldapsearchで確認します

$ ldapsearch
# extended LDIF
#
# LDAPv3
# base <> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# local
dn: dc=local
objectClass: dcObject
objectClass: organization
dc: local
o: local
description: LDAP Root Directory

# numResponses: 2
# numEntries: 1
 

slapd.confで設定したとおり データの参照は 管理者権限は必要ありませんが
結果コメント行に ちらっと情報があるように 「ldapsearch」は実は
「ldapsearch -s subtree -b ‘dc=local’ ‘(objectClass=*)’ ‘*’」 の省略形です
-s subtree は 検索スコープで 検索範囲を指定します 以下のようなものがあります
base (ベースエントリ検索)
one (1レベル検索)
subtree (サブツリー検索)
children (子エントリ検索)
-b ‘dc=local’ は 検索の起点となるベースDN を指定します 省略時 slapd.conf の suffixが入ったため dc=local となってます
次の ‘(objectClass=*)’ は 検索フィルタ条件の指定です
objcectClass属性は全てのエントリがなんらかの値を持つので つまり 全てのエントリが該当することになります
(dn を検索フィルタ条件に指定できないので objectClass属性となっているのかもしれません)
最後の ‘*’ は 検索に引っかかったエントリのどの属性情報を表示するかの指定です
dn以外のどの属性を表示するかを 空白区切りで指定できますが ‘*’で全項目を指定しています

ひととおりデータの 挿入 と 検索 ができることが確認できました
実際に アカウント管理を行うためのエントリを定義します nis.schema で定義される管理方法です

$ ldapadd -D 'cn=Manager,dc=local' -w testpass
dn: ou=Groups,dc=local
objectClass: organizationalUnit
ou: Groups

dn: ou=Users,dc=local
objectClass: organizationalUnit
ou: Users

dn: cn=ldapuser,ou=Groups,dc=local
objectClass: posixGroup
cn: ldapuser
gidNumber: 500

dn: uid=test,ou=Users,dc=local
uid: test
cn: test
objectClass: account
objectClass: posixAccount
userPassword: testpass2
uidNumber: 550
gidNumber: 500
homeDirectory: /home/test
loginShell: /usr/local/bin/bash
gecos: test account

(ここで Ctrl+D)

Groupsという グループ管理ディレクトリ と Usersという アカウント管理ディレクトリを作り
test というアカウント情報を登録しました
ldapsearch で 登録どおりの情報が返ることを確認できますが もう 1点 重要な確認事項があります
「userPassword」の属性が見えないことを確認してください
先の slapd.confで設定したとおり anonymous状態では参照できないようになっているはずです
(もちろん 「cn=Manager,dc=local」でバインドすれば見えます)

libnss_ldap.so の導入

LDAPへは testアカウントを登録しましたが
「getent passwd」のコマンドで testアカウントの情報はまだ見えません
nsswitch に nss_ldap の機能を追加する必要があります

ここ から libnss_ldap のパッケージを取得して

$ tar -xzf nss_ldap.tgz
$ cd nss_ldap-260
$ ./configure
〜
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
$ make
make  all-am
make[1]: Entering directory `/home/admin/nss_ldap-260'
〜
$ su
# cp nss_ldap.so /usr/glibc/2.5/i686/lib/libnss_ldap.so.2
# ln -s libnss_ldap.so.2 /usr/glibc/2.5/i686/lib/libnss_ldap.so
 

libnss_ldap.so.2 は GLIBCの lib/ ディレクトリに入れます
手元の環境は /usr/glibc/2.5/i686 ですが大抵の人は /usr でしょう
最後に /etc/nsswitch.conf で libnss_ldap.so を使う設定を入れます

passwd:      files
shadow:      files
group:       files
 

のそれぞれのエントリに “nss_ldap”の設定を追加します

passwd:      files nss_ldap
shadow:      files nss_ldap
group:       files nss_ldap
 

次のように testアカウントの存在を確認します

$ getent passwd
〜
vpopmail:x:89:89::/var/vpopmail:/bin/false
alias:x:200:200::/var/qmail/alias:/bin/false
postfix:x:207:207:postfix:/var/spool/postfix:/bin/false
smmsp:x:209:209:smmsp:/var/spool/mqueue:/bin/false
portage:x:250:250:portage:/home/portage:/bin/false
nobody:x:65534:65534:nobody:/:/bin/false
test::550:500:test account:/home/test:/usr/local/bin/bash
 

testアカウントが見えていれば OKです

pam_ldap.so の導入

telnet ftp などパスワードを要求する 多くのプログラムは PAM の機構を導入してます
PAMに pam_ldap の機能を追加します

ここ から pam_ldap のパッケージを取得して

$ tar -xzf pam_ldap.tgz
$ cd pam_ldap-184
$ ./configure
〜
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
$ make
gcc -DHAVE_CONFIG_H   -DLDAP_REFERRALS -DLDAP_DEPRECATED -D_REENTRANT  -g -O2 -Wall -fPIC -c pam_ldap.c
〜
gcc  -g -O2 -Wall -fPIC   -o pam_ldap.so -shared -Wl,-Bdynamic -Wl,--version-script,./exports.linux pam_ldap.o md5.o  -lldap -llber -lnsl -lcrypt -lresolv -lpam -ldl
$ su
# cp pam_ldap.so /usr/local/lib/security/
# cp pam_ldap.5 /usr/local/man/man5/
 

本来 make install でインストールすべきところですが
ldap.conf を不意に上書きするおそれがあったので あえて手動インストールしています

PAMの /etc/pam.d/system-auth に ldapの設定を追加します

#%PAM-1.0

auth       required     pam_env.so
auth       sufficient   pam_unix.so likeauth nullok
auth       sufficient   pam_ldap.so use_first_pass
auth       required     pam_deny.so

account    sufficient   pam_unix.so
account    sufficient   pam_ldap.so
account    required     pam_deny.so

password   required     pam_cracklib.so retry=3
password   sufficient   pam_ldap.so try_first_pass echo_pass
password   sufficient   pam_unix.so nullok md5 shadow use_authtok
password   required     pam_deny.so

session    required     pam_limits.so
session    required     pam_unix.so
 

pam_ldap.so を使う 3行を追記します
これで testアカウントで認証ができるはずです

$ telnet localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Linux 2.6.24 (localhost) (pts/5)


turion.local login: test
Password:
 

これで 認証されれば OKです

OpenLDAPのアカウント管理は さらに Sambaの認証バックエンドとしても使えるらしいのですが
手元の環境では 動作確認まで至りませんでした
(「NT_STATUS_LOGON_FAILURE」と出て終了)