
हाइब्रिड कर्नेल जो macOS और iOS के लिए Mach, FreeBSD और IOKit को जोड़ता है। x86_64 और ARM64 पर कोर OS सेवाएं, ड्राइवर फ्रेमवर्क और सुरक्षा नीति प्रवर्तन प्रदान करता है।
XNU कर्नेल Darwin ऑपरेटिंग सिस्टम का हिस्सा है जो macOS और iOS ऑपरेटिंग सिस्टम में उपयोग होता है। XNU एक संक्षिप्त नाम है जो "X is Not Unix" के लिए है। XNU एक हाइब्रिड कर्नेल है जो Carnegie Mellon University में विकसित Mach कर्नेल को FreeBSD के घटकों और ड्राइवर लिखने के लिए C++ API जिसे IOKit कहते हैं, के साथ जोड़ता है। XNU x86_64 और ARM64 पर एकल प्रोसेसर और बहु-प्रोसेसर दोनों कॉन्फ़िगरेशन के लिए चलता है।
config - समर्थित आर्किटेक्चर और प्लेटफ़ॉर्म के लिए निर्यातित APIs के कॉन्फ़िगरेशनSETUP - कर्नेल कॉन्फ़िगर करने, संस्करण प्रबंधन और kextsymbol प्रबंधन के लिए उपयोग किए जाने वाले बुनियादी उपकरणों का सेटEXTERNAL_HEADERS - बिल्ड के दौरान निर्भरता चक्र से बचने के लिए अन्य प्रोजेक्ट्स से लिए गए हेडर। ये हेडर स्रोत अपडेट होने पर नियमित रूप से सिंक किए जाने चाहिए।libkern - ड्राइवर और kexts को संभालने के लिए C++ IOKit लाइब्रेरी कोडlibsa - स्टार्टअप के लिए कर्नेल बूटस्ट्रैप कोडlibsyscall - यूज़रस्पेस प्रोग्राम के लिए syscall लाइब्रेरी इंटरफ़ेसlibkdd - कर्नेल डेटा (जैसे कर्नेल चंक्ड डेटा) को पार्स करने के लिए यूज़र लाइब्रेरी का स्रोतmakedefs - कर्नेल बिल्ड के लिए शीर्ष स्तर के नियम और परिभाषाएँosfmk - Mach कर्नेल आधारित उप-प्रणालियाँpexpert - प्लेटफ़ॉर्म-विशिष्ट कोड जैसे इंटरप्ट हैंडलिंग, एटॉमिक्स आदिsecurity - Mandatory Access Check नीति इंटरफ़ेस और संबंधित कार्यान्वयनbsd - BSD उप-प्रणालियों का कोडtools - कर्नेल परीक्षण, डिबगिंग और प्रोफाइलिंग के लिए उपयोगिताओं का सेटDEVELOPMENT कर्नेल बनानाxnu make सिस्टम KERNEL_CONFIGS & ARCH_CONFIGS चरों को तर्क के रूप में लेकर कर्नेल बना सकता है।
यहाँ सिंटैक्स है:```text
make SDKROOT= ARCH_CONFIGS= KERNEL_CONFIGS=
जहाँ:
* `<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"
Remember to replace `DEVELOPMENT` and `ARM64` with the appropriate build and platform.
> Extra Flags: आप `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
## Building KernelCaches
xnu कर्नेल का परीक्षण करने के लिए, आपको एक कर्नेलकैशे बनाने की आवश्यकता है जो kexts और कर्नेल को एक ही बूट करने योग्य इमेज में जोड़ता है।
कर्नेलकैशे बनाने के लिए आप निम्नलिखित तंत्रों का उपयोग कर सकते हैं:
* `kextd` के साथ स्वचालित कर्नेलकैशे जनरेशन का उपयोग करना।
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` को मैन्युअल रूप से आमंत्रित करना।
```text
kextcache -q -z -a x86_64 -l -n -c /var/tmp/kernelcache.test -K /var/tmp/kernel.test /System/Library/Extensions
```
## Booting a KernelCache on a Target machine
डेवलपमेंट कर्नेल और iBoot बूट आर्गुमेंट्स कॉन्फ़िगर करने का समर्थन करते हैं ताकि हम सुरक्षित रूप से परीक्षण कर्नेल में बूट हो सकें और, यदि कुछ गलत हो, तो सुरक्षित रूप से पहले उपयोग किए गए कर्नेलकैशे पर वापस आ सकें।
इस तरह का सेटअप प्राप्त करने के लिए निम्नलिखित चरण हैं:
1. kextcache कमांड का उपयोग करके `/kernelcache.test` के रूप में कर्नेल कैशे बनाएं।
2. मौजूदा बूट कॉन्फ़िगरेशन को वैकल्पिक फ़ाइल में कॉपी करें
```sh
cp /Library/Preferences/SystemConfiguration/com.apple.Boot.plist /next_boot.plist
```
3. अपने सेटअप के लिए कर्नेलकैशे और बूट-आर्ग्स अपडेट करें
```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. नए कॉन्फ़िग्स के साथ वॉल्यूम को आशीर्वाद दें।
```text
sudo -n bless --mount / --setBoot --nextonly --options "config=boot"
```
`--nextonly` फ्लैग निर्दिष्ट करता है कि केवल एक बूट के लिए `boot.plist` कॉन्फ़िग्स का उपयोग करें।
इसलिए यदि कर्नेल पैनिक होता है तो आप आसानी से पावर रीबूट करके मूल कर्नेल पर वापस आ सकते हैं।
## Creating tags and cscope
अपना बिल्ड एनवायरनमेंट सेट करें और शीर्ष निर्देशिका से, चलाएँ:
make tags # यह ctags और etags बनाएगा एक case-sensitive वॉल्यूम पर, केवल ctags case-insensitive पर
make TAGS # यह etags बनाएगा
make cscope # यह cscope डेटाबेस बनाएगा
## Installing New Header Files from 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 Internal Development** के लिए उपलब्ध हैं।
हेडर फ़ाइल वाली निर्देशिका में एक 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 internal के लिए यूज़र लेवल में उपलब्ध कराने हेतु -
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
d. `EMBEDDED_PRIVATE_DATAFILES` : हेडर फ़ाइल को macOS के लिए यूज़र लेवल में `EXTRA_DATAFILES` के रूप में, लेकिन एम्बेडेड OS के लिए Apple internal में यूज़र लेवल में `EXTRA_PRIVATE_DATAFILES` के रूप में उपलब्ध कराने हेतु -
`$(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 internal को उपलब्ध कराने हेतु -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
g. `MODULEMAPFILES` : मॉड्यूल मैप फ़ाइल को यूज़र लेवल में उपलब्ध कराने हेतु -
`$(DSTROOT)/usr/include`
h. `PRIVATE_MODULEMAPFILES` : मॉड्यूल मैप फ़ाइल को Apple internal को यूज़र लेवल में उपलब्ध कराने हेतु -
`$(DSTROOT)/usr/local/include`
i. `LIBCXX_DATAFILES` : हेडर फ़ाइल को इन-कर्नेल libcxx क्लाइंट्स के लिए उपलब्ध कराने हेतु:
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders/kernel_sdkroot`
j. `EXCLAVEKIT_DATAFILES` : हेडर फ़ाइल को Apple internal ExclaveKit SDK के लिए उपलब्ध कराने हेतु -
`$(DSTROOT)/System/ExclaveKit/usr/include`
k. `EXCLAVECORE_DATAFILES` : हेडर फ़ाइल को Apple internal ExclaveCore SDK के लिए उपलब्ध कराने हेतु -
`$(DSTROOT)/System/ExclaveCore/usr/include`
Makefile ऊपर उल्लिखित फ़ाइल सूचियों को विभिन्न इंस्टॉल सूचियों में जोड़ता है जिनका उपयोग बिल्ड सिस्टम द्वारा हेडर फ़ाइलों को स्थापित करने के लिए किया जाता है। दो प्रकार की इंस्टॉल सूचियाँ हैं: मशीन-निर्भर और मशीन-स्वतंत्र। ये सूचियाँ बिल्ड सेटिंग में क्रमशः `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 internal के लिए उपलब्ध है।
स्थान -
$(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 internal को उपलब्ध स्थान पर स्थापित करता है।
स्थान -
$(DSTROOT)/System/Library/Frameworks/IOKit.framework/PrivateHeaders
परिभाषा -
INSTALL_IF_MI_LCL_LIST = ${DATAFILES} ${PRIVATE_DATAFILES}
f. `INSTALL_SF_MI_LCL_LIST` : हेडर फ़ाइल को एक ऐसे स्थान पर स्थापित करता है जो यूज़र लेवल में Apple internal के लिए उपलब्ध है।
स्थान -
$(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 internal को उपलब्ध स्थान पर स्थापित करता है।
स्थान -
$(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 internal को उपलब्ध स्थान पर स्थापित करता है।
स्थान -
$(DSTROOT)/System/ExclaveKit/usr/include
परिभाषा -
INSTALL_EXCLAVEKIT_MI_LIST = ${EXCLAVEKIT_DATAFILES}
l. `INSTALL_EXCLAVECORE_MI_LIST` : हेडर फ़ाइल को ExclaveCore के लिए Apple internal को उपलब्ध स्थान पर स्थापित करता है।
स्थान -
$(DSTROOT)/System/ExclaveCore/usr/include
परिभाषा -
INSTALL_EXCLAVECORE_MI_LIST = ${EXCLAVECORE_DATAFILES}
यदि आप हेडर फ़ाइल को (1) में वर्णित पथों की उप-निर्देशिका में स्थापित करना चाहते हैं, तो दो वेरिएबल `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` : यदि परिभाषित किया गया है, तो संलग्न परिभाषाएँ सिस्टम निजी इंटरफ़ेस मानी जाती हैं। ये xnu के भीतर दिखाई देती हैं और सिस्टम और कर्नेल फ्रेमवर्क के 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 का समर्थन करते हैं (अर्थात सिस्टम या कर्नेल फ्रेमवर्क नहीं)।
## VM हेडर फ़ाइल नामकरण परंपरा
VM हेडर निम्नलिखित नामकरण परंपराओं का पालन करते हैं:
* `*_internal.h` हेडर में VM उपतंत्र के वे घटक होते हैं जो केवल VM कोड द्वारा उपयोग के लिए हैं।
* `*_xnu.h` हेडर में VM उपतंत्र के वे घटक होते हैं जो केवल अन्य xnu कोड द्वारा उपयोग के लिए हैं।
* `*.h` हेडर में VM उपतंत्र के वे घटक होते हैं जो kexts को निर्यात किए जाते हैं।
* `vm_iokit.h` हेडर में VM उपतंत्र के वे घटक होते हैं जो iokit उपतंत्र को निर्यात किए जाते हैं।
* `vm_ubc.h` हेडर में VM उपतंत्र के वे घटक होते हैं जो ubc उपतंत्र को निर्यात किए जाते हैं।
## मॉड्यूल मैप फ़ाइल नामकरण परंपरा
सरल मामले में, `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` मॉड्यूल मैप फ़ाइलों के लिए नामकरण परंपरा इस प्रकार है।
क. आदर्श रूप से मॉड्यूल मैप फ़ाइल एक संपूर्ण निर्देशिका को कवर करती है। `usr/include/a/b/c` को कवर करने वाली मॉड्यूल मैप फ़ाइल का नाम `a_b_c.modulemap` होगा। `usr/local/include/a/b/c` को कवर करने वाली फ़ाइल का नाम `a_b_c_private.modulemap` होगा।
ख. कुछ हेडर विशेष होते हैं और उन्हें अपने स्वयं के मॉड्यूल की आवश्यकता होती है। उस स्थिति में, मॉड्यूल मैप फ़ाइल का नाम उस मॉड्यूल के नाम पर रखा जाएगा जिसे वह परिभाषित करता है। मॉड्यूल `One.Two.Three` को परिभाषित करने वाली मॉड्यूल मैप फ़ाइल का नाम `one_two_three.modulemap` होगा।
## सशर्त संकलन
`xnu` कोड को सशर्त रूप से संकलित करने के लिए निम्नलिखित तंत्र प्रदान करता है:
1. *CPU विशेषताएँ* यदि आप जिस कोड की रक्षा कर रहे हैं, उसमें विशिष्ट विशेषताएँ हैं जो केवल लक्षित CPU आर्किटेक्चर के आधार पर भिन्न होंगी, तो इस विकल्प का उपयोग करें। आर्किटेक्चर की सुविधाओं (जैसे `__LP64__`, `__LITTLE_ENDIAN__`, आदि) की जाँच करना पसंद करें।
2. *नई सुविधाएँ* यदि आप जिस कोड की रक्षा कर रहे हैं, वह एक साथ लेने पर एक सुविधा लागू करता है, तो आपको `config/MASTER` में एक नई सुविधा परिभाषित करनी चाहिए और परिणामी `CONFIG` प्रीप्रोसेसर टोकन (जैसे `config_virtual_memory` नाम की सुविधा के लिए `#if CONFIG_VIRTUAL_MEMORY` की जाँच करें) का उपयोग करना चाहिए। यह अभ्यास सुनिश्चित करता है कि केवल एक सुविधा स्विच को बदलकर मौजूदा सुविधाओं को अन्य प्लेटफार्मों पर लाया जा सकता है।
3. *मौजूदा सुविधाएँ* आप मौजूदा सुविधाओं का उपयोग कर सकते हैं यदि आपका कोड उनसे मजबूती से जुड़ा हुआ है (उदाहरण के लिए यदि आपका कोड नई कार्यक्षमता लागू करता है जो विशेष रूप से विश्वसनीय कर्नेल से संबंधित है और विश्वसनीय कर्नेल होने की परिभाषा/समझ को अपडेट करता है, तो `SECURE_KERNEL` का उपयोग करें)।
यह अनुशंसा की जाती है कि आप लक्ष्य प्लेटफ़ॉर्म के आधार पर संकलन करने से बचें। `xnu` `TargetConditionals.h` से प्लेटफ़ॉर्म मैक्रो (`TARGET_OS_OSX`, `TARGET_OS_IOS`, आदि) को परिभाषित नहीं करता है।
## XNU को डीबग करना
डिफ़ॉल्ट रूप से, पैनिक की स्थिति में कर्नेल रीबूट होता है।
इस व्यवहार को `debug` boot-arg द्वारा ओवरराइड किया जा सकता है -- `debug=0x14e` पैनिक को डीबगर के अटैच होने की प्रतीक्षा करने का कारण बनेगा।
कर्नेल को बूट करने के लिए ताकि इसे किसी संलग्न मशीन द्वारा डीबग किया जा सके, उपयुक्त `ifconfig` इंटरफ़ेस के साथ `kdp_match_name` boot-arg को ओवरराइड करें।
ईथरनेट, थंडरबोल्ट और सीरियल डीबगिंग समर्थित हैं, जो हार्डवेयर पर निर्भर करता है।
कर्नेल को डीबग करने के लिए 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