Linux工作原理3设备|看点
本章是对正常运行的Linux系统中内核提供的设备基础设施的基本考察。纵观Linux的历史,在内核如何向用户展示
2023-05-31本章是对正常运行的Linux系统中内核提供的设备基础设施的基本考察。纵观Linux的历史,在内核如何向用户展示设备方面已经有了许多变化。我们将从传统的设备文件系统开始,看看内核如何通过sysfs提供设备配置信息。我们的目标是能够提取系统中的设备信息,以便了解一些基本的操作。后面的章节将更详细地介绍与特定类型设备的交互。了解当出现新设备时,内核如何与用户空间进行交互是很重要的。udev系统使用户空间的程序能够自动配置和使用新设备。你将看到内核如何通过udev向用户空间进程发送消息的基本工作原理,以及该进程如何处理这些消息。
(相关资料图)
操作Unix系统中的大多数设备是很容易的,因为内核将许多设备的I/O接口以文件形式呈现给用户进程。这些设备文件有时被称为设备节点。除了程序员使用常规的文件操作来处理设备外,一些设备也可以被像cat这样的标准程序访问。然而,你能用文件接口做的事情是有限的,所以不是所有的设备或设备功能都能用标准的文件I/O访问。
设备文件在/dev目录下,运行ls /dev可以看到/dev中的相当多的文件。那么,你是如何处理设备的呢?
$ echo blah blah > /dev/null就像其他带有重定向输出的命令一样,这个命令将标准输出中的内容发送到文件中。然而,这个文件是/dev/null,是一个设备,所以内核绕过了通常的文件操作,对写入这个设备的数据使用了设备驱动程序。在/dev/null的情况下,内核只是接受了输入的数据并将其丢弃。要识别一个设备并查看其权限,可以使用ls -l。下面是一些例子:
$ ls -lbrw-rw---- 1 root disk 8, 1 Sep 6 08:37 sda1crw-rw-rw- 1 root root 1, 3 Sep 6 08:37 nullprw-r-r-- 1 root root 0 Mar 3 19:17 fdatasrw-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接口。
传统的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 ueventbdi events inflight ro slavescapability events_async power sda1 statdev events_poll_msecs queue sda2 subsystemdevice 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系统的细节。
当你在处理块和字符设备时,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选项:
有时很难找到设备的名称(例如,在给磁盘分区时)。这里有几个方法可以找出它是什么:
用udevadm查询udevd(见第3.5节)。
在/sys目录下寻找设备。
从journalctl -k命令(打印内核信息)或内核系统日志(见第7.1节)的输出中猜测其名称。这个输出可能包含了对你系统中设备的描述。
对于系统已经可见的磁盘设备,你可以检查mount命令的输出。
运行cat /proc/devices来查看你的系统目前有驱动的块和字符设备。每一行都包括编号和名称。数字是设备的主要编号,如第3.1节所述。如果你能从名称中猜出设备,在/dev中寻找具有相应主要编号的字符或块设备,你就找到了设备文件。
在这些方法中,只有第一个方法是可靠的,但它确实需要udev。如果你遇到udev不可用的情况,可以尝试其他方法,但要记住,内核可能没有适合你的硬件的设备文件。下面的章节列出了最常见的Linux设备和它们的命名规则。
大多数连接到当前Linux系统的硬盘对应于带有sd前缀的设备名,比如/dev/sda,/dev/sdb,等等。这些设备代表整个磁盘;内核为磁盘上的分区制作单独的设备文件,如/dev/sda1和/dev/sda2。这个命名规则需要解释一下。名称中的sd部分代表SCSI磁盘。小型计算机系统接口(SCSI)最初是作为一种硬件和协议标准开发的,用于磁盘和其他外围设备等设备之间的通信。虽然传统的SCSI硬件在大多数现代机器中没有使用,但由于SCSI协议的适应性,它无处不在。例如,USB存储设备使用它进行通信。SATA(串行ATA,PC上常见的存储总线)磁盘上的情况要复杂一些,但Linux内核在与它们交谈时,仍然在一定程度上使用SCSI命令。要列出你系统上的SCSI设备,可以使用一个工具来行走由sysfs提供的设备路径。其中一个最简洁的工具是lsscsi。当你运行它时,你可以看到以下内容:
$ lsscsi[0:0:0:0]1 disk2 ATA WDC WD3200AAJS-2 01.0 /dev/sda3[2:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdb第一列标识了系统中设备的地址,第二列描述了它是什么类型的设备,最后一列3出在哪里可以找到设备文件。其他的都是厂商信息。Linux按照其驱动程序遇到设备的顺序将设备分配给设备文件。所以,在前面的例子中,内核首先找到了磁盘,其次才是闪存驱动器。不幸的是,当你重新配置硬件时,这种设备分配方案历来会引起问题。举例来说,你有一个有三个磁盘的系统: /dev/sda,/dev/sdb,和/dev/sdc。如果/dev/sdb爆炸了,你必须把它移走,以便机器能够重新工作,那么以前的/dev/sdc就会移到/dev/sdb上,而不再有/dev/sdc了。如果你直接参考fstab文件中的设备名称(见第4.2.8节),你就必须对该文件做一些修改,以便使事情(大部分)恢复正常。为了解决这个问题,许多Linux系统使用通用唯一标识符(UUID;见第4.2.4节)和/或逻辑卷管理器(LVM)来稳定磁盘设备映射。关于如何在Linux系统上使用磁盘和其他存储设备,本文的讨论几乎没有触及表面。关于使用磁盘的更多信息,见第4章。在本章的后面,我们将研究SCSI支持在Linux内核中是如何工作的。
一些磁盘设备为虚拟机进行了优化,如AWS实例和VirtualBox。Xen虚拟化系统使用/dev/xvd前缀,而/dev/vd是一种类似的类型。
一些系统现在使用非易失性内存快车(NVMe)接口来与某些类型的固态存储进行对话。在Linux中,这些设备显示在/dev/nvme*。你可以使用nvme list命令来获得你系统上这些设备的列表。
在一些系统上,比磁盘和其他直接块存储更高级别的是LVM,它使用一个叫做设备映射器的内核系统。如果你看到以/dev/dm-开头的块设备和/dev/mapper的符号链接,你的系统可能使用了它。你将在第4章中了解这一切。
Linux将大多数光存储驱动器识别为SCSI设备/dev/sr0、/dev/sr1,等等。然而,如果驱动器使用旧的接口,它可能会显示为一个PATA设备,如下所述。/dev/sr*设备是只读的,它们只用于从磁盘上读取。对于光学设备的写入和重写能力,你将使用 "通用 "SCSI设备,如/dev/sg0。
PATA(Parallel ATA)是一种较早的存储总线。Linux块设备/dev/hda、/dev/hdb、/dev/hdc和/dev/hdd在旧版本的Linux内核和旧硬件上很常见。这些是基于接口0和1的设备对的固定分配。 有时,你可能会发现SATA驱动器被识别为这些磁盘之一。这意味着该SATA驱动器在兼容模式下运行,这阻碍了性能。检查你的BIOS设置,看看你是否可以将SATA控制器切换到其原始模式。
终端是在用户进程和I/O设备之间移动字符的设备,通常用于向终端屏幕输出文字。终端设备接口可以追溯到很久之前,当时的终端是基于打字机的设备,很多都是连接在一台机器上的。大多数终端是伪终端设备,是理解真正终端的I/O特性的仿真终端。内核不是与真正的硬件对话,而是将I/O接口呈现给软件,例如你可能在其中输入大部分命令的shell终端窗口。两个常见的终端设备是/dev/tty1(第一个虚拟控制台)和/dev/pts/0(第一个伪终端设备)。/dev/pts目录本身是一个专门的文件系统。/dev/tty设备是当前进程的控制终端。如个程序当前正在从终端读写,这个设备就是该终端的同义词。进程不需要连接到终端。
Linux有两种主要的显示模式:文本模式和图形模式(第14章介绍了使用这种模式的窗口系统)。尽管Linux系统传统上是以文本模式启动的,但现在大多数发行版使用内核参数和临时图形显示机制(bootsplashes,如plymouth)来完全隐藏系统启动时的文本模式。在这种情况下,系统会在启动过程接近尾声时切换到全图形模式。Linux支持虚拟控制台来复用显示。每个虚拟控制台可以在图形或文本模式下运行。当处于文本模式时,你可以通过ALT功能键组合在控制台之间进行切换--例如,ALT-F1会带你到/dev/tty1,ALT-F2会到/dev/tty2,以此类推。许多这样的虚拟控制台可能被运行登录提示的getty进程所占据,如第7.4节所述。
在图形模式下使用的虚拟控制台略有不同。除非被指示使用一个特定的虚拟控制台,否则图形环境会接管空闲的虚拟控制台,而不是从初始配置中获得一个虚拟控制台的分配。例如,如果你有getty进程在tty1和tty2上运行,新的图形环境会占用tty3。此外,一旦进入图形模式,你通常必须按CTRL-ALT-功能键组合来切换到另一个虚拟控制台,而不是更简单的ALT-功能键组合。所有这些的结果是,如果你想在系统启动后看到你的文本控制台,按CTRL-ALT-F1。要返回到图形环境,按ALT-F2、ALT-F3,以此类推,直到你进入图形环境。
注意:有些发行版在图形模式下使用tty1。在这种情况下,你将需要尝试其他控制台。
如果你在切换控制台时由于输入机制的故障或其他情况而遇到麻烦,你可以尝试用chvt命令强迫系统改变控制台。例如,要切换到tty1,以root身份运行以下命令:
# chvt 1较早的RS-232类型和类似的串行端口被表示为真正的终端设备。你不能在命令行上对串口设备做很多事情,因为有太多的设置需要担心,比如波特率和流量控制,但是你可以使用screen命令,通过添加设备路径作为参数来连接到终端。你可能需要该设备的读写权限;有时你可以通过将自己添加到特定的组(如dialout)来实现。在Windows上被称为COM1的端口是/dev/ttyS0;COM2是/dev/ttyS1;以此类推。插入式USB串行适配器显示为USB和ACM,名称为/dev/ttyUSB0、/dev/ttyACM0、/dev/ttyUSB1、/dev/ttyACM1,等等。一些涉及到串行端口的最有趣的应用是基于微控制器的板子,你可以把它插入你的Linux系统进行开发和测试。例如,你可以通过USB串行接口访问CircuitPython板的控制台和读-评-印循环。你所需要做的就是插上一个,寻找设备(通常是/dev/ttyACM0),然后用屏幕连接到它。
单向并口设备/dev/lp0和/dev/lp1代表着一种接口类型,在很大程度上已经被USB和网络所取代,在Windows中对应于LPT1:和LPT2:。你可以用cat命令将文件(如要打印的文件)直接发送到并口,但你可能需要在之后给打印机一个额外的进纸或复位。像CUPS这样的打印服务器在处理与打印机的交互方面要好得多。双向的并行端口是/dev/parport0和/dev/parport1。
Linux有两套音频设备。有独立的设备用于高级Linux声音架构(ALSA)系统接口和较早的开放声音系统(OSS)。ALSA设备在/dev/snd目录下,但很难直接使用它们。使用ALSA的Linux系统支持OSS的后向兼容设备,如果目前加载了OSS的内核支持。对OSS的dsp和音频设备可以进行一些基本的操作。例如,计算机会播放你发送到/dev/dsp的任何WAV文件。然而,由于频率不匹配,硬件可能做不到你期望的那样。此外,在大多数系统上,该设备往往在你登录后就开始忙碌。
注意:由于涉及到许多层次,Linux的声音是一个混乱的主题。我们只谈了内核级的设备,但通常还有用户空间的服务器,如 pulseaudio,管理来自不同来源的音频,作为声音设备和其他用户空间进程之间的中介。
在任何合理的最近的Linux系统上,你都不会创建自己的设备文件;它们是由devtmpfs和udev创建的(见第3.5节)。然而,看看如何创建设备文件是很有意义的,在罕见的情况下,你可能需要创建命名的管道或套接字文件。mknod命令创建设备。你必须知道设备的名称以及它的主号和次号。例如,创建/dev/sda1只需使用下面的命令:
# mknod /dev/sda1 b 8 1b 8 1指定了一个主数为8、次数为1的块设备。对于字符或命名的管道设备,使用c或p而不是b(对于命名的管道,省略主要和次要数字)。在旧版本的Unix和Linux中,维护/dev目录是一个挑战。随着每一次重要的内核升级或驱动程序的增加,内核可以支持更多种类的设备,这意味着将有一组新的主要和次要数字被分配给设备文件名。为了解决这个维护难题,每个系统都有一个MAKEDEV程序,在/dev中创建设备组。当你升级你的系统时,你将试图找到MAKEDEV的更新,然后运行它以创建新的设备。这个静态的系统变得很难看,所以一个替换是必要的。解决这个问题的第一个尝试是devfs,一个内核空间的/dev实现,包含了当前内核支持的所有设备。然而,有一些限制,这导致了udev和devtmpfs的发展。
我们已经谈到了内核中不必要的复杂性是很危险的,因为你太容易引入系统的不稳定性。设备文件管理就是一个例子:你可以在用户空间创建设备文件,那么你为什么要在内核中这样做?Linux内核可以在检测到系统中的新设备时(例如,当有人安装了U盘时)向udevd的用户空间进程发送通知。这个udevd进程可以检查新设备的特性,创建设备文件,然后执行任何设备初始化。
注意:你几乎肯定会看到udevd以systemd-udevd的形式在你的系统上运行,因为它是你将在第六章看到的启动机制的一部分。
这就是理论。不幸的是,这种方法有一个问题--设备文件在启动过程的早期是必需的,所以udevd也必须提前启动。但是为了创建设备文件,udevd不能依赖于任何它应该创建的设备,它需要非常快速地执行其初始启动,这样系统的其他部分就不会因为等待udevd的启动而被耽搁。
devtmpfs文件系统是为了解决启动过程中的设备可用性问题而开发的(关于文件系统的更多细节,见第4.2节)。这个文件系统类似于较早的devfs支持,但有所简化。内核在必要时创建设备文件,但它也会通知udevd新的设备是可用的。收到这个信号后,udevd不会创建设备文件,但它会执行设备初始化,同时设置权限并通知其他进程新设备可用。此外,它在/dev中创建一些符号链接,以进一步识别设备。你可以在/dev/disk/by-id目录下找到例子,每个连接的磁盘都有一个或多个条目。
例如,考虑典型的磁盘(连接在/dev/sda)和它在/dev/disk/by-id中的分区的链接:
$ ls -l /dev/disk/by-idlrwxrwxrwx 1 root root 9 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671 -> ../../sdalrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part1 ->../../sda1lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part2 ->../../sda2lrwxrwxrwx 1 root root 10 Jul 26 10:23 scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671-part5 ->../../sda5udevd进程按接口类型命名链接,然后按制造商和型号信息、序列号和分区(如果适用)命名。
注意:devtmpfs中的 "tmp "表示文件系统驻留在主内存中,具有用户空间进程的读/写能力;这个特性使udevd能够创建这些符号链接。我们将在第4.2.12节看到更多细节。
但udevd如何知道要创建哪些符号链接,以及如何创建它们?下一节将描述udevd是如何工作的。然而,你不需要知道这些或本章中的任何其他材料来继续阅读本书。事实上,如果这是你第一次研究Linux设备,我们强烈建议你跳到下一章,开始学习如何使用磁盘。
udevd守护进程的运作方式如下:
ACTION=changeDEVNAME=sdeDEVPATH=/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.2/1-1.2:1.0/host4/target4:0:0/4:0:0:3/block/sdeDEVTYPE=diskDISK_MEDIA_CHANGE=1MAJOR=8MINOR=64SEQNUM=2752SUBSYSTEM=blockUDEV_LOG=3这个特殊的事件是对设备的改变。在接收到uevent后,udevd知道了设备的名称、sysfs设备路径和其他一些与属性相关的属性;它现在准备开始处理规则。规则文件在/lib/udev/rules.d和/etc/udev/rules.d目录下。/lib中的规则是默认的,而/etc中的规则是重写的。对规则的全面解释会很乏味,你可以从udev(7)手册中了解更多,但这里有一些关于udevd如何读取规则的基本信息:
让我们看一下第3.5.1节中/dev/sda例子中的符号链接。这些链接是由/lib/udev/rules.d/60-persistent-storage.rules中的规则定义的。在里面,你会看到以下几行:
# ATAKERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", IMPORT{program}="ata_id --export $devnode"# ATAPI devices (SPC-3 or later)KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}=="5",ATTRS{scsi_level}=="[6-9]*", IMPORT{program}="ata_id --export $devnode"这些规则与通过内核的SCSI子系统(见第3.6节)呈现的ATA磁盘和光学介质相匹配。你可以看到有一些规则来捕捉设备可能的不同表现方式,但想法是udevd将尝试匹配以sd或sr开头但没有数字的设备(用KERNEL"sd[!0-9]|sr"表达式),以及子系统(SUBSYSTEMS"scsi"),最后还有一些其他属性,取决于设备的类型。如果所有这些条件表达式在任何一条规则中都为真,udevd就会转到下一个也是最后表达式:
IMPORT{program}="ata_id --export $tempnode"这不是一个条件。相反,它是一个指令,从/lib/udev/ata_id命令中导入变量。如果你有这样一个磁盘,自己在命令行上试试。它看起来会像这样:
# /lib/udev/ata_id --export /dev/sdaID_ATA=1ID_TYPE=diskID_BUS=ataID_MODEL=WDC_WD3200AAJS-22L7A0ID_MODEL_ENC=WDC\x20WD3200AAJS22L7A0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20ID_REVISION=01.03E10ID_SERIAL=WDC_WD3200AAJS-22L7A0_WD-WMAV2FU80671--snip--现在,导入设置了环境,使这个输出中的所有变量名都被设置为所示的值。例如,接下来的任何规则现在都会将 ENV{ID_TYPE} 识别为磁盘。
在我们到目前为止看到的两条规则中,特别值得注意的是ID_SERIAL。在每条规则中,这个条件都出现在第二条:
env{id_serial}!="?*"如果ID_SERIAL没有被设置,这个表达式会评估为真。因此,如果ID_SERIAL被设置了,条件就是假的,整个当前规则就不适用,udevd就会转到下一条规则。为什么会出现在这里?这两条规则的目的是运行ata_id来查找磁盘设备的序列号,然后将这些属性添加到uevent的当前工作副本中。你会在许多udev规则中发现这个一般模式。设置了ENV{ID_SERIAL}后,udevd现在可以在后面的规则文件中评估这个规则,它寻找任何连接的SCSI磁盘:
KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*",SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"你可以看到,这条规则要求ENV{ID_SERIAL}被设置,它有一个指令:
SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"这个指令告诉udevd为进入的设备添加一个符号链接。所以,现在你知道设备的符号链接是怎么来的了!你可能想知道如何区分条件表达式和指令。条件表达式用两个等号(==)或砰的一声等号(!=)表示,指令用一个等号(=)、一个加号(+=)或一个冒号等号(:=)表示。
udevadm程序是udevd的管理工具。 你可以重新加载udevd规则和触发事件,但udevadm最强大的功能可能是搜索和探索系统设备的能力,以及udevd从内核接收uevent时监控uevent的能力。不过,命令的语法可能有点儿复杂。大多数选项都有长短两种形式,我们在这里使用长的。让我们从检查一个系统设备开始。回到第3.5.2节中的例子,为了查看所有的udev属性,以及与/dev/sda这样的设备的规则一起生成的属性,运行以下命令:
$ udevadm info --query=all --name=/dev/sdaP: /devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sdaN: sdaS: disk/by-id/ata-WDC_WD3200AAJS-22L7A0_WD-WMAV2FU80671S: disk/by-id/scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671S: disk/by-id/wwn-0x50014ee057faef84S: disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0E: DEVLINKS=/dev/disk/by-id/ata-WDC_WD3200AAJS-22L7A0_WD-WMAV2FU80671 /dev/disk/by-id/scsi-SATA_WDC_WD3200AAJS-_WD-WMAV2FU80671 /dev/disk/by-id/wwn-0x50014ee057faef84 /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0E: DEVNAME=/dev/sdaE: DEVPATH=/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sdaE: DEVTYPE=diskE: ID_ATA=1E: ID_ATA_DOWNLOAD_MICROCODE=1E: ID_ATA_FEATURE_SET_AAM=1--snip--每行的前缀表示设备的一个属性或其他特征。在这个例子中,顶部的P:是sysfs设备路径,N:是设备节点(也就是给/dev文件起的名字),S:表示udevd根据其规则放在/dev中的设备节点的符号链接,E:是udevd规则中提取的额外设备信息。(这个例子中的输出远远超过了这里需要展示的内容;自己尝试一下这个命令,感受一下它的作用)。
要用udevadm监视uevents,请使用monitor命令:
$ udevadm monitorKERNEL[658299.569485] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)KERNEL[658299.569667] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)KERNEL[658299.570614] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host15 (scsi)KERNEL[658299.570645] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/ host15/scsi_host/host15 (scsi_host)UDEV [658299.622579] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)UDEV [658299.623014] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)UDEV [658299.623673] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host15 (scsi)UDEV [658299.623690] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/host15/scsi_host/host15 (scsi_host)--snip--在这个输出中,每条信息都有两份,因为默认行为是同时打印来自内核的传入信息(用KERNEL标记)和来自udevd的处理信息。 要想只看到内核事件,请添加--kernel选项,要想只看到udevd处理事件,请使用--udev。要看到整个传入的uevent,包括3.5.2节中显示的属性,使用--property选项。--udev和--property选项一起显示处理后的uevent。你还可以按子系统过滤事件。例如,要想只看到与SCSI子系统的变化有关的内核信息,使用这个命令:
$ udevadm monitor --kernel --subsystem-match=scsi关于udevadm的更多信息,请看udevadm(8)手册页。udev的内容还有很多。例如,有一个叫做udisksd的守护进程,它监听事件,以便自动连接磁盘,并通知其他进程有新的磁盘可用。
在这一节中,我们将看一下Linux内核中的SCSI支持,作为探索Linux内核结构的一部分。你不需要为了使用磁盘而了解这些信息,所以如果你急于使用磁盘,请继续阅读第四章。此外,这里的材料比你到目前为止所看到的更高级,更具有理论性,所以如果你想保持动手能力,你肯定应该跳到下一章。让我们从一点背景开始。传统的SCSI硬件设置是一个主机适配器通过SCSI总线与一连串的设备相连,如图3-1所示。主机适配器被连接到计算机上。主机适配器和设备都有一个SCSI ID,根据SCSI版本,每条总线可以有8或16个ID。一些管理员可能会用SCSI目标这个词来指代设备和它的SCSI ID,因为在SCSI协议中,会话的一端被称为目标。
图3-1:带有主机适配器和设备的SCSI总线
任何设备都可以通过SCSI命令集以点对点的关系与另一个设备进行通信。计算机没有直接连接到设备链上,所以它必须通过主机适配器才能与磁盘和其他设备通信。通常情况下,计算机向主机适配器发送SCSI命令以转达给设备,而设备则通过主机适配器转达响应。较新版本的SCSI,如串行连接SCSI(SAS),提供了卓越的性能,但你可能不会在大多数机器中找到真正的SCSI设备。你会更经常地遇到使用SCSI命令的USB存储设备。此外,支持ATAPI的设备(如CD/DVD-ROM驱动器)使用SCSI命令集的一个版本。SATA磁盘也作为SCSI设备出现在你的系统上,但它们略有不同,因为它们中的大多数是通过libata库中的转换层进行通信的(见3.6.2节)。一些SATA控制器(特别是高性能的RAID控制器)在硬件中进行这种转换。这一切是如何组成的?考虑一下下面系统中显示的设备:
$ lsscsi[0:0:0:0]diskATAWDC WD3200AAJS-201.0/dev/sda[1:0:0:0]cd/dvdSlimtypeDVD A DS8A5SHXA15/dev/sr0[2:0:0:0]diskUSB2.0CardReader CF0100/dev/sdb[2:0:0:1]diskUSB2.0CardReader SM XD0100/dev/sdc[2:0:0:2]diskUSB2.0CardReader MS0100/dev/sdd[2:0:0:3]diskUSB2.0CardReader SD0100/dev/sde[3:0:0:0]diskFLASHDrive UT_USB200.00/dev/sdf方括号内的数字从左到右分别是SCSI主机适配器号、SCSI总线号、设备SCSI ID和LUN(逻辑单元号,是设备的进一步细分)。在这个例子中,有四个连接的适配器(scsi0、scsi1、scsi2和scsi3),每个都有个总线(都是总线号0),每个总线上只有一个设备(都是目标0)。位于2:0:0的USB读卡器有四个逻辑单元,但每一种闪存卡都可以被插入。内核给每个逻辑单元分配了一个不同的设备文件。尽管不是SCSI设备,NVMe设备有时会在lsscsi输出中显示出N作为适配器编号。注意:如果你想自己尝试lsscsi,你可能需要把它作为一个额外的软件包来安装。图3-2显示了这个特定系统配置的内核中的驱动和接口层次,从单个设备驱动到块驱动。它不包括SCSI通用(sg)驱动。尽管这是一个庞大的结构,一开始可能会让人不知所措,但是图中的数据流是非常线性的。让我们从SCSI子系统和它的三层驱动开始剖析:顶层处理一类设备的操作。例如,sd(SCSI磁盘)驱动程序就在这一层;它知道如何将来自内核块设备接口的请求翻译成SCSI协议中的磁盘特定命令,反之亦然。中间层在顶层和底层之间调节和路由SCSI信息,并跟踪所有的SCSI总线和连接到系统的设备。底层处理特定的硬件动作。这里的驱动程序向特定的主机适配器或硬件发送传出的SCSI协议信息,并从硬件提取传入的信息。与顶层分离的原因是,尽管SCSI消息对于一个设备类别(如磁盘类别)是统一的,但不同种类的主机适配器有不同的发送相同消息的程序。
图3-2: Linux SCSI子系统原理图上层和下层包含许多不同的驱动,但是重要的是要记住,对于你系统上的任何一个设备文件,内核(几乎总是)使用一个上层驱动和一个下层驱动。在我们的例子中,对于位于/dev/sda的磁盘,内核使用sd顶层驱动和ATA桥层驱动。有些时候,你可能会为一个硬件设备使用不止一个上层驱动(见第3.6.3节)。对于真正的硬件SCSI设备,比如连接到SCSI主机适配器或硬件RAID控制器的磁盘,下层驱动程序直接与下面的硬件对话。然而,对于你发现连接到SCSI子系统的大多数硬件来说,情况就不同了。
为了让SCSI子系统与普通的USB存储硬件对话,如图3-2所示,内核需要的不仅仅是一个低层的SCSI驱动。一个由/dev/sdf代表的U盘可以理解SCSI命令,但是为了和驱动器进行实际的通信,内核需要知道如何通过USB系统进行对话。从抽象的角度来看,USB与SCSI非常相似--它有设备类别、总线和主机控制器。因此,Linux内核包括一个与SCSI子系统非常相似的三层USB子系统也就不足为奇了,它的顶端是设备类驱动程序,中间是总线管理核心,底部是主机控制器驱动程序。与SCSI子系统在其组件之间传递SCSI命令一样,USB子系统在其组件之间传递USB信息。甚至还有一个lsusb命令,与lsscsi相似。我们在这里真正感兴趣的部分是顶部的USB存储驱动器。这个驱动充当了翻译者的角色。在一端,驱动程序说的是SCSI,而在另一端,它说的是USB。因为存储硬件在其USB信息中包含SCSI命令,所以驱动程序的工作相对容易:它主要是重新包装数据。有了SCSI和USB子系统,你几乎拥有了与闪存盘对话所需的一切。最后缺失的环节是SCSI子系统中的下层驱动,因为USB存储驱动是USB子系统的一部分,而不是SCSI子系统。(由于组织上的原因,这两个子系统不应该共享一个驱动。)为了使子系统能够相互交谈,一个简单的、低层的SCSI桥接驱动连接到USB子系统的存储驱动。
图3-2中的SATA硬盘和光驱都使用相同的SATA接口。为了将内核的SATA驱动连接到SCSI子系统,内核采用了一个桥接驱动,就像对待USB驱动器一样,但是有不同的机制和额外的复杂情况。光驱说的是ATAPI,这是ATA协议中编码的SCSI命令的一个版本。然而,硬盘不使用ATAPI,也不对任何SCSI命令进行编码!Linux内核使用一个叫做libata的库的一部分来调和SATA(和ATA)驱动器与SCSI子系统。对于讲ATAPI的光驱来说,这是一个相对简单的任务,即把SCSI命令打包并提取到ATA协议中去。但对硬盘来说,这项任务要复杂得多,因为库必须做一个完整的命令转换。光驱的工作类似于将一本英文书打入电脑。你不需要为了完成这项工作而理解书的内容,甚至也不需要理解英语。但硬盘的任务更像是阅读一本德语书,并将其作为英文翻译输入电脑。在这种情况下,你需要理解两种语言以及书中的内容。尽管有这样的困难,libata还是执行了这项任务,并使将ATA/SATA接口和设备连接到SCSI子系统成为可能。(除了图3-2中所示的一个SATA主机驱动程序外,通常还涉及更多的驱动程序,但为了简单起见,我们没有显示出来)。
当用户空间进程与SCSI子系统通信时,它通常是通过块设备层和/或其他位于SCSI设备类驱动(如sd或sr)之上的内核服务进行的。换句话说,大多数用户进程不需要知道任何关于SCSI设备或它们的命令。然而,用户进程可以绕过设备类驱动程序,通过其通用设备直接向设备发出SCSI协议命令。例如,考虑第3.6节中描述的系统,但这次,看看当你为lsscsi添加-g选项以显示通用设备时会发生什么:
$ lsscsi -g[0:0:0:0] disk ATA WDC WD3200AAJS-2 01.0 /dev/sda 1/dev/sg0[1:0:0:0] cd/dvd Slimtype DVD A DS8A5SH XA15 /dev/sr0 /dev/sg1[2:0:0:0] disk USB2.0 CardReader CF 0100 /dev/sdb /dev/sg2[2:0:0:1] disk USB2.0 CardReader SM XD 0100 /dev/sdc /dev/sg3[2:0:0:2] disk USB2.0 CardReader MS 0100 /dev/sdd /dev/sg4[2:0:0:3] disk USB2.0 CardReader SD 0100 /dev/sde /dev/sg5[3:0:0:0] disk FLASH Drive UT_USB20 0.00 /dev/sdf /dev/sg6除了通常的块设备文件外,每个条目在最后一列1中列出SCSI通用设备文件。例如,位于/dev/sr0的光驱的通用设备是/dev/sg1。为什么你想使用一个通用设备?答案是与内核中代码的复杂性有关。随着任务变得越来越复杂,最好把它们留在内核之外。考虑一下CD/DVD的写入和读取。读取光盘是相当简单的操作,而且有专门的内核驱动。然而,写光盘要比读光盘困难得多,而且没有关键的系统服务依赖于写光盘的操作。没有理由用这种活动来威胁内核空间。因此,要在Linux中写入光盘,你需要运行一个用户空间程序,与一个通用的SCSI设备对话,比如/dev/sg1。这个程序可能比内核驱动的效率低一些,但它更容易建立和维护。
图3-3展示了Linux SCSI子系统从用户空间访问光驱的两个点(sr和sg)(SCSI下层的任何驱动都被省略了)。进程A使用sr驱动从驱动器中读取,进程B使用sg驱动向驱动器写入。然而,像这样的进程通常不会同时运行来访问同一个设备。
图3-3:光学设备驱动原理图在图3-3中,进程A从块设备中读取数据。但是,用户进程真的会以这种方式读取数据吗?通常情况下,答案是否定的,不是直接的。在块设备上面还有更多的层,甚至还有更多的硬盘访问点,你将在下一章中学习。
标签:
本章是对正常运行的Linux系统中内核提供的设备基础设施的基本考察。纵观Linux的历史,在内核如何向用户展示
2023-05-31
00:45定州园建筑为宋代风格,讲述宋朝诗人苏轼和黑龙泉的故事,以宋代画作中的山水关系布局建筑特征以及活
2023-05-31
5月30日,猿辅导推出旗舰型产品小猿学练机,正式入局智能学习设备市场,以封闭式系统、类纸墨水屏、数字化
2023-05-31
想必现在有很多小伙伴对于申鉴方面的知识都比较想要了解,那么今天小好小编就为大家收集了一些关于申鉴方面
2023-05-31
日前,位于石泉路街道的秋月枫舍居民区党总支、居委会便联合“秋叶枫华”党建联盟单位开展了一次生动鲜...
2023-05-31
绿地控股回应:公司无被限制高消费的情况,张玉良,绿城集团,上市公司,绿地控股,中国煤炭公司,中国能源公司
2023-05-31
汪丽萍的空间爱情说说1、鸳鸯也会羡慕我们的恩爱,蜂蜜也会妒忌我们的甜蜜,双飞蝶也会为我们的缠绵而感动
2023-05-31
【午评】一.市场动向上证此前4连阳,震荡市4阴4阳为极限,今天有收阴的需求,从目前来看,3220的强支撑依
2023-05-31
近日,由于遭遇阴雨天气,河南、陕西、江苏等地麦收受到影响。记者了解到,各地正在加紧进行农机调配、烘干
2023-05-31
在多方面有提升的情况下,蔚来全新ES6的起售价为36 8万元,较2022款的起售价38 6万元降价了1 8万元。蔚来这
2023-05-31
你需要的东西喷泉草种子发酵罐土壤手抹子水向阳种植地点紫色喷泉草,植物学上称为Pennisetumsetaceumrubrum
2023-05-31
5月24日,“那个为‘爱’减肥的少女走了”登上热搜第一,让很多网友唏嘘不已。因为患上神经性厌食症,这...
2023-05-31
大河网讯近日,中牟县广惠街街道召开全城清洁行动专题推进会,研究部署任务分工,全员参与整治行动,进一步
2023-05-31
原标题:如何正确购买儿童用品?市场监管总局发布5种儿童用品消费提示市场监管总局30日发布了轮滑鞋、儿童
2023-05-31
1、2009款的丰田卡罗拉,6升排量手动挡车型,非常的省油。2、卡罗拉车型是丰田公司旗下的一款紧凑型家用轿
2023-05-31
5月30日,国家文物局在北京召开“考古中国”重大项目重要进展工作会,聚焦商代最新考古发现,通报了陕西...
2023-05-31
新华社北京5月30日电当前,全国小麦陆续进入集中收获期。5月下旬,北方冬麦区出现大范围持续降雨天气过程,
2023-05-31
"是的,因为合约到期,我们三里屯旗舰店将于6月11日正式闭店,原址不会再开,不过未来会在北京及中国...
2023-05-31
截至2023年5月30日收盘,鸿博股份(002229)报收于31 38元,上涨9 99%,已连续涨停4天,换手率25 01%,成交量
2023-05-31
龙江和牛业绩下滑:毛利率、ROE欠佳,存货飙升严重依赖肯德基《港湾商业观察》施子夫一口和牛能玩转多少新
2023-05-31
朱琳带伤作战吞5连败北京时间5月31日凌晨,2023年法网公开赛女单首轮。中国球员朱琳以3-6 3-6连输两盘不敌
2023-05-31
ChatGPT横空出世之后,生成式AI大模型便受到广泛关注,而百度Apollo趁势推出的基于文心大模型能力的智能座
2023-05-31
5月30日北向资金增持86 83万股华能水电。近5个交易日中,获北向资金减持的有2天,累计净减持36 67万股。近2
2023-05-31
1、从济南到淄川汽车站后,直接乘坐39路淄川-峨庄公交车,到瀑布群门口的华宇文化艺术基地下车,标准间每人
2023-05-31
欢迎观看本篇文章,小升来为大家解答以上问题。关于初夏的诗句,初夏的诗句大全很多人还不知道,现在让我们
2023-05-31
2022年打征信报告一般显示近5年的记录。国家对个人征信记录的储存期限设定的是5年,征信报告上面会反映近5
2023-05-31
据我今日获悉,中国男篮近期将公布最新一期的集训大名单。如无意外发生的话,这份集训大名单将包括首钢男篮
2023-05-31
1、送气可打6018888。2、还有24小时服务电话968860华润瓶装液化石油气供应站:★湖滨供应站地址:思明区湖滨南
2023-05-31
1、你试试在开始-运行里面键入REGSVR32文本王安装路径HWOCR2K OCX试试另外你的WORD什么版本?是在不
2023-05-31
龙星化工00244205月30日在投资者关系平台上答复了投资者关心的问题投资者氟化设备是否还能正常投产龙星化工
2023-05-31
1、我起了,一枪秒了,有什么好说的来自CSGO主播茄子在直播中的一段知名对话。2、对话发生时,茄子刚刚(在
2023-05-31
中新网5月30日电近日,美孚1号车养护发布了全新的臻选技师形象片,以“动力系统养护专家”的称号赋能全
2023-05-30
聊聊一篇新中国农业行业标准第九辑植保分册,对于最新中国农业行业标准第九辑植保分册简单介绍的文章,
2023-05-30
诸多的对于代拉基翁种族值,代拉基翁这个问题都颇为感兴趣的,为大家梳理了下,一起往下看看吧。1
2023-05-30
每经AI快讯,有投资者在投资者互动平台提问:尊敬的董秘,你好!请问特斯拉储能超级工厂的建设和贵司的相关
2023-05-30
新开发银行在中国银行间债券市场发行85亿元人民币债券---总部位于上海的新开发银行最新宣布,其在中国银行
2023-05-30
欢迎观看本篇文章,小升来为大家解答以上问题。关于宇宙资料,宇宙的介绍很多人还不知道,现在让我们一起来
2023-05-30
直播吧5月30日讯阿斯报消息,本泽马收到了来自沙特的2年4亿欧元报价,他也向皇马告知了这份合同。阿斯报表
2023-05-30
5月29日上午,神舟十六号载人飞行任务新闻发布会在酒泉卫星发射中心举行。中国载人航天工程办公室副主任林
2023-05-30
1、复读到底怎么样如果复读了一年,还是报考的专科学校,那么从时间成本来说不值得,如果成绩没有显著的提
2023-05-30
今天小编岚岚来为大家解答以上的问题。元极舞全套教学下载,元极舞全套相信很多小伙伴还不知道,现在让我们
2023-05-30
中国质量新闻网讯(杨丹谢旺江)近日,重庆市璧山区市场监管局积极组织开展2023年化妆品宣传周活动,进一步
2023-05-30
来为大家解答以上问题,暴风影音2007版本有什么用,暴风影音2007很多人还不知道,现在让我们一起来看看吧!
2023-05-30
想必现在有很多小伙伴对于表明对本次谈话的态度如何写方面的知识都比较想要了解,那么今天小好小编就为大家
2023-05-30
华谊腾讯娱乐(00419 HK)5月30日晚间公告,集团旗下附属公司医智诺已与腾讯旗下附属公司腾讯云订立战略合
2023-05-30
港大即香港大学,该校在职MBA项目学制2年,上课地点在香港大学,上课时间可以选择工作日或者周末;香港大学
2023-05-30
“六一”临近,宣化区跃进街小学红领巾研学活动走进宣化国玉陶瓷文化园。从神奇的“釉下五彩”到现场展...
2023-05-30
来为大家解答以上问题,9010次列车,9010c很多人还不知道,现在让我们一起来看看吧!1、独特的旋转手机夏普sh901
2023-05-30
市面上的医疗险很多,今天要给大家说的是爱她保保险,它是一款女性专属的商业补充医疗险,那么爱她保保险怎
2023-05-30
每日小编都会为大家带来一些知识类的文章,那么为大家带来的是丹特-格林方面的消息知识,那么如果各位兴趣
2023-05-30
四川在线记者李丹日前,有网友向川观新闻反映,说他的户籍在达州,女朋友的户籍在自贡,他们想旅游结婚,问
2023-05-30
1、长宁区消防窗口电话:23039197打去咨询办公场所要是小于5000平方米的话,直接上上海消防网验收备案就可
2023-05-30
在原神的恒动械画璃月之二关卡中,我们又将会面临到新的难题,玩家需要去调整底板的方向,将齿轮放置到正确
2023-05-30
一一直觉得红高粱是离我十分遥远的一种粮食作物。有多远呢?感到它就是生长在小说、诗歌或电影里,是味道清
2023-05-30
教育部等十八部门29日联合印发《关于加强新时代中小学科学教育工作的意见》(以下简称《意见》),旨在适应
2023-05-30
导读莫斯科骚乱事件,斯科骚乱事件的简介很多人还不知道,现在让我们一起来看看吧!1、2013年10月13日,俄
2023-05-30
扎根基层多年,新丰县丰城街道南区社区党支部书记、居委会主任冯上娣20多年如一日,坚持群众利益无小事,把
2023-05-30
头部机构抢教授。
2023-05-30
5月29日,艺妙神州携靶向BCMA的新一代CAR-T细胞产品(HP21)亮相2023中关村论坛,并参加国际技术交易大会的
2023-05-30
您的浏览器不支持此视频格式搭载神舟十六号载人飞船的长征二号F遥十六运载火箭在酒泉卫星发射中心发射升空
2023-05-30
1、这个东西咱可不好说!不过我建议最少弄个全车查检!原因是。2、咱们平时开的量产车!!不是专用的赛车!
2023-05-30
中新网江苏新闻5月29日电(朱志庚张司晨)近日,在徐州市王杰小学阶梯教室里,徐州市公安局老干部党总支、关
2023-05-30
2018年雅加达亚运会,中国男足亚运队不敌沙特队止步16强。毫无疑问,李刚仁将成为今年夏天杭州亚运会韩国亚
2023-05-30
5月16日,满载6 5万吨液化天然气的“马尔文”轮在中国海油广东大鹏液化天然气接收站完成接卸,这船货物...
2023-05-30
5月29日,圆通速递(600233)融资买入624 86万元,融资偿还472 85万元,融资净买入152 01万元,融资余额2 7亿元。
2023-05-30
美国总统拜登28日晚对媒体表示,民主党与共和党就提高债务上限达成的最终协议正在提交给国会。
2023-05-30
重庆市机动车违法查询是指机动车、非机动车驾驶人、行人违反道路交通安全法和交通管理的行为,重庆市机动车
2023-05-30
今天来聊聊关于闪灵全面解析,闪灵解析的文章,现在就为大家来简单介绍下闪灵全面解析,闪灵解析,希望对各
2023-05-30
5月29日北向资金减持52 25万股劲嘉股份。近5个交易日中,获北向资金减持的有4天,累计净减持178 46万股。近
2023-05-30
1、出自《论语•述而》。2、原文是:“三人行,必有我师焉。3、择其善者而从之,其不善者而改之。4、”...
2023-05-30
今年四月以来,我国一些地方出现了冰雹,有的个头大如鸡蛋。现在就说说冰雹是这样形成的?大地在太阳短波辐
2023-05-30
证券时报e公司讯,2023长春春季房交会圆满收官,5月20日至28日,商品住房累计成交6770套,成交面积74 1万平方
2023-05-30
1、K21次,在北京西站第4候车室候车。2、K21次列车是由北京西站发往南宁站方向的空调快旅客列车,北京西站
2023-05-30
京泉华公告持有公司股份的董事鞠万金李战功张礼扬和监事何世平减持计划期限已届满在减持计划期间内上述股东
2023-05-30
5月28日,在位于铜陵市枞阳县项铺镇项金村的安徽玉堂雨具有限公司就业帮扶车间里,工人们正在紧张有序地赶
2023-05-30
娱乐圈又出CP了?近日,有娱记在同一天分别拍到刘宇宁和赵露思在迪士尼游玩。当天刘宇宁先从迪士尼离开到门
2023-05-29
1、可以。冷藏和冷冻都可以。若不能即食,买回竹笋后在切面上先涂抹一些盐,再放入冰箱中冷藏。2、想要保存
2023-05-29
安路科技(688107)05月29日在投资者关系平台上答复了投资者关心的问题。
2023-05-29
2023年,面对教育全球化的趋势以及国家对国际化人才的迫切需求,越来越多的家长开始意识到,在新时代背
2023-05-29
连日来,地摊经济频繁引发关注:淄博烧烤霸屏热搜榜、深圳将不再全面禁止“路边摊”、义乌夜宵档夫妻高...
2023-05-29
质谱技术有助于物质结构的解析,包括元素的同位素性质、丰度、核素结合能及稳定性的研究。质谱在同位素发现
2023-05-29
南方财经5月29日电,齐翔腾达公告,目前,公司投资建设的30万吨 年环氧丙烷项目生产线已建设完工,装置流程
2023-05-29
武汉碧桂园幼儿园2023年秋季招生公告武汉碧桂园幼儿园创办于2011年至今已有12年历史,位于武汉经济开发区(
2023-05-29
今天来聊聊关于空气的密度是多少克每升,空气的密度是多少的文章,现在就为大家来简单介绍下空气的密度是多
2023-05-29
1、08-OurHouseBelow flac开头的第二首吧如果需要无损的话邮给你其实整个三张CD都很赞的。本文
2023-05-29
行业顾问周四发布的一份报告显示,由于对个人交通工具的强劲需求和经销商库存的增加,预计美国5月份的新车
2023-05-29
截至2023年5月29日收盘,铂科新材(300811)报收于105 48元,上涨5 48%,换手率4 51%,成交量3 89万手,成交额4 12亿元。
2023-05-29
四川重庆陕西等地有较强降雨华南江南等地有高温天气
2023-05-29
Redmi正式官宣将推出RedmiNote12TPro,新机上午已经开始上架预约,该手机将搭载天玑8200-Ult
2023-05-29
通过一幅幅蜿蜒曲折的法制史图文,使我对中国法治史有了更直观的认识,很受触动……”八年级学生小军感...
2023-05-29
“落花无言,人淡如菊”,唐代司空图《二十四诗品》中第六首诗品《典雅》的名句,亦是香港无极乐团“意...
2023-05-29
1、删掉文件名后缀 " txt "就可以了如果看不到后缀,需要在文件夹选项中“查看”选项卡里,把“隐藏...
2023-05-29
证券时报e公司讯,共创草坪5月29日在互动平台表示,公司目前经营状况良好,在手订单充足。
2023-05-29
1、两种方法:一、热泡法先用热水将海参泡24小时(可直接随冷水装入锅内煮开,再加盖焖泡4-5小时),再从腹
2023-05-29
5月26日,我爱我家(000560)融资买入834 27万元,融资偿还483 07万元,融资净买入351 21万元,融资余额1 92亿元。
2023-05-29
科目三从上车开始,停车换人。第一步,看考官。小心点。如果你想在开车时少惹麻烦,你必须在开车前做好准备
2023-05-29
“爱情”这个话题,一直都是人们谈论得最多的话题之一,因为爱情,我们会感到幸福,也会感到痛苦。然而...
2023-05-29
音频解说一、河南省商丘市天气预报1、虞城县气象台2023年05月29日03时26分发布暴雨橙色预警信号。2、过去3小时我
2023-05-29
海报28日12时31分经历1小时59分钟飞行由C919大型客机执飞的东方航空MU9191航班平稳降落在北京首都国际机场
2023-05-29
1、《十二谭》是由优酷、唐人影视联合出品,陈淑良、贾方执导,古力娜扎、刘以豪、谷嘉诚、刘畅、周峻纬等
2023-05-29Copyright © 2015-2022 北极水产网版权所有 备案号:浙ICP备2022016517号-19 联系邮箱:514 676 113@qq.com