Linux が動作する RISC-V CPU を自作した (2019 年度 CPU 実験 余興)

私が所属する東京大学理学部情報科学科では三年の冬学期に CPU 実験という実験授業が開講されています。本稿ではその簡単な説明をした後、その実験の一環として約一ヶ月ほど取り組んだ「Linux が動作する RISC-V CPU を自作するプロジェクト」で何をしたか、またどのような成果を得たかについて紹介したいと思います。

本稿を読むその前に

弊学科では「XX 年度に教養学部から理学部情報科学科に進学してきた学生」を「XXer」と呼ぶ文化があります。本稿ではこの表現を断りなく用います1。また私は普段 Web が好きでもっぱら Web セキュリティに関することを追いかけているだけのしがない学部 3 年生なので (私についての情報は ここ に大体まとまっています)、こういう低いレイヤのことは未だによく分かっていません。あくまで素人の記事だとご理解いただけると嬉しいです。誤りの指摘や質問があれば、ここ にある連絡先に適当にご連絡いただければと思います。あとこれはポエムです。

はじめに - CPU 実験とは何か

「CPU 実験」とは東京大学理学部情報科学科三年冬学期に開講されている「プロセッサ・コンパイラ実験」の通称です。この実験は適当に分けられた 3, 4 名からなるチームのメンバーと一緒に CPU・FPU・コンパイラ・シミュレータを作り、与えられたレイトレーシングプログラムの実行速度を競うというものです。大抵 CPU 実験についての他のブログ記事には以下のような画像が添付されているのですが、これはそのレイトレーシングプログラムがこれを出力するためです。

レイトレーシングプログラムが出力する画像

この実験は長い歴史を持つので、「CPU 実験」ないしは「東大 CPU 実験」のような検索ワードで適当に検索をすると、非常に多くの先人達の記事がヒットします。特にレイトレーシングプログラムの高速化に関しては 16er の先輩たちの取り組みが非常に強烈です。気になる方は eguchishi さんの記事sueki743 さんの記事 を読んでみるといいかもしれません。

また本来 CPU 実験の目的は自作コア上でのレイトレーシングプログラムの高速化なわけですが、例年の CPU 実験ではしばしばこれとは方向性の異なる取り組みが行われます。そのような取り組みは「余興」と呼ばれており、毎年一定数の学生がチャレンジしているようです。以下に過去の先輩たちの余興プロジェクトの例を置いておきます2

なおこれは余談なのですが、この実験の面白い所として、「基本的に何も教わらない」という点が挙げられます。一応毎週集まりはするのですが、第一週に「単位要件はこれだよ」「班を決めるよ」などでワイワイする以外は、それ以外の週は進捗を各班 5 分ほどで話す発表会的ななにかが開かれるだけです。実験の中で「CPU はこう作ります」みたいなことを教わる機会はありません。なので運良く (運悪く?) コア係となった 7, 8 名は、2 年冬学期から 3 年夏学期の 1 年で学んだこと3を総動員するか、別途独学をするか、先輩のブログに学ぶかをして、自力でコアを書き上げる必要があります。2 年冬学期と 3 年夏学期に学んだことがあればシンプルなコアくらいは書けるようになっているはずですから、適切な強度の演習だとは思うのですが、想像以上の放任感に拍子抜けしたのは事実です。

Linux が動作する RISC-V CPU を自作する

背景

14er の nullpo_head さんは、自身の CPU 実験についてのブログ記事 で、以下のように述べています。

“…Linuxに初めから、とは言わずも、ucLinuxくらいには挑戦していればよかったかもしれない。…”

また 17er の yamaguchi_1024 さんの記事 にも次のような一節があります。

“…Iwashi班という自作CPU上でlinuxを動かすことを目標とした余興班を…”

ここからもよく分かる通り、「自作 CPU 上で Linux を動作させる」という夢は私たちの余興文化に根強く存在しているものの (?)、未だ達成されてこなかった夢なわけです。

もっとも 「Linux を動作させる」という目標が「自作 OS を動作させる」「xv6 をツールチェインごと移植する」という目標に対する上位の目標なわけではありません。それにどれも価値のある素敵な試みであるということは、疑うまでもありません。過去の先輩が既に達成したことを余興のゴールとして設定したとしても、十分に価値のあるプロジェクトが遂行できたことでしょう。それに私はこの世界の「巨人の肩に乗る」という行為も大好きですし、HIP-HOP のサンプリング文化も愛して病まないような人間ですから4、当然過去の先輩の余興資産を利用して更によいものを作る (e.g. 18er の自作 OS に 〜 を追加する) というのも一定魅力的であるように思います。

一方そのような目標設定は、過去の先輩がそれに取り組んだ当時と比べて既にチャレンジングさが消えてしまっている、と私は思います。何かに行き詰まっても先輩のソースコードを読めば大抵のことを解決できてしまうし、場合によっては直接その先輩に質問をすることだって出来るかもしれないからです。もちろん車輪の再発明は素晴らしい学びの機会を生みますから、過去の先輩の足跡を追うことが無駄だとは思いません。ただそれが昔よりはチャレンジングではないように感じる、というだけです。

それに加え自作 OS や自作 CPU をするという趣味は近年大衆化しつつあります (要出典)。少なくとも私が学生生活を過ごしている理学部の 7 号館という建物 — これは本郷にあります — で適当に歩いていれば、CPU を自作したことがある人にいくらでも出会えてしまいます。余興のテーマ設定をする上では、このような潮流も考慮に入れなくてはなりません。

余興プロジェクトの概要

このような過去の先輩たちの余興や、これまで様々な挑戦をしてきた先人たちのマインドを見習って、 「過去に余興としてやられていないこと」「自分が楽しいと思えること」「今の自分の実力では達成が容易といえないこと(十分にチャレンジングであること)」 をやろう、という方針を固めました。そして 10 月頃本郷のやよい軒で学友とご飯を食べながら 「Linux が動く CPU を作ると面白いのでは」 という会話をして、好感触を得たので、これをテーマにすることにしました。また適当に募ったところ 3 人ほど友人が興味を示してくれたので、余興プロジェクトは彼らと一緒に取り組みました。余興は半ば僕のわがままで始まったわけです。以降私を含む余興に取り組んだ 4 人のことを余興班と呼ぶことにします。

今回やったことの概要を箇条書きで示します。なお余興班の私以外の 3 人の仕事なくしては Linux は動かなかったはずですし、私だけがブログを書くことで彼らの功績が目立たなくなるのは余り快い出来事ではありません。なので今回の作業の分担も付記しておくことにします。

  • 全体的な設計とゆるゆる PM 業 (担当: 私)
  • xv6-riscv (rv64gc) の rv32imasu 向け移植 (担当: 私)
  • 適当なブートローダの実装 (担当: 私)
  • Linux カーネルや OpenSBI、QEMU に適当なパッチを当てたり、Device Tree を用意したり、というソフトウェア面全般 (担当: 私)
  • RISC-V コアの実装 (担当: 私)
  • MMU + TLB の実装 (担当: 私)
  • virtio-blk ぽいものの実装 (ロジック部分: 私, フラッシュメモリとの通信部分: A くん)
  • PLIC, CLINT の実装 (担当: A くん)
  • クロック分割した mul/div モジュールの実装 (担当: B くん)
  • キャッシュの実装 (担当: C くん / 現在も作業中)

僕と A くんが書いたのが Linux 完動のために必要だった部分で、B くん C くんが書いてくれた・書いているのが高速化のためのものでした。

またSlack のログを振り返ると、作業の大まかなタイムラインは次のような感じだったようです。

  • 1/17: 余興をやるぞと僕が叫ぶ
  • 1/19: 分担を決める
  • 2/16: xv6-riscv が動作するようになる
  • 2/25: linux が動作するようになる (バージョンは 4.19.0; このバージョンにしたのはちょうど手元でそれをいじって遊ぶ別の機会があったからです)
  • 2/27: 200 MHz で動作するようになる
  • 2/28: 発表会

この余興の期間は自分の勤めている会社での仕事や、OWASP Night というイベントでの Blind Reguar Expression Injection Attack についての発表 (参考: 私の過去のブログ記事PortSwigger 社のメディア The Daily Swig によるまとめ)、その他物書き業や人生等も並行して進めていたので、余興だけに集中できる環境下であればもう少し早く動いただろうなと思います5。また元々知識がほとんどない状態6からのスタートだったので、だいぶ遠回りしてしまいました。ぜひ 20er の皆さんには Linux 完動タイムアタックをしていただきたいところです。

結果と成果物

先述の通り、無事 Linux は動きました。以下にブート時の様子の動画を埋め込んでおくので、ぜひこちらをご覧ください。

なお途中で xv6-riscv が動くようにもしました。この時の様子は Twitter でツイートしました。

ソースコードは以下の Organization 下のリポジトリで全て公開されています7。ハードウェアの実装は基本 SystemVerilog で行いました。ただ正直自分でももうメンテ出来ないシロモノになってしまったので、参考になるかはわかりません。今全て書き直したい気分です。

また最終発表会で利用したスライドは以下に置いてあります。

余興で行ったことの詳細

ここからは余興プロジェクトの全体像や、私や余興班の班員が実装したものについて簡単に述べていきます。せっかくなので、一部実装当時考えていたことなんかも添えて書いてみようと思います。

CPU の設計と MMU

実はここまで「CPU を作る」というなんとも雑な表現な表現でお茶を濁してきたのですが、どんな CPU を作るかは大切な要素です。この選択によって MMU の仕組みであったり、Linux カーネルをどう用意するかであったり、ツールチェインをどうするかであったりがある程度(ほぼ)決まってくるからです。

結論から言うと、今回私は ISA として RISC-V (rv32imasu; Privileged ISA v1.10Unprivileged ISA v2.2 を参照) を選びました。その理由は私が RISC-V が好きだから・MIPS のシミュレータ (特権管理はありません) を過去に軽く書いたことがあったので MIPS には飽きていた、の 2 点でした。RISC-V は FPGA 上で動かして遊ぶ CPU を作るためにはほどよいサイズの ISA であると思いますし、何より非常にシンプルに実装ができます。MIPS のようにオペランド順が非自明でバグらせる、ということもほぼほぼなかったと記憶しています。なお user-level trap と PMP (Physical Memory Protection) 機能の実装はサボりました。なお実装は ここ にあります。

マイクロアーキテクチャ面に関しても多少付言しておくと、今回はシンプルなマルチクロックサイクルのコアにしました。また FPGA 上には 1 hart — 所謂 1 コア — のみを乗せることにしました。そのためもちろん分岐予測のような機能は必要なく、かつアトミック命令の実装も最小限で済みます。また CLINT 経由でのソフトウェア割り込みの実装も比較的サボることができました8

また rv32 (32 bit な ISA) 系を採用したため、ページングアルゴリズムには Sv32 を利用することになりました。Sv32 は Privileged ISA v1.10 で定義されており、他のアーキテクチャよろしく、仮想アドレスの [31:22] の部分 (VPN1 と呼ばれます) と satp レジスタ (x86 でいう cr3 レジスタ) の値を使って次のページテーブルのアドレスを得て、それと仮想アドレスの [21:12] の部分 (VPN0 と呼ばれます) とそのアドレスを利用して物理ページ番号 (PPN) を得て、それと仮想アドレスの [11:0] の部分 (offset と呼ばれます) から物理アドレスを得る、というものです。極めて自然なページングアルゴリズムですね。MMU の実装は ここ にあります。

Vivado から利用できる IP コアを利用したもの

FPGA ボードと外部との通信は UART 経由で行いました。そのためには Vivado から利用できる IP コアである AXI UART 16650 を利用しました。これはただの UART 16650 なので、これ以上記述することがないのですが、興味のある方は Linux カーネルの drivers/tty/serial/8250/* を眺めてみるなどすると面白いかもしれません。

また MMIO に関しては、同じく Vivado から利用できる IP コアである AXI Interconnect を利用しました。

SPI 通信に関しても AXI Quad SPI という IP コア経由で行いました。

Linux をブートするための初期の方針

私たちが実験に使っていた FPGA ボードは KCU105 というものです。このボードには比較的豊富な資源があります(e.g. SDRAM やフラッシュメモリ)。したがって Linux を動かすことにハードウェア的な問題はそこまでなさそうでした。

ただ何も考えずにビルドした Linux カーネルは BRAM (KCU105 の場合容量は約 2MB ほど; 初期値を FPGA への bitstream の書き込み時に指定できる) には乗り切らず、かつ SDRAM に対して起動時の初期値を 現実的な時間で 流し込むことはそれなりに難しそうだ、ということは比較的初期から分かっていました。これは適当に作業を進めていけば本当に初期で気がつくはずですし、IS の先輩も自身のブログでこう語っています。

“次はコアだが

  • kernelは展開すると仮想アドレスだしかなり大きくなってしまうので、elfやgzipなどで圧縮してブートローダで展開しないといけないが実装とてもつらい
  • ハードウェアの検出部分で死んでいると考えられるのでそこらへんの関数全部無効にしないといけない
  • riscvの仕様通りに仮想メモリやシステムレジスタを実装するの厳しい 等の理由でlinux移植は現実的に無理だろうという話になり、…”

そこでひとまずは以下のような計画のもと余興を進めていくことにしました。

  • まずはただちに BRAM に乗るサイズの OS である xv6-riscv を動かして素振りをする。
  • 次に Linux カーネルのイメージサイズを縮めて BRAM に初期値として乗せ、同じく BRAM 中に置いたブートローダか何かで展開する。
  • フラッシュメモリをバックエンドとして QEMU の virtio-blk 相当の動作をハードウェア的に完璧に再現し、フラッシュメモリ中に /init を置く。

また /init としては busybox を利用することに決めました。initramfs の生成スクリプト等は このリポジトリ に置いてあります。

そして RISC-V の世界における BIOS/UEFI 的な存在である SBI (こう理解していますが、間違えているかも) については、自分で実装してもよかったのですが、今回は時間の都合上 OpenSBI を利用することにしました。ただ実際は一部パッチを当てる必要が生じたので、適当に fork をしたもの を利用しました。SBI の仕様については RISC-V Supervisor Binary Interface Specification を参照してください。

xv6-riscv の (簡単な) 移植

ところで先程「素振り」として登場した xv6-riscv とは、MIT の授業 で使われている教育用の小さい OS です。元々 xv6 は x86 向け だったのですが、最近授業では RISC-V 版を利用しているようです。

ただこれは rv64gc 向けなので、ページングアルゴリズムとしては Sv39 が使われていますし、多くの変数が 64 bit で定義されていますし、メモリマップも若干違います。特にカーネルを指す仮想アドレスの値等は要修正なはずです。

なのでまずは素振りとして、これを rv32imasu の範囲で済むように移植しました。移植して出来たものが これ です。なおこの移植作業は極めて自明な作業の連続ですが、一点注意すべきこととして、はじめのユーザープロセスを起動するための stager 的なプログラム に C 系命令 (圧縮命令) が利用されていることが挙げられます。私は rv32imasu を ISA として採用し、圧縮命令はサポートしなかったため、このへんで非自明なバグを踏むはめになりました。

この移植作業と先程述べたようなコアの実装により、無事 xv6-riscv を動作させることが出来ました。当時のコアの実装は このあたりのコミット においてあります。このころは virtio-blk に従ったインターフェイスが実装されており、ディスクの代わりに BRAM を利用していたのですが、後のコミット のころにはフラッシュメモリにファイルシステムを置いた状態で xv6-riscv が動作するようになりました。これで xv6-riscv は完璧に動かせたわけです。

初期の方針の問題と方針の変更

このように初期の計画に則ってしばらく頑張ってみたところ、xv6-riscv は妥当な作業量で動かすことができました。しかし初期の方針は Linux 動作のためには不適切でした; カーネルサイズを縮めるのには限界があるからです。また virtio-blk 相当のインターフェイスをハードウェア的に実装するのはそれなりに骨が折れる作業であるようにも感じられていました。もっとも xv6-riscv が利用する程度の機能は仕様に反しているものはあれど実装できたので、根気強く取り組めば十分可能であるとは思います。しかし余興に使える期間は短いですから、Linux を起動させるという最終目標を考えると、このような非本質的な努力は省略するのが安全だと感じました。

したがって、xv6-riscv が動作するようになったころに、次のような方針に切り替えることにしました。

  • /init を含むに rootfs を initramfs としてビルドしたカーネルのイメージをよしなに調理し、フラッシュメモリに置いておく。
  • 「フラッシュメモリをバックエンドとし、virtio-blk のようなインターフェイスをもったハードウェア」を用意し、お手製ブートローダからそれとお喋りし、フラッシュメモリの中身を SDRAM に展開する。

こうすることで Linux が取り扱うファイルシステムが揮発性になってしまいますが、Linux の起動までは最低限の実装でこぎつけることができそうです。またこのような方針転換をすることにより、フラッシュメモリと会話するためのハードウェアのインターフェイスは virtio-blk に準じる必要もなくなりますから、元々の方針よりも CPU を実装することに注力することができます。Linux を起動するためのブートローダからディスクに対して行いたい操作などせいぜい読み出しだけなのですから、ディスクコントローラは粛々とフラッシュメモリから読み出しをして、適当に割り込み信号さえアサートしてくれればよいのです。

ブートローダの実装と virtio-blk 的ハードウェアの実装

先述のような方針変更をした後は、まずブートローダを実装しました。ブートローダとしては xv6-riscv の virtio.c をちょこっといじって こういうもの を書きました。このプログラムはハードウェアとして実装した virtio-blk 的なもの とお喋りをすることで、フラッシュメモリの中身を 512 バイトずつ読み出してはメモリにコピーする、ということをしています。

また xv6-riscv の動作にも一役買ったvirtio-blk 的なハードウェアについては、この辺 に仕様が落ちているので、ただひたすらに実装しました。なおこの仕様の Legacy Interface (MMIO) の Split Virtqueue をひとまず実装してやれば xv6-riscv は動くようになるはずです。実装は ここ にあります。

班員が実装してくれたもの

ここまでは自分の作業内容についてをつらつらと述べたわけですが、先述の通り、以下のコンポーネントは余興班の他の班員が書いてくれました。

  1. virtio-blk 的なハードウェアが利用する、フラッシュメモリとの通信モジュール
  2. 割り込みコントローラ 2 種 (PLIC, CLINT)
  3. クロック分割した mul/div モジュール
  4. キャッシュ (実はまだ作業中…)

これらはどれも大切なものです。とりわけ Linux を動作させるのにあたって大切なのは 1, 2 です。大きいサイズのカーネルを動かすためにはフラッシュメモリが不可欠ですし、割り込みコントローラ無しでは Linux が (まともに) 動くことはないです。なお PLIC, CLINT に関しては 1, 2 日で実装を終えていました (そしてこれは妥当だと思います)。ちなみに 1, 2 を担当してくれた A くんと僕は、春休みが始まってから Linux が動くその瞬間まで非常に長い時間を大学の学生控室 — 普通この部屋は「地下」と呼ばれます — で過ごしたのですが、そのせいか、A くんに僕のいくつかの口癖がうつってしまったようです。もちろんその逆もまた然り。

3 は比較的早く実装を終えてくれていたのですが、諸事情で Linux が動作し始めてからマージしました。4 に関しては現在も作業中で、できればマージしてどれくらい早くなったかを見たいと思っています。特に今回は initramfs が圧縮されているので、その展開操作の際に非常に多量のメモリ操作が発生します。冒頭に埋め込んだ動画 を見ると一目瞭然なのですが、ブートにかかる時間の殆どはこのあたりの処理です。直感的にはキャッシュを導入することでこの処理がある程度高速化され、ブートもある程度現実的な速さで実現できるのではないか、と思っています。

デバッグ

ここまで紹介したような実装物により、無事 Linux が動くようになりました。もっともしばらくの間は CPU をバグらせて困ったりはしていたのですが、そういう時は大体自分が悪いということを理解していたので、riscv-tests の rv32imasu の p 系 & v 系が全て通るか確認したり、コーナーケースをコアに投げつけたりしながらテストをしました。

元々自分はセキュリティ畑の人間だからか、コーナーケースを考えて遊ぶのは面白かったなあ、という思い出があります。またあからさまなバグで U-mode から M-mode に遷移できることが分かったときには(仕様上の問題ではなく自分のミスです)、exploit を書いて遊んだりもしました。このへんで RISC-V の特権周りの仕様が腹落ちした思い出。

その他

ここまで非常に多くの実装と意思決定と仕様読みをしてきたわけですが、この最中にはツールチェインをたくさん改造する必要がありました。例えば QEMU では 一部の命令を削除したものを作ったり、メモリマップを変更したりしたもの を用意したりしました。またしばしばツールチェインのバグ (と読んでよいのか?) にも悩まされましたが、それは後日談ということで。

間に合わなかったこと

現状なぜか起動してから少しコマンド操作をしていると落ちてしまいます。このバグの原因は発表会の 1 時間くらい前まで必死になって探ったのですが、最後まで取れることはありませんでした。ロック周りか tty 周りでバグっているのではないか、と疑っているのですが…。

またインターネットでのお喋りも本当は実現したかったところです。今思えばFPGA ボード (KCU105) には RJ45 端子があり、かつ Vivado から利用できる IP コアである AXI なんたらというやつのデバイスドライバが Linux カーネルにありそうだったので、これを Device Tree で見せてあげるだけでよさそうだったのですが、時間の都合上取り組むことはできませんでした。

また最終日までにキャッシュを積むことができなかったのも心残りです。キャッシュ自体は余興班の他のメンバーに実装を依頼してあって、かつ実装もあらかた終わっていたようなのですが、マージした後発生したバグの原因を見つけることが出来ませんでした。私の努力不足です。

感想 (実質の余談)

今回 Linux が動く CPU を (ほぼ) 1 ヶ月と 1 週間くらいで自作する、という試みをして、それを完遂したわけです。これは僕にとって申し分のない強度の課題でした。特に前述のような期間の制約があり、かつ基本的に全員自分の班の実験の作業や実験以外の活動があるという制約は非常に厳しかったのですが、これは幾多の夜を大学の学生控室 (地下) で越し、1 ヶ月間ほど太陽をほぼ見ない生活を続けることによりクリアすることができました9 (?)。

また Linux を動かすチャレンジは「理解していればやるだけ」なことの繰り返しです。これは少し攻撃的な表現であるようにも思えますが、結構真実だと思っています。ただしキモは 「理解していれば」 の部分です。私の場合余興を始めた頃は何もかも理解していなかったので、何もかも自明ではありませんでしたし、何も実装できませんでした。そして完全に理解したと思って実装を始めても、案外わからないことがでてきて改めて仕様書を読まなくてはいけなくなったり、誤った理解のまま実装をしてたくさんの非自明なバグを埋めるなどをしました。この辺は「余興に取り組んでいる時間は、OS・CPU・その他諸々に関する自分の理解をひたすらに問い詰められる時間であった」と言い換えることができそうです。余興は自分の未熟さを再確認できるこれ以上にない機会でした。こうしていろんな理解が叩き直されたので、今回実装した範囲に関しては、今となっては全てやるだけだったな、と思えるようになりました。

また非常に沢山の OSS のソースコードや仕様を読み倒すので、色々なものと仲良くなれました。これも今回の余興をやってよかった点の一つです。QEMU, OpenSBI, Linux カーネル, xv6-riscv, riscv-gnu-toolchain, … 挙げるときりがないのですが、色々なソースコードに触れたことで、大変よい知見が得られた気がします。またその分これらの OSS のバグをそれなりの数踏み抜いてしまったり、「この実装やばそう」みたいな箇所をちらほら見かけたりしたので、気が向いたら contribute していきたいところです。

一方、今回余興に取り組んでいる中で、精神的な健康についての課題も見えてきました。発表会前の最終週は「本当に Linux が動くところまでいくだろうか」という不安感がだいぶあり、学生控室でよく発狂 (?) していた記憶があります。途中から気軽にやめられるタイプのプロジェクトではなくなってしまいましたし、半ば僕の巻き込んでしまったとも言える余興メンバーに対しての恩義と責任感も感じていましたから、なおさらです。今後もそれなりに強度の高い挑戦をするときには、このようなギリギリ感がつきまとうこともしばしばあるでしょうから、この辺のメンタルコントロール (やそもそも追い込まれないためのスケジューリング) は積極的に学んでいくべきだと感じています。やりたいこと・やるべきことを淡々とこなす精神力を身につけたいと思います。

また身体的な健康についての課題もありました。まあコンビニ飯を食べながら地下室で椅子を並べて寝る生活を続ければ直ちに体調が崩壊する、というのは至極当然のことです。「ハイキュー!!」 — これは僕が好きなバレーボール漫画です — で、「”無事” を習慣にする」という言葉が最近登場したのですが、非常にこれは僕に刺さりました。この辺だけ語ると所謂意識高い系の人になってしまいそうなので、こんなことを言うのは少し恥ずかしいのですが…。ただ漫画で先述の一文が登場するシーンは非常に名場面だと思っているので、ぜひ『ハイキュー!!』をご一読ください。

いずれにせよ、今後来るであろう大切な瞬間のために、体と心を健康に保つことを心がけていきたいと考えています。

これからの余興への期待と CPU 実験全般について思うこと

来年度以降の余興については、個人的にはChisel での CPU 実験なんかは面白そうだなあとか、自作 CPU 上でのハイパーバイザ的なものの実装ができたらもっと面白いだろうなあ、なんていう妄想をしています。20er 以降の皆さんのご活躍を楽しみにしております10

また CPU 実験の主目的であるレイトレーシングについては、これはこれで楽しいものの、「OS を動かす演習にしたほうが学びが深まるのでは?」と思わないこともないです。レイトレーシングはそんなに大きなメモリ領域を要求しないため、1 クロックで読み出しの出来る BRAM を利用するだけで済みます。キャッシュはいりません。また何よりコアに特権管理や割り込みの処理機構が必要ないので、そのへんの複雑な実装をする必要がありません。このような事実が「OS を動かすほうが学びが深まりそう」という意見をもった理由です。ただレイトレに特化しようとすることで、FPU の高速化やパイプライン処理の導入、アウトオブオーダ{発行,完了}やマルチコア化のような動きが活発になってきたのでしょうから、難しいところだとは思います。なおレイトレーシングに関しては同期 (19er) の Mister くんが書いた記事 が非常に詳しいので、ぜひこちらをご一読ください。

最後に

本稿を執筆したのは、ひとえに筆者が苦しかった 2 月を締めくくるためです。これでようやく筆者の 2 月が終わるのです!長かったようで短かった 1 ヶ月間でした。楽しい 1 ヶ月でもありました。そして余興は自分に「まだ私には出来ないことがたくさんある」という漠然とした課題意識を残してくれました。今後も精神的・肉体的な健康を保ちながら精進を続けたいと思います。とりあえず直近は Web セキュリティ関連でいくつか出したいネタがあるので、少しずつ今年も放出していけたらと考えています。面白いほど CPU 実験とはレイヤが違う世界の話ではあるんですが、今年も元気に器用貧乏芸人をしていきたいと思います。

ここまで書ききった今となっては、まさかこんな長文を最後まで読んでくれている人はいないだろう、という気分になっているのですが、この駄文が後輩各位、あるいはその他の RISC-V 愛好家の方の参考になるものであったのであれば、それに勝る喜びはありません。20er の皆様、CPU 自作を趣味とする皆様、そしてこれからこの沼に飛び込もうとしているそこのあなた(!) が、楽しい CPU 自作ライフを送れますように。

(画像は使用した FPGA ボードである KCU105 と、よくわからないけど地下にいた Linux っぽいペンギンの画像です) KCU105 と地下にいた Linux っぽいペンギンの画像

謝辞

まず余興班の 3 人には大変お世話になりました。彼らなしでは発表会に間に合わせられなかったと思います。本当にありがとうございました。

また msyksphinz さんのブログ記事には非常に助けられました。基本的に英語のドキュメントを読んでいたのですが、時折 (というかしばしば) 見かける日本語記事には勇気づけられましたし、何より丁寧に解説されていたので非常に参考になりました。ありがとうございました。

そして IS の先輩や TSG 各位にも大変お世話になりました。皆様のおかげで色々な沼を回避することが出来ました。また特に余興をしていた IS の先輩方には勇気付けられましたし、今回のテーマ設定は皆様の偉業(!)があってこそのものです。ありがとうございました。

紹介

他の 19er のブログもぜひ読んでください。面白いので。

  1. もっとも私の記事を読むのは主に弊学科に近い方々でしょうから、特にこのような断りを入れる必要もないだろうとは思うのですが、念の為。 

  2. ところでこういう余興やっている人ってみなさん TSG 部員でびっくりするな。僕も TSG 部員 (自称) です。 

  3. 2 年夏学期までは教養学部に所属するので、情報系の授業は基本ありません。 

  4. 私は日本語ラップが昔から好きで、日頃からよく聴いています。実験の期間中は LowPass のアルバム『Mirroz』、PUNPEE さんのアルバム『Modern Times』、RHYMESTER のアルバム『ダーティーサイエンス』あたりをメインでループしつつ、夜外を歩くときには JJJ さんの作品や Kid Fresino さんの作品(つまり元 Fla$hBackS のラッパーたち。R.I.P. Febb) を聴き、気合を入れたい時には AKLO さん ZORN さんの合作を聴いたりしていました。この二人に関しては最近 MV が出た 2 作 (これこれ) も dope でしたね。あとはたまにキミドリの作品『自己嫌悪』を聞きながらぼうっとしたり、KEN THE 390 さんや SKY-HI さんの作品を聴きながらご飯を食べたりしました。最近 M ステに出てた chelmico さんの作品も時も聴いてました。どれも私の人生観に非常に大きな影響を及ぼした作品たちであり、かつ心から好きな作品たちです。あと日本語ラップシーンでは今もなおフリースタイルバトルの流行が続いているわけですが、この時期毎日一本ずつ公開されている凱旋 MC バトルの動画は継続して見ています。だいぶ意味不明な脚注になってしまったけれど、脚注ってなんでも書いていい場所ですよね?そうだと思います。 

  5. 物書きについては今後また皆さんにご報告できる日が来ると思うので、その時はまたよろしくお願いします。 

  6. CPU 実験を始めたころ元々 OS の一般論については 加藤先生の学部三年夏学期の講義と Silberschatz, Galvin, and Gagne の Operating System Concepts なる教科書で多少学んでおり、Linux カーネルやベアメタルな hoge については大学の演習で少し遊んだことがある程度でした。またハードウェア (特に CPU) については学部二年冬学期にハードウェア構成法なる講義を受講していたのと、パタヘネとヘネパタを雑に読み通したことがある程度です。当然ながら研究ができるほどの知識はありませんでしたし、今もありません。 

  7. ライセンス的に怪しいものはないはずなのですが、もしなにかあれば 私の Web ページ にある連絡先までご一報ください。 

  8. なお余興ではなく、レイトレーシングのために実装したコアは、5 段パイプライン + 2 bit 分岐予測を搭載したものでした。まあ割り込みも何も起こらないことを考えると、これは非常に容易であると言えます。寝ぼけた頭で実装したためにフォワーディングを盛大にバグらせるなどはしましたが、それは内緒です。なおレイトレの記録は 48 秒ほどで、他班に比べて非常に劣るものでした。情けない。 

  9. 2 月中に人と会うたびに「元気なくない?」と言われてしまった気がして、ちょっと情けない。 

  10. ただこれは 20er の皆さんに向けてなのですが、余興に関しては、あまり過去の代と張り合うことにこだわらないのことをオススメしたいと思います。余興などという「やらなくてもいいもの」を満足行くまでやりきるためには、自分のやっていることを心から楽しいと思えることが非常に大切です。私は冒頭で「過去の先輩がやっていないことをやりたいと思った」という趣旨のことを書いていますが、これは一つの価値観に過ぎません。高速化然り余興然り、のびのびと自分の好きなことを深堀りできるというのが CPU 実験の良いところだと思っているので、ぜひワイワイやっていってください。 

Written on February 28, 2020