驅動基本框架

2021-07-10 02:09:00 字數 4978 閱讀 4558

#include "ring0.h"

//驅動在解除安裝的時候,經過這裡,我們可以在這裡釋放一些資源。

//斷開通話

void driverunload(pdriver_object driverobject)

//函式派遣的irp,如果我們不需要用到這裡通訊。

ntstatus iodispatch(pdevice_object deviceobject, pirp irp)

//其實就是win32dll裡面的入口

//bool winapi dllmain(hinstdll,fdwreason,lpvreserved);

//driver_object其實是乙個結構體

/*lkd> dt_driver_object

nt!_driver_object

+0x000 type : int2b

+0x002 size : int2b

+0x004 deviceobject : ptr32 _device_object

+0x008 flags : uint4b

+0x00c driverstart : ptr32 void //就是驅動在記憶體中的開始位址,也可以把它當成是乙個pe檔案的頭開始

+0x010 driversize : uint4b //驅動的大小

+0x014 driversection : ptr32 void

+0x018 driverextension : ptr32 _driver_extension

+0x01c drivername : _unicode_string

+0x024 hardwaredatabase : ptr32 _unicode_string

+0x028 fastiodispatch : ptr32 _fast_io_dispatch

+0x02c driverinit : ptr32 long

+0x030 driverstartio : ptr32 void

+0x034 driverunload : ptr32 void //驅動的解除安裝例程

+0x038 majorfunction : [28] ptr32 long

lkd> dt_unicode_string

nt!_unicode_string

+0x000 length : uint2b //這個是文字的長度

+0x002 maximumlength : uint2b //最大長度

+0x004 buffer : ptr32 uint2b //這個是文字的內容 unicode

*/ntstatus driverentry(pdriver_object driverobject,punicode_string theregistrypath)

//同樣我們也需要乙個符號鏈結,不然會影響到驅動和應用層的通訊

//我們還需要乙個移動卡

status = iocreatesymboliclink(&dosdevicename,&devicename);

if( !nt_success(status))

//驅動通訊例程

//這是驅動的解除安裝例程,類似於dll裡面的dll_process_detach,要解除安裝這個驅動,就要設定解除安裝例程

driverobject->driverunload = driverunload;

//irp_mj_create,響應的是應用層函式createfile,應用層呼叫這個函式就會進入這個例程

driverobject->majorfunction[irp_mj_create] = iodispatch; //createfile();#include "ring0.h"

//驅動在解除安裝的時候,經過這裡,我們可以在這裡釋放一些資源。

//斷開通話

void driverunload(pdriver_object driverobject)

//函式派遣的irp,如果我們不需要用到這裡通訊。

ntstatus iodispatch(pdevice_object deviceobject, pirp irp)

//其實就是win32dll裡面的入口

//bool winapi dllmain(hinstdll,fdwreason,lpvreserved);

//driver_object其實是乙個結構體

/*lkd> dt_driver_object

nt!_driver_object

+0x000 type : int2b

+0x002 size : int2b

+0x004 deviceobject : ptr32 _device_object

+0x008 flags : uint4b

+0x00c driverstart : ptr32 void //就是驅動在記憶體中的開始位址,也可以把它當成是乙個pe檔案的頭開始

+0x010 driversize : uint4b //驅動的大小

+0x014 driversection : ptr32 void

+0x018 driverextension : ptr32 _driver_extension

+0x01c drivername : _unicode_string

+0x024 hardwaredatabase : ptr32 _unicode_string

+0x028 fastiodispatch : ptr32 _fast_io_dispatch

+0x02c driverinit : ptr32 long

+0x030 driverstartio : ptr32 void

+0x034 driverunload : ptr32 void //驅動的解除安裝例程

+0x038 majorfunction : [28] ptr32 long

lkd> dt_unicode_string

nt!_unicode_string

+0x000 length : uint2b //這個是文字的長度

+0x002 maximumlength : uint2b //最大長度

+0x004 buffer : ptr32 uint2b //這個是文字的內容 unicode

*/ntstatus driverentry(pdriver_object driverobject,punicode_string theregistrypath)

//同樣我們也需要乙個符號鏈結,不然會影響到驅動和應用層的通訊

//我們還需要乙個移動卡

status = iocreatesymboliclink(&dosdevicename,&devicename);

if( !nt_success(status))

//驅動通訊例程

//這是驅動的解除安裝例程,類似於dll裡面的dll_process_detach,要解除安裝這個驅動,就要設定解除安裝例程

driverobject->driverunload = driverunload;

//irp_mj_create,響應的是應用層函式createfile,應用層呼叫這個函式就會進入這個例程

driverobject->majorfunction[irp_mj_create] = iodispatch; //createfile();

//下面的分別對應closehandle readfile writefile

driverobject->majorfunction[irp_mj_close] = iodispatch; //closehandle() //你可以把這些想象成是不同的**號碼

driverobject->majorfunction[irp_mj_read] = iodispatch; //readfile()

driverobject->majorfunction[irp_mj_write] = iodispatch; //writefile()

//一般我們跟應用層通訊,都是通過irp_mj_device_control例程,這個例程對應的是應用層下的deviceiocontrol

driverobject->majorfunction[irp_mj_device_control] = iodispatch; //deviceiocontrol()

//像所有入門程式一樣,我們可以列印出hello world證明我們的驅動載入成功

dbgprint("hello world\r\n");

return status_success;

}

//下面的分別對應closehandle readfile writefiledriverobject->majorfunction[irp_mj_close] = iodispatch; //closehandle() //你可以把這些想象成是不同的**號碼driverobject->majorfunction[irp_mj_read] = iodispatch; //readfile()driverobject->majorfunction[irp_mj_write] = iodispatch; //writefile()//一般我們跟應用層通訊,都是通過irp_mj_device_control例程,這個例程對應的是應用層下的deviceiocontroldriverobject->majorfunction[irp_mj_device_control] = iodispatch; //deviceiocontrol()//像所有入門程式一樣,我們可以列印出hello world證明我們的驅動載入成功dbgprint("hello world\r\n");return status_success;}

Linux 字元裝置驅動基本框架(二)

一 位址對映 我們知道 stm32 無法跑 linux 系統,是由於它內部沒有 mmu 記憶體管理單元 mmu 主要完成的功能如下 1 完成虛擬空間到物理空間的對映。2 記憶體保護,設定儲存器的訪問許可權,設定虛擬儲存空間的緩衝特性。linux 核心啟動的時候會初始化 mmu,設定好記憶體對映,設定...

Linux 字元裝置驅動基本框架(三)

前面的字元裝置驅動框架有缺點,如 1 register chrdev 函式只能指定主裝置號,無法指定次裝置號,會將乙個主裝置號下的所有次裝置號都使用掉。2 不能自動分配裝置號,需要在程式中利用巨集定義指定裝置號。2 不能自動建立裝置節點,需要手動 mknod dev c 主裝置號 次裝置號 我們接下...

Linux GPIO驅動 驅動框架概述

gpio是嵌入式開發中最常見的介面,之前自己就有寫過小的gpio驅動,提供ioctl介面給使用者空間操作。但直到最近才發現linux自身就有完善的gpio驅動框架,並且通過sysfs向使用者空間提供操作介面。linux的gpio驅動框架層次及資料結構如下 最上層是用來向向使用者空間提供介面,使用者可...