0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

浅论Linux 内核函数调用关系的验证方法

电子工程师 来源:微型机与应用第21期 刘志 作者:微型机与应用第 2021-04-02 11:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

摘 要: 作为最流行的开源操作系统Linux在各行各业得到了广泛的应用。因此了解Linux 内核的架构及工作机制就显得非常重要。然而目前对Linux 内核的主要学习途径是各种教科书以及经验博客,而对于Linux内核的实时动态监控技术却很少有人了解。本文提供一种动态监视内核运行过程的方法。通过此方法可以动态地观察Linux内核的函数调用情况,以及CPU寄存器值等动态信息。

0 引言

众所周知Linux是目前公认的最好的开源操作系统。它被广泛应用于各行各业。因此对Linux内核的学习就显得尤为重要。目前对于Linux内核的学习一般都是通过以下几个途径。

⑴通过经典教材,这些教材一般由著名的Linux 内核开发者编写。比较常用的如参考文献[1-3] 。通过这些教材读者可以从宏观的角度去了解Linux内核的整体架构以及运行机制。但是由于教科书只能提供基于作者理解的内核架构,读者无法从中获得直观的内核的动态运行状况,而这点对加深内核的理解是非常有益的。

⑵通过Linux内核的邮件列表,Linux 的开发者可以从这些列表中与其他开发者交流遇到的问题。

⑶Linux内核的源代码。Linux 的源代码涵盖了Linux的所有实现细节,但由于源代码的数量非常巨大,所以开发者往往需要在了解了相关机制以后才可以定位代码片段的位置。

以上提到的是目前了解和学习Linux内核的一些主要途径,通过这些途径可以了解内核的大体运行机制。然而这些方法都存在一个相同的问题就是无法动态实时地反应内核的运行情况。而在分析Linux内核的运行机制尤其是在遇到通过函数指针的赋值调用的情况时能够动态实时地检测内核的运行情况是非常必要的。

本文将介绍一种基于 DDD (Data Display Debugger)[4]、 BusyBox [5]、QEMU(Quick Emulator)[6]工具来对Linux内核代码运行进行动态检测的方法。

1 相关实验工具简介

本文将利用QEMU[7]搭建一个虚拟机,同时用BusyBox[5]在虚拟机上搭建一个小型Linux文件系统,然后用命令行调试程序DDD[4]来监视Linux内核的运行情况。

1.1 QEMU简介

QEMU[7]是一套由Fabrice Bellard所编写的模拟处理器的自由软件。QEMU能模拟至接近真实电脑的速度。通过QEMU可以建立一个运行目标内核的轻量级的虚拟机,并可以像调试普通应用程序一样对虚拟机中的内核代码进行单步调试,从而可以很清楚地看到代码跳转过程、CPU寄存器的变化、内核堆栈的变化等内核动态运行信息。

1.2 DDD简介

DDD(Data Display Debugger)是命令行调试程序,它特有的图形数据显示功能可以把数据结构按照图形的方式显示出来。DDD的功能非常强大,可以调试用C\C++Ada、Fortran、Pascal、Modula-2和Modula-3编写的程序。可以超文本方式浏览源代码;同时可以进行断点设置、显示各种数据结构之间的关系并由此将数据结构以图形化形式显示。

1.3 BusyBox简介

BusyBox集成压缩了 Linux 的许多工具和命令,也包含了 Android 系统的自带的shell。BusyBox将许多具有共性的小版本的Unix工具结合到一个单一的可执行文件。BusyBox提供了一个比较完善的环境,可以运行任何小的系统或嵌入式系统

2 验证流程

2.1 实验环境

本文将在Linux发行版Ubuntu 12.04上搭建实验工具。

2.2 实验工具搭建说明

这个工具套件的环境搭建由以下几个步骤组成:

⑴编译内核

选用Linux Kernel 3.5.4的内核版本。在进行内核代码的验证之前先要对目标内核进行编译,用wget命令从内核服务器下载3.5.4版本的内核,在对其编译之后就能获得内核镜像文件bzImage。

⑵安装QEMU

从QEUM的官方网站[5]上下载QEMU的最新源码文件。而后切换到 QEMU 的源码目录输入./configure生成 makefile 文件。在完成后输入编译命令make 开始编译QEMU。最后用make install命令将QEMU安装到系统中。

⑶制作根文件系统

利用DD 命令建立一个大小为10 MB的磁盘镜像文件。本实验内核将运行在这个系统上。在完成后挂载刚刚生成的镜像。在镜像中建立Linux根目录下的文件夹dev、proc、sys。

⑷安装 BusyBox 到根文件系统

在BusyBox的官方网站[8]上下载最新的BusyBox 源码。切换到BusyBox的源码目录,输入命令 make menuconfig 配置编译选项。

在弹出的配置菜单中勾选静态编译的选项(BusyBox Settings→Build options→Build BusyBox as a static binary)。

完成后输入命令make 开始编译。最后用命令make install 把编译好的BusyBox文件系统安装到刚刚生成的镜像根文件系统中。

通过以上4个步骤就可以完成Linux内核运行验证系统的搭建。

3 验证演示实例

3.1 验证的内核模块

在本文中将演示验证Linux 内核中虚拟终端(TTY)子系统open操作的运行流程。通过阅读源代码,总结出TTY子系统open操作的主要流程如图1所示。

6357782753806600002796520.jpg

3.2 DDD中显示的内核运行结果

⑴因为在Linux内核中TTY设备被归于字符型设备,所以TTY初始化的第一步是将申请的设备描述结构体的open操作函数指针(def_chrfops->chrdec_open)赋值成字符设备open函数(chrdev_open)的函数指针。 程序代码如下:

const struct file_operations def_chr_fops = {

.open = chardev_open,

.llseek = nop_llseek,

};

⑵调用字符设备子系统的open函数进入char_open函数。相关代码如下:

static int chardev_open(struct *inode,struct file *filp){

struct dev *p;

struct cdev *new =NULL;

int ret = 0;

}

⑶检测内核kobject链表是否有TTY设备,如果找不到这个设备,则返回错误。其内核代码如下所示:

if(!kobj)

return -ENXIO;

new = container_of(kobj, struct codec,kobj);

spin_lock(&cdev_lock);

p = inode->i_cdev;

⑷运行内核 filip结构体的open函数。以下为相关代码:

if(filp->f_op->open){

ret = filp->f_op->open(inode,filp);

if(ret)

goto out_cdev_put;

}

通过DDD对Linux内核运行的检测结果发现,Linux内核中TTY子系统的打开操作的流程与我们通过源代码分析出来的结论是一致的。从而验证了我们流程图的正确性。

4 结束语

本文介绍了一个基于DDD、QEMU、BusyBox工具套件,对Linux内核进行动态检测的方法。通过该方法能够对这个Linux内核的实时运行情况进行监测,从而使内核学习者和研究者对Linux 的整个运行机制有了立体的了解,对内核的运行有直观深刻的印象。本文还以虚拟终端(TTY)子系统open操作为例进行了完整的分析。展示了这个方法对一个具体的应用场景进行动态分析的过程及通过这个套件捕捉到Linux内核函数指针的动态赋值及调用过程。

参考文献

[1] Bovet D P, Cesati M. Understanding the Linux Kernel [M]. O'Reilly,2006.

[2] Wolfgang Mauerer.Professional Linux Kernel Architecture [M]. Wiley India Pvt. Limited, 2008.

[3] Robert Love. Linux Kernel Development [M]. Addison-Wesley Professional, 2010.

[4] Zeller A, Lütkehaus D. DDD-a free graphical front-end for UNIX debuggers [J]. ACM Sigplan Notices [C]. 1996, 31(1): 22-27.

[5] Bellard, Fabrice. QEMU open source processor emulator [OL]. (2007-04-03)[2014-07-15] (2007).

[6] Wells N. BUSYBOX: A swiss army knife for Linux [J]. Linux Journal, 2000, 2000(78es): 10.

[7] Fabrice B. QEMU, a fast and portable dynamic translator[C]. USENIX Annual Technical Conference, FREENIX Track, 2005.

[8] Andersen, Erik. BusyBox[OL]. (2008-01-19)[2014-07-15] BusyBox.net (2008).

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • LINUX内核
    +关注

    关注

    1

    文章

    318

    浏览量

    23053
  • ddd
    ddd
    +关注

    关注

    0

    文章

    23

    浏览量

    3096
  • 函数调用
    +关注

    关注

    0

    文章

    19

    浏览量

    2734
  • qemu
    +关注

    关注

    0

    文章

    57

    浏览量

    5874
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于 DR1M90 的 Linux-RT 内核开发:从编译配置到 GPIO / 按键应用实现(1)

    本手册由创龙科技研发,针对 DR1M90,详述 Linux-RT 实时内核开发:含实时性测试(LinuxLinux-RT 对比、CPU 空载 / 满负荷 / 隔离状态测试)、
    的头像 发表于 12-02 10:38 265次阅读
    基于 DR1M90 的 <b class='flag-5'>Linux</b>-RT <b class='flag-5'>内核</b>开发:从编译配置到 GPIO / 按键应用实现(1)

    Linux内核模块的加载机制

    使用insmod或modprobe命令来加载模块。insmod是直接加载,而modprobe会处理依赖关系。 2、如何工作 那内核模块具体是怎么工作的呢?当执行insmod时,会调用系统调用
    发表于 11-25 06:59

    Linux内核printk日志级别全解析:从参数解读到实操配置

    一、开篇:一个命令引出的核心问题 在 Linux 终端执行 cat /proc/sys/kernel/printk,你可能会看到这样的输出: 这串数字不是随机的,而是内核日志系统的“核心配置开关
    的头像 发表于 11-20 15:54 1258次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>printk日志级别全解析:从参数解读到实操配置

    探索操作系统底层的关键接口

      在linux中,将程序的运行空间分为内核空间与用户空间(内核态和用户态),在逻辑上它们之间是相互隔离的,因此用户程序不能访问内核数据,也无法使用
    的头像 发表于 11-08 12:42 582次阅读

    深入了解系统调用API:探索操作系统底层的关键接口

    ,也无法使用内核函数。当用户进程必须访问内核或使用某个内核函数时,就得使用系统调用(System
    的头像 发表于 11-03 09:20 441次阅读

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 787次阅读

    如何在Linux内核5.18版本之后和64位架构中从内核空间调用ioctl?

    我尝试在最近的内核中重新构建以前版本 (4.19) 的 Linux 设备驱动程序,即嵌入式平台上的 6.1.22,ARM64 架构。 驱动程序管理 tty 设备。 当我调用类似于用户空间
    发表于 04-02 06:06

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    引言本文是对我之前关于RaspberryPi3同一主题的帖子的更新。与之前的帖子一样,我使用的是随Raspbian镜像提供的标准内核,以及应用了RT补丁的相似内核版本。对于实时版,我
    的头像 发表于 03-25 09:39 656次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    如何把两个数据返回给调用函数

    函数的处理结果包含两个数据,如何把两个数据返回给调用函数? 第一种,把两个数据封装成一个结构体,函数返回结构体。 调用
    的头像 发表于 01-08 10:15 679次阅读

    EE-128:C语言中的DSP:从C调用汇编类成员函数

    电子发烧友网站提供《EE-128:C语言中的DSP:从C调用汇编类成员函数.pdf》资料免费下载
    发表于 01-07 13:48 0次下载
    EE-128:C语言中的DSP:从C<b class='flag-5'>调用</b>汇编类成员<b class='flag-5'>函数</b>

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核启动流程

    /kernel/vmlinux.lds可以找到内核入口ENTRY(stext):而stext存在于arch/arm/kernel/head.S中:在stext下有一个__mmap_switched函数:该函数
    发表于 01-07 09:20

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核启动流程

    函数: 该函数存在于arch/arm/kernel/head-common.S,其中有一句跳转指令:b start_kernel 从start_kernel函数开始,内核进入C语言
    发表于 01-06 09:51

    腾讯云内核团队修复Linux关键Bug

    腾讯云操作系统(Tencent OS)内核团队近日在Linux社区取得了显著成果。他们提交的两项改进方案,成功解决了自2021年以来一直困扰众多一线厂商,并在近期让多个Linux顶级
    的头像 发表于 12-31 10:58 916次阅读

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    用户提供移植好的板级开发包。板卡厂商也会对移植好的内核版本进行维护,例如一些BUG修复或者物料替换。接下来讲一下获取这三种源码的方法:获取linux官网源码 地址:https
    发表于 12-16 13:08

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    用户提供移植好的板级开发包。板卡厂商也会对移植好的内核版本进行维护,例如一些BUG修复或者物料替换。接下来讲一下获取这三种源码的方法:获取linux官网源码地址:https
    发表于 12-13 09:03