uchan note

プログラミングや電子工作の話題を書きます

x86 OS自作ゼミの進め方

セキュリティ・キャンプ2017のx86 OS自作ゼミの進め方、最大限の成果を出す方法について思うところを書きます。

3日間は短い!

x86 OS自作ゼミは3日間しかありません(それでもセキュリティ・キャンプの中では最長なのですが)。OS自作という壮大なテーマに対して3日間というのはとても短いです。しかし短い中でも人に自慢できる成果が出た方が本人も楽しいだろうし、講師も皆さんの成果を見て楽しみたいと思っていますので、3日間である程度のモノが出来上がるようにしたいです。

3日間というと、独自のOSを1からそれなりの完成度まで持っていくには時間が到底足りません。「30日でできる!OS自作入門」をノンストップで読みまくると、それだけで3日間が終わるでしょう。それくらい短い時間です。

講師を最大限活用する

この3日間は、講師が皆さんのプログラミングをお手伝いする、というのが基本スタイルです。みっちり講義をするのではなく、皆さんが自分で手を動かして、講師がデバッグや設計のお手伝いをします。逆に、講師をどれだけ活用できるかが勝負と言ってもいいかもしれません。

ということで、受講者の皆さんには3日間という時間リソースと、講師という人的リソースを最大限に活用して成果を出せるようにネタを仕込んできていただきたいです。例えば、キャンプ当日までに基本的なコードは書いておいて、3日間は講師を捕まえてデバッグを手伝わせる、なんてのはいいやり方です。デバイスドライバを作ろうと思うのであれば、キャンプに来る前にそのデバイスに関する情報(IOポートの番号、デバイスレジスタ表、サンプルコードなど)を集めておいて、3日間は調べ物に時間をかけなくて良いようにする、というのもいいですね。

関連リンク

  • seccamp2017x86 OS自作ゼミの概要とか講師紹介とか、応募課題の出題意図の説明とか

seccamp2017

x86 OS自作ゼミ 基本情報

x86 OS自作ゼミの基本的な情報は以下の通りです。

  • タイトル:x86 OS自作ゼミ
  • トラック:言語やOSを自作しよう
  • 時間帯:3日間連続
  • 必要機材:PCのみ
  • 事前学習:あり(詳しくは後述)

x86 OS自作ゼミ 概要

講師がサポートしつつ、世界に1つのPC用オリジナルOSを作ります。

開発テーマは何でも良いです。 例えば「はりぼてOS」に新しい機能(コマンドラインシェル、ディスク書き込み、プロセス間通信など)を追加したり、 最新のハードウェア(マルチコア、64bit、NICなど)に対応したOSをフルスクラッチで作ったり。 自分でOSを作っている方はもちろん、このゼミをきっかけに作り始めようとする方も、チャレンジ精神さえあれば幅広く対応します。

講師紹介

x86 OS自作ゼミでは2人の講師が参加者の皆さんの開発をサポートします。2人とも「自作OSもくもく会」を主催するosdev-jpのコアメンバーで、OS自作に対する幅広い知識を持っています。

内田公太

サイボウズ株式会社のソフトウェアエンジニアを務める傍ら、「自作OSもくもく会」を主催するなど「OSの自作」という楽しい趣味の普及に向けて活動しています。本業ではPythonやGo言語に触ることが多いですが、本当はもっとC++をやりたいです。自作OSはC++で書いています。

中学生のころに川合さん(言語自作ゼミの講師)が作っていたOSASKというOSに出会いました。そこから「30日でできる!OS自作入門」の校正作業を手伝いつつ、自分のOSを作りました。社会人になってからは粟本さん、西田さん(セキュアなCPUを自作しようゼミの講師)とともにosdev-jpというコミュニティを作り、OS自作活動の普及を目指しています。

セキュリティキャンプでは、参加者の皆さんの質問に答えたり、デバッグを手伝ったりして、OS開発のサポートをさせていただきます。

粟本真一

東京大学情報理工学系研究科コンピュータ科学専攻の加藤研究室で、主にメニーコア(Intel Xeon Phi Knights Landing processor)向けOSの研究をしています。研究兼趣味で書いているOSカーネルでは、比較的最近のデバイス(ここ10年くらい?のデバイス、マルチコア/メニーコアアーキテクチャ、PCIe、Intel NIC、USB)の実装等を行っているので、そういった事がやりたい、というチャレンジングな要望は特に歓迎します。

テーマ例

x86 OS自作ゼミの開発テーマは自由ですが、いくつかそれっぽい例をご紹介します。参加者の皆さんは、ここに書いてあるテーマでもいいですし、もちろん独自のテーマでも良いので、1つテーマを選んで応募時に書いてください。

  • はりぼてOSにディスク書き込み機能を付ける
  • はりぼてOSのセキュリティバグを探して直す
  • はりぼてOSで任意コード実行するバグを利用してマルウェアを作る
  • 新しいメモリアロケータを実装する
  • ページングに対応する
  • デバイスドライバを追加する
  • プロセス間通信をサポートする
  • マルチスレッドをサポートする
  • マルチコアをサポートする
  • 64bit対応する
  • NICドライバを実装してネットワーク通信する
  • オンメモリファイルシステムを実装する
  • カーネルモジュール機能を付ける
  • 高機能なコマンドラインシェルを実装する
  • 自作OSと組み込み機器をシリアル通信でつないで何かする

応募課題の出題意図

応募課題を通して講師が見たいのは、応募者である皆さんの「やる気」です。もちろん、ゼミを有意義なものにするのに必要な技術力は要求しますが、応募者の中から技術力の高い順に採用するわけではありません。皆さんには課題に答える形で、「自分がどれだけOS自作に興味があるか」を表現して欲しいです。

ただし「やる気がある」というのは、単に大きな声で「僕/私はこれをやりたいです!」と言えばいいというわけではありません。皆さんに期待する「やる気」は、自分で設定した課題に対していかに熱心に取り組み、問題解決できるかどうかです。今の技術力が低くとも、「やる気がある」人なら将来伸びることでしょう。講師としては、是非そういう人と一緒にキャンプの3日間を過ごしたいです。応募課題はこちらが与えた問題に答えてもらう形式ではありますが、問題に対して本気で取り組んだことを解答の中で示してください。

選択問題は基本的に「考察してください/自由に論じてください」といった形式です。自由に書けるため、一見すると簡単に思えるかもしれません。しかし、どの設問も広範な知識を要求するため、それぞれの設問で議論すべき要素を列挙することさえ難しいでしょう。現時点で議題を列挙できる必要はありませんが、少なくともWebを検索して分かる程度のことは調べてください。そして、調べたことをそのまま書くのではなく、自分の意見などで肉付けしてください。自分の意見を書くときは、なるべく根拠も書いてください。根拠のない独りよがりの意見は受け入れ難いものです。

このゼミはOS自作ゼミですから、自分のこれまでのOS自作経験を基に考察なり論じることができると良い解答になるでしょう。さらに説得力のある解答にするためには、出題されているテーマを本当に実装してみるといいかもしれません。例えばスピンロックを実装してみると利点や欠点が実体験として分かる可能性があります。ここまで頑張るかは、応募する皆さんにお任せします。

設問4は、共通課題やこのゼミの設問1-3の中で書ききれなかった自己アピールを書いてもらう設問です。「設問3は難しいから飛ばして、その分設問4にいっぱい書く」よりは、きちんと設問3を解答してくれた方が出題者は喜びます。

選択問題の補足

x86 OS自作ゼミの応募課題の中でも、難易度が高いと思われる選択問題について補足の説明をします。

選択問題は意図的に難しくしています。各問題について詳しくない人が多いと思いますが、ウェブや書籍で調べ、自分なりに回答していただきたいと思いながら設問を考えました。もちろん既に知識のある方はその知識を活用して回答を書いていただいて問題ありませんが、そうでない方もあきらめないで欲しいです。

各問題の出題意図と、その問題についての情報源を示しますので、回答する際の参考にしてください。

設問3.a

i386が持つメモリ管理機能であるセグメンテーションとページングについて説明してください。また、現代のOSではセグメンテーションは使われていませんが、その理由を考察してください。さらに、現代のOSにおけるページングの用途を説明してください。

この問題はOSの基本的な機能の1つであるメモリ管理を、CPUの視点から説明してもらう問題です。i386でセグメンテーションとページングという機能が追加されました。どちらの機能もメモリ管理に役立ちそうに見えますが、LinuxWindowsなどの現代的なOSではセグメンテーションは使われていません。それぞれの機能の特徴を比べ、セグメンテーションの何が、メモリ管理機能を実装する際の障壁になったのか、ページングではその障壁をどうやって回避したのかを議論してください。

役立つ情報源: - 『はじめて読む486』蒲地輝尚著(アスキー) - 5章「セグメント」 - 9章「ページング」 - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 4.3.1「ページング」 - 4.6「セグメンテーション」

設問3.b

OSカーネル内でスピンロックを用いる事の、利点や課題点(及びその改善策)等々を理由と共に自由に論じてください。

この問題は、マルチコアPC用のOSを作る際に必要となる技術である排他制御技術の中でも単純な原理のスピンロックを扱った問題です。排他制御技術にはいろいろな種類があります。例えばミューテックス、リーダー・ライターロック、RCUなど。工夫を凝らした技術があるのに、いまだにスピンロックが使われるのは相応の利点があるからです。もちろん、スピンロックの原理から生ずる課題点もあります。それらを自由に論じてください。

役立つ情報源: - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 2.2.3「ビジーウエイトによる相互排除」

設問3.c

ディスクはメモリに比べてとても遅いので、ファイル書き込みのシステムコールが同期的にディスクを操作すると絶望的に遅くなります。改善策を考えてください。また将来、不揮発性メモリ(NVM)が普及し、メモリと同じ要領で永続記憶にアクセスできるようになる事が期待されていますが、そのような世界のOSはどのような変化を遂げているでしょうか?根拠と共に自由に論じてください。

この問題は、CPU・メモリ・ディスクの速度差と、そこから生じる問題を軽減するための技術にはどんなものがあるかを問う問題です。例えば、引数に与えたバイト列をファイルに書き込むシステムコールがあるとします(C言語のfwriteのようなもの)。そのシステムコールが、内部でディスクのヘッドをシークしたりバイト列を書き込んだりした場合、1回の実行に数10ミリ秒以上かかることになります。これはとっても遅いです。こうならないためには、どんな改善策があるでしょうか。

現在Intel 3D Xpoint等に代表される、NVM(nonvolatile memory)と呼ばれるストレージが開発されています。これまでのストレージの多く(HDDやSSD)はブロック単位で読み書きしますが、NVMはメモリと同じようにバイト単位で読み書きできるようになり、速度もメモリ並になると予想されています。現在のOSインターフェース(システムコールなど)のままで、この次世代アーキテクチャを使いこなせるでしょうか?使いこなせないと思った場合は改善策を考えてみてください。そうでない(今のOSの仕組みでも使いこなせる)と思う場合は、その根拠を考えてみてください。

役立つ情報源: - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 5.3.6「ファイルシステムの性能」 - How Intel’s 3D XPoint will transform servers and storageZDNet、2016年3月31日 - 大解説! IntelとMicronが提唱した次世代メモリ規格「3D Xpoint Technology」ITmedia、2015年08月14日

事前学習

x86 OS自作ゼミは「事前学習あり」ということにしています。なぜなら、OS自作を全くしたことがなく、開発環境の構築の方法から教えてください、というようなレベルでキャンプ当日を迎えてほしくないからです。自分で作りたいものが決まっていて、コンパイルなどがちゃんとできる状態までは自分で学習してきてください。

キャンプ当日はいきなりコーディングを始められると理想的です。そのために、次のような状態になっていると良いです。 - 他のOSの力を借りずに自力で起動するようなプログラムが作れるようになっている - QEMUなどのエミュレータ上で起動するだけでも構いません。『30日でできる!OS自作入門』を読むなどすると学習できます。 - ある程度の大きさのプログラムを自在に書ける - このゼミではある程度のプログラミング力が必須です。OS自体を作ったことがなくてもいいですが、何らかのプログラム経験は積んでおいてください。 - 開発環境の操作に慣れている - キャンプで使う予定の開発環境の操作には事前に慣れておきましょう。

パソコンなどの準備

キャンプ受講者にはノートパソコンが貸し出される予定です。そのパソコンにはテキストエディタバイナリエディタの他、『30日でできる!OS自作入門』の開発環境であるtolset_hがインストールされています。それだけで十分なら、ご自分のパソコンは持参しなくても大丈夫です。

tolset_h以外の開発環境を使いたい場合、開発環境をインストール済みのパソコンを持参してください。例えばLinuxで開発したいとか、こだわりのテキストエディタを使いたいとかいう場合は、それらをインストールしたパソコンをキャンプ会場に持ってきてください。また、特定のハードウェアのためのドライバを書きたい場合、そのハードウェアが搭載されたパソコンをご自身で準備してください。

容量の大きな資料などは事前にダウンロードしておくとスムーズです。Linuxソースコードを参考にするつもりなら事前にgit cloneしておきましょう。アセンブリでプログラムを書きたいなら、インテル・ソフトウェア・デベロッパーズ・マニュアルのPDFをダウンロードしておくといいでしょう。

※パソコンの持参は自己責任でお願いします。キャンプ中に壊れてしまっても講師やセキュリティキャンプ実施協議会は責任は取れません。特に、OS開発にはハードウェアを壊すリスクがつきまといます。

関連リンク

【技術書典2】Linuxカーネルモジュール自作入門を出します(ダウンロード販売有)

皆さんは 技術書典2 というイベントをご存知でしょうか。2017年4月9日に秋葉原で開催される、技術書オンリーの同人誌即売会です。

この記事では、技術書典2のために書いた Linuxカーネルモジュール自作入門」 の目次をご紹介します。最後にダウンロード販売のお知らせもあります。

追記:おかげさまで、技術書典2自体も私たちのブースも非常に盛況でした。ご来場いただいた方々、運営の方々、他サークルの方々、大変ありがとうございました。ダウンロード販売のお知らせを更新しましたので、興味のある方はご確認をお願いします。

販売情報

  • 日時 2017年4月9日(日)
  • 場所 アキバ・スクエア
  • ブース き-09「tech@サイボウズ式」編集部
  • 書名 Linuxカーネルモジュール自作入門
  • ページ数 36(表紙含む)

目次

第1章「はじめに」より:

 本書を手にとって頂いてありがとうございます。この本はLinuxカーネルモジュールのビルド手順を説明する本です。Hello Worldを画面に表示するだけのモジュールを紹介します。さらに、カーネルブレークポイントを仕掛けるkprobesやカーネル内の変数を公開できるsysfsというLinuxの機能を自作モジュールから使ってみます。

 読者は基本的なLinuxの操作ができ、C言語の読み書きができることを前提としています。Linuxカーネルソースコードは読んだことがなくても大丈夫です。

  • 第1章 はじめに
    • 1.1 Linux カーネルモジュールとは
    • 1.2 動作確認環境
    • 1.3 著者について
    • 1.4 本書の取り扱い方法
  • 第2章 Hello World モジュール
  • 第3章 モジュール解剖
    • 3.1 カーネルヘッダ
    • 3.2 module 構造体
    • 3.3 モジュールファイル
    • 3.4 モジュール情報セクション
    • 3.5 シンボルバージョンセクション
  • 第4章 kprobes
    • 4.1 プローブの種類
    • 4.2 jprobe の登録
    • 4.3 コールバック関数の定義
    • 4.4 jprobe の実験
    • 4.5 全体ソースコード
  • 第5章 sysfs
    • 5.1 sysfs を覗いてみる
    • 5.2 sysfs に値を公開する
    • 5.3 コールバック
    • コラム scnprintf
    • 5.4 sysfs への登録
    • 5.5 ビルドと実行
    • コラム echo とdd
  • 参考文献

ダウンロード販売

同人誌即売会の雰囲気を大事にしたいので、当日ブースまで来ていただけると嬉しいです。しかし、何らかの理由により来られない場合、ダウンロード販売もしますのでご利用ください。

ダウンロード販売は、Amazonギフト券500円分を @uchan_nos までDMしていただければダウンロードURLをお教えします。

自作OS Advent Calendar 2016 目次

これは 自作 OS Advent Calendar 2016 の 25 日目の記事です。 1 日目から 24 日目までの記事をまとめた目次になっています。

それぞれの記事のURLの後に書いてある一言紹介は、uchanによるものです。 記事の著者さんに確認を取っておらず、もしかしたら誤った内容の可能性があります。

OSの機能拡張

OS自作用の処理系いろいろ

BIOS/UEFI

  • 12/4 neriring2

    • はりぼてOSをUEFIで起動する/総集編 - 借り初めのひみつきち
    • http://neriring.hatenablog.jp/entry/2016/12/04/180254
    • タイトルの話もさることながら、近年はレガシーデバイスがサポートされなくなってOS開発が厳しいね、という話が興味深い(と同時にちょっと悲しい)です。
  • 12/7 hikalium

  • 12/14 liva_jy

    • ディスクイメージをネットワークブートする – Raphine Project<サイト製作中>
    • https://raphine.wordpress.com/2016/12/14/netboot/
    • 開発マシンに立てた簡易HTTPサーバでOSイメージを配布し、ターゲットマシンでOSを起動させちゃうお話です。やってみたくなること間違い無し。
  • 12/17 ナカタニ

その他技術話

エッセイ

はりぼてOSでELFなアプリを起動する

これは 自作 OS Advent Calendar 2016 の 18 日目の記事です。

概要

『30 日でできる!OS 自作入門』 の「はりぼて OS」が対応している実行可能形式は HRB 形式です。 HRB という名の通り「はりぼて OS」独自の形式で、.text、.data、.bss セクションに相当するデータを含むことができます。

構造がシンプルなので、入門者にとっては実行可能形式を学ぶのに都合がいい形式であると思います。 しかし、独自形式ゆえ周辺のツールが整いづらく、実際に扱いやすい形式というわけでもありません。

本記事では、Linux 環境でスタンダードとなっている ELF 形式を「はりぼて OS」でも動かそうじゃないか、ということでやり方をご紹介します。 ELF 形式のアプリをロードして実行する方法(OS 側)、ELF 形式でアプリをコンパイルする方法(アプリ側)の 2 つの側面から解説します。

f:id:uchan_nos:20161218173129p:plain

画像はいらすとやから頂いたエルフです。

続きを読む

Windows で GCC 6.2.0 をビルドするメモ

f:id:uchan_nos:20161208235327j:plainこれは 自作 OS Advent Calendar 2016 の 8 日目の記事です。

概要

現時点で最新バージョンの GCC 6.2.0 を Windows 上でビルドするメモです。 このメモでは、i386-elf をターゲットにした GCC を作ります。 コンパイラ本体のみが対象で、標準ライブラリ等はビルドしません。 (将来、標準ライブラリも自作 OS 向けにビルドできるようになったら、また記事を書こうかと思います。っていつだよ!)

続きを読む

レベル変換の仕組み(オームの法則からMOS-FETを使ったレベル変換回路まで)

レベル変換

レベル変換とは、電圧の異なる信号線をつなぐ際に電圧を変換することです。

例えば Raspberry Pi という小さな Linux ボードコンピュータの電源電圧は 3.3V です。 そのため GPIO の入出力電圧も 3.3V となっており、電子工作でよくある 5V 駆動の装置を直接つなぐことができません。 著者は最近、秋月電子通商で売っている中で最安のキャラクタ液晶表示器 SC1602Raspberry Pi から制御しようと思ってレベル変換回路を作りました。

また、いわゆる「L チカ」といって LED を点滅させるだけの回路でも、LED によっては 3.5V 程度の電圧がないと十分に光らない品種があり (赤色 LED に比べ、青色 LED は高い電圧を求める傾向があります)、3.3V の出力では十分でないケースがあります。

レベル変換は低電圧側の回路から高電圧側の回路を制御するだけでなく、逆に高電圧側から低電圧側の回路を制御するのに用いる場合もあります。

ハードウェアエンジニアにとっては良く知られた回路ですが、ソフトウェア専門の人がちょっと電子工作しようとするとハマることが多いと思います。 この記事では、オームの法則を復習しつつ、レベル変換回路の基礎を見てみます。

続きを読む