64bit版 Linuxをスクラッチ構築して 32bit版 Linuxから移行する
ために 以下の手順を実行しました
- ターゲット環境の パーティションを設定する
- ターゲット環境に 64bitベース Linux環境をインストールする
- 32bit Linux上で動作する クロスコンパイラを構築する
- 32bit Linux上で 64bit版 Linuxカーネルをコンパイルする
- ターゲット環境に 64bitカーネルをコピーして環境を整える
- ターゲット環境で 64bit環境が起動することを確認
- インストール後の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上で作業を続けます

インターネットから getntooのファイルシステムイメージを拾ってきます

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 直後の状態から続けて
今回 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 の設定が必要です
先ほどと同じく
*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)を削除します
*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 プログラムをコンパイルしてみます
#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 の指定は必須です
結果下記のような カーネルのコンフィグが出ます

もしくは Xを使っている場合は ARCH=x86_64 make xconfig で GUIのコンフィグ画面が使えます
今回 ハードウェアが PhenomII CPUと マザーボードが GA-880GM-USB3 を意識して
設定ポイントは次のとおりです

まず General Setupですが
クロスコンパイルなので Cross-compiler tool prefix を amd64-linux-gnu- と指定します
この指定により amd64-linux-gnu-gcc が利用されます
あと SWAPを使わない方針としたので Support for paging of anonymous memory のチェックを外します

Processor type and features で AMD CPU系の設定を入れます
Processor family は K8 を選択しました (PhenomIIは 正確には K10ですが選択肢がない)

Bus options では PCI Express support を有効にします

IA32 Emulation を有効にすれば 32bitバイナリも実行できそうです

Device Drivers の中の Serial ATA and Parallel ATA drivers です
SATAを使えるように設定します

Device Drivers の中の Network device support です
ここだけは 後で再設定します NICのドライバがまだ収録されていないのです

Device Drivers の中の Graphics support です
ほとんど未設定です Xクライアントを動かす予定がないためです
Radeon HD 4250 相当のため Xを動かす場合 AMDから X用のドライバを入手する必要あります

Device Drivers の中の Sound card support です
ALSAを選択して さらにデバイスを指定する必要あります

さらにその中の PCI sound devices から Intel HD Audio を選択
Realtek の項目を選択します

Device Drivers の中の USB support です
USB3を持っているため USB3.0の項目を選択しておきます

Device Drivers の中の Xen driver support です
Xenを使って 仮想環境をそのうち構築したいなぁとか考えているので
それっぽいデバイスを選択してみました

File systems です
まず ターゲットマシンを ext3 で初期化しているため Ext3 は必須です
後は 用途に応じて必要なファイルシステムを選択します

File systems の中の Miscellaneous filesystems です
Freebsdのパーティションがあるので UFSを選択しておきます

File systems の中の Network File Systems です
あると便利な NFSと リモートWindowsのマウントもしたいので CIFSも選択しています

File systems の中の Partition Types です
UFSを選択しただけでは足りず スライスを認識するために BSD disklabel が必要です

File systems の中の Native language support です
今回から UFS8 をデフォルトとし UFS8ベースのシステムを構築したいと思ってます
今まで EUC-JPで記録した日本語ファイルがことごとくファイル名が文字化けするので
ファイル名の変換も必要になると思います (大変そう)

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 から直接ダウンロードします

ドライバは カーネルと別ディレクトリで カーネルモジュールにコンパイルできますが
今回は カーネルディレクトリに組み込む方法をとりました
手順は以下のとおりです まずダウンロードしたアーカイブを展開します
$ 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を編集して コンフィグにドライバを追加します
下記の行を追加します 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

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
うまく ブートしてきて ログインプロンプトが表示されたら
と叩いてください パスワードなしでログインできるはずです
ログインできたら手始めに何をしましょうか
次回以降システムをブートしたとき ネットワークが適切に設定され
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 のグローバルが割り当てられているのもポイントです
上記の設定がリブート後も有効になるように 各設定ファイルをカスタマイズします
一番最後の行に 自前のホスト名を設定しておきます
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の設定も設定ファイルに落とし込みます
# 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サーバ側へログインするときに その秘密鍵を使うように設定します
下記の行を追加します
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 ファイルをダウンロードしましょう

この中から必要なファイルだけ展開します ここでは 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コマンドで反映するだけです