uchan note

プログラミングや電子工作の話題を書きます

Newlibビルドメモ

Newlibをclangを使って自作OS向けにビルドしたメモ

Newlibはなぜか、host=targetでconfigureしてしまうと何もビルドが走らない。 たとえホスト環境と同じ環境で動く自作OSをビルドする際も、ちょっと違うtargetを指定する必要があるらしい。 target=x86_64-none-elfとすることでビルドが走るようになった。

(2017/07/26追記:newlib-cygwinのトップディレクトリではなく、newlib-cygwin/newlibを直接ビルドすることでhost=targetでもビルドできた。詳しくは後述)

さて、target=Xとすると、NewlibのビルドスクリプトX-cc というクロスコンパイラが PATH が通ったところに存在することを求めてくる。 gccを使ってビルドするときは、クロスコンパイルをする際にクロスコンパイラがあることが一般的なので、まあこれは妥当な仕様なのだろう。

ところがclangはクロス環境別のclangコマンドを用意しなくても、–targetオプションで好きなバイナリを出力できる。 X-cc という名前で、clang --target=X という内容のスクリプトを用意してNewlibビルドスクリプトをだます。

今回、自作OSのバイナリを位置独立実行ファイルとしたかったので CFLAGS=-fPIC を付けたい。 クロスコンパイルするので CFLAGS_FOR_TARGET という変数に設定することがミソ。CFLAGS だとlibc.aのビルドには影響を与えることができない。

git clone git://sourceware.org/git/newlib-cygwin.git

echo 'clang --target=x86_64-none-elf "$@"' > SOMEWHERE_IN_PATH/x86_64-none-elf-cc
chmod +x SOMEWHERE_IN_PATH/x86_64-none-elf-cc

mkdir build-newlib
cd build-newlib
CC=clang ../newlib-cygwin/configure CFLAGS_FOR_TARGET='-g -O2 -fPIC' --prefix=$HOME/x86_64-none-elf --target=x86_64-none-elf
make
make install

ネイティブビルド

Newlibをビルドしている環境と、Newlibの対象の環境が等しい(host=target)の場合のビルド方法。

Newlibはx86Linux環境でネイティブビルドを行うとlibtoolを用いたビルドになる。 で、おそらくその場合に --enable-multilib オプションがデフォルトで有効になっていて、 手元の実験だと -m32 付きで64ビット向けソースコードをビルドしようとしてエラーになるという間抜けなことになった。

そこで --disable-multilib でエラーを回避した。multilibは32ビット版と64ビット版を同時に生成するような機能らしいが、どうせ64ビット版ライブラリしか使わないので。

git clone git://sourceware.org/git/newlib-cygwin.git

mkdir build-newlib
cd build-newlib
CC=clang ../newlib-cygwin/newlib/configure CFLAGS='-g -O2 -fPIC' --prefix=$HOME/x86_64-pc-linux-gnu --disable-multilib
make
make install

UEFI Memory Map メモ

UEFI で得られる Memory Map の実例。

機種:qemu-system-x86_64

Index Type PhysicalStart VirtualStart NumberOfPages Attribute
0 3 EfiBootServicesCode 00000000 00000000 1 F
1 7 EfiConventionalMemory 00001000 00000000 9F F
2 7 EfiConventionalMemory 00100000 00000000 700 F
3 A EfiACPIMemoryNVS 00800000 00000000 8 F
4 7 EfiConventionalMemory 00808000 00000000 8 F
5 A EfiACPIMemoryNVS 00810000 00000000 8 F
6 7 EfiConventionalMemory 00818000 00000000 8 F
7 A EfiACPIMemoryNVS 00820000 00000000 E0 F
8 4 EfiBootServicesData 00900000 00000000 A00 F
9 7 EfiConventionalMemory 01300000 00000000 2C36 F
10 4 EfiBootServicesData 03F36000 00000000 20 F
11 7 EfiConventionalMemory 03F56000 00000000 2C89 F
12 2 EfiLoaderData 06BDF000 00000000 100 F
13 1 EfiLoaderCode 06CDF000 00000000 3 F
14 3 EfiBootServicesCode 06CE2000 00000000 AA F
15 A EfiACPIMemoryNVS 06D8C000 00000000 C F
16 0 EfiReservedMemoryType 06D98000 00000000 17 F
17 6 EfiRuntimeServicesData 06DAF000 00000000 20 800000000000000F
18 7 EfiConventionalMemory 06DCF000 00000000 167 F
19 4 EfiBootServicesData 06F36000 00000000 106 F
20 7 EfiConventionalMemory 0703C000 00000000 3 F
21 4 EfiBootServicesData 0703F000 00000000 5FB F
22 7 EfiConventionalMemory 0763A000 00000000 C F
23 4 EfiBootServicesData 07646000 00000000 689 F
24 7 EfiConventionalMemory 07CCF000 00000000 D F
25 3 EfiBootServicesCode 07CDC000 00000000 173 F
26 5 EfiRuntimeServicesCode 07E4F000 00000000 30 800000000000000F
27 6 EfiRuntimeServicesData 07E7F000 00000000 24 800000000000000F
28 0 EfiReservedMemoryType 07EA3000 00000000 4 F
29 9 EfiACPIReclaimMemory 07EA7000 00000000 8 F
30 A EfiACPIMemoryNVS 07EAF000 00000000 4 F
31 4 EfiBootServicesData 07EB3000 00000000 63 F
32 3 EfiBootServicesCode 07F16000 00000000 18 F
33 4 EfiBootServicesData 07F2E000 00000000 9 F
34 3 EfiBootServicesCode 07F37000 00000000 11 F
35 7 EfiConventionalMemory 07F48000 00000000 8 F
36 6 EfiRuntimeServicesData 07F50000 00000000 20 800000000000000F
37 7 EfiConventionalMemory 07F70000 00000000 8 F
38 A EfiACPIMemoryNVS 07F78000 00000000 88 F
39 6 EfiRuntimeServicesData FFE00000 00000000 200 8000000000000001

x86 OS自作ゼミの進め方

セキュリティ・キャンプ2017のx86 OS自作ゼミの進め方、最大限の成果を出す方法について思うところを書きます。

3日間は短い!

x86 OS自作ゼミは3日間しかありません(それでもセキュリティ・キャンプの中では最長なのですが)。OS自作という壮大なテーマに対して3日間というのはとても短いです。しかし短い中でも人に自慢できる成果が出た方が本人も楽しいだろうし、講師も皆さんの成果を見て楽しみたいと思っていますので、3日間である程度のモノが出来上がるようにしたいです。

3日間というと、独自のOSを1からそれなりの完成度まで持っていくには時間が到底足りません。「30日でできる!OS自作入門」をノンストップで読みまくると、それだけで3日間が終わるでしょう。それくらい短い時間です。

講師を最大限活用する

この3日間は、講師が皆さんのプログラミングをお手伝いする、というのが基本スタイルです。みっちり講義をするのではなく、皆さんが自分で手を動かして、講師がデバッグや設計のお手伝いをします。逆に、講師をどれだけ活用できるかが勝負と言ってもいいかもしれません。

ということで、受講者の皆さんには3日間という時間リソースと、講師という人的リソースを最大限に活用して成果を出せるようにネタを仕込んできていただきたいです。例えば、キャンプ当日までに基本的なコードは書いておいて、3日間は講師を捕まえてデバッグを手伝わせる、なんてのはいいやり方です。デバイスドライバを作ろうと思うのであれば、キャンプに来る前にそのデバイスに関する情報(IOポートの番号、デバイスレジスタ表、サンプルコードなど)を集めておいて、3日間は調べ物に時間をかけなくて良いようにする、というのもいいですね。

関連リンク

  • seccamp2017x86 OS自作ゼミの概要とか講師紹介とか、応募課題の出題意図の説明とか

seccamp2017

x86 OS自作ゼミ 基本情報

x86 OS自作ゼミの基本的な情報は以下の通りです。

  • タイトル:x86 OS自作ゼミ
  • トラック:言語やOSを自作しよう
  • 時間帯:3日間連続
  • 必要機材:PCのみ
  • 事前学習:あり(詳しくは後述)

x86 OS自作ゼミ 概要

講師がサポートしつつ、世界に1つのPC用オリジナルOSを作ります。

開発テーマは何でも良いです。 例えば「はりぼてOS」に新しい機能(コマンドラインシェル、ディスク書き込み、プロセス間通信など)を追加したり、 最新のハードウェア(マルチコア、64bit、NICなど)に対応したOSをフルスクラッチで作ったり。 自分でOSを作っている方はもちろん、このゼミをきっかけに作り始めようとする方も、チャレンジ精神さえあれば幅広く対応します。

講師紹介

x86 OS自作ゼミでは2人の講師が参加者の皆さんの開発をサポートします。2人とも「自作OSもくもく会」を主催するosdev-jpのコアメンバーで、OS自作に対する幅広い知識を持っています。

内田公太

サイボウズ株式会社のソフトウェアエンジニアを務める傍ら、「自作OSもくもく会」を主催するなど「OSの自作」という楽しい趣味の普及に向けて活動しています。本業ではPythonやGo言語に触ることが多いですが、本当はもっとC++をやりたいです。自作OSはC++で書いています。

中学生のころに川合さん(言語自作ゼミの講師)が作っていたOSASKというOSに出会いました。そこから「30日でできる!OS自作入門」の校正作業を手伝いつつ、自分のOSを作りました。社会人になってからは粟本さん、西田さん(セキュアなCPUを自作しようゼミの講師)とともにosdev-jpというコミュニティを作り、OS自作活動の普及を目指しています。

セキュリティキャンプでは、参加者の皆さんの質問に答えたり、デバッグを手伝ったりして、OS開発のサポートをさせていただきます。

粟本真一

東京大学情報理工学系研究科コンピュータ科学専攻の加藤研究室で、主にメニーコア(Intel Xeon Phi Knights Landing processor)向けOSの研究をしています。研究兼趣味で書いているOSカーネルでは、比較的最近のデバイス(ここ10年くらい?のデバイス、マルチコア/メニーコアアーキテクチャ、PCIe、Intel NIC、USB)の実装等を行っているので、そういった事がやりたい、というチャレンジングな要望は特に歓迎します。

テーマ例

x86 OS自作ゼミの開発テーマは自由ですが、いくつかそれっぽい例をご紹介します。参加者の皆さんは、ここに書いてあるテーマでもいいですし、もちろん独自のテーマでも良いので、1つテーマを選んで応募時に書いてください。

  • はりぼてOSにディスク書き込み機能を付ける
  • はりぼてOSのセキュリティバグを探して直す
  • はりぼてOSで任意コード実行するバグを利用してマルウェアを作る
  • 新しいメモリアロケータを実装する
  • ページングに対応する
  • デバイスドライバを追加する
  • プロセス間通信をサポートする
  • マルチスレッドをサポートする
  • マルチコアをサポートする
  • 64bit対応する
  • NICドライバを実装してネットワーク通信する
  • オンメモリファイルシステムを実装する
  • カーネルモジュール機能を付ける
  • 高機能なコマンドラインシェルを実装する
  • 自作OSと組み込み機器をシリアル通信でつないで何かする

応募課題の出題意図

応募課題を通して講師が見たいのは、応募者である皆さんの「やる気」です。もちろん、ゼミを有意義なものにするのに必要な技術力は要求しますが、応募者の中から技術力の高い順に採用するわけではありません。皆さんには課題に答える形で、「自分がどれだけOS自作に興味があるか」を表現して欲しいです。

ただし「やる気がある」というのは、単に大きな声で「僕/私はこれをやりたいです!」と言えばいいというわけではありません。皆さんに期待する「やる気」は、自分で設定した課題に対していかに熱心に取り組み、問題解決できるかどうかです。今の技術力が低くとも、「やる気がある」人なら将来伸びることでしょう。講師としては、是非そういう人と一緒にキャンプの3日間を過ごしたいです。応募課題はこちらが与えた問題に答えてもらう形式ではありますが、問題に対して本気で取り組んだことを解答の中で示してください。

選択問題は基本的に「考察してください/自由に論じてください」といった形式です。自由に書けるため、一見すると簡単に思えるかもしれません。しかし、どの設問も広範な知識を要求するため、それぞれの設問で議論すべき要素を列挙することさえ難しいでしょう。現時点で議題を列挙できる必要はありませんが、少なくともWebを検索して分かる程度のことは調べてください。そして、調べたことをそのまま書くのではなく、自分の意見などで肉付けしてください。自分の意見を書くときは、なるべく根拠も書いてください。根拠のない独りよがりの意見は受け入れ難いものです。

このゼミはOS自作ゼミですから、自分のこれまでのOS自作経験を基に考察なり論じることができると良い解答になるでしょう。さらに説得力のある解答にするためには、出題されているテーマを本当に実装してみるといいかもしれません。例えばスピンロックを実装してみると利点や欠点が実体験として分かる可能性があります。ここまで頑張るかは、応募する皆さんにお任せします。

設問4は、共通課題やこのゼミの設問1-3の中で書ききれなかった自己アピールを書いてもらう設問です。「設問3は難しいから飛ばして、その分設問4にいっぱい書く」よりは、きちんと設問3を解答してくれた方が出題者は喜びます。

選択問題の補足

x86 OS自作ゼミの応募課題の中でも、難易度が高いと思われる選択問題について補足の説明をします。

選択問題は意図的に難しくしています。各問題について詳しくない人が多いと思いますが、ウェブや書籍で調べ、自分なりに回答していただきたいと思いながら設問を考えました。もちろん既に知識のある方はその知識を活用して回答を書いていただいて問題ありませんが、そうでない方もあきらめないで欲しいです。

各問題の出題意図と、その問題についての情報源を示しますので、回答する際の参考にしてください。

設問3.a

i386が持つメモリ管理機能であるセグメンテーションとページングについて説明してください。また、現代のOSではセグメンテーションは使われていませんが、その理由を考察してください。さらに、現代のOSにおけるページングの用途を説明してください。

この問題はOSの基本的な機能の1つであるメモリ管理を、CPUの視点から説明してもらう問題です。i386でセグメンテーションとページングという機能が追加されました。どちらの機能もメモリ管理に役立ちそうに見えますが、LinuxWindowsなどの現代的なOSではセグメンテーションは使われていません。それぞれの機能の特徴を比べ、セグメンテーションの何が、メモリ管理機能を実装する際の障壁になったのか、ページングではその障壁をどうやって回避したのかを議論してください。

役立つ情報源: - 『はじめて読む486』蒲地輝尚著(アスキー) - 5章「セグメント」 - 9章「ページング」 - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 4.3.1「ページング」 - 4.6「セグメンテーション」

設問3.b

OSカーネル内でスピンロックを用いる事の、利点や課題点(及びその改善策)等々を理由と共に自由に論じてください。

この問題は、マルチコアPC用のOSを作る際に必要となる技術である排他制御技術の中でも単純な原理のスピンロックを扱った問題です。排他制御技術にはいろいろな種類があります。例えばミューテックス、リーダー・ライターロック、RCUなど。工夫を凝らした技術があるのに、いまだにスピンロックが使われるのは相応の利点があるからです。もちろん、スピンロックの原理から生ずる課題点もあります。それらを自由に論じてください。

役立つ情報源: - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 2.2.3「ビジーウエイトによる相互排除」

設問3.c

ディスクはメモリに比べてとても遅いので、ファイル書き込みのシステムコールが同期的にディスクを操作すると絶望的に遅くなります。改善策を考えてください。また将来、不揮発性メモリ(NVM)が普及し、メモリと同じ要領で永続記憶にアクセスできるようになる事が期待されていますが、そのような世界のOSはどのような変化を遂げているでしょうか?根拠と共に自由に論じてください。

この問題は、CPU・メモリ・ディスクの速度差と、そこから生じる問題を軽減するための技術にはどんなものがあるかを問う問題です。例えば、引数に与えたバイト列をファイルに書き込むシステムコールがあるとします(C言語のfwriteのようなもの)。そのシステムコールが、内部でディスクのヘッドをシークしたりバイト列を書き込んだりした場合、1回の実行に数10ミリ秒以上かかることになります。これはとっても遅いです。こうならないためには、どんな改善策があるでしょうか。

現在Intel 3D Xpoint等に代表される、NVM(nonvolatile memory)と呼ばれるストレージが開発されています。これまでのストレージの多く(HDDやSSD)はブロック単位で読み書きしますが、NVMはメモリと同じようにバイト単位で読み書きできるようになり、速度もメモリ並になると予想されています。現在のOSインターフェース(システムコールなど)のままで、この次世代アーキテクチャを使いこなせるでしょうか?使いこなせないと思った場合は改善策を考えてみてください。そうでない(今のOSの仕組みでも使いこなせる)と思う場合は、その根拠を考えてみてください。

役立つ情報源: - 『オペレーティングシステム第3版』アンドリュー・S・タネンバウム、アルバート・S・ウッドハル共著(ピアソン・エデュケーション) - 5.3.6「ファイルシステムの性能」 - How Intel’s 3D XPoint will transform servers and storageZDNet、2016年3月31日 - 大解説! IntelとMicronが提唱した次世代メモリ規格「3D Xpoint Technology」ITmedia、2015年08月14日

事前学習

x86 OS自作ゼミは「事前学習あり」ということにしています。なぜなら、OS自作を全くしたことがなく、開発環境の構築の方法から教えてください、というようなレベルでキャンプ当日を迎えてほしくないからです。自分で作りたいものが決まっていて、コンパイルなどがちゃんとできる状態までは自分で学習してきてください。

キャンプ当日はいきなりコーディングを始められると理想的です。そのために、次のような状態になっていると良いです。 - 他のOSの力を借りずに自力で起動するようなプログラムが作れるようになっている - QEMUなどのエミュレータ上で起動するだけでも構いません。『30日でできる!OS自作入門』を読むなどすると学習できます。 - ある程度の大きさのプログラムを自在に書ける - このゼミではある程度のプログラミング力が必須です。OS自体を作ったことがなくてもいいですが、何らかのプログラム経験は積んでおいてください。 - 開発環境の操作に慣れている - キャンプで使う予定の開発環境の操作には事前に慣れておきましょう。

パソコンなどの準備

キャンプ受講者にはノートパソコンが貸し出される予定です。そのパソコンにはテキストエディタバイナリエディタの他、『30日でできる!OS自作入門』の開発環境であるtolset_hがインストールされています。それだけで十分なら、ご自分のパソコンは持参しなくても大丈夫です。

tolset_h以外の開発環境を使いたい場合、開発環境をインストール済みのパソコンを持参してください。例えばLinuxで開発したいとか、こだわりのテキストエディタを使いたいとかいう場合は、それらをインストールしたパソコンをキャンプ会場に持ってきてください。また、特定のハードウェアのためのドライバを書きたい場合、そのハードウェアが搭載されたパソコンをご自身で準備してください。

容量の大きな資料などは事前にダウンロードしておくとスムーズです。Linuxソースコードを参考にするつもりなら事前にgit cloneしておきましょう。アセンブリでプログラムを書きたいなら、インテル・ソフトウェア・デベロッパーズ・マニュアルのPDFをダウンロードしておくといいでしょう。

※パソコンの持参は自己責任でお願いします。キャンプ中に壊れてしまっても講師やセキュリティキャンプ実施協議会は責任は取れません。特に、OS開発にはハードウェアを壊すリスクがつきまといます。

関連リンク

【技術書典2】Linuxカーネルモジュール自作入門を出します(ダウンロード販売有)

皆さんは 技術書典2 というイベントをご存知でしょうか。2017年4月9日に秋葉原で開催される、技術書オンリーの同人誌即売会です。

この記事では、技術書典2のために書いた Linuxカーネルモジュール自作入門」 の目次をご紹介します。最後にダウンロード販売のお知らせもあります。

追記:おかげさまで、技術書典2自体も私たちのブースも非常に盛況でした。ご来場いただいた方々、運営の方々、他サークルの方々、大変ありがとうございました。ダウンロード販売のお知らせを更新しましたので、興味のある方はご確認をお願いします。

販売情報

  • 日時 2017年4月9日(日)
  • 場所 アキバ・スクエア
  • ブース き-09「tech@サイボウズ式」編集部
  • 書名 Linuxカーネルモジュール自作入門
  • ページ数 36(表紙含む)

目次

第1章「はじめに」より:

 本書を手にとって頂いてありがとうございます。この本はLinuxカーネルモジュールのビルド手順を説明する本です。Hello Worldを画面に表示するだけのモジュールを紹介します。さらに、カーネルブレークポイントを仕掛けるkprobesやカーネル内の変数を公開できるsysfsというLinuxの機能を自作モジュールから使ってみます。

 読者は基本的なLinuxの操作ができ、C言語の読み書きができることを前提としています。Linuxカーネルソースコードは読んだことがなくても大丈夫です。

  • 第1章 はじめに
    • 1.1 Linux カーネルモジュールとは
    • 1.2 動作確認環境
    • 1.3 著者について
    • 1.4 本書の取り扱い方法
  • 第2章 Hello World モジュール
  • 第3章 モジュール解剖
    • 3.1 カーネルヘッダ
    • 3.2 module 構造体
    • 3.3 モジュールファイル
    • 3.4 モジュール情報セクション
    • 3.5 シンボルバージョンセクション
  • 第4章 kprobes
    • 4.1 プローブの種類
    • 4.2 jprobe の登録
    • 4.3 コールバック関数の定義
    • 4.4 jprobe の実験
    • 4.5 全体ソースコード
  • 第5章 sysfs
    • 5.1 sysfs を覗いてみる
    • 5.2 sysfs に値を公開する
    • 5.3 コールバック
    • コラム scnprintf
    • 5.4 sysfs への登録
    • 5.5 ビルドと実行
    • コラム echo とdd
  • 参考文献

ダウンロード販売

同人誌即売会の雰囲気を大事にしたいので、当日ブースまで来ていただけると嬉しいです。しかし、何らかの理由により来られない場合、ダウンロード販売もしますのでご利用ください。

ダウンロード販売は、Amazonギフト券500円分を @uchan_nos までDMしていただければダウンロードURLをお教えします。

自作OS Advent Calendar 2016 目次

これは 自作 OS Advent Calendar 2016 の 25 日目の記事です。 1 日目から 24 日目までの記事をまとめた目次になっています。

それぞれの記事のURLの後に書いてある一言紹介は、uchanによるものです。 記事の著者さんに確認を取っておらず、もしかしたら誤った内容の可能性があります。

OSの機能拡張

OS自作用の処理系いろいろ

BIOS/UEFI

  • 12/4 neriring2

    • はりぼてOSをUEFIで起動する/総集編 - 借り初めのひみつきち
    • http://neriring.hatenablog.jp/entry/2016/12/04/180254
    • タイトルの話もさることながら、近年はレガシーデバイスがサポートされなくなってOS開発が厳しいね、という話が興味深い(と同時にちょっと悲しい)です。
  • 12/7 hikalium

  • 12/14 liva_jy

    • ディスクイメージをネットワークブートする – Raphine Project<サイト製作中>
    • https://raphine.wordpress.com/2016/12/14/netboot/
    • 開発マシンに立てた簡易HTTPサーバでOSイメージを配布し、ターゲットマシンでOSを起動させちゃうお話です。やってみたくなること間違い無し。
  • 12/17 ナカタニ

その他技術話

エッセイ

はりぼてOSでELFなアプリを起動する

これは 自作 OS Advent Calendar 2016 の 18 日目の記事です。

概要

『30 日でできる!OS 自作入門』 の「はりぼて OS」が対応している実行可能形式は HRB 形式です。 HRB という名の通り「はりぼて OS」独自の形式で、.text、.data、.bss セクションに相当するデータを含むことができます。

構造がシンプルなので、入門者にとっては実行可能形式を学ぶのに都合がいい形式であると思います。 しかし、独自形式ゆえ周辺のツールが整いづらく、実際に扱いやすい形式というわけでもありません。

本記事では、Linux 環境でスタンダードとなっている ELF 形式を「はりぼて OS」でも動かそうじゃないか、ということでやり方をご紹介します。 ELF 形式のアプリをロードして実行する方法(OS 側)、ELF 形式でアプリをコンパイルする方法(アプリ側)の 2 つの側面から解説します。

f:id:uchan_nos:20161218173129p:plain

画像はいらすとやから頂いたエルフです。

続きを読む