NimでOS開発したいねという話

これは自作OS Advent Calendar 2017 の10日目の記事です.遅刻です.

アアアアアすみません!!!!!

では謝罪も終わったところで(こいつ反省してんのか?),Nimで自作OSしたいねーっていう話をしていきたいと思います.

そもそもNimってなによ?

プログラミング言語のひとつで,最近僕が気に入ってるやつです.

Nim - Wikipedia

構文とかはかなりPythonっぽくて,インデントでブロックができます. フィボナッチ数列とかはこんなかんじ

proc fib(n: int): int =
  if n < 2:
    return n
  else:
    return fib(n-1) + fib(n-2)

echo(fib(30))

見た目はPythonっぽいですがintとか出てきてますね.そう,Nimは静的型付け言語なんです.

なんでNim?

さて,ここまで来て「え?そんなPythonみたいなやつどうやってベアメタルで動かすの?mrubyみたいなのあるの?*1」と思われた方もいるかもしれませんが違います.

なんでかというと,そもそもNimはコンパイル言語だからなんですね. コンパイル言語なので,コンパイルするとバイナリが出てきます(それはそう).

しかし,Nimのコンパイル手順はちょっと特殊です.コンパイルしても直接オブジェクトファイルとかは出てきません. じゃあなにが出てくるのかというと,なんとビックリ,C言語のコードが出てきます.面白くないですか?

そのため,Nimをコンパイルしてバイナリを出力する手順は,

Nim ==nimコンパイラ==> C ==Cコンパイラ==> バイナリ

というかんじになっています. コンパイラというよりトランスパイラに近いのかも.

Cだけではなく,C++/Objective-C/JavaScriptなどにも変換出来るらしいですね.すごい.

では,実際どんなかんじなのか,まずはちょっと普通に使ってみましょう.

nim-lang.org

ここの記事そのまんまなのでインストールは割愛します.

では,初めににハローワールドしてみます.

echo "Hello, World!"

これをhello.nimというファイルに保存します. で,コンパイル言語なのでコンパイルして実行形式のバイナリを作ることができます.

$ nim compile hello
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: system [Processing]
Hint: hello [Processing]
CC: hello
CC: stdlib_system
Hint:  [Link]
Hint: operation successful (10984 lines compiled; 1.404 sec total; 17.938MiB peakmem; Debug Build) [SuccessX]

compileオプションはcとしてもOK.((ここをcppとするとC++に,jsとするとJavaScriptに変換出来ます))

これで,helloという実行形式バイナリが出来ました.

$ file hello
hello: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=184748d3c78ff375408fdf598d6217f3256f5721, not stripped
$ ./hello
Hello, World!

しかし,先程書いたように,Nimは直接バイナリなりアセンブリなりは吐かず,代わりにCコードを生成します. そのCコードはどこに行ったのかというと,nimcacheというディレクトリの下に生成されています.

$ ls ./nimcache
hello.c  hello.json  hello.o  stdlib_system.c  stdlib_system.o

hello.c,stdlib_system.cというCコードが生成されていて,それをCコンパイラコンパイルしたhello.o,stdlib_system.oというオブジェクトファイルが出来ているのがわかります*2

stdlib_system.cは共通のAPIラッパーみたいなやつなので,生成されたプログラムの本体はhello.cです.

hello.cを見てみると,ちょっとゴチャゴチャしています*3

int main(int argc, char** args, char** env) {
        cmdLine = args;
        cmdCount = argc;
        gEnv = env;
        NimMain();
        return nim_program_result;
}

main関数はこんな感じです. コマンドライン引数とかをグローバル変数にとっておいて,NimMainという関数を呼び出しているだけですね.

...と思ったら,んんん!?main関数に3つ目の引数がある!?

調べてみたら,ここから環境変数が得られるらしいですね.初めて知った...

moge32.jugem.jp

じゃあNimMainはどうなってるのかというと,PreMainやらinitStackBottomWithとかいう関数を呼んだ後,NimMainInnerという関数が呼ばれ,そこからNimMainModule を呼んでいます.

STRING_LITERAL(TM_xLHv575t3PG1lB5wK05Xqg_2, "Hello, World!", 13);
〜〜〜
NIM_EXTERNC N_NOINLINE(void, NimMainModule)(void) {
        nimfr_("hello", "hello.nim");
        nimln_(1, "hello.nim");
        printf("%s\012", ((NimStringDesc*) &TM_xLHv575t3PG1lB5wK05Xqg_2)? (((NimStringDesc*) &TM_xLHv575t3PG1lB5wK05Xqg_2))->data:"nil")
;
        fflush(stdout);
        popFrame();
}

ゴチャゴチャはしていますが,printf"Hello, World!"を表示しているのが分かります. この関数が変換されたNimコードの本体のようです. なので,生成されたCコードを確認したくなったらここらへんを見ましょう.

というわけでやってみる

さて,これでNimがちゃんとCに変換されてprintfで文字列表示をしているのが分かりましたが,本題はここからです. 本題は何だったかというと,NimでOSを作りたいんです. 要するにNimをライブラリとかが全然ない環境でも動かしたいんです.

じゃあどうすればいいか?ここまでくれば簡単ですね. Nimコンパイラが生成したCコードで呼び出している基本的な関数を専用のやつに置き換えてしまえばいいんです!

とはいっても,printfやらputsをいちいち作るのは面倒なので,もうちょっと楽な手段を使います. 実はNimは,デフォルトでCに変換するだけあって,Cとの連携がしやすくなっています.具体的に言うと,インラインアセンブラみたいにCが直接書けたり(emit),Cの関数をNimの関数として呼び出すことが出来ます.

Nim Backend Integration

詳しくは公式のドキュメントを見ましょう.

で,こんな感じにやればベアメタルでNimが使えるのでは?と思って試行錯誤してなんとか標準Cライブラリ無しでフィボナッチを計算して出力してみたというのが,以下のリポジトリです.

github.com

しかし,このrepoをよく見てもらえると分かると思うんですが,なんか結構色々やってますね. Cのコードが66%もあります.

何故こんなことになったのかというと,あのstdlib_system.cがかなり曲者でした. 最初はstdlib_system.cを自作して置き換えてやればいいかなあとか思っていたんですが,バージョンによって少しづつ変わるみたいなのと,GCの処理などがあったので弄るのをやめました. では具体的には何をやったのかというと,stdlib_system.cでincludeしているstdio.hとかのヘッダを自作して,そのうちの必要な関数をちまちまと実装しました. そして,標準Cライブラリを使っていないので,アセンブラでwriteシステムコールのラッパーも書きました.*4

まあ手抜き実装なので,エラーが発生したときに呼ばれるsignalとかはマクロで虚無に書き換えています.

でも,これはあまりにも面倒ではないですか? まあもちろん,mrubyをハイパーバイザに移植とかよりは断然楽なんですが,ここからこれを使ってOSを書いていくとなると,環境構築のコストが高いです. そして,僕が作ったものも手抜き実装なので色々と抜けているところがあります.これならC++やRustでいいじゃん...ってなっちゃいますよね.

Rustとか特に

https://os.phil-opp.com/

とか出てますし.*5

「は?ベアメタルでNimやるのダルすぎ.C++/Rust使うわ」

と思うじゃん???

いやね,僕もそう思ったんですよ. でもね,違ったんですよ. あっ待ってそこの人!まだチャンネル変えないで!ここからすごいの!!! 衝撃の真実はCMの後で!

CM

github.com

えーっと,x86エミュレータを作ってm...作ってるはずです. いや進捗出てなくて申し訳ない,というか学校関連特に夏休みあたりがアすぎたはい僕もやりたいんですよでも時間がえ?時間は無かったら作るもの?それはそうはい作ります!作るぞ!!!(宣言)

衝撃の真実的なsomething(575)

はい,CM終わり(CMか?)

CMが終わったので予告していた衝撃の真実です!!!

結論から言いましょう!!!

先程僕がやったことはすべて無意味です!!!

いやあ,やってて気付いたこととかもあるので個人的には無意味ではなかったので良かったんですが,超絶楽な他の方法がありました.

気がついたきっかけはNimのコンパイルオプションを調べていた時のことです. 適当にスクロールしていたら,"embedded"という文字列を見かけた気がして,見たら,あったんです.

Nim Compiler User Guide

Nim for embedded systems

...え?embedded?組み込み?組み込み向けに使えるの????

The standard library can be avoided to a point where C code generation for 16bit micro controllers is feasible. Use the standalone target (--os:standalone) for a bare bones standard library that lacks any OS features.

え?--os:standalone?なんですかそのいかにもって感じのオプションは!?

色々調べてみたら,CPUとかGCの設定も出来ることが分かりました. また,

using Nim / Nimrod for micro-controllers (embedded) - Nim Forum

を見てみると,

Check out nimkernel for an example of using Nim to program bare metal.

ん?????

github.com

え??????

というわけで,僕がやろうとしていたことは既にやられていたのでした.

そして,このrepoでは僕が先程やっていたようなことはやっていません!

やってみた2

さて,超簡単な解決策が見つかったので,今度こそNimでOS(っぽいもの)を作っていきましょう!

基本的には(nimkernel)GitHub - dom96/nimkernel: A small kernel written in Nimと似たようなかんじでやっていきます.

まずは,main.nimを作ります.

proc main() {.exportc.} =
  return

これがmain関数になります..exportc.というのはこの関数をCの関数にする指定です. このmain関数はブートローダーから呼ばれるので,この指定を付けておきます.

で,あとはさっきの--os:standaloneとかのオプションをつけてコンパイルして色々弄っていけばいいんですが,いちいちコンパイルオプションを打つのは面倒です. こういう時はMakefileを使うのがよくある手ですが,Nimでは他の方法があります. main.nim.cfgというファイルを作って,そのファイルにコンパイルオプションを列挙するだけでOKです. コンパイルオプションは,--os:standaloneの他に,--gc:none,--deadCodeElim:onとかも付けておくと良いです.

あと,デフォルトのmain関数を作らない--noMain,変換後のCコードをコンパイルしたオブジェクトファイルをリンクしない--noLinkingなどもお忘れなく.

では,ちょっとコンパイルしてみましょう.

$ nim c main
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: used config file 'main.nim.cfg' [Conf]
Hint: system [Processing]
lib/nim/system.nim(2708, 11) Error: cannot open '/home/sksat/prog/nim/nim-os/panicoverride'

失敗してしまいました.どうやら,panicoverrideというファイルが無いと言っています.

ここで,もう一度 Nim Compiler User Guide を見てみると,

For the standalone target one needs to provide a file panicoverride.nim. See tests/manyloc/standalone/panicoverride.nim for an example implementation. Additionally, users should specify the amount of heap space to use with the -d:StandaloneHeapSize= command line switch. Note that the total heap size will be * sizeof(float64).

とあります.panicoverride.nimを作らないといけないみたいですね.

とりあえず空のファイルを作ってコンパイルしてみると,

$ nim c main
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: used config file 'main.nim.cfg' [Conf]
Hint: system [Processing]
lib/nim/system.nim(2714, 12) Error: undeclared identifier: 'panic'

panicという関数は必須のようです. 同様に,rawoutputという関数も必要なようなので,とりあえず空の関数を作っておきます.

proc rawoutput(s: string) =
  return

proc panic(s: string) =
  return

で,またコンパイルしてみます.

$ nim c main
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: used config file 'main.nim.cfg' [Conf]
Hint: system [Processing]
Hint: main [Processing]
Hint: gcc -c  -w -w -I$lib -ffreestanding -O2 -Wall -Wextra  -I/usr/lib/nim -o /home/sksat/prog/nim/nim-os/nimcache/main.o /home/sksat/prog/nim/nim-os/nimcache/main.c [Exec]
In file included from /home/sksat/prog/nim/nim-os/nimcache/main.c:10:0:
/usr/lib/nim/nimbase.h:482:13: エラー: 配列 ‘Nim_and_C_compiler_disagree_on_target_architecture’ のサイズが負です
 typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1];
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error: execution of an external program failed: 'gcc -c  -w -w -I$lib -ffreestanding -O2 -Wall -Wextra  -I/usr/lib/nim -o /home/sksat/prog/nim/nim-os/nimcache/main.o /home/sksat/prog/nim/nim-os/nimcache/main.c'

あー,これはターゲットが32bitなのにコンパイルに使用しているgccが64bit向けだから起きてるエラーですね.nimkernelみたいに別のコンパイラを使ってもいいんですが,面倒なので-m32オプションをつけてしまいましょう. Cコンパイラコンパイラオプションを書き換えるのは--passcオプションで出来ます.

$ nim c main
Hint: used config file '/etc/nim.cfg' [Conf]
Hint: used config file 'main.nim.cfg' [Conf]
Hint: system [Processing]
Hint: main [Processing]
Hint: gcc -c  -w -w -I$lib -ffreestanding -O2 -Wall -Wextra -m32  -I/usr/lib/nim -o /home/sksat/prog/nim/nim-os/nimcache/main.o /home/sksat/prog/nim/nim-os/nimcache/main.c [Exec]
Hint: gcc -c  -w -w -I$lib -ffreestanding -O2 -Wall -Wextra -m32  -I/usr/lib/nim -o /home/sksat/prog/nim/nim-os/nimcache/stdlib_system.o /home/sksat/prog/nim/nim-os/nimcache/stdlib_system.c [Exec]
Hint: operation successful (5319 lines compiled; 0.254 sec total; 3.758MiB peakmem; Debug Build) [SuccessX]

--os:standaloneオプションを付けているので,stdlib_system.cでincludeしているのはnimbase.hだけになっています.素晴らしい.

さて,これでmain関数が出来たので,あとはmain関数をブートローダーから呼び出してあげればいいですね.

今回はちょっと遅くなっちゃったのでnimkernelのboot.Sを拝借しました.

boot.Sをアセンブルしてやると,必要なオブジェクトファイルが揃います.

$ as --32 boot.S -o boot.o

後はこれらをリンクして,バイナリを作ります.

$ gcc -T linker.ld -o main.bin -m32 -ffreestanding -nostdlib boot.o nimcache/main.o nimcache/stdlib_system.o

あとはQEMUで起動してみるだけです.((今回はマルチブート仕様に則ったバイナリになっているので,-kernelオプションで起動できます.))

$ qemu-system-i386 -kernel main.bin

f:id:sksat:20171212203420p:plain

まだ何もしていないので何も起こりませんが,無事起動出来ているようです.

...と思ってnimkernelの画面描画のコード持ってきて動かしてみても失敗しました....何故...というかこれmultiboo 2じゃないんですか...

まあ,自分でコード書けってことですね.

あと,nimkernelについてはそもそもビルドが通りませんでした.これについてももうちょっと調べてみます.

ということで不完全燃焼なかんじですが今回はここまでにします.期末試験中だし.

*1:そういうのが気になる人はベアメタル,というかハイパーバイザ上でmrubyを動かしてブイブイ言わせてるchikuwaitさんというガチプロがいるので調べててみると面白いかも?

*2:hello.jsonコンパイル/リンクのコマンドの設定みたいなやつです

*3:自動生成なのでこればっかりは仕方ないですが,かなりマクロを多用しているからです.まあCコンパイラが最適化してくれますし,基本的にこれらの生成されたCコードを見ることはないので良しとしましょう

*4:setjmp/longjmpは面倒だったのでGCCにくっついてきてるやつを使いました

*5:Rustもやってみたいとは思っている

NeoVim使ってみた

Vim好きだけどちゃんと使ってる???

はい,はてブやってくかって思ったのでやっていきます. 今回のはみなさん大好きVim*1のやっていきです.

僕はあいでーいーとかちょっとよくわからない(というか,マトモに動いてくれない)*2ので,プログラミングにはだいたいVimを使ってます.

ですが,今までは生のVimを使っていただけでした. これはVimmerとしてちょっとどうなのかと思われるかもしれませんが,実はマトモに.vimrcを書いたことがないです.

ということで(そろそろ環境ごとにちょいちょい違うのも嫌になってきたので),「Vimをちゃんと使うか」というお気持ちになってきたので,やります.

NeoVim入れてみた

さて,ここで気になってきたのがNeoVimとかいうやつです. ググってたら頻繁に目についたので.

github.com

次世代のVim?かっこいいやんけ使ったろ(適当). Luaとかがデフォルトで入ってるっぽいですね.良さ.

まずはNeoVimのインストールですね.

# apt-get install neovim
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package neovim

は?

はい.デフォルトのaptだと入りませんね. PPAを追加してやるといけますね.

$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:neovim-ppa/stable
$ sudo apt-get update
$ sudo apt-get install neovim

これだとstableですがunstableにしてやると最新版ににるっぽいですね. でも,せっかくなので最新版をビルドしてみます.

$ git clone https://github.com/neovim/neovim
$ cd neovim
$ make CMAKE_BUILD_TYPE=RelWithDebInfo
$ sudo make install

ここでMakeの時に「まけ」と打った貴方は負けです. はい,負けました.

んでもって色々と調べてみてちょいちょい.vimrc書いてたんですが,どうもこの世界には数々の素晴らしいプラグインといふものがあるっぽいですね. で,しかもそのプラグインたちの管理をするプラグインマネージャもあるとか. 良さそうなので入れてみますかね.

闇の力に目覚める

プラグインマネージャにもいくつかあるっぽいのですが,某はオワコンとのことで,dein.vimを導入してみます.

github.com

"Dark powered"...かっこいい...

ところでこの記事をはてブのエディタで書いていたらFireFox落ちて一部原稿が吹き飛びました. 反省して(Neo)Vimで書きます.

はい.

では,闇の力に目覚めていきましょう. なんかQiitaのよくわからん記事見ながらほげほげしてたら失敗したので公式見ながらやります.

$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.vim/dein

こんかなんじにやると,installer.shがいいかんじに最低限必要な.vimrcを吐いてくれるので,.vimrcにコピペします.

あとはNeoVimを起動して,

:call dein#install()

とかしてやればok

と思いきや,ダメでした. 調べてみると,NeoVimにおける.vimrc的な奴は~/.config/nvim/init.vimとのこと. ということで,~/.config/nvim/init.vimにさっきのやつをコピペして,dein#install()してやると,うまくいきました.

というわけでNeoVimの方を使い始めていくので良さげな使い方とかプラギンとかあったら教えていただけると嬉しいです.はい.解散~w

*1:Emacs?なんですかそれは?

*2:スペックが低いんじゃ

最近の進捗(10月)

ひと月に一回くらい進捗記録しておくと良さそうなのでやる.

最近やったこと...なんだろう...夏休みがアだった*1のは覚えてるけど...

あと9月は文化祭がありましたね.夏休みがアだったので準備も割とアだったし色々とアなこともありましたが,うまくいったと思います.後輩も色々やってくれたので来年が楽しみですね.

さて10月の進捗ですが,プログラミング関連ではなんかlibsksatなるものを作ってました. これはなにかというと,C++のヘッダオンリライブラリ的なsomethingで,libslankdevとか,clxとか良さみが深いなあ,と思ってなんかほげほげしてました.

libsksatはなんか良さげ,と思ったクラスやらなんやらをとりあえずぶち込んでいくかんじrepoなので,再利用性があるかとかは微妙です. まあC++とgitの練習場みたいなものと思ってるのでいいんですけど(ブランチモデルとか最近知った顔). 使えそうなのができたらemu*2で使おうかな.

あとなんかあるかな...あった. そうそう,Redmine立ててみました.Herokuに.

HerokuでRedmine · GitHub

前はPFLabのイベントの時にちょまどさんにもらったAzureのサブスクリプションのやつでRedmineVM立てて文化祭とか某で使おうとして全然使ってもらえなかった使ってたんですが,あのときはbitnamiでシュッとやったのでRuby on Railsがどうとかはよく分からないまま使ってました.

で,そろそろサブスクリプション切れるし別の立てるか,みたいなノリで色々調べてやってみたはいいものの,動いたと思ったらInternal errorが多発してなんやお前,となったのでうーんうーんと唸りながらうまくいったやつをgistにまとめてみた次第. 大体rmagicとかDB周りで躓くっぽい.

せっかく立てたので有効活用していきたい(今の所某の別のやつで使ってる). あと,チョットRuby on Railsに興味持ったのでそのうちなんか作ってみようかな(などと

最近の進捗はこれぐらいですかねー(少ない). あとはせいぜいGASでslackにチームドライブの更新通知ぶん投げるやつ作ったり,sksat_botを334とか1333とか1640*3に反応させるようにしたぐらいか.

11月も進捗がnullじゃなければ書く.まあ何も無ければもくもく会のこととか書けばいいか(行ければだけど).

*1:ラボ行く機会なかなか無かったから楽しみにしていたラ某ユース合宿行けなかったのホンマつらい...

*2:放置しててア.そろそろ再開する.

*3:というか,334以外元ネタ知らないんだけど,1333とか1640ってなんなん?

BoCCHAN-1使ってみた

はてブ書いてなさすぎて広告表示されちゃいましたよ

ということで、何を書こうかなあと思ったのですが、最近弄っているBoCCHAN-1 OBC(On Board Computer)のことをメモ代わりに書いておこうと思います。

BoCCHAN-1 is 何

超小型衛星用標準搭載計算機ボード – Kimura-Lab.net

木村研究室が開発した技術を使った小型高性能な衛星用計算機ボードで、6cm四方の大きさでありながら従来の超小型衛星のOBCとは一線を画す性能を発揮します。

こういうやつです。

大学発の小型人工衛星、「ほどよし」の主計算機として使われていたりする、けっこうすごいやつです。

え?なんでそんな特殊なコンピュータ使ってんのかって? 実は今年、東京理科大学がやっている宇宙教育プログラムというものに参加していまして、

www.tus.ac.jp

そこでやるCanSat実験用に使っています(贅沢すぎでは)。

機能とか

なんとこいつLinuxが動きます。第1回CHD(CanSat Hands-on Discussion)のときこれを聞いて、静かに興奮しておりました。 アーキテクチャSH4*1。組み込みってかんじですね。

インターフェースについては、I2CとかUARTとかGPIOとかイケるみたいで中々良い。

Xbeeで通信もできるし。

チュートリアルやってみた

宇宙教育プログラムLETUS*2にアップロードされたクイックスタートガイドやユーザーズマニュアルとかを見ながらチュートリアルとかをやってみました。

そこに書いてあった開発手順を簡単に紹介すると、

  • 開発環境一式が入っている仮想マシンイメージをダウンロード
  • 仮想マシン内の、"ほどよしSDK"が導入されたEclipseを起動して、"Executable with HODOYOSHI SDK"プロジェクトを選択して作成
  • C/C++でコード書いてビルド
  • Eclipseの中にいる"BoCCHAN-1 ttyConsole"からBoCCHAN-1にシリアル接続
  • バイナリを"BoCCHAN-1 ttyConsole"にD&Dして転送
  • ttyConsoleから実行してみる

みたいなかんじでした。

開発環境の自作

というわけで、チュートリアルは出来たのですが、ここでいくつか問題が発生しました。 問題とは何かというと、

  • 僕のマシンが非力すぎて長時間仮想マシン(しかもUbuntu)で作業とかちょっとツライさん
  • EclipseというかIDEチョット..vimでやりたい

はい。開発環境自作のお時間です。

まずはEclipseどうなってんのかなと思ったので、適当な"Executable with HODOYOSHI SDK"プロジェクトを作って、Makefileを見てみました。 IDEが生成したMakefileとかクソ長いんじゃないの・・・とか思ったものの、かなり短かったのでやってることはすぐわかりました(Releaseだけだったし)。 主要な部分を抜き出すと、

subdir.mk(コンパイル部分)

%o:../%.cpp
    @echo 'Building file: $<'
    @echo 'Invoking: SH4-Linux G++ Compiler'
    sh4-linux-g++ -I/home/shdevelop/hodosdk/include/ -O0 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<"
    @echo 'Finished Building: $<'

makefile(リンク部分)

hoge: $(OBJS) $(USER_OBJS)
    @echo 'Building target: $@'
    @echo 'Invoking: SH4-Linux G++ Linker'
    sh4-linux-g++ -L/home/shdevelop/hodosdk/lib -o "hoge" $(OBJS) $(USER_OBJS) $(LIBS)
    @echo 'Finished building target: $@'

こんなかんじです。

ちなみに$(LIBS)は、objects.mkにて、

LIBS := -lpthread -lm -lhodoyoshi -lrt

となっていました。

ようするに、SuperH向けのg++でコンパイルして、ほどよしSDK内のライブラリをリンクしてるだけです。 なんだこれならホスト環境でも全然出来そうじゃん。

なんかpacmanでそれっぽいのが見つからなかったのと、ほどよしSDKとかが結構古いバージョンのもので構成されてたので、Ubuntu環境に移動してSH4向けのgcc,g++を探してみると、ありました。

SH4 - Debian Wiki

# apt-get install gcc-sh4-linux-gnu g++-sh4-linux-gnu

よーし、これでいけるでしょう、ということで、

$ vim hello.c
$ sh4-linux-gnu-gc hello.c -o hello
$ file hello
hello: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=..., for GNU/Linux 3.2.0, not stripped
$ qemu-sh4 -L /usr/sh4-linux-gnu/ ./hello
Hello, World!

うん、いいかんじ。じゃあこれをBoCCHAN-1に転送して・・・あれ?転送ってどうやってやってるんだ? シリアル接続してコンソールにD&Dってあれなにやってんの?

クイックスタートガイドだけではよく分からなかったので、ユーザーズマニュアルを見てみると、EclipseのttyConsoleの代わりにTera Term*3を使ったファイルのアップロード・ダウンロード方法が書いてありました。 読んでみると、Tera Termというより、それに付属しているZMODEMとかいうものでバイナリをやり取りしているみたいです。ZMODEMってなんぞ?

ZMODEM - Wikipedia

YMODEMというバイナリ転送プロトコルを改善したものらしい。1986年…生まれてねえ…

じゃあYMODEMってなんなの?

YMODEM - Wikipedia

ZMODEMよりは説明が詳しい。これは1985年。1年で名前変えたのか…

これはこれでXMODEMとかいうのを発展させたものらしいので、それも見てみる

XMODEM - Wikipedia

パソコン通信で広く使われてたそうな(こいつは何年なんだ…)。

さて、wikiだとあんまり使い方とかが分からなかったので色々と調べてみると、シリアル接続やtelnet接続、SSHなどでリモートにログインしている時に、受信側でrz、送信側でszを実行すると(速度は遅いが)バイナリが双方向に転送できるらしい。なるほど。

でもLinuxでTera Termとかは使えないし、出来れば端末内で済ませたいなあって思ったら、screenコマンドなるものがあったので使ってみた。 BoCCHAN-1をPCにつなぐと/dev/ttyUSB0が生えるので、screenコマンドを使って、ボードレート115200で接続する。

$ screen /dev/ttyUSB0 115200

BoCCHAN-1は電源を入れたらLinuxが起動して、自動的にログインまで済ましてくれているので、あとはZMODEMを使ってバイナリを転送する。

具体的には、BoCCHAN-1側でrzを実行したらCtrl+A+“:exec sz hello"とかやればファイルが転送できる。

ようやくバイナリが転送出来たので、張り切ってBoCCHAN-1の上で実行してみる。

$ ./hello
sh: ./hello: not found

…は?

$ ls hello
hello

は???

なんでえええええええ(泣)

これ、1週間ぐらい理由が分かりませんでした。

最初は転送がうまく行かなかったのかとか色々考えて、配布された仮想環境でビルドしてできたバイナリを同じ方法で転送してみたりしたのですが、これはうまくいくんですよねえ・・・

原因は、うまく行く方とうまく行かない方のバイナリをfileコマンドにかけてみたら分かりました。CTFかよ。

うまく行かない方

$ file hello
hello: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=..., for GNU/Linux 3.2.0, not stripped

うまく行く方

$ file hello
hello: ELF 32-bit LSB executable, Renesas SH, version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, not stripped

どうやら、インタプリタ(?)が違うようです。このインタプリタってなんぞ? 調べてみたら、ELFの共用ライブラリをmmapに配置するあいつでした。確かにそれ違ったら動かないよね じゃあうまく行く方のELFインタプリタ、/lib/ld-uClibc.so.0ってなんなんだ・・・なんかlibcっぽい名前だな・・・

これも調べてみたら、uClibcという組み込み向けのlibc用のインタプリタ、みたいなかんじでした。 心の奥底で、「libcってglibcでしょ?」みたいな先入観が抜け切れていませんでしたね。

ということで、どうやらuClibcを使わなきゃいけないみたいですが、使用するlibcを変更するとかやろうとすると、gccの設定ファイル弄ったり色々しないといけないらしく、どうも面倒です。

でも、そういえば仮想環境の方では普通にsh4用のg++を使っているだけでした。つまり何らかの方法があるはずです。

ここで、ユーザーズマニュアルを眺めていたら、buildrootという文字列を見つけました。BoCCHAN-1で動いているLinuxはこいつを使ってビルドした、ということでbuildrootについて調べてみると、

Buildroot - Making Embedded Linux Easy

Buildroot is a simple, efficient and easy-to-use tool to generate embedded Linux systems through cross-compilation.

組み込みLinux向けのクロスコンパイル用のツールを簡単に作る・・・?どういうことだ・・・?

www.ne.jp

なるほど。組み込みLinux向けのクロスコンパイラやリンカ、さらにLinuxイメージまで作ってくれるものらしい。

$ make menuconfig

でTUIの分かりやすい画面で細かいところまで設定出来る。これは良い。ちょっとcrosstool-ngっぽい。

TOOLCHAINの"C library"を見てみたら、もうデフォルトでuClibcが選択されていた。これはいけそうだ。

本当は仮想環境のbuildrootとgccを同じバージョン、にしたり、色々と設定を合わせたりした方がいいのだろうが、面倒だったので、とりあえずTARGET ArchitectureをSuperH、Target Architecture Variantをsh4(SH4 Little Endian)に設定した。

ついでに、C++を使いたいので"GCC Options"の"Enable C++ support"にもチェックを入れておく*4

これで.configに設定が保存されるので、makeして数時間ほど待つと、buildroot/output/host/usr/bin下にクロスコンパイラやリンカが大量に生える。

$ ls output/host/usr/bin
...
sh4-buildroot-linux-uclibc-g++
...

このコンパイラでビルドして、ZMODEMでBoCCHAN-1に転送すると…

$ ./hello
Hello, BoCCHAN-1!

キタアアアアア!!!

いやー時間かかりました。宇宙教育プログラム受講生でここまでしたの僕ぐらいでしょ(謎のイキリ)(無駄な努力)(素直に配布された環境使え)

今回作った開発環境もどきはGitHubに置いときました。

github.com

なんか間違ってるとことかあったらPRなりIssueなり頂けると嬉しいです(BoCCHAN-1ユーザーそんなにいないだろ

余談

http://www.hodoyoshi.org/

このサイト落ちてる(数年前は割と活動してたっぽい)し、色々とBoCCHAN-1とかほどよしSDKの情報少なすぎでは・・・

もっと情報がオープンになったらいいなーと思うので、CanSat合宿の時にでも木村教授に話してみたいです。

*1:SH4ってなんか聞いたことがあるようなって思ってたけど、OSECPUのhh4と名前が似てる。関係ないけど。

*2:理科大の教育用のなんかの宇宙教育PG用鯖。掲示板とかファイルアップロード出来るのはいいなと思うけど通知とか遅らせられないんですかね。頻繁に見に行くというのは地味にめんどい。調べてみたらmoodleっていうOSS使ってるっぽくて、Rubyで書かれたAPIラッパーがあったから試してみようとしたのだけれど、管理者権限が無いといけないみたいで諦めた。仕方ないからBeautifulSoupからログインするスクリプト書いたけど、めんどくさくなってそれで終わってる。新規投稿が来たらSlackに流すみたいなのが出来れば便利なんだけど。

*3:そういえば作者の方がFF内…ひょええ

*4:最初気づかなくてビルドし直した

サイボウズ・ラボユースに採択された

ちょっと事後報告になりますが、これからはもうちょっと頻繁に更新していきたいので書きます。

ところで、

ということで、タイトルの通り、サイボウズ・ラボユース研究生に採択されました。

サイボウズ・ラボユースって何よ?

http://labs.cybozu.co.jp/youth.htmllabs.cybozu.co.jp

まあ詳しくはこのサイトを見て欲しいのですが、

サイボウズ・ラボユースは、世界に通用する日本の若手エンジニアの発掘と育成を目指すことを目的とし、学生の若手クリエイターに研究開発の機会を提供する場として、2011年3月31日に設立されました。

という学生支援制度です。

何がいいの?

対象:中卒以上(大学生・院生・未就業者の方も応募できます)

個人のソフトウェア研究開発プロジェクトを会社が応援する制度です。 年間103万円を上限(※1)にサイボウズが奨励金を支払います。 (個別に契約を結ぶ、開発時間に応じた報酬です) 関東近郊在住(東京日本橋まで通えること)を条件としています。 (在宅による遠隔地からの参加も考慮いたします) サイボウズ・ラボ社員が直接指導いたします。 (サイボウズLiveによるオンライン指導もあります) 中間発表会・成果発表会の場で途中成果を報告していただきます。 交通費・宿泊費は規程により別途支給します。 (※1)学生が親の扶養を外れない程度の金額を想定しています

というわけで、端的に言って神です。

作りたいもの作って、ラボの超強いプロに色々教えてもらえて、しかもお金が貰えるんですよ!

NDAとかも結ぶ必要無いですし、基本的に成果物はOSSにする、ということ以外は制約はほとんどありません。

いやー、いいっすね。まあ僕は学校がバイト禁止で、「サイボウズ・ラボユース研究生」というちょっと毛色の違うやつにしたのでお金は貰えないんですが(それでも、交通費とかは支給されますし、基本的にはラボユース生と同じです)。

ラボユースはバイトじゃないし許可してくんねえかなー(小声)

まあ、僕は学校がちょっと忙しかったりするので、出社(?)できるのは夏休みの一部期間だけなんですけどね。 でも、オンラインでの指導とかもしていただけるみたいなので、そこらへん有効活用していきたいです。

あとは、ラボユース研究生は「ラボユースの登竜門」ってなってるので、大学生になったらラボユース生になりたいですね(こういう話も面接の時にさせてもらいました)。

で、お前なにやるの?

github.com

このx86エミュレータを作っていこうと思っています。

QEMUとかBochsとかでよくね?」、え、はいそうです。新規性の欠片もねえ。

なんでこんなので通ったのかというと、ラボユースはあまり新規性を要求しないからです。

僕がラボユースに応募した主目的は「コンピュータ、というか、x86アーキテクチャの仕組みを学びたい」というのが大きいです。なので、出来たエミュレータがクソ遅くてとても使い物にならなかったとしても、ちゃんとしたエミュレーションができれば満足です。まあ速いに越したことはないんですが。

今のところの最終目標は、このエミュレータ上で「はりぼてOS」を動作させることです。自作OS on 自作エミュレータってカッコイイ。

ちょっと小噺

ところでですね?

えーっと、何をやったのかというとですね、

3月30日に、「第6期サイボウズ・ラボユース成果発表会」というものに行ってきたんですよ。

blog.cybozu.io

で、ここでラボユースの相談などもさせていただきました。

で、この成果発表会を境に第6期サイボウズ・ラボユースが終了したわけです。

しかし、この日にラボユースのサイトを見てみると、

f:id:sksat:20170504164057p:plain

「サイト見たらまだ第6期募集してる!」ということで、3月31日に応募メールを送りました。いやあとんだ悪ガキですね。

はい。反省してます(ホントか?)。

あ、ちなみに今のサイトでは、第7期の仕様に変更されてるのでご安心を。

あと、僕は第7期での採用です。はい。

セキュリティ・キャンプのススメ的なsomething(応募課題晒し)

超久しぶりの投稿です。

ところで、

今年のセキュリティ・キャンプの募集が開始されましたー!!!

www.ipa.go.jp

いやー、めでたい(?)っすね〜

で、なんかセキュキャン2016卒業生のプロ各位が応募用紙晒したり、それをまとめたスプレッドシート(黒歴史収集・・・?)

が爆誕したりしているので、僕もなんか書いてみようかなー、と思いました。

このスプレッドシートに載っているようなプロ各位の記事を読むと、

セキュキャンの卒業生=任意のプロって感じがしますが、

僕は全然プロではないので、全然進捗無いので、プロではないので(大事なことなので2回言いました)、あんまり参考にはならないと思いますが、ノリで書きます。あまり参考にはなりませんが、まあそんなかんじでお願いします。

まずは、去年の僕が応募用紙に何書いたかを晒していきます(ウワアアアア)。

去年の問題は、今は https://www.ipa.go.jp/files/000053055.pdf にあるようです。では、初めの方から見ていってみましょう。

とりあえず目次です

■はじめにお読みください

※このページは、60分程度でセッションが切断され、入力内容が無効となります。そのため、回答内容は応募者ご自身が適宜保存しながら回答するよう、 くれぐれもご注意ください。 ※一時保存機能による回答内容の保存は48時間有効です。一時保存URLは、①有効期限を過ぎた場合、②再度一時保存をした場合(新しく別の一時保 存URLが発行され、古いURLは無効となります)、③回答内容を送信した場合に、無効となりますので、ご注意ください。

はい。これ超重要です。もしかしたら僕がこの記事で書いた一番重要な情報かもしれませんよ! セキュキャンの応募課題はクソ時間かかります。いや、プロだと一瞬で出来るのかもしれませんが、僕は無理です。というわけで、ちゃんと保存しましょう。僕は当時安定的に使えるPCが無かったのと、どこでも編集できるようにクラウドサービス上で作業しました。僕はセキュキャン後にgitを知ったのでアレですが、git管理とかしてもいいかもしれません。応募課題をgit管理、かっけえ。

あと、消えてしまうととてつもなく悲しくなるので、バックアップを定期的に取ってもいいかもしれません(?)。今年は一時保存機能も無いようですし。

※回答の締め切りは、【2016年5月30日 17:00】です。再提出を含め、締め切りまでに回答を送信してください。

あー、これも重要ですよ。〆切。どんなに時間をかけてでも1限死んででも応募課題には時間をかけるべき(かもしれない)、と言いたいところですが、そんなに頑張っても出せなかったらなんの意味もありません。全部水の泡です。超もったいないです。まあ僕が学校の課題でもやるべきことなんですが。

はい、これで僕が言えるアドバイスとかもう9割9分9厘終わりですね。あとの記事は残りカスみたいなもんです。黒歴史ですし。

というわけで後はダラダラと去年の僕が書いた応募用紙を晒していきますが、まあまさかこんなところを読む人なんていないだろうということで、黒歴史ぶちまけちゃいましょうか。

共通問題

では共通問題から。

共通問題.1

共通問題.1 (1)

あなたが今まで作ってきたものにはどのようなものがありますか? いくつでもいいので、ありったけ自慢してください。

来ましたよ、この自慢コーナー。イキリオタク案件です。僕はどうイキリオタクしたんだっけか・・・

・ロケット
 小学生の頃からペットボトルロケットを作っていて、地学部に入ってからは先輩とペットボトルロケットを設計、製作、シミュレーション、実験を行っていた。先輩が卒業し、僕が部長兼宇宙科学班班長になってからは、「モデルロケット」という、火薬を使用したロケットの設計、製作、シミュレーション、実験を行っている。
・ロケットシミュレーション
 上述のロケットの設計及び、実験結果のフィードバックを論理的かつ効率的に行うために、物理シミュレーションを行っている。ロケットの軌道は空気抵抗にかなり左右されるため、空気抵抗の計算がかなり重要となる。現在は近似式で計算を行っているが、PC教室のPCを全てLANで接続してスーパーコンピューターのようにして有限要素法で正確な軌道計算を行う試みを考えもした。
・流体シミュレーション
 「粒子法入門」を読んで、SPH法を用いてナビエ‐ストークス方程式を離散化して解いて、流体シミュレーションを行っている。また、シミュレーションだけやっていてもつまらないので、ParaviewやPov-Rayによる可視化も行っている。
・天体シミュレーション
 流体シミュレーションで学んだ粒子法シミュレーションの手法を用いた上で、多体重力シミュレーションをどのようにやればよいか考えてプログラムを作っている。この成果は今年の部誌、ホルストに掲載する予定。
・HELIOS
 「OS自作入門」を読んで自分で作り始めたOS。この開発コードネーム(ヘリウムの語源で太陽の意)を思いついたときは、かなり中二病に近かった。そして実際に中2だった。2回ほど「はりぼてOS」を作り、少しづつ自分で考えてコーディングをした。現在は勉強とか部活とか忙しくて中断している。ちなみにAPMシャットダウン成功一歩手前まで行った(シャットダウンだけする16bitOSを作った)。アルゴリズムまで思いついたもののコーディングせずにほったらかしているアイデアがたくさんある。

アアアアアなんじゃこりゃあああああああ(吐血)

とりあえず次に進みます。。。

共通問題.1 (2)

それをどのように作りましたか?ソフトウェアの場合にはどんな言語で作ったのか、どんなライブラリを使ったのかなども教えてください。

・ロケット
 ペットボトルロケットは、ペットボトル・ビニールテープ・ホチキスで製作。小型カメラを搭載して動画撮影を行ったり、パラボリックフライトの真似事をして疑似無重力実験を行ったりした。
 モデルロケットは、残念ながらまだモデルロケットライセンス4級を取得していないためA型エンジンしか使用することができないが、近いうちに取得する。今年の文化祭までにArduinoを用いた無線打ち上げ制御を行いたいと考えている。
・ロケットシミュレーション
 日本モデルロケット協会の本を参考に、最初はExcelでシミュレーションを行っていたが、計算が遅い・開くたびに計算する・あくまで表計算ソフトなので精度が期待できない、などの理由で、C/C++(MinGW)言語によるシミュレーションプログラム開発に移行した。後述する流体シミュレーションから多大な影響を受け、計算精度などの問題をまじめに考え始めた。現在は、モデルロケットのシミュレーションに対応するため、エンジンデータなどを調べている。
・流体シミュレーション
 丸善で見た「粒子法入門」に感銘を受たので、学校の図書館に購入させ(理工書は高い)、何度も読み返して(僕以外借りる人がいなかった)、実際にコンパイル・実行してみて、「大学院の物理って面白そう」と感じた。あまり僕が手を加えられた部分は少ないので、これは「自分が作ったもの」とはいいがたいが、これを参考に後述の天体シミュレーションを行っているのでお許しいただきたい。
・天体シミュレーション
 前述の粒子法シミュレーションを参考に、「あれ、国立天文台の4D2Uってスパコン要るだけでやってることはそんなに難しくないんじゃないか?」と自惚れて作り始めたもの。数値積分の面倒くささを再認識した。言語はC/C++(MinGW)。衝突判定が足りないので、天体同士が接近すると計算不安定が大変なことになる。
・HELIOS
 「OS自作入門」を読んで作り始めた名前中二病OS。今は開発を中断している。言語はC/C++(GO)。「WinAPIが面倒なら自分でOSを作ればいいのに」という僕の迷言を生み出した。動的リンクライブラリとか実装したい。APMシャットダウンがうまくいかないまま中断している。

あうあう・・・

まだ自覚している節があるのでマシといえばマシですが、なんだこの厨2はってかんじですね。嘘にならない範囲でギリギリのことを書いているというか。これだけ見ると強そう。まだ終わってないことも多いし。

でも、この問題は、応募してくる人の、「どのくらいイキリオタクしてくるか」、ようするにやる気を見ていると個人的に思っている(ホントか?)ので、応募する人はバンバンイキリオタクするといいと思います(さあ黒歴史を作るんだ)

「俺に自慢できるものなんてねえよ」なんて人もいると思います。僕もそうでした。でもきっと大丈夫です。セキュリティ・キャンプは必ずしもプロを求めているわけではありません。もしそうなら僕は確実に落ちています。CTFの大会に出たり、CVEを持ってたり、言語作ったりしていたわけではありません。

こんな僕でもキャンプに行けた理由は、多分、セキュリティ・キャンプという事業が、「プロをさらにプロにする」というイベントではなく、人材発掘、ということに重点を置いているからだと思います。

「キャンプで成長するというよりも、あくまでキャンプはきっかけにしてほしい。」

こんなことをキャンプの偉い人が言ってました。これは本当にその通りだと思います。いやもちろん、キャンプに来た時点でプロでプロプロしてるプロもいたのですが、僕はキャンプで無双することなんて全然無理でした。今でこそ受けた講義の内容はなんとなく分かっている(はず)ですが、キャンプ中には全然イミワカランなんだこれ、みたいな講義もありました。

しかし、僕はセキュリティ・キャンプに行かなければ、「OS自作入門」の著者のKさんに会うことも無かったでしょうし、参加者のすごい人たちに会うことも無かったでしょうし、OSCにも行くことも無かったでしょうし、サイボウズ・ラボユースに応募してみようなんて微塵も思わなかったでしょう。最悪、プログラミングをやめていたかもしれません。

なにより、「こんなすごいことをしてる人たちがいるのか」ということを知ることができたのが、一番大きいと思っています。井の中の蛙が大海を知った訳です。海じゃなくて湖、ひょっとしたら池くらいかもしれませんが。

・・・あれ?まだ1つしか問題終わってないのに、4.7k文字・・・? なんかいいかんじのこと言ってますし、もう晒すの終わりで良いのでわ? え、ダメですか。仕方ないですね・・・

共通問題.2

共通問題.2 (1)

あなたが経験した中で印象に残っている技術的な壁はなんでしょうか?(例えば、C言語プログラムを複数ファイルに分割する方法)

・コンパイラがうまく動かなかった
 部のPCで、学習用C言語開発環境(ようするにtcc)がうまく動かなかった。Hello, Worldぐらいは動くのだが、少し行数が増えただけで全く違うところでコンパイルエラーが発生し、コンパイルできてもおかしな挙動をした(コードがおかしいわけではなかった)。
 仕方ないので、Visual Studio 2008をインストールしたが、何もコンパイルできなかった。
・クラスの概念が理解できなかった
 軽くCをやったあと、C++をやろうとしたが、オブジェクト指向が理解できなかった

今考えるともう少し原因究明しろよとか、何がどう理解出来なかったのか書こうよってかんじですが、当時は本当にこれに困ってたんですよね・・・

共通問題.2 (2)

また、その壁を乗り越えるために取った解決法を具体的に教えてください。(例えば、知人に勧められた「○○」という書籍を読んだ)

・コンパイラがうまく動かなかった
 なにを試してもうまくいかなかったが、MinGWとGOだけまともに動いたので、以後gccを多用し、IDEという文明の利器から離れていくことになる(eclipseは展開不良のため使えなかった)。そもそもPCに問題がある可能性がかなり大きい。
・クラスの概念が理解できなかった
 アセンブラからやり直し、構造化プログラミングの意義を理解し、その延長線上としてのオブジェクト指向を理解した

_人人人人人人人人人人人人人人人_ > オブジェクト指向を理解した <  ̄YYYYYYYYYYYYYY

ギャアアアアアアなんだこいつはアアアアアアア(黒歴史(吐血))

オブジェクト指向を理解とか、出来てないです。それこそJavaとかほとんどやったことないですし。

共通問題.2 (3)

その壁を今経験しているであろう初心者にアドバイスをするとしたら、あなたはどんなアドバイスをしますか?

・コンパイラがうまく動かなかった
 IDEなんて甘えです。古いPCだとうまく動かないし、遅いし、はたまたインストールできないことだってあります。別に、IDEを使うことは悪いとは思いません。生産性も上がるでしょう。なんだかんだで僕も今はたまにNetBeansとか使います。でも、IDEの恩恵を普通だと思ってしまったり、IDE特有の癖(特にVC++)とかが分からないと、IDEが使えないときや、何らかの事情で(例えば、OS作るとか)IDEを使えないときに、絶望しか味わえません。というわけで、コマンドラインコンパイルとかやるようにしましょう。
・クラスの概念が理解できなかった
 アセンブラからやり直しましょう。オブジェクト指向は楽ですが、それしかやらないとなぜそれが要求されたのかも、実際にはどのように動いているのかも理解できません。というわけで、低層からやりましょう。

いや、あのですね、こんなこと書いちゃいましたが、IDEがダメとか甘えとかは別に思ってません(言い訳)。この前Visual Studio 2017を使ってみたんですが、ヤバかったです。あれ、コード書かないで色々出来てやべえ。

ただですね、ちょーっと言わせてもらうと、僕はINF回Visual StudioやらEclipseやらの有名なIDEのインストールにコケていた(大体スペック不足)ので、IDEには未だにトラウマが・・・

当時のプログラミング環境は、gcc(MinGW or GO) + TeraPad でしたね。今はgcc(build-essential) + vimですね。vimはいいぞ。

えーっと、次はクラス云々の話ですか。これもちょっと黒歴史ですね。

まあでも、アセンブラやるのは悪いことではないと思います。そこらへんで売ってるC言語の入門書とか読んでも、僕は無限にポインタのことが分かりませんでしたし。

というわけで「OS自作入門」はいいぞ(N回目)。 https://www.amazon.co.jp/30%E6%97%A5%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B-OS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%B7%9D%E5%90%88-%E7%A7%80%E5%AE%9F/dp/4839919844www.amazon.co.jp

みなさんもOS自作してアセンブラC言語で遊びましょう!(低レイヤー沼)

次は講義の希望です。

共通問題.3

共通問題.3 (1)

あなたが今年のセキュリティ・キャンプで受講したいと思っている講義は何ですか?(複数可) そこで、どのようなことを学びたいですか?なぜそれを学びたいのですか?

■1-B BareMetalで遊ぶ Raspberry Pi 入門編
ラズパイを使ってみたかったので
■3-B フィジカル・リバースエンジニアリング入門
2歳ぐらいから分解大好きなので
■5-B USBメモリからブートしてみよう
HELIOSのUSBブートで失敗したので
■2-C 人工知能とセキュリティ
ディープラーニングの実装に失敗したので
■3・4・5E システムに新機能を追加したときのセキュリティを考えよう
川合さんの話はとても好きなので。また、あえて今「C言語に機能を追加する」というところに惹かれたから。

これ、「なんでセキュリティ・キャンプに行きたいのか」ってのに直結する質問なので、もう少し色々書くべきでしたね・・・

僕の場合、合格通知の後の講義の選択希望で、割と希望を変えましたし。

それこそ今年度の場合は、希望する講義で応募課題が変わってくるくらいですし、どの講義を希望するかはちゃんと考えて応募したほうがいいと思います。

共通問題.3 (2)

あなたがセキュリティ・キャンプでやりたいことは何ですか?身につけたいものは何ですか?(複数可) 自由に答えてください。

・自分と同じようなことに興味を持つ人と出会いたい(基本ぼっち)
・今自分が作っているものの参考にしたい
・アイデアの発想の仕方を学びたい
・セキュリティについて詳しく学びたい

あー・・・これも、もう少し色々書いておくべきでした。 なにを言いたいのかはなんとなくは分かるのですが、情報がとても少ないですね・・・

ただ、応募した時は、正直自分が何をやりたいのか、キャンプで何を学べるのかとかがイマイチ分かっていなかったので、ある意味しょうがなかったかもしれません。

まあ自分が何をやりたいのか、なんてことは今でもあまり分かってないのですが、キャンプに行ったことで割と考えさせられたところはありますね。

選択問題

以降は選択問題です。

どの問題を選択するかはかなり迷ったのですが、知識が圧倒的に足りなかったので、どうにかして答えられそうなものを選びました。

ただ、もう少しよく調べたり、考えたりして書けばよかったかなあと思っています。

選択問題.3

RAMは主記憶装置、HDDやSSDなどは補助記憶装置と呼ばれます。一般にCPUは主記憶装置上のプログラムしか実行できません。ではなぜ、私たちは普段から補助記憶装 置に書き込んだプログラムを実行できているのでしょうか?パソコンの電源を入れてからのストーリーを考えてみてください。

PCの電源を入れると、ROMなどに書き込まれたBIOSが自動的に起動し、BIOSがOSを呼び出すための初期プログラムローダ(IPL)が書かれたブートセクタ(MBR)をHDD、SSD、CDなどの補助記憶装置から事前に登録された順番で探していく。そして、IPLを発見すると、IPLを実行する。IPLは1セクタ分、つまり512バイト分しかないので、OSを起動するためのプログラムを主記憶装置に転送するプログラムが書かれている(はりぼてOSではサイズが小さく、HDD読み込みができないのでOSとそのほかのファイルを全て転送する)。こうして主記憶に転送されたプログラムが、さらに必要なデータを補助記憶から転送するなどしてOSが起動する準備を行う。こうして、ようやくOSが起動する準備が完了し、プログラムがOS本体を実行する(正確にはジャンプする)。
OSが起動した後は、OSがおそらくout命令で補助記憶装置の制御チップに色々と命令を送って補助記憶から主記憶にデータを転送させている。

はい。ブートプロセスを考えろってことですね。僕がプログラミングを始めたきっかけが「OS自作入門」なので、この問題(と次の問題)を見つけたときは、「アーッこれあの本で見た!」って思いましたね。というか、これらの問題があったから応募してみた、という節もあるかもしれません。

でも、これも今見ると理解がイマイチでしたね・・・

書いた時ははりぼてOSのことしか知らなかったのでこうなったのですが、Linuxなどのブートプロセスも調べたほうが良かったと思います(GRUBとか)。

選択問題.5

PCなどに搭載されているOSは「汎用OS」と呼ばれますが、それに対して、家電やAV機器などの「組込みシステム」に搭載されているOSは「組込みOS」と呼ばれます。 組込みOSと汎用OSの違い、「OSが無い」や「ベアメタル」という環境、そもそもOSとは何なのか?など、あなた自身はどう考えているのかを、 あなた自身の言葉で自由に説明してください。(「正しい答え」を聞いているわけではありません。あなた自身の考えを教えてください)

正直、「OSはこうあるべきだ」というような明確な定義は無意味だし、必要ないと思う。「カーネルがどうこう」なんて話はこの際無視する。僕が考えるOSとは、本当の意味での「オペレーティングシステム」、つまり、なんらかの電子機器を直接制御するシステムのことだ。それは、家電製品を制御しているかもしれないし、人工衛星を制御しているかもしれないし、はたまたPCを制御して、その上でアプリケーションを実行しているかもしれない。タブレットやPCを制御し、そのうえで様々なアプリケーションを実行して多くのエンドユーザーがいるのであれば、それは「汎用」OSと呼ばれるのだろうし、人工衛星や、ロケットや、家電製品など、特定作業に特化した電子機器を制御するため、必要な機能のみを必要なICなどに「組み込まれた」OSは、「組み込みOS」と呼ばれるのだと思う。

この考え方は、割と今も変わってないですね。でも、自作OSもくもく会とかに行くと、人によってOSの定義、とでもいうものが色々あるので、「OSってなんだろう」みたいな問いは、これからも考えていきたいですね。

選択問題.6

IDとパスワードを入力してユーザの認証を行うWebアプリがあります。あなたがこのアプリに対してセキュリティテストを行う場合、まず、どのようなテストをします か? なぜそのテストを選択したのか、その背景や技術的根拠と共に記載してください。アプリの内部で使われている技術やシステム構成に、前提を置いても構いません。

認証される組み合わせがくるまで延々とIDとパスワードを生成し、入力してくる辞書攻撃に対応できるか判断するため、IDとパスワードを延々と生成し入力するプログラムを作り、このアプリに対して攻撃を行う。そして、これにクリアした後は、「同じIPアドレスから大量に認証申請が来ている」ということだけをもとにして前回の攻撃をクリアしたのではないか、という観点から、常時IPを変えつつ前回と同じ攻撃を行う。

う、う〜ん、これだけかよってかんじですね・・・(小並感)

Webアプリとかなにも分かんなかったんです!許してくださいなんでもしますから(なんでもするとは言っていない)

選択問題.9

マイナンバーカードの配布システムを構築・運用することになりました。あなたなら何に気をつけてどんなサービスを構築しますか? マイナンバーカードの仕様は現実通りのICカードとします。 ※ 注意: マイナンバーでは無くマイナンバーカードです。

・ICカードは少し離れていても情報を読み取ることが可能なので、それを防ぐために、磁気などを遮断する厳重な金庫に入れて輸送する
・配布要員が不正を行わないようにするため、作業員は全員ICタグなどで出入を管理し、配達用の車両の現在位置を追尾する
・苦情に迅速に対応するため事前に苦情対策について行政と協議する
・配達員にタブレットを配布し、配達時に本人確認を行い、タブレットで配達完了を管理センターに知らせるようにする

マイナ◯バーカードwww

なんか、誤配達とかあって大変だったらしいですね。結構当時としてはタイムリーな話題でしたね。 一応そこも踏まえて書いたような気がしていたのですが、これだと全然伝わらないですね。しかも箇条書き・・・

終わりに

はい。これで僕の黒歴史晒しは終わりです。書いててちょっとつらかった・・・

他の過去の参加者のみなさんの応募用紙と比べると、あまりにもクソということが分かっていただけたと思います。

もし、「キャンプ勢とか強そう・・・自分には無理だ・・・」と思って応募を諦めようとしている人が「こんなのでも受かるのか!」と思っていただけたなら幸いです。

何回でも言いますが、セキュリティ・キャンプは応募に際して技術力を要求していません。それはこの記事を見れば明白です。

しかし、だからといって応募課題をテキトーにやっていいわけでは決してありません。こんな応募課題でも当時の僕はかなり時間をかけて書きましたし(時間かけてこれかよとか言わないであげて・・・死んじゃう・・・)。

特に、今年の応募課題は去年のものと比較しても時間をかけて試行錯誤することを要求している(気がする)ので、今年応募する人は頑張ってほしいですね。

今年のセキュリティ・キャンプはとてもパワーアップしていてすごく面白そうなので、今年応募する人、マジで応援してます!!!

僕もチューターやりたいので頑張ります!(あまりにも面白そうなので行きたくなった)

CTF for ビギナーズ に当選した

@hiwwさんのお誘いでTeam Harekazeの一員になったものの、stringsぐらいしか出来ない情弱なので申し訳ない気持ちになっていた。ハリネズミ本も終わってないし。

マトモにやれたのはsometa1ぐらいじゃなかろうか(といっても解けなかったのだけれど)。

そんなこんなでCTF力のNASAを感じていたので、ctf4bにダメ元で申し込んでみた。抽選になるほどの人気イベントなので(そもそも、抽選で参加出来なかった人がたくさんいたから今回追加でやることになったらしい)、まあどうせ受からんだろと高を括っていたら、
f:id:sksat:20170121232935j:image

当選してしまった(びっくり)。

ということで、CTFも頑張りたいと思います。