PiBVT | カオスの坩堝 https://anqou.net/poc Chaos is not kaos. Sun, 23 Dec 2018 11:16:46 +0000 ja hourly 1 https://wordpress.org/?v=6.1.1 https://anqou.net/poc/wp-content/uploads/2018/02/9dc10fe231765649c0d3216056190a75-100x100.png PiBVT | カオスの坩堝 https://anqou.net/poc 32 32 僕とコンピュータ https://anqou.net/poc/2018/12/23/post-2477/ https://anqou.net/poc/2018/12/23/post-2477/#comments Sun, 23 Dec 2018 11:16:46 +0000 https://anqou.net/poc/?p=2477 この投稿は「カオスの坩堝 Advent Calendar 2018」 の23日目の記事です.

こんにちは、PiBVTです。今回は僕とコンピュータのこれまでの付き合いについて語りたいと思います。

 

幼少期(幼稚園まで)

そもそも、僕自身は計算機・コンピュータよりも工作用紙や木材であれやこれやと作る、工作の方が好きでした。

コンピュータも僕の好奇心の対象にはなりましたが、操作をすると画面が変化することを楽しむだけで、それ自体の魅力を感じ取ったわけではありませんでした。

 

小中学校時代

コンピュータをまともに操作するようになったのは小学生低学年のころだったように思います。誰にもコンピュータ関連のことを相談できなかったので近所の図書館のPC関連書籍棚にある本を片っ端から読んで勉強していました。が、当時僕の家庭ではゲーム・PCは休日の昼間のみという制限があり、コンピュータを使ってプログラミングをしたりするのではなく、本にある内容を試してみる程度のことしかしていませんでした。

 

一方、工作系は何ら制限が無かったので紙・木細工から電子回路へと分野を切り替え、壊れた電化製品を分解して部品を集めて簡単な回路を作ったり、ラジオのキットを買って組み立てたり、改造して受信感度を良くしたりアンプを付けてスピーカーを鳴らしたりしてました。

ちなみに、僕は四国の田舎に住んでいたためまともな部品屋さんもなくお小遣い自体もなかったので、100均ショップの電気小物をベースにして改造することが多かったです。汎用部品で出来ている製品が多かったので、むしろありがたかったです。

 

高校時代

高校生になると状況は一変します。まず、お小遣い制度が導入されある程度の金額までならば自由に買い物が出来るようになりました。さらに、通学用の自転車を買ってもらえたので行動範囲が一気に拡大しました。

 

まずコンピュータ関連のことからですが、高校生になる直前にそれまで貯めていたお年玉で自分専用のノートPC(中古)を購入しました。が、もちろん前述の家庭ルールは適用されているので時間的には自由に使うことは出来ませんでしたが、自分専用のPCなだけあって自由にアプリケーションを入れたりOSを入れ替えたり出来るようになったことはとても嬉しかったです。

さらに、お小遣いのおかげで自由に使えるお金がある程度あったことと、行動範囲を広げれる自転車の登場で、PCパーツ目当てに週2,3のペースで部活終わりに高校近くのHARDOFFに通うようになります。(ちなみに、部活は中高共に柔道をしていました) 良さげなジャンクのパーツやら機器があれば自転車の荷台に積み、家までの12,3kmの道を帰るような日々を過ごしていました。

そんなことをしていると、高校2年生にもなるとジャンクの寄せ集めなPCが2台ほど確保できたので、これらのPCをベースにLinuxを入れてWebサーバーにしたり、KVMを利用して仮想化サーバーを立てるようになります。これといって立てたから何か運用するわけでもなく、ひたすら立てては壊し、また別の何かを立てることを繰り返していました。

 

一方工作系の分野に関しては、PICやAVRのマイコンを触るようにはなったものの、部活が忙しく休日すらまともにまとまった工作の時間を確保することが出来ず、下火になります。高校3年生になるまではPC中心で色々やっていたのですが、高校3年生の4月に本屋で運命的な本と出会いました。渡波 郁さん著の「CPUの創りかた」です。CPUをDIPのロジックICだけで作る内容はまさしく衝撃的でした。この本をきっかけに僕のコンピュータ系の流れと工作系の流れが合流することとなります。

さらに追い打ちをかけるように、ぬるぽへさんの「CPU実験で自作CPUにUNIXライクOS (xv6) を移植した話」の記事を見つけ、自作CPUの上で自作OSが走るのか!と感動し、自分でもやってみたいという思いを持つようになります。

 

大学生になってから

受験を終えて無事大学生となりましたが、想像以上に忙しい毎日でひらすらレポートやら勉強やらで1回生の間は趣味的な何かをすることはほとんどありませんでした。ちなみに、講義の1つでRaspberry Piを使って何か作るというゼミがあり、ここで初めてプログラミングをし始めます。言語はCでした。しかし2回生になる前の春休みに、前述の「CPUの創りかた」や「CPU実験で自作CPUにUNIXライクOS (xv6) を移植した話」を再び読み返し、やっぱりCPUとOS作りたい!という思いから春休みはひたすらnand2tetrisで有名な「コンピュータシステムの理論と実装」を読んで実装をしていました。さらに、この時期にセキュリティキャンプなるイベントがあることを知ります。

2回生になってから、「CPU,OS作りたい」という思いは高まる一方でした。4月の中頃にクラスメートの艮鮟鱇さんから「セキュリティキャンプなるイベントでCコンパイラやらOSが作れるらしい」という話を聞きます。僕は迷うことなくその話に飛びつき、GW中に組み込みOSを書いたりミニキャンプ兵庫に参加したりしてました。倍率は5倍以上という話を聞き、「ダメ元でもいいから出しとくか」と、調べた内容全てを応募用紙に書き送りました。その結果、見事選考を通過し8月14日〜8月18日にセキュリティキャンプ全国大会に参加しました。参戦記はココにあります。キャンプをきっかけにOS自作界隈の方々をTwitter上で知ることが出来、僕の世界がそれまでと大きく異なるものになりました。

これから

これから先の目標としては、まず自作CPU上で自作OSを動かすという計画があります。高校生からずっと夢に見てきた計画なので必ず実現します。他には、0から独自設計された自作OSやCコンパイラも作りたいなぁと考えています。また、外向きな目標としてはセキュキャンや自作OS等のコミュニティについても積極的に参加し、繋がりを広げていきたいと思っています。

大学生という身分を最大限活用して、自分がやりたいと思うことをとことん突き詰めて悔いのないようにしたい。この一言に尽きます。

]]>
https://anqou.net/poc/2018/12/23/post-2477/feed/ 1
セキュリティキャンプでxv6を64bitUEFIから起動した話 https://anqou.net/poc/2018/08/22/post-1860/ https://anqou.net/poc/2018/08/22/post-1860/#respond Wed, 22 Aug 2018 01:56:13 +0000 https://anqou.net/poc/?p=1860 どうもみなさん。お久しぶりです。PiBVTです。

今回、セキュリティキャンプに参加し、xv6_uefiを開発したことについて書いていきたいと思います。

キャンプ全体のことや、今回の技術的な話はまた後日僕のブログで記事にします。

セキュリティキャンプとは?

セキュリティ・キャンプとは

セキュリティ・キャンプとは、日本における将来の高度IT人材となり得る優れた人材の発掘と育成を目的とした独立行政法人情報処理推進機構(IPA)の事業の一つです。

現代においては、情報セキュリティの脅威は高まる一方です。
本事業では、セキュリティ分野に興味を持ち、将来同分野で活躍したいという意志をもった若者に対して、高度な情報セキュリティ技術の習得機会を提供しています。また、モラルや法律遵守の意識、セキュリティ意識、職業意識、自立的な学習意識についても向上のための機会を提供しています。

本事業は、2004年度のスタート以来、2017年度のセキュリティ・キャンプまでで計663名の将来が有望なIT人材を輩出しています。セキュリティ業界はもとより各方面から、高度なIT人材育成に有益なイベントとして高く評価されています。

https://www.ipa.go.jp/jinzai/camp/2018/zenkoku2018_about.htmlより

と、こんな感じです。今年は8月14日から8月18日までの5日間開催されました。要するに、優秀なIT人材の卵を育てようというものです。

システムプログラミングトラック OS開発ゼミ

以前の記事で応募用紙は晒したのですが、僕は応募した結果、システムプログラミングトラック OS開発ゼミ フルスクラッチOSの講座に参加することとなりました。

応募用紙の記事を見てもらえば分かるとおり、とにかく情報を集めまとめただけだったので、実際の実装経験や方法すら知らない状態で参加してしまいました。

しかも、ぼくの本格的なプログラミング歴は大学生になってからなので、およそ1年と半年程度といったところでしょうか。つまり、ガチのプログラミング初心者だったのです。

開発の道のり

グダグダ書いてもアレなので、時系列順に僕がやっていたことを追いかけていきます。

参加決定後〜6月下旬

参加が決定し、講師の@uchan_nos先生と一緒に具体的に作るOSの方針を決めました。当時の僕はxv6を改造したいと考えていたので、

  • x86-64,UEFI対応化
  • NICデバドラ開発
  • TCP/IPプロトコルスタック開発

の3つを目標と掲げていました。当時は何を考えていたのか分かりませんが、とにかくやりたいことを目標にした感じです。

目標は具体的に決定したので、まずはxv6の構造を知ることから始めました。

6月下旬〜7月上旬

このころは、通学中の電車内でxv6 bookをひたすら読み、暇があるときはUEFIアプリケーションの開発SDKであるEDK2を使ってHello UEFIをしたりしていました。

xv6 book自体は英語で書かれていて、読めなくは無いのですが中々頭に入ってこなくて大変でした。UEFIアプリの開発の方は、他の方が作られたソースコードを参考にしたりして割と順調に進んでいたように思います。まだこのころは幸せでした….

7月中旬〜7月下旬

試験期間に突入し、進捗がほとんど生まれなくなります。また、実験的に32bitバイナリのxv6を32bitUEFIから起動しようとしたものの、ELFファイルの読み込みをする段階でQEMUがフリーズしてしまうという謎現象に悩まされ、何もできなくなってしましました。

そこで、xv6をx86-64に移植するのではなく、64bit UEFIで起動して、CPUのモードを32bit protected modeに移行してからxv6を実行するという方法で作業量を圧倒的に減らす方法を講じることにしました。我ながら変態なことを考えたものだと思います。uchan先生もおもしろい方法だと褒めてくださり、Intel SDMでmode switchingの章を教えてくださりました。

その後はxv6のELF形式のバイナリをメモリー上に展開するためのUEFIプログラムを書き、IntelSDMの手順に従ってアセンブリを書いたりしていました。

が、中々うまく行きませんでした。

8月上旬

試験が大体終わり、ある程度の進捗が生まれ始めます。

今となっては何言ってるの?って感じですが、当時はそれなりに嬉しかったんですよ。

この時点で割と真理に気がついていた。

32bitバイナリを実行できる状態にはなりましたが、ページングが有効化できない症状にこれから10日間近く悩まされることになります。

切実。

完成したと思っていたUEFIローダーで.dataと.bss領域が読み込めてないバグが発覚。かなり落ち込んでました。

キャンプ直前

もはやxv6を起動すらできてない状態でキャンプに突入しそうになり、半ばヤケになってます。

LinuxのRaw Socketでパケットを読み込んだり、パケットを作って送信したりして何とか精神状態を保とうとしています。

ほぼ諦めてます。

キャンプ当日

キャンプのことはまた別記事で詳しく書きたいと思います。ここではxv6のことについてのみ触れます。

キャンプ DAY2

午前中にページングが有効化出来ない問題が解決します。原因はPAEが有効になっていたこと。たったレジスタの1bitに2週間近く溶かされたことが判明した瞬間でした。

正直、もっとしっかりSDMを確認していれば回避できていた問題なので出来れば気が付きたかった。

午後にはxv6のmain関数が走り始め、本格的に起動の兆しが見えてきます。と思ったのもつかの間、mp_init()という関数がBIOS依存のため、UEFIでは起動できないことが判明。「あんれまぁ」という感じで、uchan先生も「いばらの道」とおっしゃっていました。

さらに、GDBがCPUのmodeを正しく認識できてないことが判明し、逆にクラッシュする原因となっていました。そのため、GDBは使えず、hltやmov hoge,%eaxのインラインアセンブリで怪しい部分にhltを入れては変数の値をmov hoge,%eaxで読むという変態じみた手法でデバッグしていました。

結局この日はメモリーダンプをとってBIOSが構成するMP構造体がないか探していましたが無いことが判明したためuchan先生と相談し、@liva先生のRaphine OSを参考にMADTを利用する方針となりました。

キャンプ DAY3

朝食を6:30から食べた後、すぐに前日の続きでMADTの情報取得を実装していました。前日の時点でほぼ実装は終了していたため、何個かバグを修正した後、LAPICとIOAPICの初期化処理が無事走るようになります。後少しの所まで来た感じになりましたが、IDEドライバとConsoleのtext mode問題が発覚します。

午後からIDEドライバ問題とConsoleのtext mode問題に取り組んでいました。IDEドライバ問題は、xv6にメモリーを利用した仮想IDEデバイスモードがあったためそれを利用することで回避し、text mode問題はディスプレイでの表示を諦め、シリアル通信経由で文字をやり取りすることにしました。

ついに起動!

DAY3の午後、ついにxv6のシェルが起動しました!このときはほんとに嬉しくてuchan先生と一緒にはしゃいでいました。同じ部屋でコンパイラを書いていた鮟鱇さん曰く「何か叫んでた」と言うぐらいはしゃいでました。ほんとにうれしくて感動してました。

DAY3はその後、貸出実機のMinnowBoard上で動かすためにあーだこーだしていましたが、再起動を繰り返してばかりでうまくいきませんでした。

QEMU側でもメモリを増やすと起動できなくなる問題に直面しました。

その夜、

ひらめきました。ひらめきを元に実装し直すと、

という感じであっけなく解決。もうこれは実機でも起動するだろうとルンルン気分で寝ました。

DAY4

この日は朝から実機で動かす気満々で朝食を食べたのち、作業をしていました。部屋が開いてからすぐに実機でテストをしましたが、シリアルから何も出てこない。

これはどういうことだ?と、DAY3にMinnowBoardとPCをつなぐシリアル変換ケーブルを貸してくださったシステムプログラミングトラック ベアメタル開発のN先生に相談したところ、送信バッファの中身が空かどうか確認すると良いというアドバイスを頂いたので、早速試してみました。

アセンブリで、送信バッファが空ならばクラッシュさせ、空でなければ無限ループするというコードを書き実行。結果、クラッシュすることなく無限ループしているようだったので、送信バッファが吐けていないことが判明。さらに、MinnowBoardのシリアルはIOポートでなくPCI Express経由で入出力していることが判明し絶望。

仕様書をよく読むと、IOポートでの通信を可能にするオプションがあったためそれを有効化にしてみましたが、何も出てこず、あえなく時間切れとなりました。

 

ちなみに、実機でのデバッグはhltをかけても止まっているのかすら分からないので、xv6がクラッシュすることなく無限ループに入っていることを利用して、意図的にクラッシュさせることでカーネルパニックが起こることなく正常に処理が到達していることを確認するカオスな方法でデバッグしていました。

最後に

当初の目標とは大きく異なる着地地点となりましたが、これはこれでとても楽しかったです。もちろん、最初の3つの目標は達成するつもりなので、気長に頑張っていこうかなと考えています。OS開発はデバッグやら設定の作法などで大変な部分が多いですが、その分うまく動いてくれたときの感動は格別です。自作OSは最高に楽しいのでみなさんもチャレンジしてみてください。

謝辞

@uchan_nos先生のほぼマンツーマンでのアドバイスがなければここまでたどり着くことは出来なかったと思います。自作OS開発の辛さと楽しさを知ることが出来ました。また、GDBについては@sat先生、MADTについては@liva先生、実機での実験はベアメタル開発のN先生のアドバイスを元に問題を解決することができました。多くの講師の先生方のご指導のおかげでこのような成果を出すことが出来ました。本当にありがとうございました。

成果物

64bitのUEFIからxv6の起動には成功したので、ソースはGitHubで公開しています。

]]>
https://anqou.net/poc/2018/08/22/post-1860/feed/ 0
セキュリティ・キャンプ全国大会2018応募用紙の話 https://anqou.net/poc/2018/06/15/post-1606/ https://anqou.net/poc/2018/06/15/post-1606/#respond Fri, 15 Jun 2018 14:06:37 +0000 https://anqou.net/poc/?p=1606 お久しぶりです。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バスのことを調べたりするうちに、ぱっと見では複雑な動作をしているものでも裏は簡単な仕組みの積み重ねであり、それを追いかけていけば何が起きているのか把握できる。難しそうだから…という考えはもったいないものであり、少しでいいから中身を覗き込む。そうすれば楽しいワクワクする世界が広がっている。そんなことを感じることができました。

]]>
https://anqou.net/poc/2018/06/15/post-1606/feed/ 0
GW中に「12ステップで作る組込みOS自作入門」をした話 https://anqou.net/poc/2018/05/07/post-1562/ https://anqou.net/poc/2018/05/07/post-1562/#comments Mon, 07 May 2018 14:37:12 +0000 https://anqou.net/poc/?p=1562 どうも。半年ぶりの投稿のPiBVTです。

今回は、GW中に「12ステップで作る組込みOS自作入門」をしたのでそのことを書きたいと思います。

12ステップで作る組込みOS自作入門とは?

H8/3069Fというマイコンボードを利用して、少しずつステップアップしながら最終的にはOSを動かそう。という主旨の本です。

気になる方は色々検索してみてください。

12ステップで作る組込みOS自作入門

なんでGW中に?

で、何でGW中にこんなことをやっていたのかというと、すべてはこのツイートから始まりました。

今年のセキュリティキャンプのテーマが発表されて専門講義に「OSフルスクラッチ開発」という項目を見つけました。

しかし、参加するには、課題に対する回答を書かないといけません。OSについていろいろ調べたり妄想していると…

となりました。普通のコンピュータ大好きな学生にとってはよくあることですね。

ちょうど大学図書館にも本があったので早速借りて読み始めました。

準備物

作りながら読み進めるために、27日の昼にはH8/3069Fマイコンボードを購入しました。

H8/3069Fネット対応マイコンLANボード(完成品)

3連休中は届かないだろうと思っていると…

次の日の昼には届きました。秋月電子さんと佐川急便さん優秀すぎ。

シリアルケーブルは持っていたので新たには注文しませんでしたが、これがトラブルとなります…

前半三連休の様子

とりあえず、マイコンボードも届いたのでgccクロスコンパイラ等の環境構築を済ませ、

1stステップのHello Worldをすべくせっせと写経し始めました。

本の内容は、ステップごとにソースコードを写経しそのコードに関する解説がついてくる構成なのでかなり分かりやすかったです。

1stステップは「Hello World」とシリアル通信で表示するための制御プログラム、いわばドライバみたいなものをCで書き、処理関数への突入用にアセンブリを数行書いた程度でした。写経自体は1時間半ほどで終わりビルドもできたので早速バイナリをマイコンボードに書き込もうとしました。が、

書き込めん!なんでや!

Arch Linuxが悪いのかWindows環境でも試してみましたが、全く書き込めません。結局、深夜過ぎまで試行錯誤していましたが全くうまく行きません。ネットの海をサーフィンした結果、300円で購入したシリアルケーブルが悪いようなので半ギレになりながら、他の方の実績があるiBUFFALO USBシリアルケーブルと、RS-232C ストレートケーブルを購入しました。届くのには数日かかるのでそれまではせっせと本を読み進めていました。

「はやくへろーわーるどしたい」と5分おきに言いながら2ndステップを読み進めます。このステップでは1stステップのシリアル通信プログラムの解説を読んだり、putsなどのシリアル出力系の関数を書いたりしていました。

2ndステップを読み終わっても注文したものが届かないので3rdステップを読み進めます。個人的には前半三連休の中で一番ワクワクした内容でした。静的変数等のメモリ領域割当についてのステップだったのですが、リンカスクリプトを駆使してROM,RAMの領域を操作したり、初期値を持つ変数と持たない変数の領域確保の違いを初めて知ったりしました。

ここでようやく荷物が到着し、試しに書き込んでみると何事もなかったかのようにあっさりと「Hello World」しました。

2ndステップ、3rdステップのプログラムも無事動き、次は4thステップへと進みました。

4thステップでは、シリアル通信でデータを転送し、RAMの領域上に展開するプログラムを書きましたが、3連休中には動きませんでした。

中二日間の平日

講義にはちゃんと参加し、帰宅後せっせと作業しました。4thステップのプログラムは一行だけ抜けている部分があり、受信後無限ループになっていたのを修正すると無事動きました。

dumpコマンドで送り込んだデータのバイナリを表示し、一致するかチェックすると無事一致しました。少し感動。

まだまだ元気なので5thステップに進みます。5thステップではELF形式のバイナリを読み込み、ヘッダーなどを取得したりRAM上に展開したりするプログラムを書きました。普段何気なく実行しているELF形式ファイルの中身がどうなっているのか知れたのはいい経験です。ヘッダーを読んでいると実行アーキテクチャやメモリセグメントなど予想以上に情報量がありました。で、ビルドし書き込み実行すると、

しっかりとヘッダーを取得してくれました。

5thステップがうまく動き調子に乗ったのか6thステップに突入しました。次の日は6時起きなのにそんなことは完全に無視です。6thステップはシリアル通信経由で実行バイナリを受け取り、実行するブートローダーを完成させます。1stステップで動かしたHello Worldを実行バイナリ化し、ブートローダーで読み込んで実行します。

1時間ちょっとで動き、中身も大して難しくなかったので楽に読み進めることができました。

5/2水曜日は、前日夜遅くまで作業していたせいで教科書を忘れるやらバイトで寝そうになるやら散々で迷言を吐く以外何もできませんでした。

意味不明です。

 

後半4連休(作業自体は2日間)

さあ、待ちに待った後半4連休です。木曜日と金曜日はサークルで夜も「攻殻機動隊S.A.C」の鑑賞会をしながら作業していました。

7thステップは割込み処理の実装です。OSにとって重要な要素の1つでワクワクしながら読み進めました。ここでは、シリアル通信を割込み処理で行えるようにしました。

割込み処理突入時のレジスタやスタックポイントの退避、割込み処理終了時の復帰はアセンブリで数十行でしたが、使っている命令は殆ど同じなので簡単でした。で、

動きました。

次は8thステップでスレッドの実装です。ここらへんまで来るとOSって感じがしてきてテンション上がりまくりですね。「ひゃー楽しいい」とか言いながらやってました。(本当です) スレッド処理に必要なタスク情報を格納するTCB(タスクコントロールブロック)を構造体で実装し、実行可能なスレッドを保持するレディ・キューの実装は、うまい具合に考えられていて勉強になりました。スレッドの実装だけあって、それなりのコード量はありましたが無事ビルドし、

スレッドが1つ動きました。この段階ではスレッドはラウンドロビンなスケジューリングになっているので9thステップは優先度を実装します。

9thステップはスレッドの優先度実装です。スレッドをどのような順番で実行するのか、割と実行効率に直結する部分です。スレッド関連のシステムコールを実装し、優先度に関する項目を追加したりしていましたが、8thステップのレディ・キューの概念がここでかなり役立ちました。(レディー・キューを優先度が高い順にすることで、必然的に優先度が高いスレッドから実行される。) 若干のバグを埋め込んで正常に動かなかったりしましたが、なんとかデバッグして、

動きました。この時点で深夜1時40分です。だいぶ疲れてきましたがまだまだです。

10thステップはメモリ管理です。有名なmalloc()やfree()などの動的なメモリ領域確保のシステムコールを実装します。今回のマイコンにはMMU(メモリ管理ユニット)がないため、仮想メモリやメモリ保護機能はありません。そのため、ちゃんとメモリ管理をしないとOSが破綻してしまいます。ここでもスレッドの管理と同様にリンクを利用したデータ構造が用いられていて、個人的にはかなり面白い部分でした。眠かったけど。眠い目をこすりながら頑張った結果、

動的に確保した領域に文字列を保存できました。ここでついに力尽き、仮眠を取ることにしました。ちなみに大学内です。

硬い長椅子の上で長時間寝れるわけもなく、目を覚ますと…

徹夜で映画「インターステラー」を見ながらPythonで物理シミュレーションをしていたサークルの仲間がブラックホールについて計算していました。どうやらブラックホールの半径について計算しているようでしたが、何をしているのかよく分かりませんでした。自分がブラックホールになった場合の半径を計算して満足そうにしていました。

そんなことはさておき、11thステップのタスク間通信を実装します。スレッドでプログラミングをしていると割込み処理などで意図しない変数が書き換わる可能性があります。その対策としてタスク間通信によってスレッド同士で同期をとり、データを書き換える恐れのあるサービスをスレッド化することで、問題を回避しています。この実装もメッセージボックスというものを利用していて面白かったです。まだ覚め切らぬ頭で書き、

動きました。

いよいよ最終ステップの12thステップ外部割込みの実装です。ここではシリアル通信とコマンド応答部分を割り込み処理とタスク間通信を利用して実装します。なのですが、このステップは殆ど記憶に残ってないです。システムコールや割込みハンドラが複数出てきて寝不足の頭には辛いところがありました。とにかく写経ロボとなりながら書き、

動きました。ここで本の内容は終了ですが、タイマやDRAM、LANなど遊べる要素はまだまだあるので少しずつやっていきたいですね。

まとめ

結局ちょうど1週間で終わりましたが、すごい良い経験だったと思います。x86での開発はかなり手間がかかるらしいのですが、マイコンは機能が単純なだけあって書いたプログラムも理解しやすかったです。実際に書きながら、「OSってこうなってんのね」とか「簡単なやつなら自分でも作れるかも」と思っていました。実際作れるかどうかは分かりませんが。あと、C言語とアセンブラのみでの開発だったのですが、C言語の構造体の使い方や管理のしやすいプログラムの書き方を経験できたのはよかったです。これからも少しずつ勉強していくつもりなので、興味のある方は一緒にどうでしょか笑

みなさんも是非OS開発を体験してみてください。きっとコンピューターに対する目線が変わることと思います。

]]>
https://anqou.net/poc/2018/05/07/post-1562/feed/ 2
最近のAI・仮想通貨ブームに思うこと https://anqou.net/poc/2017/12/24/post-797/ https://anqou.net/poc/2017/12/24/post-797/#comments Sun, 24 Dec 2017 12:37:07 +0000 https://anqou.net/poc/?p=797 この投稿は「カオスの坩堝 Advent Calendar 2017」の24日目の記事です。

はじめまして。カオスの坩堝 Advent Calendar 2017 24日目担当のPiBVTです。おそらくほとんどの方が僕のことをご存じでないと思います。簡単な自己紹介でもしようかと考えたのですが、 紹介したところで何ら役に立たないので控えさせていただきます。

今日は12月24日でクリスマスイブですが、皆さんいかがお過ごしでしょうか。幸せな方もいれば、僕のように1人で過ごしている方もいるかと思います。せっかくのクリスマスイブなのでクリスマスにまつわることを書くのがよいかと思ったのですが、あえて全く関係ない「AI・仮想通貨」について書かせていただきます。

AIについて

まずはAIについて徒然なるままに書いていきます。

第三次AIブーム到来

多層型ニューラルネットワークを利用した深層学習(ディープラーニング)が実用化され、AI研究は一大産業となりました。AIに関係ある企業、関係ない企業も決まり文句のようにAI,AIと叫んでいて、まるでAIが万能であるかのように錯覚してしまいそうですね。まずは、このブームの発端について少し説明しておきたいと思います。

ニューラルネットワークという考え方自体はAI黎明期の1950年代から存在してましたが、当時は教師データの不足や計算資源の不足で高い精度は得られませんでした。しかし、長年の研究と計算能力の改善によって、大量の教師データを学習することが可能になりました。さらに、「隠れ層」の存在する多層型ニューラルネットワーク(多層型パーセプトロン、畳み込みニューラルネットワーク等)の実現によって画像認識コンテストで優勝するほどの成績を収めました。まさにここが今の一大AIブームの起点となったのです。

それ以来、Google、Apple、Microsoft等の大企業はこぞってAIの研究を開始し、優秀なAI研究者は次々と吸収されていきました。普通の企業でも「なんかよく分からんが、AIはいいぞ」という噂に乗っかって業務を自動化させるべくAIを導入したり、宣伝文句でもAIという言葉が目立つようになりました。まぁAIがブームになって嬉しいことには嬉しいのですが、今まで見向きもしなかった人たちがこぞってAIを語るようになったのは異様な気もします。それだけAIが身近になり、注目される分野となったということなんですかねぇ。

AIは人を超えるのか?

このテーマに関して考えることがよくあるのですが、現状僕の考えとしては「まだ無理だろう」というところですかね。深層学習に関しては研究がまだまだ不十分でそのポテンシャルは計り知れないのですが、原理上、「大量の教師データ」が必要となるところがボトルネックになるような気がしてます。画像処理、音声認識が成功したのは膨大な教師データが存在するからであり(間違ってるかもしれません)、会話するロボットに関しても、人間の会話パターンを学習することで実現しているそうです。某M社の会話AIがナチズムを肯定したことでも有名ですね。あれは一部の人間がそのような情報を学習させたため起きたと言われてます。

画像認識や音声認識に関してはすでに人間よりAIの方が優秀ですが、人間に出来てAIには出来ない分野があります。それは「探求」です。今のAIは、与えられた情報を学習して学習をもとに判別対象を確率的に「なんかこれっぽい」と判断してるに過ぎません。積極的に学習データを自分で取得して学習するアクティブなAIも存在しますが、すべてのAIはあくまでプログラム上に形成されているため、アルゴリズムという限界を超えることは出来ません。この「アルゴリズムの限界」が今のAIの限界であると僕は考えてます。アルゴリズムの限界によってAIが自分でプログラムを作ることは不可能(詳しいことは省略しますが、証明は存在します。)であるが故に学習範囲が限定され、そもそも探求等ということは出来ないと思うんです。人間のまねごとは出来ても、人間と同等の存在にはなり得ない。というのが僕の考えです。

なんで「探求」?

正直なところ、自動操縦とかのAIに探究心なんか必要ないですよね。でもそれでは一定のアルゴリズムに沿って作業するちょっと賢いロボットに過ぎないと思うんです。正直それでは面白くない。会話AIも所詮ネット上の情報を取得してしゃべるか、学習した情報をもとにしゃべるだけで面白くないですね。

人間が千差万別、十人十色である理由はこの「探求」心のベクトルが人によって違うからではないでしょうか?それが人間のアイデンティティの一角を形成していると考えることも出来るでしょう。人によって着目点が違うからこそ、人は独創的と言われる発想ができ、天才と呼ばれる人が存在するのです。AIが人間と同等な存在になるために欠けている要素とすればこの「探求」ではないかと思うのです。

結論

今回はちまたでよく言われている「AIは人間を超えるのか?」という観点で考察しましたが、部分的には超えてる分野もあるけど、まだまだ人間の需要は尽きない。といったところが結論となります。もちろん、僕の個人的な勝手な意見なので実際とは異なる可能性の方がかなり高いですが、確かにいえることは「人間に求められる能力は発想力に変わりゆく」といったところでしょうか。

仮想通貨

AIについての馬鹿丸出し駄文で、もううんざりという方もいると思いますが、許してください。仮想通貨について書かせてください。

ビットコインブーム

まーすごいですね。ビットコインのブーム。一時は200万円に届くかと思われましたがその後大暴落。普通の通貨ではありえないアグレッシブな価格変動です。おそらく金儲け目的で「なんかよく分からんが、仮想通貨は儲かるぞ」と買った直後に大暴落で青ざめた人も沢山いると思いますが、まぁそんなもんですよね。だってビットコインは何にも管理されてませんから。普通の円をはじめとする通貨は金を価値基準とした「金本位制度」を元に作られ、その後、国によって流通が管理される「管理通貨制度」に移行しました。つまり、ある程度の管理によって通貨の価値が保障されているため、安心して使うことが出来るわけです。しかし、ビットコインはどうでしょうか。一部の人間が大半のビットコインを保有し、その気になれば自由に相場を変化させることが出来るそうです。株取引では禁止されてるようなインサイダー取引も可能です。つまり、ビットコインはネット世界共通の通貨形態をもたらすという本来の理念とは異なり、単なる金儲けの手段になってしまったわけです。金儲け関連の話は話し出したらきりがないのでここら辺にしといてビットコインの仕組みについて語りたいと思います。

ブロックチェーン

はっきり言ってブロックチェーンの仕組みは「素晴らしい」の一言です。全取引履歴をあえて公開することによって、通貨、取引の確かさを保証するという仕組みは目から鱗です。そして、その保証する仕組みに必要な計算資源の対価にビットコインを与えるという人間の心理をも利用した完璧なアルゴリズムだと思うのです。しかも、分散型という。あっ。ブロックチェーンの仕組みをここで語るほど余裕はないので適当にググってください。アルゴリズムとしては、完璧だったと思うのです。「アルゴリズムとしては」ですけどね。

ビットコインの問題点

ビットコインの問題点としてはさっき言ったように投資目的の取引の他に、ビットコインのシステムに対して計算資源を提供するマイナーが中国に集中してしまったことがあります。マイナーは誰でもなることが出来、提供した計算資源に応じたビットコインが与えられるため、大規模なマイニング設備を電気代の安いところに建てて荒稼ぎし始めたのです。そして、

組織化された採掘集団がマイニングに殺到しました。2016年現在、「採掘」は7割を中国が担っており、もはやコミュニティ運営が正常に行えなくなっていて、コアの開発を担当していた人物が「ビットコインという実験は失敗だった」と表明する事態になっています。 (Gigazine,2016)

という事態にもなっています。まぁブロックチェーンを応用した最初のシステムなので当然と言えば当然です。しかし、もはや手のつけられない領域にビットコインは達してしまいました。おそらく、この先様々な規制が仮想通貨全般にかけられることになると思います。そのときに価格がどうなるのかは神のみぞ知るところでしょうか。(おそらく大暴落すると思いますが。)

僕が面白いと思う点

僕がこのビットコインで面白いと思ったことは、システム全体が「分散型計算システム」を形成しているところです。深層学習やデータマイニングが主流となった今、計算資源はあればあるほどよいものです。一方で普通のユーザーがパソコンの計算リソースを使い果たしてることはほとんどありません。その余剰な計算リソースを集めて必要な人に提供する。僕がたまに「P2Pは偉大」とTwitterでつぶやいているのはP2Pが分散システムの基礎であるからです。実際にこのようなシステムは「BOINC」等で実現されてます。このシステムをもっと自由度が高いものに出来たらいいなと思ってて、今のところ個人で色々調べてます。

最後に

AI、仮想通貨についてつらつらと書いてきましたが、ここ数年でIT界ではすさまじい革新が起きてますね。この先どのようになるのか、すごい楽しみです。

参考文献

大野健太(2015) 「ニューラルネットの歩んだ道、ディープラーニングの登場で全てが変わった 」

Gigazine(2016) 「Bitcoin採掘の7割を中国が占め、元開発者が「実験は失敗だった」と表明」

 

この記事は「カオスの坩堝 Advent Calendar 2017」の24日目の記事でした。 PiBVTが担当しました。25日目は、艮 鮟鱇 さん担当の予定です。

]]>
https://anqou.net/poc/2017/12/24/post-797/feed/ 1