---
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