赞
踩
拆开一台国产电脑,会发现,很多重要芯片,其实已经国产化了,CPU、GPU、电源管理芯片等等,刚做了一下GOP的笔记,回头想想,之前包入厂商的显卡驱动一直没怎么关注他们的运行逻辑是什么,那么,这篇文章就来探讨深入一下,这个显卡驱动是怎么做的
国产显卡,属于前列的当属景嘉微显卡,那么这次就来分析一下JM7200的驱动是怎么做的。
驱动总的分为两种,一种是符合驱动模型的,一种就是不符合的了,UEFI驱动模型的核心是通过EFI Driver Binding Protocol管理驱动程序。作为一个用户友好的驱动程序,通常它还包含一个EFI Component Name Protocol,在UEFI驱动的入口函数,安装EFI Driver Binding Protocol的位置通常为自身的Handle,这个实例会常驻内存,用于驱动的安装与卸载。直接贴代码是违反保密协议的,所以就用USB的驱动代码来解释了。
UEFI 会调用 gBS->Startimage(..)执行 Driverimage的入口函数,在入口函数里,Driver Binding Protocol被加载到 Handle 上(Driver Imagehandle 或者其他的 Controller Handle),然后 UEFI 会遍历所有的控制器,为每个控制器调用 CoreConnectSingleController 函数,在CoreConnectSingleController 中会调用EDBP的Supported 函数测试这个驱动是否支持该控制器,如果支持,则调用 Start( )安装驱动。
通常每个驱动都还有一个可打印的名字,便于向用户显示驱动的信息。这个可打印名字是由 EFI Component Name Protocol(ECNP)或 EFI Component Name2 Protocol(ECN2P)提供的。ECNP 和 ECN2P 不是驱动必需的 Protocol,但建议驱动开发者提供这个 Protocol
- EFI_STATUS
- EFIAPI
- UsbBusDriverEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
-
- Status = EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &mUsbBusDriverBinding,
- ImageHandle,
- &mUsbBusComponentName,
- &mUsbBusComponentName2
- );
- }
- ASSERT_EFI_ERROR (Status);
-
- Status = gBS->InstallMultipleProtocolInterfaces (
- &ImageHandle,
- &gEfixxxxxGuid,
- &xxxxxxx,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
- }

上面的代码就是入口函数的基本操作流程,安装EDBP以及ECNP,然后还会安装所需的protocol,比如显卡驱动自己的protocol。
EDBP有三个函数,咱们就开始进入VideoControllerDriverSupported,对于显卡,它是一个PCI设备,这里就需要用到PciIoProtocol,咱们打开这个protocol,然后获取这个PCI设备的VID与DID,是否符合,如果符合,则开始实现Start服务。
- //
- // Open the PCI I/O Protocol
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- if (EFI_ERROR (Status))
- {
- return Status;
- }
- //
- // Read the PCI Configuration Header from the PCI Device
- //
- Status = PciIo->Pci.Read ( PciIo, EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci );
-
-
- Pci.Hdr.VendorId==?
- Pci.Hdr.DeviceId==?

进入Start服务后,一般先进行显卡专有的数据设置与获取,然后就是构建video模块缓冲区了,其实就是设置video的一些相关数据
- VideoMode = &JM5400VideoVideoModes[0];
- for (Index = 0; Index < JM5400_VIDEO_MODE_COUNT; Index ++)
- {
- ModeData->ModeNumber = Index;
- ModeData->HorizontalResolution = VideoMode->Width;
- ModeData->VerticalResolution = VideoMode->Height;
- ModeData->ColorDepth = VideoMode->ColorDepth;
- ModeData->RefreshRate = VideoMode->RefreshRate;
- DEBUG ((EFI_D_INFO, "Adding Video Mode %d: %dx%d, %d-bit, %d Hz\n",
- ModeData->ModeNumber,
- ModeData->HorizontalResolution,
- ModeData->VerticalResolution,
- ModeData->ColorDepth,
- ModeData->RefreshRate
- ));
- 。。。。。。。

现在数据什么的都有且已经准备好了,那么当然就是图像的构造啦:
- GraphicsOutput = &Private->GraphicsOutput;
- GraphicsOutput->QueryMode = JM5400VideoGraphicsOutputQueryMode;
- GraphicsOutput->SetMode = JM5400VideoGraphicsOutputSetMode;
- GraphicsOutput->Blt = JM5400VideoGraphicsOutputBlt;
- .......
具体内容怎么构造的,这就是核心内容,当然,这一节只是熟悉一下显卡驱动是怎么做的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。