Because Windows shields the underlying system operations, the system becomes safer for users, but it brings great difficulties to many hardware or system software developers, as long as the application involves underlying operations, developers have to go deep into the Windows kernel to write system-level virtual device drivers.
WIN98 and Win95 device drivers have different mechanisms. Win98 not only supports WDM (Win32 driver mode) Drivers compatible with Windows NT 5.0, it also supports Virtual Device Driver (VxD) compatible with Win95 ). The following describes the basic principle and design method of virtual environment and Virtual Device Driver VxD based on Windows 9X, combined with the development tool VtoolsD, a virtual device driver VxD is designed for the video phone audio card.
1. Windows 9x Virtual Environment
Windows 9x is a complete 32-bit multitasking operating system, unlike Windows 3. X depends on the MS-DOS, but to ensure software compatibility, Windows 9x also supports the running of MS-DOS applications in addition to Win16 and Win32 applications. Windows 9x ensures compatibility and multi-task features through Virtual Machine (VM) environments.
The so-called windows Virtual Machine (Windows VM) is the virtual environment that executes the application, it includes MS-DOS Vm and system VM Virtual Machine environment. Only one MS-DOS process is running in each MS-DOS Vm, and system VM provides a runtime environment for all Windows applications and Dynamic Linked Library DLL (dynamic link libraries. Each virtual machine has an independent address space, register status, stack, Local Descriptor Table, interrupt table status, and execution priority. Although Win16 and Win32 applications run in the system VM environment, Win16 applications share the same address space, while Win32 applications have their own address space.
When writing an application, programmers often ignore the differences between the virtual environment and the real environment. Generally, they think that the virtual environment is the real environment. However, this cannot be done when writing the Virtual Device Driver VxD, because the VxD works to provide an environment for the application code to interface with the hardware, manages the status of Virtual Devices for each virtual machine of a customer, transparently arbitrates multiple applications, and simultaneously accesses the underlying hardware. This is the so-called concept of virtualization.
VxD runs under the monitoring of Virtual Machine Manager (vmm), while vmm is actually a special VxD. Vmm performs work related to system resources, provides virtual machine environments (which can generate, schedule, and detach VMS), schedules multiple threads to take the first time slice, and manages virtual memory. VxD and vmm run on any other virtual machine. VxD is actually part of the software that implements the virtual machine.
Like a large operating system, Windows also adopts a hierarchical architecture. Vmm and vxds constitute the ring0 system core of Win 95 (applications run at ring3 and ring1 and ring2 are not used), which has the highest priority of the system. Windows also provides drivers with the suffix "DRV", mainly the communication program of the serial port and the printer program of the parallel port. Different from VxD, these programs run on ring3. Figure 1 helps you better understand the Windows virtual environment.
2. in-depth understanding of vmm and VxD
As mentioned above, VxD is short for virtual device driver, but someone regards it as virtual any driver. In fact, VxD is not just a device driver that virtualizes a specific hardware. For example, some VxD can virtualize the device, while some VxD as the device driver does not virtualize the device, and some VxD has nothing to do with the device, it only provides services to other VxD or applications.
VxD can be statically loaded along with vmm, or Dynamically Loaded or detached as needed. It is precisely because of the close collaboration between VxD and vmm that VxD has the capabilities that applications do not possess, for example, you can access hardware devices without restrictions and view the operating system data structure (such as Descriptor Table and page table) at will), access to any memory area, capture software interruption, capture I/O port operations and memory access, and even intercept hardware interruption.
Although VxD uses the flat memory model, its code and data are still managed in segments in six ways, that is, the real Mode Initialization, Protection Mode Initialization, paging, non-Paging, static, and debug only (debug only). Each type has a code segment and a data segment, so there are 12 VxD segments. The real-mode code segment and data segment are 16 bits (segment mode), while the other segments are 32 bits (plane mode ). The "real-Mode Initialization" section contains the code to be executed before the vmm becomes protected during the initial phase of the Windows initialization process. Static Loading VxD now allows you to view the real-mode environment before Windows starts, decide whether to continue loading, and notify vmm. After loading, the vmm enters the protection mode and executes the Protection Mode Initialization code. The execution result is also sent to the vmm. After initialization, the "instance Mode Initialization" and "Protection Mode Initialization" segments are discarded. Most of the VxD code is stored in another section. The paging section allows the virtual storage manager to perform paging management, most VxD code should be in the paging section. The "non-Paging" section mainly includes the main entry point of VxD, hardware interrupt processing function, accessed data, and asynchronous service that can be called by another VxD interrupt processing function. Static segments are only used for VxD that can be dynamically loaded. After VxD is detached, both static segments and data segments are stored in the memory. The "Debug only" section is loaded only when vmm is in a soft-ice For Win 95 debugging environment.
Vmm is identified by the device descriptor block DDB (device descriptor block) of VxD. DDB provides vmm with the primary entry point of VxD and the entry point of applications and other VxD. Vmm uses this primary portal to notify VxD of the VM and Windows status, and then VxD responds to these events through corresponding work. Because VxD serves not only one physical device (such as multiple serial ports) or only one Vm, VxD needs to generate its own supported data structure (supporting data structures) to save the configuration and status information of each device and VM. VxD uses one or more device context structures to store device information, such as the I/O port base address and interrupt vector, vxD saves the status information of each VM in the VM control block of vmm.
Vmm provides the following services: event Service, memory management service, compatible execution and protection mode execution service, login table service, Scheduler Service, synchronization service, debugging service, I/O capture service, handling errors and interruptions service, Vm interrupt and callback service, configuration management program service, and other miscellaneous services.
The above content only involves a small part of the VxD design. As a VxD developer, more knowledge is required. First, knowledge about operating systems, such as address space, execution context, resource locking, inter-process communication, and asynchronous event processing. Second, we should have a deep understanding of Intel processors, includes registers, machine instruction sets, protection mechanisms, paging mechanisms, and virtual 8086 modes. Finally, you must be familiar with various services and interfaces provided by vmm and other Windows systems.
3. Introduction to the development tool VtoolsD
VtoolsD is a tool software specially used to develop VxD programs, it includes VxD framework code generator quickvxd, C Runtime Library, vmm/VxD service library, VxD C ++ class library, vxdload, vxdview and other practical tools as well as a large number of C, C ++ routines. VxD programs compiled by 32-bit compilers of VC ++ and BC ++ can be run in a VtoolsD environment.
Quickvxd can be used to generate the VxD framework conveniently and quickly, that is, to generate three files with the suffix H, CPP, and Mak. The source file contains the basic components for running VxD, including the function framework for controlling message processing, API entry points, and VxD services. It also defines the flag and sets the compilation parameters, declare the class, add your own code to the generated handler bodies in the C ++ environment, and finally use the compiler nmake to generate a standard VxD program.
As VxD runs at ring0, debugging is quite difficult. The debugging tool I used is soft-ice For Win 95.
The latest version of VtoolsD is 3.0. It supports the Device Access architecture DAA (Device Access architecture ), the compiled program code can be shared on all Windows platforms (including Windows 95, Windows 98, and Windows NT. Of course, you can also use the DDK (device developer kit) of Microsoft to develop VxD, however, DDK cannot provide a wide range of C Runtime libraries and C ++ class libraries by shielding the underlying technical details of the system and VxD like VtoolsD, instead, developers can fully enjoy the convenience and efficiency of object-oriented programming methods. Therefore, it is inconvenient to use DDK.
4. VxD Program Design Example
In the design process of developing a video phone audio card, I used VtoolsD 2.03 and VC ++ 5.0 to develop a Virtual Device Driver audcard. VxD for the self-made PC/XT bus expansion card. The card is interrupted every 20 ms. The application dynamically loads the audcard. VxD response of the system and processes the interruption. After the interrupt service program ISR (interrupt service routine) ends, call the shell_postmessage () function to send a custom message to the application window. After the application receives the message, it transmits the buffer data through the onw32deviceiocontrol () interface between the deviceiocontrol () function and the VxD function. After the program ends, the VxD can be dynamically uninstalled. Indicates the process of handling hardware interruptions by VxD under Win 95.
Handling of hardware interruptions in Win95
When an interruption occurs, the processor switches to ring0 protection mode. In Windows, the Interrupt Descriptor Table IDT (Interrupt Descriptor Table) does not direct to the interrupt processing process as DoS does. Instead, the IDT entry points to the program in vmm. The program will determine whether the call is interrupted. If yes, it will hand over the interrupt control to the Virtual Programmable Interrupt Controller vpicd (Virtual Programmable Interrupt Controller Device). vpicd is actually an important VxD. The vpicd then delivers it to another VxD that has registered the interrupt (such as audcard. VxD) for processing. The VxD program registers for interruption by calling the vpicd service vpicd_virtualize_irq.
Part of the source code audcard. h and audcard. cpp of the Virtual Device Driver audcard. VxD are online at www.pccomputing.com.cn. This application uses the following functions: createfile () dynamically loads VxD, closehandle (), and dynamically detaches VxD, pretranslatemessage () to intercept messages, deviceiocontrol () and Vxd to transmit buffer data. The Virtual Device Driver audcard. VxD works normally after debugging. No data loss or crashes have occurred.
The following are part of the source code audcard. h and audcard. cpp of the Virtual Device Driver audcard. VxD, which are not listed by audcard. Mak automatically generated by quickvxd.
① Audcard. h
// Audcard. H-include file for VxD audcard # Include # Define device_class audcarddevice # Define audcard_deviceid undefined_device_id # Define audcard_init_order undefined_init_order # define audcard_major # Define audcard_minor 0 # Define my_irq 5 // define the interrupt number 5 Class myhwint: Public vhardwareint { Public: Myhwint (): vhardwareint (my_irq, 0, 0 ){} Virtual void onhardwareint (vmhandle ); }; Class audcarddevice: Public vdevice { Public: Virtual bool onsysdynamicdeviceinit (); Virtual bool onsysdynamicdeviceexit (); Virtual DWORD onw32deviceiocontrol (pioctlparams pdiocparams ); Myhwint * pmyirq; };Class audcardvm: Public vvirtualmachine { Public: Audcardvm (vmhandle hvm ); }; Class audcardthread: Public vthread { Public: Audcardthread (threadhandle hthread ); }; |
② Audcard. cpp
// Audcard. cpp-Main module for VxD audcard # Define device_main # Include "audcard. H" Declare_virtual_device (audcard) # Define wm_user_postvxd 0x1000 // custom message # UNDEF device_main Audcardvm: audcardvm (vmhandle hvm): vvirtualmachine (hvm ){} Audcardthread: audcardthread (threadhandle hthread): vthread (hthread ){} Bool audcarddevice: onsysdynamicdeviceinit () // initialization during dynamic loading { ... // Hardware initializationPmyirq = new myhwint (); If (pmyirq & pmyirq-$ # @ 62; hook () // hook interruption { Pmyirq-$ # @ 62; physicalunmask (); // interrupt allowed Return true; } Else return false; } Bool audcarddevice: onsysdynamicdeviceexit () // Dynamic uninstall process { Delete pmyirq; Return true; } DWORD audcarddevice: onw32deviceiocontrol (pioctlparams pdiocparams) // Interface functions with Win32 applications { ...... } Void myhwint: onhardwareint (vmhandle hvm) { ... // Interrupt handling Shell_postmessage (appwnd, wm_user_postvxd, 0, 0, null ); // Send a message to the application window Sendphysicaleoi (); // notification that the vpicd interruption ends } |