自作OS事始め 1. 環境構築編


そうだ、OS作ろう!

というわけで、OSを作ってみたいと思います。
今回はGCCのクロスコンパイラを入手するところまでやっちゃいましょう。

用意するもの

  • Ubuntu 20.04

1. 依存関係のインストール

まずは、依存関係をインストールしていきます。

必要なものは以下の通りです。

  • curl
  • build-essential, m4
  • libgmp3-dev, libmpc-dev, libmpfr-dev
  • qemu, qemu-kvm

curlはお好みで、wgetなどでも構いません。

$ sudo apt update
$ sudo apt -y install curl build-essential m4 libgmp3-dev libmpc-dev libmpfr-dev qemu qemu-kvm

2. gmp、mpfr、mpc、binutilsのビルド

まずは、gmpをmakeします。--prefix=/usr/local/ccにしていますが、ここもお好みで構いません。ただし、この--prefixで指定した値はgmp、mpfr、mpc、binutilsで共通とした方が良いと思います。

まずはgmpから。

gmp
$ curl --output gmp-6.2.0.tar.bz2 https://ftp.gnu.org/gnu/gmp/gmp-6.2.0.tar.bz2
$ tar -xvf gmp-6.2.0.tar.bz2
$ cd gmp-6.2.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..

つづいてmpfr、mpc、binutilsの順番でmakeしていきます。

mpfr
$ curl --output mpfr-4.1.0.tar.bz2 https://ftp.gnu.org/gnu/mpfr/mpfr-4.1.0.tar.bz2
$ tar -xvf mpfr-4.1.0.tar.bz2
$ cd mpfr-4.1.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..
mpc
$ curl --output mpc-1.2.0.tar.gz https://ftp.gnu.org/gnu/mpc/mpc-1.2.0.tar.gz
$ tar -xvf mpc-1.2.0.tar.gz
$ cd mpc-1.2.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..
binutils
$ curl --output binutils-2.35.tar.xz https://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.xz
$ tar -xvf binutils-2.35.tar.xz
$ cd binutils-2.35
$ ./configure --target=x86_64-elf --prefix=/usr/local/cc --disable-nls
$ make
$ make install
$ cd ..

3. gccのビルド

さて、ついにGCCのmakeです。
ここで、注意点がいくつかあります。
1つ目は、gccのソースコードのディレクトリに入って、./configureとしてはいけないということです。そのようにしてしまうと、make all-target-libgccでこけます。
2つ目は、configureの引数の--with-xxxです。これは、それぞれ前の段階でgmp、mpfr、mpcの--prefixで指定したディレクトリを指定してください。
3つ目は、--with-as引数です。これは、ほかのものと違い、実行バイナリのパスを直接指定する必要があります。

gccのmake
$ curl --output gcc-10.2.0.tar.xz https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz
$ tar -xvf gcc-10.2.0.tar.xz
$ mkdir gcc-make-tmp
$ cd gcc-make-tmp
$ ../gcc-10.2.0/configure\
    --target=x86_64-elf\
    --prefix=/usr/local/cc\
    --disable-nls\
    --enable-languages=c\
    --without-headers\
    --with-gmp=/usr/local/cc\
    --with-mpfr=/usr/local/cc\
    --with-mpc=/usr/local/cc\
    --with-as=/usr/local/cc/bin/x86_64-elf-as # asコマンドのバイナリのパスを指定する
    # これがないとこけることがある(stdio.h: no such file or directory.)
    # こける場合は追加する
    # --with-headers=/usr/include\
    # --with-headers=/usr/include/x86_64-linux-gnu
$ # 結構な時間がかかるので、このコマンドを実行している間にお茶休憩をしましょう。
$ make all-gcc && make install-gcc
$ make all-target-libgcc && make install-target-libgcc

4. テスト

$ export PATH=/usr/local/cc/bin:$PATH
$ x86_64-elf-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-elf-gcc
COLLECT_LTO_WRAPPER=/mnt/d/usr/local/cc/libexec/gcc/x86_64-elf/10.2.0/lto-wrapper
Target: x86_64-elf
Configured with: (省略)
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (GCC)

このような出力がなされれば成功です。お疲れさまでした。

5. 感想

情報が少なくて苦労しました。特に、最後のgccのmakeがしんどかった。

binutilsはソースからビルドしましょう。