連載
» 2012年02月09日 11時55分 UPDATE

H8マイコンボードで動作する組み込みOSを自作してみよう!(7):ソフトウェア完全自作のWebサーバを動かしてみよう (1/4)

本連載もついに最終回。今回はTCP/IPを実装し、最終目標である「ソフトウェア完全自作のWebサーバ」を動作させる。その手順を詳しく紹介する。

[坂井弘亮,@IT MONOist]

 本連載では、学習用・ホビー用の組み込みOS「KOZOS」を使ってマイコンボード上でいろいろと実験をしつつ、フルスクラッチで組み込みOSを自作していく過程を体験してみます。

 前回「『ping』によるネットワーク通信機能を実装してみよう」では、ネットワーク通信を実装し、「ping」による通信を動作させました。

 今回は、ついに最終目標の「Webサーバ」を動作させます。それは、ブートローダーからOSのカーネル、TCP/IPスタック、HTTPサーバアプリケーションまで、ソフトウェア完全自作のWebサーバです。そして、ソースコード量はブートローダーとOSモジュール、アプリケーションの全てを含めても、“6000行”を切っています。たった数千行のソースコードで、ソフトウェア完全自作のWebサーバがマイコンボード上で動くと聞いて、何だかワクワクしてきませんか?

1.マイコンボードとソースコード

 本連載では、秋月電子通商の「H8/3069Fネット対応マイコンLANボード(完成品)」(図1)を利用します。マイコンボードの詳細については連載第1回を参照してください。ちなみにこのボードは、3750円(税込)と非常に安価で入手性も良く、個人のホビー用途にオススメです。

図1 本連載で利用するH8/3069Fマイコンボード 図1 本連載で利用するH8/3069Fマイコンボード

 今回紹介するソースコードは、著書「12ステップで作る組込みOS自作入門」とKOZOSのWebサイトの内容に、“プラスα”でネットワーク機能を追加したものです。その内容は、http://kozos.jp/kozos/h8_2_06.htmlで公開しています。今回はこちらをダウンロードして使用してください(補足)。

※補足:今回、Webサーバのソースコードは説明の都合上、上記で紹介したものを使用しますが、最新版も筆者のWebサイトで公開しています。ご興味のある方はこちらを参照してください。最新版では、Ethernetの送信割り込み対応やシミュレータ対応、GDBによるデバッグ対応の他、さまざまなバグ修正などが行われています。


 また、開発環境の構築方法は連載第1回で説明してありますので、興味のある方はぜひソースコードをビルドし、実機での動作を試してみてください(幾つか対応は必要となりますが、シミュレータ上でも動作させることが可能です)。

 なお、本連載で利用する組み込みOS、KOZOSのカーネル構造については、著書「12ステップで作る組込みOS自作入門」に詳しい説明がありますので、そちらも参考にしてみてください。

参考文献[1]

  • 「12ステップで作る組込みOS自作入門」(カットシステム/著:坂井 弘亮)


2.TCP/IPスタック

 Webサーバの動作のためには、まずはTCP/IPスタックの実装が必要です。前回までの内容でIP通信はできていますから、TCPによるやりとり、つまり「プロトコル」が実装できればいいことになります。

 TCP/IPは“コネクション型”のプロトコルです。接続側が「SYNパケット」を送信し、受信側がそれに対して「SYN+ACKパケット」で応答します。さらに、接続側がそれを受けて「ACK」を送信することで、コネクションが確立されます。この一連の流れを図2に示します。

TCPによるコネクション確立 図2 TCPによるコネクション確立

 コネクションの確立後は転送したいデータを任意に送信し、受信側は応答としてやはりACKを返します。これを簡単な図にすると、図3のようなイメージになります。実際には、データの順番を保証するためのシーケンス番号の制御なども含まれます。

TCPによるデータ転送 図3 TCPによるデータ転送

 ここまでできれば、取りあえずコネクションを確立してデータの転送を行うことは可能です。さらに、TCP/IPはスライディングウィンドウや輻輳(ふくそう)制御などのさまざまな機能を持っており、ネットワークの帯域や遅延に合わせて動的にチューニングを行います。ただし、単純なデータ転送だけであれば、こうした機能がなくても動作可能です。

 KOZOSの開発ポリシーは「組み込みOSが持っているような一通りの機能を、おのおの数百行程度の少ないソースコード量でサンプル実装してみる」ですので、本稿でも難しい付加機能のことは考えず、取りあえず実装してみましょう。

3.HTTPサーバ・アプリケーション

 Webサーバとして動作させるためには、HTTPによる接続を受け付けて応答するサーバアプリケーションが必要です。

 HTTPは“80番ポート”で待ち受けし、接続したらWebブラウザ側で「GET /index.html」のように取得したいファイルを送信すると、サーバ側が応答でそのファイルを送ってくる……という単純なプロトコルです。このため、TCP/IP通信さえできてしまえば、Webサーバを実装することはそれほど難しいことではありません。

 例えば実験として、HTTPプロトコルを手動で発行してみましょう(リスト1)。

hiroaki@red:~>% telnet xxx.xxx.xxx 80  ←telnetでWebサーバの80番ポートに接続
……(中略)……
Connected to kozos.jp.
Escape character is '^]'.
GET / HTTP/1.0  ←GETメソッドを手作業で入力
  ←空行を入力するとWebサーバから応答が返ってくる
HTTP/1.1 200 OK
Date: Sat, 21 Jan 2012 00:33:40 GMT
……(中略)……
Connection closed by foreign host.
hiroaki@red:~>% 
リスト1 HTTPによるGETメソッドの発行

 リスト1は、TelnetクライアントでWebサーバの80番ポートに接続し、手作業でHTTPのGETメソッドを発行してみたところです。接続後にGETメソッドの一文を手で書き、(HTTPでは空行がヘッダ部とメッセージ部の区切りを表すため)Enterキーを2回押すことでサーバから応答が返ってきます。

 つまり、サーバ側はTCPで接続待ち受けをして、行単位に文字列を受信し、GETメソッドが来たら要求されたHTMLの本文をリスト1のようにヘッダを付けて返してやれば、簡単なWebサーバとして機能することになります。

 ただし、KOZOSはファイルシステムを持っていないため、「index.html」をファイルとしてシステム上に持つことはできません。そこで、HTMLファイルは、HTTPサーバ側で“静的な文字列”として保持させることにします。つまり、HTML文書をソースコード上にハードコーディングしてしまうわけです。

4.タスク設計

 前回は、Ethernet、ARP、IP、ICMPの処理をそれぞれタスクとして実装しました。これは各処理を細かくタスク分けすることで、おのおのの処理の見通しをよくすることが目的でした。

 今回も同様の考えで、TCP処理とHTTPサーバをそれぞれ独立したタスクとして実装することにします。

 TCPの処理に必要なのは、IPパケットの送受信のみです。このため「tcpタスク」はipタスクとメッセージ通信し、受信パケットを受け取ったり、送信パケットを依頼したりすることで処理を行います。

 HTTPサーバは、「httpdタスク」として実装します。httpdタスクは、tcpタスクに対して接続待ちの依頼を発行します。Webブラウザから接続されたら、tcpタスクからhttpdタスクに対して受信文字列が送られ、httpdサーバは受信文字列を解析してリクエストに応じてHTMLのデータをHTTPで返信します。このようにして、Webサーバの機能が実現されます。

 図4は、これらのタスクの構成です。そして、タスク間通信は、KOZOSのメッセージ通信を利用して実装します。

HTTP通信のためのタスクの構成 図4 HTTP通信のためのタスクの構成
       1|2|3|4 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.