いもとりのページ
ホームに戻る一般
どうでもいいことを好きなだけ書く場所です。
まあ、開発の話がほとんどになるでしょうけど...
目次
- 2025/06/15 OS自作8
- 2025/06/08 OS自作7
- 2025/06/01 OS自作6
- 2025/05/26 OS自作5
- 2025/05/20 OS自作4
- 2025/05/16 OS自作3
- 2025/05/11 OS自作2
- 2025/05/07 OS自作1
- 2025/05/06 OS自作をしよう(唐突)
- 2025/01/04 今日も今日とて京都へ
- 2024/12/14 ProjectCの進捗 対戦編
- 2025/06/15 OS自作8
- 2025/06/08 OS自作7
- 2025/06/01 OS自作6
- 2025/05/26 OS自作5
- 2025/05/20 OS自作4
- 2025/05/16 OS自作3
- 2025/05/11 OS自作2
- 2025/05/07 OS自作1
- 2025/05/06 OS自作をしよう(唐突)
- 2025/01/04 今日も今日とて京都へ
- 2024/12/14 ProjectCの進捗 対戦編
メモリ管理を実装します。
私の中で、メモリ管理はOS最大の役目だと考えています。
なぜなら30年ITエンジニアやってる人に「OSは基本メモリ管理しかやってねえんだよ」と言われたからです(思考放棄)
実際、ちゃんとメモリ管理をしてやらないと、使用中の領域に関係ないデータが書き込まれたりして大変です。
ここで久しぶりにメモリマップの登場です。1か月ぶり?
メモリマップの情報はUEFIが持っているので、KernelMainの引数にとってやれば問題ありません。
メモリマップの構造体を用意し、それのポインタをKernelMainで渡し、表示させる...という流れですね
表示させるとこんな感じ
OSは命令に応じてメモリ領域を割り当てたり、使用中の領域を避けたりしてメモリを管理します。
UEFIにはメモリ区画の用途に応じてメモリタイプが定義されており、これをチェックすることで空き領域かどうか判断します。
画面に書かれているtype3, 4はUEFIを抜けたら自由に使っていい領域。7はOSが自由に使っていい領域です。
これら3つだった場合、使用可能だと判断するIsAvailable関数を用意します。
データ構造をOSが所有するメモリ領域へ移動させます。
移動させるのは、プログラムの実行に使うスタック領域、メモリを区画に分けるGDT(Global Descriptor Table)、メモリを固定長に分割するページテーブルの3つです。
これらのデータ構造は、起動時にブートローダ専用データ領域(kEftBootServiceData)、番号で言うと4番ですね。
さっき言った通り、4番はIsAvailable関数が使用可能と判断します。つまり、この領域は他のデータに上書きされる可能性があるのです。
なぜここを使用可能メモリと扱ってしまったのか、コレガワカラナイ。
3つも解説してたら長くなるので短めに
まずはスタックを移動させます。
レジスタのひとつであるRSPには、スタックの先頭アドレス(8バイト)が入っています。
スタックはアドレスの上から下に積まれるため、Pushする度にRSPはどんどん小さくなります。
何が言いたいのかと言うと、RSPの初期値をメモリ領域の末尾に置けばいい、という訳です。
カーネルのプログラムに新しいスタック領域となる配列(要素数1024 * 1024)を用意してあげましょう。
次はセグメンテーション。
セグメンテーションに必要なデータ構造はGDTで、ディスクリプタという8バイトのデータ構造を並べた配列です。
GDTは、SegmentDescriptorを要素として3つ持つ配列を、グローバル変数gbtとして宣言します。
セグメントディスクリプタの構造体を用意し、この構造体に値を設定しGDTを再構築する関数SetupSegmentsを実装します。
0番目に0、1番目にコードセグメントディスクリプタ、2番目にデータセグメントディスクリプタに設定してLoadGDT関数を呼び出せば、変数gdtをCPUに登録できます。
LoadGDTでは、アセンブリでlimit(GDTのバイト数)とoffset(GDTの先頭アドレス)の10バイト分の領域をlgdt命令で受け取り、その値をGDTR(GDT Register)に設定します。
GDTRが切り替わったら終わりではなく、隠し領域にセグメントディスクリプタが残っています。
これはGDTRを書き換える際の不具合を防いでくれますが、最終的にこの部分も書き換えます。
セグメンテーション、本当はもっと複雑な手順を踏んでいるのですが、まともに理解できる内容ではないのでここには書きません。いや、書けません(これを書くのに休日が半分消えている!)
さいごにページング。
仮想アドレスと物理アドレスを変換する機能を持ち、やろうと思えば複雑な変換もできます。
今回はシンプルな物理・仮想ともにアドレスを一致させるアイデンティティマッピングができるようにします。
ここまで理解するまでに時間が掛かったことが気に入らず、何度も本で顔を叩き続けたせいでページが破れそうです。
ページングは4層になっており、ページマップレベル4テーブル(PML4table)、ページディレクトリポインタテーブル(PDPtable)、ページディレクトリ、ページテーブルという構成になっています。
この構成を実装し、PML4テーブルの物理アドレスをCR3レジスタに設定すれば、用意した階層ページング構造が使えるようになります。
これでようやく下準備も終わり、メモリ管理の実装が始まります。
メモリマネージャは書籍では、ページフレーム(物理アドレス上の区画)を1ページフレームあたり1ビットで管理する方式である、ビットマップを採用しています。
BitmapMemoryManagerクラスで実装するのは
・1ページフレームを1ビットで表したビットマップであるalloc_map_
・何もしないとメモリマネージャが物理メモリは無限にあると勘違いするため、メモリ割り当てを行う範囲を決めるrange_begin_とrange_end_
・初期状態ではメモリ領域全体を未使用と判定するため、使用中の領域を伝えるMarkAllocated関数
・ビットの読み書きを行うGetBitとSetBit関数
・メモリ割り当てと解放
最も大事なのはメモリ割り当てと解放ですね。
メモリの割り当て方には、指定されたメモリの要求量以上の未使用領域を探索し、その位置を返すfrist fitという方法があります。
書籍ではこれをAllocate関数として実装することになります。
割り当てるページフレームの数を渡して、range_begin_から探索し、見つかり次第その領域を使用中にし、先頭アドレスを返します。
また、Free関数は指定したフレームの範囲を返却します。
メモリ管理、OS自作でも特に難しい要素でした。
次回は重ね合わせ処理を実装していきます。
x86-64アーキテクチャでの割り込みを実装します。
低レイヤに限らずとも、ソフトウェア開発者なら誰もが耳にするであろう割り込み(Interrupt)
かなり削って説明すると、イベントが発生した際に、ハードウェアがOSに通知し処理する、というものです。
前回はポーリングで常にマウスの状態を監視していましたが、マウスは不定期に動作するため監視し続けるのはCPUの無駄使いになります。
割り込みではマウスが操作されたときだけイベントを発生させるため、ポーリングと比べると効率が良いです。
そして何より、今後他の周辺機器やシステムコールが増えても、CPUを無駄なく使えるからですね。
割り込みを行うには、イベント発生時の処理である割り込みハンドラを書く必要があります。と言っても、気にするべきはたった2つ。
・関数の定義の前に __attribute__((interrupt)) と書くこと。
→コンパイラに割り込みハンドラと認識してもらうため。
・割り込みハンドラの最後にEnd of Interruptレジスタに0を書き込むこと。
→割り込みが終了したと伝えるため。こうしないと次の割り込みハンドラが呼び出されない。
レジスタと言っても、CPUではなくメモリの一部(1024バイト)をレジスタとして使用している。
割り込みベクタについても。
まず、割り込みは色々あります。
外部割り込み(入出力、タイマー...)、内部割り込み(ゼロ除算、不正なメモリ書込み...)、これらをただの割り込みと一括りにするのは愚かです。
そのため、割り込みの種類に応じて番号を割り当てる...これが割り込みベクタです。
しかし、番号を割り当てるだけではいけません。
割り込みベクタに対応する割り込みハンドラを割り当てなければなりません(あと何回、割って書けばいいんだろう...)
N番の割り込みが発生したら、この割り込みハンドラを実行する...という情報が必要になります。
この関係を表にしたのがIDT(Interrupt Descriptor Table)、割り込み記述子テーブルです。
0~255までの割り込みベクタと、割り込みハンドラのアドレスが対応しており、これにより異なる割り込みハンドラを呼び出すことができます。
ここまでで割り込みが発生してから実行されるまでの実装はできました。
しかし、肝心の割り込みが発生する部分ができていません。
xHCIでの割り込み発生には、MSI(Message Signaled Interrupts)を利用します。
特定のメモリアドレス(Message Address)に32ビットの値を書き込み、CPUに割り込みを通知する、という流れです。
Message Addressには、割り込みを通知するCPUコアの番号や、割り込みベクタ番号などを指定します。
これで割り込みが発生してくれます。
ここまでの仕組みは複雑に見えますが、流れさえ分かれば処理のイメージがしやすいと思います。ちなみに私はイメージできません。
これで割り込みは完成...ではありません。
今のままでは、割り込み処理が長引いた場合、他の割り込みを取りこぼす可能性があります。
そのため、割り込みハンドラの高速化を行いましょう。
書籍では、割り込みが発生したことを記録するキューを用意し、そこから取り出して...を空になるまで繰り返す方法を実装します。
キュー(Queue)とは、先入れ先出し(FIFO)と呼ばれるデータ構造で、配列などの先頭からデータを順に格納(Push, Enqueue)し、先頭から取り出す(Pop, Dequeue)、という2つの操作でデータを管理します。
キューが用いられる場面として、プリンターの印刷ジョブやネットワーク通信、テトリスのネクストなどがあります。
キューについて長々と話すのも趣旨がズレるので、使う際の注意点だけ確認しておきます。
それは、キューの操作中にCPUの割り込みフラグを0にしておくことです。0の間、CPUは外部割り込みを受け取らなくなります。
こうしないと、別の割り込みが発生した際に、キューが想定と異なる操作が行われ、データ競合が起こる可能性があります。
最後に、キューの操作が終了したら割り込みレジスタを1に戻してあげましょう。
見た目は変わりませんが、やや動作が軽くなったような気がする??
ちょっと駆け足になってしまいましたが、これで割り込みは完成です。
割り込みはかなり重要な処理なので、本当はもっと詳しく書くべきなんでしょうが、今の私にはこれが限界でした。
次回はメモリ管理を行います。
マウスに対応させます。
まずはカーソルだけ表示させましょう。
二次元配列にマウスカーソルの絵を格納します。
このとき配列の要素数は、Null文字を格納するために横幅を1つ多めに確保する必要があります。
ついでに長方形を描画する関数も用意されていたので、OSらしく画面を少し手を加えてみましょう。
ここからが本番?
USB(Universal Serial Bus)、多分この世で最も有名なシリアル通信規格に対応させます。書籍ではUSB 3.xへの対応を目指します。
そもそもシリアル通信とは、一本の信号線を用いた通信のことで、パラレル通信の対になる存在です。
かつてはパラレル通信で一度に多くの情報を送るのが強力とされていましたが、通信の整合性を取るのが難しいという欠点があります。
だから、1本の線だけで済むシリアル通信の方が一般的になったんですね。
有名どころとしてUARTやSPI、modの名前みたいなI2Cなんかもあり...と、大して詳しくもないのに語ってボロが出ても嫌なのでこれくらいで。
ついにUSBドライバの実装を...と思いましたが、書籍には著者が用意したドライバを使ってとしか書かれていません。
察してはいましたが、USBドライバの実装はあまりにも過酷とのことで、解説すら載っていません。
コードはあるので、試しにドライバがどのように実装されているのか確認したのですが、理解するには永遠より永い時間が必要そうです。
(さっきシリアル通信の話で時間稼ぎしてたのは、ここで書くことがないからなんですね、はい)
一番重要そうな所をすっ飛ばす羽目になりましたが、次へ行きましょう。
PCI(Peripheral Component Interconnect)という規格をご存じでしょうか。私はPCO(Perfect Clear Opener)しか知りません。
これは周辺機器とマザーボードをと通信するための規格で、現在はPCIeという後継規格もあります(互換性あり)
PCIバスに接続されているPCIデバイスを読み込み、USB3.xのホストコントローラの規格であるxHCI(eXtensible Host Controller Interface)に準拠したxHCを探索します。
ここでのOSの役割は、PCIコンフィギュレーション空間という256バイトの領域を読み取り、どのようなデバイスが接続されているかを把握します。
ここではっきり言わせてください。私はもう何が起きているのか全然分かりません。
こんな調子では、自力で基本ソフトウェアの設計なんて夢のまた夢です。
ハードウェアに弱すぎるが故(あたかもソフトなら分かるかのような発言)に、どうも理解に時間が掛かりそうです。
とにかくマウスの実装を進めましょう
ポーリングでマウスの動きを監視します。
ポーリングは常に周辺機器の状態を監視するので、マウスのようなデバイスでは効率が悪いとされていますが、一旦これで実装することになります。
こちらもまたコードが複雑ですが、どうにか流れだけでも追ってみます。
まず、PCIからxHCを探すところからです。PCIが認識できる限界までループして探索します。
見つけたxHCを初期化し、動作を開始させます。動作が開始すると、PCに接続されたUSBデバイスを認識します。
USBマウスが認識されたら、今度はマウスからデータを受信し、マウスを動かした分だけ画面上でも動かします。
実際に動かしてみると...
ようやく動いたかと思えば、移動後の塗りつぶしが悪さをしてこのザマです。
これは書籍の内容を進めれば改善されるのですが、しばらくはこの状態になりそうです。
なんとなく、どう改善するのかは分かるような気がします、読んでないから知らんけど。
次回は割り込みの実装を行います。
文字の描画をやっていきます。
前回使用したピクセルを描画する関数を利用&文字データを用意して描画します。
どう文字データを実装するのかと思ったら、まさかの配列に8ビットデータを突っ込む形でした。
書籍では"A"だけ描画するサンプルがあります。
さすがにこれを全部作るのは過酷なので、東雲フォントを使用することになっていました。
こちらを読み込ませると、無事に文字が使えるようになります。
文字列を引数で渡して描画する関数も用意します。
他にもprintfのような書式整形付きの関数も欲しいですが、標準ライブラリのNewlibから、sprintfで代用することに。
NewlibはOSの依存度が低いらしいですが、その代わりに動的メモリ管理や入出力周りの一部は自分で実装しなければなりません。セルフサービスです。
Newlibのヘッダーファイルをインクルードして、sprintfを使うと、書式整形付きの文字列が描画できるようになります。
まだまだやります。
Linuxではカーネルコンソールに出力する関数であるprintkを模した関数を作ります。
こちらも可変長の引数を受け取る関数で、printfと同じように書式整形ができるようになっています。
これがあれば、ログ出力も容易になり開発が楽になることでしょう。
次回はマウス入力を実装します。
makeだったり描画だったりをやっていきます。
書籍にあるmakeのサンプルを実行しようとしたのですが、インクルード出来ねえよハゲと一蹴されてしまいました。
これも前回と同じくIssueが立っていたので、そちらを参考にして実行できるようにしました。
Makefileは完全に初見ですが、これを機に書き方だけちょっと見てきました(本当に見ただけ)
コンパイル時のコマンドをまとめてくれるのは間違いなく便利なので、ここや別の環境でも慣れておきたい所です。
さて、Makefileの話はここまでにして、描画をやってみましょう。
前回まではフレームバッファに直接値を書き込んでいましたが、人間にはあまりにも使いづらいので手を加えます。
UEFIにはピクセルデータを扱う規格が4つもあるのですが、書籍ではその内の扱いやすい2つを利用します。
1つはRGBと座標を指定してピクセルを描画し、もう一つはBGRを指定します(順番変わっただけでは...?)
歴史的な理由でBGRもあるらしいですが、個人的にRGBの方が分かりやすいのでそちらを使います。
・Graphics Output Protocol
UEFIが提供するグラフィック描画プロトコル
今回はPixelRedGreenBlueReserved8BitPerColorという規格を使用します。
光の三原色でおなじみのRGB(+予約領域 or αチャンネル)を8ビットずつ使うフォーマットです。
この規格は最も描画が楽で、ピクセル単位で1つずつ色を付けていきます。
中には、一度にバッファに情報を格納してから、一気に描画する方法もありますが、実装がとても大変と聞いているためやってません。
早速main.cppに描画用クラスを用意し、そこに座標や色を指定して描画できるメンバ関数を実装します。
書籍に緑色の長方形を描くサンプルがあったので、これを実行してみます。
無事に描画されましたね。
せっかくなので、私も何か描いてみましょう。
私がよく使っている山岳積み二号です。
どう考えてもこんなのやってる暇ねえだろというツッコミは受け付けておりません。
次回は文字の描画を行います。
ブートローダやカーネルを作成していきます。
・カーネル
ハードウェアの資源管理、ハードウェアとソフトウェアを仲介するプログラム
UEFIの規格通り作る必要があるが、ブートローダーからカーネルを呼び出す形式にすることで、その制約を回避します。
コマンド例(Clang++ & LLD)
$ clang++ -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone -fno-exceptions -fno-rtti -std=c++17 -c main.cpp
ld.lld --entry KernelMain -z norelro --image-base 0x100000 --static -o kernel.elf main.o
カーネルを読み込む際は、UEFIのOpen関数でkernel.elfを読み込み、GetInfo関数でファイル情報を取得します。
GetInfoの4番目の引数が特殊で、EFI_FILE_INFO型の構造体が入るだけのメモリ領域を指定するのですが、ただ指定するだけではいけません。
実は、ここにはelfファイルに付けた名前を格納する必要もあり、その名前の文字数分メモリを多めに確保しなければなりません。
今回のkernel.elfはsizeof(CHAR16) * 12バイトだけ多く確保しています。
まずはmain.cppに特に何も起こらないだけのカーネルを書きます。
名前修飾やインラインアセンブラといった初見の要素ばかりですが、この書き方にも少しずつ慣れていかねば。
コンパイルとリンクが終わるとkernel.elfファイルが生成されます。
ブートローダでもカーネルを読み込めるように、Main.cも修正します。
カーネルを配置する番地を指定したり、ファイルを読み込めるようにメモリを確保したりします。
ビルドしてQEMUで起動して、無事に動けば成功です。
このときは気づいていなかったのですが、私がここで作ったカーネルは正常に動作していませんでした。
どうやら書籍では、リンカはLLVM-7の使用を前提としており、LLD10では動作しないようです。
LLVM-7は古いため、Ubuntu20.04にすらデフォルトで入っておらず、わざわざダウングレー
ドしなければなりません。
この件については公式のGitHubにIssueが立っていたため、そちらを参考にしました。
バージョン違いでのエラーは別界隈で慣れていましたが、自作OSでも同じ目に遭うとは...油断しました。
この事実に気づかず私が次にやっていたのは、ブートローダ上で画面を白く塗り潰す命令でした。
こちらは特に問題なく動作します、カーネルを使ってる訳ではないので。
次はカーネルを使って、画面をグラデーションのように塗りつぶす命令を作ります。
しかし、なぜか命令を書いても画面が白いままです。
それもそのはず、あなた、リンカのバージョンを間違えてますよ?
これに気づかず何時間も四苦八苦していました。もう少し早くIssueを見ていれば...。
四苦八苦と言ったら一つネタを思いつきました。
テトリスは、四楽八苦(これが通じる人は、もう立派なTGMプレイヤーです)
そんな冗談はさておき、リンカのバージョンを直してからカーネルをビルドし直すと、ちゃんとグラデーションが表示されました。
最後に、簡易的なエラー処理を実装しましょう。
といっても単純なもので、ブートローダ上でエラーメッセージの表示をするだけです。
あと無限ループを呼び出して無理やり実行を止める感じですかね。
次回は画面に絵を描く命令を実装していきます。
EDK IIやメモリについての話です。最初だから仕方ないけど地味な要素が多い...。
どうやらEDK2(II表記は面倒なので2でいいよね)はUEFI BIOSや、そのUEFI BIOS上で動くアプリの開発ができるとのこと。
開発環境は書籍の付録に付いているGitHubのリンクがあるので、そこからダウンロー
ドすることができます。
・EDK2
EFI Development Kit II、最近色々と話題のIntel製のUEFIファームウェアとかアプリの開発環境。
EDK2のフォルダの中身を見てみると、その中には大量のフォルダが!全部見てたらキリがないです。
大事なのはedksetup.shとMdePkgでしょうかね?
前者はビルド環境をセットアップするためのスクリプトで、後者はUefi.hとかが入ってるフォルダです。
Uefi.hもインクルードの連続で見るのが億劫になります。お前らどんだけヘッダーファイルあるんだ。
他にもLibraryフォルダのUefiLib.hも追っていたら時間がいくらあっても足りません。こっちは1Fも無駄にできないんだ。
一応、書籍の付録にedk2のファイル説明の一部が載っているのですが、正直ここに載せるほどのことは書いていません。気になるなら本買って見てくれ(ダイマ)
・メモリマップ
メインメモリのどこが・何に・どれだけ使われているかを確認できる。
もし既に使われているアドレスにデータを置こうものなら、当然死は免れられません。
ありがたいことに、BIOSにはメモリマップを確認する機能があります。
ブートサービスを表すグローバル変数gBSを使い、GetMemoryMapという関数を呼び出すことで確認できます。
なお、GetMemoryMapは、OSがUEFIの制御を離れる前(ExitBootServicesの直前)に呼ぶのが一般的です。
・UEFI BIOS
Unified Extensible Firmware Interface、Basic Input/Output System
OSを起動するため、つまりブートローダを読み出す機能。
UEFI BIOSとBIOSは別物ですが、今回はUEFIという表現で統一。
細かいことを言うと、UEFIはハードウェアを動かす役割のファームウェアの仕様を定めたものであり、プログラムではありません。
しかしOS作りの素人がこんなのを気にしていては埒があきません。BIOSみたいなもんだと認識させていただきます。
UEFIのプログラムは.efiという形式にして実行されます。適切にコンパイル&リンクしてあげれば生成されます。
コマンド例(Clang & LLD)
$ clang -target x86_64-pc-win32-coff -mno-red-zone -fno-stack-protector -fshort-wchar -wall -c "ファイル名".c
$ lld-link /subsystem:efi_application /entry:"関数名" /out:"ファイル名".efi "ファイル名".o
coff形式で.oファイルを作成 → PE形式で実行ファイル(Windowsの.exeもPE形式)作成という流れですね。
では、EDK2を用いてHello, World!をやってみます。実行結果だけ見たらほぼ再放送です。
Main.cには、EDK2フォルダ内にあるヘッダーファイルをincludeしてからプログラムを書きます。
普段のC言語との違いは、最初に実行されるのはmain関数ではなく、Loader.infファイルにENTRY_POINTという項目があり、そこで設定した名前がmain関数の代わりになる所でしょうか?
あとprintfは使わず、Uefi.hで定義されているPrint関数を使うみたいです。一応printfとほぼ同じ挙動をするのでそこまで違和感はないです。
他にも機能を実装しましょう。今回はメモリマップをcsvファイルに書き込む機能を作ります。
書籍にはコードの解説も載っているのですが、それ以上にポインタの解説が多いです。
やはりポインタは難しいので、著者も念入りに教えておきたいのでしょう...(まずポインタ分からん人は他の内容も大丈夫なのか?という疑問も残りますが)
完成したらビルドして起動します。
ちゃんと起動するまで結構ミスりました...根気がないとやってられん作業ですねえ。
出力されたcsvファイルも確認してみましょう。
アドレスが表示されまくってます。1つくらい勝手に使ってもバレへんかな。
次回はブートローダを作成し、いよいよOS本体にも手を出していきます。
環境構築からHello, World!までを試してみました。
まず開発環境について、最初はWSL2とUbuntu24.04を使おうと思ったのですが、これ
を見る限り非推奨らしいのでUbuntu20.04を別で用意しました。
Ubuntu上にディスクイメージを用意してQEMUで起動する、という流れでHello, World!まで進めます。
C言語でやるのかなと思いきや、最初だけなぜかバイナリエディタで書かされました、飛鳥時代でもこんなんやらんぞ。
作ったバイナリファイルをさっき作ったディスクイメージに読み込ませてから起動すると...
なんとHello, World!が表示されたではありませんか!どうなってんだこれ(無知)
仕組みは追々調べるとして、とりあえず起動は成功です。
次回はUEFI用の開発キット EDK IIを試します。
大学でソフトウェア系の授業を担当している教授が、技術を身につけるための活動をしていると聞いて参加してみました。
参加者は7,8人ほど(しかも全員知り合い)で、自由に何でもやっていい感じの雰囲気でした。
せっかくの機会なので、私は無謀にもOSの自作に挑戦することにしました。
何があっても逃げられないように速攻で内田公太氏の「ゼロからのOS自作入門」を購入。
ここに色々書いているのも逃げ場を塞ぐ一環でございます。
正直なところ、私一人の力だけで完成させられる気がしません。
去年までポインタで苦しんでいたような人間に出来るのでしょうか...?
しかし今回はありがたいことに、心強い味方が大勢います!
電子系・情報系の学生と教授がサポートしてくれるのです。こんないい環境が他にあるというのか。
というか、これだけ協力者がいるのに諦めるのは無理です。裏切るわけにいかん...。
目標としては、2か月以内での完成を目指しています。
今回使う書籍では1か月が目標とされていますが、他のメンバーとの折り合い&これとは別の活動で多忙なため、ある程度余裕は持たせておきます。
果たしてOSは完成するのか? すべては明日の私にかかっている!
本日は高校の友人たちと北野天満宮まで行って参りました。
流石に4日なので人はそこまで多くなかったです。
テトリスが上手くなるのを願って、賽銭は20円にしました。
延命長寿のお守りも買っておきました。Moddedマイクラやテトリスは時間がいくらあっても足りないので...。
近くにうまいラーメン屋もありました。
偏食なので、ラーメン食う時は毎回みそを注文してます。
京都に来たついでにa-choでTGMをしましたが、Shirase S8という残念な結果に...。
次来たときはS12まで行きたいですね。
11月から開発を進めているProjectCですが、3割くらい完成したので報告だけしておきます。
某対戦アクションパズルゲームのような何かですね。
今のところローカル環境でのみ対戦可能。
操作はTGM、対戦はテトエフェ寄りの仕様を目指しています。
RENテーブルはテトリスの歴史を見て、独自のものを使用することにしました。
2~5REN +1今後もテストプレイを重ねてバランス調整しようと思います。
6~10REN +2
11~16REN +3
17~REN +4