目录

一 接续上文

二 编译根文件系统

三 构建完善根文件系统

四 内核中指定根文件系统

五 带根文件系统启动内核

一 接续上文

在上一篇文章中,我们展示了通过QEMU仿真软件来运行Linux内核的过程。因为是仿真,所以我们可以构建不同架构平台的环境来进行调试,这对开发者学习内核非常友好。当然,为了简化过程且能够有一定代表性,平台选择了ARM。

学内核之一:基于QEMU搭建Linux内核启动调试环境_龙城赤子的博客-CSDN博客

显然,基于上文的环境,我们只能调试内核的启动过程。这是因为没有提供根文件系统,内核启动后,加载文件系统时就会异常停止,自然也无法执行shell等待用户输入。当我们想要调试一些运行过程中的内容时,就很不方便了,甚至是无法进行。比如,想看看一些系统调用的执行过程,或者设定一些触发条件,在事件产生时查看内核的处理逻辑等。

这这一篇文章中,我们就来补充缺失的根文件系统。这也算是对上一篇最后部分提出的第一个问题的解答。

在正式开始之前,对另外两个问题也做个简单的说明。

关于append参数,就是提供给内核的启动命令,效果类似uboot中传递给内核的cmdline。当然,有没有这个参数以及参数内容设置正确与否,都不影响启动过程。因为只有运行到使用参数的地方时,代码逻辑才会检测出问题。在本文中,这个参数不仅要有,而且还要正确,因为我们要加载根文件系统,让系统在模拟环境下完整运转起来。

关于GDB调试,其实我们可以将内核生成的vmlinux也看做是一个程序,那就好理解多了。vmlinux跟普通程序的区别是它的地址空间是确定下来了的。里面使用的地址也是加载后实际的地址。vmlinux.o文件则类似应用程序,使用的是相对地址。对于应用程序,可以由操作系统的加载过程完成地址的映射处理,而对于内核,就需要自己解决。

其次,GDB使用vmlinux可以明确调试过程中的符号信息。

好了,进入正题。

二 编译根文件系统

为了不让内核运行后挂起来,我们需要完成根文件系统的加载。这样,就需要提供一个根文件系统。对于嵌入式领域开发者来讲,busybox是流行选择。

从busybox官方网站下载一个稳定版。BusyBox

我这里下载了1.33.2版本。解压后,就可以考虑编译了。参照网上的资料,选择静态库方式。

make defconfig
make menuconfig
make CROSS_COMPILE=arm-none-eabi- ARCH=arm -j4

在menuconfig中选择静态方式 Build static binary

不过,在编译过程中出现了错误:

CC      applets/applets.o
In file included from include/libbb.h:13,from include/busybox.h:8,from applets/applets.c:9:
include/platform.h:168:11: fatal error: byteswap.h: No such file or directory168 | # include <byteswap.h>|           ^~~~~~~~~~~~
compilation terminated.
scripts/Makefile.build:197: recipe for target 'applets/applets.o' failed
make[1]: *** [applets/applets.o] Error 1

提示找不到byteswap.h头文件。在编译工具链目录下搜索了一下,确实没有上述头文件。具体是编译工具链自身问题还是跟busybox版本匹配问题,有时间了再研究。参考本人方法的读者,需要在这块注意了。

我选择了另一个工具链,这个是瑞星微开发板带的工具链,有上述头文件

./arm-buildroot-linux-gnueabihf/sysroot/usr/include/bits/byteswap.h
./arm-buildroot-linux-gnueabihf/sysroot/usr/include/byteswap.h

使用这个工具链,可以编译通过。所以,如果你也遇到了上述问题,可以考虑换个工具链。为确保工具链匹配,在编译之前,可以先检查一下是否包含上述头文件。另外需要注意的是,不同工具链的二进制兼容性也是要考虑的。像eabi、thumb、浮点支持情况等。这里也先留作一个问题,后续我们通过一篇新的文章来介绍于ARM相关的此类常见问题。

最终的编译工具链就换成了下面这个

make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm -j4

编译完成后,直接make install可能会有问题,尽量带上工具链,确保万无一失

make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm install

完成后,会生成一个_install目录,里面包含了基础的命令。因为是静态方式,所以不包含库。

其实,生成的各种命令是符号链接,这样不仅可以缩小体积,还可以加速启动和执行过程。内核启动加速技术就有这相关的。感兴趣的读者可以搜索相关资料研究。

三 构建完善根文件系统

目前只是具备了启动程序和周边命令。我们还要补充文件系统相关的其他目录,包括dev、etc、proc、sys等。这里面有些是内核自动生成的,有些是手动或者执行特定命令创建的。本人没有花费太多时间,参考了网上例子。具体读者可以自己搜索,这部分问题不大。

然后将生成的文件系统目录下的所有文件打包

root@ubuntu:/home/work/KernelStudy/rootfs# find . | cpio -o --format=newc > rootfs.img
cpio: File ./rootfs.img grew, 1918976 new bytes not copied
7563 blocks

现在我们有了根文件系统,剩下只需做两件事,在内核配置中指定上述文件所在目录,其次在qemu命令行中指定上述文件所在位置。我们一件一件来搞定。

四 内核中指定根文件系统

这里需要注意,如果直接在内核目录下menuconfig,并在其中配置上述配置项CONFIG_INITRAMFS_SOURCE="/home/work/KernelStudy/rootfs"

则编译内核时,会引出很多配置要求

如果你一路默认选择下来,并使用前一篇文章中指定的qemu命令启动新生成的内核时,将看不到任何输出。本人试了好几次,都是这样。每次make defconfig后直接编译的版本是可用的。为了规避这个问题(后续有时间再研究),我采用了另外一种迂回的办法,就是先make defconfig,然后打开生成的.config文件,直接修改里面的CONFIG_INITRAMFS_SOURCE项目,之后执行make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-none-eabi-。此时虽然还会出现一些配置项,但是默认处理后,编译的内核是可以通过qemu启动的。

五 带根文件系统启动内核

 现在,我们在qemu命令中指定append附带的cmdline以及关联的根文件系统img文件。

qemu-system-arm -nographic   -m 512M -M virt -kernel /home/work/KernelStudy/Kernel/linux-4.19.244/arch/arm/boot/zImage -append "rdinit=/linuxrc root=/dev/ram console=ttyAMA0 loglevel=8" -initrd /home/work/KernelStudy/rootfs/rootfs.img 

之后,内核启动起来。且cmdline也传递进去了

最后,成功加载根文件系统

我们看到,命令可以使用

在此基础上,我们就可以调试运行状态的内核了。关于GDB调试内核过程及前面提到的问题,我们下一篇再讲。今天就到这里。

JUST DO IT

ENJOY IT

学内核之二:基于QEMU搭建Linux内核运行调试环境相关推荐

  1. 基于Qemu搭建x86_64虚拟环境运行Linux内核

    主机软件版本信息 主机系统: wxer@wxer:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Desc ...

  2. 国外linux内核视频播放器,基于Video for Linux内核的USB摄像头视频信号采集实现

    摘要:Video for Linux是Linux中关于视频设备的内核驱动,本文介绍了在Video for Linux内 >> 基于ARM9和USB摄像头的网络视频采集系统设计 基于嵌入式V ...

  3. 基于Qemu搭建imx6l模拟开发板环境+添加驱动+驱动测试

    一.Qemu镜像下载 准备环境 vmware ubuntu18.04 git工具 下载镜像文件 root@ubuntu:/home/mf/Desktop# git clone https://e.co ...

  4. (二) DIM-SUM系统环境搭建之编译与调试环境

    系统的编译与调试环境 一.编译 1.获取源码 2.编译工具 GCC Make 3.编译系统 (1)安装开发环境 (2)安装依赖 (3)编译内核 二.调试 1.下载QEMU 2.下载Python2.7 ...

  5. vs2017搭建Linux的开发调试环境(VisualGDB)

    在Linux下调试工程是一件很苦逼的事情,不像在Windows下用Visual Studio那样简便,但是最近发现一件神器可以让Linux下的程序一样可以在Windows下的Viusal Studio ...

  6. 基于Centos搭建nginx+uwsgi运行django环境

    环境: CentOS 7 nginx/1.9.12 Python 2.7.5 一:安装依赖包5 yum install zlib-devel bzip2-devel pcre-devel openss ...

  7. qemu debug linux内核,在QEMU环境中使用GDB调试Linux内核

    简介 对用户态进程,利用gdb调试代码是很方便的手段.而对于内核态的问题,可以利用crash等工具基于coredump文件进行调试.其实我们也可以利用一些手段对Linux内核代码进行gdb调试,qem ...

  8. [转载]基于ARM的linux内核裁剪与移植

    基于ARM的linux内核裁剪与移植 http://bbs.elecfans.com/forum.php?mod=viewthread&tid=185020  wutaimin( 楼主 ) 2 ...

  9. 基于树莓派对Linux内核简单认识

    基于树莓派对Linux内核简单认识 树莓派等芯片带操作系统的启动过程 Linux 内核源码 Linux 内核源码目录树 安装tree命令 目录树结构 Linux根目录下 \ 树莓派Linux源码配置 ...

最新文章

  1. 计算机毕业论文过程管理手册,毕业论文过程管理手册(修改)-陈亚琴.doc
  2. Intellij IDEA中使用Protobuf的正确姿势
  3. Windows Phone 7 多点触摸编程
  4. 熟悉linux unix,熟悉这几个常用命令,你就是Linux/Unix的vi高手了。
  5. ACM Doing Homework again
  6. Makefile浅尝
  7. discuz! X3 更改域名全程记录 (修改域名的方法)
  8. 带你深入了解何为TeamViewer视频通话
  9. JS URL传中文参数引发的乱码问题
  10. JavaGUI版聊天室
  11. 文献阅读-CSC-中文错别字-有关论文搜集-+CGED
  12. swf播放器air android 版,网极SWF播放器安卓版
  13. c语言中的16进制坐标计算器,16进制计算器
  14. 新浪云mysql_php连接mysql数据库(新浪云SAE)
  15. 20201224 windows10下多显示器在多虚拟桌面下如何保持某个显示器一直显示相同的内容
  16. Linux终端分屏软件tmux工具基本快捷键
  17. ChatGPT技术原理 第七章:Seq2Seq模型
  18. 万级送风天花工作原理以及操作方法
  19. C++ OpenCV特征提取之KAZE和AKAZE的匹配
  20. 【微信小程序】-- 使用 npm 包 - API Promise化(四十二)

热门文章

  1. oracle saiku_Apache Kylin | Saiku + Kylin 搭建多维 OLAP 平台
  2. CS:GO官方封禁超304000作弊帐号;任天堂疑似开发工具、源代码等机密数据泄露;Valorant上线全新处罚功能已修改
  3. vue 实现el-select组件 配合 el-tabs 完成动态tabs然后有勾选 全选,还有模拟提交,回显数据
  4. java 中数组中删除元素_java数组中删除元素的操作
  5. 计算机图形学新篇章——Games 101环境搭建
  6. SpringCloud之SpringCloud常用的五大组件
  7. 微软“创新杯”全球学生大赛
  8. 瞎搞系列-超分辨率进程
  9. 自定义歌词View的优化(一)
  10. opencv学习笔记二十一:使用HSV颜色空间实现颜色识别