--- tags: Apple --- # Mac driver note slide: https://hackmd.io/@QSquirrel/HyUlguwGF --- > 本篇將紀錄 macOS 中開發 System Extension 及 DriverKit 的相關資料 > [name=Nick Xiao] [time=October 2021] [color=#907bf7] > > Email: s9926004@gmail.com {%hackmd ryr9Ug6sd %} --- ## 幫開發裝置掛上 Developer ID 金鑰 - Step1 - 啟動台 > 鑰匙圈存取 - Step2 - 鑰匙圈存取 > 憑證輔助程式 > 從憑證授權要求憑證 - Step3 - 使用者電子郵件位址: username@gmail.com - 一般名稱: username - CA 電子郵件位址: 不用填 - 已將要求: 儲存到磁碟 - 點選”繼續” - Step4 - 儲存憑證至電腦 - Step5 - [登入 developer 帳號](https://developer.apple.com/account/mac/certificate/distribution) - Step6 - 左邊選擇Certificates - 按下 “+” - Step7 - 選擇Developer ID Application and Kernel Extension - 按下 “Continue” - Step8 - 點選Choose File - 選取Step4所儲存的憑證 - 按下 “Continue” - Step9 - 點選Download儲存憑證 - Step10 - 開啟下載的憑證 - Step11 - 點選”加入” - 確認是否加入成功 ## 如何建立 Developer Profile 分支 由於 Developer ID Certificate 在到期前是有限且無法主動刪除的, 因此不同裝置在做開發時應該使用分支的方式, 允許擁有 Developer ID Certificate 以外的裝置開發. :::warning 以下操作在已下載 Developer ID Certificate 的電腦上 ::: - Step1 - 開啟Xcode > Preferences - Step2 - Accounts > Export Apple ID and Code Signing Assets - Step3 - 輸入電腦密碼 - Stpe4 - 設定developer profile的密碼 :::warning 以下操作為尚未下載Developer ID Certificate的裝置 ::: - Step1 - 開啟Xcode > Preferences - Step2 - Account > Import Apple ID and Code Signing Assets - Step3 - 載入剛剛所存的 developer profile - Step4 - 輸入剛剛所設定的developer profile密碼 - Step5 - 按下OK ## 申請 Notarization 流程 - Step1 - 首先這邊有四個 shell script 在之後會用到 <notarization.sh> ```Shell= #!/bin/sh FILE_PATH='/Users/nick/Desktop/Notarization/' KEXT_FILE_NAME='PeripheralDevice.kext' ZIP_FILE_NAME='PeripheralDevice.kext.zip' AC_USERNAME='username@gmail.com' AC_PASSWORD='aaaa-bbbb-cccc-dddd' BUNDLE_ID='com.username.driver.PeripheralDevice' #Apply a new app specific password: #https://appleid.apple.com/account/manage # create zip for app or kernel extension file ditto -c -k --keepParent $FILE_PATH$KEXT_FILE_NAME $FILE_PATH$ZIP_FILE_NAME #Notarize app or kernel extension xcrun altool --notarize-app --primary-bundle-id "$BUNDLE_ID" --username "$AC_USERNAME" --password "$AC_PASSWORD" --file $FILE_PATH$ZIP_FILE_NAME #Check notarization history to get Request UUDI xcrun altool --notarization-history 0 -u "$AC_USERNAME" -p "$AC_PASSWORD" ``` <notarization_check_approved.sh> ```Shell= #!/bin/sh FILE_PATH='/Users/nick/Desktop/Notarization/' KEXT_FILE_NAME='PeripheralDevice.kext' AC_USERNAME='username@gmail.com' AC_PASSWORD='aprl-awkg-pvmx-xunp' REQUEST_UUID='aaaa-bbbb-cccc-dddd' #Apply a new app specific password: #https://appleid.apple.com/account/manage #Get Notarization Info xcrun altool --notarization-info $REQUEST_UUID -u "$AC_USERNAME" -p "$AC_PASSWORD" ``` <notarization_staple.sh> ```Sehll= #!/bin/sh FILE_PATH='/Users/nick/Desktop/Notarization/' KEXT_FILE_NAME='PeripheralDevice.kext' #Attach ticket to app or kernel extension xcrun stapler staple $FILE_PATH$KEXT_FILE_NAME #Validate notarization by xcrun stapler command again if necessary xcrun stapler validate $FILE_PATH$KEXT_FILE_NAME ``` <notarization_check_notarization .sh> ```Shell= #!/bin/sh FILE_PATH='/Users/nick/Desktop/Notarization/' KEXT_FILE_NAME='PeripheralDevice.kext' #Verify the file has been notarized by spctl command spctl -a -t open --context context:primary-signature -v $FILE_PATH$KEXT_FILE_NAME ``` - Step2 - https://appleid.apple.com/account/manage/ - 登入Apple ID - 產生密碼 - Step3 - 編輯 ```notarization.sh``` - 產生的密碼填至 ```AC_PASSWORD``` - kernel extension 所在路徑填入至 ```FILE_PATH``` - Step4 - 開啟 Terminal - 到 Shell Script 路徑 - 執行 ```sh notarization.sh``` - 取得RequestUUID - Step5 - 編輯 ```notarization_check_approved.sh``` - Step4 取得的 RequestUUID 填至 ```REQUEST_UUID``` - kernel extension 所在路徑填入至 ```FILE_PATH``` - Step6 - 開啟 Terminal - 到 Shell Script路徑,執行sh - ```notarization_check_approved.sh``` 確認有無錯誤 - Step7 - 編輯 ```notarization_staple.sh``` - kernel extension 所在路徑填入至 ```FILE_PATH``` - Step8 - 開啟 Terminal - 到 Shell Script 路徑 - 執行 ```sh notarization_staple.sh``` 確認有無錯誤 - Step9 - 編輯 ```notarization_check_notarization.sh``` - kernel extension 所在路徑填入至 ```FILE_PATH``` - Step10 - 開啟 Terminal - 到 Shell Script路徑 - 執行 ```sh notarization_check_notarization.sh``` 確認有無錯誤 ## Xcode 設定注意事項 - 使用Xcode 7.0 以後的版本才能登入Apple ID 及選擇簽證, 新版的Xcode 如果沒有簽證會不能編譯 - Apple ID 登入: 上方工具列 -> Xcode -> Preferences -> Accounts - Xcode上在General的設定部分有個" Automatically manage signing", 為了避免它一直找錯開發者帳號, 請取消掉, 自行設定簽章. - 一台機器(電腦)要跑一次申請簽章的流程, 也可以同一組開發簽章, 開分支給其他台電腦 :::warning 分支簽章的有效期限和主要的有效期限有差, 請記得一開始是用哪一台的簽章做開發的. [(參考)](http://itouchs.blogspot.com/2015/04/mac-xcode.html ) ::: - Build Settings -> Architectures -> Base SDK 選擇 macOS - Build Settings -> User Defined : 這項目前不確定如何填寫, 全部留白 - Info.plist (Information Property List) :::info 目前實驗中, 基本上要根據開發環境的kernel 版本去設定OSBundleLibraries, 可以使用 uname –a 或者 sudo kextlibs PeripheralDevice.kext 查看. ::: ## Apple Silicon 平台注意事項 ### XCode設定 - Build Settings: - Architectures >``` Standard architectures - $(ARCHS_STANDARD)``` - User Define > VALID_ARCHS > ```x86_64 arm64e``` - Build: Any Mac(產生Universal版Driver支援x86_64 + arm64e) ![](https://i.imgur.com/Eo2KWea.png) - Info.plist: LSRequiresNativeExecution: YES(If you never want users to run your app under Rosetta translation on Apple Silicon platform) ![](https://i.imgur.com/BMAEGmc.png) ### 在 Recovery Mode 的安全性規則允許 kernel extension - Step1: Power off your Mac device - Step2: Press and hold the power button until system go to the Recovery mode - Step3: Click “Options” icon and press “Continue” button. If there is only one option “Security Policy”, please go to Step7 directly. ![](https://i.imgur.com/TH6eSPF.png =200x) - Step4: Select user and press “Next” - Step5: Menu > Utilities > Startup Security Utility ![](https://i.imgur.com/s2gyf5b.png =200x) - Step6: Unlock ![](https://i.imgur.com/dfWyVV7.png =300x) - Step 7: Click “Security Policy…” (安全性規則) ![](https://i.imgur.com/9lKmDwy.png =300x) - Step 8: Select “Reduced Security”, and checked “Allow user management of kernel extensions from identified developers” ![](https://i.imgur.com/nuq5QIY.png =300x) ## 如何手動卸載/安裝 kernel extension ### 手動解除安裝kernel extension: - Step1: 移除已存在kernel extension MacOS 10.14 以前 ``` $ sudo rm -rf /System/Library/Extensions/PeripheralDevice.kext ``` MacOS 10.15, 11.0 以後 ``` $ sudo rm -rf /Library/Extensions/PeripheralDevice.kext ``` - Step2: 清除Staging Extensions MacOS 10.15 以前 ``` $ sudo kextcache --clear-staging ``` MacOS 11.0以後 ``` $ sudo kmutil clear-staging ``` - Step3: 完整將kernel extension從啟動目錄移除(目前只有MacOS 11.0 Beta需要) 1. 進入Recovery Mode 2. 開啟Terminal並執行以下指令 ``` $ kmutil trigger-panic-medic --volume-root /Volumes/[Your Volume Name] ``` 3. 重新開機 ### 手動安裝kernel extension: - Step1: For Apple Silicon平台,請先按照”在Recovery Mode的安全性規則允許kernel extension”設定 - Step2: 將kernel extension複製到啟動目錄下 MacOS 10.14以前 ``` $ sudo cp -R /System/Library/Extensions ``` MacOS 10.15, MacOS 11以後 ``` $ sudo cp -R /Library/Extensions ``` - Step3: 修改 kernel extension 權限 ``` $ sudo chown -R root:wheel PeripheralDevice.kext $ sudo chmod -R 755 PeripheralDevice.kext ``` - Step4: 查看 kernel extension 是否有效 :::info 這裡會載入、檢查簽證、檢查版本以及檢查權限…等) ::: MacOS 10.14 以前 ``` $ sudo kextutil -v /System/Library/Extensions/PeripheralDevice.kext ``` MacOS 10.15 以後 ``` $ sudo kextutil -v /Library/Extensions/PeripheralDevice.kext ``` MacOS 11 以後 ``` $ sudo kmutil –load –bundle-path /Library/Extensions/PeripheralDevice.kext ``` - Step5: System Preferences > Security & Policy > 點選Allow(首次安裝時會出現) - Step6: 重新開機 - Step7: 透過檢視kernel extension狀態確認是否運作中 MacOS 10.15 以前 ``` $ sudo kextstat | grep PeripheralDevice ``` MacOS 11 以後 ``` $ sudo kmutil showloaded | grep PeripheralDevice ``` - Step8: 透過檢視dmesg檢查IOLog的印字來確認是否運作中 ``` $ sudo dmesg | grep PeripheralDevice ``` ### 手動卸載kernel extension: MacOS 10.15 以前 ``` $ sudo kextunload /Library/Extensions/PeripheralDevice.kext ``` MacOS 11 以後 ``` $ sudo kmutil unload -p /Library/Extensions/PeripheralDevice.kext ``` ### 手動載入kernel extension: MacOS 10.15以前 ``` $ sudo kextload /Library/Extensions/PeripheralDevice.kext ``` MacOS 11 以後 ``` $ sudo kmutil load -p /Library/Extensions/PeripheralDevice.kext ``` ## 測試尚未 Notarization 的 kernel extension - Step1. - 進入Recovery Mode: - Apple Silicon平台: 關機後,按住開機鍵直到燈號轉橘色,點Options進入一般平台: Command + R - Step2. - Utilities > Terminal - csrutil status確認狀態 - csrutil disable 關閉SIP - reboot - Step3. - 按照手動安裝 kernel extension 步驟安裝即可 - Step4. - 測試完畢後按照手動卸載 kernel extension 步驟卸載 - Step5. - 重新進入Recovery Mode,開啟Terminal - csrutil enable - reboot ## 參考資料 允許kernel加載 https://developer.apple.com/library/archive/technotes/tn2459/_index.html Apple後台登入管理(憑證等等): https://developer.apple.com/account/mac/certificate/distribution Apple建立分支教學: http://itouchs.blogspot.com/2015/04/mac-xcode.html Xcode 說明: https://help.apple.com/xcode/mac/8.0/#/devdc0193470 macOS SDK https://github.com/phracker/MacOSX-SDKs/releases 建立kernel文件 https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/build/build.html Xcode 設定(apple) https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptIOKit/iokit_tutorial.html#//apple_ref/doc/uid/20002366 Notarization https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution https://developer.apple.com/documentation/xcode/notarizing_your_app_before_distribution/customizing_the_notarization_workflow https://forums.developer.apple.com/message/389982#389982 建立Developer Profile分支 https://help.apple.com/xcode/mac/current/#/dev8a2822e0b https://medium.com/%E5%BD%BC%E5%BE%97%E6%BD%98%E7%9A%84-swift-ios-app-%E9%96%8B%E7%99%BC%E5%95%8F%E9%A1%8C%E8%A7%A3%E7%AD%94%E9%9B%86/%E8%BC%B8%E5%87%BA%E4%B8%8A%E6%9E%B6-ios-app-%E4%B8%8D%E8%83%BD%E6%B2%92%E6%9C%89%E7%9A%84-private-key-5d935ede10c8 Apple Silicon相關 https://developer.apple.com/documentation/xcode/porting_your_macos_apps_to_apple_silicon https://developer.apple.com/documentation/xcode/building_a_universal_macos_binary Apple Silicon的DTK的OS下載網頁 https://developer.apple.com/download/universal/ Recovery mode redo coming to Apple Silicon Macs https://www.imore.com/recovery-mode-redo-coming-apple-silicon-macs Explore the new system architecture of Apple silicon Macs https://developer.apple.com/videos/play/wwdc2020/10686/ 各種範例: https://bbs.pediy.com/thread-197990.htm https://www.itread01.com/content/1535307613.html http://www.tanhao.me/pieces/1547.html/ http://www.tanhao.me/pieces/1545.html/ http://www.tanhao.me/pieces/1525.html/ http://www.tanhao.me/pieces/1515.html/ https://www.jianshu.com/p/232022a08ba4