2013-12-14

MacOSXでOS自作覚え書き 下準備編

30日でできる! OS自作入門』の開発環境を構築する手順を書いていきます。

前提となる環境は下記の通りです。

$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.9
BuildVersion: 13A603


まず遠回りをして こちらの記事 を参考にOSXに付属しているBSD系のアセンブラ nasm を使って VirtualBox で OS をブートして遊んでみます。

$ nasm -v
NASM version 0.98.40 (Apple Computer, Inc. build 11) compiled on Aug 13 2013

フロッピー形式でプログラムを用意して hello, world と言わせてみましょう。アセンブリですよ!



つぎに VirtualBox にフロッピーとして読み込ませる img ファイルを生成します。

$ nasm -o helloos.img helloos.asm && ruby -e 'print "\0" * (0x168000-0x200)' >> helloos.img



難なく動いてくれました。

仮想マシンを使って開発を進められるので大変手軽です。フロッピードライブも必要ないので助かります。



それではいよいよ tolsetOSX からツールセットを導入します。

まずは素直にできあいの tolsetOSX の z_tools を使うことにします。

その前に z_tools とともに同梱されている OSAkkie0.1.04 を走らせてみましょう。

OSAkkie0.1.04 ディレクトリで make all img するだけで osakkie.img がつくられるのでそれを先ほどの hello, world と同じ手順で VirtualBox 上で動かしてみます。



うまく動きました。GUIがあってリッチですね。これがOS自作の目標のレベルです。


この見本に追いつくべく開発を進めたいのですが、問題が生じました。



この記事の底本となっている『30日でできる! OS自作入門』は、本だけで完結しておらずソースコードがないと進めることができなかったのです。

本文でも Chapter 0 で下記のように書かれています。

「本と付録のCD-ROM」ではなくて、「CD-ROMと付録のぶ厚い本」なのかもしれません(笑)


ということで、『OS自作入門』を参考にしようというひとはCD-ROMを手に入れるようにしましょう。

僕はすでにこの本を持っている人に借りてOS自作を進めていますが、この記事で紹介した方法で VirtualBox 上でうまく実行できました。


下準備編はここまでですが、せっかくなのでソースからのインストールにも挑戦して失敗した経緯も書いておきます。

・コンパイルのしかた
tolsrc内でmake installを実行してください。最後までコンパイルができたら、OKディレクトリにツールがすべて入ります。


しかしその make install が失敗する。エラーは下記の通り。

$ make install
make all
make -C go_0023s
make -C gcc
make -r gocpp0 gocc1 gocc1plus
make -C ../libiberty
make -r libiberty.lib
make[6]: `libiberty.lib' is up to date.
make -C ../intl
make -r libintl.lib
make[6]: `libintl.lib' is up to date.
make -C ../go_lib
make -r go_lib.lib stdin.o
make[6]: `go_lib.lib' is up to date.
make[6]: `stdin.o' is up to date.
make -C ../drv_stdc
make -r cpp0main.obj cc1main.obj cc1pmain.obj drv_stdc.obj
gcc -c -Os -o cpp0main.obj cpp0main.c
In file included from cpp0main.c:8:
./cc1drv.c:26:5: error: second parameter of 'main' (argument array) must be of type 'char **'
int main(int argc, UCHAR **argv)
    ^
1 error generated.
make[6]: *** [cpp0main.obj] Error 1
make[5]: *** [all] Error 2
make[4]: *** [gocpp0] Error 2
make[3]: *** [all] Error 2
make[2]: *** [all] Error 2
make[1]: *** [all] Error 2
make: *** [install] Error 2


OSX 付属の clang に原因があるようなので homebrew で最新のものを入れます。

$ brew tap homebrew/versions && brew install gcc49

make bootstrap に非常に時間がかかるのですが gcc49 の make bootstrap が終わったようなので新しいほうへ symlink を貼り直します。

$ ln -s /usr/local/bin/gcc-4.9 /usr/loca
l/bin/gcc
$ ln -s /usr/local/bin/g++-4.9 /usr/loca
l/bin/g++

バージョンを確認してみましょう。

$ type -a gcc
gcc is /usr/local/bin/gcc
gcc is /usr/bin/gcc
$ /usr/local/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/gcc
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc49/4.9-20131201/libexec/gcc/x86_64-apple-darwin13.0.0/4.9.0/lto-wrapper
Target: x86_64-apple-darwin13.0.0
Configured with: ../configure --build=x86_64-apple-darwin13.0.0 --prefix=/usr/local/Cellar/gcc49/4.9-20131201 --enable-languages=c,c++,objc,obj-c++ --program-suffix=-4.9 --with-gmp=/usr/local/opt/gmp4 --with-mpfr=/usr/local/opt/mpfr2 --with-mpc=/usr/local/opt/libmpc08 --with-cloog=/usr/local/opt/cloog018 --with-isl=/usr/local/opt/isl011 --with-system-zlib --enable-version-specific-runtime-libs --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --disable-werror --enable-plugin --disable-nls --disable-multilib
Thread model: posix
gcc version 4.9.0 20131201 (experimental) (GCC)
$ /usr/bin/gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

準備が整ったところで make install に再度挑戦します。

しかし無念にも下記のエラー。

$ make install
make all
make -C go_0023s
make -C gcc
make -r gocpp0 gocc1 gocc1plus
make -C ../libiberty
make -r libiberty.lib
make[6]: `libiberty.lib' is up to date.
make -C ../intl
make -r libintl.lib
make[6]: `libintl.lib' is up to date.
make -C ../go_lib
make -r go_lib.lib stdin.o
make[6]: `go_lib.lib' is up to date.
make[6]: `stdin.o' is up to date.
make -C ../drv_stdc
make -r cpp0main.obj cc1main.obj cc1pmain.obj drv_stdc.obj
make[6]: `cpp0main.obj' is up to date.
make[6]: `cc1main.obj' is up to date.
make[6]: `cc1pmain.obj' is up to date.
make[6]: `drv_stdc.obj' is up to date.
gcc -Wl,-s -o gocpp0  ../drv_stdc/cpp0main.obj cppmain.o intl.o \
  libcpp.lib hashtable.o version.o ../intl/libintl.lib ../libiberty/libiberty.lib ../go_lib/go_lib.lib ../go_lib/stdin.o ../drv_stdc/drv_stdc.obj
ld: warning: option -s is obsolete and being ignored
Undefined symbols for architecture x86_64:
  "___builtin_stdarg_start", referenced from:
      _GO_fprintf in go_lib.lib(fprintf.o)
      _cpp_ice in libcpp.lib(cpperror.o)
      _cpp_fatal in libcpp.lib(cpperror.o)
      _cpp_error in libcpp.lib(cpperror.o)
      _cpp_error_with_line in libcpp.lib(cpperror.o)
      _cpp_warning in libcpp.lib(cpperror.o)
      _cpp_warning_with_line in libcpp.lib(cpperror.o)
      ...
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make[4]: *** [gocpp0] Error 1
make[3]: *** [all] Error 2
make[2]: *** [all] Error 2
make[1]: *** [all] Error 2
make: *** [install] Error 2

くやしいですがソースからインストールするのは諦めました。


参考