设为首页 加入收藏

TOP

Linux工作原理3设备(一)
2023-07-23 13:29:49 】 浏览:99
Tags:Linux 设备

本章是对正常运行的Linux系统中内核提供的设备基础设施的基本考察。纵观Linux的历史,在内核如何向用户展示设备方面已经有了许多变化。我们将从传统的设备文件系统开始,看看内核如何通过sysfs提供设备配置信息。我们的目标是能够提取系统中的设备信息,以便了解一些基本的操作。后面的章节将更详细地介绍与特定类型设备的交互。
了解当出现新设备时,内核如何与用户空间进行交互是很重要的。udev系统使用户空间的程序能够自动配置和使用新设备。你将看到内核如何通过udev向用户空间进程发送消息的基本工作原理,以及该进程如何处理这些消息。

3.1 设备文件

操作Unix系统中的大多数设备是很容易的,因为内核将许多设备的I/O接口以文件形式呈现给用户进程。这些设备文件有时被称为设备节点。除了程序员使用常规的文件操作来处理设备外,一些设备也可以被像cat这样的标准程序访问。然而,你能用文件接口做的事情是有限的,所以不是所有的设备或设备功能都能用标准的文件I/O访问。

设备文件在/dev目录下,运行ls /dev可以看到/dev中的相当多的文件。那么,你是如何处理设备的呢?


$ echo blah blah > /dev/null

就像其他带有重定向输出的命令一样,这个命令将标准输出中的内容发送到文件中。然而,这个文件是/dev/null,是一个设备,所以内核绕过了通常的文件操作,对写入这个设备的数据使用了设备驱动程序。在/dev/null的情况下,内核只是接受了输入的数据并将其丢弃。
要识别一个设备并查看其权限,可以使用ls -l。下面是一些例子:

$ ls -l
brw-rw---- 1 root disk 8, 1 Sep 6 08:37 sda1
crw-rw-rw- 1 root root 1, 3 Sep 6 08:37 null
prw-r-r-- 1 root root 0 Mar 3 19:17 fdata
srw-rw-rw- 1 root root 0 Dec 18 07:43 log

注意每一行的第一个字符(文件模式的第一个字符)。如果这个字符是b、c、p或s,则该文件是一个设备。这些字母分别代表块、字符、管道和套接字:

  • 块设备
    程序以固定的块来访问块设备的数据。前面例子中的sda1是一个磁盘设备,是块设备的一种类型。磁盘可以很容易地被分割成数据块。因为块设备的总大小是固定的,并且容易索引,程序在内核的帮助下可以快速随机访问设备中的任何块。

  • 字符设备
    字符设备与数据流一起工作。你只能从字符设备中读取字符或向字符设备中写入字符,就像前面用/dev/null演示的那样。字符设备没有大小之分;当你从设备中读出或写入时,内核通常对它进行读或写操作。直接连接到你的计算机上的打印机是由字符设备表示的。值得注意的是,在字符设备的交互过程中,内核在将数据传递给设备或进程后,不能备份和重新检查数据流。

  • 管道设备
    命名的管道就像字符设备,在I/O流的另一端是另一个进程,而不是内核驱动。

  • 套接字设备
    套接字是特殊用途的接口,经常用于进程间通信。它们经常在/dev目录之外被发现。套接字文件代表Unix域套接字;你将在第10章中了解更多关于这些套接字的信息。
    在来自ls -l的块和字符设备的文件列表中,日期前面的数字是主要和次要的设备号,内核用它来识别设备。类似的设备通常有相同的主设备号,比如sda3和sdb1(都是硬盘分区)。

注意
不是所有的设备都有设备文件,因为块和字符设备的I/O接口不是在所有情况下都合适。例如,网络接口没有设备文件。理论上,使用单一的字符设备与网络接口交互是可能的,但是由于这很困难,内核提供了其他的I/O接口。

3.2 sysfs设备路径

传统的Unix的/dev目录是一种方便的方式,用户进程可以引用和连接内核支持的设备,但这也是一种非常简单的方案。在/dev中的设备名称告诉你关于该设备的一些情况,但通常不够有用。另一个问题是,内核是按照找到设备的顺序来分配设备的,所以设备在重启之间可能有不同的名字。

为了提供基于实际硬件属性的附加设备的统一视图,Linux内核通过文件和目录系统提供sysfs接口。设备的基本路径是/sys/devices。例如,位于/dev/sda的SATA硬盘在sysfs中可能有如下路径:


/sys/devices/pci0000:00/0000:00:17.0/ata3/host0/target0:0:0/0:0:0:0/block/sda

你可以看到,与/dev/sda文件名相比,这个路径相当长,它也是一个目录。但你不能真正比较这两个路径,因为它们有不同的目的。/dev文件使用户进程能够使用设备,而/sys/devices路径是用来查看信息和管理设备的。如果你列出设备路径的内容,比如前面的那个,你会看到类似下面的内容:


alignment_offset  discard_alignment  holders   removable  size       uevent
bdi               events             inflight  ro         slaves
capability        events_async       power     sda1       stat
dev               events_poll_msecs  queue     sda2       subsystem
device            ext_range          range     sda5       trace

这里的文件和子目录主要是供程序而不是人阅读的,但是你可以通过查看/dev文件这样的例子来了解它们包含和代表的内容。在这个目录下运行cat dev会显示数字8:0,这恰好是/dev/sda的主设备号和次设备号。
在/sys目录下有一些快捷方式。例如,/sys/block应该包含一个系统上所有可用的块设备。然而,这些只是符号链接;你应该运行ls -l /sys/block来显示真正的sysfs路径。
要在/dev中找到一个设备的sysfs位置可能很困难。使用如下的udevadm命令来显示路径和其他一些有趣的属性:


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

你会在第3.5节找到更多关于udevadm和整个udev系统的细节。

3.3 dd和设备

当你在处理块和字符设备时,dd程序是非常有用的。它的唯一功能是从输入文件或流中读出,然后写到输出文件或流中,在这个过程中可能会进行一些编码转换。对于块设备来说,dd的特别有用的功能是,你可以在文件的中间处理一大块数据,而忽略之前或之后的内容。

警告:
dd的功能非常强大,所以当你运行它时,请确保你知道你在做什么。如果不小心犯了错误,很容易损坏设备上的文件和数据。如果你不确定它将会做什么,通常可以将输出写入一个新的文件。
dd以固定大小的块复制数据。下面是如何在字符设备上使用dd,利用一些常见的选项:


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

正如你所看到的,dd的选项格式与大多数其他Unix命令的选项格式不同;它是基于旧的IBM工作控制语言(JCL)风格。你不是用破折号(-)来表示一个选项,而是用等号(=)来命名一个选项并设置其值。前面的例子从/dev/zero复制了一个1,024字节的块(一个连续的零字节流)到new_file。
这些是重要的dd选项:

  • if=file 输入文件。默认是标准输入。
  • of=file 输出文件。默认是标准输出。
  • bs=s
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇INFINI Labs 产品更新 | Console .. 下一篇shell 常用命令3

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目