В настоящее время я экспериментирую с Apple I / O Kit для разработки модуля ядра. Я пытаюсь создать драйвер устройства для беспроводной карты USB (TP-Link WN722N-v1) с помощью IOUSBHostDevice. Мне удалось загрузить kext, и он корректно прощупывает карту, но мне нужно отправить прошивку на карту, что я пытаюсь сделать в probe (). Я не обладаю достаточными знаниями о том, как все происходит, но мне кажется, что мне нужно отправить запрос в конечную точку конфигурации 0, но способы, которые я пробовал, получают ядро pani c, и другие примеры, которые у меня есть, использование устаревшего DeviceRequest без обмена аргументами с новым deviceRequest. У меня есть ссылка для написания прошивки из проекта github "BrcmPatchRAM", но все вилки используют старый IOUSBInterface вместо IOUSBHostInterface. Я искал на этом сайте похожие вопросы, но не нашел ничего полезного в этом вопросе, я также искал документацию веб-сайта разработчика Apple, и она ссылается также на старые способы DeviceRequest. Какой правильный способ переписать это, например:
IOReturn USBInterfaceShim::hciCommand(void* command, UInt16 length)
{
IOUSBDevRequest request =
{
.bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBDevice),
.bRequest = 0,
.wValue = 0,
.wIndex = 0,
.wLength = length,
.pData = command
};
return m_pInterface->DeviceRequest(&request);
}
Использование некоторой другой реализации этой функции выдает ошибку при загрузке драйвера и говорит, что я отправляю запрос перед вызовом prepare, но я позвонил подготовить перед отправкой запроса.
Вот часть моего грязного кода:
<code><pre>IOReturn AirPort_Atheros9271::pipeCommand(UInt8 requestType, UInt8 command, UInt16 address, IOMemoryDescriptor *buffer)
{
DeviceRequest request;
request.bmRequestType = requestType;
request.bRequest = command;
request.wValue = address;
request.wIndex = 0;
request.wLength = buffer->getLength();
uint32_t bytesTransferred;
return fInterface->deviceRequest(request, buffer, bytesTransferred, kUSBHostStandardRequestCompletionTimeout);
}
IOReturn AirPort_Atheros9271::pipeCommand(UInt8 requestType, UInt8 command, UInt16 address, void *buffer, UInt16 length)
{
DeviceRequest request;
request.bmRequestType = requestType;
request.bRequest = command;
request.wValue = address;
request.wIndex = 0;
request.wLength = length;
uint32_t bytesTransferred;
return fInterface->deviceRequest(request, buffer, bytesTransferred, kUSBHostStandardRequestCompletionTimeout);
}
bool TL_WN722N::performUpgrade()
{
IOLog("TL_WN722N::[%04x:%04x]: Performing firmware upgrade.\n", fVendorId, fProductId);
OSData *firmwareData = OSData::withBytes(ar9271_fw, ar9271_fw_len);
IOMemoryDescriptor *buffer = IOMemoryDescriptor::withAddress((void*)firmwareData->getBytesNoCopy(), firmwareData->getLength(), kIODirectionIn);
bool success = true;
IOLog("TL_WN722N::[%04x:%04x]: I have firmwareData and created the buffer\n", fVendorId, fProductId);
IOLockLock(fCompletionLock);
IOReturn result;
if (buffer!=NULL)
{
IOLog("TL_WN722N::[%04x:%04x]: Buffer is not null, now calling prepare()\n", fVendorId, fProductId);
if ((result = buffer->prepare(kIODirectionNone)) == kIOReturnSuccess)
{
IOLog("TL_WN722N::[%04x:%04x]: prepare() called and pass! Piping I - writing firmware\n", fVendorId, fProductId);
IOLog("TL_WN722N::[%04x:%04x]: Resultado de prepare: Result: %d\n", fVendorId, fProductId,result);
IOLog("TL_WN722N::[%04x:%04x]: About to excecute pipeCommand\n", fVendorId, fProductId);
result = pipeCommand(0x40, FIRMWARE_DOWNLOAD, AR9271_FIRMWARE >> 8, buffer); //TODO: EXPLOTION LINE
if (result>0) {
IOLog("TL_WN722N::[%04x:%04x]: Resultado de pipeCommand: %d\n", fVendorId, fProductId,result);
}
if (result != kIOReturnSuccess)
IOLog("TL_WN722N::[%04x:%04x]: Unable to write the firmware (0x%08x).\n", fVendorId, fProductId, result);
else
{
if ((result = pipeCommand(0x40, FIRMWARE_DOWNLOAD_COMP, AR9271_FIRMWARE_TEXT >> 8, NULL, 0)) != kIOReturnSuccess)
IOLog("TL_WN722N::[%04x:%04x]: Unable to write the firmware complete sequence (0x%08x).\n", fVendorId, fProductId, result);
else
{
IOLog("TL_WN722N::[%04x:%04x]: Success in writing the firmware sequence.\n", fVendorId, fProductId);
success = true;
}
}
}
else
IOLog("TL_WN722N::[%04x:%04x]: Failed to prepare write memory buffer (0x%08x).\n", fVendorId, fProductId, result);
if ((result = buffer->complete()) != kIOReturnSuccess)
IOLog("TL_WN722N::[%04x:%04x]: Failed to complete write memory buffer (0x%08x).\n", fVendorId, fProductId, result);
}
else
IOLog("TL_WN722N::[%04x:%04x]: Unable to allocate write memory buffer.\n", fVendorId, fProductId);
IOLockUnlock(fCompletionLock);
OSSafeReleaseNULL(buffer);
OSSafeReleaseNULL(firmwareData);
return success;
}