Linux核心 2 裝置驅動實驗

2021-06-27 00:26:32 字數 4300 閱讀 8570



今天做了linux課設關於裝置驅動的實驗。

實驗採用模組的方法編寫乙個可以進行簡單讀寫的字元裝置驅動,該裝置可以儲存一定長的字串,寫入裝置即可以將字串存入裝置,讀出即可以獲取該字串,並編寫了測試程式對其測試。

(1)首先新建並編寫了字元驅動裝置chardev.c檔案,檔案**如下:

/**

建立乙個字元裝置(讀寫)

*//*

必要的標頭檔案,核心模組標準標頭檔案

*/#include

#include/*

核心工作

*/#include/**/

#include

#include/*

明確指定是模組

*/#include

/*對於字元裝置

*/#include/*

字元裝置定義

*/#include

#include

#include

module_author("author");

module_license("gpl");

struct char_dev *char_device;

int dev_major=0;

int dev_minor=0;

module_param(dev_major,int,s_irugo);

module_param(dev_minor,int,s_irugo);

//裝置儲存區的指標

char *p_mem=null;

//裝置儲存區的大小

long len=1000;

//表示裝置的資料結構

struct char_dev

;int char_open(struct inode *inode,struct file *filp)

//讀時將呼叫的函式

static ssize_t char_read(struct file * filp, char __user *buf, size_t count, loff_t *offset)

printk("you are using the read function!");

return count ;}//

引數定義和

char_read

類似static ssize_t char_write(struct file * filp, const char __user *buf, size_t count, loff_t *offset)

return count;}//

讀寫完畢後呼叫的函式

int char_release(struct inode *inode,struct file *filp)

//定義裝置節點檔案的操作

static struct file_operations char_ops=;

//裝置初始化時呼叫的函式,用於獲取儲存區記憶體空間

int memory_init(void)

return 1;}//

裝置初始化

static int dev_init(void)

else

if(result < 0)

//返回主裝置號

printk("the dev_major %d/n",dev_major);

//獲取全域性

char_dev

結構體char_device = kmalloc(sizeof(struct char_dev),gfp_kernel);

if(!char_device)

memset(char_device,0,sizeof(struct char_dev));

//使用定義了的檔案操作

char_ops

初始化cdev

cdev_init(&char_device->cdev, &char_ops);

char_device->cdev.owner = this_module;

char_device->cdev.ops = &char_ops;

//使用後區的裝置號註冊裝置

devno=mkdev(dev_major,dev_minor);

//新增此字元裝置到系統

err=cdev_add(&char_device->cdev,devno,1);

char_device->data=p_mem;

char_device->len=len;

return 0;}//

裝置被移出時呼叫

static void dev_exit(void)

//註冊模組初始化和解除安裝函式

module_init(dev_init);

module_exit(dev_exit);

(2)然後編寫相應的makefile檔案:

# makefile

# if kernelrelease is defined, we've been invoked from the

# kernel build system and can use its language.

ifneq ($(kernelrelease),)

obj-m := chardev.o

# otherwise we were called directly from the command

# line; invoke the kernel build system.

else

kerneldir ?= /lib/modules/`uname -r`/build

default:

make -c $(kerneldir) m=`pwd` modules

endif

(3)使用make 命令,生成驅動程式chardev.ko

(4)用root

掛載裝置

insmod chardev.ko

(5)在檔案系統為其建立乙個代表節點(建立裝置檔案)。

建立節點命令格式如下:

mknod /dev/

例如(若主裝置號為249):

mknod mychardev0 c 249 0

(6)修改屬性:

chmod 666 mychardev*

(7)裝置掛載後,就能夠使用系統命令寫入資料和讀取資料啦~

如讀操作:more mychardev0 (

友情提示:mychardev0會很大,若想體驗計算機編碼的奇妙可嘗試cat命令)

(8)編寫測試程式test.cpp:

#include

#include

#include

#include

using namespace std;

int main()

//向指定裝置寫入使用者輸入文字

cout<<"please input the text:/n";

cin>>buffer_write;

write(fd, buffer_write, 20); //

輸出裝置中的內容

read(fd, buffer_read, 20);

cout<<"

指定裝置中的內容為:

/n"<

close(fd);

return 0; }

**功能:實現了裝置的讀資料寫資料操作,有以下幾點值得注意:

①fd=open("/home/guest/dev/mychardev0", o_rdwr);

不能只看對應資料夾下是否有

mychardev0

裝置,若開啟不成功可能需要重新

mknod

一下。②

iostream

不能直接寫

#include

,而要寫:

#include

using namespace std;

③關於read

和write

函式的第三個引數n:

其作用要追溯到

copy_to_user

和copy_from_user

兩個函式上,其值就表示要寫入或讀出的字串大小

(以位元組為單位)。

Linux核心裝置驅動註冊

platform device與platform driver 引入devicetree後改變 platform device會由kernel自動展開,呼叫of platform bus probe null,of bus ids,null 即可自動展開所有的platform device 引入de...

Linux裝置驅動 核心開發

linux裝置驅動需要使用核心api來實現,一般被包含在linux核心原始碼樹中。驅動可以編譯到核心,隨著核心一起在系統啟動的時候被載入。也可以編譯成核心模組,在系統執行起來之後動態地載入到核心中,使得除錯的時候無需重新編譯核心,也無需重啟系統,很大程度上方便了驅動 的除錯。但並不是只有裝置驅動才能...

Linux核心混雜裝置驅動

1.1混雜裝置驅動特點 本質上還是一類字元裝置,在驅動軟體上,混雜裝置的主裝置號已經由核心指定主裝置號為10 各個混雜裝置個體通過次裝置號來區分 1.2linux核心描述混雜裝置的資料結構 struct miscdevice 作用 描述混雜裝置 成員 minor 混雜裝置對應的次裝置號,切記主裝置號...