
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`
i. `LIBCXX_DATAFILES` : カーネル内libcxxクライアントでヘッダファイルを利用可能にする場合:
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders/kernel_sdkroot`
j. `EXCLAVEKIT_DATAFILES` : Apple内部のExclaveKit SDKで
利用可能にする場合 -
`$(DSTROOT)/System/ExclaveKit/usr/include`
k. `EXCLAVECORE_DATAFILES` : Apple内部のExclaveCore SDKで
利用可能にする場合 -
`$(DSTROOT)/System/ExclaveCore/usr/include`
Makefileは、上記のファイルリストを、ビルドシステムがヘッダファイルのインストールに使用するさまざまなインストールリストに結合します。インストールリストには、マシン依存とマシン非依存の2種類があります。これらのリストは、ビルド設定に`MD`と`MI`が存在することによってそれぞれ示されます。ヘッダがアーキテクチャ固有の場合は、マシン依存のインストールリスト(例: `INSTALL_MD_LIST`)を使用する必要があります。ヘッダをすべてのアーキテクチャにインストールする場合は、マシン非依存のインストールリスト(例: `INSTALL_MI_LIST`)を使用する必要があります。
必要なインストールリストが存在しない場合は、適切なファイルリストを追加して作成します。デフォルトのインストールリスト、そのメンバーのファイルリスト、およびそれらのデフォルトの場所を以下に説明します。
a. `INSTALL_MI_LIST`, `INSTALL_MODULEMAP_MI_LIST` : ヘッダファイルとモジュールマップファイルを、
ユーザーレベルで誰もが利用できる場所にインストールします。
場所 -
$(DSTROOT)/usr/include
定義 -
INSTALL_MI_LIST = ${DATAFILES}
INSTALL_MODULEMAP_MI_LIST = ${MODULEMAPFILES}
b. `INSTALL_DRIVERKIT_MI_LIST` : ヘッダファイルをDriverKitユーザースペースドライバが利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/DriverKit/usr/include
定義 -
INSTALL_DRIVERKIT_MI_LIST = ${DRIVERKIT_DATAFILES}
c. `INSTALL_MI_LCL_LIST`, `INSTALL_MODULEMAP_MI_LCL_LIST` : ヘッダファイルと
モジュールマップファイルを、ユーザーレベルでApple内部が利用できる場所にインストールします。
場所 -
$(DSTROOT)/usr/local/include
定義 -
INSTALL_MI_LCL_LIST =
INSTALL_MODULEMAP_MI_LCL_LIST = ${PRIVATE_MODULEMAPFILES}
d. `INSTALL_IF_MI_LIST` : ヘッダファイルをIOKitユーザースペースクライアント向けに誰もが利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/IOKit.framework/Headers
定義 -
INSTALL_IF_MI_LIST = ${DATAFILES}
e. `INSTALL_IF_MI_LCL_LIST` : ヘッダファイルをIOKitユーザースペースクライアント向けにApple内部が利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/IOKit.framework/PrivateHeaders
定義 -
INSTALL_IF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES}
f. `INSTALL_SF_MI_LCL_LIST` : ヘッダファイルをユーザーレベルでApple内部が利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
定義 -
INSTALL_SF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES}
g. `INSTALL_KF_MI_LIST` : ヘッダファイルをカーネルエクステンション向けに誰もが利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
定義 -
INSTALL_KF_MI_LIST = ${KERNELFILES}
h. `INSTALL_KF_MI_LCL_LIST` : ヘッダファイルをカーネルエクステンション向けにApple内部が利用できる場所にインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
定義 -
INSTALL_KF_MI_LCL_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
i. `EXPORT_MI_LIST` : コンパイルのみを目的として、ヘッダファイルをxnu全体(bsd/、osfmk/など)に
エクスポートします。SDKには何もインストールしません。
定義 -
EXPORT_MI_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
j. `INSTALL_KF_LIBCXX_MI_LIST` : カーネル内libc++サポート用にヘッダファイルをインストールします。
場所 -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders/kernel_sdkroot
定義 -
INSTALL_KF_LIBCXX_MI_LIST = ${LIBCXX_DATAFILES}
k. `INSTALL_EXCLAVEKIT_MI_LIST` : ExclaveKit向けにApple内部が利用できる場所にヘッダファイルをインストールします。
場所 -
$(DSTROOT)/System/ExclaveKit/usr/include
定義 -
INSTALL_EXCLAVEKIT_MI_LIST = ${EXCLAVEKIT_DATAFILES}
l. `INSTALL_EXCLAVECORE_MI_LIST` : ExclaveCore向けにApple内部が利用できる場所にヘッダファイルをインストールします。
場所 -
$(DSTROOT)/System/ExclaveCore/usr/include
定義 -
INSTALL_EXCLAVECORE_MI_LIST = ${EXCLAVECORE_DATAFILES}
ヘッダファイルを(1)で説明したパスのサブディレクトリにインストールする場合は、次のように2つの変数`INSTALL_MI_DIR`と`EXPORT_MI_DIR`を使用してディレクトリ名を指定します。```text
INSTALL_MI_DIR = dirname
EXPORT_MI_DIR = dirname
モジュールマップファイルをサブディレクトリにインストールしたい場合は、
変数 INSTALL_MODULEMAP_MI_DIR を使用してディレクトリ名を次のように指定します -```text
INSTALL_MODULEMAP_MI_DIR = dirname
単一のヘッダファイルは、前述の手順を使用して異なる場所に存在させることができます。
ただし、ヘッダファイル内のすべてのコードをすべての場所で利用可能にすることが
望ましくない場合もあります。たとえば、関数をユーザーレベルではなくカーネルレベルにのみ
エクスポートしたい場合です。
C言語のプリプロセッサディレクティブ(`#ifdef`、`#endif`、`#ifndef`)を使用して、
ヘッダファイルがインストールされる前に生成されるテキストを制御できます。カーネルは、
条件付きマクロがTRUEの場合のみコードを含め、FALSE条件のコードを
ヘッダファイルから取り除きます。
いくつかの定義済みマクロとその説明は次のとおりです -
1. `PRIVATE` : 定義されている場合、囲まれた定義はSystem
Private Interfacesと見なされます。これらはxnu内で表示され、
SystemおよびKernelフレームワークのAppleInternal内にインストールされた
"PrivateHeaders"セクションで公開されます。
2. `KERNEL_PRIVATE` : 定義されている場合、囲まれたコードはxnu
カーネル全体とApple内部カーネルエクステンションで利用可能になり、
ユーザーヘッダーからは除外されます。
3. `BSD_KERNEL_PRIVATE` : 定義されている場合、囲まれたコードは
xnu/bsdモジュール内でのみ表示されます。
4. `MACH_KERNEL_PRIVATE`: 定義されている場合、囲まれたコードは
xnu/osfmkモジュール内でのみ表示されます。
5. `XNU_KERNEL_PRIVATE`: 定義されている場合、囲まれたコードは
xnu内でのみ表示されます。
6. `KERNEL` : 定義されている場合、囲まれたコードはxnuおよびカーネル
エクステンション内で利用可能であり、ユーザーレベルのヘッダファイルでは表示されません。
次のパスにインストールされたヘッダファイルのみがコードを持ちます -
```text
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
```
7. `DRIVERKIT`: 定義されている場合、囲まれたコードは
ユーザースペースドライバーが使用するDriverKit SDKヘッダー内でのみ表示されます。
8. `EXCLAVEKIT`: 定義されている場合、囲まれたコードは
ExclaveKit SDKヘッダー内でのみ表示されます。
9. `EXCLAVECORE`: 定義されている場合、囲まれたコードは
ExclaveCore SDKヘッダー内でのみ表示されます。
10. `MODULES_SUPPORTED` 定義されている場合、囲まれたコードは
モジュール/Swiftをサポートする場所でのみ表示されます(つまり、SystemまたはKernelフレームワークではありません)。
## VMヘッダファイルの命名規則
VMヘッダは次の命名規則に従います。
* `*_internal.h` ヘッダには、VMコードのみが使用するVMサブシステムのコンポーネントが含まれています。
* `*_xnu.h` ヘッダには、他のxnuコードのみが使用するVMサブシステムのコンポーネントが含まれています。
* `*.h` ヘッダには、kextにエクスポートされたVMサブシステムのコンポーネントが含まれています。
* `vm_iokit.h` ヘッダには、iokitサブシステムにエクスポートされたVMサブシステムのコンポーネントが含まれています。
* `vm_ubc.h` ヘッダには、ubcサブシステムにエクスポートされたVMサブシステムのコンポーネントが含まれています。
## モジュールマップファイルの命名規則
単純なケースでは、`usr/include` または `usr/local/include` のサブディレクトリは、
スタンドアロンモジュールとして表すことができます。この場合、
`INSTALL_MODULEMAP_MI_DIR` を `INSTALL_MI_DIR` に設定し、`module.modulemap`
ファイルをそこにインストールします。`module.modulemap` は、
`usr/local/include` 内のプライベートモジュールでも使用されます。`module.private.modulemap` は使用されません。
注意: 単純なケースを維持するには、モジュール名がディレクトリ名と完全に同じである
必要があります。それが不可能な場合は、次の方法を
適用する必要があります。
`xnu` は、CoreOSModuleMapsで定義されたモジュールに、
`usr/include/module.modulemap` と `usr/local/include/module.modulemap` から取得される
モジュールマップファイルをインストールすることで貢献しています。`xnu` の
モジュールマップファイルの命名規則は次のとおりです。
a. 理想的には、モジュールマップファイルはディレクトリ全体をカバーします。モジュールマップ
ファイルが `usr/include/a/b/c` をカバーする場合、`a_b_c.modulemap` という名前になります。
`usr/local/include/a/b/c` は `a_b_c_private.modulemap` になります。
b. 一部のヘッダは特別であり、独自のモジュールが必要です。その場合、
モジュールマップファイルは、それが定義するモジュールにちなんで命名されます。
`One.Two.Three` モジュールを定義するモジュールマップファイルは、
`one_two_three.modulemap` という名前になります。
## 条件付きコンパイル
`xnu` は、コードを条件付きでコンパイルするための以下のメカニズムを提供します。
1. *CPU特性* ガードするコードが特定の特性を持ち、
その特性が対象とするCPUアーキテクチャにのみ基づいて変化する場合は、
このオプションを使用します。アーキテクチャの機能をチェックすることを優先してください
(例: `__LP64__`、`__LITTLE_ENDIAN__` など)。
2. *新機能* ガードするコードが、まとめて見たときに
1つの機能を実装する場合、`config/MASTER` に新しい機能を定義し、
結果として得られる `CONFIG` プリプロセッサトークンを使用する必要があります
(例: `config_virtual_memory` という機能の場合、`#if CONFIG_VIRTUAL_MEMORY` を確認します)。
この方法により、既存の機能はフィーチャースイッチを変更するだけで
他のプラットフォームに導入できます。
3. *既存機能* コードが既存機能に強く結びついている場合は、
それらを使用できます(例: コードがトラステッドカーネルにのみ関連する新しい機能を実装し、
トラステッドカーネルであることの定義/理解を更新する場合、
`SECURE_KERNEL` を使用します)。
ターゲットプラットフォームに基づいたコンパイルは避けることをお勧めします。`xnu`
は `TargetConditionals.h` のプラットフォームマクロを定義しません
(`TARGET_OS_OSX`、`TARGET_OS_IOS` など)。
## XNUのデバッグ
デフォルトでは、カーネルはパニック発生時に再起動します。
この動作は `debug` ブート引数で上書きできます。`debug=0x14e` は、パニック時にデバッガが接続されるのを待機させます。
接続されたマシンからデバッグできるようにカーネルを起動するには、`kdp_match_name` ブート引数を適切な `ifconfig` インターフェースで上書きします。
ハードウェアに応じて、イーサネット、Thunderbolt、およびシリアルデバッグがサポートされています。
LLDBを使用してカーネルをデバッグします:```text
xcrun -sdk macosx lldb <path-to-unstripped-kernel>
(lldb) gdb-remote [<host-ip>:]<port>
カーネル (dSYM) のデバッグ情報には、カーネルデバッグをサポートするための一連のマクロが付属しています。
カーネルにアタッチするときにこれらのマクロを自動的に読み込むには、~/.lldbinit に以下を追加します:```text
settings set target.load-script-from-symbol-file true
`tools/lldbmacros` には、これらのコマンドのソースコードが含まれています。
使用法については、そのディレクトリの README を参照するか、組み込みの LLDB ヘルプを使用してください:```text
(lldb) help showcurrentstacks