当前位置:   article > 正文

UEFI原理与编程实践--UEFI驱动模型之显卡(UEFI方向)驱动分析_uefi 显卡驱动

uefi 显卡驱动

拆开一台国产电脑,会发现,很多重要芯片,其实已经国产化了,CPU、GPU、电源管理芯片等等,刚做了一下GOP的笔记,回头想想,之前包入厂商的显卡驱动一直没怎么关注他们的运行逻辑是什么,那么,这篇文章就来探讨深入一下,这个显卡驱动是怎么做的

国产显卡,属于前列的当属景嘉微显卡,那么这次就来分析一下JM7200的驱动是怎么做的。

UEFI驱动模型

驱动总的分为两种,一种是符合驱动模型的,一种就是不符合的了,UEFI驱动模型的核心是通过EFI Driver Binding Protocol管理驱动程序。作为一个用户友好的驱动程序,通常它还包含一个EFI Component Name Protocol,在UEFI驱动的入口函数,安装EFI Driver Binding Protocol的位置通常为自身的Handle,这个实例会常驻内存,用于驱动的安装与卸载。直接贴代码是违反保密协议的,所以就用USB的驱动代码来解释了。

UEFI驱动加载过程

UEFI 会调用 gBS->Startimage(..)执行 Driverimage的入口函数,在入口函数里,Driver Binding Protocol被加载到 Handle 上(Driver Imagehandle 或者其他的 Controller Handle),然后 UEFI 会遍历所有的控制器,为每个控制器调用 CoreConnectSingleController 函数,在CoreConnectSingleController 中会调用EDBP的Supported 函数测试这个驱动是否支持该控制器,如果支持,则调用 Start( )安装驱动。

EFI Component Name Protocol 的作用和构成

通常每个驱动都还有一个可打印的名字,便于向用户显示驱动的信息。这个可打印名字是由 EFI Component Name Protocol(ECNP)或 EFI Component Name2 Protocol(ECN2P)提供的。ECNP 和 ECN2P 不是驱动必需的 Protocol,但建议驱动开发者提供这个 Protocol

  1. EFI_STATUS
  2. EFIAPI
  3. UsbBusDriverEntryPoint (
  4. IN EFI_HANDLE ImageHandle,
  5. IN EFI_SYSTEM_TABLE *SystemTable
  6. )
  7. {
  8. EFI_STATUS Status;
  9. Status = EfiLibInstallDriverBindingComponentName2 (
  10. ImageHandle,
  11. SystemTable,
  12. &mUsbBusDriverBinding,
  13. ImageHandle,
  14. &mUsbBusComponentName,
  15. &mUsbBusComponentName2
  16. );
  17. }
  18. ASSERT_EFI_ERROR (Status);
  19. Status = gBS->InstallMultipleProtocolInterfaces (
  20. &ImageHandle,
  21. &gEfixxxxxGuid,
  22. &xxxxxxx,
  23. NULL
  24. );
  25. ASSERT_EFI_ERROR (Status);
  26. return Status;
  27. }

上面的代码就是入口函数的基本操作流程,安装EDBP以及ECNP,然后还会安装所需的protocol,比如显卡驱动自己的protocol。

EDBP有三个函数,咱们就开始进入VideoControllerDriverSupported,对于显卡,它是一个PCI设备,这里就需要用到PciIoProtocol,咱们打开这个protocol,然后获取这个PCI设备的VID与DID,是否符合,如果符合,则开始实现Start服务。

  1. //
  2. // Open the PCI I/O Protocol
  3. //
  4. Status = gBS->OpenProtocol (
  5. Controller,
  6. &gEfiPciIoProtocolGuid,
  7. (VOID **) &PciIo,
  8. This->DriverBindingHandle,
  9. Controller,
  10. EFI_OPEN_PROTOCOL_BY_DRIVER
  11. );
  12. if (EFI_ERROR (Status))
  13. {
  14. return Status;
  15. }
  16. //
  17. // Read the PCI Configuration Header from the PCI Device
  18. //
  19. Status = PciIo->Pci.Read ( PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci );
  20. Pci.Hdr.VendorId==
  21. Pci.Hdr.DeviceId==

进入Start服务后,一般先进行显卡专有的数据设置与获取,然后就是构建video模块缓冲区了,其实就是设置video的一些相关数据

  1. VideoMode = &JM5400VideoVideoModes[0];
  2. for (Index = 0; Index < JM5400_VIDEO_MODE_COUNT; Index ++)
  3. {
  4. ModeData->ModeNumber = Index;
  5. ModeData->HorizontalResolution = VideoMode->Width;
  6. ModeData->VerticalResolution = VideoMode->Height;
  7. ModeData->ColorDepth = VideoMode->ColorDepth;
  8. ModeData->RefreshRate = VideoMode->RefreshRate;
  9. DEBUG ((EFI_D_INFO, "Adding Video Mode %d: %dx%d, %d-bit, %d Hz\n",
  10. ModeData->ModeNumber,
  11. ModeData->HorizontalResolution,
  12. ModeData->VerticalResolution,
  13. ModeData->ColorDepth,
  14. ModeData->RefreshRate
  15. ));
  16. 。。。。。。。

现在数据什么的都有且已经准备好了,那么当然就是图像的构造啦:

  1. GraphicsOutput = &Private->GraphicsOutput;
  2. GraphicsOutput->QueryMode = JM5400VideoGraphicsOutputQueryMode;
  3. GraphicsOutput->SetMode = JM5400VideoGraphicsOutputSetMode;
  4. GraphicsOutput->Blt = JM5400VideoGraphicsOutputBlt;
  5. .......

具体内容怎么构造的,这就是核心内容,当然,这一节只是熟悉一下显卡驱动是怎么做的

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/753973
推荐阅读
相关标签
  

闽ICP备14008679号