スマホの中で作っていたカーネルを、自宅のサーバーへ引っ越した

当時の開発ログを見返しながらのメモ。

8/12、p-kernel の開発場所を引っ越した。引っ越し元はスマホの中。

■スマホの中の Linux

それまでは Android スマホの Termux の上に Ubuntu を載せて、その中で開発していた。
PRoot という仕組みで、システムコールを横取りしてファイルの場所などをごまかすことで、root 権限なしで Linux の環境をまるごと動かせる。CPU は ARM の64ビット。
AI と一緒にこの中でカーネルを書いて、ビルドして、QEMU で動かしていた。

■スマホで Android アプリを作る遠回り

Android のビルド道具(NDK)は x86_64 向けしかなく、ARM のスマホでは動かない。
x86_64 の実行ファイルを1個ずつシェルスクリプトで包んで、qemu-x86_64 経由で動かした。

qemu-x86_64 -0 "$0" -L /usr/x86_64-linux-gnu "$0.real" "$@"

スマホの中で PC の CPU のまねをさせながら、スマホ用のアプリを作っていた。なかなかの遠回り。
通るまでに罠を11個踏んでいて、記録には「1個ずつ踏んで約90分」とある。6月には APK のビルドが約6分で通るように。

■スマホではできないこと

・裏で長く動かしたプロセスが殺されるので、何台かをつなぐ試験が動かせない
・ネットワークの名前空間が作れない
・受信バッファの上限が読めない
・ThreadSanitizer(スレッドの競合を探す道具)が動かない

なので6月後半からは、自宅の小さなサーバー(x86_64)にコードを送って、本番に近い試験だけそっちで回していた。
最初に回した日に、p-kernel の中の2つの機能が同じポート番号を使っていて、片方の通信がもう片方に食われる、という本物のバグが見つかった。スマホの中の試験ではどうやっても見えないやつ。

逆に、スマホ専用の設定をうっかりコミットして、ほかの環境のビルドを黙って壊したこともある(7/12 に修正)。

■引っ越し

7/12 を最後に開発は1か月止まっていた。再開のタイミングで開発そのものをサーバーに移した。

やったことは地味。スマホ側に push していないコミットや stash が残っていないかを確認して、サーバーに GitHub から clone し直し、x86_64 向けのビルドが通るのを確認しただけ。

git のログを見ると、引っ越しの境目がタイムゾーンで分かるのがちょっと面白い。スマホの中の環境は UTC だったので、8/12 のお昼から +0900 に変わっている。

2026-08-12 03:50:49 +0000  スマホから最後の push
2026-08-12 13:22:24 +0900  サーバーで最初のコミット

移ったその日に QEMU で170回起動してクラッシュを数える測定も回していて、1か月以上気づいていなかったバグが見つかった。これはまた別で。

※リポジトリ: https://github.com/monyuonyu/p-kernel

※この記事は、p-kernel の開発を手伝ってもらっている AI(Claude)と一緒に書いています。

OS部のサイトが消えていたのでアーカイブから復活してみた

学生の頃に入っていたOS部のWikiです。久しぶりにリンクを踏んだら、ドメインごとなくなっていました。

Internet Archive と Common Crawl から、できるだけ復旧してみました。→ OS部(保存版)

自分はほとんど見るだけでしたけど、消えちゃうのは悲しいので、完全に消える前に復旧しときました。

ヒデさん、アリスさんに感謝。

超久しぶりにブログを復活させました

超久しぶりにブログを復活させました。

前のサーバーが壊れてしまってそのままになっていたのですが、たまたまバックアップが残っていたので、復活させてみました。

何年ぶりの投稿になるのか、もう分かりません。

またちょっと、自分用の備忘録として使っていこうかなと思っています。気が向いたときに、少しずつ。

(追記)ブログが止まっていた間も、自作OS の p-kernel はちょこちょこ触っていたので、そのときの開発ログを見返して「p-kernel 開発記」にメモとして残しています。なので、この記事より前の日付の開発メモがあります。

Windows 用の .exe が作れるようになった

当時の開発ログを見返しながらのメモ。

7/5、p-kernel を Windows のネイティブな実行ファイル(.exe)としてビルドできるようになった。WSL ではなく、Windows そのものの上で動くプログラム。
ビルドは Linux 上で mingw-w64。3日前に載せ替えたばかりの μT-Kernel 3.0 に、Windows 用のターゲットを1つ追加。

■タスク切り替えは Fiber に任せた

Linux 版や x86 版では、タスク切り替えをアセンブラで手書きしている。
Windows には Fiber(切り替えを自分で決められる軽いスレッドのようなもの)があるので、タスク1つにつき Fiber を1つ作って、切り替えは SwitchToFiber を呼ぶだけ。スタックもレジスタも Windows が面倒を見るので、手書きのアセンブラが要らない。書かなければ間違えようもない。

困ったのは、Fiber は自分自身の再開位置を書き換えられないこと。タスクを最初からやり直すときは、古い Fiber をいったん「墓場」に置いてあとで消すようにした。

■最初の版は協調型

Linux 版はシグナルでタイマ割り込みの代わりをしているけど、Windows 版の最初の版にはそれが無い。タスクが自分から手放したときだけ切り替わる協調型。起動時にそのことを表示するようにした。

[win] cooperative scheduler (no preempt in v1)

ネットワークは、BSD ソケットの呼び出しを Winsock に読み替える薄いヘッダをかぶせて済ませた。脳の部分には触っていない。

■LLP64 の罠

64ビットの Linux だと long は8バイトだけど、64ビットの Windows だと4バイトのまま(LLP64)。
メモリを配る処理がポインタを long にしまっていたので、Windows ではポインタの上半分が消えていた。3日前に Linux で踏んだ64ビットの罠に、別の形でまた引っかかった…
ポインタと同じ幅の型を用意して修正。ほかの環境では今までと同じ型になるので、既存の版の機械語は1バイトも変わっていない。

■メモ

この日できたのは、正しい形式の .exe が作れるところまで。作業環境には Windows も wine も無かったので、起動するかは実機で確認が必要(とコミットにも書いてある)。
1週間後に「毎回 .exe がビルドできること」を自動テストの必須項目にした。ただ、起動の確認はまだしていない。次は実際の Windows で試したい。

※リポジトリ: https://github.com/monyuonyu/p-kernel

※この記事は、p-kernel の開発を手伝ってもらっている AI(Claude)と一緒に書いています。

カーネルの芯を μT-Kernel 3.0 に載せ替えた

当時の開発ログを見返しながらのメモ。

7/2、p-kernel の芯を micro T-Kernel 2.0 から μT-Kernel 3.0 に丸ごと載せ替えた。
3.0 は IEEE 2050 として国際標準になった版で、TRON フォーラムがソースを公開している。

■やり方

公開ソースを手を加えずにそのまま取り込んで、p-kernel 側の変更は上に小さなパッチとして重ねる。あとで上流と見比べやすいように。

移す順番はデバッグしやすいところから。
Linux 上のプロセス版(x86-64)→ Linux 上の ARM 版 → x86 ベアメタル → ARM ベアメタル。全部そろったところで 2.0 を削除。

■LP64 の罠

最初の Linux 版でいきなりスタックが壊れた。
原因は 3.0 の memset。unsigned long 単位で書き込んでいるのに、残りの長さは4ずつしか減らしていない。
μT-Kernel はもともと32ビットマイコン向けなので unsigned long は4バイトで問題ないけど、64ビットの Linux だと8バイト。頼んだ量の約2倍を塗りつぶして、呼び出し元のスタックを壊していた。
ポインタを32ビットの型に変換して上半分が消えている箇所もいくつかあったので一緒に修正。

■ほかにも

・x86 版:タイマ割り込みがいつまでたっても来ない。割り込みマスクを外す関数は引数をレジスタで受け取るのに、呼ぶ側はスタックで渡す宣言になっていて空振りしていた
・ARM 版:4バイトの変数に8バイトのゼロを書いて、隣の変数まで消していた。これは自分たちのコードに前からあったバグ

■脳の部分は差分ゼロ

最終的な変更は702ファイル。分散して動く脳の部分(arch/common)は1行も変わっていない。

わざと変えたのは1つだけ。crown の確認に使っているカーネル本体の機械語は、芯が変わったので当然変わる。新しい値を4回別々にビルドして同じになるのを確かめてから基準を更新した。crown をわざと更新したのはこれが初めて。

取り込む直前にもう1つ。「全4ターゲット通過」のはずが、新しい GCC(14以降)だとエラーになる箇所が3つあった。古いコンパイラでしか確かめていなかった…

■後日談

8月、x86 版がまた時々落ちていることが判明。
6月に苦労して入れた kill 対策(タイマの修正など)が、2.0 のファイルと一緒に消えていた。修正を 2.0 側に直接書いていたので、2.0 を消したときに道連れに。3.0 の作りに合わせて入れ直した。

※リポジトリ: https://github.com/monyuonyu/p-kernel

※この記事は、p-kernel の開発を手伝ってもらっている AI(Claude)と一緒に書いています。