亚洲成精品动漫久久精久,九九在线精品视频播放,黄色成人免费观看,三级成人影院,久碰久,四虎成人欧美精品在永久在线

掃一掃
關注微信公眾號

linux設備驅動筆記——字符設備驅動1
2007-08-07   中國IT實驗室

“全局性”是指,如果打開設備多次,所有打開它的文件描述符共享其中的數據。“持久性”是指,如果設備關閉后再次打開,數據不丟失。

※ 真實的驅動程序利用中斷與它們的設備同步

主設備號和次設備號

※ 主設備號標識設備對應的驅動程序;次設備號由內核使用,用于正確確定設備文件所指的設備。我們可以通過次設備號獲得一個指向內核設備的直接指針,也可將次設備號當作設備本地數組的索引,不管用哪種方式,除了知道次設備號用來指向驅動程序所實現的設備之外,內核本身基本上不關心關于次設備號的任何其他消息。

※ 設備編號的內部表達

n 在內核中,dev_t類型(在<linux/types.h>中定義)用來保存設備編號——包括主設備號和次設備號。

n MAJOR(dev_t dev); MINOR(dev_t dev) MKDEV(int major, int minor)

※ 分配和釋放設備編號

n <linux/fs.h>:

int register_chrdev_region(dev_t first, unsigned int count, char *name);

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, 
                        unsigned int count, char *name);
void unregister_chrdev_region(dev_t first, unsigned int count);
 
驅動程序需要將設備編號和內部函數連接起來,這些內部函數用來實現設備的操作。

※ 動態分配主設備號

n 某些主設備號已經靜態地分配給了大部分公用設備。在內核源碼樹的Documentation/device.txt文件中可以找到這些設備的列表。

n 一旦驅動程序被廣泛使用,隨機選定的主設備號可能造成沖突和麻煩

n 強烈推薦你不要隨便選擇一個一個當前不用的設備號做為主設備號,而使用動態分配機制獲取你的主設備號。

n 動態分配的缺點是,由于分配給你的主設備號不能保證總是一樣的,無法事先創建設備節點。然而這不是什么問題,這是因為一旦分配了設備號,你就可以從/proc/devices讀到。為了加載一個設備驅動程序,對insmod的調用被替換為一個簡單的腳本,它通過/proc/devices獲得新分配的主設備號,并創建節點

#!/bin/sh
module="scull"
device="scull"
mode="664"
 
# invoke insmod with all arguments we got
# and use a pathname, as newer modutils don't look in . by default
 
/sbin/insmod ./$module.ko $* || exit 1
 
# remove stale nodes
 
rm -f /dev/${device}[0-3]
major=$(awk "\\$2=  =\"$module\" {print \\$1}" /proc/devices)
mknod /dev/${device}0 c $major 0
mknod /dev/${device}1 c $major 1
mknod /dev/${device}2 c $major 2
mknod /dev/${device}3 c $major 3
 
# give appropriate group/permissions, and change the group.
# Not all distributions have staff, some have "wheel" instead.
 
group="staff"
grep -q '^staff:' /etc/group || group="wheel"
 
chgrp $group /dev/${device}[0-3]
chmod $mode  /dev/${device}[0-3]

n 分配主設備號的最佳方式:默認采用動態分配,同時保留在加載甚至是編譯時指定主設備號的余地。

n Here's the code we use in scull 's source to get a major number:

if (scull_major) {
    dev = MKDEV(scull_major, scull_minor);
    result = register_chrdev_region(dev, scull_nr_devs, "scull");
} else {
    result = alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
    scull_major = MAJOR(dev);
}
if (result < 0) {
    printk(KERN_WARNING "scull: can't get major %d\n", scull_major);
    return result;
}

熱詞搜索:

上一篇:把設備驅動程序編譯進嵌入式Linux內核
下一篇:linux設備驅動筆記——字符設備驅動2

分享到: 收藏