一、知识准备

1、在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列)

2、操作这些不同的类型就像操作文件一样,比如增删改查等

3、块设备是将信息存储在大小固定的块中,每一个块都有自己的地址,块设备支持随机访问。典型的块设备比如我们使用的硬盘

二、环境准备

组件 版本
OS Ubuntu 16.04.4 LTS

三、主设备号(major)与次设备号(minor)

● 当一块磁盘被注册到操作系统的时候,会被分配主设备号与次设备号

● 其中主设备号代表了该设备属于的类型,次设备号代表了该设备在操作系统中的唯一标识

主设备号

root@Bastion:~# ls -l /dev/sd*
brw-rw---- 1 root disk 8, 0 9月 30 17:47 /dev/sda
brw-rw---- 1 root disk 8, 1 9月 30 17:47 /dev/sda1

sda的主设备号是8,代表了sda这块磁盘是属于8这个类型的,那8是什么类型的?

root@Bastion:~# grep 8 /proc/devices
108 ppp
128 ptm
248 pps
8 sd

在/proc/devices告诉我们,8是属于sd类型的,那sd又是啥意思?

打开 https://www.kernel.org/doc/Documentation/admin-guide/devices.txt

   8 block	SCSI disk devices (0-15)
0 = /dev/sda First SCSI disk whole disk
16 = /dev/sdb Second SCSI disk whole disk
32 = /dev/sdc Third SCSI disk whole disk
...
240 = /dev/sdp Sixteenth SCSI disk whole disk Partitions are handled in the same way as for IDE
disks (see major number 3) except that the limit on
partitions is 15.

终于清楚的看到,8这个类型代表了块设备,并且是SCSI 硬盘

次设备号

由于/dev/sda做了1个分区/dev/sda1,再加上原有的/dev/sda,操作系统内核给二者打上了唯一的标记:

8,0 代表了/dev/sda

8,1 代表了/dev/sda1

小结一下:

主设备号:代表着某一类型的设备,比如SCSI硬盘、虚拟硬盘、USB等等

次设备号:操作系统分配的整数,与主设备号一起(major,minor),组成了该设备在操作系统当中唯一的ID

四、块设备文件

● 块设备文件是连接用户空间和内核空间的桥梁,通过块设备文件描述符,能够找到内核中的设备驱动程序

● 通过内核中的驱动程序从而对该设备进行读写

   +----------------------+
| user space |
| |
| +---------+ |
| | test.py | |
| +---------+ |
+----------------------+
|
|
+----v----+
|/dev/sda1|
+----+----+
|
|(8,1)
|
+---------------------------------------------
| kernel space | |
| | |
| v |
| +-----+----+ +---------------+ |
| | major:8 | | device driver | |
| +-----+----+ | | |
| | +---------------+ | +--------+
| +---------->| minor:1 |-------->| device |
| +---------------+ | +--------+
| | | |
| +---------------+ |
+--------------------------------------------+

五、测试

(a)首先虚拟一个块设备文件

root@Bastion:~# dd if=/dev/zero of=/tmp/device_test bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0890014 s, 1.2 GB/s
root@Bastion:~# mknod /dev/device_test b 7 80
root@Bastion:~# losetup /dev/device_test /tmp/device_test

我们已经虚拟出一个块设备文件了,由于是通过losetup虚拟出来的,所以major号只能为7

下面将该块设备格式化、挂载:

root@Bastion:~# mkfs.ext4 /dev/device_test
mke2fs 1.42.13 (17-May-2015)
Discarding device blocks: done
Creating filesystem with 102400 1k blocks and 25688 inodes
Filesystem UUID: f38c24be-851b-41ff-8d55-4e692d5a4c83
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729 Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done root@Bastion:~# mount /dev/device_test /mnt
root@Bastion:~# df -h | grep /mnt
/dev/device_test 93M 1.6M 85M 2% /mnt
root@Bastion:/mnt# ls -l /dev/device_test
brw-r--r-- 1 root root 7, 80 Nov 12 09:54 /dev/device_test

至此,我们拥有了一个块设备,并且大小为100M

(b)测试脚本

准备一个python文件,每秒往test.log写入hello world

root@Bastion:/mnt# more device_test.py
import time
f = open('test.log','a+')
while 1:
f.write('hello world\n')
time.sleep(1)

运行并查看其打开的文件描述符

root@Bastion:/mnt# python device_test.py &
[1] 25873
root@Bastion:/mnt# lsof -n | grep 25873
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
python 25873 root 3u REG 7,80 8923 14 /mnt/test.log

整理一下我们的信息:

● 首先运行脚本,它的进程号为25873。脚本的逻辑是需要打开test.log,然后进行读写

● 由于脚本中是相对路径,并且当前目录在/mnt下,/mnt相关联的硬盘是/dev/device_test

● 进程通过/dev/device_test拿到了该设备的设备号(7,80)

● 通过设备号在内存中找到对应的设备驱动程序,然后通过设备驱动程序对块设备进行读写

● 在块设备上没有发现test.log,首先创建一个,然后开始对该文件每秒写入一句'hello world'

六、小结

● 当块设备挂载的时候,会先在操作系统的/dev下创建一个块设备文件,并且分配主设备号与次设备号

● 块设备文件是连接用户空间和内核空间的桥梁,应用程序通过它能够找到在内核中的设备驱动,从而实现对设备的读写


至此,本文结束

在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

linux一切皆文件之块设备文件(四)的更多相关文章

  1. Linux以列表格式显示块设备

    Linux以列表格式显示块设备 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ lsblk -l NAME MAJ:MIN RM SIZE RO TYPE MO ...

  2. Linux下按扇区读写块设备

    本文介绍Linux下按扇区读写块设备(示例TF卡),实际应用是在Android系统上,主要方法如下: 1.找到sdcard的挂载点,在android2.1系统下应该为/dev/block/mmcblk ...

  3. LINUX中块设备文件和字符设备文件的本质区别

    在LINUX系统文件类型分类的文章中我们提到了 块设备 和 字符设备文件,那么什么是块设备 字符设备文件呢?他们之间有什么本质上的区别呢? 设备文件分为 Block(块) Device Driver ...

  4. Linux设备驱动--块设备(四)之“自造请求”

    前面, 我们已经讨论了内核所作的在队列中优化请求顺序的工作; 这个工作包括排列请求和, 或许, 甚至延迟队列来允许一个预期的请求到达. 这些技术在处理一个真正的旋转的磁盘驱动器时有助于系统的性能. 但 ...

  5. Linux设备驱动--块设备(四)之“自造请求”(转)

    前面, 我们已经讨论了内核所作的在队列中优化请求顺序的工作; 这个工作包括排列请求和, 或许, 甚至延迟队列来允许一个预期的请求到达. 这些技术在处理一个真正的旋转的磁盘驱动器时有助于系统的性能. 但 ...

  6. 判断一文件是不是字符设备文件,如果是将其拷贝到 /dev 目录下?

    #!/bin/bashread -p "Input file name: " FILENAMEif [ -c "$FILENAME" ];then cp $FI ...

  7. Linux磁盘管理之设备文件详解04

    Linux一切接文件,除了普通文件和目录文件,还包括一些其它的特殊文件:块设备文件.字符设备文件.套接字文件.链接文件等.今天这里主要说一下常见的块设备文件和字符设备文件,这2类是最常见的设备文件类. ...

  8. linux中的文件类型以及查看文件类型的方法

    Linux文件类型和文件的文件名所代表的意义是两个不同的概念,在linux中文件类型与文件扩展名没有关系.它不像Windows那样是依靠文件后缀名来区分文件类型的,在linux中文件名只是为了方便操作 ...

  9. linux入门系列9--用户管理及文件权限控制

    ​ 前面文章分享了Linux下常用命令以及Shell编程相关知识,本节继续学习Linux用户管理及文件权限控制. ​ Linux是多用户多任务操作系统,具有很好的稳定性和安全性.既然是多用户,那就意味 ...

随机推荐

  1. 拉格朗日插值和牛顿插值 matlab

    1. 已知函数在下列各点的值为   0.2 0.4 0.6 0.8 1.0   0.98 0.92 0.81 0.64 0.38 用插值法对数据进行拟合,要求给出Lagrange插值多项式和Newto ...

  2. 【Android自动化】测试系统的应用程序安装与卸载性能,判断长时间反复安装对系统的整体性能影响

    # -*- coding:utf-8 -*- import sys import os import time import subprocess from uiautomator import de ...

  3. BZOJ3105:[CQOI2013]新Nim游戏(线性基,贪心)

    Description 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴 ...

  4. Integer、String、StringBuffer、StringBuilder

    Integer Interger 是int基本数据类型的包装类,在Integer内部封装了一个final int value的属性. 构造方法: Integer类提供了两种构造方法:它们都会返回一个I ...

  5. windows 下配置 Nginx 常见问题

    因为最近的项目需要用到负载均衡,不用考虑,当然用大名鼎鼎的Nginx啦.至于Nginx的介绍,这里就不多说了,直接进入主题如何在Windows下配置. 我的系统是win7旗舰版的,到官网下载最新版本 ...

  6. 20145236《网络对抗》Exp1 逆向及Bof基础

    20145236<网络对抗>Exp 1逆向及Bof基础 一.实践目标 运行原本不可访问的代码片段 强行修改程序执行流 以及注入运行任意代码. 二.基础知识及实践准备 理解EIP寄存器及其功 ...

  7. table border

    table的CSS为{border-collapse:collapse;border:none;},再设置td的CSS为{border:solid#000 1px;}是一个非常不错的方法. 示例: & ...

  8. C#自定义控件开发

    自定义控件开发 一般而言,Visual Studio 2005中自带的几十种控件已经足够我们使用了,但是,在一些特殊的需求中,可能需要一些特殊的控件来与用户进行交互,这时,就需要我们自己开发新的.满足 ...

  9. 如何一步一步建立CAN通讯

    如何一步一步建立CAN通讯 2016-04-12 20:38:14来源: eefocus 关键字:CAN通讯  硬件环境   收藏 评论(0) 分享到 微博 QQ 微信 LinkedIn CAN通讯的 ...

  10. 【CobaltStrike】CobaltStrike简介与使用

    CobaltStrike简介与使用 0x00 简介 1. 什么是CobaltStrike?可以用来做什么? CobatStrike是一款基于java编写的全平台多方协同后渗透攻击框架.CobaltSt ...