移植のノウハウ - FreeBSDのドライバの移植を試みたら失敗した

僕が「この人はすごいなぁ」と思う人は大抵、過去に何らかの大きな移植を経験して力をつけているように思えます。
例えばOSASKの川合さんはGOなどを手がけられています。
また達人に話を聞くと、「移植なんて、コンパイル通るまでスタブとか作ってエラーがなくなるまでがんばればいいんだよ」と言います・・・



最近ようやく僕も必要に迫られて思い腰を上げて移植に取り組むようになりました。
で、その成果と言うか成績は

と1勝1敗です。

uIPの移植はなぜうまくいったか

  • uIPが移植されることを前提とした作りになっていた
  • 全容が把握できるほどに小さいサイズだった

の2つが大きいと思います。
移植初心者の僕にはちょうど良い難易度でした。

FreeBSDのドライバの移植はなぜうまくいかないか

  • 移植前提で書かれていない
  • カーネル全体のコードを把握するのはとても時間がかかる

それ以外にもたくさんの理由があると思うのですが、手探り状態なのでまずは移植失敗の過程を明らかにして、識者の方々に少しでもアドバイスいただけたらうれしいです。

FreeBSDのドライバの移植の失敗過程

1.FreeBSDNICドライバが移植できたらうれしいと考えた。
2.NICのNE2000に関して、MonaにはNE2000.cppという動作するドライバがある。
3.FreeBSDには src/sys/dev/ed/if_ed.cという動作するドライバがある。
4.この両者を比べれ、共通点を探し少しでも似ている部分があれば、その一部だけを置き換えてみて、コンパイルして動作させてみる
5.4を繰り返すことで、FreeBSDのドライバインターフェースの勉強、さらにはif_ed.cがNE2000.cppにとってかわり、移植が成功するはず。
6.実際にソースコードを比べてみると、初期化部分のフローでoutpされている内容とかがかなり似ていることが分かる。
7.初期化部分 ed_init(void *xsc), ed_init_locked(struct ed_softc *sc) をMona用にコンパイルしようとしました。
8.まずは該当部をコピペして、未解決シンボルを、FreeBSD側からコピーし続けました。
9.未解決シンボルは、defineされていたり、typedefされていたりと多岐に渡りますが、とりあえず「そのコードの内容の意味を理解せず」どんどんFreeBSDからコピーしました。
10.その結果、FreeBSDのたくさんあるヘッダから必要なものをとってくればとってくるほど、さらにそいつらが別のものを参照していて・・・。という悪循環にはまり、挫折してしまいました。
11. 更なる詳細やら挫折したコードはmones2/21.NICドライバ移植/05.初期化処理をコピペコンパイルにあります。

失敗したけど・・・

でもこれで諦めては、移植力が上がらないので以下の感じで再チャレンジしようと思うのですがどうでしょうか。
FreeBSDに詳しい方や、移植得意な方々アドバイスいただけたら助かります。

方針
if_ed.cの初期化処理をさらに細かく分けて、その分けた断片の移植をこころみる

おまけ - 今回学んだこと

  • GLOBALによるソース読み
  • find src/sys -name "*.h" | xargs grep ifnet | grep -v "*"
  • 大量のtypedef, マクロが生む、コンパイルエラー時のわからなさっぷり
  • ヘッダの依存関係が半端じゃない構造