linux2.6核心中使用cdev結構體描述字元裝置:
structcdev結構體的dev_t定義了裝置號,32位。高12位為主裝置號,低20位為次裝置號。cdev
;
下列巨集可從dev_t獲得主、次裝置號:
major(dev_t通過主、次裝置號生成dev_t:dev)
minor(dev_t
dev)
mkdev(intmajor,
intminor)
一組函式操作cdev結構體:
void呼叫cdev_add()前,先呼叫register_chrdev_region()或alloc_chrdev_region():cdev_init(
struct
cdev*,
struct
file_operations
*); //
初始化cdev成員,建立cdev和file_operations之間的連線
struct
cdev
*cdev_alloc(
void
); // 動態申請乙個cdev記憶體
void
cdev_put(
struct
cdev
*p); // 減少模組的引用計數,釋放結構體空間
intcdev_add(
struct
cdev*,
dev_t,
unsigned
); // 向系統新增乙個dev,完成字元裝置的註冊,常用於模組載入函式中
void
cdev_del(
struct
cdev
*);// 向系統刪除乙個dev,完成字元裝置的登出,常用於模組解除安裝函式中
intcdev_del()後,unregister_chrdev_region()應被呼叫以釋放裝置號:register_chrdev_region(dev_t
from,
unsigned
count,
const
char
*name); // 用於已知起始裝置號
intalloc_chrdev_region(dev_t
*dev,
unsigned
baseminor,
unsigned
count,
const
char
*name); // 裝置號未知,向系統動態申請未占用裝置號放入dev
voidfile_operations結構:unregister_chrdev_region(
dev_t
from
,unsigned
count);
1linux字元裝置驅動函式模板:struct
file_operations
;
//其他說明:裝置結構體
struct
***_dev_t
//裝置驅動模組載入函式
static
int__init
***_init(
void
)else
ret=
cdev_add(
&***_dev
.cdev,
***_dev_no,1);
// 註冊裝置..
.}//裝置驅動模組解除安裝函式
static
void
__exit
***_exit(
void)//
讀裝置//
filp是檔案結構指標,buf是使用者空間的記憶體位址,該位址空間不能直接讀寫,count是要讀的位元組數,f_pos是讀的位置相對於檔案開頭的偏移
ssize_t
***_read(
struct
file
*filp,
char
__user
*buf,
size_t
count,
loff_t
*fpos)
//寫裝置
ssize_t
***_write(
struct
file
*filp,
const
char
__user
*buf,
size_t
count,
loff_t
*fpos)
//ioctl函式
int***_ioctl(
struct
inode
*inode,
struct
file
*filp,
unsigned
intcmd,
unsigned
long
arg)
return0;
}//字元裝置檔案操作結構體,在模組載入函式的cdev_init(&***_dev.cdev, &***_fops)的語句中被建立與cdev的連線
struct
file_operations
***_fops=;
核心空間和使用者空間的記憶體不能直接訪問,需借助copy_from_user()和copy_to_user():
unsigned上述函式返回不能被複製的位元組數。若完全複製成功,返回0.long
copy_from_user(
void
*to,
const
void
__user
*from,
unsigned
long
count);
unsigned
long
copy_to_user(
void
__user
*to,
const
void
*from,
unsigned
long
count);
若要複製的記憶體是簡單型別,如char、int、long等,則可以使用簡單的put_user()和get_user():
int讀和寫函式中的__user是乙個巨集,表明其後的指標指向使用者空間:val; //
核心空間整形變數..
.get_user(val,
(int
*)arg); //
使用者空間到核心空間,arg是使用者空間的位址..
.put_user(val,
(int
*)arg);//
核心空間到使用者空間,arg是使用者空間的位址
#ifdef__checker__
#define
__user
__attribute__((noderef,
address_space(
1)))
#else
#define
__user
#endif
Linux字元裝置驅動總結
linux2.6核心中使用cdev結構體描述字元裝置 struct cdev cdev結構體的dev t定義了裝置號,32位。高12位為主裝置號,低20位為次裝置號。下列巨集可從dev t獲得主 次裝置號 major dev t dev minor dev t dev 通過主 次裝置號生成dev t...
Linux字元裝置驅動框架總結
對於linux而言,一切皆檔案,在linux系統下,所有檔案都可以像文字檔案一樣open read write,那麼對於linux裝置驅動而言,比如現在有乙個點燈的驅動程式,它的裝置節點是 dev 當應用程式執行open read write的時候,是如何呼叫到驅動程式裡的open read wri...
驅動 linux裝置驅動 字元裝置驅動開發
preface 前面對linux裝置驅動的相應知識點進行了總結,現在進入實踐階段!linux 裝置驅動入門篇 linux 裝置驅動掃盲篇 fedora下的字元裝置驅動開發 開發乙個基本的字元裝置驅動 在linux核心驅動中,字元裝置是最基本的裝置驅動。字元裝置包括了裝置最基本的操作,如開啟裝置 關閉...