加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(89)

发布时间:2020-12-15 05:00:38 所属栏目:百科 来源:网络整理
导读:键盘驱动程序是一个最基本的驱动程序,通过学习这个简单而实用的驱动程序来了解 ReactOS 驱动程序的结构,驱动程序的运行流程。在前面的 I/O 管理器分析里,已经知道操作系统加载驱动程序的过程,也了解了驱动程序在系统里是以驱动程序对象来管理的,也就是

键盘驱动程序是一个最基本的驱动程序,通过学习这个简单而实用的驱动程序来了解ReactOS驱动程序的结构,驱动程序的运行流程。在前面的I/O管理器分析里,已经知道操作系统加载驱动程序的过程,也了解了驱动程序在系统里是以驱动程序对象来管理的,也就是通过DRIVER_OBJECT对象来表示一个驱动程序的。

键盘驱动程序是一个输入输出的设备,但在ReactOS驱动程序分类里,是分在输入设备类。这个驱动程序的源程序所在的目录是在reactos/drivers/input/i8042prt目录。在分析这个驱动程序,还是采用从程序运行过程来分析它的流程。那么驱动程序加载运行的入口点在那里呢?这是一个最先要解决的问题,其实每个驱动程序都固定有一个函数名称DriverEntry,因此操作系统加载驱动程序时,就会找到这个入口函数,然后就调这个函数,就可以把驱动程序和操作系统内核联系在一起了,就可以调用驱动程序相关的功能了。在内核的I/O管理器里是这样调用这个函数的,如下:

#148 DPRINT("Calling driver entrypoint at %p/n",InitializationFunction);

#149 Status = (*InitializationFunction)(DriverObject,RegistryPath);

通过内核的调用,就知道函数DriverEntry应具备两个参数,第一个参数是驱动程序对象,这是内核表示一个驱动程序的对象。第二个参数是驱动程序文件在注册表里的路径。因此,驱动程序入口函数,就写成下面这样:

#001 NTSTATUS NTAPI

#002 DriverEntry(

#003 IN PDRIVER_OBJECT DriverObject,

#004 IN PUNICODE_STRING RegistryPath)

#005 {

#006 PI8042_DRIVER_EXTENSION DriverExtension;

#007 ULONG i;

#008 NTSTATUS Status;

#009

#010 /* ROS Hack: ideally,we shouldn't have to initialize debug level this way,

#011 but since the only way is to change it via KDBG,it's better to leave

#012 it here too. */

#013 #if 0

#014 DbgSetDebugFilterState(

#015 DPFLTR_I8042PRT_ID,

#016 (1 << DPFLTR_ERROR_LEVEL) | (1 << DPFLTR_WARNING_LEVEL) |

#017 (1 << DPFLTR_TRACE_LEVEL) /*| (1 << DPFLTR_INFO_LEVEL)*/ | DPFLTR_MASK,

#018 TRUE);

#019 #endif

#020

#021

调用函数IoAllocateDriverObjectExtension来分配键盘驱动程序的对象内存,以便保存更多扩展的属性。

#022 Status = IoAllocateDriverObjectExtension(

#023 DriverObject,

#024 DriverObject,

#025 sizeof(I8042_DRIVER_EXTENSION),

#026 (PVOID*)&DriverExtension);

#027 if (!NT_SUCCESS(Status))

#028 {

#029 WARN_(I8042PRT,"IoAllocateDriverObjectExtension() failed with status 0x%08lx/n",Status);

#030 return Status;

#031 }

初始化扩展分区内存。

#032 RtlZeroMemory(DriverExtension,sizeof(I8042_DRIVER_EXTENSION));

初始化扩展的设备列表。

#033 KeInitializeSpinLock(&DriverExtension->Port.SpinLock);

#034 InitializeListHead(&DriverExtension->DeviceListHead);

#035 KeInitializeSpinLock(&DriverExtension->DeviceListLock);

#036

拷贝注册表路径。

#037 Status = DuplicateUnicodeString(

#038 RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE,

#039 RegistryPath,

#040 &DriverExtension->RegistryPath);

#041 if (!NT_SUCCESS(Status))

#042 {

#043 WARN_(I8042PRT,"DuplicateUnicodeString() failed with status 0x%08lx/n",Status);

#044 return Status;

#045 }

#046

从注册表里获取驱动程序的资源分配。

#047 Status = ReadRegistryEntries(RegistryPath,&DriverExtension->Port.Settings);

#048 if (!NT_SUCCESS(Status))

#049 {

#050 WARN_(I8042PRT,"ReadRegistryEntries() failed with status 0x%08lx/n",Status);

#051 return Status;

#052 }

#053

添加即插即用调用函数,以便创建这个驱动程序支持的设备。

#054 DriverObject->DriverExtension->AddDevice = i8042AddDevice;

指向驱动程序中处理串行I/O请求的函数,I/O管理器自动为驱动程序串行化多个I/O请求。

#055 DriverObject->DriverStartIo = i8042StartIo;

#056

缺省地初始化IRP消息为IrpStub函数处理。

#057 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)

#058 DriverObject->MajorFunction[i] = IrpStub;

#059

指定IRP消息IRP_MJ_CREATE的处理函数i8042Create

#060 DriverObject->MajorFunction[IRP_MJ_CREATE] = i8042Create;

清除分配资源的函数i8042Cleanup

#061 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = i8042Cleanup;

指定关闭设备时,调用的函数i8042Close

#062 DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close;

通过IO操作函数i8042DeviceControl

#063 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl;

指定中断处理函数i8042InternalDeviceControl

#064 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl;

指定即插即用时响应函数i8042Pnp

#065 DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp;

#066

判断驱动程序是否初始化安装时运行,如果是初始化时就调用函数i8042AddLegacyKeyboard处理。

#067 if (IsFirstStageSetup())

#068 return i8042AddLegacyKeyboard(DriverObject,RegistryPath);

#069

#070 return STATUS_SUCCESS;

#071}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读