セキュリティ・キャンプ全国大会2018応募用紙の話

お久しぶりです。PiBVTです。前回、ゴールデンウィークにH8マイコン用のOSを作った話以来の投稿となります。あの記事も、もともとはセキュリティキャンプ全国大会に応募しようと思ったことがきっかけで書いたものでしたが、この度、無事にシステムプログラミングトラックOS開発ゼミの審査に通過したので、応募した内容を掲載したいと思います。

私は他の参加者の方たちのように洗練されたナウでヤングでバッチグーな文章ではなく、思いついたことを脈絡もなく書いた文章なので読みづらいところも多々ありますし、かなり長い(約4万字)ので、高速スクロール等を使いながら部分的に読むことをおすすめします。

最後にこれまでの感想と、キャンプまでの目標を書いているので、読んでいただければ幸いです。

それでは、以下が私が応募した内容です。課題内容はセキュリティキャンプ全国大会2018応募課題システムプログラミングトラックから、それ以外は原文ママです。

■共通問題A

我々講師は、普段いくつかのOSを使っていますが、使い込むうちに色々な発見をします。
皆さんもきっとそういう体験があると思います。
あなたが普段使っているOSで、好きな機能と改善してほしい部分について、思いのたけを聞かせてください。
この問では、皆さんが普段どの程度興味を持って既存OSを観察しているかを評価します。

私は普段、Windows 10とLinux(Arch Linux)を使っているが、それぞれについて好きな機能と改善してほしい部分を挙げる。

Windows
好きな機能
・インストールするだけで正常に作動して直観的に操作しやすいアプリケーションが多い。
私はWindows 2000以降しか利用したことが無いためWin95系の不安定な環境は体験したことがない。
そのため、Windows に関して感じるところとしては、アプリケーションのインストーラーや実行ファイルを実行するだけで容易にアプリケーションを利用することができ、コンパイルエラーで四苦八苦することがないというのは好きな点である。また、一応インストールされているプログラムを修正したり、アンインストールしたりする機能もあり、PCにインストールされているアプリケーションの管理が容易なところが良いと思う。さらに、アプリケーション自体もGUIによって操作できるものがほとんどであり、コマンドを追加で覚える必要がなくマウスだけで操作が完結してしまうものもあるため、アプリケーションを利用する初期段階の難易度は圧倒的に低く、とっつきやすいところが好きである。

・GUI型のアプリケーションを容易に開発できる言語と統合開発環境が無償で提供されている
10数年前から、Windows のアプリケーションの開発環境としてVisual Studioが個人向けに無償で提供されているが、インストールすればトラブルなく利用することができ、さらに非常に分かりやすいVisual Basicを使うことが出来る点が好きである。私が初めて使ったプログラミング言語がVisual Basicであり、GUI型の数あてゲームを作ったことがある。後にLinuxでQtを利用したGUI型アプリケーションを作成しようとしたことがあるが、複雑さ故に挫折してしまった。当時小学生の私でも簡単なGUIアプリケーションならば簡単に作ることができ、Windows とその開発環境をサポートできるMicrosoftならではの利点であると思う。

・アプリケーションのエコシステムの大きさ
最近はLinuxやMac対応のゲームソフトやプラットフォーム(Steam)が登場しているが、私が小・中学生の頃はゲームはwindowsでしか動作しないものばかりであり、ゲーム分野やそれに付随してグラフィック系のドライバは今もなおWindowsが強い分野であり、ゲーム好きの私にとっては嬉しい点である。さらに、マイコン系の開発環境もWindows向けがほとんどであり、インストールすれば簡単に開発環境を構築できるのは素晴らしいと思う。他にも、Officeや個人開発者の方たちが作られた便利な各種フリーソフト等もほとんどがWindowsでのみ利用できるものであり、Windows環境であれば必要なアプリケーションは全て揃えることが出来るというポテンシャルの高さは素晴らしいと思う。

・とりあえずの安心感
前述のアプリケーションのエコシステムの大きさと共通する部分もあるが、利用者が圧倒的に多いため、トラブルに遭遇しても周囲の人やネット上で解決策を探せば解決できる可能性が非常に高いと言えるところである。利用するアプリケーションも周囲の人と同じものにすれば質問することも出来る。デバイスドライバに関してもWindows向けのものが提供されていないことは無いといえるほど充実しているため、機器を買ってドライバをインストールすればとりあえず動くという安心感は素晴らしい。セキュリティに関しても毎月配布されるパッチを入れてWindows 10に関してはウイルス対策ソフトが標準で搭載されているため、そこまで気にする必要はない。パッチを入れたら起動しなくなるというトラブルも殆ど無いのは安心である。(たまにはあるが…)とりあえずWindowsを入れておけば何とかなるという安心感はWindowsだけの特権であると言える。

・デバイスの動作率の高さ
これに関してはUSBのおかげである気もしなくはないが、殆どのデバイスについてハードウェアベンダーからのドライバが用意され、適当なドライバが無い場合はMicrosoft製の標準ドライバでとりあえずは動作させることが出来る。また、個人的には、デバイスの動作状況をGUI上で確認できる「デバイスマネージャー」は素晴らしいツールであると思っている。

改善してほしい部分
・個人情報の収集機能
現在のWindowsでは位置情報やWebページの閲覧履歴その他の履歴等を収集する機能が搭載されているが、OSというものはあらゆるアプリケーションの土台となる部分であり、そのOSが個人情報を収集し、Microsoftに送信する機能があるのは残念である。エラーを起こしたアプリケーションのログ等は構わないと思うが、位置情報などの実生活と結びついた情報を収集する機能は必要ないと思う。

・クラウドとの連携前提
Windows 10になってからクラウドとの連携が深くなり、ドキュメントのデフォルトの保存場所をOneDriveにしたり、インストール時にMicrosoftアカウントを作成することを要求してくることがある。OneDrive自体も無料版の容量が5GBしか無いため実用性に欠ける。また、GoogleやAppleではクラウドによってスマートフォンとの連携が容易になっているが、Windows搭載のスマートフォンは殆ど使われていないし、PCを複数持つ人も限られているため、クラウドを利用する利点が見いだせていない。むしろ、データを同期するためのバックグラウンド処理が非常に重いことがあり残念である。

・広告
Windows 10では利用者の好みを認識して好みそうなアプリケーションの広告を表示する機能があるが、ライセンスを買ったOSで必要ない広告が表示されるのは目障りである。

・必要のないアプリケーション
私がWindowsの改善してほしい部分で最も強く思い、大嫌いな要素である。Windows XPの頃は、必要なユーティリティとメーラーらWebブラウザなどインターネットを利用するために必要最低限のものしかインストールされていなかった。しかし、Windows 10ではインストール直後にCortanaやOneDrive、VR,AR系のアプリケーション、よくわからないゲームの数々といった、私にとって何ら意味の無いアプリケーションが大量にインストールされるのは非常に不愉快であるし、Window Storeによる自動アップデートで負荷が高くなり、作業効率が低下することも多々あった。Microsoftがどういった意図でこれらのアプリケーションを標準でインストールするようにしているのかはわからないが、Windowsをインストールする段階で選択できるようにしてほしい。

・アップデートでの自動的な再起動
Windows Updateを実行するために自動的に再起動する機能のせいで、作業が中断されたり、放置していた処理をやり直すことになったことがある。システムのファイルを書き換えるために再起動は必要なことではあるが、自動的に再起動したり、更新作業にかかる時間が長いことは改善してほしい。出先でノートPCを起動したとき起動直後の更新作業がなかなか終わらずPCが使えなかったことがある。

Linux
好きな機能
・ディストリビューションの多様性
Linuxのカーネルを利用したものとして、UbuntuやFedora,Debian,ArchLinux,Gentooなど様々であるが、好みに合わせてディストリビュージョンを選ぶことができる。初心者ならばUbuntu、新しい物好きならFedora,サーバー用のOSならDebian,CentOS、イチからパッケージを入れて環境を構築したいならArch Linux、ソースコードからパッケージを導入したいならGentooなどそれぞれのディストリビューションが特徴を持ち、利用する側もその特徴や使い心地に応じて選択できる。その一方でカーネルはLinuxであるため、だいたいのソフトウェアはどのディストリビューションでも動き、蓄積したノウハウも活かすことが出来る。この多様性もLinuxの良い点である。

・パッケージ管理システム
Windowsでは第三者が配布するアプリケーションを自分でダウンロードしたりCD,DVDからインストールすることで利用するが、Linuxの場合は大半のアプリケーションがディストリビューションごとのパッケージ管理システムによってパッケージとして配布されている。一部ディストリビューションにはパッケージ管理システムが無いが、殆どの場合はこのシステムを利用できる。このシステムによって、パッケージのアップデートの有無を効率的に確認することができ、パッケージでインストールすれば、依存関係も自動的に処理され、ほとんどのアプリケーションが問題なく動作するというのはWindowsには無い便利な機能である。

・システムコール・ライブラリコールを用いたプログラミング
Linuxでアセンブリを使ってHello Worldをするプログラムを書いたことがあるのだが、レジスタに標準出力のシステムコール番号を放り込み、int 0x80でシステムコールを実行するものであった。このプログラムを書くまでは、システムコール=難しいものというイメージがあり忌避していたが、アセンブラで標準出力をするのにたった数行で事足りるのは衝撃であり、OS,システムコールの威力を知るきっかけとなった。また、Linuxではソケットを用いることでipv4等の通信を容易にすることができる。Androidの自作アプリとRaspberry PiでWi-Fiラジコンを作ったときに初めてCでソケットプログラムングをしたが、ipv4で通信してデータを処理するプログラムが200行ほどで書け、想像以上に簡単であった。このような機能はLinuxの特徴の1つであり便利だと感じている。

・サーバーとして利用できる
個人がLinuxを使う理由として最大の理由がサーバーのOSとして使えることである。私は自分のサーバーでNextCloudやGitLab、テスト用のWebサーバーを運用しているが、OSは全てLinux(Debian)である。Windows ServerもMicrosoft Imagineの制度で無償で利用することが出来るが、正直必要のない機能もあり、さらにはメモリー等のリソースもLinuxに比べて多く消費するため使いたいとは思わない。DebianやCentOS等のサーバー向けディストリビューションならば必要最低限のパッケージをインストールするように設定できるため、無駄なリソースを消費することなく、セキュリティの安全性も高めることが出来る。また、CentOSやDebianは商用のサーバーOSとしても利用されているため、安定性・信頼性も高い。

・セキュリティ管理の容易さ
パッケージ管理システムによって、ディストリのサポートが切れていない限りではパッケージの更新だけでソフトウェアの脆弱性を潰すことができる。Windowsではいちいちアプリケーションごとに公式サイト等を確認してアップデートがないかを確認する必要があり、面倒である。IPAから更新の有無を確認できるアプリケーションも配布されているが、マイナーなアプリケーションは対応していない。Linuxというよりパッケージ管理システムのおかげではあるが、これも便利な機能である。また、ファイルやディレクトリごとの権限が明確に設定されているため、第三者の不正なアクセスを防げる可能性がWindowsに比べて高い。ls -lによってファイル・ディレクトリの所有者・権限を確認することができ、不適切な設定ならばchmodやchownで簡単に変更できるのは素晴らしい。また、このときに設定するユーザー・グループもLinuxでは容易に確認・管理することが出来る。Windowsでは権限を設定しようとするとGUIで分かりにくいステップを踏まなければならなく、権限がどのように設定されたのか簡単に確認することができない。

・シェル(CLI)
最大の利点でもあり初心者にとっては障壁となるシェルである。私はまだまだシェルを使いこなせていないのだが、書籍やネット上の記事を見ていると、Windowsでは面倒なディレクトリやファイルの操作が一括で終わらすことができ、さらにはシェルスクリプトで自動化も出来る。さらにはインストールしたアプリケーションの殆どが端末からCLIで操作することができ、GUIだと何階層もマウスで辿らなければならない操作をキーボードでコマンドを数個打つだけで操作できるのは非常に便利である。また、サーバーの管理をする際もSSHで入ればCLIで快適に操作することができ、リモートデスクトップのような回線が遅い場合フリーズするようなことにならなくて済むのは快適である。

・カスタマイズ性の高さ
Windowsでは触ることのできないカーネルを始め、GUI(WM,DM)や、シェルもbashやzshといったものに自由に入れ替えることが出来るのはLinuxだけである。カーネルに関しては普段はカスタマイズをすることはほとんどなく、せいぜいドライバのモジュールをインストールするぐらいではあるが、人によってはLinuxのカーネルコンフィグの設定を書き換えてビルドして独自カーネルとして利用するということもしている。GUIに関しても、WindowsやMacでは最初から入っているものを使うだけであるが、LinuxではGNOME,KDE,XFCE4,i3WM,Awesomeなど複数種ある中から自分が使いたいと思うものを選び使うことが出来る。ちなみに、私の友人でArch Linuxを使っている人が2人いるが、全員違うWMを使っている。私はXFCE4で、友人はKDE,i3WMである。同じディストリビューションでも使っているWMが違うため外観が全く違うというのは面白いことであるし、自分好みの環境を構築できるため愛着が湧いてくる。

・低スペックPCでもその気になれば快適に利用できる
自由にカスタマイズすることが出来るため、無駄な機能を省き、軽量なWMを入れることで10数年前のPCでも快適に利用できる環境を構築することができる。PuppyLinuxはLive CDで起動することができ、メモリが256MBさえあればちょっとしたプログラミング程度ならば普通に使える。私が中学生の頃はWindows XP初期のパソコンをもらい使っていたためWindowsの動作が遅く、なんとかしようとして軽いと言われていたLinuxを入れて使っていたことがあった。現在ではGUIがリッチになりUbuntuやFedoraはかなり重量級のOSになってしまっているが、私が愛用しているArch Linuxでは、インストール直後はGUIに関するものが一切入っていないため自由にDM,WMを選定して入れることができ、快適な環境を構築することができている。

改善してほしい部分
・グラフィック系のドライバの充実
Linuxでよくトラブルになるのがグラフィック関連で、解像度が正しく認識されない・表示が崩壊している・そもそもGUIが起動するとフリーズする、などのトラブルに遭遇したことがある。最近ではドライバも充実してトラブルに遭遇することは頻繁ではなくなったが、やはり不安定なこともある。また、最近のCPUには動画再生支援機能が搭載されており動画等の処理を請け負ってくれるが、Linuxの場合、ChromeでYoutubeを見ようとすると動画再生支援機能が正常に動作せずCPUの負荷が高いままになってしまう。何度か解決しようとしたものの失敗した。Windowsでは標準で動作しているため、改善してほしいものである。

・PC初心者に対する敷居の高さ
Ubuntuの登場でLinuxに対する敷居は圧倒的に低くなったものの、アプリケーションが動かなかったり、周囲に相談できる人がいないという点からPC初心者におけるLinuxの敷居は依然高いものであると感じている。私個人としては、プログラミングをするならばWindowsでCygwinを入れたりするよりもLinuxでgccを入れるほうが簡単だしトラブルも少ないと感じているが、初心者にとってはそうでないらしい。Windowsは良くも悪くも難しい部分を覆い隠しているため初心者にとっては扱いやすいものではあるが、Linuxのほうが簡単に出来ることもあるし、難しいイメージを払拭できればいいなと思っている。

・パッケージの新旧
これはCentOSやDebianでよく遭遇することであるが、レポジトリ上のパッケージが古く、別の開発環境で書いたプログラムが動かないことがある。また、サーバー方面では改善されたり、新たに追加された機能を利用することができないことがある。最近遭遇したトラブルとしてはメイン環境(Arch Linux)で書いたRubyのプログラムがCentOSではレポジトリのRubyが古く、gem(nokogiri)がインストールできないことがあった。当然そのままでは動かすことができないため、最新版のRubyのソースコードをコンパイルして導入しようとしたがうまくいかなかった。その時はArchLinuxでサーバーを建てることに興味があったため、ArchLinuxでサーバーを建て動かしていた。ロングサポートなどの関係でパッケージのバージョンが古いままであることは仕方が無いと思うが、CentOSやDebianでももっと容易に最新版パッケージを利用できるようにしてほしい。

■共通問題B

皆さんが仮にOSを作るとしたら、「どんなOS(やOSの機能)を作ってみたい」でしょうか?
(既にOSを作った事がある人は、その特徴を書いてくれても構いません。)
そして、なぜそれを作ってみたいと思ったのでしょうか?
皆さんが心の中で夢描いているであろう、ワクワクするようなOS像を教えてください。

・ネットワーク上で動くOS
クラスタコンピューティングで大量の物理マシン上のアプリケーションを協調動作させる手法は昔からあるが、私は、1つのOSで複数のマシンを管理するというOSを作ってみたい。今考えている構成としては、各マシンでは必要最低限だけの機能(デバイス・ネットワーク管理等)が搭載された小型OSが走り、それらを束ねたいわば1つの仮想マシン的な環境で豊富な機能を持つOSが走るという構成を考えている。ネットワークの通信や互いの協調動作など解決すべき問題は多いが、単純に大量のマシン上で1つのOSが走るというのはカッコイイと感じるし、ホームネットワークのIoT機器群について応用すれば、限られたハード資源を有効に活用できるのではないかと考えたからである。私の個人的な趣向で、P2Pやクラスタコンピューティング、ブロックチェーンのマイニングなど大量の何かが、1つの目的を達成するために協調して動作していることに非常にワクワクすることも理由の1つである。

・アプリケーションとしてのOS
Dockerは内部にOSと似たようなものを動作させその上で原則1つのアプリケーションを動作させているが、あえて、物理マシン上で1つのアプリケーションしか動作しないOSを作ってみたい。もちろん想定するマシンは普通のPCではなくESP32のような小型・省電力・低性能なハードである。従来の組み込みOSでは各種Linuxディストリのパッケージのようなものは利用することができないが、アプリケーションをパッケージとしてまとめ、それだけを実行させるOSがあればハード依存の面倒な部分を気にすることなく、IoTなどの分野の利用がより便利になると考えたからである。

■共通問題C

ほとんどのプログラマが興味があったり実際に作ったりしているのはユーザが直接使うアプリケーションです。
そんな中、みなさんがOS開発に興味を持ってくれたことは、講師としてとても嬉しいです。
OS開発を通してアプリケーション開発ではできないどのようなことをしたいのかを是非教えてください!

・ライブラリが全くない状態からの開発
普段LinuxでC言語を利用したプログラムを書いているとstdioやstdlibなどの標準ライブラリを必ず利用しているが、その中身がどんなことになっているのかは気にすることがほとんどない。それらのライブラリが全くない状態からの開発は普段体験できることはまず無いはずだし、体験してみたい。

・アセンブラ
C言語やRuby,Pythonなどの高級言語しか使ったことがなく、アセンブラに関しては前述したHello Worldと「セキュリティコンテストのためのCTF問題集」(マイナビ出版)での脆弱性攻撃スクリプトを書いたぐらいである。機械語を1つ1つ書いていくという経験はコンピュータそのものを掌握できているという感覚で普段は感じることのない快感を体験することができた。OSの開発を通じて普段は書く機会のないアセンブラにしっかりと取り組みたいと考えている。

・BIOS,UEFIに関する知識
BIOSやUEFIは起動設定等をするだけで裏ではどのような動作をしているのか気にすることがない。ブートローダーの実装等を通してBIOSがどのような仕組みで動いているのか知りたい。

・ファイルシステム
FATやBTFS,EXT4など多くのファイルシステムが存在するが、それらの違いを意識することは殆ど無い。OS開発においてファイルシステムは重要なものであるため、OS開発を通してそれぞれのファイルシステムがどのような特徴を持ち、利点・欠点が存在するのか、また、どのようにして実装されているのか体験してみたい。

■選択問題S1 テーマ「フルスクラッチOSを書こう!」(内田講師)

現代のパソコンではPCIバス(ソフトウェア互換性のあるPCIeバスも含む)を使ってほとんどの周辺機器が接続されており、PCIバスはとても重要な存在になっています。
PCIバスが制御できるようになると、SATAやNVMeの読み書き、USBの制御などができるようになります。

以下3つについて詳しく答えてください。
1. 今現在、あなたがPCIバスについて知っていること(PCIバスについて何も知らなくても問題ないので、その場合はそう書いてくださいね!)
2. PCIバスについて知識を深めるために調べて分かったこと
3. どうやってその情報を調べたか(○○の記事を検索して見つけた、Linux上で実験コマンドを使った、とか)

調べる取っ掛かりになるキーワードを挙げておきます。いくつかを調べてみると良いと思います。
PCIe、PCIコンフィギュレーション空間、BAR、IRQ、MSI、APIC、SATA、xHCI

1.PCIバスについて現在知っていること

・多種多様な拡張ボードを利用できる
USBやオーディオなど様々な種類の拡張ボードがPCIバス向けに作られていた。グラフィックボードもPCI向けに製造されていることがあったが、通信速度の関係上、グラフィックボード専用のAGPに取って代わられた。

・パラレルであること
PCIは複数線利用して一度に複数ビットのデータを送受信するようになっている。HDD,光学ドライブで利用されていたIDEや、プリンタとの接続もパラレル型であった。

・一般向けにはPCI,サーバー向けにはPCI-Xという規格があること
サーバー向けにはPCI-Xという仕様のPCIバスが搭載されていることがあり、RAIDカードなどで利用されていた。

・PCIeはシリアルであること
PCIはパラレル型であるが、PCIeはシリアル型で、データを1ビットずつ順番に送受信する。また、複数のシリアルを束ねることで高速通信が可能になっている。PCIe x1が基本単位でPCIe x16はそれを16本まとめたものである。SATAやUSBもシリアル型である。

2.PCIバスについて調べてわかったこと

・PCIに接続されたデバイスはプロセッサのアドレス空間が割り当てられる
PCIに接続されたデバイスは、プロセッサのアドレス空間が割り当てられるが、バスマスタによってDMA(Direct Memory Access)が可能になっているものもある。そのため、大量のデータ転送を必要とするSCSIやIDE,SATA,LANなどのインターフェースボードではバスマスタ対応になっているものが多い。

・バスマスタ
バスマスタとはバスマスタ型デバイスのことであり、DMA転送を能動的に起動できるデバイスのことである。汎用的なバスマスタとしてはDMAC(DMAコントローラ)があるが、PCIの規格ではデバイスがDMAマスタになる機能がサポートされており、デバイスに搭載された専用DMACによって能動的にDMA転送が出来る。また、最近のチップセットではUSBやLANのDMAをサポートするためにIntelの場合ではICH(I/O Controller Hub)でDMA転送をサポートしている。PCIでは複数のデバイスがバスマスタとなるため、それらを取りまとめるPCIバスコントローラーがチップセットに内蔵されており、DMA転送を管理している。

・DMA転送
Direct Memory Access(直接メモリアクセス)のこと。CPUを介することなくメモリにアクセスすることでCPUにかかる処理負担を軽減することができ、高速なデータ転送が可能になっている。DMA転送には3つの方式があり、

・サイクルスチール転送モード
DMA転送を1サイクル実行する度にバスの制御権を解放する方式。CPUや複数のデバイスがバスを共有できるが基本的には遅い。仕組みとしては、CPUとはBR(バス・リクエスト)とBG(バス・グラウンド)の2つの信号を利用して制御する。DMAコントローラーはBRを介してバス制御権を獲得後データを転送し、1バイトのデータ転送が終了するとBGを介してCPUにバス制御権を移す。転送すべきデータが残っている場合は、再びバス制御権を獲得し、同様の動作を転送が完了するまで繰り返す。1バイト転送するごとにCPUにバス制御権が戻るためリアルタイム制御には向いているが、CPUが非アクティブにならないため負荷が大きい。

・バースト転送モード
DMA転送を開始後、一定のバイト数を転送するまではバスの制御権を解放しない転送方式。度々バス制御権のやり取りをしないため高速なデータ転送をすることが出来るが、転送が終了するまではCPUや他のDMACがバスを利用できないため待ち時間が発生する。

・デマンド転送モード
DMAスレーブデバイスからのDMA転送要求信号によってDMA転送を開始し、要求信号がアクティブになっている間だけDMA転送を行う方式。スレーブが要求信号を取り下げるとDMACはDMA転送を中断してバスの制御権を解放する。

の以上である。

・PCIにはバス幅に複数種類がある
PCIバスには32bitバスと64bitバスがあった。一般的なPCIバスは32bitでいわゆるPCI-Xが64bitである。32itバスでの転送速度はバスクロック33MHzで133MB/s、66MHzで266MB/sであった。

・PCIバストランザクション
PCIバスを介したデータ転送は一連のバストランザクションで構成されている。

・PCIアドレス空間
PCIにはメモリ空間、I/O空間、コンフィグレーション空間の3つのアドレス空間が存在する。メモリアドレス空間は32bitでキャッシングをサポートしている。これら3つのアドレス空間はCPUから全てアクセスすることができ、PCI I/O空間とPCIメモリ空間へのアクセスはデバイスドライバを利用し、PCIコンフィグレーション空間はLinuxの場合、カーネル内のPCI初期化コードを使ってアクセスする。

・PCIコンフィグレーション空間
PCIコンフィグレーション・レジスタにアクセスする場合はコンフィグレーション・アドレス・レジスタを利用する

コンフィグレーション・アドレス・レジスタ(CONFIG_ADDRESS)の中身
(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)

バス番号は0〜255で、最大255本のPCIバスを持つことが出来る
デバイス番号は0〜31で1つのPCIバスに最大で31個のデバイスをつけられる
機能番号は0〜7で1つのデバイスに複数の機能が搭載されている場合、それらを区別して扱うための番号
レジスタアドレスは下のコンフィグレーション・レジスタにアクセスする番地を指定する

コンフィグレーション・データ・レジスタ(CONFIG_DATA)
コンフィグレーション・アドレス・レジスタの31つまりENが1のとき、指定されたPCIコンフィグレーション・レジスタに
コンフィグレーション・データ・レジスタを介してアクセスすることが出来る。

PCIコンフィグレーション・レジスタの中身
(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)


ベース・アドレス・レジスタ(BAR)
PCIデバイスではI/O空間およびメモリ空間にPCIデバイスのレジスタを割り当ててアクセスする。そのとき空間にマップするアドレスがBARであり、BARはPCIコンフィグレーション・レジスタの一部である。また、BARは必要な空間の領域を取得することにも利用することができる。BARには領域の大きさと同じ大きさにあラインされたアドレスしか設定することができない。BARは通常、BIOSやUEFIがPCIデバイスを初期化するときに自動で設定されるが、設定後であってもOS側から自由に書き換えることが出来る。

・割込み処理
一般的なCPUでの割込みは「ハードウェア割込み」と「ソフトウェア割込み」に二分される。ハードウェア割込みではIRQ(Interrupt ReQuest)端子の状態を変化させることで割込みを発生させる。PCIの割込み処理ではIRQを利用した古典的な手法やPCI(Advanced Progmmable Interrupt Controller)やMSI(Message Signaled Interrupt)を利用した割込みが利用されている。ソフトウェア割込みでは自身が実行した命令や、キャッシュ、例外によって発生させることが出来る。

・APIC
APICとはAdvanced Programamable Interrupt Controllerの略で、インテルによって開発されたx86における割り込みコントローラである。APICにはCPUに内蔵されるLocal APICとI/Oからの割込みを管理するIOAPICの2種類が存在する。
・Local APIC
CPU内部に実装され、外部からの割込みの全てを管理している。I/Oの割込み以外にもIPI(Inter-Processor Interrupt)と呼ばれる、マルチプロセッサによる割込みを使用したCPU間通信にも利用されている。IOAPICから割込み通知を受け取った場合など、割込み処理が発生すると、優先度などをチェックして割込みハンドラを呼び出す。割込み処理終了後はIOAPICに処理が終了したことを通知し、割込み処理前の処理に戻る。この際に発行される通知はEOI(End Of Interrupt)というもので、対応した割込みベクタの情報を持ち、該当する割込みベクタの処理が終了したことを通知している。
・IOAPIC
I/Oデバイスから受け取った割込みを、OSやBIOSによって設定されたリダイレクション・テーブルを参照し、それに従ってCPUに対して割込みの通知を行う。PCIバスにおいては、1本のバスにはINT_A,B,C,Dの最大4本のI/O割込み線が存在し、IOAPICに接続されている。IOAPICではそれぞれの割込み線に対するリダイレクションテーブルが割り当てられており、割込み種別、割込みベクタなどLocal APICと通信するための設定がなされている。デバイスの数が多い場合は1本の割込み線を複数のデバイスで共有する場合があるが、このような場合の管理もIOAPICが担当している。さらには、MSIをサポートするIOAPICでは割込み線を使用することなくIOAPICを介してCPUに対して割込み通知を行うことが出来る。

・リダイレクション・テーブル
リダイレクション・テーブル・レジスタは64bitのレジスタであり、24個のリダイレクション・テーブル・レジスタがリダイレクション・テーブルに存在する。
リダイレクション・テーブル・レジスタの構造は次のとおりである。

(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)

Destination:APICのIDを指定
Extended Destination ID:プロセッサーシステム明日モードにおいてのみlocal APICに送信される
MS(Mask):割込みマスク
TM(Trigger Mode):0->Edge Triggered 割込み信号の状態が変化したとき(H->L,L->H)のときに割込み処理をする
1->Level Triggered 割込み信号が指定した状態であるとき割込み処理を実行し続ける
RI(Remote IRR):Level Triggeredなときに利用される
0->local APICからEOIを受け取ったときにリセットする
1->IOAPICから発行した割込み処理がLocal APICに受け取られたときにセットする。
IP(Interrupt Input Pin Polaroty):割込みを実行するときの割込み線の状態
0-> 信号線がHighのとき割込みを実行
1-> 信号線がLowのとき割込みを実行
DS(Delivery Status):割込み通知の配送状況を示す。このビットに対する書き込みに意味はない
0->この割込みに関する処理は実行されていない
1->この割込みに関する処理は保留状態になっている

DM(Destination Mode):0->物理アドレス。APIC IDは59:56のビットから判断される
1->論理アドレス。63:56ビットとLocal APIC内のDestination Format RegisterとLogical Destination Registerを照らし合わせることで判断する

Deliver Mode 000->Fixed 指定されたプロセッサに対して割込み通知を行う
001->Lowest Priority 最も優先度が低いプロセッサに対して割込み通知を行う
010->SMI システムマネジメント割込み 最高の優先度を持つ
100->NMI CPUが割込み禁止状態でも強制的に割込みを実行することが出来る。デバッグ等に利用する
101->INIT
111->ExtInt 指定された全プロセッサに対して割込み通知を行う

Vector:割込みベクターのアドレス

・MSI,MSI-X
MSIとはMessage Signaled Interruptの略であり、システムバスに対して、メモリに対する書き込み処理を発行することで割込みを発生させる機能である。MSI-XはMSIの拡張規格である。MSIでは32までの割込み、MSI-Xでは2048までの割込みをサポートしている。専用の割込み線を使用しないため、限られた割込み線を共有するという事態を避けることが出来る。MSIをサポートするPCIデバイスには、メモリ書き込みのとき、アドレスを指定するMessage Addressレジスタ、データを指定するMessage Dataレジスタの2種類のレジスタが存在する。
・Message Addressレジスタ

(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)

RH(Redirection Hint) 0->DMは無視され、指定したLocal APIC IDへ割込み通知が送られる
DM(Desitination Mode) RH=1 -> DM=0 -> 指定したLocal APIC IDへ割込み通知が送られる
DM=1 -> 指定したLogical APIC IDへ割込み通知が送られる
・Message Dataレジスタ
(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)


TM(Trigger Mode) 0->Edge
1->Level
LV(Level for Trigger Mode) TM=0 -> don’t care
TM=1 -> 0 -> Deassert
1 -> Assert
Delivery Mode:上記のリダイレクション・テーブル・レジスタのものと同一

・APICがどのようになっているのか見てみた
“cat /proc/interrupts”でAPICのIRQの状態を見てみた。
なお、文字数制限のため一部削除している

(後述:応募用紙では文字で書きましたが、レイアウトが崩れる可能性があるので画像を添付します。)

IR-IO-APICはIOAPICへとつながるIRQで、DMAR-MSIはDMAR(DMA Remapping Table)つまりDMA転送用のMSI、IR-PCI-MSIはPCIバス用のMSIであると考えられる。NMI等の英字3文字のものは仮想的なIRQであり内部割込みやOSが発行する割込み用のものであると考えられる。

・今PCのPCIバスに接続されているデバイスを見てみた
“lspci -vv”コマンドを使って接続されているPCIデバイスの詳細を見てみた。
なお、文字数制限の都合上大部分を削除している

lspci -vv

00:02.0 VGA compatible controller: Intel Corporation HD Graphics 520 (rev 07) (prog-if 00 [VGA controller])
	Interrupt: pin A routed to IRQ 128
	Region 0: Memory at f0000000 (64-bit, non-prefetchable) [size=16M]
	Region 2: Memory at e0000000 (64-bit, prefetchable) [size=256M]
	Region 4: I/O ports at e000 [size=64]
	Kernel driver in use: i915
	Kernel modules: i915

00:14.0 USB controller: Intel Corporation Sunrise Point-LP USB 3.0 xHCI Controller (rev 21) (prog-if 30 [XHCI])
	Subsystem: Lenovo Sunrise Point-LP USB 3.0 xHCI Controller
	Interrupt: pin A routed to IRQ 123
	Region 0: Memory at f1220000 (64-bit, non-prefetchable) [size=64K]
	Kernel driver in use: xhci_hcd
	Kernel modules: xhci_pci

00:14.2 Signal processing controller: Intel Corporation Sunrise Point-LP Thermal subsystem (rev 21)
	Subsystem: Lenovo Sunrise Point-LP Thermal subsystem
	Interrupt: pin C routed to IRQ 18
	Region 0: Memory at f124a000 (64-bit, non-prefetchable) [size=4K]
	Capabilities: 
	Kernel driver in use: intel_pch_thermal
	Kernel modules: intel_pch_thermal

00:16.0 Communication controller: Intel Corporation Sunrise Point-LP CSME HECI #1 (rev 21)
	Subsystem: Lenovo Sunrise Point-LP CSME HECI
	Interrupt: pin A routed to IRQ 125
	Region 0: Memory at f124b000 (64-bit, non-prefetchable) [size=4K]
	Capabilities: 
	Kernel driver in use: mei_me
	Kernel modules: mei_me

00:17.0 SATA controller: Intel Corporation Sunrise Point-LP SATA Controller [AHCI mode] (rev 21) (prog-if 01 [AHCI 1.0])
	Subsystem: Lenovo Sunrise Point-LP SATA Controller [AHCI mode]
	Interrupt: pin A routed to IRQ 124
	Region 0: Memory at f1248000 (32-bit, non-prefetchable) [size=8K]
	Region 1: Memory at f124e000 (32-bit, non-prefetchable) [size=256]
	Region 2: I/O ports at e080 [size=8]
	Region 3: I/O ports at e088 [size=4]
	Region 4: I/O ports at e060 [size=32]
	Region 5: Memory at f124c000 (32-bit, non-prefetchable) [size=2K]
	Capabilities: 
	Kernel driver in use: ahci
	Kernel modules: ahci

00:1c.0 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #1 (rev f1) (prog-if 00 [Normal decode])
	Interrupt: pin A routed to IRQ 16
	I/O behind bridge: None
	Memory behind bridge: f1100000-f11fffff [size=1M]
	Prefetchable memory behind bridge: None
	Kernel driver in use: pcieport
	Kernel modules: shpchp

00:1c.2 PCI bridge: Intel Corporation Sunrise Point-LP PCI Express Root Port #3 (rev f1) (prog-if 00 [Normal decode])
	Interrupt: pin C routed to IRQ 18
	Memory behind bridge: f1000000-f10fffff [size=1M]
	Kernel driver in use: pcieport
	Kernel modules: shpchp

00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio (rev 21)
	Subsystem: Lenovo Sunrise Point-LP HD Audio
	Interrupt: pin A routed to IRQ 126
	Region 0: Memory at f1240000 (64-bit, non-prefetchable) [size=16K]
	Region 4: Memory at f1230000 (64-bit, non-prefetchable) [size=64K]
	Capabilities: 
	Kernel driver in use: snd_hda_intel
	Kernel modules: snd_hda_intel, snd_soc_skl

00:1f.4 SMBus: Intel Corporation Sunrise Point-LP SMBus (rev 21)
	Subsystem: Lenovo Sunrise Point-LP SMBus
	Interrupt: pin A routed to IRQ 16
	Region 0: Memory at f124d000 (64-bit, non-prefetchable) [size=256]
	Region 4: I/O ports at efa0 [size=32]
	Kernel driver in use: i801_smbus
	Kernel modules: i2c_i801

00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection I219-V (rev 21)
	Subsystem: Lenovo Ethernet Connection I219-V
	Interrupt: pin A routed to IRQ 129
	Region 0: Memory at f1200000 (32-bit, non-prefetchable) [size=128K]
	Kernel driver in use: e1000e
	Kernel modules: e1000e

02:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS522A PCI Express Card Reader (rev 01)
	Subsystem: Lenovo RTS522A PCI Express Card Reader
	Interrupt: pin A routed to IRQ 122
	Region 0: Memory at f1100000 (32-bit, non-prefetchable) [size=4K]
	Kernel driver in use: rtsx_pci
	Kernel modules: rtsx_pci

04:00.0 Network controller: Intel Corporation Wireless 8260 (rev 3a)
	Subsystem: Intel Corporation Wireless 8260
	Interrupt: pin A routed to IRQ 127
	Region 0: Memory at f1000000 (64-bit, non-prefetchable) [size=8K]
	Kernel driver in use: iwlwifi
	Kernel modules: iwlwifi

CPUのチップセットや、グラフィック、PCIブリッジ、USBコントローラー、SATAコントローラーなどあらゆるデバイスがPCIバスに接続されており、Pin AやPin CつまりINTAやINTCに対するIRQも割り振られている。デバイスによってはIO空間にマップしていたり、メモリ空間に複数のアドレスをマップしていたりしてデバイスごとに様子が異なる。また、それぞれのデバイスに対応するKernel Driverが割り振られている。前述のAPICのIRQ割当状況と照らし合わせるとPCIやPCI-Expressのホストコントローラー、CPUのチップセットなどシステムの中核をなすデバイス以外はIRQ122からIRQ129つまり、IR-PCI-MSIとして接続されており、PCI-Expressによる接続と考えられる。

・APICのメモリーマッピングを調べてみた
“sudo cp /sys/firmware/acpi/tables/APIC . && sudo iasl -d APIC && less APIC.dsl”でAPICのメモリーマッピングを確認してみた。文字数の都合上一部削除している。

[024h 0036   4]           Local Apic Address : FEE00000
[028h 0040   4]        Flags (decoded below) : 00000001
                         PC-AT Compatibility : 1

[02Ch 0044   1]                Subtable Type : 00 [Processor Local APIC]
[02Dh 0045   1]                       Length : 08
[02Eh 0046   1]                 Processor ID : 01
[02Fh 0047   1]                Local Apic ID : 00
[030h 0048   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1

[034h 0052   1]                Subtable Type : 00 [Processor Local APIC]
[035h 0053   1]                       Length : 08
[036h 0054   1]                 Processor ID : 02
[037h 0055   1]                Local Apic ID : 02
[038h 0056   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1

[03Ch 0060   1]                Subtable Type : 00 [Processor Local APIC]
[03Dh 0061   1]                       Length : 08
[03Eh 0062   1]                 Processor ID : 03
[03Fh 0063   1]                Local Apic ID : 01
[040h 0064   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1

[044h 0068   1]                Subtable Type : 00 [Processor Local APIC]
[045h 0069   1]                       Length : 08
[046h 0070   1]                 Processor ID : 04
[047h 0071   1]                Local Apic ID : 03
[048h 0072   4]        Flags (decoded below) : 00000001
                           Processor Enabled : 1

[04Ch 0076   1]                Subtable Type : 00 [Processor Local APIC]
[04Dh 0077   1]                       Length : 08
[04Eh 0078   1]                 Processor ID : 05
[04Fh 0079   1]                Local Apic ID : FF
[050h 0080   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0

[054h 0084   1]                Subtable Type : 00 [Processor Local APIC]
[055h 0085   1]                       Length : 08
[056h 0086   1]                 Processor ID : 06
[057h 0087   1]                Local Apic ID : FF
[058h 0088   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0

[05Ch 0092   1]                Subtable Type : 00 [Processor Local APIC]
[05Dh 0093   1]                       Length : 08
[05Eh 0094   1]                 Processor ID : 07
[05Fh 0095   1]                Local Apic ID : FF
[060h 0096   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0

[064h 0100   1]                Subtable Type : 00 [Processor Local APIC]
[065h 0101   1]                       Length : 08
[066h 0102   1]                 Processor ID : 08
[067h 0103   1]                Local Apic ID : FF
[068h 0104   4]        Flags (decoded below) : 00000000
                           Processor Enabled : 0

[06Ch 0108   1]                Subtable Type : 01 [I/O APIC]
[06Dh 0109   1]                       Length : 0C
[06Eh 0110   1]                  I/O Apic ID : 02
[06Fh 0111   1]                     Reserved : 00
[070h 0112   4]                      Address : FEC00000
[074h 0116   4]                    Interrupt : 00000000

[08Ch 0140   1]                Subtable Type : 04 [Local APIC NMI]
[08Dh 0141   1]                       Length : 06
[08Eh 0142   1]                 Processor ID : 01
[08Fh 0143   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[091h 0145   1]         Interrupt Input LINT : 01

[092h 0146   1]                Subtable Type : 04 [Local APIC NMI]
[093h 0147   1]                       Length : 06
[094h 0148   1]                 Processor ID : 02
[095h 0149   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[097h 0151   1]         Interrupt Input LINT : 01

[098h 0152   1]                Subtable Type : 04 [Local APIC NMI]
[099h 0153   1]                       Length : 06
[09Ah 0154   1]                 Processor ID : 03
[09Bh 0155   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[09Dh 0157   1]         Interrupt Input LINT : 01

[09Eh 0158   1]                Subtable Type : 04 [Local APIC NMI]
[09Fh 0159   1]                       Length : 06
[0A0h 0160   1]                 Processor ID : 04
[0A1h 0161   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[0A3h 0163   1]         Interrupt Input LINT : 01

[0A4h 0164   1]                Subtable Type : 04 [Local APIC NMI]
[0A5h 0165   1]                       Length : 06
[0A6h 0166   1]                 Processor ID : 05
[0A7h 0167   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[0A9h 0169   1]         Interrupt Input LINT : 01

[0AAh 0170   1]                Subtable Type : 04 [Local APIC NMI]
[0ABh 0171   1]                       Length : 06
[0ACh 0172   1]                 Processor ID : 06
[0ADh 0173   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[0AFh 0175   1]         Interrupt Input LINT : 01

[0B0h 0176   1]                Subtable Type : 04 [Local APIC NMI]
[0B1h 0177   1]                       Length : 06
[0B2h 0178   1]                 Processor ID : 07
[0B3h 0179   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1
[0B5h 0181   1]         Interrupt Input LINT : 01

[0B6h 0182   1]                Subtable Type : 04 [Local APIC NMI]
[0B7h 0183   1]                       Length : 06
[0B8h 0184   1]                 Processor ID : 08
[0B9h 0185   2]        Flags (decoded below) : 0005
                                    Polarity : 1
                                Trigger Mode : 1

このPCのCPUは2core4Threadであるため、1つの物理CPUコアにつき4つのLocal APICとLocal APIC MNIが割り当てられていると考えられる。また、IOAPICはFEC00000のアドレスに割り当てられていることが分かる。

3.情報の調査方法
・Peripheral Component InterConnect – Wikipedia (https://en.wikipedia.org/wiki/Conventional_PCI)
・DMA対応と言われたら(1) – uQuest (https://www.uquest.co.jp/embedded/learning/lecture15-1.html)
・Direct Memory Access – Wikipedia (https://en.wikipedia.org/wiki/Direct_memory_access)
・7.PCI(http://archive.linux.or.jp/JF/JFdocs/The-Linux-Kernel-7.html)
・Device/PCI – OS Project Wiki(http://www.wiki.os-project.jp/?Device%2FPCI)
・PCI Memo – OS Dev JP(https://github.com/osdev-jp/osdev-jp.github.io/wiki/PCI-Memo)
・PCI MSI – OS Dev JP(https://github.com/osdev-jp/osdev-jp.github.io/wiki/PCI-MSI)
・PCI – Osask OSwiki(http://oswiki.osask.jp/?PCI)
・APIC – Wikipedia(https://ja.wikipedia.org/wiki/APIC)
・I/O APICについて - 睡分不足(http://mmi.hatenablog.com/entry/2017/04/09/132708)
・MSI/MSI-Xとx2APIC – 睡分不足(http://mmi.hatenablog.com/entry/2017/03/28/032646)
・ハイパーバイザの作り方~ちゃんと理解する仮想化技術~ 第4回 I/O 仮想化「割り込み編・その1」(https://syuu1228.github.io/howto_implement_hypervisor/part4.pdf)

・”cat /proc/interrupts”でAPICのIRQの状態を確認
・”sudo cp /sys/firmware/acpi/tables/APIC . && sudo iasl -d APIC && less APIC.dsl”でAPICのメモリーマッピングを確認
・”lspci -vv”で接続されているPCIデバイスの詳細を確認

■共通問題D

その他、書ききれなかったことを好きなだけ書いてください。

私がOSに惹きつけられた理由の1つとして、誰もが普通に使っているものを自分の手で作ることが出来るからである。
OSと言われるとなんだか難しそうで、一部の天才たちが作っているように考えてしまっていたことが私にもあったが、色々と調べるうちに簡単なOSならば作れることも分かった。セキュリティキャンプ全国大会には以前から応募したいと考えていたが、今年は、OS開発ゼミがあることを知り、応募することを即決した。

課題を見ていると実際のOS開発がどのようなものであるか知りたい、とりあえずどんなものでもいいから作ってみようということで今年のゴールデンウィークに坂井 弘亮さんの「12ステップで作る組込みOS自作入門 」を実際にやってみた。その時の記録は「GW中に「12ステップで作る組込みOS自作入門」をした話」(https://anqou.net/poc/2018/05/07/post-1562/)にまとめている。実際に作ってみたと言うより写経しながらOS開発を体験してみた感想としては、とにかく「おもしろい」ことであった。
記事中にほぼ徹夜になりながらやっていたとあるが、1ステップごとにシステムコールや新たな処理を実装すると出来ることが増え、どんどんOSをOSらしくしたいという思いにかられて実装していた。シリアル通信のデバイスドライバの自作なんて絶対難しいに違いないと最初は思っていたが、対象ボードが小型のマイコンボードであることから、レジスタの設定をするだけで簡単に実装できてしまうことには衝撃を受けた。「これなら自分でもOSを作れる」という確信を抱き、GWの体験をきっかけに最近は川合 秀実さんの「30日でできる! OS自作入門」やMITの「Operating System Engineering」(https://pdos.csail.mit.edu/6.828/2017/index.html)の講義資料を少しずつ読み進めている。

あと、2018年私の中で最大級のプロジェクトとして「3.14を計算するリレー式計算機」の製作を進めている。このことについては私のブログ「外部記憶装置」(http://pibvt.hateblo.jp/)に記事を投稿している。記事は命令セットの選定前で止まっているが、現在は、命令セットを決めてエミュレーターをつくり、試作の計算プログラムを走らせ、改良する。という段階にあり今はようやく命令セットが決定し、本番のエミュレーターを作っている途中である。
なぜ今更リレーで作るのかというと、単純に大量のリレーがカシャカシャ音を立てて計算する姿を見てみたいと思ったからである。

ハードウェアやOS、デバイスドライバなどの低レイヤは普通は気にしない、かつ、一筋縄ではいかない分ワクワクする分野であり、もっと知識を身に付けて弄り回すことができるようになりたい。セキュリティキャンプ全国大会のOS開発ゼミに参加することができれば、貴重な経験と友人を得ることができ、私の人生の大きな転換点となることは間違いないと考えている。

以上よろしくお願いします。

感想&目標

長い。とにかく長い。応募したときはWindowsの悪g..改善点を書いたり、PCIバスについて調べたりするのが楽しく、どうせなら全部書いたろ!みたいな感じで書いていたのですが、かなり冗長ですね….審査された方もうんざりしていたかも知れません(笑)。この回答自体も締切の4時間前ぐらいにGoogleフォームで提出しようとしたのですが、文字数が多すぎて提出できないというトラブルがあり、急遽、後半のPCIバスについての回答をPDFファイルにして自分のGoogle Driveへのリンクを付けて提出しました。
個人的には英語に臆することなくIntelの仕様書とかも募集開始時くらいから読んでおけばよかったのですが、のほほーんとしすぎて、気がつけば締切1週間前だったので全く読めなかったです…日本語で分かりやすい解説を書いてくださった上記リンクの方たちには感謝ばかりです。ありがとうございます。
全体的に経験が薄く知識ベースの内容なので、他の方の応募回答を見てると、私の回答は頭でっかちで恥知らずな文章な気がします。いや、そうに違いない。うん。しかし、逆に言えば、経験がなくとも頑張って調べたり、とにかくやってみたりするという熱意があれば何とかなるということなのでしょう。
あと、Windowsの改善点に悪意というか嫌悪感が滲んでいるのは、決してWindowsが不便なOSであるというわけでなく、私をワクワクさせてくれるOSがArch LinuxなどのLinux系のOSであり、Windowsはそうではなかったということです。Windowsは私のコンピュータとの出会いのきっかけとなり、優しい環境でコンピュータ・OSの素晴らしさを教えてくれた親のようなものであり、Linuxはいつも共にある親友といった感じですかね。そんな感じです。
大会当日に向けては、とりあえず今ちまちま読んでいる30日自作OS入門をやり遂げることが目標です。試験等もあるけれど、そこはまぁ何とかなるはずです。それに並行してMITの講義資料等も読み進めるなど、応募回答内で書いたことをやり遂げたいと思っています。出来るかできないかは私の熱意次第であり、出来なければその程度の人である。ということになってしまうのでなんとかしてやり遂げたいところです。まぁ、楽しいので試験勉強をほったらかしてやってそうな気がしますけど(笑)

最後に

書いた感想としては一言で言うと、「世界の見方が変わった」です。OSを実際に書いてみたりPCIバスのことを調べたりするうちに、ぱっと見では複雑な動作をしているものでも裏は簡単な仕組みの積み重ねであり、それを追いかけていけば何が起きているのか把握できる。難しそうだから…という考えはもったいないものであり、少しでいいから中身を覗き込む。そうすれば楽しいワクワクする世界が広がっている。そんなことを感じることができました。