view paper/chapter/03-gears.tex @ 55:76eee6847726

...
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Tue, 02 Feb 2021 12:23:46 +0900 (2021-02-02)
parents 66b32f3ec7fa
children 69e341226e5a
line wrap: on
line source
\chapter{GearsOS}

GearsOSとはContinuation Based Cを用いて実装しているOSプロジェクトである。
CodeGearとDataGearを基本単位として実行する。
GearsOSはOSとして実行する側面と、 CbCのシンタックスを拡張した言語フレームワークとしての側面がある。

\section{GearsOSのビルドシステム}
GearsOSではビルドツールにCMakeを利用している。
ビルドフローを図\ref{fig:gearsbuild1}に示す。
CMakeはautomakeなどのMakeファイルを作成するツールに相当するものである。
GearsOSでプログラミングする際は、ビルドしたいプロジェクトをCMakeLists.txtに記述する。
CMakeは自身がコンパイルをすることはなく、ビルドツールであるmakeやninja-buildに処理を移譲している。
CMakeはmakeやninja-buildが実行可能なMakefile、 build.ninjaの生成までを担当する。


GearsOSのビルドでは直接CbCコンパイラがソースコードをコンパイルすることはなく、 間にPerlスクリプトが2種類実行される。
Perlスクリプトはビルド対象のGearsOSで拡張されたCbCファイルを、純粋なCbCファイルに変換する。
ほかにGearsOSで動作する例題ごとに必要な初期化関数なども生成する。
Perlスクリプトで変換されたCbCファイルなどをもとにCbCコンパイラがコンパイルを行う。
ビルドの処理は自動化されており、 CMake経由でmakeやninjaコマンドを用いてビルドする。

\begin{figure}[hp]
  \begin{center}
   \includegraphics[width=120mm]{drawio/geasflow1.pdf}
  \end{center}
  \caption{GearsOSのビルドフロー}
  \label{fig:gearsbuild1}
 \end{figure}

\section{pmake}
GearsOSをビルドする場合は、x86アーキテクチャのマシンからビルドするのが殆どである。
この場合ビルドしたバイナリはx86向けのバイナリとなる。
これはビルドをするホストマシンに導入されているCbCコンパイラがx86アーキテクチャ向けにビルドされたものである為である。

CbCコンパイラはGCCとllvm/clang上に構築した2種類が主力な処理系である。
LVM/clangの場合はLLVM側でターゲットアーキテクチャを選択することが可能である。
GCCの場合は最初からjターゲットアーキテクチャを指定してコンパイラをビルドする必要がある。

時にマシンスペックの問題などから、 別のアーキテクチャ向けのバイナリを生成したいケースがある。
教育用マイコンボードであるRaspberry Pi\cite{rpi}はARMアーキテクチャが搭載されている。
Raspberry Pi上でGearsOSのビルドをする場合、 ARM用にビルドされたCbCコンパイラが必要となる。
Raspberry Pi自体は非力なマシンであるため、 GearsOSのビルドはもとよりCbCコンパイラの構築をRaspberry Pi上でするのは困難である。
マシンスペックが高めのx86マシンからARM用のバイナリをビルドして、 Raspberry Piに転送し実行したい。
ホストマシンのアーキテクチャ以外のアーキテクチャ向けにコンパイルすることをクロスコンパイルと呼ぶ。


GearsOSはビルドツールにCMakeを利用しているので、 CMakeでクロスコンパイル出来るように工夫をする必要がある。
ビルドに使用するコンパイラやリンカはCMakeが自動探索し、 決定した上でMakefileやbuild.ninjaファイルを生成する。
しかしCMakeは今ビルドしようとしている対象が、自分が動作しているアーキテクチャかそうでないか、クロスコンパイラとして使えるかなどはチェックしない。
つまりCMakeが自動でクロスコンパイル対応のGCCコンパイラを探すことはない。
その為そのままビルドするとx86用のバイナリが生成されてしまう。


CMakeを利用してクロスコンパイルする場合、CMakeの実行時に引数でクロスコンパイラを明示的に指定する必要がある。
この場合x86のマシンからARMのバイナリを出力する必要があり、 コンパイラやリンカーなどをARMのクロスコンパイル対応のものに指定する必要がある。
また、 xv6の場合はリンク時に特定のリンカスクリプトを使う必要がある。
これらのリンカスクリプトもCMake側に、 CMakeが提供しているリンカ用の特殊変数を使って自分で組み立てて渡す必要がある。
このようなCMakeの処理を手打ちで行うことは難しいので、 \texttt{pmake.pl}を作成した。
\texttt{pmake.pl}の処理の概要を図\ref{fig:pmake}に示す。
\texttt{pmake.pl}はPerlスクリプトで、 シェルコマンドを内部で実行しクロスコンパイル用のオプションを組み立てる。
\texttt{pmake.pl}を経由してCMakeを実行すると、 makeコマンドに対応するMakefile、 ninja-buildに対応するbuild.ninjaが生成される。
以降はcmakeではなくmakeなどのビルドツールがビルドを行う。

\begin{figure}[h]
  \begin{center}
   \includegraphics[width=160mm]{drawio/pmake.pdf}
  \end{center}
  \caption{pmake.plの処理フロー}
  \label{fig:pmake}
 \end{figure}

 


 \section{Interfaceの取り扱い方法の検討}

 GearsOSのInterfaceはモジュール化の仕組みと\texttt{goto}文での引数の一時保管場所としての機能を持っている。
InterfaceのImplementのヘッダーファイルを実装したことで、 GearsOS上でInterfaceを実装する際に新たな方法での実装を検討した。
ImplementのCodeGearは今まではInterfaceで定義したCodeGearと1対1対応していた。
ImplementのCodeGearからgotoする先は、 入力として与えられたCodeGearか、 Implement内で独自に定義したCodeGearにgotoするケースとなっていた。
後者の独自に定義したCodeGearにgotoするケースも、 実装のCbCファイルの中に記述されているCodeGearに遷移していた。

GearsOSを用いてxv6 OSを再実装した際に、 実装側のCodeGearを細かく別けて記述した。
細分化によって1つのCbCファイルあたりのCodeGearの記述量が増えてしまうという問題が発生した。
見通しをよくする為に、 Interfaceで定義したCodeGearと直接対応するCodeGearの実装と、 それらからgotoするCodeGearで実装ファイルを分離することを試みた。