
macOSおよびiOS向けにMach、FreeBSD、IOKitを組み合わせたハイブリッドカーネル。x86_64およびARM64上で、コアOSサービス、ドライバフレームワーク、セキュリティポリシーの適用を提供します。
XNUカーネルは、macOSおよびiOSオペレーティングシステムで使用されるDarwinオペレーティングシステムの一部です。XNUは「X is Not Unix」の頭字語です。 XNUは、カーネギーメロン大学で開発されたMachカーネルと、FreeBSDのコンポーネント、およびドライバを記述するためのC++ APIであるIOKitを組み合わせたハイブリッドカーネルです。 XNUは、シングルプロセッサとマルチプロセッサの両方の構成で、x86_64およびARM64上で動作します。
config - サポート対象アーキテクチャとプラットフォーム向けにエクスポートされたAPIの構成SETUP - カーネルの構成、バージョン管理、kextsymbol管理に使用される基本ツールセットEXTERNAL_HEADERS - ビルド時の依存関係の循環を避けるために他のプロジェクトから取得されたヘッダ。ソースが更新されたら定期的に同期する必要があるlibkern - ドライバとkextの処理を行うC++ IOKitライブラリコードlibsa - 起動用のカーネルブートストラップコードlibsyscall - ユーザースペースプログラム向けのsyscallライブラリインターフェースlibkdd - カーネルチャンクデータなどのカーネルデータを解析するユーザーライブラリのソースmakedefs - カーネルビルドのトップレベルルールと定義osfmk - Machカーネルベースのサブシステムpexpert - 割り込み処理、アトミックなどのプラットフォーム固有コードsecurity - 必須アクセスチェックポリシーインターフェースと関連実装bsd - BSDサブシステムコードtools - カーネルのテスト、デバッグ、プロファイリング用のユーティリティセットDEVELOPMENTカーネルのビルドxnu makeシステムは、KERNEL_CONFIGSおよびARCH_CONFIGS変数を引数としてカーネルをビルドできます。
構文は次のとおりです:```text
make SDKROOT= ARCH_CONFIGS= KERNEL_CONFIGS=
Where:
* `<sdkroot>`: ディスク上のmacOS SDKへのパス(デフォルトは`/`)。
* `<variant>`: `debug`、`development`、`release`、`profile`のいずれかを指定可能で、カーネルコード全体のコンパイルフラグとアサーションを設定します。
* `<arch>`: ビルド対象の有効なアーキテクチャを指定できます(例: `X86_64`)。
実行中のOSと同じアーキテクチャのカーネルをビルドするには、次のように入力するだけです。```text
make SDKROOT=macosx.internal
さらに、ARCH_CONFIGSによるアーキテクチャ設定と、KERNEL_CONFIGSによるカーネル設定がサポートされています。```text
make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=DEVELOPMENT
make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS="RELEASE DEVELOPMENT DEBUG"
> 注: デフォルトでは、アーキテクチャはビルドマシンのアーキテクチャに設定され、デフォルトのカーネル設定は `DEVELOPMENT` 向けのビルドに設定されます。
これにより、ブート可能なイメージ、kernel.[config]、 およびシンボル付きのカーネルバイナリ kernel.[config].unstripped も作成されます。
カーネルを DSTROOT にインストールするには、`install_kernels` ターゲットを使用します:```text
make install_kernels DSTROOT=/tmp/xnu-dst
より満足のいくカーネルデバッグ体験のために、 すべてのローカル変数と引数にアクセスできるが、 DEBUG カーネルの余分なチェックをすべて含まないよう、make コマンドに次のようなものを追加してください:```text CFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2" CXXFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2"
`DEVELOPMENT` と `ARM64` は、適切なビルドとプラットフォームに置き換えることを忘れないでください。
> 追加フラグ: `EXTRA_CFLAGS` ビルド設定を使用して、コマンドラインで C コンパイラに追加フラグを渡すことができます。これらのフラグは基本の `CFLAGS` に追加され、設定のデフォルト値は空文字列です。
>
> この設定を使用すると、例えばプリプロセッサマクロでガードされたデバッグコードを選択的に有効にできます。使用例...
>
> ```text
> make SDKROOT=macosx.internal PRODUCT_CONFIGS=j314s
> EXTRA_CFLAGS='-DKERNEL_STACK_MULTIPLIER=2'
> ```
* RELEASE カーネル構成でビルドする場合
```text
make KERNEL_CONFIGS=RELEASE SDKROOT=/path/to/SDK
```
### FAT カーネルバイナリのビルド
アーキテクチャは、環境変数として定義するか、make コマンド実行時に定義してください。```text
make ARCH_CONFIGS="X86_64" exporthdrs all
XNUビルドシステムは、オプションで色付きのビルド出力を生成できます。これを有効にするには、XNU_LOGCOLORS環境変数をyに設定するか、makeコマンドにLOGCOLORS=yを渡します。
xnuバージョンは、SDKまたはKDKのSystem/Library/Extensions/System.kext/Info.plistファイルのCFBundleVersionを読み取って導出されます。
これは、環境変数またはmakeコマンドラインでRC_DARWIN_KERNEL_VERSION変数を設定することでカスタマイズできます。
詳細については、doc/building/xnu_version.mdを参照してください。
デフォルトでは、インストールフェーズ中にDWARFデバッグ情報リポジトリが作成されます。これはkernel.development.<variant>.dSYMという名前の「バンドル」です。 古いSTABSデバッグ情報形式(デバッグ情報がkernel.development.unstrippedイメージに埋め込まれる)を選択するには、BUILD_STABS環境変数を設定します。```sh export BUILD_STABS=1 make
## KernelCachesの構築
xnuカーネルをテストするには、kextとカーネルをリンクして単一の起動可能なイメージにするkernelcacheを構築する必要があります。
kernelcacheを構築するには、次のメカニズムを使用できます。
* `kextd`を使用したkernelcacheの自動生成。
kextdデーモンは、`/System/Library/Extensions`ディレクトリの変更を監視し続けます。
したがって、次のように新しいカーネルをセットアップできます。
```text
cp BUILD/obj/DEVELOPMENT/X86_64/kernel.development /System/Library/Kernels/
touch /System/Library/Extensions
ps -e | grep kextd
```
* `kextcache`を手動で呼び出して新しいkernelcacheを構築する。
```text
kextcache -q -z -a x86_64 -l -n -c /var/tmp/kernelcache.test -K /var/tmp/kernel.test /System/Library/Extensions
```
## ターゲットマシンでのKernelCacheの起動
開発用カーネルとiBootはブート引数の設定をサポートしているため、テストカーネルに安全にブートでき、問題が発生した場合は以前使用していたkernelcacheに安全にフォールバックできます。
このようなセットアップを行う手順は次のとおりです。
1. `kextcache`コマンドを使用して、カーネルキャッシュを`/kernelcache.test`として作成する。
2. 既存のブート設定を代替ファイルにコピーする。
```sh
cp /Library/Preferences/SystemConfiguration/com.apple.Boot.plist /next_boot.plist
```
3. セットアップ用にkernelcacheとboot-argsを更新する。
```sh
plutil -insert "Kernel Cache" -string "kernelcache.test" /next_boot.plist
plutil -replace "Kernel Flags" -string "debug=0x144 -v kernelsuffix=test " /next_boot.plist
```
4. 新しい設定を`/Library/Preferences/SystemConfiguration/`にコピーする。
```sh
cp /next_boot.plist /Library/Preferences/SystemConfiguration/boot.plist
```
5. 新しい設定でボリュームをblessする。
```text
sudo -n bless --mount / --setBoot --nextonly --options "config=boot"
```
`--nextonly`フラグは、`boot.plist`設定を1回のブートにのみ使用することを指定します。
したがって、カーネルパニックが発生した場合でも、電源再起動するだけで元のカーネルに簡単に復旧できます。
## タグとcscopeの作成
ビルド環境をセットアップし、トップディレクトリから次のコマンドを実行します。
make tags # this will build ctags and etags on a case-sensitive volume, only ctags on case-insensitive
make TAGS # this will build etags
make cscope # this will build cscope database
## XNUからの新しいヘッダファイルのインストール
XNUはヘッダファイルを以下の場所にインストールします。
a. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
b. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
c. $(DSTROOT)/usr/include/
d. $(DSTROOT)/usr/local/include/
e. $(DSTROOT)/System/DriverKit/usr/include/
f. $(DSTROOT)/System/Library/Frameworks/IOKit.framework/Headers
g. $(DSTROOT)/System/Library/Frameworks/IOKit.framework/PrivateHeaders
h. $(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
`Kernel.framework`はカーネルエクステンションで使用されます。\
`System.framework`、`/usr/include`、`/usr/local/include`はユーザーレベルのアプリケーションで使用されます。\
`IOKit.framework`はIOKitユーザースペースクライアントで使用されます。\
`/System/DriverKit/usr/include`はユーザースペースドライバで使用されます。\
フレームワークの`PrivateHeaders`内のヘッダファイルは、**Apple内部開発**でのみ利用可能です。
ヘッダファイルを含むディレクトリには、さまざまな場所にインストールするファイルのリストを作成するMakefileが必要です。
ディレクトリに最初のヘッダファイルを追加する場合は、`xnu/bsd/sys/Makefile`と同様のMakefileを作成する必要があります。
インストール先に応じて、ヘッダファイルを適切なファイルリストに追加します。
各ファイルリストからヘッダファイルがインストールされるデフォルトの場所は次のとおりです。
a. `DATAFILES` : ヘッダファイルをユーザーレベルで利用可能にする場合 -
`$(DSTROOT)/usr/include`
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
b. `DRIVERKIT_DATAFILES` : ヘッダファイルをDriverKitユーザースペースドライバで利用可能にする場合 -
`$(DSTROOT)/System/DriverKit/usr/include`
c. `PRIVATE_DATAFILES` : ヘッダファイルをApple内部がユーザーレベルで
利用できるようにする場合 -
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
d. `EMBEDDED_PRIVATE_DATAFILES` : macOSでは`EXTRA_DATAFILES`としてユーザーレベルで
利用可能にし、組み込みOSでは`EXTRA_PRIVATE_DATAFILES`としてユーザーレベルの
Apple内部向けに利用可能にする場合 -
`$(DSTROOT)/usr/include` (`EXTRA_DATAFILES`)
`$(DSTROOT)/usr/local/include` (`EXTRA_PRIVATE_DATAFILES`)
e. `KERNELFILES` : ヘッダファイルをカーネルレベルで利用可能にする場合 -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers`
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
f. `PRIVATE_KERNELFILES` : カーネルエクステンション向けにApple内部で
利用可能にする場合 -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
g. `MODULEMAPFILES` : モジュールマップファイルをユーザーレベルで利用可能にする場合 -
`$(DSTROOT)/usr/include`
h. `PRIVATE_MODULEMAPFILES` : モジュールマップファイルをApple内部が
ユーザーレベルで利用できるようにする場合 -
`$(DSTROOT)/usr/local/include`