feat: auto-install WinUSB driver for Kneron devices on Windows
Bundle WinUSB driver INF + co-installer DLLs in installer payload. During USB driver setup step, extract driver files and run pnputil to install the WinUSB driver for all Kneron devices (KL520 VID_3231&PID_0100, KL720 VID_3231&PID_0200, KL720v2 VID_3231&PID_0720). This eliminates the need for manual Zadig installation, which was the root cause of KP_ERROR_CONNECT_FAILED_28 on Windows. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
49bdef68c7
commit
f744e8ca26
@ -117,6 +117,10 @@ jobs:
|
||||
Copy-Item "local_service_win\third_party\Kneron_DFUT\bin\libusb-1.0.dll" "$base\installer\payload\scripts\"
|
||||
$kpWheel = Get-ChildItem "local_service_win" -Filter "KneronPLUS*.whl" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($kpWheel) { Copy-Item $kpWheel.FullName "$base\installer\payload\scripts\" }
|
||||
New-Item -ItemType Directory -Force -Path "$base\installer\payload\drivers\amd64"
|
||||
Copy-Item "$base\server\scripts\drivers\kneron_winusb.inf" "$base\installer\payload\drivers\"
|
||||
Copy-Item "local_service_win\LocalAPI\win_driver\amd64\WdfCoInstaller01011.dll" "$base\installer\payload\drivers\amd64\"
|
||||
Copy-Item "local_service_win\LocalAPI\win_driver\amd64\winusbcoinstaller2.dll" "$base\installer\payload\drivers\amd64\"
|
||||
|
||||
- name: Build Windows installer
|
||||
run: |
|
||||
|
||||
4
.github/workflows/build-installer.yaml
vendored
4
.github/workflows/build-installer.yaml
vendored
@ -117,6 +117,10 @@ jobs:
|
||||
Copy-Item "local_service_win\third_party\Kneron_DFUT\bin\libusb-1.0.dll" "$base\installer\payload\scripts\"
|
||||
$kpWheel = Get-ChildItem "local_service_win" -Filter "KneronPLUS*.whl" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($kpWheel) { Copy-Item $kpWheel.FullName "$base\installer\payload\scripts\" }
|
||||
New-Item -ItemType Directory -Force -Path "$base\installer\payload\drivers\amd64"
|
||||
Copy-Item "$base\server\scripts\drivers\kneron_winusb.inf" "$base\installer\payload\drivers\"
|
||||
Copy-Item "local_service_win\LocalAPI\win_driver\amd64\WdfCoInstaller01011.dll" "$base\installer\payload\drivers\amd64\"
|
||||
Copy-Item "local_service_win\LocalAPI\win_driver\amd64\winusbcoinstaller2.dll" "$base\installer\payload\drivers\amd64\"
|
||||
|
||||
- name: Build Windows installer
|
||||
run: |
|
||||
|
||||
@ -135,6 +135,14 @@ installer-payload: build-server-tray ## Stage payload files for GUI installer
|
||||
cp ../local_service_win/KneronPLUS*.whl installer/payload/scripts/; \
|
||||
echo " KneronPLUS wheel bundled."; \
|
||||
fi
|
||||
@# Copy WinUSB driver files (for Windows installer)
|
||||
@mkdir -p installer/payload/drivers/amd64
|
||||
cp server/scripts/drivers/kneron_winusb.inf installer/payload/drivers/
|
||||
@if [ -d "../local_service_win/LocalAPI/win_driver/amd64" ]; then \
|
||||
cp ../local_service_win/LocalAPI/win_driver/amd64/WdfCoInstaller01011.dll installer/payload/drivers/amd64/; \
|
||||
cp ../local_service_win/LocalAPI/win_driver/amd64/winusbcoinstaller2.dll installer/payload/drivers/amd64/; \
|
||||
echo " WinUSB driver files bundled."; \
|
||||
fi
|
||||
@echo "Payload staged in installer/payload/"
|
||||
|
||||
installer: installer-payload ## Build GUI installer app
|
||||
|
||||
@ -71,43 +71,50 @@ func removeSystemLink() {
|
||||
}
|
||||
|
||||
func installLibusb(installDir string) error {
|
||||
// Check if already present in system or install directory
|
||||
checkPaths := []string{
|
||||
filepath.Join(os.Getenv("SystemRoot"), "System32", "libusb-1.0.dll"),
|
||||
filepath.Join(os.Getenv("SystemRoot"), "SysWOW64", "libusb-1.0.dll"),
|
||||
filepath.Join(installDir, "libusb-1.0.dll"),
|
||||
}
|
||||
for _, p := range checkPaths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return nil // already installed
|
||||
}
|
||||
}
|
||||
|
||||
// Try to extract libusb-1.0.dll from payload to install directory
|
||||
// The DLL is bundled at payload/scripts/libusb-1.0.dll
|
||||
// 1. Extract libusb-1.0.dll from payload
|
||||
dllDest := filepath.Join(installDir, "libusb-1.0.dll")
|
||||
data, err := payloadFS.ReadFile("payload/scripts/libusb-1.0.dll")
|
||||
if err == nil {
|
||||
if writeErr := os.WriteFile(dllDest, data, 0644); writeErr == nil {
|
||||
return nil // successfully extracted
|
||||
if _, err := os.Stat(dllDest); os.IsNotExist(err) {
|
||||
data, readErr := payloadFS.ReadFile("payload/scripts/libusb-1.0.dll")
|
||||
if readErr == nil {
|
||||
os.WriteFile(dllDest, data, 0644)
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: try winget
|
||||
if wingetPath, err := exec.LookPath("winget"); err == nil {
|
||||
cmd := exec.Command(wingetPath, "install", "libusb",
|
||||
"--accept-source-agreements", "--accept-package-agreements", "--silent")
|
||||
cmd.Run() // best effort
|
||||
// 2. Extract and install WinUSB driver for Kneron devices
|
||||
installWinUSBDriver(installDir)
|
||||
|
||||
// Re-check
|
||||
for _, p := range checkPaths {
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// installWinUSBDriver extracts the WinUSB driver package from the payload
|
||||
// and installs it via pnputil so libusb can access Kneron USB devices.
|
||||
func installWinUSBDriver(installDir string) {
|
||||
driverDir := filepath.Join(installDir, "drivers")
|
||||
os.MkdirAll(filepath.Join(driverDir, "amd64"), 0755)
|
||||
|
||||
// Extract driver files from embedded payload
|
||||
driverFiles := map[string]string{
|
||||
"payload/drivers/kneron_winusb.inf": filepath.Join(driverDir, "kneron_winusb.inf"),
|
||||
"payload/drivers/amd64/WdfCoInstaller01011.dll": filepath.Join(driverDir, "amd64", "WdfCoInstaller01011.dll"),
|
||||
"payload/drivers/amd64/winusbcoinstaller2.dll": filepath.Join(driverDir, "amd64", "winusbcoinstaller2.dll"),
|
||||
}
|
||||
|
||||
for src, dst := range driverFiles {
|
||||
data, err := payloadFS.ReadFile(src)
|
||||
if err != nil {
|
||||
return // driver files not bundled, skip silently
|
||||
}
|
||||
if err := os.WriteFile(dst, data, 0644); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("libusb not found. For Kneron USB device support, install the WinUSB driver via Zadig: https://zadig.akeo.ie")
|
||||
infPath := filepath.Join(driverDir, "kneron_winusb.inf")
|
||||
|
||||
// Use pnputil to add driver to the driver store and install on matching devices.
|
||||
// This requires admin privileges; pnputil will trigger a UAC prompt if needed.
|
||||
cmd := exec.Command("pnputil", "/add-driver", infPath, "/install")
|
||||
cmd.CombinedOutput() // best effort — non-fatal if it fails
|
||||
}
|
||||
|
||||
func checkLibusbInstalled() bool {
|
||||
|
||||
@ -94,6 +94,18 @@ if ($kpWheel) {
|
||||
Write-Host " KneronPLUS wheel not found, skipping." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# Copy WinUSB driver files
|
||||
New-Item -ItemType Directory -Force -Path installer\payload\drivers\amd64 | Out-Null
|
||||
Copy-Item server\scripts\drivers\kneron_winusb.inf installer\payload\drivers\
|
||||
$winDriverDir = Join-Path $repoRoot "local_service_win\LocalAPI\win_driver\amd64"
|
||||
if (Test-Path $winDriverDir) {
|
||||
Copy-Item (Join-Path $winDriverDir "WdfCoInstaller01011.dll") installer\payload\drivers\amd64\
|
||||
Copy-Item (Join-Path $winDriverDir "winusbcoinstaller2.dll") installer\payload\drivers\amd64\
|
||||
Write-Host " WinUSB driver files bundled." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " WinUSB co-installer DLLs not found, skipping." -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
$fileCount = (Get-ChildItem -Recurse installer\payload -File).Count
|
||||
Write-Host " Payload staged: $fileCount files." -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
82
edge-ai-platform/server/scripts/drivers/kneron_winusb.inf
Normal file
82
edge-ai-platform/server/scripts/drivers/kneron_winusb.inf
Normal file
@ -0,0 +1,82 @@
|
||||
; kneron_winusb.inf
|
||||
; WinUSB driver for Kneron KL520 and KL720 USB AI accelerators
|
||||
; Supports: KL520 (PID 0x0100), KL720 KDP legacy (PID 0x0200), KL720 KDP2 (PID 0x0720)
|
||||
|
||||
[Strings]
|
||||
DeviceName520 = "Kneron KL520"
|
||||
DeviceName720 = "Kneron KL720"
|
||||
DeviceName720v2 = "Kneron KL720 v2"
|
||||
VendorName = "Kneron Inc."
|
||||
SourceName = "Kneron WinUSB Install Disk"
|
||||
DeviceGUID = "{A897B340-F751-4FEE-8DAD-40EC8BC77200}"
|
||||
|
||||
[Version]
|
||||
Signature = "$Windows NT$"
|
||||
Class = "USBDevice"
|
||||
ClassGuid = {88bae032-5a81-49f0-bc3d-a4ff138216d6}
|
||||
Provider = %VendorName%
|
||||
CatalogFile = kneron_winusb.cat
|
||||
DriverVer = 03/09/2026, 6.1.7600.16385
|
||||
|
||||
[ClassInstall32]
|
||||
Addreg = WinUSBDeviceClassReg
|
||||
|
||||
[WinUSBDeviceClassReg]
|
||||
HKR,,,0,"Universal Serial Bus devices"
|
||||
HKR,,Icon,,-20
|
||||
|
||||
[Manufacturer]
|
||||
%VendorName% = KneronDevices,NTamd64
|
||||
|
||||
[KneronDevices.NTamd64]
|
||||
%DeviceName520% = USB_Install, USB\VID_3231&PID_0100
|
||||
%DeviceName720% = USB_Install, USB\VID_3231&PID_0200
|
||||
%DeviceName720v2% = USB_Install, USB\VID_3231&PID_0720
|
||||
|
||||
[USB_Install]
|
||||
Include = winusb.inf
|
||||
Needs = WINUSB.NT
|
||||
|
||||
[USB_Install.Services]
|
||||
Include = winusb.inf
|
||||
AddService = WinUSB,0x00000002,WinUSB_ServiceInstall
|
||||
|
||||
[WinUSB_ServiceInstall]
|
||||
DisplayName = "WinUSB - Kneron USB Device"
|
||||
ServiceType = 1
|
||||
StartType = 3
|
||||
ErrorControl = 1
|
||||
ServiceBinary = %12%\WinUSB.sys
|
||||
|
||||
[USB_Install.Wdf]
|
||||
KmdfService = WINUSB, WinUsb_Install
|
||||
|
||||
[WinUSB_Install]
|
||||
KmdfLibraryVersion = 1.11
|
||||
|
||||
[USB_Install.HW]
|
||||
AddReg = AddDeviceInterfaceGUID
|
||||
|
||||
[AddDeviceInterfaceGUID]
|
||||
HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%
|
||||
|
||||
[USB_Install.CoInstallers]
|
||||
AddReg = CoInstallers_AddReg
|
||||
CopyFiles = CoInstallers_CopyFiles
|
||||
|
||||
[CoInstallers_AddReg]
|
||||
HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01011.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"
|
||||
|
||||
[CoInstallers_CopyFiles]
|
||||
WinUSBCoInstaller2.dll
|
||||
WdfCoInstaller01011.dll
|
||||
|
||||
[DestinationDirs]
|
||||
CoInstallers_CopyFiles = 11
|
||||
|
||||
[SourceDisksNames]
|
||||
1 = %SourceName%
|
||||
|
||||
[SourceDisksFiles.amd64]
|
||||
WinUSBCoInstaller2.dll = 1,amd64
|
||||
WdfCoInstaller01011.dll = 1,amd64
|
||||
Loading…
x
Reference in New Issue
Block a user