最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

linux 驅(qū)動編寫之虛擬字符設(shè)備的編寫實例詳解

 更新時間:2017年01月18日 16:06:38   投稿:lqh  
這篇文章主要介紹了linux 驅(qū)動編寫之虛擬字符設(shè)備的編寫實例詳解的相關(guān)資料,需要的朋友可以參考下

 linux 驅(qū)動編寫

前言:

 昨天我們說了一些簡單模塊編寫方法,但是終歸沒有涉及到設(shè)備的編寫內(nèi)容,今天我們就可以了解一下相關(guān)方面的內(nèi)容,并且用一個實例來說明在Linux上面設(shè)備是如何編寫的。雖然我不是專門做linux驅(qū)動的,卻也經(jīng)常收到一些朋友們的來信。在信件中,很多做驅(qū)動的朋友對自己的工作不是很滿意,認(rèn)為自己的工作就是把代碼拷貝來拷貝去,或者說是改來改去,沒有什么技術(shù)含量。有這種想法的朋友不在少數(shù),我想這主要還是因為他們對自己的工作缺少了解導(dǎo)致。如果有可能,我們可以問問自己這樣幾個問題:

    (1)我真的搞懂設(shè)備的開發(fā)驅(qū)動流程了嗎?我是否可以從0開始,編寫一個獨(dú)立的驅(qū)動代碼呢?
    (2)我真的了解設(shè)備的初始化、關(guān)閉、運(yùn)行的流程嗎?
    (3)當(dāng)前的設(shè)備驅(qū)動流程是否合理,有沒有可以改進(jìn)的地方?
    (4)對于內(nèi)核開發(fā)中涉及的api調(diào)用,我自己是否真正了解、是否明白它們在使用上有什么區(qū)別?
    (5)如果我要驅(qū)動的設(shè)備只是在一個前后臺系統(tǒng)中運(yùn)行,在沒有框架幫助的情況下,我是否有信心把它啟動和運(yùn)行起來?

    當(dāng)然,上面的內(nèi)容只是我個人的想法,也不一定都正確。但是,知其然,更要知其所以然,熟悉了當(dāng)前開發(fā)流程的優(yōu)缺點才能真正掌握和了解驅(qū)動開發(fā)的本質(zhì)。這聽上去有些玄乎,其實也很簡單,就是要有一種刨根問底、不斷改進(jìn)的精神,這樣才能做好自己的工作。因為我們是在pc linux上學(xué)習(xí)驅(qū)動的,因此暫時沒有真實的外接設(shè)備可以使用,但是這絲毫不影響我們學(xué)習(xí)的熱情。通過定時器、進(jìn)程,我們可以仿真出真實設(shè)備的各種需求,所以對于系統(tǒng)來說,它是無所謂真設(shè)備、假設(shè)備的,基本的處理流程對它來說都是一樣的。只要大家一步一步做下去,肯定可以了解linux驅(qū)動設(shè)備的開發(fā)工程的。

    下面,為了說明問題,我們可以編寫一段簡單的char設(shè)備驅(qū)動代碼,文件名為char.c,

#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/fs.h> 
#include <linux/cdev.h> 
 
static struct cdev chr_dev; 
static dev_t ndev; 
 
static int chr_open(struct inode* nd, struct file* filp) 
{ 
  int major ; 
  int minor; 
   
  major = MAJOR(nd->i_rdev); 
  minor = MINOR(nd->i_rdev); 
   
  printk("chr_open, major = %d, minor = %d\n", major, minor); 
  return 0; 
} 
 
static ssize_t chr_read(struct file* filp, char __user* u, size_t sz, loff_t* off) 
{ 
  printk("chr_read process!\n"); 
  return 0; 
} 
 
struct file_operations chr_ops = { 
  .owner = THIS_MODULE, 
  .open = chr_open, 
  .read = chr_read 
}; 
 
static int demo_init(void) 
{ 
  int ret; 
   
  cdev_init(&chr_dev, &chr_ops); 
  ret = alloc_chrdev_region(&ndev, 0, 1, "chr_dev"); 
  if(ret < 0 ) 
  { 
    return ret; 
  } 
   
  printk("demo_init(): major = %d, minor = %d\n", MAJOR(ndev), MINOR(ndev)); 
  ret = cdev_add(&chr_dev, ndev, 1); 
  if(ret < 0) 
  { 
    return ret; 
  } 
   
  return 0; 
} 
 
static void demo_exit(void) 
{ 
  printk("demo_exit process!\n"); 
  cdev_del(&chr_dev); 
  unregister_chrdev_region(ndev, 1); 
} 
 
module_init(demo_init); 
module_exit(demo_exit); 
 
MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("feixiaoxing@163.com"); 
MODULE_DESCRIPTION("A simple device example!"); 

    在module_init中的函數(shù)是模塊加載時處理的函數(shù),而模塊卸載的函數(shù)則是在module_exit中。每一個設(shè)備都要對應(yīng)一個基本的設(shè)備數(shù)據(jù),當(dāng)然為了使得這個設(shè)備注冊在整個系統(tǒng)當(dāng)中,我們還需要分配一個設(shè)備節(jié)點,alloc_chrdev_region就完成這樣一個功能。等到cdev_add的時候,整個設(shè)備注冊的過程就全部完成了,就是這么簡單。當(dāng)然為了編寫這個文件,我們還需要編寫一個Makefile文件,

ifneq ($(KERNELRELEASE),) 
obj-m := char.o 
 
else 
PWD := $(shell pwd) 
KVER := $(shell uname -r) 
KDIR := /lib/modules/$(KVER)/build 
all: 
  $(MAKE) -C $(KDIR) M=$(PWD) modules 
clean: 
  rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions modules.* Module.* 
endif 

    這個Makefile文件和我們之前編寫的makefile基本上沒有區(qū)別,唯一的區(qū)別就是文件名稱改成了char.o,僅此而已。為了編寫模塊,我們直接輸入make即可。這時候,char.ko文件就可以生成了。然后,模塊需要被注冊在系統(tǒng)當(dāng)中,insmod char.ko是少不了的。如果此時,我們還不確信是否模塊已經(jīng)加入到系統(tǒng)當(dāng)中,完全可以通過輸入lsmod | grep char進(jìn)行查找和驗證。為了創(chuàng)建設(shè)備節(jié)點,我們需要知道設(shè)備為我們創(chuàng)建的major、minor數(shù)值是多少,所以dmesg | tail 查找一下數(shù)值。在我hp的機(jī)器上,這兩個數(shù)值分別是249和0,所以下面可以利用它們直接創(chuàng)建設(shè)備節(jié)點了,輸入mknod /dev/chr_dev c 249 0即可,此時可以輸入ls /dev/chr_dev驗證一下。那么,按照這種方法,真的可以訪問這個虛擬設(shè)備了嗎,我們可以編寫一段簡單的代碼驗證一下,

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 
 
#define CHAR_DEV_NAME "/dev/chr_dev" 
 
int main() 
{ 
  int ret; 
  int fd; 
  char buf[32]; 
 
  fd = open(CHAR_DEV_NAME, O_RDONLY | O_NDELAY); 
  if(fd < 0) 
  { 
    printf("open failed!\n"); 
    return -1; 
  } 
   
  read(fd, buf, 32); 
  close(fd); 
   
  return 0; 
} 

    代碼的內(nèi)容非常簡單,就是利用CHAR_DEV_NAME直接打開設(shè)備,讀寫設(shè)備。當(dāng)然。首先還是需要對這個文件進(jìn)行編譯,文件名為test.c,輸入gcc test.c -o test,其次就是運(yùn)行這個文件,直接輸入./test即可。如果沒有問題的話,那么說明我們的代碼是ok的,但是我們還是沒有看到任何內(nèi)容。沒關(guān)系,我們還是通過dmesg這個命令查看內(nèi)核中是否存在相關(guān)的打印內(nèi)容,直接輸入dmesg | tail即可。此時如果沒有意外的話,我們就可以看到之前在chr_open和chr_read中留下的printk打印,這說明我們的代碼完全是ok的。

    上面的代碼只是一段小例子,真實的內(nèi)容要比這復(fù)雜一下。不過既然我們都已經(jīng)入門了,那么后面的內(nèi)容其實也沒有什么好怕的了。最后有兩個事情補(bǔ)充一下:(1)如果大家在創(chuàng)建節(jié)點后想刪除設(shè)備節(jié)點,直接rm -rf /dev/chr_dev即可;(2)上面這段代碼的原型來自于《深入linux設(shè)備驅(qū)動程序內(nèi)核機(jī)制》這本書,稍作修改,如果大家對內(nèi)核機(jī)制的內(nèi)容感興趣,可以參考這本書的內(nèi)容。

 感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • 解決Ubuntu19 安裝Theano問題

    解決Ubuntu19 安裝Theano問題

    這篇文章主要介紹了解決Ubuntu19 安裝Theano出現(xiàn)"No module named ‘theano.compat.six’"問題,需要的朋友可以參考下
    2019-12-12
  • Linux使用nload監(jiān)控網(wǎng)絡(luò)流量的方法

    Linux使用nload監(jiān)控網(wǎng)絡(luò)流量的方法

    Linux 中的 nload 命令是一個用于實時監(jiān)控網(wǎng)絡(luò)流量的工具,它提供了傳入和傳出流量的可視化表示,幫助用戶一目了然地了解網(wǎng)絡(luò)活動,本文給大家介紹了Linux使用nload監(jiān)控網(wǎng)絡(luò)流量的方法,需要的朋友可以參考下
    2025-02-02
  • 淺談Linux內(nèi)核創(chuàng)建新進(jìn)程的全過程

    淺談Linux內(nèi)核創(chuàng)建新進(jìn)程的全過程

    這篇文章主要為大家深入淺出的介紹了Linux內(nèi)核創(chuàng)建新進(jìn)程的全過程,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 如何創(chuàng)建Linux的swap交換分區(qū)文件的方法步驟

    如何創(chuàng)建Linux的swap交換分區(qū)文件的方法步驟

    這篇文章主要介紹了如何創(chuàng)建Linux的swap交換分區(qū)文件的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • Ubuntu14.04安裝pycharm的步驟

    Ubuntu14.04安裝pycharm的步驟

    這篇文章主要介紹了Ubuntu14.04安裝pycharm的步驟,非常不錯具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • 優(yōu)化Apache服務(wù)器性能的方法小結(jié)

    優(yōu)化Apache服務(wù)器性能的方法小結(jié)

    盡管Apache是一個高可定制的功能強(qiáng)大且相當(dāng)復(fù)雜的服務(wù)器軟件,我們很有興趣的注意到即使是Apache的標(biāo)準(zhǔn)安裝也可以得到不錯的性能。
    2010-12-12
  • socket unix domain IPC的實例代碼

    socket unix domain IPC的實例代碼

    下面小編就為大家?guī)硪黄猻ocket unix domain IPC的實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 在linux中設(shè)置tomcat開機(jī)自啟動的方法

    在linux中設(shè)置tomcat開機(jī)自啟動的方法

    由于各種各樣的原因,服務(wù)器有重啟的可能,這樣tomcat就需要配置成開機(jī)自動啟動,否則每次重啟后就需要連遠(yuǎn)程手動啟動tomcat,如果服務(wù)器被迫重啟,而技術(shù)人員又不能及時運(yùn)行tomcat,那么后果很嚴(yán)重,所以本文給大家介紹了在linux中設(shè)置tomcat開機(jī)自啟動的方法
    2024-02-02
  • linux特殊權(quán)限使用(suid、sgid、sbit)

    linux特殊權(quán)限使用(suid、sgid、sbit)

    這篇文章主要介紹了linux特殊權(quán)限使用(suid、sgid、sbit),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Centos安裝php高版本

    Centos安裝php高版本

    PHP(超文本預(yù)處理器)是一種通用開源腳本語言。主要適用于Web開發(fā)領(lǐng)域。用PHP做出的動態(tài)頁面與其他的編程語言相比,PHP是將程序嵌入到HTML(標(biāo)準(zhǔn)通用標(biāo)記語言下的一個應(yīng)用)文檔中去執(zhí)行,執(zhí)行效率比完全生成HTML標(biāo)記的CGI要高許多,使代碼運(yùn)行更快。
    2016-05-05

最新評論

阳泉市| 汉源县| 安化县| 海安县| 新源县| 靖江市| 蒲江县| 金塔县| 柯坪县| 焉耆| 沂南县| 德庆县| 罗定市| 高密市| 武夷山市| 蕲春县| 沂水县| 本溪| 印江| 桂平市| 绥棱县| 靖边县| 上思县| 延寿县| 景洪市| 开封市| 抚顺市| 文昌市| 社会| 夏邑县| 玉树县| 深水埗区| 逊克县| 丁青县| 如皋市| 资源县| 乌什县| 肃宁县| 饶平县| 富川| 二连浩特市|