linux字元設備
1. linux 設備的含義
inux 中的設備有2種類型:字元設備(無緩沖且只能順序存取)、塊設備(有緩沖且可以隨機存取)。這些設備中,有些設備是對實際存在的物理硬體的抽象,而有些設備則是內核自身提供的功能(不依賴於特定的物理硬體,又稱為"虛擬設備")。每個設備在 /dev 目錄下都有一個對應的文件(節點)。
常見設備及相應/dev/下的文件名:
/dev/usb/hiddev0 | /dev/usb/hiddev1 --- USB 字元設備(滑鼠/鍵盤/游戲桿/手寫版等人操作計算機的設備)
/dev/uba | /dev/ubb --- USB 塊設備(U盤之類)
/dev/sda | /dev/sdb --- 第n個 SCSI 磁碟(整個磁碟)
/dev/hda | /dev/hdb --- 第n個 IDE 磁碟(整個磁碟)
/dev/sdc1 | /dev/sdc2 --- 第3個 SCSI 磁碟的第n個 分區 Linux/i386來說,分區1-4是主分區,5-15是邏輯分區。
/dev/scd0 | /dev/scd1 --- 第n個 SCSI CD-ROM
/dev/tty0 | /dev/tty1 --- 當前虛擬控制台、第n個虛擬控制台 TTY(終端)設備
Linux系統Mount點:mount的時候,mount的目標文件夾/media/cdrom要手動創建
mount /dev/cdrom /media/cdrom
2. 在linux系統下,設備分那幾種
跟WINDOWS一樣吧。硬碟,光碟,軟盤,可移動磁碟,滑鼠,列印機,網卡,磁碟。。。
常見硬體設備在linux中的代號:
IDE硬碟 /dev/hd[a-d]
SCSI硬碟 /dev/sd[a-d]
光碟機 /dev/cdrom
軟碟機 /dev/fd[0-1]
列印機 /dev/lp[0-1]
滑鼠 /dev/mouse
磁碟 /dev/ht0(IDE) /dev/st0 (SCSI)
網卡 /dev/ethn (n由0開始)
3. Linux┊字元設備和塊設備的區別
字元設備和塊設備的區別在於前者只能被順序讀寫,後者可以隨機訪問。大多數設備為字元設備,以位元組為單位,實現file_operations結構體。而如磁碟為塊設備,以塊為單位接受輸入和返回輸出。實現block_device_operations結構體.
4. linux用mknod怎麼創建設備怎麼用
首先要明白什麼是設備文件,簡單的我們說,操作系統與外部設備(入磁碟驅動器,列印機,modern,終端 等等)都是通過設備文件來進行通信的,在Unix/Linux系統與外部設備通訊之前,這個設備必須首先要有一個設備文件,設備文件均放在/dev目錄下。
一般情況下在安裝系統的時候系統自動創建了很多已檢測到的設備的設備文件,但有時候我們也需要自己手動創建,命令行生成設備文件的方式有 insf,mksf,mknod等等
根據mknod命令的使用參數來看【mknod Name { b | c } Major Minor 】,使用mknod之前,至少要明白以下幾點:
設備文件類型:分為塊設備和字元設備。ls -l /dev 結果顯示第一個欄位有b*** 和 c****,這里即標識了塊設備和字元設備。
字元設備文件----字元設備文件傳送數據給設備的時候,一次傳送一個字元,終端,列印機,繪圖儀,modern等設備都經過字元設備文件傳送數據
塊設備---系統通過塊設備文件存取一個設備的時候,先從內存中的buffer中讀或寫數據,而不是直接傳送數據到物理磁碟,這種方式能有效的提高磁碟和CD-ROMS的I/O性能。磁碟和CD-ROMS即可以使用字元設備文件也可使用塊設備文件。
主號和次號
主號:當在任意目錄使用ls -l 時,結果的第5個欄位就是主號,設備主號代表了這個設備使用的是哪個設備驅動程序
次號:次號是一個24位的十六進制數字,定義了設個設備在系統中的物理的位置
就拿我們常用的創建卷組來看:
先來看看mknod 命令,如果該設備文件你想放在一個特定的文件夾下當然就先創建文件夾
mknod 設備文件名[/dev/xyz] b/c 主號 次號
{ mkdir /dev/vg01
mknod /dev/vg01/group c 64 0X010000}
創建之後,就可以使用你想要創建的設備對於德創建命令了,如我現在的卷組的創建命令:
vgcreate /dev/vg01 /dev/dsk/c*t*d*
一直進行下去,之後的步驟根據不同的設備而不盡相同。
5. linux中什麼是塊設備和字元設備
塊設備是I/O設備中的一類,是將信息存儲在固定大小的塊中,每個塊都有自己的地址,還可以在設備的任意位置讀取一定長度的數據。數據塊的大小通常在512位元組到32768位元組之間。塊設備的基本特徵是每個塊都能獨立於其它塊而讀寫。
字元設備是在I/O傳輸過程中以字元為單位進行傳輸的設備。在linux系統中,字元設備以特別文件方式在文件目錄樹中占據位置並擁有相應的結點。結點中的文件類型指明該文件是字元設備文件。可以使用與普通文件相同的文件操作命令對字元設備文件進行操作。
(5)linux字元設備擴展閱讀:
在大多數的linux操作系統中,塊設備只支持以塊為單位的訪問方式,如磁碟等。KYLIN支持以字元方式來訪問塊設備,即支持以字元為單位來讀寫磁碟等塊設備。所以在/dev目錄中的塊設備,如磁碟等,均以字元設備的外觀出現。
當一台字元型設備在硬體上與主機相連之後,必須為這台設備創建字元特別文件。linux操作系統的mknod命令被用來建立設備特別文件。
參考資料來源:
網路——塊設備
網路——字元設備
6. 在Linux內核中,注冊字元設備驅動程序的函數是
字元設備驅動程序框架 1、寫出open、write函數 2、告訴內核 1)、定義一個struct file_operations結構並填充好 static struct file_operations first_drv_fops = { .owner = THIS_MODULE, /* 這是一個宏,推向編譯模塊時自動創建的__this_mole變數 */ .open = first_drv_open, .write = first_drv_write, }; 2)、把struct file_operations結構體告訴內核 major = register_chrdev(0, "first_drv", &first_drv_fops); // 注冊, 告訴內核相關參數:第一個,設備號,0自動分配主設備號,否則為主設備號0-255 第二個:設備名第二個:struct file_operations結構體 4)、register_chrdev由誰調用(入口函數調用) static int first_drv_init(void) 5)、入口函數須使用內核宏來修飾 mole_init(first_drv_init); mole_init會定義一個結構體,這個結構體裡面有一個函數指針指向first_drv_init這個函數,當我們載入或安裝一個驅動時,內核會自動找到這個結構體,然後調用裡面的函數指針,這個函數指針指向first_drv_init這個函數,first_drv_init這個函數就是把struct file_operations結構體告訴內核 6)、有入口函數就有出口函數 mole_exit(first_drv_exit); 最後加上協議 MODULE_LICENSE("GPL"); 3、mdev根據系統信息自動創建設備節點: 每次寫驅動都要手動創建設備文件過於麻煩,使用設備管理文件系統則方便很多。在2.6的內核以前一直使用的是devfs,但是它存在許多缺陷。它創建了大量的設備文件,其實這些設備更本不存在。而且設備與設備文件的映射具有不確定性,比如U盤即可能對應sda,又可能對應sdb。沒有足夠的主/輔設備號。2.6之後的內核引入了sysfs文件系統,它掛載在/sys上,配合udev使用,可以很好的完成devfs的功能,並彌補了那些缺點。(這里說一下,當今內核已經使用netlink了)。 udev是用戶空間的一個應用程序,在嵌入式中用的是mdev,mdev在busybox中。mdev是udev的精簡版。首先在busybox中添加支持mdev的選項: Linux System Utilities ---> [*] mdev [*] Support /etc/mdev.conf [*] Support subdirs/symlinks [*] Support regular expressions substitutions when renaming device [*] Support command execution at device addition/removal 然後修改/etc/init.d/rcS: echo /sbin/mdev > /proc/sys/kernel/hotplug /sbin/mdev -s 執行mdev -s :以『-s』為參數調用位於 /sbin目錄寫的mdev(其實是個鏈接,作用是傳遞參數給/bin目錄下的busybox程序並調用它),mdev掃描 /sys/class 和 /sys/block 中所有的類設備目錄,如果在目錄中含有名為「dev」的文件,且文件中包含的是設備號,則mdev就利用這些信息為這個設備在/dev 下創建設備節點文件。一般只在啟動時才執行一次 「mdev -s」。熱插拔事件:由於啟動時運行了命 令:echo /sbin/mdev > /proc/sys/kernel/hotplug ,那麼當有熱插拔事件產生時,內核就會調用位於 /sbin目錄的mdev。這時mdev通過環境變數中的 ACTION 和 DEVPATH,來確定此次熱插拔事件的動作以及影響了/sys中的那個目錄。接著會看看這個目錄中是否「dev」的屬性文件,如果有就利用這些信息為 這個設備在/dev 下創建設備節點文件重新打包文件系統,這樣/sys目錄,/dev目錄就有東西了下面是create_class的原型: #define class_create(owner, name) / ({ / static struct lock_class_key __key; / __class_create(owner, name, &__key); / }) extern struct class * __must_check __class_create(struct mole *owner, const char *name, struct lock_class_key *key); class_destroy的原型如下: extern void class_destroy(struct class *cls); device_create的原型如下: extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) __attribute__((format(printf, 5, 6))); device_destroy的原型如下: extern void device_destroy(struct class *cls, dev_t devt); 具體使用如下,可參考後面的實例: static struct class *firstdrv_class; static struct class_device *firstdrv_class_dev; firstdrv_class = class_create(THIS_MODULE, "firstdrv"); firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */ class_device_unregister(firstdrv_class_dev); class_destroy(firstdrv_class); 下面再來看一下應用程序如何找到這個結構體的在應用程序中我們使用open打開一個設備:如:open(/dev/xxx, O_RDWR); xxx有一個屬性,如字元設備為c,後面為讀寫許可權,還有主設備名、次設備名,我們注冊時 通過register_chrdev(0, "first_drv", &first_drv_fops)(有主設備號,設備名,struct file_operations結構體)將first_drv_fops結構體注冊到內核數組chrdev中去的,結構體中有open,write函數,那麼應用程序如何找到它的,事實上是根據打開的這個文件的屬性中的設備類型及主設備號在內核數組chrdev裡面找到我們注冊的first_drv_fops,實例代碼: #include #include #include #include #include #include #include #include #include #include static struct class *firstdrv_class; static struct class_device *firstdrv_class_dev; volatile unsigned long *gpfcon = NULL; volatile unsigned long *gpfdat = NULL; static int first_drv_open(struct inode *inode, struct file *file) { //printk("first_drv_open\n"); /* 配置GPF4,5,6為輸出 */ *gpfcon &= ~((0x3<<(4*2)) | (0x3<<(5*2)) | (0x3<<(6*2))); *gpfcon |= ((0x1<<(4*2)) | (0x1<<(5*2)) | (0x1<<(6*2))); return 0; } static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) { int val; //printk("first_drv_write\n"); _from_user(&val, buf, count); // _to_user(); if (val == 1) { // 點燈 *gpfdat &= ~((1<<4) | (1<<5) | (1<<6)); } else { // 滅燈 *gpfdat |= (1<<4) | (1<<5) | (1<<6); } return 0; } static struct file_operations first_drv_fops = { .owner = THIS_MODULE, /* 這是一個宏,推向編譯模塊時自動創建的__this_mole變數 */ .open = first_drv_open, .write = first_drv_write, }; int major; static int first_drv_init(void) { major = register_chrdev(0, "first_drv", &first_drv_fops); // 注冊, 告訴內核 firstdrv_class = class_create(THIS_MODULE, "firstdrv"); firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */ gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); gpfdat = gpfcon + 1; return 0; } static void first_drv_exit(void) { unregister_chrdev(major, "first_drv"); // 卸載 class_device_unregister(firstdrv_class_dev); class_destroy(firstdrv_class); iounmap(gpfcon); } mole_init(first_drv_init); mole_exit(first_drv_exit); MODULE_LICENSE("GPL"); 編譯用Makefile文件 KERN_DIR = /work/system/linux-2.6.22.6 all: make -C $(KERN_DIR) M=`pwd` moles clean: make -C $(KERN_DIR) M=`pwd` moles clean rm -rf moles.order obj-m += first_drv.o 測試程序: #include #include #include #include /* firstdrvtest on * firstdrvtest off */ int main(int argc, char **argv) { int fd; int val = 1; fd = open("/dev/xyz", O_RDWR); if (fd < 0) { printf("can't open!\n"); } if (argc != 2) { printf("Usage :\n"); printf("%s \n", argv[0]); return 0; } if (strcmp(argv[1], "on") == 0) { val = 1; } else { val = 0; } write(fd, &val, 4); return 0; }
7. LINUX,下面設備文件中那些是字元設備文件
/dev/audio是字元設備文件,其他的是塊設備文件
補充:對audio的存取是以
位元組流
方式來進行的。其它的設備/dev/cdrom,
/dev/fd0,
/dev/had都是磁碟(光碟機,軟碟機,主硬碟),它們的存取是通過
數據塊
來進行的
8. linux命令怎麼打開字元設備文件
在Linux中使用ls-l命令來列出文件時,b、c字母開頭的文件,分別表示區塊(block)設備和字元(character)設備,是特殊類型的文件。也就是說Linux字元設備文件以c字母做為開始標志 。
可以執行如下命令,查看到大量字元設備的文件:
ls-l/dev | more
執行結果如下圖所示:
9. 字元設備和塊設備
提供連續的數據流,是一個線性設備,應用程序可以順序讀取,通常不支持隨機存取。相反,此類設備支持按位元組/字元來讀寫數據。舉例來說,數據機是典型的字元設備。
如:鍵盤、滑鼠、顯示屏
應用程序可以隨機訪問設備數據,程序可自行確定讀取數據的位置。硬碟是典型的塊設備,應用程序可以定址磁碟上的任何位置,並由此讀取數據。此外,數據的讀寫只能以塊(通常是512B)的倍數進行。與字元設備不同,塊設備並不支持基於字元的定址。
如:硬碟、U盤
兩種設備本身並沒用嚴格的區分,主要是字元設備和塊設備驅動程序提供的訪問介面(file I/O API)是不一樣的
Linux的設備管理是和文件系統緊密結合的,各種設備都以文件的形式存放在/dev目錄下,稱為設備文件。應用程序可以打開、關閉和讀寫這些設備文件,完成對設備的操作,就像操作普通的數據文件一樣。為了管理這些設備,系統為設備編了號,每個設備號又分為主設備號和次設備號。 主設備號用來區分不同種類的設備,而次設備號用來區分同一類型的多個設備。 對於常用設備,Linux有約定俗成的編號,如硬碟的主設備號是3。
一個字元設備或者塊設備都有一個主設備號和次設備號。主設備號和次設備號統稱為設備號。主設備號用來表示一個特定的驅動程序。次設備號用來表示使用該驅動程序的各設備。 例如一個嵌入式系統,有兩個LED指示燈,LED燈需要獨立的打開或者關閉。那麼,可以寫一個LED燈的字元設備驅動程序,可以將其主設備號注冊成5號設備,次設備號分別為1和2。這里,次設備號就分別表示兩個LED燈。
一般的, 主設備號標識出與設備關聯的設備驅動 。如 /dev/null 和 /dev/port 由 1 號驅動來管理。
現在的 Linux 內核允許多個驅動共享一個主設備號,但更多的設備都遵循一個驅動對一個主設備號的原則。
內核由 次設備號確定當前所指向的是哪個設備。 根據所編寫的驅動程序,可以從內核那裡得到一個直接指向設備的指針,或者使用次設備號作為一個設備本地數組的索引。但不論如何,內核自身幾乎不知道次設備號的什麼事情。
當靜態分配設備號時,需要查看系統中已經存在的設備號,從而決定使用哪個新設備號。可以讀取/proc/devices文件獲得設備的設備號。/proc/devices文件包含字元設備和塊設備的設備號,如下所示:
用於創建Linux中的字元設備文件和塊設備文件。