Cygwin をホストとした EOTA 用の Linux toolchain のビルド
NAKANISHI Shin (snakani at users.sourceforge.jp)
2001/9/13 更新
2003/3/7 修正
この文章は、「Cygwin をホストとした Linux toolchain のビルド」
(原文)
を大いに参考にして作業を行った記録です。EOTA カーネルのビルドが Windows
の Cygwin 環境上でできるようになります。他の UNIX 環境でのクロス開発環境
構築にも参考になるのではないかと思います。
目次
1. 筆者の環境
2. Cygwin のインストール
3. 必要なファイル
4. 変数を設定
5. ディレクトリの作成
6. Linux のヘッダその他の展開、配置
7. gcc と binutils のソースの展開
8. binutils のビルド
9. gcc のビルド
10. EOTA カーネルのビルドについて
11 必要なパッケージその他
12. ソースの展開
13. カーネルの make
14 statfs 等のツールの作成
15. アプリケーションの make
16. newlib のビルド
17. newlib を利用したアプリケーションのビルド
18. 備考
19. 謝辞
20. 更新記録
1. 筆者の環境
=============
K6-II 450MHz, 32MB のデスクトップ。Windows98SE, Cygwin 1.1.6 です。
2. Cygwin のインストール
========================
に関しての詳細は割愛します。
C: のルートにインストールしないで、D: あるいは C:\cygwin などをルートに
してインストールするのが無難です。
3. 必要なファイル
=================
私は手元にある Debian potato(2.2) の CD-ROM に含まれるファイルを使用しまし
た。このバージョンでなければならないという訳ではありません。
binutils_2.9.5.0.37.orig.tar.gz -- 6.8MB
gcc_2.95.2.orig.tar.gz -- 12.3MB
libc6-dev_2.1.3-10.deb -- 2.1MB
gcc と binutils はソース。libc6-dev は Linux のヘッダとライブラリです。
Linux のヘッダは gcc のコンパイル時に必要になります。
2001/6/10 現在でも既に少しずつ Version が古いです。
入手先の例です。私の使った Version より進んでいます。libc-dev は新旧にと
らわれないのではないかと思いますが、binutils と gcc はリリースされた時期
がなるべく同じものを使った方がよさそうです。例えば 2001/6/15 時点で
ring.asahi-net.or.jp サーバに存在した最新版であろう binutils と gcc ファ
イルは以下の物でした。
http://ring.asahi-net.or.jp/archives/GNU/binutils/binutils-2.11.tar.gz
http://ring.asahi-net.or.jp/archives/GNU/gcc/gcc-2.95.3.tar.gz
http://ring.asahi-net.or.jp/archives/linux/debian/debian/dists/potato/main/binary-i386/devel/libc6-dev_2.1.3-18.deb
4. 変数を設定
=============
以下のシェル変数の設定を行います。
$ host=i686-pc-cygwin
$ build=i686-pc-cygwin
$ target=i686-pc-linux-gnu
$ prefix=/usr/local/linux
$ src_root=/usr/local/src/gnu
$prefix と $src_root は自分の環境に合わせて変更して構いません。他はそのま
ま入力してください。なぜ eota ではなく linux なのかは…私には説明できませ
ん。
作業すべてが一発ではできず何度かやり直す事になると思うので設定をホーム
ディレクトリの .bashrc ファイルに書いておくのも手です。Windows のメモ帳
などで bashrc.txt の名前で作成、保存し、Cygwin 環境で .bashrc と改名する
こともできそうです。ツールのビルドができてしまえばこの設定は必要ありませ
ん。消しましょう。
$ mv /tmp/bashrc.txt $HOME/.bashrc
----- .bashrc の内容 -----
host=i686-pc-cygwin
build=i686-pc-cygwin
target=i686-pc-linux-gnu
prefix=/usr/local/linux
src_root=/usr/local/src/gnu
----------
(追記) .bashrc に直接書き込むのは問題でしょう。後に違うクロス環境構築を
行なった時にはまります。適当なシェルスクリプトを作り、作業の前に実行す
るのが良さそうです。試してはいませんが、スクリプトの例です。
----- cross.sh -----
#!/bin/sh
export host=i686-pc-cygwin
export build=i686-pc-cygwin
export target=i686-pc-linux-gnu
export prefix=/usr/local/linux
export src_root=/usr/local/src/gnu
----------
実行の例です。
$ sh cross.sh
5. ディレクトリの作成
=====================
ディレクトリを作成します。
$ mkdir -p $prefix
$ mkdir -p $src_root
6. Linux のヘッダその他の展開、配置
===================================
libc-dev を展開します。.deb ファイルは ar コマンドで展開できます。その中
の data.tar.gz が中身です。それを $prefix 以下に展開し、usr を $target に
改名します。
$ cd /tmp
$ mkdir libc6
$ cd libc6
$ ar x /tmp/libc6-dev_2.1.3-10.deb
$ cd $prefix
$ tar xzf /tmp/libc6-dev/data.tar.gz
$ mv usr $target
$ cd $target
$ ls
bin include lib share
include から sys-include へシンボリックリンクを張ります。これは原文に書か
れていたからで意味は不明です。
$ ln -s include sys-include
/tmp/libc6 以下は必要なくなったので消します。
$ cd /tmp
$ rm -r libc6
(追加)
上記の様に私は作業をしましたが、/tmp ディレクトリで展開して usr/include
以下だけを $prefix/$target 以下に格納する方が無駄がないです。
$ cd /tmp
$ mkdir libc6
$ cd libc6
$ ar x /tmp/libc6-dev_2.1.3-10.deb
$ tar xzf data.tar.gz
$ mkdir -p $prefix/$target
$ cp -r include $prefix/$target
$ cd $prefix/$target
$ ls
include
$ ln -s include sys-include
$ cd /tmp
$ rm -r libc6
7. gcc と binutils のソースの展開
=================================
gcc と binutils のソースを展開します。私が入手した gcc のソースはな
ぜか二重に圧縮されていたので展開する前に一段解凍しておきます。
ファイル名の違い (Version の違い) は適宜置き換えてください。
$ cd /tmp
$ tar xzf gcc_2.95.2.orig.tar.gz
$ cd $src_root
$ tar xzf /tmp/binutils_2.9.5.0.37.orig.tar.gz
$ tar xyf /tmp/gcc-2.95.2.orig/gcc-2.95.2.tar.bz2
仮に、tar xyf ... でうまく行かない場合は、
$ bzip2 -dc /tmp/gcc-2.95.2.orig/gcc-2.95.2.tar.bz2 | tar xf -
でもできます。
8. binutils のビルド
====================
binutils をビルドし、インストールします。ソースツリーの中ではなく、ディレ
クトリを作ってその中で行います。
$ mkdir -p $src_root/BUILD/binutils
$ cd $src_root/BUILD/binutils
$ $src_root/binutils-2.9.5.0.37/configure \
--target=$target --host=$host --build=$build \
--prefix=$prefix -v
$ make > make.log 2>&1
うまくいったならインストールします。
$ make install > install.log 2>&1
ここで $prefix/bin を PATH に追加します。
$ export PATH=$PATH:$prefix/bin
.bashrc ファイルにも追加しておきましょう。
9. gcc のビルド
===============
gcc をビルドし、インストールします。
$ mkdir -p $src_root/BUILD/gcc
$ cd $src_root/BUILD/gcc
$ $src_root/gcc-2.95.2/configure --enable-languages=c --target=$target \
--host=$host --build=$build --prefix=$prefix -v
$ make > make.log 2>&1
うまくいったなら、インストールします。
$ make install > install.log 2>&1
------------------------------------------------------------
------------------------------------------------------------
10. EOTA カーネルのビルドについて
=================================
EOTA を Linux(ix86) 以外でコンパイルする時にややこしい点は EOTA カーネ
ル、アプリケーションとそれらを操作するためにホスト (この場合は Cygwin) で
動作するアプリケーション (コマンド) を標準とクロス用の gcc で作り分ける必
要がある点です。
11. 必要なパッケージその他
==========================
eota.0.X.X.tar.gz
最新版のソースを浪花氏のページ
http://www.rbt.fukui-u.ac.jp/~naniwa/comp/OS/
から入手します。2001/6/21 release 以降の版であればソースの変更なしで
ビルドできます。
12. ソースの展開
================
適当なディレクトリで展開します。どこでも構いません。私はホームディレクト
リに EOTA ディレクトリを作り、そこに展開をしているのでそれにそって説明し
ます。適宜置き換えてください。
$ cd
$ mkdir EOTA
$ cd EOTA
$ tar xzf /tmp/eota.0.2.3.tar.gz
私のこの文章での説明を楽にするためにシェル変数を設定します。
$ eota_root=$HOME/EOTA
13. カーネルの make
===================
kernel/BTRON/make に移動し、make build をしてから カーネルの make をしま
す。2001/6/21 release 以降、build.exe の作成時の面倒な作業が必要なくなり
ました。
$ cd $eota_root/eota/kernel/BTRON/make
$ make build
$ make LD=$target-ld CC=$target-gcc
$ ls -l btron
rw-r--r-- 1 hogehoge 544 446464 Jun 10 00:46 btron
のようにファイルサイズが約400KB程度ならばOKです。rawrite2.exe 等でフロッ
ピーディスクに書き込んで bootimage.bin と posix_fs.bin と組み合わせて動か
してください。
14. statfs 等のツールの作成
===========================
kernel/POSIX/mkfs 以下のツールも作成しておきましょう。
$ cd $eota_root/eota/kernel/POSIX/mkfs
$ make
statfs.exe mksfs.exe 等が作られます。PATH を通しておきましょう。
$ PATH=$PATH:$eota_root/eota/kernel/POSIX/mkfs
.bashrc ファイルにも追加しておきましょう。eota_root と PATH の項目は私の
説明が楽になるという事であって省いても構いません。
----- .bashrc の内容 -----
host=i686-pc-cygwin
build=i686-pc-cygwin
target=i686-pc-linux-gnu
prefix=/usr/local/linux
src_root=/usr/local/src/gnu
eota_root=$HOME/EOTA
export PATH=$PATH:$prefix/bin:$eota_root/eota/kernel/POSIX/mkfs
----------
15. アプリケーションの make
===========================
ディレクトリを移動し、make をします。
$ cd $eota_root/eota/kernel/POSIX/app
$ make LD=$target-ld CC=$target-gcc
$ cd $eota_root/eota/contribution/applications/pager
$ make LD=$target-ld CC=$target-gcc
$ cd $eota_root/eota/contribution/applications/frtm-bf/src
$ make LD=$target-ld CC=$target-gcc
それぞれ statfs.exe でディスクイメージへ書き込んでください。
「例」
$ statfs /tmp/sfsboot.bin dir /
$ statfs /tmp/sfsboot.bin write /hello hello
$ statfs /tmp/sfsboot.bin chmod 777 /hello
------------------------------------------------------------
------------------------------------------------------------
16. newlib のビルド
===================
必要なファイルを入手します。
newlib-1.8.1.tar.gz
newlib-eota.patch
newlib-1.8.1.tar.gz はRed Hat あるいはミラーサイトから。
newlib-eota.patch は浪花氏のページ
http://www.rbt.fukui-u.ac.jp/~naniwa/comp/OS/
から入手します。
適当なディレクトリに展開します。私はホームに EOTA ディレクトリを作り、そ
こに libc ディレクトリを作って作業をしているのでそれに添って説明します。
違うディレクトリで行なっても構いません。
$ cd $eota_root
$ mkdir libc
$ cd libc
$ tar xzf /tmp/newlib-1.8.1.tar.gz
$ cd newlib-1.8.1
$ patch -p1 < /tmp/newlib-eota.patch
$ ./configure --target=eota
$ make CC_FOR_TARGET=$target-gcc \
AS_FOR_TARGET=$target-as \
LD_FOR_TARGET=$target-ld > make.log 2>&1
これで newlib-1.8.1/eota/newlib/ 以下に libc.a crt0.o などができます。
17. newlib を利用したアプリケーションのビルド
=============================================
テストをしてみます。
$ cat > hello.c
#include <stdio.h>
main()
{
printf("Hello, world\n");
}
^D
$ $target-gcc -I. -I$eota_root/libc/newlib-1.8.1/eota/newlib/libc/include \
-c -o hello.o hello.c
$ $target-ld -Bstatic -o hello -e _start -Ttext=0x00001000 hello.o \
$eota_root/libc/newlib-1.8.1/eota/newlib/crt0.o \
$eota_root/libc/newlib-1.8.1/eota/newlib/libc.a \
$eota_root/eota/kernel/POSIX/libc/libnative.a
$ ls
hello hello.c hello.o
hello ができました。サイズが大きいので strip をかけます。
$ $target-strip hello
できたならばディスクイメージに組み込んで動かしてみましょう。
------------------------------------------------------------
------------------------------------------------------------
18. 備考
========
make 時に ar と nm その他のツールは特に指定はしませんでしたが、問題は顕在
化しませんでした。
binutils と gcc のビルド時などに、
$ $src_root/binutils-2.9.5.0.37/configure \
--target=$target --host=$host --build=$build \
--prefix=$prefix -v
と改行の前に「\」を付けていますが、これは文章化する都合であって実際には省
いて一行に長く入力して構いません。
statfs.exe マウントしているパーティションにあるディスクイメージへの書き込
みが失敗します。Cygwin 環境のあるパーティション以外へ statfs.exe ではアク
セスできないようです (私の環境では) 。
世界のどこかには Cygwin で動作する Linux(ix86) の ELF フォマートを作成で
きるツール群をバイナリで配布しているサイトが存在するかもしれません。それ
を使えればツールを作成、格納する作業時間を大幅に短縮できるので、もし発見
したら教えてください。
参考にした文章では binutils と gcc の configure のオプションは以下の通り
でした。
$ $src_root/binutils-2.10.1/configure \
--with-included-gettext \
--target=$target --host=$host --build=$build \
--prefix=$prefix -v
$ $src_root/gcc-2.95.2/configure \
--enable-languages=c,c++ \
--with-included-gettext --enable-shared --enable-threads \
--target=$target --host=$host --build=$build \
--prefix=$prefix -v
この文章ではかなり簡略化しましたが、とりあえず副作用は具体化していませ
ん。
19. 謝辞
========
浪花氏にソースの書き換えなど多くの事を協力して頂きました。
20. 更新記録
============
2001/6/10 初稿
6/14 改訂
6/15 一部改訂
6/20 一部改訂
6/21 一部改訂
6/25 一部改訂
6/29 一部修正
7/24 更新
9/13 HTML 化
2003/3/7 リンク先の URL を修正