bdd.cxx/.h
bdd_ddi.cxx
bdd_util.cxx
BltFuncs.cxx
memory.cxx
都已经分析过了, 而bdd_dmm.cxx就是被bdd_ddi.cxx调用关于VidPN的相关函数.
剩下就blthw.cxx没有分析了.
写了这5篇内容, 也只是对KMDOD的内容有了一点皮毛上的了解与理解.
目前还有好多问题,没有得到解决:
Q1. VidPN代码怎么和具体的硬件相结合, 即根据不同显卡的硬件参数配置, 来相应地改变代码中的VidPN的代码?
Q2. Frame buffer的指针是从POST设备中取得的, 那么这个POST设备是指哪一个具体设备?
A2: 我的理解是, KMDOD驱动从 (UEFI or BIOS)中接管了显卡设备, 这个设备在UEFI, BIOS管理时, 被KMDOD接管前的时候, 就叫作POST显卡设备, 不知道理解的是否正确?
Q3. Frame buffer是由谁来"画"的?
首先, frame buffer如果在有独显的情况下, 是显卡上的一块显存, 如果是集显的情况下,就是系统中的一块内存
第二, 系统中有多少显卡,就有多少块FRAME BUFFER, 他们之间是独立的, 在某些情况下(每块显卡负责显示桌面的某一部分), 显存中的内容也是不同的(桌面中的某一部分).
所以, 任何一块FRAME BUFFER, 是在GPU接受到系统的drawing command后, 在它自己的FRAME BUFFER中"画"的.
对于KMDOD的的FRAME BUFFER, 与上面的FRAME BUFFER相同性质.
Q4. USB设备,能否安装KMDOD驱动?
比如说, 在DxgkDdiQueryDeviceDescriptor加入一个DESCRIPTOR, 表示一个显示器的EDID, 但不清楚,这样的方法, 能够对USB设备起作用吗?
因为别人的应用场景是:
把KMDOD的sample改造一下,使这个driver挂一个虚拟的display,这样OS以为有两个monitor(包括一个硬件monitor)
KMDOD针对于有系统资源的PCI/PCIE显卡, 特别是它们带有显存(可以映射到系统), FRAME BUFFER, 但USB设备肯定是没有显存的(在设备上有的内存, 作为EP的BUFFER, 但并不能映射到系统), 同样,也没有中断, DMA, PORT, 等相应资源.
OSR上有人说, KMDOD只针对有系统资源的设备, 那么对于USB这类,是不能安装了?
特别是, 在START DEVICE中调用:
DxgkCbAcquirePostDisplayOwnership, 从POST设备取得FRAME BUFFER, 是不是这一步肯定不能成功?
能不能将这个KMDOD驱动:
1. 通过某种方法, 绕开以上对KMDOD驱动的要求, 安装到USB设备上
2. 从别的显卡的FRAME BUFFER中取得RENDER内容, 然后通过USB给设备?
说一下,这个CXX文件中的内容:
DxgkDdiPresentDisplayOnly最终调用的是类的成员函数BDD_HWBLT::ExecutePresentDisplayOnly
例子给出了同步与异步的两种方式的交替.
1. 所谓的同步,就是在系统调用期间,把该做的事情做完了, 即直接调用了HwExecutePresentDisplayOnly
2. 所谓的异步,就是在一个线程HwContextWorkerThread(启一个线程 在函数中StartHwBltPresentWorkerThread)中去做相同的事情, HwExecutePresentDisplayOnly, 做完后, 还通过ReportPresentProgress,给系统回馈一个完成的情况(SynchronizeVidSchNotifyInterrupt), 事后,还排了一个DPC, 我不明白, 这个DPC在例子中又做了些什么事情.
其中,StartHwBltPresentWorkerThread在建立一个线程后,需要等待, 线程函数HwContextWorkerThread来设置m_hThreadStartupEvent, 当这个EVENT被设置后,就说明线程已经跑起来了, 于是StartHwBltPresentWorkerThread调用, SetPresentWorkerThreadInfo设置当前线程的信息.
而HwContextWorkerThread在设置完m_hThreadStartupEvent后, 就在等待m_hThreadSuspendEvent被设置,
StartHwBltPresentWorkerThread设置了m_hThreadSuspendEvent后, HwContextWorkerThread就可以继续执行HwExecutePresentDisplayOnly了.
简单地讲, 这两个EVENT是作为StartHwBltPresentWorkerThread与HwContextWorkerThread同步而用
一个用来等待线程真正已经跑起来, 可以设置线程信息
另一个用来等待线程信息已经设置完, 可以继续执行真正的DisplayOnly的工作.
具体的的不多讲了, 但要明白的一点, DisplayOnly中的工作,就是将SRC COPY到DEST中.
SRC是从PresentDisplayOnly的参数得到的, 这个应该就是系统的SURFACE信息(不知道是否准确), 包括了"画"好的内容
DST就是FRAME BUFFER, 而这个FRAME BUFFER就是在DxgkCbAcquirePostDisplayOwnership得到的.