2014年12月25日木曜日

ブートローダーは4行で実装される

この記事はUEFI Advent Calender自作OS Advent Calenderのためにかかれました。
22日(+3日)の記事です。

遅れてもうしわけないです。

ブートローダー

まず、自作OSにはブートローダーによってカーネルをロードしなければはじまりません。
特段複雑なローダーがなくとも、たとえばBIOSから直接起動するのなら
そのための形式で用意せねばなりません。
しかし、これが自作の入口としてかなりの関門になってしまっているのではないでしょうか。

なので自作OSからはちょっと離れますが、ブートローダーについて書きます。

UEFI

ということで、UEFI Appsとしてブートローダーを実装する話です。
まず、UEFIとは何かについてはUEFI Advent Calender 1日目の記事を、
そしてこの作業の前知識としてUEFI Advent Calender 12日目の記事を参照していただけると良いです。

一応ざっとUEFIについて触れておくと、
BIOSの代替規格のファームウェアで、多機能かつ高機能。また、可搬性も考えられています。

UEFIのファームウェア上で直接動作できるUEFI Appを記述するには、
tianocoreがBSDLで公開しているEDKというツールキットか、
Gnu toolchainと合わせて使えるgnu-efiというBSDLのライブラリを用います。
EDKでも一応gcc等が使えます。

EDKは、パッケージとして豊富にライブラリが揃っており、libcやbsd socket、pythonがつかえます。
gnu-efiは、Linux/OS Xの上で開発するにはEDKより手軽にはじめる事ができます。

UEFI AppはWindows同様PE形式のバイナリなので、
実はEDKやgnu-efiがなくとも*.dllなバイナリ(つまりrelocatableでsharedなPEバイナリ)を作成してから、objcopyコマンドとかで必要な部分だけ取り出して拡張子がefiのファイルにするとかでも一応動作できるバイナリを作る事は可能です(が、面倒です)

UEFIのAPIであるProtocolは初期状態でもFile I/OやGraphicsの処理まで揃っていますが、
自分でUEFI Driverを実装してこのドライバをロードすればProtocolを増やせます。
今回はDriverは実装しません。

実装

さて、そしてUEFI Appとして実装されたブートローダーがこちらになります。(料理番組風)
後でコードの説明をするので、最初は読み飛ばしても結構です。

いきなりコード貼ってしまいましたが、そんなにコード量はないですね。

Protocol

さて、UEFI Appですが、uefi_mainというエントリポイントが
EFI_IMAGE_HANDLE、EFI_SYSTEM_TABLEという引数をとって起動していますね。
InitializeLibを行なっているのは、gnu-efi独特の作法です。

その後早速Print();なんてやってますが、これでいきなり文字列出力ができてしまいます。
単純ですね。

その次からが、肝心のブートローダーです。

UEFIのAPIは、ただ関数コールすれば良いものではありません。
全てのProtocolには、それぞれの構造体が定義されています。
BIOSメーカーでありUEFIコンソーシアムの参加企業でもあるPhoenixのwikiに、
構造体の一覧が見やすく書いてあるのでこれを見ると良いです。

UEFIのProtocolは、まず使いたいProtocolと同名の型の構造体を宣言し、
OpenProtocol();にその構造体と、使いたいProtocolのGUIDと、いくつかのオプションを渡すことで、
渡した構造体のメンバに欲しい情報であったりとか、必要な関数ポインタが代入されます。

そこで、その情報を使うなり、関数ポインタから関数を呼ぶなりして、Protocolは使われます。

しかし、OpenProtocl();自体もある種のProtocolの関数であるため、そのような関数がグローバルに
宣言されているわけではないです。

ではどうやってProtocolを呼ぶかというと、UEFI Appの起動時に
BSという大域変数(EDKの場合はgBS)にEFI_BOOT_SERVICEのProtocol構造体に
必要な情報が詰められて最初から使えるようになっています。
よって、BS->OpenProtocol();のようにして、Protocolを呼び出します。

このブートローダーのコードでは、Print();の次にuefi_call_wrapper();という関数の
第一引数にBS->OpenProtocolを渡していますが、
これはUEFI Protocolの呼び出しが一般的なC言語の関数呼び出し(cdecl規約)ではなく
Win32API同様のstdcall規約を用いているためのwrapperです。

uefi_call_wrapper(つかいたいProtocolの関数ポインタ, その関数の引数の数, その関数への引数);
という使い方になります。

ブートローダー仕組み

では、ブートローダーの本格的な部分である17行目以降から解説します。

まず、エントリポイントの引数であったEFI_IMAGE_HANDLE型のImageHandleを使って、
EFI_LOADED_IMAGE_PROTOCOLを構造体LoadedImageParentに入れています。

このIMAGEというのは、実行メモリイメージの事(だと思われます)
ImageHandleについては実行している自分自身のハンドルになります。

LOADED_IMAGE_PROTOCOLというのは、自分自身やBS->LoadImage()によって
既にメモリ上にロード済みのイメージに対して情報を得る事ができます。

続く23行目では先程入手した自分自身のハンドルのDevicePathを使って、
\vmlinuzというファイルパスのファイルをEFI_DEVICE_PATH型の変数に代入しています。

これはどういうことかというと、
自分自身はブートローダーなので、かならずEFIのシステムパーティションに置かれています。
このパーティションはHDDの先頭のパーティションでFAT32です。
なので、自分自身のDevicePathはこのシステムパーティションのDeviceそのものを指す事になります。
更に、\vmlinuzということなので、このシステムパーティションのroot directoryにあるvmlinuzファイルについてのDevicePathをPathという変数に格納した事になります。
このDevicePathはブートローダーがカーネルをロードするのに用います。

29行目のBS->LoadImage()で呼び出しているのがそれです。これでカーネルはメモリに展開されています。

46行目のBS->StartImage()でこのロードされたイメージを起動するだけで、カーネルは起動されます。

29行目と46行目の間の処理は、ロードしたカーネルイメージについてLOADED_IMAGE_PROTOCOLを手に入れ、LoadOptionsというメンバに起動オプションを
指定することで、カーネルコマンドラインを指定しています。

自作OSをつくる上では、エラー処理や後処理を省くと、
17行目 23行目 29行目 46行目
この4行の処理のみでブートローダーは完成してしまっています。

さらに、USBメモリなどでEFIシステムパーティションのみで完結させる構成のディレクトリに
このようなブートローダーと自作カーネルとあと必要なバイナリや設定ファイルを適当に配置して
しまうだけで、おそらくさくっと自作OSの入口に立つ事が可能でしょう。



と、いうことで、自作OSをしたい方は是非、UEFIを前提に考えてみてください!

なお、このブートローダーでLinuxカーネルを起動してみたい場合、
EFIシステムパーティションのroot directoryにvmlinuzとrenameされたカーネルを配置し、
11行目のカーネルコマンドラインを自分の環境に合わせて書きなおしてください。
また、initrdについては度外視しているので、カーネルにroot partitionのファイルシステムのドライバを組み込んでおかないと、起動時にroot partitionがmountできずカーネルパニックを起こします。

このブートローダー自体は、EFIシステムパーティションの好きな所において、
bcdeditなりblessなりefibootmgrなりでUEFIにそのPathを登録するか、
UEFI Shellから直接このバイナリをたたいてやってください。

上記コードのMakefileも含めたリポジトリはこちらになります。
https://github.com/orumin/SimpleMyLoader

2014年12月20日土曜日

UEFIアプリケーションのはじめかた

UEFI Advent Calender 12日目だったoruminです
盛大に遅刻かましてもはや遅刻とさえ言えない感じです。

UEFIのアプリケーション、まずどう作るかわからない方も多いかと思います。

まず、UEFIが実行できる実行形式について、これはWindowsと同じPEバイナリです。

また、EDKのようなツールキットを用いる必要がありますが、
今回はgnu-efiで説明します。

gnu-efiとは、BSDLなEFIアプリケーション開発用ライブラリです。
LinuxやBSDでの開発に親和性が高いと思われます。

これは最近だとaptやpacmanでそのままバイナリインストールが可能です。

そして、次にこのようなファイルを用意します




前者がUEFIでのHello, World!です。efi_mainがエントリポイント、
ImageHandleもSystemTableもUEFIのAPI(Protocol)を呼び出し、使うのに必要なパラメータとなります。
今回は、gnu-efiの初期化をしてから文字列を出力するだけなので特に使用していません。
デバッグ文字列出力は
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Hello, EFI!\n");
でも良いのですが。

後者のMakefileについては、書いてある通りです。
ライブラリとインクルードファイルの指定、
それにリンカスクリプトやスタートアップルーチンはgnu-efiのものを使うように指定。
shared objectな実行ファイルを作ってから、
objcopyコマンドで必要な部分を抜き出す(ELFヘッダは要らないので)
という流れになります。
CFLAGSについては、色々ごちゃっと指定してますが、
まず必須なのは-fPICと-fshort-wchar、そしてx86_64であれば-DEFI_FUNCTION_WRAPPERだけで、あとのは特段必ず指定しないといけないものではないです。

さて、これでmakeをしますと、hello.efiが作成されるので、

あとはEFIシステムパーティション直下にでも置いてあげて、起動時にUEFI Shellを立ち上げてから
hello.efi
とコマンドを入力してみてください。Hello, EFI!と文字列が出たら成功です!

UEFIの開発やProtocolについては、1日目の記事の最後に書いたドキュメントがオススメですが、
リファレンスよりも手軽にProtocolの型や名前だけ把握するには、
Phoenixのwikiが便利です。

2014年12月10日水曜日

@toshi_aにTLを大破させられて1年がたちました……

mikutter Advent Calender 9日目の記事です.

みなさん,去年のAdventCalenderは覚えておいででしょうか.きっと,
全部覚えてる人は少ないでしょう.

@toshi_a被害者の会

http://orumin.blogspot.jp/2013/12/toshia.html

mikutter Advent Calender 2013 8日目の記事の様子です.
TLを壊されました.そしてささやかな復讐をしました.

そう,あれから1年がたったのです.

何か記念(怒)に書こうと思ったのですがネタが特に思い付きませんでした.
適当に今年の振り返りでも書きます.

あれから色々ありました.

まずなぜか@toshi_aさんにフォローされました.

そして,
とりあえず私がひっこしたおかげでイベントとかに参加しやすくなったので,


なんか貰ったんですね,初夏の京都のOSCで.
おかげで部屋に彩りが増えました.
ありがとうございました

とくにそれからはmikutter関連でなにかあったりはしてないのですが,
mikutterそのものは3系になりさらに進化して良いです.
ArchLinuxユーザーの私は新しいmikutterをすぐに使えてとても有り難いですね.
ということでArchをつかおう!

あれ,なんかArchの宣伝になってしまった,まあいいや,oruminでした.

2014年12月3日水曜日

Ruby on OSv

これはOSv Advent Calender 2+1日目の記事です.
グアムのハワイのワイキキビーチで書き上げたからまだ12/2という"てい"でよろしくおねがいします.



OSvのCRuby移植担当してたoruminです.
OSv1日目の記事@syuu1228さんが説明されていた通り,現在OSvで
複数の言語ランタイム/アプライアンスが動作します.

CRubyも移植は一応の完成を見ることができ,動作させる事が可能です.
今回は動作方法について書きます.

じゅんび

まずはリポジトリのcloneから.
$ git clone http://github.com/cloudius-systems/osv.git osv
その後,忘れずsubmoduleをinit & updateしましょう
$ cd osv && git submodule --init update
ビルドのためには,いくつかパッケージが必要です.
https://github.com/cloudius-systems/osv/blob/master/README.md
に必要なパッケージはFedora,Debian,Archについて記述されています.

しかし,Fedora20を用意できるのであれば,osvのディレクトリで,
$ sudo ./script/setup.py
と実行すれば必要なパッケージを全て準備してくれます.

ビルド 

ビルドは単純です.
$ make -j`nprocs` image=ruby-example
このようにしたら,あとはビルドが終わるまで待機です.
なお,rubyのビルド中にエラーで失敗する時は,-jフラグを外してもう一度やってみてください.
まだrubyとosv kernelの並列ビルドがうまくいかない時があるようです(すみません)

実行

次のスクリプトでOSvは実行できます
$ ./script/run.py
どうでしょうか? うまくいけば
OSv v0.16-814d434
eth0: 192.168.1.89
Hello, world!
のように表示されます.
また,
$ ./script/run.py -e "/ruby.so /irb"
のように起動引数を手動で設定すれば,irbが実行できたりします.
apps/ruby-example/sample-codes/に,このビルドされたイメージファイルで他に
実行できるサンプルのrubyスクリプトもあるので,適当に指定してみたりして試してみてください.

2014年12月1日月曜日

What's UEFI

UEFI Advent Calender一日目,oruminです.

初っ端なのでまずUEFIとは何かについて書こうと思います.

・UEFIとは?

UEFIとは,ファームウェアの一種です.
一般的なPCはBIOSからOSを起動している事はご存知だと思われますが,
実はBIOSは最早過去の遺物となりました.

BIOSの代替として2000年頃からIntelが開発していたEFIは,
多くの企業とコンソーシアムを立ち上げ,現在UEFIとして規格が策定されています.
2010年頃からはIntelのマザーボードを皮切りとして一般向けにも採用され,
現在市場にあるPCのほぼ全てがUEFIでしょう.
BIOSの設定画面だと思っているそれは最早UEFIです


・BIOSとの違いは?

大きな違いはデファクトスタンダードとしてなんとなしに採用されてきたBIOSと違い,
多くの企業のコンセサスの元策定された規格が存在し,閲覧が可能である事です.

この規格は,ブートローダや診断ツールといったものの開発が容易であるよう,
プログラミングのためのインターフェイス,APIが規定され公開されています.
これを扱うためのSDKが公開されているため,C言語やPythonといったもので
診断ツール等を記述可能になっています.

なんと,UEFIのAPIを用いて記述したアプリケーションプロラムは,OSが起動する前の段階(pre-OS Environment)でUEFI内蔵のShellから起動する事ができます.

また,IBM-PCの時に作られたBIOSは16bit Intel CPU前提のアークテクチャであるため,
多くの制限がありましたが,UEFIの場合はこの制限が無くなり,CPUのアーキテクチャに非依存です.Intel CPUのReal modeでないとBIOSから起動できない,などという事がないためブートローダーも16bitでなく32bitプロセッサなら32bit,64bitプロセッサなら64bitの命令がつかえるため,メモリも潤沢に使えます.

現在はx86,x86_64,AArch64のUEFI実装が存在します.

そして,一番のBIOSとの違いはブートシーケンスにあるのではないでしょうか.

・UEFIのブートシーケンス

BIOSは,当初のその制約から,ディスク先頭の第一セクタしかロードできませんでした.
よって,現在はその第一セクタ ― ディスク先頭512バイトの領域に
ブートローダーとパーティションテーブル(MBR)を格納し,そのブートローダーからOSを起動するという仕組みが一般的でしょう.
このブートローダーがMBMであればさらにパーティション毎の先頭のセクタ(PBR)のブートローダーを起動し,そのブートローダーが宜しくやってくれるというわけです.

この第一セクタ,つまりブートセクタをつかう方法は今や旧い方法となりました.
このブートセクタに置かれるブートローダーは容量の制約上技巧的な物にならざるを得ませんし,普通のファイルの容易に書き込みや入れ換えができるものでもないです.
多段階的な方法を取らねばマルチブートできないのもBIOSの制約から来るものです.

UEFIでは,ディスクの第一パーティションをFAT32でフォーマットし,これをシステムパーティションと呼びます.このシステムパーティションにUEFIのSDKで記述したアプリケーション,ブートローダーを配置します.
UEFIのアプリケーションバイナリはWindowsのEXE同様,PEバイナリとなります.

さて,このファイルをどう起動するよう指定するかというと,
UEFIのファームウェアそのものにブートマネージャーというマルチブートの際のOS選択画面の機能のようなものが備わってます.
このブートマネージャーに,ブートマネージャーに表示するエントリ名と,ブートローダーやUEFIアプリケーションのシステムパーティションでのパスを指定し,登録する事が可能です.
よって,OS毎に専用のローダーをUEFI SDKで記述し,それぞれのローダーをこのUEFIファームウェアのブートマネージャーに登録するだけでマルチブートが可能となるのです.

MBMやGRUBのような巨大なマルチブートのための"からくり"はもう必要ないのかもしれません.

もう一つ,ここで重要なのは,パーティションテーブルはMBRではなくなり,GPT形式となります.これは,パーティション数が最大128となり,1つのパーティションも2TiBの壁を越えて設定できます.パーティションの管理はGUIDを用いて行なわれます.



以上,軽くBIOSのおさらいも兼ねてUEFIとの違いに触れました.
UEFIのもう一つのBIOSとの違いとしてセキュリティ面で大幅に変化がありましたが,
これはまた別の機会に触れたいと思います.
また,度々文中に記載しましたがUEFIのSDK(EDK)の存在によりブートローダーの
作成は容易化しました.自作OSを作成する場合にもこれは大きなアドバンテージではないでしょうか.このEDKについても別の機会に触れたいと思います.

最後に,UEFIのドキュメントを紹介します.
まずUEFIの規格書は最大のドキュメントでしょう.
http://www.uefi.org/specifications

また,Intelが出しているペーパーブックは
UEFIアプリケーションの開発等で役立つほぼ唯一のドキュメントです

2014年11月27日木曜日

オーディオアンプを作ってみました。

初アンプ自作。

ぺるけさんのFET作動式ヘッドフォンアンプを作成。


ぺるけさんの作例をそのまま使わせてもらってます。
ただ、シャーシの穴開けをボール盤使える環境にある友人に依頼した時、依頼ミスで左右が反転したのでラグの位置等もそのようになってます。おかげで音量ツマミが左側になりましたが些細な事でしょう。
結局他にいくつか穴を開ける必要出てきて結局電動ドリル買いました。
ぺるけさんはオーディオクラスでないパーツを使っておられましたが、私はなんとなーくコンデンサを東信工業のUTSJにしてみました。初アンプ自作ですしオーディオに対して無知なのでこのコンデンサにしてどうとかあんまりわからんのですが。

一発で音が出て感動してますし、個人的には結構良いように思えます。
あとはボリューム抵抗のシャフトを切る道具もってなくてツマミをつけず裸のままにしてるのをなんとかしたいです

電気式華憐音楽集団2nd Live "Gig Detonator"

表題通りのライヴに参加してきました。




グッズ類

BLACK BOX、white box、Red Box

ライヴ、あまり行ったことなかったのですがなかなか楽しめました。
良いものですね。

ガジェットってどんどん増えますよね

最近買ったガジェットとかマシンとか。

まずPC-98

ええ、最近、最近買ったマシンです。
キーボードはPTOSキーボードなのでALPS電機の黄軸メカニカル!

PPC Mac (G5)

画像中央、スカイセンサー5800の台になっちゃてるやつです。
ええ、これも最近入手しました。はい。


3D対応シアターで使われてる3Dメガネ。ジャンク屋で入手
秋葉原の三月兎ですぐ売り切れたと話題の、PC-98やx68k向けCF2SxSI変換機、日本橋仕様。
生産中止した古い型のUSB TrackPointキーボード(US配列)


それと最近お気にいりのガラクタ屋でコントローラ付で1000円だったスーパーファミコン


という感じでなんか自宅のほうがジャンク屋になりかけている……むしろジャンク屋が自宅説

ちくわパフェだよ☆CKP!

事の発端。
特に意味も切っ掛けもない。ふと、思い付いた。
その後30分に渡りちくわちくわずっとtweetする。









抜粋。何のことだかさっぱりだと思う。なんだろうこれ。よくわからないテンションだった。
この調子でずっと居たので、この後出掛けて、帰りがけに色々買ってきてしまった。

これ、グラスも一緒にかってきてる。
自前ホイップ。
自前チョコソース。
無駄に凝った。


なぜだか完成してしまった。ちくパです。
みんなもやってみてね☆

BtrFSが死んだ。

10/27、突如ラップトップの/homeがRead-Onlyに。
Linux3.17.1をつかっており、FSはすべてbtrfs。
/homeだけは一時間に一度スナップショットを取っていた。



アッ……
スナップショットとるとトランザクションが壊れるバグが3.17.0と3.17.1に発生してたらしい。
3.16.xから3.17.xにupdateして、24時間も経たぬ出来事であった。



なるほどね?

btrfsckで事無きを得たと思ったけど、backrefが死んでいた。
この状態でも普通にログインしてデータをR/Wして、と出来ていたのだが、
backrefについてのエラーがずっとdmesgに流れるのは精神衛生上よろしくない。



だそうです。

btrfsck --init-csum-treeを断行。

結果。
悪化しました♡

そこで、btrfs restoreコマンドを実行。

btrfs restoreで、どのディスクをどのディレクトリにrestoreするか指定して、ひたすらrestore。

input/output errorが出たりして完全に読み書きできなくなったファイルも欠けなく全部サルベージできました。やっぱりBtrFSってすごい。

んで、結論として、FSの復活は無理だったので、mkfs.btrfsでフォーマットしました(懲りずにbtrfsをつかう)
restoreしたファイル郡をそのまま再び書きなおして、UUIDが変わったのでfstabを書き直して、終わり。

無事復旧しました、めでたしめでたし……

ニキシー管工作

夏のコミックマーケット(C86)でニキシー管時計のハウツーと部品を頒布しておられる
方(@euc_さん)がいたので、おもわずゲット。
8月の終わりに工作してみました。
開始風景

http://nixie-tube.com で販売されてる昇圧回路をつかいます。
表面実装だけなのでラクちん。

点灯確認。これだけでめっちゃテンション上がりました。
ニキシー管は足が13本もあるのでブレッドボードに載せるだけで苦労……

たぶんユニバーサル基板にニキシー管を8本載せるってあたりが一番苦労しました。
今度やる時は基板をEagleかなんかで実装してからやって配線はプリントでしたほうが良いと思う。

奥から、昇圧回路、フォトカプラでスイッチングするやつ、ニキシー管、Arduino uno、Arduinoのシールド。これらを接続
デン。

はい、ということでちゃんとダイバージェンスメーターみたいになりました!

いまこれ時計として使ってます。
ニキシー管は浪漫。

タモリカレー

夏のある日、思い立って作りました。
http://www.1101.com/curry_club/pdf/recipe.pdf
のレシピをそのまま参考に。


これが材料。

以下調理風景ダイジェスト

そして完成
手込んだことしただけあって、達成感。

Google Summer of Code 2014

無事終了しました。

今回私はCloudius Systemsの作るOSvの開発に参加しました。
これはクラウド向けに最適化されたOSで、ハイパーバイザをターゲットにしているものです。
元々はJVMの起動だけをサポートしてましたが、これにCRubyの移植を行ないました。

現在OSvはOpen betaをリリースしているので、是非試してみてください。

IIJmio

しばらく書いてなかったブログに書いていこうと思います。 8月頭まで遡りますが、Nexus7のためにIIJmioのSIM買いました。 ついでにNTT西日本からのレンタルでLTE対応の光ポータブルというポータブルWi-Fiも入手。 捗る。

2014年7月15日火曜日

UEFIシステムパーティション

# gdisk /dev/sda
パーティションタイプはEF00
# mkfs.vfat -F 32 /dev/sda1


おわり

LinuxでもrEFIndしたい!

以前UEFIについてpostした時はGRUBで説明しました.
しかし,そもそもが複数ブートローダーをインストールでき,しかもブートメニューそのものをもつUEFIにとって,GRUBのような旧来のマルチブートの巨大な仕組みは必要でしょうか.

それと,MacユーザーがrEFInt/rEFIndつかってるのかっこいい

ということでrEFIndをLinuxでもつかおう!


2014年7月5日土曜日

Linux カーネルコンフィグ 晒し

TLで今カーネルコンフィグの話になってたから自分のカーネルコンフィグ置いてみる.
マシンはThinkPad Edge E145 (A4-5000) です

今回はこれだけのネタでした.
他の人はどんなコンフィグにしてるとか,このコンフィグこうしたらいいんじゃない?とか,募集してます.

2014年6月19日木曜日

UNIX and 2BSD on PDP11(SIMH) その2

前回からの続きなので前回から読んでること前提です

BSDを入れる前に

BSD関連についてはこちらを参考にした
http://gitter.matrix.jp/simh-for-unix/v6-unix-on-simh/
情報がよくまとまって非常にかりやすいサイトである.

インストールしたUNIXv6に2BSDをインストールする.
また阪大のミラーから
ftp://ftp.ics.es.osaka-u.ac.jp/pub/mirrors/UnixArchive/PDP-11/Distributions/ucb/2bsd.tar.gz
2BSDのtarballを入手.

ftp://ftp.ics.es.osaka-u.ac.jp/mirrors/UnixArchive/PDP-11/Bug_Fixes/V6enb/v6enb.tar.gz
からv6enbを入手し,解凍.cc -o enblock enblock.cとすることでenblockコマンドを作成.

gunzip -d 2bsd.tar.gz | ./enblock > 2bsd.tap
とすることで,tar形式でアーカイブされた2bsdのテープイメージ(simh用形式に変換済み)が手に入る.これを,UNIXv6に入れてアーカイブを解凍するだけ……なのだが問題がある.
tarコマンドはUNIXv7より追加されたコマンドでUNIXv6にはtpコマンドしかない.
tpコマンドも使うとtarにかなりよくにたオプションであることがわかる.

とりあえず,前回の記事にあるSoftwareKitからもってきたUNIXv7のイメージを用いる.
その前に起動スクリプトであるUV7に修正が必要.
2bsd.tapをUV7とかと同じフォルダにコピーしてきて,
UV7に
att tm0 2bsd.tap
att tm1 tape.tap
と書く.これで2bsd.tapはtm0にアタッチされ,tape.tapというテープイメージは新しく作られた上でtm1にアタッチされる.
そして,
# cd /tmp
# tar xv0 tar
# tp rm1 tar
としてやるとtm1にあるtape.tapにtarが書き込まれる.

ちょっとウンチク.
tarのxvは現代のオプションと同様.その後ろファイル名を指定して特定のファイルだけ取り出している.tpのオプションrmも現代のtarのrmと同様で,rはappendでmはmodification-timeだ.もっとも新しいアーカイブを作るときは専らcを使うのでrをつかわない人は多いはず.
後ろの0や1という数字は単純にテープデバイスの番号である.
当時はtarもtpもテープに対するコマンドで,*.tarのようなファイルをつくるわけでなかったからこうだった.後にファイルを作ったりファイルから解凍するときの特殊ケースとして,0や1といった数字の変わりにfオプションを使うようになったがそちらのほうが今では主になってしまっている.

閑話休題

何はともあれ,tape.tapというテープイメージがつくられたので,これをUNIXv6のフォルダに持っていき,起動スクリプトにatt tm0 tape.tapと書いてアタッチしよう.
あとはUNIXv6を起動し
# chdir /tmp
# tp xm0 tar # mv tar /usr/bin
とでもしてやればtape.tapからtarコマンドが取り出され,/usr/binに配置される.これでtarコマンドがUNIXv6に導入された.これで2BSDのインストール準備が整う.

2BSDインストール
とりあえずUNIXv6の起動スクリプトのatt tm0 tape.tapをatt tm0 2bsd.tapにする.
次に,起動してから適当なフォルダ(/mntとか)に2bsdというフォルダをつくり,
# tar x0 bin
とすると2bsd.tarからbinフォルダが解凍される.
あとは,
# chdir bin
# sh install
としインストールスクリプトを走らせると,/usr/bin/ucbにコマンド群がインストールされる.

もしかしてディスクの容量が足りない時は,simhのattでrkNのディスク増やして,mkfsでフォーマットして,mountをしてやれば良い.
/etc/rcに起動時のスクリプト(run command? たぶん今のrc.confとかの原型)があるので,そこにmountコマンドとかを書いてやると起動時にマウントしてくれる.
/etc/fstabは存在しない.

UNIXv6のテープからインストールした時は/usr/share/manにman pageがはいっててもmanコマンドがなく,nroffとかをするしかなかったはずだが/usr/bin/ucb/manが増える.

また,cr3というpagerも増えるのでmanページ等がまともに読めるようになるし,
 他にもviやらMailやらcshやら現在に続くコマンド群が使えるようになる.
問題は,PATHが通っておらず使えないので,まず/bin/cshにインストールされたcshを起動して,set path=(/foo /bar)のような形でPATH環境変数を設定しなければならない.

最後に,viをつかうには/etc/termcapにxtermのtermcapを追加した上で,
sttyで通信速度を9660にする必要がある.

最後に他にいくつか参考になりそうな場所があるサイトたち
2238クラブ,いろいろな過去の情報があつめてある
http://www.tom-yam.or.jp/2238/index.html

日記だけれども有用な情報多し
http://space.geocities.jp/hamesspam/hhwA/100805.html

ここではUNIXv7のテープイメージからインストールの手順紹介されている
http://pcmemo.take-uma.net/unixv7/install-v7-1

2014年6月6日金曜日

UNIX and 2BSD on PDP11(SIMH) その1

2010年ぐらいに初めてsimh-pdp11に触れてから,
ちょいちょいancient UNIXで遊ぶのですが毎回色々忘れてググってるのでメモ

まず普通にsoftware kitからUNIX v7を実行する方法
http://simh.trailing-edge.com/software.html
SIMHの公式ページの,Software Kitは様々なアーキテクチャの様々なOSをアーカイブしている
ここからUNIX v5〜v7を入手可能

uv7swre.zipをダウンロードしたら解凍し,
simh-pdp11(ArchLinux以外でビルドしたりしたらpdp11ってコマンドだと思う)をつかって,
$ simh-pdp11 UV7
で起動.UV7は起動スクリプト,simhのコマンド用のスクリプト
@プロンプトが表示されたら,
@boot
で起動
そして
:プロンプトで
:rl(0,0)rl2unix
として
RL11な0番目のディスクの,ルートにあるrl2unixというカーネルファイルを指定することで,
カーネルをブート

まずは#なプロンプトに落ちてシングルユーザーモードになるので,
^D(Ctrl-D)でマルチユーザーモードに移行
user:root password:root
でログイン可能.
あとはmailもつかえるし各種UNIXコマンドもつかえるし,困らない

exitコマンドではexitせず,^Dでログアウト

エミュレータの終了はCtrl-Eでsimhのプロンプトに抜けた後,simhのqコマンドを発行



次にUNIXv6をテープイメージからインストールする方法
http://d.hatena.ne.jp/oraccha/20101101/1288582382
を参考.oracchaさんが紹介されてるインストール手順のファイルは消えちゃってるけど,
http://shuntavista.jimdo.com/2013/01/05/unix-v6-%E3%82%92-simh-pdp11-%E4%B8%8A%E3%81%A7%E5%8B%95%E3%81%8B%E3%81%99%E3%83%A1%E3%83%A2-%E7%B0%A1%E7%95%A5%E7%89%88/
のブログで手順を公開されてる方がおられたので再現可能

http://gunkies.org/wiki/Installing_Unix_v6_(PDP-11)_on_SIMH
のほうでもテープからのインストール手順が公開されてる

http://wwwlehre.dhbw-stuttgart.de/~helbig/os/v6/dist.tap
がテープイメージ
上にあるsimhのSoftware KitでUNIX v6をインストールすると何故か
/usr/sysのカーネルソースが抜け落ちているが,このテープからインストールすると
完全な形で当時の環境が入手できる

ftp://ftp.ics.es.osaka-u.ac.jp/pub/mirrors/UnixArchive/PDP-11/Distributions/research/Dennis_v6/
阪大のUnixArchiveのミラーから入手できるUNIXv6のファイルセットからもカーネルソースは入手可能(これは普通にtarball形式)
このミラーには起動可能なsimh用の2.9BSDや2.11BSDだったりとか,
まだソフトウェアディストリビューションに過ぎなかった時代の2BSDとか,
はたまたPDP11を作ったDEC自身が開発したUNIXであるUltrixとか
資料的価値の高い物を大量にアーカイブしているので非常に興味深い

手順は,

simhの起動コマンドスクリプトでUNIXv6のテープイメージを起動するところからはじめる
d cpuはsimhのコマンドで機械語を直接メモリに置いてるが,
実機だとここでディップスイッチ操作でブートローダーを設定してたらしい.
今回はテープから起動するようにする

このスクリプトは途中で無限ループになるので,
Ctrl-Eで一度実行を停止した後にsimhのコマンドg 0で0番地に飛ぶ.

すると=プロンプトが出てくるはずである.
UNIXv6のmkfs(8) (そう,この時代はmkfsがsection VIIIだった!)は,
ファイルシステムを作る時先頭にブートローダーを埋め込む.
テープイメージはここでディスクへテープイメージを書き込むローダーが入っている
いくつか種類があるが,今回はtm(テープデバイス)からRK05なディスクデバイス(rk)に
インストールするので,tmrkコマンドで実行.
=tmrk
disk offset?
0
tape offset?
100
count?
1
=tmrk
disk offset?
1
tape offset? 101
count?
3999
と入力してテープからディスクにインストール.とりあえずこれでrk0ディスクにシステムインストール終了.
やっぱりCtrl-Eの後qで実行を終了し一度simhをリセット



ディスクからブート

とし先程同様ディップスイッチでブートローダーを設定しRK05ディスクからブートするか,

とsimhの機能(bootコマンド)で起動してしまうか.
どうやらsimhのbootコマンドはsimhの内部で汎用のブートローダーを持ってるらしい.
そしてbootコマンドのオペランドによってどのブートローダー(tmかrkかデバイスを見る)を呼ぶか判別し,呼び出してるらしいので,結局ディップスイッチ設定とやることは同じ

とりあえず起動したら@プロンプトが表示される.
UNIX v7と違いここで/にあるファイル名を指定することでカーネルを指定し,カーネルをブートしてしまう.
今回はRK05ディスクにインストールしてるのでrkunixというカーネルを起動.
user名はrootのみ最初は存在.passwordはなし.
起動するといきなりマルチユーザーモードログイン.つまりシングルユーザーモードにいかない.
また,これまた違う部分としてはcdコマンドが存在せずchdirコマンドでディレクトリ移動.
これは不便な上驚きである.

また,/devにmemやkmem以外のデバイスファイルがないのでmknodコマンドでデバイスファイルを
作成する必要がある.
現在もこのコマンドでデバイスファイル作成は可能だが,
当時はmknodやmkfs,mountにinitといった今だと/sbinや/usr/sbin相当のコマンドが/etc/に存在し,
/etcにはPATHが通ってないのでフルパスでコマンドを入力しなければならない.
/etc/mknod /dev/rk0 b 0 0
/etc/mknod /dev/rk1 b 0 1
/etc/mknod /dev/rk2 b 0 2
/etc/mknod /dev/mt0 b 3 0
/etc/mknod /dev/tap0 b 4 0
/etc/mknod /dev/rrk0 c 9 0
/etc/mknod /dev/rrk1 c 9 1
/etc/mknod /dev/rrk2 c 9 2
/etc/mknod /dev/rmt0 c 12 0
/etc/mknod /dev/lp0 c 2 0
/etc/mknod /dev/tty0 c 3 0
/etc/mknod /dev/tty1 c 3 1
/etc/mknod /dev/tty2 c 3 2
/etc/mknod /dev/tty3 c 3 3
/etc/mknod /dev/tty4 c 3 4
/etc/mknod /dev/tty5 c 3 5
/etc/mknod /dev/tty6 c 3 6
/etc/mknod /dev/tty7 c 3 7
chmod 640 /dev/*rk*
chmod 640 /dev/*mt*
chmod 640 /dev/*tap*
これでおーけー.
また,カーネルのリビルドもしておこう.
# chdir /usr/sys/conf
# cc mkconf.c
# mv a.out mkconf
# ./mkconf
rk
tm
tc
8dc
lp
done
# as m40.s
# mv a.out m40.o
# cc -c c.c
# as l.s
# ld -x a.out m40.o c.o ../lib1 ../lib2
# mv a.out /unix
mkconfコマンドで周辺機器(デバイス)は何があるのか自分で入力,設定し,
その後に/usr/sys/confに生成される各種ファイルをコンパイル,
最後に/usr/sys/lib1と/usr/sys/lib2とリンクすることでカーネルが生成される.
今回は/unixという名前で置いてるので,次回起動時にはrkunixでなくunixを指定すれば良い
なお,lib1やlib2の中のモジュールも含め完全にカーネルリビルドしたければ,
/usr/sysに移動しsh runを実行すると,runというシェルスクリプトがビルドしてくれる.
runにはすでにmkconfとその設定も記述されてしまっているので,
デバイスを増やしたり減らしたりしたければrun自体をedで編集する必要がある.

# dd if=/dev/mt0 of=/dev/rk1 count=4000 skip=4100
# /etc/mount /dev/rk1 /usr/source
# dd if=/dev/mt0 of=/dev/rk2 count=4000 skip=8100
# mkdir /usr/doc
# /etc/mount /dev/rk2 /usr/doc
これは必須ではないが,テープイメージからコマンド類のソースとドキュメントを
ddで持ってきて,別のディスク(rk1,rk2)にコピーし,これらをマウントさせておくと楽しくなると思われる.
ただ次回起動時にはマウントされなくなるので,

# cat >> /etc/rc
# /etc/mount /dev/rk1 /usr/source
# /etc/mount /dev/rk2 /usr/doc
として,rcスクリプト(起動時に実行)にmountコマンドを追加しておこう.
catとリダイレクトでテキストファイルを書く時は^D(EOF)で追記終了.

ここには書かないので先に挙げたURL達を参考にして貰いたいが,
dfコマンドは参照するデバイスがハードコードされてるので,
/usr/source/s1にあるdf.cの最初の関数のところを適当にdfで空き領域が見たいデバイスファイルに書き換えたり追加してリビルドしよう.
おそらく今回の場合は/dev/rk0,/dev/rk1,/dev/rk2を書く必要がある.

また,/usr/source/s2のsh.cの中の,
if(equal(cp1, "chdir"))としている行で,chdirをcpに変更した後リビルドすると,
今度からchdirコマンドでなくcdコマンドになってちょっぴり便利かもしれない.

これで初期設定は一度終了だが終了の前には
# sync
# sync
# sync
と適当にsyncを繰り返しディスクにバッファをフラッシュする必要がある
そうでないとまれにファイルやディスクが壊れる.
そしてCtrl-Eとqでsimhを終了

そしてインストールも終わったので起動スクリプトを変更しておく

これは今後毎回起動時にこれを呼ぶとする.
なお,カーネルに8dcを追加しこのスクリプトでもdcについていくつか設定したので,
simhでUNIXv6を起動してる最中はそのマシンのホストOSからtelnetでログイン可能である.
このスクリプトではdciを5555に設定してるのでポート5555番からtelnetログイン可能


……その2につづく

2014年5月31日土曜日

Google Summer of Code starting up now



今年のGoogle Summer of Codeもはじまって2週間が経ちました.


私も今年のGSoCに参加することになりまして,libcと格闘しています.
どうにか死なない程度にがんばって完遂させたいと思います.

2014年5月30日金曜日

マシンの更新

ThinkPad x121e(E-300)を愛用していましたが,
実家のマシンがWindows XPしかなかったのでこいつを実家のマシンにする変わりに
ThinkPad Edge E145(A4-5000)を使いはじめました

奥がThinkPad x121e,手前がThinkPad Edge E145

(わざとですが)パッと見よく似てます

EFI System Partitionが/dev/sda2にあるのはびっくりしました,が,問題ありません

RadeonなGPUですしx121eからほぼそのままE145にLinux環境移しても問題なく動作しています

ただ,wi-fiのドライバがOSSが存在せずプロプライエタリなものを使うことになりました
broadcom-wlです.

以上雑記

[解決済み] UEFI nvramが壊れた

ごぶさたです.
ネタあったけどしばらく投稿してませんでした.

4月頭の話です

UEFIではマシンがbootmenuというブートローダーみたいなのを持ち,
*.efiなブートローダーもしくはOSカーネルへのパスエントリとエントリの名前とをセットで保存でき,
HDDやUSB-HDD,FDD,CD/DVDを含めたそれらエントリの起動優先順をbootorderの形で保持しています.これらはnvramに記録されます.

ひとつ前のefibootmgr(0.7.0のひとつ前)の時,libefivarがブッ壊れてたっぽいことがありました.
そしてこいつがnvramに保持されたbootmenuへのデータを壊してしまったのです.

以下その顛末

2014年3月13日木曜日

ArchLinux + XfceでもシステムヴォイスをCV:丹下桜に

最近知りましたが,Linux-HA JapanさんがUbuntuやCinnamon用にサウンドテーマを公開しているようです. リンク

Ubuntu用,とはありますが,/usr/share/sounds/に配置する形のフォルダ構造/ファイル名で,
実はこれFreeDesktop.org準拠なデスクトップ環境ならだいたい使えるはずです.

ということでこれをXfceで使ってみようというのが今回の趣旨です.
CV:丹下桜さんですよ! ゴウランガ!

はじめに
@lindwurm_ さんがブログでUbuntuやCinnamon用に設定方法をブログで紹介されております.
該当する環境の方はそれを参考にすると良いでしょう.
http://blog.lindwurm.biz/2013/07/use-sound-theme.html
http://blog.lindwurm.biz/2013/12/cinnamon-sounds-setting.html

Ubuntuを使用していてもXubuntuユーザーならこっちの記事が参考にできるかもしれません.

だうんろ〜ど
記事冒頭で挙げたリンクからダウンロードしましょう

Xfceで使用するのはUbuntu用と書いてあるほうです.

そして,
$ sudo tar xvf kayo-theme.tar.gz -C /
 としてインストール.次は設定ですね

必要ソフトウェア
と,設定の前に必要なソフトウェアをインストールせねばなりません.
GUIでなにか行動した時,イベントサウンドを発行するのはLibcanberraです
また,このイベントサウンドを実際に再生するのは,SoXです
ちなみにSoXはplayというコマンドをつかってCUIで多種多様な音声ファイルを再生できる上に
CUIなのにレベルメーターが見れます.

インストールは,
$ sudo pacman -S libcanberra libcanberra-pulse libcanberra-gstreamer sox
でOK. PulseAudioを使わずにALSAしかつかってない人はlibcanberra-pulseなくて良し
なんのことかわからない人はとりあえずインストールしておきましょう.
もしかしたらlibcanberra*は既にインストールされているかもしれません.

設定

では設定です.まず,libcanberraを使うために環境変数をセットする必要があります.
export GTK_PATH=/usr/lib/gtk-2.0
export GTK_MODULES=canberra-gtk-module
とか言うのを.xprofileなり.bashrcなり.zshenvなり.zshrcなりに書いとけば良いと思います.
が,
ArchLinuxの場合
/etc/X11/xinit/xinitrc.d/40-libcanberra-gtk-module
で既に定義されているようなので上に挙げた2行はどこにも追加せず何もしなくて良い模様

私の場合AdobeAirを使用する関係上.zshenvでGTK_SESSION_ID環境変数を設定していたところ,
GTK_MODULESが設定されなくなっていたので自分で.zshenvに追加しました
(40-libcanberra-gtk-moduleを読むとわかると思います)

次にデスクトップ環境での設定です.(画像はクリックで拡大)
まずSetting Manager(設定マネージャ)を開きます

そしてAppearance(外観)を開きましょう


外観の中のタブで,Settings(設定)を選びます.


項目の下側にEnable event sounds(イベントサウンドを有効にする)というのがあるので,
このチェックボックスをオンにしましょう.
一度設定マネージャに戻って,


Settings Editor(設定エディタ)を開きます


xsettings > Net > SoundThemeNameの項目を見ると空っぽのはずですので,
そこにサウンドテーマの名前(今回はkayo)を書き込みます.
/usr/share/sounds/にあり,index.themeというファイルを持つフォルダのフォルダ名を
サウンドテーマの名前として使います.
デフォルトではfreedesktopというサウンドテーマが実は用意されています.

最後に

あとはログアウトしてからログインしなおすなり,再起動するなりすると後は
LinuxがCV:丹下桜に!

あとこのサウンドテーマのファイル名とフォルダ構造を参考にお好きなサウンドテーマを作って使ってみるのも良いのではないでしょうか.
おそらくWindows向けサウンドテーマも流用できるでしょう.

Q&A

Q. ログイン&ログアウトの音はないままなんだけど……

A. ログインは適当にスクリプトを用意して,
#!/bin/sh
play /usr/share/sounds/<サウンドテーマの名前>/stereo/desktop-login.ogg
あとはそれをログイン時に読み込むようにSession and Startup(セッションとスタートアップ)から設定してください.      ……ログアウト? がんばってください

Q.  ゴミ箱を空にした時とかの音がちゃんと出てない気がするんだけど

A. がんばって♡
libcanberraのソースコード
(https://gitorious.org/libcanberra/mainline/source/ac5ac9e486aa33f7be0cd9ddd315c03780676795:src/canberra-gtk-module.c#L40)
の40行目から列挙されてるTODOまでのファイル名以外の音声ファイルは確実に読み込んでくれるかどうかちょっと不確定っぽいです.