livaの雑記帳

alpine linuxのminirootfsからqemuで起動する話

小さくて便利で皆大好きalpine linux

docker触ってたら一度くらい使った事ありますよね?(個人の意見です)

このalpine linuxではminirootfsというものが提供されています。これはalpineのファイルシステムをtar.gzに圧縮して固めたもので、公式サイトいわく、コンテナやchrootする時に使う事を想定されているようです。

このminirootfsは2MBしかなく、数十MBもあるインストールISOと違って、ものすごく軽量です。これなら、この軽量なminirootfsを使ってファイルシステムを構築すれば軽量なんじゃないかと思い、(ちょうど軽量なLinux環境をqemuで立ち上げたかったので)やってみました、というのが今回の話です。

別にminirootfsとか使わなくても、これとか使ってVMイメージを作れば十分軽量なんじゃないかと言われればそれまでなんですけどね・・・。
 

 

kernelを準備する

minirootfsにはカーネルが無いので、適当なバージョンのソースコードを引っ張ってきて、ビルドしましょう。僕はモジュールとかを適切にrootfsに展開するのが面倒になり、全てkernelにstatic buildしてしまいました。

ここで得られたbzImageをqemuのオプションで渡します。

 

qemuでどうやって起動するか

qemuからはこんな感じで起動しようと思います。

 

$ qemu-system-x86_64 -kernel bzImage -initrd rootfs -append "root=/dev/ram rdinit=/bin/sh console=ttyS0,115200" -net nic -net user,hostfwd=tcp::2222-:22 -serial stdio -display none

 

-kernelオプションで先程のbzImageを指定、initramfsとしてrootfs(minirootfs)を指定、出力はシリアルポート、initramfsで起動したまま、シェルを立ち上げる(カーネルパラメータオプションの rdinit=/bin/sh)、みたいなのを想定しています。

 

initramfsをrootとしてしまうのは完全に手抜き(別にinitramfsでの起動でも僕が本当にやりたい事は達成できるので)です。この上でファイルシステムに何か書き込んでも、当然qemuを終了したら吹き飛びます。まあ気になる人はちゃんとハードディスクイメージにするか、適当にNFSマウントでもすれば良いのではないでしょうか。

 

とりあえずこれをやるために必要な事として、rootfsを準備しなきゃいけません。次からこれを準備していきます。

 

rootfsの準備

initramfsのファイルフォーマットはcpioです。minirootfsはtar.gzで落ちてくるので、展開した後、cpioにしなければいけません。

そして展開しようとすると、デバイスファイルが展開できなくてこけます。

 

なので、fakerootを使いましょう。

 

$ fakeroot && tar xf ../alpine-minirootfs-3.8.0-x86_64.tar.gz && 

find | cpio --quiet -o -H newc | gzip -9 > ../rootfs

tarでカレントディレクトリにminirootfsを展開した後、cpioコマンドで固め、gzip圧縮しています。

 

確かこれだけで/bin/shは起動するはず

 

initを起動したい

シェルが立っただけだと、何もサービスが使えないので、使い物にならないです。わかりやすい例で言えばネットワークとか。

というわけで、initスクリプトを起動しましょう。

 

$ qemu-system-x86_64 -kernel bzImage -initrd rootfs -append "root=/dev/ram rdinit=/sbin/init console=ttyS0,115200" -net nic -net user,hostfwd=tcp::2222-:22 -serial stdio -display none

rdinit=/sbin/initにすると、initスクリプトが起動します。

 

これで起動すると、以下のようなエラーが出てしまいます。シェルすら出ません。辛い。

can't open /dev/tty1: No such file or directory

 

/dev/tty1というデバイスファイルがない、というエラーですね。

minirootfs内の/etc/inittabには以下のような行があり、ここで/dev/tty1を参照していますが、その時までに/dev/tty1が作成されていないため、このようなエラーが出るわけです。

tty1::respawn:/sbin/getty 38400 tty1

 

バイスファイルを準備したい


/dev/tty1を生やす簡単な方法を探すと、こんなのが出てきます。

 

kernhack.hatenablog.com

 

initramfsのinitと同様に、以下のようなコマンドを実行すればデバイスファイルやその他諸々が整備されるはずです。

mount -t proc proc /proc -o nosuid,noexec,nodev
mount -t sysfs sys /sys -o nosuid,noexec,nodev
mount -t devtmpfs dev /dev -o mode=0755,nosuid
mount -t tmpfs run /run -o nosuid,nodev,mode=0755


なので例えばこんな感じの事を/etc/inittabの最初でやれば、解決します。

 

::sysinit:mount -t proc proc /proc -o nosuid,noexec,nodev

 

最初はこれで解決していたのですが、途中でもっと綺麗なやり方がある事に気づく事になります。ひとまずこれで解決した、という体で話を進めさせてください。

 

そもそも/etc/inittabの編集ってどうやれば良いんだ!という方もいらっしゃるかもしませんが、それはtarで展開した後、/etc/inittabで編集し、cpioに食わせれば良いだけですよ。

 

シリアルでログイン画面が出てこない。

これだけだと、エラーは出なくなりますが、まだログイン画面には到達できません。/etc/inittabでは以下の行がコメントアウトされているためです。

 

ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100

 

まあそりゃ今はシリアルで画面出力しているから、シリアルコンソールに対応するデバイスファイルを設定しなきゃ駄目ですね。

 

ログインしたい

ログイン画面出ただけではどうしようもないので、ユーザー作りましょう。

 

cpioに固める前に、アカウント情報をファイルシステム上に乗っけます。(cpioに固めた後はファイルシステムに手出しできないので。ログインもできてないですし)

minirootfsの展開先にchrootし、minirootfs上のadduserコマンドでユーザーを作れば、minirootfs上にアカウント情報が作成されます。

$ chroot . addgroup alpine

$ chroot . adduser -S -s /bin/sh -G alpine alpine

$ chroot . addgroup alpine wheel

$ chroot . sh -c "echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"

 

alpineユーザーを作り、ついでにwheelにも追加します。wheelはパスワード無しでsudoできるようにします。

 

sudoするためにはminirootfs上にsudoコマンドが無いといけないので、sudoをapkでインストールします。僕はsshサーバーを立てたかったので、ついでにdropbearと、dropbearを自動起動するためにopenrcも入れました。

 

$ chroot . apk add --no-cache --initdb sudo dropbear openrc

 

これだけで終わりと言いたい所ですが、手元だとpermissionエラーでログインできませんでした。minirootfsを展開後に、/(minirootfsのroot)を755に設定する必要があるようです。

 

/etc/network/interfacesの設定

これで無事ログインできたのですが、"rc-service dropbear start"ってしてdropbearを起動しようとすると、「/etc/network/interfacesがナイヨ」と怒られます。

 

というわけで、/etc/network/interfacesを整備しましょう。

 

auto lo

iface lo inet loopback

 

auto eth0

     iface eth0 inet dhcp

こうすると、ifconfigでloとeth0が見えるようになります。でも相変わらず通信できません。ていうか、それ以前にdropbearを起動する事でnetworkingが起動するってどういう事よ、最初からnetworkingは起動しててよ、みたいな気になりますよね。

 

openrcの設定

なので、openrcがinitを自動起動してくれるようにします。

$ chroot . rc-update add dropbear default

$ chroot . rc-update add networking boot

これが上手く動けば良いんですが、後者はなぜかSEGVして動きませんでした。コードを読むと、bootの時だけ何か特殊な処理が走るっぽいんですよね。その中でコケてるらしい。もしかしたらdocker環境上で実行したのが悪かったのかもしれません。

 

で、コードいわく、こいつはシンボリックリンクを貼る以上の事をやってなさそうなので、自分でやります。こんな感じ。

 

$ chroot . ln -s /etc/init.d/networking /etc/runlevels/boot

 

/etc/runlevels/bootは存在しないので、事前に作っておく必要があります。

 

なんかnetworkingとdropbearの設定をするんだったら、ついでに他のサービスも全部立てとこうぜ、みたいな気持ちになったので、alpineのVMイメージの設定と比較して、全部設定する事にしました。

 

$ chroot . install -d /etc/runlevels/boot /etc/runlevels/default /etc/runlevels/sysinit /etc/runlevels/shutdown /etc/runlevels/nonetwork

$ chroot . ln -s /etc/init.d/acpid /etc/runlevels/default

$ chroot . ln -s /etc/init.d/bootmisc /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/crond /etc/runlevels/default

$ chroot . ln -s /etc/init.d/devfs /etc/runlevels/sysinit

$ chroot . ln -s /etc/init.d/dmesg /etc/runlevels/sysinit

$ chroot . ln -s /etc/init.d/dropbear /etc/runlevels/default

$ chroot . ln -s /etc/init.d/hostname /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/hwclock /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/hwdrivers /etc/runlevels/sysinit

$ chroot . ln -s /etc/init.d/killprocs /etc/runlevels/shutdown

$ chroot . ln -s /etc/init.d/loadkmap /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/mdev /etc/runlevels/sysinit

$ chroot . ln -s /etc/init.d/modules /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/mount-ro /etc/runlevels/shutdown

$ chroot . ln -s /etc/init.d/networking /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/savecache /etc/runlevels/shutdown

$ chroot . ln -s /etc/init.d/swap /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/sysctl /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/syslog /etc/runlevels/boot

$ chroot . ln -s /etc/init.d/urandom /etc/runlevels/boot

 

※これは最終系のコードで、後の話でapkによってインストールされるサービスも登場しています。

 

これによって、devfsサービスが自動起動するようになり(/etc/inittabの最初の、"::sysinit:/sbin/openrc sysinit"の中で起動される)、先程のmount文は不要になりました。

 

アドレスが割当らない

さて、これでdropbearを手動で起動しなくても良くなりましたし、networkingも最初から起動するようになりました。でも相変わらずssh接続ができません。ネットワークが死んでます。


しかもこれ、何か変なんですよね。ifconfig走らせるとIPv6アドレスは何か割当たってるっぽいし、udhcpc走らせるとちゃんとIPアドレスは振ってくる。でもifconfigにinet addr(IPv4アドレス)は割当らないみたいな。

なんでじゃなんでじゃって言いながら調べてたら、これが見つかり、「ふんふん、busyboxがudhcpcのサンプルスクリプトを提供してるのか、でもminirootfsには無いな」となり、じゃあサンプルスクリプトコピペするか、なんて思いながらググってたらこんなのを見つけました。

 

Alpine Linux packages

 

どうやらbusybox-initscriptsをインストールすると、/usr/share/udhcpc/default.scriptが手に入るらしい!!

 

$ chroot . apk add --no-cache --initdb busybox-initscripts

 

ちゃんとifconfigするとIPv4アドレスも割り当たるようになったし、apkでパッケージもダウンロードできるようになりました。めでたしめでたし。

ubpfで遊んでみる

eBPFくらい簡単に遊べるようになっておかないとまずいよな、という気持ちになったので、遊んだときの記録。

とりあえずユーザーランドで動かしたいんじゃ、って思ったので、ubpfを使ってみる。

 

github.com

 

clang入れるのと、pipで nose pyelftools parcon を入れる必要あり。
で、リポジトリのルートで`make -C vm`ってやるとvmディレクトリ内に`test`っていう実行ファイルができるから、これで遊ぶ。

 

testsの中から引っ張ってきたコード

extern int strcmp_ext(const char *a, const char *b);

 

int entry(int *mem)

{

  char a = "abcx";

  char b = "abcy";

 

  if (strcmp_ext(a, a) != 0) {

    return 1;

  }

 

  if (strcmp_ext(a, b) == 0) {

    return 1;

  }

 

  return 0;

}

 

こいつ(main.c)を

$ clang -O2 -target bpf -c main.c -o main.o

こうして、

$ vm/test -j main.o

こうすると実行できる。0って帰ってきますね。

 

エントリポイントがバイナリの先頭っぽいので、entry()の前に関数置くとそっちが実行されちゃいます。

 

メモリ使うのもやってみてくなった。

3バイトのmemというファイルを用意し、

int entry(char *mem)

{

  return mem[100];

}

こんなん実行したら、range execeptionで落ちるのかなーとか期待。

 

$ vm/test -j -m mem main.o

 

落ちなかった。ubpfではメモリチェックとかはやってないっぽい。

 

おまけ

ubpf環境はDockerで作った。→livadk/ubpf

こんな感じで使うと、環境構築から開放されて、大変幸せになれる。

Mac+dockerでx11アプリケーションを起動する

Mac上で動作するdockerコンテナ内で、GUIアプリケーションを起動したい事って良くあると思うんだけども、動かすまで結構手間取ったので記録に残しておく。

ググるといろいろ出てくるけど、結論としてはこのページ通りにすると上手く行った。

medium.com

 

  1. XQuartzをインストールする。
  2. XQuartzを起動し、環境設定を開き、「セキュリティ」タブの「ネットワーク・クライアントからの接続を許可」にチェックをつける。
  3. 一度XQuartzを再起動する。
  4. シェルで以下のコマンドを実行する。

xhost + 127.0.0.1

docker run -e DISPLAY=docker.for.mac.localhost:0 jess/firefox

 

Firefoxが起動するはず。 
3番が一番手こずった。

 

ubuntuのコンテナでxeyesが起動するかも試したけど、問題なさげ

 

qemu(not kvm)上のゲストOSへのsshが遅くてハゲるので何とかした備忘録

QEMU上でLinux動かす時、kvm有効化しないとめちゃくちゃ遅くないですか?

ゲストOSはUbuntuなんですが、ログインシェル出るまで数分かかるとかありえねぇ!kvm有効化すると10秒掛からずに起動するのに!!

 

・・・みたいな感じで深夜の研究室でブチ切れてたんですが、よく考えたら15年前とかOSの起動って普通に数分かかってましたよね。10年前でも1分近くしたような記憶。

確か、SSDとか出た辺りから起動がどんどん早くなっていったなぁ(しみじみ

 

昔語りしてると老けちゃうので、前置きはこのくらいにして本題へ。

kvm有効化しないqemuが遅いのはまあ仕方ないんですが、ホストからゲストにssh接続するのに10秒掛かるのはありえないだろう、と。ハゲそう

もちろんkvm使えば一瞬で繋がります。でもまあちょっとkvm使いたくない事情があって・・・

 

というわけで、なんとかしてssh接続してシェル出すまでの時間を削減すべく頑張った話。

 

ちなみに環境は以下の通り

  • CPU:Xeon E3-1275 v5 @ 3.60GHz
  • ストレージ:適当に生協で買ったCrucialのSATA SSD
  • メモリ:16GB

 

試したこと

UseDNS no, GSSAPIAuthentication no

鉄板ですね。意味無し。

 

dbusの再起動

ぐぐったら結構でてきた。これも意味なし。

 

公開鍵認証を使わずにパスワード認証にする

意味なし。

ただし、パスワード認証にすると速攻でパスワードを聞かれたので、とりあえずゲストOSがおねんねしているわけではないという事はわかった。

 

UsePrivilegeSeparation no, UseLogin no

後で示すやつを試すついでにもしやと思って試したのだけど、意味なし

 

効果があったもの

ログインシェルをbashからdashにする。

bash重いからねー。これで8秒。

ちなみに計測は人間ストップウォッチです。

 

~/.hushloginを作成する。

ログイン時にずらずら出てくるウェルカムメッセージが明らかに遅いので止める。

これで7秒。

これを作るとmotd周りが全て無効化されるらしい(?)んだけど、個人的には lsb_release -s -d が諸悪の根源であって、こいつを削れば良いんじゃないかとか思ったり。

ubuntu@ubuntu:~$ time lsb_release -s -d

Ubuntu 16.04.4 LTS

real 0m1.155s

user 0m1.056s

sys 0m0.100s

なんでたったこれだけの物を表示するのにこんなに時間が掛かるんだろうね、python3が遅いのかな。

 

で、この状態でも依然7秒。

ssh -vvvの出力を眺めると、

 

debug1: Entering interactive session.

debug1: pledge: network

*** ここで5秒くらい待つ ***

debug3: receive packet: type 80

debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0

 

みたいな感じ。で、これを短縮したのが次。

 

/etc/ssh/sshd.confの設定で、UsePAM noにする

これで2秒になった。

たぶんPAMとの通信が遅いんだろうね。
PAM使わないと困る事があるのかもしれないけど(よくわかってない)、今の環境ではパット見問題なさそうなので大丈夫。

 

これでssh -vvvしてもサラサラッとログが流れて、すぐログインシェルに到達する。

まあもう少しチマチマした改善はできるのかもしれないけど、体感がそんな変わらなさそうなので、まあ良いかなー、と。

最終的に10秒 →2秒になったので、個人的には満足です。

 

僕の髪の毛は守られた!!!!

 

OSを好きなだけの普通の大学生が簡単に強くなる方法

raphine.hatenablog.com

 

以前こんな記事を書きました。

この記事の最後では「ここの記事に書いた内容を実践するだけじゃ大学生は強くなれないよ」と言い残したわけですが、多方面から「じゃあ大学生はどうすれば良いんだよ!」みたいなお叱りを頂いたので、続編の大学生版を書きます。

 

ただし続編といっても、少しだけ補足条件を。

 

  • 上の記事の内容をある程度実践している。(完璧にとは言いません。完璧なんてものは存在しないので)
  • 研究室配属前の学生である。

 

二つ目は結構大事な事で、まだ研究を初めてない、というのは大きなポイントです。

 

中高生版でも書きましたが「強さ」というのは曖昧です。別に成績が良くなくても強い人はいます。だから「SNS映えするような強さ(?)を求めるだけなら簡単でっせ?」という事を伝えたい、というのが前の記事の趣旨でした。

でも研究始めちゃうと、強さの定義って「いかに良い学会に論文がacceptされたか」に定まっちゃうじゃないですか。(ココらへんで筆者が血を吐いて死ぬ

なので「どうやったら強くなれますか?」という話は是非指導教員に聞いてみてください。きっとあなたが既に持ってる者を活かした、強くなり方を伝授してくれるんじゃないでしょうか。たぶん?(ココらへんで筆者が再度血を吐いて死ぬ

 

さて、もう少し前置きを続けさせてください。
中高生の場合はほぼ確実に上の記事で書いた通りの事をやれば良いと僕は思っているのですが、大学生となると「強くなり方」に様々なバリエーションが出ると思っています。

中高生と大学生だと、やはり時間の束縛度が違うので、人生経験の幅も違うし、その人が武器にできる物も異なると思うんですよね。ある人はアルバイトいっぱいやってて、お金を持ってるかもしれない。ある人は勉強会とかイベントとかに沢山参加してて、人脈が広いかもしれない。ある人は、プレゼンが上手い/コミュ力がある/語学力がある/マネジメントスキルがあるなどなど・・・。


だから例えば「凄いソフトを作って名前を広めたい!」と思ったとして、ある人は外注してしまうかもしれないし、ある人は仲間を集めて共同開発し、その取りまとめという立ち位置で才能を発揮するかもしれないし。やり方がどうであれ最終的な成果が世に広まれば、その人の名前は売れるわけです。別にその人自身が全部作らなくても良いのです。

 

とはいえこの記事を読んでいる人で、そういった才能を持っていると自覚している人はたぶん少ないと思うので、そういった個々人の才能に頼らずにどうやって強くなるかという話をしていこうと思います。

 その上でここに書いてある事を鵜呑みにせず、自分なりにアレンジはしてみてくださいね。誰しもが自分の人生経験で培った強さを持っているはず(自覚しているかはさておき)ですから、折角なのでそれを活かしてショートカットしつつレベルアップを目指してみるのが良いように思います。

 

さてだいぶ前置きが長くなりましたが、本題に入りましょう。

 

基本は前のブログで書いた、「勉強し、手を動かし、自分の頭で考え、アウトプットする」というのと同じです。少しだけ内容がアップデートされるだけ。

 

1. 論文を読もう

大学のOSの授業内容の自習がある程度終わり基礎知識が身についたら、論文を読んでみましょう。(基礎知識身につける前に論文読んでも何も理解できないと思うので、基礎を学ぶ方が先ですよ?)

 

僕が学部生の時、先輩から「今のうちに論文を読んでおいた方が良いよ」と何度も言われました。もしかしたらこれを読んでいる皆さんの中にも心当たりのある方がいらっしゃるかもしれません。

 

でも、いきなり「論文読め」って言われても難しいですよね。

 

  • 論文読もうにもどんな論文を読めば良いかわからない。
  • 論文をどう読めば良いか分からない。
  • 英語辛い。
  • そもそもモチベ沸かない。

 

論文読むまでの壁、ざっと並べるとこんな所でしょうか。

 

とりあえずまずは「モチベ」の話から。

OSって難しくて、 過去にいろいろ研究され尽くしてしまっているから、今更自分がOS分野に触れてもしょうがないんじゃないか、みたいな気持ちになりませんか?僕はなりました。

これに対する消極的な回答としては、「アプリケーションはOSの上で動いているから、OS(等のシステムソフトウェア)が理解しているとできる事の幅が広がるし、いろいろ潰しが利いて良いよ!」というものです。

まあでもこの記事を読んでいるような人にそんな事を言ってもしょうがないですよね。もっと、「OSって今でもできる事あるんだ!楽しいんだ!」みたいな事を知りたいのではないでしょうか。

 

それ、論文を読めば書いてあります。

 

そもそも論文って何なのでしょう?
研究室配属されいてる学生にとっては当たり前の事なのですが、ここでは学部生向けに簡単に解説してみます。

 

情報系の論文の多くは、

  • 世の中に存在する解決されるべき(解決すると皆が喜ぶ)問題を示す。
  • その課題に対する他の誰かが思いつかなかった(或いは思いついていても以前は有用ではなかった)解決策、及びその実装方法を示す。
  • その解決策が実際に解決できた事を実験結果を用いて示す。

という構成で成り立っています。(自然科学系とかだと違うかもしれませんが、専門外なので良く分からないです)

 

そしてもう一つ大事な情報として、OS関連の論文は最近も沢山発表されています。

これらの事から導かれるのは、「OSについて解決されるべき問題」がまだまだ沢山残っているという事です。

だから論文を読めば、「OSって今でもできる事があるんだ!楽しんだ!」という気持ちになれそうだと思いませんか?実際、僕は論文を読む度にそんな気持ちになりますよ!

もちろんそれなら自分でも同様に論文を書けるかというと、それはまた別問題なんですけどねー。(ココらへんで筆者が吐いた血がダンスを踊り始める

 

さてじゃあ次にどんな論文を読めば良いか、ですがここは1修士学生の意見で書くよりも品川先生(@ut_shina2)の意見を参考にしましょう。

 

d.hatena.ne.jp

 

ここに挙がっている通り、OS系のトップ学会はSOSP/OSDI/EuroSys/USENIX ATCの4つです。

 

で、学部生の間はこの4つの学会の論文を読んでおくのが良いと思います。トップ学会の論文はきちんとロジックが通っているし、研究として抜けが無いので、ハズレ論文を引くリスクが無いというのが主な理由です。

 

学部生の貴重な時間をハズレ論文を読むのに費やすのは勿体無いので、この学会リストの中から興味がわいた物を読んでみるのが一番無難でしょう。

あと、OSDIとUSENIX ATCはPDFが直接ダウンロードできるので、ACMに(所属組織や個人で)課金してなくても論文読めるのが良いですね。

ちなみに僕はACMから論文pdfをダウンロードしてくる方法、学部生の時にわからずに挫折しました。大学回線で繋げばダウンロードできるらしいけど、なんかよく分からん的な。卒論書いてる間にいつの間にか大学回線以外からもダウンロードできるようになったけど、結局なんでできるようになったのかは良く分かってません。アカウント作ったら何か大学と紐付いた的な。まあでもダウンロードできるからいいや、って思ってます。

 

雑談が長くなりました。次行きましょう。

英語読むのダルい、という問題の対策法ですね。

一般的にはAbstract(要旨)を読んで何となく研究概要を把握しろ、みたいに言われますが、ぶっちゃけ英語力無いとAbst読んだだけできちんと理解するの難しいです。まあ僕の英語力がクソ雑魚ってのはあるんですが。。。

僕の場合は論文一回通して読んでも、結局論文が本質的に何が言いたいんだ?ってなって、そこからしばらくウンウン唸って何度も読み返して、ストンと落ちて納得できるまでにだいぶ時間が掛かります。で、きちんと理解できた後にAbst読むと「あぁ〜、なるほど!」ってなるんですが、まあでもそれって実はAbst読めてなかったって話なわけで、何が言いたいかって英語力無いの辛い。

で、そんな人は発表スライドを一通り読んでから論文読むと良いと思います。

 

例えばOSDI'16だったら、Programをズラッとみてみると、多くの論文はスライドが公開されているので、それを最初から最後まで眺める、と。そうすると論文の言いたい事が簡潔にまとまっているし、図で綺麗に説明されているので英語力が低くても割と何とかなります。

まあスライド掲載されてない論文もあるし、そもそも年度が古いと学会の公式サイトが落ちちゃっててスライドにアクセスできない、とかあるんですけどね。とはいえ、ひとまずスライドがある論文から読んでいくだけでも、だいぶ勉強になるんじゃないでしょうか?

 

最後に、論文をどう読むかの話。
これも研究を始めると基本なんですが、論文は章立てて書かれています。

論文ごとにどんな章立てかは異なるのですが、大雑把に分けて以下のような構成になっています。

  • (Abstract)
  • Introduction, Background and Motivation
  • Design and Implementation
  • Evaluation and Discussion
  • Related Work
  • Conclusion

ただし、これを読んでる皆さんはまだ研究をしているわけではないので、論文全てを読まなくても良いと思います。

 

皆さんが論文を読む意義は、

  • 「OSに関して、こんな解決されるべき課題があったんだ!」という知識を得る。
  • 「こんな予想だにしない解決方法があるんだ!」という気づき

といった事でしょう。
そうなると、読むべき章としては、

 

  • (Abstract)
  • Introduction, Background and Motivation
  • Design(Implementationの部分は興味があれば)
  • Conclusion

 

辺りを読むと良いのかな、と。

Introductionでは、「存在する課題」、「それに対してこれまでどう解決しようとしてきたか(学術的な話に限らず、例えばLinuxにおいてどう実装されているか、といった内容も多いので、読むだけで知識が広がる)」、「それをどう解決するか、なぜそのような解決方法だと有用なのか」といった事が書かれています。これらについては、BackgroundやMotivationといった章として独立している事も多いです。

Designは解決方法の全貌です。折角論文を読むからには、「どう解決されたか」を読まないと勿体無いですよね。

Conclusionは論文のまとめで、「結局この論文が何を言いたかったか」がまとまっています。僕は、一通り読んだ後の復習として「自分がこの論文を理解できたか」を把握するために読んでいます。

 

これらの内容は、研究者でなくても知識として知っておく事でいろいろな事に応用できるでしょう。学部生の皆さんでも十分に知っておく価値のある事です。

 

Related Workも読むと知識が増えるから良いよ、なんて言われますが、これは既存研究の列挙なので、研究を始めたら読んだ方が良い一方、研究が人生の中心ではない皆さんは別に読まなくても大丈夫なのではないかなと。

 

さて。

「論文はこう読もう!」という話をダラダラと書いてきた上でこんな事を言うのも何ですが、僕の方から1つ注意点を挙げさせてもらうと、論文を読んでそのまま鵜呑みにはしないでください。

論文に書かれている事は論理的に正しい事が多いのですが、やはり研究という枠で行われている物なので実社会と結びついていない事もあります。

例えば、

  • 「起こりうるかもしれない未来の話」を仮定して問題設定をしているかもしれない。
  • 問題設定が物凄く条件を限定した、実社会では起こり得ない事かもしれない。
  • 解決策を実アプリケーションで採用するには課題があるかもしれない。
  • そもそも実アプリケーション上では起こっている問題を解決できないかもしれない。

とまあいろいろあります。

トップ学会に通っている論文は、比較的これらの「アカデミアあるあるな実社会と結びついてない良くない部分」が少なめではありますが(これもまたトップ学会の論文を読む事と良い、と言われる理由ですね)、それでも多少はあると思って読んだ方が良いでしょう。

「実社会に影響を与えなければ、その研究は無価値だ」とまでは言いませんが、書いてある事を全て鵜呑みにしていくと、「実社会とリンクしていない、机上の空論を並べただけの頭でっかち」になってしまうだけです。

なので、「論文に書いてあるこの部分は実社会とリンクしているだろうか?」という事は常に頭の片隅に置いておくと良いのではないでしょうか?

 

2. 手を動かそう

これについてはこの記事でアップデートする程の物でも無いのですが。

まあでも折角なので、論文読んだ時に得た知識等が自分の書いている物にある程度反映できると良いですよね。

 

「OSを今更作って何の意味があるんだ!」なんて事をよく言われますが、そういう人は放っておくとして、論文を読めば「まだまだOS周りでできる事いっぱいあるじゃん!簡単な物を自分で作ってみても意味があるかもしれないじゃん!」みたいな気持ちになれるかと思います。

(まあどんな論文読むかにもよるんですが。Linuxの改良、みたいな論文ばかり読んでいてもそんな気持ちにはなりにくいので笑)

 

本当は論文で読んだ物を軽く実装してみる、みたいなのが一番良いのですが、システムソフトウェア系の論文って、いざ自分で0から実装するのは結構大変だったり・・・。

それを何とか解決したくて裏でチマチマ作っている物もあるんですが、その話はまた暫くしたらブログに書くかもしれません。

 

3. 自分の頭で考え、議論しよう

中高生版では「自分の頭で考えようね」という話を書きました。

大学生になったら、周りに情報系の友達も(たぶん)できると思うので、そういう人たちと議論してみましょう。

 

議論する事のメリットは、

  • 自分の知識を口に出して説明する事で、理解の浅さに気づいたり、より知識を定着させる事ができる。
  • 自分の意見を説明する事で、その意見の論理的に弱い部分を周囲に指摘してもらえる。
  • 他の人の知識や意見を学ぶ事ができ、価値観が広がる。それによって新しいアイディアが生まれる可能性が増える。

といった所でしょうか。

 

別に友達がOSに詳しくなくても構いません。(もちろん詳しい人の方が良いんだけど)「OSを教えてあげるよ!」という体でその友達と喋れば、自分の知識の整理だけでもできますよね。初心者ならではの視点や発想、なんてのも得られるかもしれません。

 

もちろん、友達がいないと話は全く始まらないんですが。コミュ障辛いね。

 

4. アウトプットする

これはもうアップデートする程の事は無いでしょう。

大学生になったら、時間の自由度や経済力を活かして、勉強会で発表したり、イベントに参加できたりしますよね。

ま、これも引っ込み思案な人間には辛いんですけどね。お家に引きこもるのタノシイ

 

 

 

 

 

 

 

 

だいぶ長くなってしまいましたが、いかがでしたでしょうか?

「論文読もうね」という話が殆どを占めていますが、できるだけ具体的に書いてはみたので、多少は参考になると嬉しいな、と。

ここに書いてある事って研究室配属後だと当たり前の話だと思うんですが、こういう事を学部生の自分に教えてくれる人、僕の周りにいなかったんですよね。少なくとも僕は学部生自体、こういう話めっちゃ知りたかったです。というわけで未来ある若者向けに書いてみました。

 

 

もう6200文字とか書いてるのでさっさと終わらせたい所なんですが、最後に宣伝させてください。(中高生編を読んだ方からすれば「またかよ!」って話ですね、ごめんなさい)

 

今回の記事に書いた内容を、僕が直接サポートしながら実践するという機会を作りました。ここに書いてある内容、いざ一人で実践するのは中々難しいと思うので。


「セキュリティ・キャンプ2018全国大会」(公式サイト)「集中開発コース、YI OS開発ゼミ」の中の「最先端OS談義」というテーマです。

 

テーマ詳細は以下のブログ記事を参考にしてください。

 

raphine.hatenablog.com

 

22歳以下の学生なら参加可能で、費用負担0なので、是非ご応募ください!
応募〆切は5/28です。

ご応募お待ちしております!

普通の中高生でも簡単にOS分野で強くなる方法

釣りタイトルだと思った皆さん、残念ながら本記事は釣り記事ではありません。

安心して読み進めてください。

 

 

 

 

「強くなりたいです。どうやったら強くなれますか?」

 

恐らく情報系の多くの人が抱えている疑問なのではないでしょうか。

「I know everything」みたいに言える人って中々いないですよね。

ちなみに、僕も強くなりたいです。

どうやったら強くなれるんでしょうね。もし強くなれる方法があったら知りたいですよね。 

 

そもそも強さって・・・何だ?

そもそも論で行くと、「強くなりたい」とだけ言うのは少し微妙で、どのように強くなりたいか、という具体的なイメージがあった方が良いのではないかとは思うのですが、まあそんな事を思う人は恐らくこのブログを読んでいない事でしょう。

 

なのでこちらで「強さとは何か」を邪推してみるわけですが、このページを読んでいらっしゃる中高生の皆さん的には、「周囲にドヤれる、twitter上とかでブイブイ言わせられるくらいの知識があったり、技術力があったり」みたいなのを求めているのかなぁ、と。

 

で、それくらいなら簡単なんじゃね?って思ったので、僕が思う「『普通』の中高生でも『簡単に』OS分野で強くなれる方法」を書いてみたいと思います。

どれくらい強くなれるかというと、OS分野に限って言えば、そこら辺に転がってる情報系の大学生よりは強くなれると思います。大学院生の自分からすれば当たり前なのだけど、これを中高生の頃の自分に知っていれば、もっといろいろ世界が広がっていたと思うので、共有させてください。

 

 

1. 手を動かそう

絶対に必要な事として、手は動かさないとダメです。

ただ漠然とtwitterを眺めていても当然強くはなれないですし、Google検索で出てきたページを眺めたり、本屋で買った本を読んでいるだけでは強くなれません。

強くなりたければ実践あるのみ。コードを書きましょう。いろいろな壁にぶつかると思いますが、その壁を乗り越える事でしか強くなる事はできません。

 

皆さんご存知の「30日でできる!OS自作入門」はコードを書く上でとても参考になります。

 

 

 もちろんこの本を読んだだけではダメで、実際に書籍内のコードを動かし、自分で書き、そして本の内容から外れた、オリジナルなコードを書いてみる必要があります。

 

とはいえ、OSに興味がある方ならこのステップはそんなに苦では無いでしょう。

「OSというブラックボックスを自分の手で書けるんだ!」というワクワク感から、自ずと手が動いてしまいますよね!

 

この本を読む上での注意ですが、この本はあくまで「自分でもOSは書けるんだ!」という事を読者に理解させるのが目的の本で、「OSについて学ぶ」本ではないです。(ちゃんと節々にその注意書きがありますよね)

なので、この本を読んだだけでOSの全てを理解したと思わない方が、OS分野で「強く」なれると思います。

 

「OSについて学ぶ」事にはそんなに興味はないんだけどなー、なんて人もいるかもしれません。もちろん、OSについて学ばなくても、持ち前の高い技術力で素晴らしいアウトプットを出せる方にはそういった話は不要なのですが、僕のような「普通の人」は、やはり一度は「OSについて学んでおく」事をオススメします。なぜなら、一度OSの基礎を学んだ人間の方が、その後で手を動かした時に出てくるアウトプットの質が上がるからです。

 

じゃあどうすれば良いのか、というのが次の話。

 

2. 大学の情報系学科のOSの授業スライドで自習する

多くの情報系の学科では「オペレーティングシステム」という講義(あるいはそれに類するもの)があります。その資料を手に入れ、自分で勉強しましょう。

大学の学部の授業は、専門家によって作られているだけあって、一通りの基礎知識をきちんと過不足無く教えてくれます。これをマスターするだけで大学生に肩を並べられるだけの知識がつくでしょう。

基礎を学ぶ事は大変重要です。基礎を学ばないと、学ばかなかった事によっていろんな所でつまづいてしまいます。つまづいて失う時間は基礎を学ぶのに要する時間よりも明らかに大きいので、とても非効率的なわけです。手を動かすときも、「知識があった上で手を動か」した方が作れる物の幅も広がるし、それによって得られる物も大きくなります。

(もちろん、これは「大学の講義の内容なんて学ばなくても、0から同じ内容を自分で再構築できるぜ!」と言い切れるぐらい強い中高生には当てはまりませんが、一応これは普通の中高生向けの記事なので)

 

というわけで、大学の講義を自習すると強くなれるよ!という所までは伝わったと思うのですが、恐らく中高生の皆さんにとって、大学の授業というのはイマイチイメージがつかないものだと思います。大学では凄く高度な教育が展開されてるから、今の自分には難しいかも・・・なんて身構えたくなる気持ちもわかります。

 

しかし多くの大学生は、試験直前に慌てて授業資料をWebからダウンロードし、一夜漬けで勉強してなんとか試験を乗り切るものです。よほど良い教員の授業を除いて、教員の講義なんてあってないようなもの。

大学の授業なんてこの程度の物なんですから、中高生の皆さんでも自力でなんとか勉強できそうですよね?

勉強できるという事は、巷の大学生並の強さにはなれそうですよね?

 

参考として授業資料がダウンロードできるリンクを貼っておきます。

 

東京大学理学部情報科学科「オペレーティングシステム

www.pf.is.s.u-tokyo.ac.jp

 

東京大学電子情報工学科・電気電子工学科「オペレーティングシステム

https://www.eidos.ic.i.u-tokyo.ac.jp/~tau/lecture/operating_systems/

 

勉強する上での注意として、「スライドをただ読み進めるだけ」というだけではさほど強くなれないので、オススメはしません。それだとそこら辺の大学生と同じになってしまいます。

 

スライドを読む時は、「自分が他の人にスライドを使って講義できるようになる」ぐらいまで理解しましょう。(具体的にはこの記事を自力で書けるくらいになると良いですね)ほんの少しでも理解していない所が残っていると、それを聞いた人は容赦なくツッコみを入れてくるものです。怖いですね。手を抜かず頑張りましょう。

 

 

3. 自分で更に膨らませて考えてみる

勉強しただけで終わり、ではその先の成長がありません。

基礎知識が身についたからといって考えるのを止めず、ふとした拍子に気づいた事やアイディアについて想像を膨らませましょう。

アンテナを広げて、いろいろ情報収集をしましょう。SNSGoogle検索を活用したり、勉強会に参加したりすると、きっといろいろな学びや気付きがあるはずです。

基礎をきちんと築いた上で得られる学びや気付きは、とても価値のあるものです。それを大切にしましょう。

言うまでもない事ですが、学びや気付きを得たら、手を動かしてくださいね。

 

4. 手を動かした事をアウトプットする

これは有名な話なので、私がわざわざ書くまでもないですよね。

自分がやった事をブログに書いたり、勉強会で発表したりすれば、いろいろな人に自分の事を知ってもらえて、良い機会に巡り会える事も多くなるでしょう。

 

 

 

長くなりましたが、要するに「基礎をきちんと学び、手を動かし、アウトプットする」事をバランス良くやってね、っていう事です。どれかが欠けてもダメですよ。

いかがでしょう?中高生の皆さんでも簡単にできそうな事ばかりですよね?

 

補足:大学生の方へ

もしかしたら大学生の方もこの記事を読んでらっしゃるかもしれません。一応誤解なきように書いておきますが、「大学生の場合はここまで書いてきた事を全てやっても、強くはなれません」。

大学の講義をきちんと身につけるのなんて当たり前だし、課外活動だって当たり前。ここに書かれている事は「少し強い大学生」なら皆やっている事です。

この内容を中高生が実践してなぜ強くなれるかというと、彼ら、彼女らには「年齢的アドバンテージ」があるからです。

大学生の皆さんがもっと強くなりたいのであれば、他にもやらなければいけない事があるわけですが、それはまた別エントリで。

 

追記:書きました。

raphine.hatenablog.com

 

宣伝:セキュリティ・キャンプ2018

最後に宣伝させてください。

 

「強くなるための方法」として上で挙げた内容ですが、最初から一人で全てやる、というのは少し不安ですよね。

 

そこで、それを私がサポートする機会を作りました。

「セキュリティ・キャンプ2018全国大会」(公式サイト)というイベントがこの夏開かれます。「集中開発コース、YI OS開発ゼミ」の中の「最先端OS談義」というテーマは、「皆さんが自分の力でOS分野で強くなれる」事を目指す物です。まあ、有り体に言えば、このブログ記事に書いてある内容を、私がサポートしつつ実践してみる、っていうテーマですね。

 

学生の皆さんの金銭面での負担は一切無いので、是非ご応募ください。

私のテーマの詳細については、以下のブログエントリーで解説しています。こちらも参考にしてみてください。

raphine.hatenablog.com