前言

在分析块设备驱动之前,整体规划如下:

 1. 介绍qemu使Linux内核挂载块设备。2. 介绍块设备驱动挂载过程。3. 介绍块设备驱动运行过程。

本章先重点介绍使用qemu使Linux内核和根文件系统挂载块设备的操作执行过程。
为什么要介绍在qemu中使Linux内核和根文件系统挂载块设备?我们为什么要操作这些繁琐的步骤?
下面着重回答一下为什么要使用QEMU中挂载块设备,是因为我们在上一章《QEMU+GDB调试Linux内核总结(全)》[link][https://blog.csdn.net/weixin_37867857/article/details/88205130]中介绍了要使用gdb调试linux内核代码必须使用qemu启动,并且设置调试模式才能够启动。其实如果有其他的方式和方案也可以,只不过个人觉得这个操作比较方便并且实用性高。而且在gdb调试中随时可以终止调试设置断点,这个在应用层是没有的。在应用层如果终止调试的话直接程序退出了,但是内核中是不会的。
为什么要操作这些繁琐的步骤呢?上面一句话已经回答了这个问题。
为了防止损伤硬盘,我们会以虚拟硬盘的形式挂载在磁盘中,下面第一章中我们会先介绍虚拟磁盘的制作和设置。

1. 虚拟磁盘的制作

虚拟磁盘,顾名思义这个磁盘是虚拟的,也可以在磁盘里面写入东西而不会丢失,除非虚拟磁盘损坏(损坏的方式有很多:重新格式化,挂载之后关机之前忘了卸载等都有可能损坏虚拟磁盘,但是好在都是虚拟磁盘的磁盘内容损坏,不会伤及物理磁盘)。虚拟磁盘也是云计算的一个重要的基础,所谓云计算也就是远程虚拟机的集群化部署。
话题扯的有点远了,言归正传,制作虚拟磁盘命令如下:

qemu-img create -f qcow2 disk.img 200M   #现阶段的虚拟磁盘空间不用太大,200M就行了qcow2格式的
dd if=/dev/zero of=./disk.img bs=1M count=200       # 清空我们的虚拟磁盘。mkfs.ext2 -q ./disk.img         # 磁盘格式化成ext2
mount -t ext2 disk.img /mnt/         # 本地磁盘挂载测试
umount /mnt                     # 本地磁盘卸载测试;
qemu-system-x86_64 -kernel ./boot/bzImage -initrd ./initramfs.img -hdc ./disk.img -append "console=ttyS0" -nographic      # 虚拟机启动磁盘测试
#进入虚拟机后使用 ls /dev | grep sd测试虚拟机磁盘是否已经有了,比不加-hdc ./disk.img多了一个sda
#紧接着使用mount /dev/sda /mnt目录做一个挂载测试,最好是在本地磁盘挂载测试时候拷贝一个文件测试

下面是我执行如上命令的时候的执行记录:

root@ubuntu:/home/alex/kernel# qemu-img create -f qcow2 disk.img 200M
Formatting 'disk.img', fmt=qcow2 size=209715200 encryption=off cluster_size=65536 lazy_refcounts=off
root@ubuntu:/home/alex/kernel# dd if=/dev/zero of=./disk.img bs=1M count=200
200+0 records in
200+0 records out
209715200 bytes (210 MB) copied, 3.28703 s, 63.8 MB/s
root@ubuntu:/home/alex/kernel# mkfs.ext2 -q ./disk.img
./disk.img is not a block special device.
Proceed anyway? (y,n) y
root@ubuntu:/home/alex/kernel# mount -t ext2 disk.img /mnt/
root@ubuntu:/home/alex/kernel# ls /mnt/
lost+found
root@ubuntu:/home/alex/kernel# cd /mnt/
root@ubuntu:/mnt# mkdir alex
root@ubuntu:/mnt# ls
alex  lost+found
root@ubuntu:/home/alex/kernel# umount /mnt/

以下是虚拟机启动磁盘后的测试,也就是执行完qemu-system-x86_64 -kernel ./boot/bzImage -initrd ./initramfs.img -hdc ./disk.img -append "console=ttyS0" -nographic之后的执行记录:

/ # ls
bin      etc      linuxrc  root     sys
dev      init     proc     sbin     usr
/ # ls /dev/sda
/dev/sda
/ # mkdir mnt
/ # ls
bin      etc      linuxrc  proc     sbin     usr
dev      init     mnt      root     sys
/ # mount -t ext2 /dev/sda /mnt/
mount: mounting /dev/sda on /mnt/ failed: No such device
/ # mount -t loop /dev/sda /mnt/          # 执行完两次之后心里有点烦躁,本着司马当活马医的心态直接使用mount /dev/sda/mnt
mount: mounting /dev/sda on /mnt/ failed: No such device
#先使用fdisk -l看磁盘是否真正有效,发现内核能够发现磁盘。
/ # fdisk -lDisk /dev/sda: 209 MB, 209715200 bytes
255 heads, 63 sectors/track, 25 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytesDisk /dev/sda doesn't contain a valid partition table
/ # mount /dev/sda /mnt/      #挂载成功
[  229.258151] EXT4-fs (sda): mounted filesystem without journal
/ # ls /mnt/                            # 查看文件,和在制作时候创建的文件名一致。
alex        lost+found

OK,经过上述步骤,证明物理磁盘挂载成功到我们编译好的内核版本,下一章进行gdb调试。

qemu启动磁盘+GDB调试内核代码。

上一章中我们已经学会了怎么在内核镜像使用qemu加磁盘并且成功挂载上磁盘的操作。本章中我们学习怎么使用此调试内核代码。
如同内核调试步骤一样,正常的启动虚拟机除了加上-hdc ./disk.img我们的启动命令之外,我们还要添加-S -s的调试步骤。命令如下:

 qemu-system-x86_64 -kernel ./boot/bzImage -initrd ./initramfs.img -hdc ./disk.img -append "console=ttyS0" -nographic -S -s```然后启动另外一个终端敲gdb调试命令:

gdb vmlinux

gdb运行结果如下:
```shell
alex@ubuntu:/usr/src/linux-2.6.32.20$ gdb vmlinux
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vmlinux...done.
(gdb) target remote:1234
Remote debugging using :1234
0x0000000000000000 in per_cpu.irq_stack_union ()
(gdb) c
Continuing.
Remote connection closed
(gdb) q
alex@ubuntu:/usr/src/linux-2.6.32.20$ gdb vmlinux
GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from vmlinux...done.
(gdb) target remote:1234
Remote debugging using :1234
0x0000000000000000 in per_cpu.irq_stack_union ()
(gdb) b blkdev_open
Breakpoint 1 at 0xffffffff8116fc90: file fs/block_dev.c, line 1303.
(gdb) c
Continuing.

这时候我们看到gdb阻塞到continue回显步骤了,是因为我们打了一个断点,断点函数名称为blkdev_open。
我们只需要在启动的虚拟机里面执行如下:

cat /dev/sda

执行如上命令后,gdb效果如下,可以看到,我们可以正常的查看代码,并且分析代码了。而且分析代码跟我们上述的cat命令有关,否则gdb调试还处于阻塞状态。

好了,本章就先介绍如何使用qemu挂载虚拟硬盘,并且使用gdb调试和块设备相关的代码。下一章重点介绍块设备驱动代码框架。

Linux内核块设备总结(一)相关推荐

  1. linux 内核块设备驱动,你了解Linux 块设备驱动?

    1 什么是Ramdisk Ramdisk是一种模拟磁盘,其数据实际上是存储在RAM中,它使用一部分内存空间来模拟出一个磁盘设备,并以块设备的方式来组织和访问这片内存.对于用户来说可以把Ramdisk与 ...

  2. 深入理解 Linux 内核---块设备驱动程序

    块设备的处理 一个进程在某个磁盘文件上发出一个 read() 系统调用,内核对进程请求回应的一般步骤: read() 调用一个适当的 VFS 函数,将文件描述符和文件内的偏移量传递给它. 虚拟文件系统 ...

  3. 进一步理解Linux操作系统的块设备

    在前文<理解Linux操作系统的块设备>中我们从比较高层面(Hight Level)介绍了块设备的原理和块设备的特性.但是关于Linux操作系统块设备的实现原理可能还一知半解.本文将进一步 ...

  4. linux内核中kset是什么意思,Linux内核之设备驱动-底层数据结构kobject/kset

    Linux内核之设备驱动-底层数据结构kobject/kset kobject kobject是组成device.driver.bus.class的基本结构.如果把前者看成基类,则后者均为它的派生产物 ...

  5. 嵌入式(iMX6Q)TFTP加载 Linux 内核与设备树NFS挂载根文件系统

    配置实现过程: 嵌入式(iMX6Q)TFTP加载 Linux 内核与设备树 注:bootm对应启动uImage,bootz对应启动zImage setenv bootcmd "tftp 0x ...

  6. Linux 内核console设备实现详解

    本文基于Linux-4.14 1.earlycon early console,顾名思义,他表示的就是早期的console设备,主要用于在系统启动阶段的内核打印的输出,由于linux内核实际设备驱动模 ...

  7. 基于块的linux驱动程序,基于块的Linux驱动程序 块设备驱动 centos内核编译过程 操作系统课程设计...

    操作系统的课程设计,本人也是一头雾水地做完了课程设计,在这里贴下操作过程,放下当时参考的一篇CSDN文章链接:https://blog.csdn.net/cxy_chen/article/detail ...

  8. 如何提高Linux下块设备IO的整体性能?

    编辑手记:本文主要讲解Linux IO调度层的三种模式:cfp.deadline和noop,并给出各自的优化和适用场景建议. 作者简介: 邹立巍 Linux系统技术专家.目前在腾讯SNG社交网络运营部 ...

  9. linux内核与设备驱动,第二章 Linux内核与设备驱动程序

    2.1 Linux操作系统 Linux操作系统由系统的启动.进程调度.虚拟内存管理器.文件系统.设备驱动程序等多个组成 2.2Linux内核 设备驱动程序中使用的函数也用在内核上,并且影响着内核,因此 ...

最新文章

  1. Keras使用多个GPU并行
  2. framework之Activity 生命周期解析(基于Android11源码)
  3. 网络测试与分析工具简介
  4. nodejs 向mongodB获取指定数目的数据
  5. XML DOM 节点
  6. 【深度学习】 - MobileNet使用的可分离卷积
  7. 记一次PSP游戏文件(iso)提取BGM(cpk文件处理,无后缀音频文件格式转换,pmf文件转换)
  8. 华硕计算机u盘启动不了怎么办,华硕笔记本、台式机无法从U盘启动安装系统的终极解决办法-网络教程与技术 -亦是美网络...
  9. 神奇宝贝服务器服务器修改器,pkhex修改器最新版
  10. mic in和line in
  11. Base16,Base32,Base64编码的介绍
  12. boll指标详解教了哪些窍门BOLL指标详解之注意事项是什么
  13. STM32F4+W25Q64实现一个U盘
  14. srand( 在php,PHP srand( )用法及代码示例
  15. 启动Mysql时报错:mysqld_safe mysqld from pid file /usr/local/mysql/data/Linux.pid ended
  16. Cesium 修改geojson样式
  17. Clickhouse如何实现数据更新
  18. 安装cadence软件到使用过程中遇到的问题和解决方法
  19. 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest G - Gangsters in Central City
  20. 基于GraphHooper的离线导航软件实现

热门文章

  1. webpack-dev-server与HRM
  2. 页面局部刷新( ScriptManager 和 UpdatePanel)(转)
  3. python爬虫之云片网国内短信接口爬取
  4. 测试代码怎么做抽象才是有意义的?
  5. springboot-thymeleaf
  6. 优质文章汇总,请查收!
  7. p51 thinkpad 拆解_ThinkPad P51硬盘更换指南(图解)
  8. 阿里巴巴分布式数据库服务DRDS
  9. unity3d android存储文件,Unity3d资源写入Android内置存储卡
  10. XStream分析(2)