Moiz's journal

プログラミングやFPGAなどの技術系の趣味に関するブログです

Raspberry Pi用Haribote OSの変更箇所1 - セグメントのページングによる置き換え

本稿について

先週Githubに公開したラズベリーパイ用Haribote OSについて書いた前回のエントリー、趣味の自作OSという非常にニッチで注目されにくい分野の記事ながら、数千のアクセスをいただきました。また、ツイッターでは、旧交を温めるきっかけになったり、新たに自作OSを趣味・仕事とされている方々とフォローし合う機会を得たりと、得がたい経験になりました。

github.com

せっかくですので記録も兼ねてラズベリーパイに移植するにあたって行った変更点を紹介したいと思います。なお、本稿ではラズベリーパイに移植したHaribote OSをRPiHariboteと呼ぶことにします。

注意事項:あくまで筆者にとってOS開発は趣味の範疇の上に勉強中の身のため、内容については不正確な点もあると思います。そのような点が見つかった場合の指摘、または、さらによい方法の提案などしていただける場合は、喜んで参考にさせていただきます。なお本記事はあくまで上記プログラムの解説であり、ARMの解説記事ではありません。また、記事の内容の正確性や実機での動作の再現性についてはいずれも保証できませんし、本記事の内容を使って起こるいかなる損害についても責任をもちません。

本題にもどります。最初はセグメントからページングへの変更についてです。

セグメントのページングによる置き換え

PCとラズベリーパイの違い

オリジナルのHaribote OSでは、セグメントを使うことによりメモリ領域ををカーネルとコンソール、また、OS側とアプリケーション側とで分割して使用しています。また、セグメントによりメモリの保護、CPUの特権の管理、割り込み先の指定、なども行っています。しかし、ラズベリーパイ(ARM)ではそもそもセグメントがありません。

これらの機能のうち特権の管理はCPSR(Current Processor Status Register)、割り込み先の指定は割り込みベクターでのジャンプ先指定で行いますが、残りはページングを使うというのがラズベリーパイ上での現実的な解決策になります。

RPiHariboteで使われているページング方法

前項でこの記事はARM自体の解説ではないと書いたばかりですが、この先の部分で必要なためARMv6のページングについて以下少しだけ説明しておきます。 

ラズベリーパイで使われているARMv6では、1MBのセクション、または、16KB(ラージページ)/4KB(スモールページ)のページ単位のページング選択できます。

アドレス変換はスモールページの場合は以下のような手準で行われます。

  1. 仮想アドレスの上位12ビットを使って、変換テーブルからページテーブルのアドレスを見つける
  2. 仮想アドレスの12ビット目から19ビット目を使い、ページテーブルから、ページのアドレスを見つける
  3. 仮想アドレスの下位12ビットを使い、物理アドレスを求める
  4. 物理アドレスのデータをアクセスする

図に書くとこのようになります

 

f:id:uzusayuu:20170220152351p:plain

この図はスモールページのページテーブルを使った場合ですが、セクション単位のマッピングを行う場合は変換テーブルが直接データのあるメモリー領域(セクション)を指定します。

仮想アドレスから物理アドレスへの変換はCPUが自動で行うので、OSがページングを使って仮想アドレスを使うには、

  1. 変換テーブルの構築
  2. ページテーブルの構築
  3. 仮想アドレスのイネーブル

という手順を経ることになります。また、異なる変換テーブル・ベース・アドレス(TTBR)に切り替えることで、仮想アドレス空間を切り替えることができます。

また、各テーブルのエントリーにはアクセス制御のビット(AP)があり、領域毎にユーザーモード・特権モード毎にアクセス権限を設定できます。

  • AP=0b00: アクセス不可
  • AP=0b01: 特権モードのみ読み書きアクセス可能
  • AP=0b10: 特権モードは読み書きアクセス可能、ユーザーモードは読み出しのみ
  • AP=0b11: 特権モード・ユーザーモード共に読み書きアクセス可能

ARMにはAP以外のアクセス制御もありますが、RPiHariboteでは使用していません。

モリーマップ

タスクごとの仮想アドレス

RPiHariboteでは大きくわけて、TASK_A用仮想アドレスマップとコンソール用仮想アドレスマップをもっています。

RPiHariboteでは仮想メモリー空間を大きく二つにわけて、0x00000000-0x7FFFFFFFをOS用、0x80000000より上ををアプリケーション用にわりあてています。

f:id:uzusayuu:20170221053817p:plain

TASK_A用仮想アドレスマップ

TASK_AはHariboteOSの画像表示やキー入力うけつけなどを行うタスクで、Hariboteのカーネルのような役目をおっています。

このタスク用の変換テーブルでは、0x00000000-0x7FFFFFFFの領域のみを物理アドレスにそのまま(変換なしで)対応させています。このうち実際に対応する物理アドレスがあるのは0x1FFFFFFFまでの領域だけです。実メモリがない0x20000000以上の領域がアクセスできるようにしてあるのは、ペリフェラルのインターフェースやMailbox *1のアドレスが0x20000000-0x7FFFFFFFの領域にマッピングされているためです。

 また、0x7FFFFFFF以下では特権モードのみがアクセスできるように(AP=0b01)、0x80000000以上はアクセス不可に(AP=0b00)設定してあります。いまのところセクション・テーブルによる変換のみを行い、ページ・テーブルは使っていません。

コンソールタスク用仮想アドレスマップ

 コンソールタスクは各コンソールウインドウ用のタスクですがアプリケーションの実行にも使われます。コンソールタスク用マップではアプリケーション用の領域をそれぞれわりあてる必要があるため、呼び出されたコンソールの数だけ仮想アドレスマップと変換テーブルが作成されます。

アプリケーションとOSの間のデータのシェアのため仮想アドレス空間の0x00000000-0x7FFFFFFFの部分はTASK_A用の変換テーブルとまったく同じです。アプリケーション用の領域は今の所先頭の64MBのみ(0x80000000-0x83FFFFFF)を使用しており、その部分のみにページをわりあてています。これは仮想アドレスにページが割り振ってあるだけで、物理メモリーアドレスが割り当てられるまでは、実メモリーは消費しません。ページサイズはスモールページ(4KB)です。

RPiHariboteではこの64MBの領域にアプリケーションのコード部分とスタックとヒープの領域を設定します。実メモリの割り当てはアプリケーションがロードされる際に行われます。

実際の処理

TASK_A用の変換テーブルの設定

オリジナルのHariboteOSでセグメントの設定をしていたinit_gdtidt関数は、RPiHariboteではページングの設定をするように完全に書き換えられています。

https://github.com/moizumi99/RPiHaribote/blob/master/haribote/bridge.c

ここでは0x00200000から始まる4096x4byteの領域に対しgenerate_section_table関数を呼び出し、4GBの全領域をカバーするセクションテーブルを作成します。またAPによるアクセス制限も同時に設定します。

コンソールタスク用の変換テーブルの設定

RPiHariboteではコンソール用の変換テーブルは、各コンソールが作られる際に同時に作成されます。コンソールが作られると、bootapck.c内のopen_constaskが呼び出され、他の処理に加えて以下の処理が行われます。

  1. memman_alloc_4kを使って16KBの領域をセクションテーブル用に確保
  2. この領域に上記のgenerate_section_tableを使ってTASK_A用と同じセクション・テーブルを設定。
  3. 64KBの領域をページテーブル用に確保(仮想アドレス領域64MB分)
  4. この領域にgenerate_page_tableを使ってページテーブルを設定(この時点ではページのエントリーがあるだけで物理メモリが設定されていないので、AP=0b00としてアクセスを禁止)

次に、実際にアプリケーションがSDCARDからロードされる際に、実メモリー上にmemman_alloc_4kでアプリケーションのコード、スタック、ヒープ領域を確保し、対応する仮想アドレスのページを設定します。この一連の処理はconsole.c内のcmd_app内で行っています。

オリジナルのHariboteではスタックとヒープのサイズはMakefile内で設定できるようになっていましたが、RPiHariboteでは今の所決め打ちのサイズになっています。仮想アドレスと実メモリ上に確保されるアドレスの対応は以下のようになっています。

内容仮想アドレス確保される実メモリサイズ
実行コード0x80000000アプリケーションのファイルサイズ
スタック0x810000002MB
ヒープ0x820000002MB

アプリケーション終了後は、ページをアクセス不可に再設定し、実メモリ上に確保した領域を開放します。

仮想アドレスのイネーブル

この項の内容はdwelch氏の以下のコードを元にしました

https://github.com/dwelch67/raspberrypi/blob/master/mmu/novectors.s

TTBRの設定やMMU(Memory Management Unit)のイネーブルはCからではできないのでアセンブラで行います。処理はasm_func.S (オリジナルには無かったRPiHaribote独自ファイル)内のstart_MMUで行います。具体的にはr0にTTBRのアドレス、r1にMMUのオン・オフの設定を入れ、start_MMUにジャンプすると

  1. キャッシュの内容を破棄
  2. TLB(変換テーブルのキャッシュのようなもの)を破棄
  3. TTBRを設定
  4. MMUをオン・オフ

という処理が行われ、これにより仮想アドレスが有効化されます。

タスクスイッチ

タスクスイッチと同時に仮想アドレスのスイッチも行われます。

具体的には各タスク毎にTTBRのアドレスをメモリ上のOS用領域内に保存しておき、タスクスイッチの際に読み出し、上記のstart_MMUを使って有効なTTBRを書き換えています。OSが使用する領域の仮想アドレスは常に物理メモリーアドレスに一致しているので、テーブルの変換によりOS側の動作が影響を受けることはありません。

そのほかの変更

ARMでは変換テーブルとページテーブルは16KBアラインする必要があるので、RPiHaribote内ではmemman_alloc_4kは16KB単位でメモリー領域を確保するように変更されています。(名前と動作が食い違ってしまっており、また他の部分では16KBでは無駄がでるので、対策を検討中)。

OSがアプリケーション内で設定したデータをアクセスできるように、仮想アドレスを物理アドレスに変換するv2pという関数を作成しました。ウインドウのバッファのアドレスなどはこの関数を用いて物理アドレスに変換され、OS側に渡されます。

効果

このようにしてページングによる仮想アドレスを設定する事により、RPiHariboteでは以下のような機能を実装しました

  1. OS領域のメモリーのアプリケーションからの保護
  2. 複数のアプリケーションを同一の仮想アドレスで同時に実行する
  3. アプリケーション領域のメモリーの、他のアプリケーションからの保護

これらはオリジナルのHariboteではセグメントを用いて実現していた物です

まとめ

Haribote OSをラズベリーパイに移植する際に行った変更のうち、セグメントをページングで置き換えた部分に関して説明しました

 

 

*1:Video coreなどの設定を行うためのインターフェース

「30日でできる!OS自作入門」のHaribote OSをラズベリーパイに移植してみた

本稿について

タイトル通りですが、HariboteOSのラズベリーパイへの移植が一段落したので報告したいと思います。

f:id:uzusayuu:20170211113857j:plain

「30日でできる!OS自作入門」とHaribote OSとは

『30日でできる!OS自作入門』とは2006年に発行された川合秀実氏のOS入門書です。Haribote OSはこの書籍内で作るOSの名前です

30日でできる! OS自作入門 | マイナビブックス

f:id:uzusayuu:20170212040924p:plain

書籍販売ページの内容紹介

プログラミングの基礎からはじめて、30日後にはウィンドウシステムを有する32bitマルチタスクOSをフルスクラッチで作り上げるという入門書。
ビギナーでも無理なく作成できるようPCの仕組み・アセンブラ・Cの解説から始まり、試行錯誤を繰り返しながらアルゴリズムを学びつつ、たのしく自由な雰囲気でOSをゼロから構築していくという、他に類を見ない手法による、趣味と実用と学習を兼ね備えたOS作成の入門書です。

 

この内容紹介の通り非常にユニークかつわかりやすい内容で、発売後10年たった現在も読み継がれています。たとえば最近ではこちらのブログで紹介されているのを目にしました。

rkx1209.hatenablog.com

名前はHaribote(張りぼて)という名称ですが、教育用のOSとしては、割り込み処理、ファイルアクセス、アプリケーションのサポート、メモリーのプロテクション、APIの実装、プリエンプティブなマルチタスクの実装、周辺機器のサポート、GUIの実装と、十分な領域をカバーしていると思います。また、改変したソフトウェアの再配布・ライセンスの変更を認めるなど、このOSをもとに実用的なOSを作成することも理論上は可能になっていて、川合氏のこの分野にかける思いの程が感じられます。

当ブログの筆者もご多分に漏れず、このOS自作入門を用いてOSを『自作』してみたのですが、なにしろ10年前の書籍と言うことで現在のPC環境とは相容れない部分も多くなってきています。たとえばHariboteはフロッピーディスクからの起動を前提にしているのですが、今時フロッピーから起動できるPCを調達するのも大変です。CDからの起動もできますが、毎回焼くのも不便です。なにしろ自作OSは起動するかどうかさえやってみないとわかりません。私自身、エミュレータQEMUやVirtual Box上で動作を確認するのみとなり、少し不満が残る結果となりました。また、内容を移しただけでは無く、自分で考えてOSを作りたいという気持ちも強まり、では他のアーキテクチャーに移植して実機上で動作してみよう、という事にしました。

 

ラズベリーパイへの移植

 簡単に移植といっても、まったくアーキテクチャーの違うCPU、プラットフォームへの移植と言うことで、変更点は多岐にわたります。特にアセンブラ部分は当然ながらすべて書き換えになりましたし、CのコードもCPUの機能やプラットフォームの機能に関わる部分は全て又は大きく変更しました。以下に主要な変更点を挙げます

  • ツールチェーンをHaribote独自の物からGNUに置き換え
  • ツールチェーンの変更に伴い一部の処理(sprintf, rand)を自作の関数で置き換え
  • アセンブラのコードをx86からARMv6に全て変更
  • ブートローダーをRaspberry Piの標準の物に置き換え
  • 割り込み処理の書き換え
  • TSSによるマルチタスクをソフトウェアによるレジスタの待避・復帰に変更
  • マルチタスクの処理の変更に伴い、スーパーバイザーモードおよびシステムモード用のスタックをタスク毎に設定
  • セグメントをページングによって置き換え(ARMにはセグメントはない)
  • ファイルアクセスをBIOSによるフロッピーディスクの読み込みから、OS内のSDCARDの読み込みに変更
  • ファイルシステムFAT12からFAT16に変更(その後FAT32に対応
  • タイマー処理の全面的な書き直し
  • キーボードとマウスの処理を外部USBデバイスドライバCSUD)により置き換え
  • キーボードとマウスの割り込み処理をタイマー割り込み時のポーリングに変更(CSUDの制限による)

  • グラフィック処理の移植。特に初期化作業は完全に書き換え
  • 音声の処理をブザーからPWMに変更。具体的にはPWMをM/Sモードで動作させ、クロックを可聴領域まで落とすことでブザーと似た音声を出力させ、パルスの周期を変えることで音程を実現しています。
  • システムコールをスーパーバイザーコールに置き換えて、上記のマルチタスク変更に対応させる
  • デバッグ用にUARTおよびJTAGに対応
  • 実行ファイルの形式をHRB形式からELF形式に変更。これにともないスタックとヒープのサイズを固定値に置き換え(今後変更を検討)
  • CPUのアーキテクチャーの違いによる小さな差異を吸収(例:ARMの32ビットアクセスは4バイトアラインのため、画像描画の高速化がもとのままでは失敗することがあった)

逆に変わっていない点としては、

  • GUI、キーバインディングに関してはもとのHariboteを踏襲
  • アプリケーションはCのソースコードレベルで互換性あり
  • 「30日で出来る!OS自作入門」に登場するアプリケーションは、グラフィックビューワー以外は全て動作する(TVIEWのみ後述のバグによる制限あり。グラフィックビューワーはアセンブラ部分があるため)

現在わかっている問題点・制限としては

  • Raspberry Pi Model B+ Rev2.0でのみ動作検証済み(ラズベリーパイ2への拡張を検討中)-> 2/25 Raspberry Pi Zeroでの動作を確認しました。
  • 使用したSDCARDのサンプルファイルにバグがあることがわかっている(検討中)-> 2/25 わかっている範囲で対応済み
  • CSUDの制限のため、キーボード・マウスに関しては、動作する機種が限られる。(今までのところケーブル接続のものは動く確率が高い)
  • アプリケーションの一つ(TVIEW)が、オプションをつけるとクラッシュする。(おそらくメモリー関係の問題。検討中)  2/19 修正済み
  • 圧縮の解凍がまだサポートされていない(これは、2017年現在、数百バイトの圧縮にどれほどの価値があるのか疑問だったためプライオリティーを下げた。今後対応予定)
  • 非矩形ウィンドウの表示時に透明部分が正しく描写されない(ウィンドウの位置を動かせば正しく表示される。検討中)
  • FAT16のサポートが最小限なため、環境によっては動かない可能性がある(拡張を検討中)-> 2/25 FAT32に対応しました
  • ELF形式の実行ファイルのサポートが最小限なため、環境によっては動かない可能性がある(拡張を検討中)

ソースコードはすべてGithubに公開しています。再配布・再ライセンスを事実上制限無く許諾してくださっている川合氏の前例にならい、ライセンスとしては改変・再頒布にほぼ制限のないunlicenseを選択しました。

github.com

使用方法などはGithub内のWikiに投稿してあります。今後ビルド方法なども追加する予定です。

スクリーンショットなど

以下、スクリーンショットなどを載せておきます。残念ながらオリジナルのHariboteと全く同じです。異なるアーキテクチャー上にまったく同じ物を再現するのがテーマだったのでしかたがないのですが、すこし寂しいところです。

f:id:uzusayuu:20170211123719j:plain

この写真中tviewが表示しているipl10.nasはテキストのサンプルとして使っているだけで、OS内では使用していません。

f:id:uzusayuu:20170211123847j:plain

動画はこちら

www.youtube.com

音楽の再生が調子っぱずれなのはマルチタスクの影響だと思いますが、まだバグが残っているのかもしれません。

参考文献・サイトなど

以下、Haribote OSのラズベリーパイへの移植にあたって使用した参考文献・サイトのうちいくつかを紹介します。これらの書籍およびウェブサイトの著者の方にはあらためて感謝の気持ちをあらわしたいと思います。

「30日でできる!OS自作入門」

30日でできる! OS自作入門 | マイナビブックス

f:id:uzusayuu:20170212040924p:plain

 すでに説明しましたので、詳細は省きますが、改めてOSを学ぶ機会を与えていただいたことを感謝したいと思います。ゼロからOSを作り上げるというスタイルのため、他のアーキテクチャーへの移植も一歩ずつ進めることが出来ました

 

Cambridge University - Baking Pi - Operating Systems Development

Computer Laboratory – Raspberry Pi: Baking Pi – Operating Systems Development

 最初にラズベリーパイでベアメタル・プログラミング(OSを使わない、ハードウェア上の低レイヤーのプログラミング)をするにあたって使ったチュートリアルです。CSUDはこちら経由で入手しました。

 

Raspberry Pi respository by dwelch67

github.com

いろいろなラズベリーパイのベアメタル・プログラミングの例が載っていて、あたらしいステップに進む度に参考にしました。

 

Valver Bare Metal Programming

www.valvers.com

わかりやすいチュートリアルです。特にMailbox(ラズベリーパイでVideo coreなどと情報をやりとりする仕組み)について非常に参考になりました

 

 OSDev Wiki - Raspberry Pi Bare Bones

Raspberry Pi Bare Bones - OSDev Wiki

 OSDevにもラズベリーパイのベアメタル(ここではBare boneと呼ばれています)についての情報があります。

 

Raspberry Pi - Bare Metal Forum

Raspberry Pi • View forum - Bare metal

 本家ラズベリーパイのサイトにも当然ながらベアメタルのForumがあります。

 

BareMetalで遊ぶ Raspberry Pi

tatsu-zine.com

 貴重な日本語の情報。表紙はかわいらしいですが、中身はすべてラズベリーパイのベア・メタルプログラミングに関するものです。JTAGを使ったデバッグの方法が非常に参考になりました

 

32ビットコンピュータをやさしく語る はじめて読む486

www.amazon.co.jp

オリジナルのHariboteの動作を理解するにあたって非常にためになりました。Githubリポジトリーがあり、現代のPC環境でサンプルコードを実行する手引きが解説されています。

github.com

改訂ARMプロセッサ-32ビットRISCのシステム・アーキテクチャ

改訂 ARMプロセッサ

書籍ページの紹介

本書は,組み込み用RISC型マイクロプロセッサとして広く普及しているARMプロセッサの解説書です.ARMプロセッサの開発当初から関わってきた著者(マンチェスター大学)が,RISCプロセッサの歴史を振り返りながら,ARMアーキテクチャを詳細にわかりやすく解説していきます.改訂版では,旧版で扱っていたARM7TDMI,ARM8の各コアに加えて,ARM9TDMI,ARM9E,ARM10TDMI,ARM10Eなどの新しいコアについても触れられています.また,RISCプロセッサの原理を学ぶ教科書としても最適です.
 原書名:ARM System-on-chip Architecture (second edition)

 絶版のようなので、当初参考文献にいれていたなかったのですが、最も良く参照した本の一つなのと、アマゾンなどで手に入るようなので加えておきます。

実をいうと10年程前に買ったっきり開いていなかったのですが、今回はとても重宝しました。特にヴァーチャルアドレッシングの説明はわかりやすく助かりました。2001年の本と言うことで今となっては内容に古い部分もありますが、そういった部分の多くは拡張部分なので現代のアップデートと共に読めば今でも参考になります。

ARM Information center

ARM Information Center

Welcome to the ARM Infocenter. The Infocenter contains all ARM non-confidential Technical Publications, including:

ARMの情報ページです。ARM自体に関わる事はここで多くの情報が得られます。

まとめ

「30日でできる!OS自作入門」のHaribote OSをラズベリーパイに移植したので、その内容を報告しました。移植した結果はGithubで公開済みです。

 

関連記事

ラズベリーパイ版Haribote OSのビルド環境とインストール方法 - Moiz's journal

Raspberry Pi ZeroでHaribote OSを動かす - Moiz's journal

Raspberry Pi用Haribote OSの変更箇所1 - セグメントのページングによる置き換え - Moiz's journal

Raspberry Pi用Haribote OSの変更箇所2 - タスクスイッチ - Moiz's journal

ラズベリーパイ上のベアメタルプログラミングにおけるメールボックス 機能 - Qiita

 

修正箇所

当初、川合氏の名前を誤表記していたことをブックマークにして指摘頂きましたので修正しました。川合氏には大変失礼いたしました。またご指摘ありがとうございます。

(2/19)参考文献を追加しました。tview関連のバグが修正されたのでその旨表記しました

2016年にuClinuxをDE0ボードで動かす

2016年にuClinuxをDE0ボードで動かす
FPGAボードDE0と、参考書籍「FPGAボードで学ぶ組み込みシステム開発入門[Altera編]」
最近FPGAで遊びたくなり、「FPGAボードで学ぶ組み込みシステム開発入門[Altera編]」と、書籍中で使われているTerasic社のDE0を買ってみた。

FPGA ボードで学ぶ組込みシステム開発入門 ?Altera編?

FPGA ボードで学ぶ組込みシステム開発入門 ?Altera編?

DE0 開発学習ボード

DE0 開発学習ボード

DE0はこの手の学習向け目的では定番であり、またこの書籍もとてもわかりやすく、特に、つまづきがちなボードの設定やツールの細かい使い方などが詳しく説明されているために非常に役にたつ。書籍のサポートページもあり、今でもこの手の内容を学習する人には広くすすめたい良書だ。
ただ、発売から5年ほど経つと言うことで、現在のAlteraのツール類やLinuxの環境との違いがでてきているのは否めない。また、ツール類の細かい設定方法を紹介するという書籍のスタイルのため、そういった環境の変化が内容の再現性に直接インパクトを与えており、そのままでは動作しない部分が若干あった。そこで、完全ではないが回避方法を参考として紹介したい。
ちなみに私の環境はDell XPS8700 (Core i7-4770)+Windows 10 Home Anniversary updateで、内容はすべてこの環境を前提としている。また、書籍へのリファレンスはすべて初版第2刷をもとにしている。
このブログの内容は筆者の環境にて試した内容を参考として記した物であり、同様の内容を実行することによって正常に動作することを保証する物ではありません。また、記事の後半で紹介する問題点も残っており、全ての人に内容をすすめるものではありませんし、この内容を試したことにによって生じる結果について、いかなる責任も負いかねます。製品または書籍についての質問は、出版社およびボードのメーカーに問い合わせされるか、Alteraのforumに投稿されることをおすすめします。
書籍の内容と現在のツール類
2016年時点でも、当該書籍中第8章までは書籍の記述をほぼおいかけるだけで内容を再現することができた。書籍で使われているQuarusII Web Editionの11.0はAlteraのホームページから正常にダウンロードできる。注意点としては、

  • 付録I-2、USB-Blasterドライバのインストール
    • Windows10環境では、USB-Blasterドライバのインストール時に「ドライバーの署名を無効にする」にチェックを入れること。(入れないとエラーがでる)
  • 5−3 プログラムの作成と実行
    • NIOS2 II EDSを互換モードで動作させる。(こうしておかないと私の環境ではNIOS HWが認識されなかった)

このあたりは新しいツールを使うことで回避できるようだ。現時点でDE0に対応するQuartusの最新バージョンは13.1.0.162だった。第8章までの内容は新しいツールでも若干の手順の変更で再現できるし、書籍の付録(App. III)にも関連情報があるので、第8章までの内容を試すのなら新しいツールを使っても可能だ。(ただし、手順は一部変更になるので、そのあたり痛し痒しの面はある)
2016年にuClinuxをDE0にインストールするには
このように第8章までは、わずかな設定変更で2016年時点でも書籍の内容を再現することができるが、最後の第9章に入るととたんに難しくなる。
Ubuntuのインストール
まず、書籍中App. I-3で紹介されているUbuntu11.04だが、ダウンロードとインストールは問題無いものの、すでにサポート期間が終了している。そのため、apt-getで環境をアップデートしたりツールを追加しようとしてもサーバーが見つからないなどのエラーがでる。このあたりはサーバーのURLなどを更新することで改善可能だが、私自身は全てのツールを集めることができなかった。
現時点(2016年9月)での最新の安定版Ubuntuは16.04LTSだったのでこちらを使う事にする。また書籍で紹介されているコンパイル済みのツールチェーンは32bit環境向けなので、32bit版を選ぶ。*1
VMWareは最新版(12)を使ったが特に問題は起きていないようだ。
Ubuntuのツール類
書籍中P296でインストールしているツール中、uboot-mkimageが入手できなかったので代わりとして表示されたu-boot-toolsをインストールした
また、Altera.wikiの中にMakeのバージョンが3.82以降だとエラーがでるという記述を見つけたので一応make3.81をインストールしておいた。(ただし、これが実際に意味があるのかどうかはわからない)
http://stackoverflow.com/questions/31912233/how-to-update-make-3-81-linux
同様にGCCのバージョンも4.2でないとエラーが出るという記述がAltera.wiki内にあるが、こちらのアップデートは上手くいかなかったので、最新のGCC(5.4.0)を使っている。(もしかするとこれが次の項の原因かもしれない。)
スクリプトの変更
上記の事を行ってもmake menuconfigが正常に動作しなかったので、以下の変更を行った

  • zconf.tab.cの改変
    • uClinux-dist/config/kconfigでコンパイルエラーが出る。内容はzconf.tab.cで未定義のオブジェクト(kconf_id_lookup)への参照があるというものなので、zconf.hash.cから関数の定義部分をコピーしてzconf.tab.cにペースト
  • timeconst.plの改変

@val = @{$canned_values{$hz}};
# if (!defined(@val) ) {
# @val = compute_values($hz);
# }
output($hz, @val);

実をいうとこの二つの変更は実際に正しい変更なのかどうか自分でもわからない。仕事であれば絶対やらないような、「やったら動いた」レベルのものなので、もし同様のエラーに遭遇されているかたは、影響について調査された上で正しい方法を実行されることをお勧めしたい。もし、上記の内容を試されるかたは、必ず各ファイルのバックアップを作成し異常があったばあいすぐに戻せるようにしておくよう留意される事をおすすめする。(繰り返しになるが、このブログでは結果については一切の責任はとれない)
アプリケーションの作成
私の環境ではp.317まですすめてもmake romfsでエラーが出てromfs/binの下に実行ファイルが作成されなかった。そこで、直接romfs-inst.sh /bin/helloを呼び出したところ無事実行ファイルが作成され、その後のimageのビルド、nios IIでの実行まで進めることができた。ただし、romfs-inst.shでエラーが出ているが、romfs/binの下にファイルはできているので良しとした。書籍注9-8にも同様の記述があるので、既知の問題と思われる。
実を言うと、なぜこの部分が動作しないのかよくわからない。単に自分のMakefileにエラーが残っているだけの可能性もあるし、これまでに行ってきた変更点が悪さをしている可能性もある。
Nios IIへの転送
最後にビルドイメージのNios IIへの転送だが、私の環境ではNios II 11.0sp1 Command Shellでイメージを転送したあと、Nios IIがポーズしてしまい以降動作しないことがあった。新しいVersionの13.0ではポーズする率が減ったので、以降はそちらを使用している
ともあれ、これらの変更で、9−3までの内容(uClinuxカーネルのビルドとNiosII上での動作、アプリケーションの作成と実行)は再現することができた。以下は証拠写真

残った問題点
ここまでの方法でどうにか9-3までの内容は再現できたが、9-4の「デバイスドライバの組み込みとテスト」に関してはまだ成功していない。どういうわけか、デバイスドライバの実行ファイルがromfs/lib/modules/2.6.30/kernel/drivers/char内に作られないし、nios IIにimageを転送してデバイスドライバをロードしようとしても、そんなドラバーは無いというエラーが表示される。
もしかするとここまでやってきたエラー回避策のどれかが悪さをしているのかもしれないし、他にツール類の依存性があるのかもしれない。または、単に自分の入力した内容にエラーが残っているのかもしれない。もし解決作が見つかったら、改めて別エントリで紹介したいと思う

*1:64bit環境で動作させる方法もないわけではないようだが、私の試した範囲では上手く動作しなかった。同様にWindows10のBashでもツールチェーンが動作しなかった。また、今回はツールチェーンのコンパイルはためしていない。

アメリカの医療費と医療保険について

日本の医療費は安いですね

こんなエントリーが話題らしい
はてな匿名ダイアリー「医者の権益確保システム凄すぎワロタ」
最初の部分、整形外科に行ってレントゲンとって診察受けて処方箋もらって医療費合計 10,750円、というのを見て日本の医療費は安くていいなあ、などと思ってしまった。アメリカだといくらくらいかかるんだろうと思って、去年の医療費のレシートを探してみたら、指のレントゲン写真だけで$160ほどだった。日本円だと1万6千円ほど。ちなみにこれは保険会社による調整が入った後の請求額で、ラボからの元々の請求は$200(約2万円)を越えていた。ようするに保険会社が値切ってくれてこの値段だ。高いですねえ。MRIなんかうけたら数百ドルの請求はごく普通。救急車呼ぶような事態だと数十万円かかったりする。
上記の記事だと日本でのレントゲンの部分の費用は1570円。私の場合の十分の一ですね。その辺の写真館で証明写真撮ったってもっと高いかも知れない。さらに国民皆保険で、ほとんどの人は3割負担。保険料は別途それなりの額かかるとはいえ、リーズナブルな価格だと思う。

アメリカの医療費と保険

さて、アメリカの医療費や医療保険はどうなっているのかというと、実はややこしすぎて現地で住んでいる人でも専門家でも無い限りわけがわからない。医療保険の大枠としては高齢者向けのメディケア、低所得者向けのメディケイド、その他一般向けの民間保険があるわけだが、民間保険はさらにいくつも細分化されていて、さらに州によっても違っていたりして、もはや個人には全体像を理解するのは不可能だ。
そんな訳で、ここでは個人的に見知った範囲でアメリカの医療費や医療保険についての状況をかいて見ようと思うが、ブログ主は医療や保険については素人であり、以下は私の限定的な個人的な経験・体験談に過ぎず、内容についての細かい正確性までは保証できませんし、変化する制度にあわせてアップデートすることもできません。もし最新の正確な情報が必要であれば、公的機関、もしくは保険会社、コンサルタント、雇用先などに確認していただくことをおすすめします。

民間の医療保険

アメリカでは保険に加入する場合、個人的に保険に入るのと、雇用主を通して保険に入る二つの方法がポピュラーだ。特に雇用主を通して加入すると保険料が安かったり、雇用主の援助がでたり、病歴を問わず加入できたり、といった利点が得られる事が多く、可能な場合はこちらを選択することが普通だろう。
私自身はアメリカでは二つの会社で働いたが、業界が同じ事もあり、オファーされる保険の種類も似通っていた。保険の内容は医療保険、歯科保険とわかれており、他にメガネやコンタクトレンズ用の保険もあったりする。
医療保険のオプションで一般的なのはPPOとHMOだ。HMOは毎月それなりの保険料を払う代わりに、病院にかかる際に支払う医療費は少ない。ただし、診療できる医療機関、受けられる治療の種類にはさまざまな制限がかけられる。PPOの方は毎回病院に払う医療費は高いが、自由度が高く、毎月の保険料もHMOよりは安いことが多い。特にHMOの保険の制限は何年か前にマイケルムーアの映画で取り上げられたこともあり、日本でもそれなりにしられているのではないだろうか。この項で取り上げたいのは、もう一つの新しいプランHDHPだ。

医療費の実際 - HDHPの場合

最近現れたHDHPとはPPOのバリエーションの一つで、High Deductible Health Planの略。日本語では何というのかわからないが無理に翻訳すれば、高免責額医療保険プランとでもなるだろうか。その名のとおりDeductible(免責額)が高い、つまり病院での自己負担の額が多い代わりに、月々の保険額が安い医療保険だ。さらにこのプランのみ、後述するHSA(Health Saving Account)と組み合わせる事ができる。
さて実際にこのプランに入るとどうなるのだろうか?
まず、毎月の保険料は前述の通りHMOや通常のPPOに比べると安い。トータルのプレミアムはそれほど違わないらしいが、雇用主の援助がある場合、各個人が払う額は数分の一に下がるケースがある。その代わり、規定の免責額(プランや条件によって違うが数十万円程度)に到達するまでは、各自が医療費を全額支払う必要がある。
患者にとっては実際にはどんな感じになるだろう。ちょっと風邪を引いたりして医者にかかるとすると、かかりつけ医がいない場合、まずは保険のネットワーク内の医者を探す必要がある。PPOやそのバリエーションのHDHPはネットワーク外の医者の診療も認めるが、その場合免責額があがったりと患者の自己負担額が増えるのでなるべくネットワーク内の病院を使った方が良い。ちなみにHMOはそもそもネットワーク外での診療を認めていないのが普通だ。
つぎはそのかかりつけ医に予約して、診療を受け処方箋を書いてもらうことになる。安くて数十ドル、高くて数百ドル、というところだろうか。保険に入っている場合、請求書は一旦保険会社に行き交渉後に改めて自分の所に請求書が送付されるので、その額を振り込むことになる。その年度の医療費の総額が免責額に届くまでは全額自己負担だ。自分で全額払うのなら保険会社には事後に連絡すればいいんじゃないの?とも思うが、かかった医療費は免責額に向けて積み上がっていくので保険会社としてはチェックする必要があるし、加入者にしても保険会社のチェックが入ることで医療費が減額されるのでやはり良いことなのだ。場合によっては数百ドルの請求が数分の一に減ることがあり、こんなときは保険会社の存在がとても有難い。また、アメリカの病院では検査などは別の機関が行うのが普通なので、間に保険会社でも入らないととても把握しきれない。
ともかく、こういった理由で、病院で医師に見てもらった後は事務処理などが無い限り窓口にも行かずにそのまま帰ってしまうことができる。最初は食い逃げみたいで妙な感じだったが次第になれてきた。
処方箋を書いてもらった後は薬局に行って薬を出してもらうわけだが、個人負担額はまたプランによって違ったりする。さらに、しばらくたつと保険会社から連絡のあったメールオーダーの薬局(薬の通販)から連絡があって、そちらに切り替えをすすめられたりする。おそらく通販の方が保険会社の負担が少ないからだろうと思う。
さて運悪く重病や大けがで多額の医療費がかかった場合はどうなるだろう?もし医療費が免責額を超えた場合、保険がほとんどのコストをカバーする。さらに、おそらくプランにもよるのだろうが個人負担に上限を認めていることも多く、その場合上限を超えた医療費はすべて保険会社の負担だ。(もしかすると雇用主も一部負担しているのかもしれない。)そんなわけで万一大病を患ったり大けがをしても、医療費で破産する事態は免れることができる。健康な人がHDHPに入る理由と言えば、こういった万一の場合に備える、というのが第一の理由だろう。
さらに、多くの場合は予防医療は個人負担が無料の事が多い。たとえば年に一度の健康診断や予防接種は大概は全額保険でカバーされる。予防接種が無料になるあたりは逆に日本の医療保険よりも優れているといえるかもしれない。

HSA (Health Saving Account)

このHDHP加入者だけに認められた制度がHSA(Health Saving Account)だ。これは毎月一定額を医療専用口座に積み立てておくことが出来る制度で、加入者への利点は積み立てが税引き前だということだ。アメリカの税金は日本に比べて高いので、これはかなりありがたい。たとえば、トータルの税率が30%だとしたら、実質3割引で医療費が支払えることになる。さらに雇用主によってはこの口座に一定額を給与とは別に振り込んでくれることがあり、そんな場合の実質医療費負担はさらに下がる。
以前からFlexible Spending Accountという税引き前の積み立てることの出来る口座の制度はあったのだが、こちらの場合積み立てた額を使えるのはその同じ年のみという制限があった。つまり、たとえ口座に$5000(約五十万円)残っていても、その年に使い切れないと、次年度には綺麗になくなってしまうのだ。それに対してHSAは口座の残高を次年度以降に持ち越しができるというのが大きなメリットだ。デメリットはもちろん医療費以外には使えないこと。場合によっては国税庁の監査が入ることもあるらしく、その場合HSAから引き出した額がすべて医療費に使われた事を証明しなくてはならない。(メンドウクサイ)

まとめ

以上、個人的に経験した範囲でアメリカの医療費・医療保険についての体験談を書いてみた。こうしてみると、日本の医療費と医療保険のシンプルなわかりやすさが懐かしい。もちろんアメリカの医療機関にもいいところがあって、例えば私がいった病院はどこも日本の平均的な病院よりもはるかに患者向けのサービスがよかった。個人病院でも革張りのゆったりとした椅子や無料のコーヒーのある広い待合室は普通だし、病院の先生が各患者に向ける時間も長かった。ただ、それは私が比較的良い地域の病院にしか行ったことがないからかもしれないし、こういった豪華な設備も医療費を押し上げる要因になっているのかもしれない。第一、オバマケアがまだ施行されていない現在の制度では、医療保険自体に加入できない人が多数存在しているし、保険に加入できても全員が上記のようなすべてのメリットを享受できるわけではない。私自身も、現在は自分の加入している保険に満足しているが、先々転職などした場合どうなるかはまったくわからない。
ついでに言うと、アメリカでは医療保険プランは毎年めまぐるしくアップデートされて加入者が変更を確認するのも大変なほどだし、オバマケアが本格的に運用されればさらに大きな影響があるだろう。そんな変化を追いかけること自体が各個人にとっては大きな負担になっている。(毎年年度末になると、みんな来年の医療保険はどうしようと頭を悩ませるのです。)そういう意味でも、日本の医療制度ってわりといいんじゃないの?という気がする。

最後にくどいようですが、私は医療・保険などに関しては素人であり、上記の記事はたんなる個人の経験・体験談です。したがって、正確性や一般性は保証できません。最新の正確性が担保された情報が必要な方は、公的機関・雇用主・保険会社などから正しい情報を入手いただくことをおすすめします

Onenoteとの組み合わせでOutlook+GTDの弱点を克服する

OutlookGTD

ライフハックの九割は時間の無駄、残りのほとんどもたいして益がないが、中にはごく希に良い物も含まれている。私が使っているのは、もはや定番すぎてここに書くのも恥ずかしいが、GTD (Getting Things Done)だ。GTDの中身については本家David Allen氏のGetting Things Done「はじめてのGTD ストレスフリーの整理術」)を参照していただくとして、ここではOutlookGTDを使う際の問題点と、不完全ながらその対処法について書いてみる。
注意点:これはあくまで私の環境での動作報告であり、同様の環境で必ず動作することを保証するものではありません。試される方は各ツールのマニュアルに従い、ご自分の判断でご使用ください

Outlookの問題点

ここまで書いておいてなんだが、OutlookGTDの相性はあまり良くない。一応本家David Allen氏のホームページではOutlookを使ったGTD実践ガイドもダウンロード販売されてはいるが(https://secure.davidco.com/store/catalog/Setup-Guides-p-1-c-263.php)、もともとGTD向けに作られたツールではないのでいろいろと微妙な問題が出てくる。大きな問題はステータスの設定ができないこととプロジェクトが扱えない事だろう。ステータスの方は、私はそれほど重要視していないし、なんならカテゴリー(Outlook Setup Guideではコンテクストに使われる事になっている)にステータスも加えることだって出来る。対してプロジェクトの方は、GTDでは「二つ以上のアクションで構成される物」という非常にシンプルな定義になっており、大概の「やらなきゃいけないこと」は「プロジェクト」になってしまうほど重要なものだ。にも関わらず、Outlookにはプロジェクトを扱う機能がない。じゃあGTDに使わなきゃいいんじゃないのと言いたいところだが、職場で指定されているなどの理由で否応なしに使わざるを得ない人も多いのではないだろうか。(逆に、もしそうでなければ、素直にWebベースのGTD対応ツールなどを使った方が良いと思う。)

Outlook上でのプロジェクト

Outlook Setup GuideではプロジェクトをOutlookカテゴリーとして定義して、プロジェクトから派生するアクションを個別のOutlookタスクとして定義することを薦めている。プロジェクトと各アクションを直接つなげる機能はOutlookからは提供されないので、ワークアラウンドとしてタスクの名前にキーワードをいれる方法が提案されている。例えば、

  • カテゴリー: .Project
  • タスク:旅行の計画

に対して

  • カテゴリー:@Computer
  • タスク:ホテルの予約-旅行

などとアクションを立てる方法だ。この場合「旅行」がキーワードになる。
ただし、この方法をとるにはいちいちキーワードを覚えておく、毎回入力する、アクションが終わったら自力でもとのプロジェクトを探してアップデートする、という面倒がつきまとう。良いキーワードを常時見つけるのは大変だろうし、気をつけないとアクションが終わったのにプロジェクトに反映されないプロジェクト迷子現象が起きてしまう。

Onenoteとの組み合わせ

Outlook単体で解決が難しいプロジェクトだが、Onenoteと組み合わせると解決方法が見えてくる。
Onenoteは言わずと知れた何でもノートだが、代表的な機能は強力なリストだろう。しかもこのリストの項目はタスクとしてOutlookにリンクすることができる。この強力なリスト機能をGTDのプロジェクトとして使ってしまおうというのが今回の方法だ

  • まずGTD専用のノートブックを作る
    • とりあえず、GTD Projectという名前をつけた
  • 1つのプロジェクトにつき一つのノートを作る
  • プロジェクト名をノートのタイトルにする
    • 「夏休みの旅行」というプロジェクト名にしてみる
  • プロジェクトをOutlookのTaskとして登録
    • HomeからOutlook Task、Customを選択。(またはShift + Ctrl + K)
    • カテゴリーを.Project、日付を希望の日時に設定

これでプロジェクトができた。あとは、アクションを追加していく

  • ノート内にアクションやその他の情報をリストとして書き出す
  • 次のアクションを選び、タスクとして登録


OutlookOnenoteのアカウントを設定していれば、これでOutlookの方にもプロジェクトとタスクが登録されているはずだ。

あとは終わったタスクのフラッグをクリックして完了させたり、プロジェクトの次の項目を新たにタスクとして登録したりすることができる。
この方法の良い点は、Outlook上のTaskからもとのプロジェクトが参照できること
タスクをクリックするともとのOnenoteのノートへのリンクが現れるので、このリンクをクリックすればもとのプロジェクトにたどり着く。これで、アクションを終了したのにどのプロジェクトの項目か忘れて進行が滞ってしまう自体を防ぐことができる。

(2013年6月26日追記)複数PC間の同期について

(コメントで指摘があったので、複数PC間の同期について書いておきます。)
職場など、Outlookを使わざるを得ない状況ではExchangeサーバーとOutlookが同期されているケースが多いと思うが、その場合Outlook上に登録されたタスクはOnenoteから派生した物であってもExchangeサーバーに反映されているようだ。私自身は出先でのタスク確認を行う必要がある場合はExchangeサーバー経由で携帯電話かOutlook Web Accessからタスクの確認を行っている。ただし、Onenoteに保存されているプロジェクト情報が同期されているわけではないので、プロジェクト自身の参照や編集はオリジナルのOnenoteプロジェクトが保存されているPC上で行う必要がある。このあたりもし解決策が見つかったらまた改めて記事を更新したい。

まとめ

Onenote上にノートを作成しOutlookタスクとして登録することで、GTDのプロジェクトとして利用することができる