How to use Linux——3 设备

3.0 序言

这一章节是对于linux系统中内核提供的设备基础的简单的基本参阅。纵观linux的历史,对于内核如何呈现设备给用户发生了很多改变。我们会在一开始通过着眼于传统系统的设备文件去查看内核如何提供设备配置信息通过sysfs。我们的目标是能够提取出一些设备的信息在一个系统中去理解一些简单操作。后面的章节会讲述跟特别种类的设备的交互在更多的细节。

对于理解内核和用户空间如何交互与新设备很重要。这个udev 系统使得用户空间能够自动的配置然后使用新设备。你能够看到内核如何发送信息给用户空间进程通过udev,也是进程
对它做。

关于sysfs:
"sysfs is a ram-based filesystem initially based on ramfs. It provides a means
to export kernel data structures, their attributes, and the linkages between them to
userspace.” — documentation/filesystems/sysfs.txt

sysfs 是一种基于内存的文件系统一开始基于famfs。它提供了一种方法去导出内核中的数据结构、他们的数据,和他们对于用户空间的联系。

sysfs向用户空间展示了驱动设备的层次结构。我们都知道设备和对应的驱动都是由内核管理的,这些对于用户空间是不可见的。现在通过sysfs,可以在用户空间直观的了解设备驱动的层次结构。

3.1 设备文件

在unix系统上很容易去操纵大部分的设备因为内核提供了设备i/o接口作为文件呈现给用户进程。这些设备文件有时候被称为设备结点。不仅仅是一个编程者能够使用正规文件操作去跟一个设备交互,而且一些设备也能够使用一些标准程序像cat,所以你不用去当一个编程者去使用一个设备。然而,有点限制对于你去对一个文件接口做一些事情的时候。所以并不是
所有的设备和设备能力都能用上标准文件I/O。linux使用相同设计相比于unix风格。设备文件
在dev文件目录,去使用ls/dev去呈现更多的几个文件在/dev中。所以你对于设备如何工作?
一开始,先考虑这个命令:

$ echo blah blah > /dev/null

当任何命令伴随着重定向输出,这发送了一些东西从标准输出到文件中。然而,文件是/dev/null,一个设备,内核决定当写入任何数据到这个设备中发生了什么。在这个案例关于
dev/null中,内核简单护士了输入然后把数据丢掉了。
去确定一个设备然后查看它的许可和权限。使用ls -l。

注解——关于/dev/null:
/dev/null : 在类Unix系统中,/dev/null,或称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功),读取它则会立即得到一个EOF。
在程序员行话,尤其是Unix行话中,/dev/null 被称为位桶(bit bucket)或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。

注意一下每一行的第一个字符。如果这个字符b,c,p或者s,这个文件是一个设备。这个字母代表的是块、字符、管道、套接字、各自的,分别描述了下面更多细节。

块设备
程序从块设备中读取一定块的数据。sda1在之前的例子中是一个磁盘涉笔,一种块设备。磁盘很容易被分成块数据。因为一个块设备的整个大小是固定的并且很容易索引,进程有随机存取对于任何块在设备中在内核的帮助中。

字符设备
字符设备通过数据流工作。你只能读取字符从字符设备或者写设备到字符设备,就是之前
展示dev/null。字符设备没有一个大小。当你从一个设备中读取或者写入到一个设备中,内核通常都会执行read 或者write操作在设备上。打印器直接连接电脑通过以字符设备的形式呈现。一个重要的注意的点是,就在字符设备交互的期间,内核不能撤回,然后再次读取数据流在它把数据交付给一个设备或者进程的时候。

管设备
命名管道就像字符设备一样,有另外一个进程在I/O流的尾部而不是一个内核驱动。
关于named pipes:
in computing, a named pipe (also known as a FIFO for its behavior) is an extension to the traditional pipe concept on Unix and Unix-like systems, and is one of the methods of inter-process communication (IPC). The concept is also found in OS/2 and Microsoft Windows, although the semantics differ substantially. A traditional pipe is “unnamed” and lasts only as long as the process. A named pipe, however, can last as long as the system is up, beyond the life of the process. It can be deleted if no longer used. Usually a named pipe appears as a file, and generally processes attach to it for IPC.
在计算中,一个命名管道(也被知道是fifo对于它的特性)是一种扩展的管道观点对于传统的管道概念在unix和类unix系统,也是进程间通信的一种方法(IPC)inter-process communication。这种概念也被发现于OS/2 和微软的windows系统,虽然语义上有点微妙的不同。传统的管道是没有名字的而且只存在于进程中。一个命名管道,然而,可以一直存在于系统之中。它如果不再使用能够被删除。通常一个命名管道以文件的形式出现,而且一般来说进程是附着在IPC上的。

套接字设备
套接字是一种特殊母的的接口经常用于内部程序交流。他们经常被防线在/d目录的外面。
套接字文件文件代表了unix域套接字;你能够学习一些关于第10章。
就在例子中的前两行的数字代表了主设备和从住在的号码,帮助内核去识别设备。相似的设备往往有相同的主号码,就像sda3和sdb1(都是一些硬盘分区)
注意:并不是所有的设备都有设备文件因为块和字符设备I/O接口并不适用于各种情况。举个例子,网络接口没有设备文件。理论上是可能你的,去交互一个网络接口实用一个单一的
字符设备,但因为这会异常的难,所以内核实用其他的I/O接口。

3.2 sysfs设备路径

传统的unix /dev目录是一种方便的方式对于用户进程去参考和通过内核支持的设备进行交互,但它也有一个非常过分简单的组合。设备名字在dev告诉你关于设备的东西很少,不是很多。另一个问题是内核指定设备以他们找到的方式,所以一个设备可能有不同的名字在重启之间。

去提供一个统一的视图给附加设备基于他们实际的硬件属性,linux内核提供sysfs接口通过一个文件系统和目录系统。基本的路径对于设备是sys/devices。举个例子,sata硬盘在/dev/sda可能有一下的路径在sysfs中。
/sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
正如你看到的,这个路径相比较于/dev/sda这个文件名来说很长,它也是一个目录。但你不能够真的比较两个路径因为他们有不同的目的。存在/dev文件,以便用户进程可以使用该设备,然而/sys/devices 路径用于查看信息管理设备。如果你列举出设备的路径像之前的一个,你会看到如下的一些东西。
这里文件和文件子目录主要是给程序读取而不是人类,但你能够知道他们里面包含了什么
通过查看一个例子就像/dev文件。运行cat dev在这个目录展示了数字8:0,恰巧是一个主和从设备的/dev/sda。
里面有一些快照在/sys 文件目录。举个例子,/sys/块应该包含所有的系统可用的块设备。然而,那些就是一些符号链:运行 ls -l /sys/block去展示真正的sysfs路径。
去招一个设备的位置在/dev会很难。使用udevadm命令去展示路径和其他属性。

$ udevadm info --query=all --name=/dev/sda

注解
这个udevadm程序在/sbin 你可以把这个目录放在你路径的尾部如果他们没有在那里。
你会发现udevadm更多的系统在完整的udev系统在3.5中。

3.3 dd 和设备

程序dd对于使用符号和块设备工作十分有用。这个程序的功能是从一输入文件或者一个流然后写到一个流的输出文件,可能做了一些编码变换在这里。
dd拷贝数据在一定大小的块中。这里说的是如何使用dd去使用一个字符设备和一些常见的选项。

$ dd if=/dev/zero of=new_file bs=1024 count=1

正如你能看到的,dd的选项格式不同于大部分其他的unix命令。它是基于老的IBM 任务控制
语言(JCL) 风格。没有用破折号(-)去指示一个选项,你命名了一个选项然后设置选项值
通过=符号。前面的例子中,它拷贝了一个单一的1024 字节的块从/dev/zero 一连串的0字符输出到一个新的文件。
下面是一些重要的选项:
if = file 输入文件。默认是标准输入。
of = file 输出文件。默认是标准化输出。
bs=size 块大小。dd可以一次写入和读取大量字节的数据。为了简化大量的数据。可以使用b和k去表示512和1024字节。因此,上面的例子可以读为bs=1k而不是bs=1024。
ibs =size ,obs=size 是输入和输出块的大小。如果你能使用相同块大小对于输入和输出,使用bs选项,如果不能,使用ibs和obs各自给输入和输出。
count=num 复制的总量的块数。当处理大文件的时候——或者用设备供应一个无尽的数据流,就像/dev/zero——你想要dd去停止在一个固定的点或者你会浪费很多的磁盘空间、cpu时间,或者都有。使用count伴随skip参数去拷贝一小部分从大文件或者设备中。
skip=
num Skip 跳过num块在输入文件或者流中,然后不会把他们复制到输出中。
警告
dd十分强大,因此保证你知道你在用它干什么。很容易因为一点小错误去破坏文件和数据。
最好你x’k写一份输出到一个新的文件,如果你不知道它会干什么。

3.4 设备名字总结

有时候很难找到一个设备的名字(举个例子,当为一个磁盘分盘的时候)。这里有几种方式
去找到它:
query udevd 使用udevadm。
寻找一个设备在/sys 文件目录。
猜一猜名字从dmesg命令(打印了最后几个内核信息)或者从内核系统日志文件。这个输出可能包含一种设备描述在你的系统中。
对于一个磁盘设备已经能在系统中看到,你可以检测mount命令的输出。
运行cat /proc/devices 去看块设备和字符设备对于你的系统已经有了驱动。每一行都包含一个数字和名字。数字是一个主设备的数字描述在3.1设备文件中。如果你能够猜测一个设备从名字中,在/dev 中查找一个字符设备和块设备用对应的主数字,然后你会找到设备文件。
在这些方法中,只有第一个是可靠的,但它确实需要udev。如果你进入到一种环境当udev是不可用的,尝试其他方法但在心里记得内核可能没有一个设备文件对于你的硬件。
下一个章节列举出了大部分相同的Linux 设备和他们的命名规则。

3.4.1 硬盘:/dev/sd*

大部分硬盘链接到linux系统对应他们的设备名的前缀,就像/dev/sda,/dev/sdb等等。这些设备呈现一个完整的磁盘,内核为他们各自生成了设备文件,就像/dev/sda1 和/dev/sda2 对于一个磁盘的分区。
命名规则需要进行一点解释。sd部分代表scsi磁盘(Small Computer System Interface)最初以硬件的形式进行发展而且协议代表了设备之前的交流就像磁盘和其他外围设备。虽然传统的sisi硬盘不能运用到大部分现代的机器中,sisi协议到处使用因为它的兼容性。举个例子,USB存储设备使用它去交互。sata磁盘的故事有点复杂,但linux内核一直使用scsi命令在一点时间去跟sata磁盘交互的时候。
去列举sisi设备在你的系统,使用一个实用程序去遍历设备路径通过sysfs。最简洁的工具之一就是lssci。这是你可以期望的当你运行它的时候:

$ lsscsi
[0:0:0:0]➊ disk➋ ATA WDC WD3200AAJS-2 01.0 /dev/sda➌
[1:0:0:0] cd/dvd Slimtype DVD A DS8A5SH XA15 /dev/sr0
[2:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdb

第一列定义了设备在系统中的地址,2号解释是那一种设备,最后的3指定了哪里能找到设备文件。其他一切都是供应商信息。
Linux指定设备给设备文件以一种驱动遇到设备的顺序。所以在之前的例子中,内核首先发现了磁盘,第二个发现了光驱,最后发现了flash驱动。
不幸的是,设备指定计划因为有传统给造成问题当重新配置硬件。说,举个例子,你有个有3个磁盘的系统:/dev/sda,/dev/sdb 和 /dev/sdc 如果/dev/sdb 爆炸了你必须删除硬盘所以机器能够再次工作。之前的/dev/sdc 移动到/dev/sdb,然后再也没有/dev/sdc。如果你查找一个设备名字直接在fstab文件中。(查看4.28在 /etc/fstab 文件系统表格),你必须对那些文件进行一些修改让事情变正常。为了解决这一问题,大部分现代linux体哦给你实用通用唯一
定位符(UUID)对于现在磁盘设备的存取。
这个讨论仅仅描绘了表面如何实用磁盘和其他存储设备在linux系统中。查看第四章去肇东更多相关使用磁盘的信息,之后的章节,我们会检测scisi支持工作在linux内核中。

3.4.2 CD和DVD驱动:/dev/sr*

Linux识别大部分光存储驱动作为scsi设备 /dev/sr0,/dev/sr1 等等。然而,如果驱动使用一个老的接口,这展示了一个pata设备,就像下面讨论的。这个/dev/sr* 设备是只读文件,他们只用于从磁盘中读取。对于写入和重写的能力,您将使用“通用”SCSI设备,比如/dev/sg。

3.4.3 PATA 硬盘:/dev/hd*

这个linux块设备 /dev/hda,/dev/hdb,/dev/hdc,和/dev/hdd也是常见的老的版本的linux内核和其他硬件。这里有固定指定基于主/从设备在接口0和接口1。优势,你可能发现一个sata驱动被认为是这些磁盘之一。这意味着sata驱动运行在兼容性模型,这会影响性能。检测你的bios设置去看你能否将sata控制器转会原本的模式。

3.4.4 终端: /dev/tty*, /dev/pts/*, and /dev/tty

终端是设备对于从移动字符从一个用户进程到一个I/O设备,通常用于文件输出到终端屏幕。
这个终端设备接口可以追溯到很久以前,到那个时候,终端还是基于打字机的设备。
伪终端设备是仿真终端拥有着跟真实终端一样的I/O特性。但没有真的跟硬件的一块交互,内核展现了I/O接口给一部分软件,就像shell终端窗口你可能把你大部分的命令打进去。
两个常见的终端设备就是/dev/tty1 (第一个虚拟的控制台)和/dev/pts/0(第一个伪终端)。这个/dev/pts目录它自己就是一个专用的文件系统。
这个/dev/tty 设备是一个控制终端对于当前的进程。如果一个程序目前从一个终端中读取信息和写入信息,这个设备是那个终端的同义字。一个程序不需要附着到一个终端上。

显示模式和虚拟控制台
linux有主要的两种显示模式:文本模式和X Window System server(图形模式,通常通过一个显示管理器)。虽然linux系统传统上启动于文本模式,现在大多数发行版本都使用了内核
参数和临时的图形显示机制(开机画面例如plymouth)去完全地隐藏文本模式当系统启动时候。在这种情况下,系统在启动接近尾声的时候转化为完全的图形界面。

linux支持虚拟控制台去多路传输显示。每个虚拟控制台都可能运行于图形或者文本模式。当在文本模式的时候,你可以通过alt+function的组合按键——例如,alt+F1是使用/dev/tty1,
等等。其中getty进程占有这很多终端,直到你进行登陆。在7.4中详细阐述getty和登陆。

一个虚拟控制台被X server 以图形模式使用是有点不同的。不是从初始化配置中获取一个虚拟控制台分配,一个X server 接管一个空闲的虚拟控制台除非指定使用一个特别的虚拟控制台。举个例子,如果你已经使用getty 进程运行在tty1 和tty2 上,一个新的X server 会接管tty3.补充说,在X server 放置了一个虚拟控制台到图形模式上,你必须自然按下CRTL + ALT + 功能键的组合去转换到另一个虚拟控制台而不是使用更简单的alt+function组合键。

3.4.5 串口:/dev/ttyS*

老式的RS-232 和相似串口是特别的终端设备。你对于一台串口设备不能在在命令行上坐很多,因为你要担心很多的设置问题,例如波特率,和流动控制。

例如windows中我们知道的端口com1 /dev/tty S0;Com2 是/dev/ttyS1;等等。插入型USB
适配器显示带有/dev/ttyUSB0、/dev/ttyACM0、/dev/ttyUSB1、/dev/ttyACM1等名称的USB和ACM。

3.4.6 并行端口:/dev/lp0和/dev/lp1

展示一个接口类型大部分被usb取代,单行的端口设备/dev/jp0 和/dev/lp1 对应LPT1 ,LPT2
在Windows。你能够发送文件(例如一个文件可以被打印)知道到一个单行端口,通过cat命令,但你需要给你的输出一个额外形式的反馈或者随后复位。一个打印机服务就像CUPS是更好交互于打印机。双向并行端口是/dev/parport0和/dev/parport1。

3.4.7 音频设备: /dev/snd/*, /dev/dsp, /dev/audi,更多

linux有两种音频设备。对于Advanced Linux Sound Architecture (ALSA) 系统接口和老的
Open Sound System(OSS)。这个ALSA设备在dev/snd/目录,很难直接作用于它。linux使用了ALSA支持和OSS向后兼容设备如果OSS 内核支持现在加载。
一些简单操作可能用于到OSS dsp和音频设备上。举个例子,电脑播放wav文件你发送到/dev/dsp中的。然而,硬件可能不像你预想那般执行,因为频繁的匹配错误,还有,
在大部分系统中,这个设备你一旦登陆它就繁忙。
注解:
linux声音是一个复杂的问题因为包含了很多层次,我们只需要谈论关于内核层次设备,但往往有用户空间服务器像插入—音频 管理音频来自于不同的源然后扮演一个

3.4.8 创建设备文件

在现代的linux 系统中,你不需要创建你自己的设备文件。这是由devtmpfs 和 udev。(3.5 udev)。然而,看看它曾经了是怎么工作的,而且在一些很稍有的状态下,你可能需要创建一个命名管道。
mknod命令创建一个设备。你必须知道它的主设备号和从设备号。举个例子,创建/dev/sda1 使用下面的命令:

# mknod /dev/sda1 b 8 2

这个b 8 2指定了一个块设备有主设备号8和从设备号2。对于字符或者命名管道设备,使用c或者p而不是b(忽略管道设备的主设备和从设备号)

就之前阐述的,mknod命令只对于创建临时的命名管道,一度,它也有用于创建丢失的设备在但用户模式下的系统恢复。

在之前的老版本的Unix 和Linux 下,维持/dev 目录是一种挑战。每一个总要的内核升级或者驱动添加,内核能够支持更多种类的设备,意味着会有一种新的主设备号和从设备号指向设备文件名。维持这一点很难,所以各个系统都有一个makedev在/dev中去创建一组设备。当你升级你的系统,你会努力去找到一个对makedev的升级,然后运行它去创建新的设备。

这个静态系统变得笨拙,所以应该换一个。第一次尝试去固定它就是devfs,一个内核空间实施的/fev包含所有的设备现在的内核支持。然而,有一堆显示,这导致了udev和devtmpfs的发展。

3.5 udev

我们已经讨论了内核不必要的复杂性是很危险的,因为你能够很容易介绍系统的不稳定。设备文件管理是一个例子:你能创建设备文件在用户空间,所以为什么你在内核干这些?内核能发送通知到用户空间进程(称为udevd)当检测一个新设备在系统中(举个例子,当有人使用USB flash 驱动)。其他用户空间进程在检测了新的设备特性,创建一个设备文件,然后执行任何设备初始化。

那就是理论。不幸的是,实际中,这个方法有一个问题——设备文件在启动之前会需要。所以udevd必须早点开始。要创建一个设备文件,udevd不能依赖于任何设备它应该创造,然后它会需要去执行它出事的安装很快所以系统的其他的部分不会因为udvd的启动而延迟。
注释:
udev (userspace /dev) is a device manager for the Linux kernel. As the successor of devfsd and hotplug, udev primarily manages device nodes in the /dev directory.
udev (在用户空间/dev中)是一个内核的设备管理者。作为devfsd和hotplug的继承者,udev主要管理设备结点在/dev目录中。

3.5.1 devtmpfs

devtmfs文件系统发展去响应设备实用性在启动的过程(在4.2文件系统查看更多细节)。文件系统就像之前的devfs支持一样,但它简单了点。内核必要的时候创建设备文件,但它也通知udevd一个新设备已经可用了。一收到这个信号,udevd不会创建设备文件,但它执行了设备初始化和过程通知。此外,它在/dev中创建一堆符号链去进一步识别设备。你能发现在目录/dev/disk/by-id的例子,每一个里面都连上一次磁盘或者更多实体。

举个例子,考虑以下的磁盘:
lrwxrwxrwx 1 root root 9 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WDWMAV2FU80671 -> …/…/sda
lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WDWMAV2FU80671-part1 ->
…/…/sda1
lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WDWMAV2FU80671-part2 ->
…/…/sda2
lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WDWMAV2FU80671-part5 ->
…/…/sda5
udevd 命名链接通过接口类型,然后通过制造商和莫名信息,和串数字和分区(如果应用了)
但udevd怎么知道符号链被创建了,然后它怎么创建他们?下一段描述了udevd怎么做它的工作。然而,然而,你不需要知道这些就可以继续看这本书。事实上,如果这是你第一次查看linux 设备,你最好跳到下一张去学习怎么使用磁盘。
注解:
devtmpfs is a file system with automated device nodes populated by the kernel. This means you don’t have to have udev running nor to create a static /dev layout with additional, unneeded and not present device nodes. Instead the kernel populates the appropriate information based on the known devices.
devtmpfs 是一个文件系统用于自动化设备结点内核中大量使用。着意味着你不是一定要让udev运行或者不去创建一个/static/dev布局添加,不需要不呈现一个设备结点,除非内核大量使用了适合的信息基于知道的设备。

未晚待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值