分析工具

“欲善其事,先利其器”。Linux内核的代码量非常大,如果没有一个好的察看分析工具,那将是一件非常繁琐的事情。

Vim+cscope

cscope,如果你知道ctags,那么它是一个比ctags更强大的工具,如果你不知道ctags,也没关系,cscope使你可以在一大堆的代码中进行轻松查找函数、宏、结构体等标示符定义处、使用点,并进行跳转。

安装

cscope在Fedora和Ubuntu的源里都有,可以直接yum或apt-get。

Fedora下cscope安装好后就直接可以与Vim一起使用,但Ubuntu下安装好cscope后,还要在/ect/vim/vimrc文件的最后添加如下内容:

if has("cscope")set csprg=/usr/bin/cscopeset csto=0set cstset nocsverb" add any database in current directoryif filereadable("cscope.out")cs add cscope.out" else add database pointed to by environmentelseif $CSCOPE_DB != ""cs add $CSCOPE_DBendifset csverb
endif

这使Vim可以自动加载cscope生成的索引文件。要获取更多信息,在Vim中输入“:help cscope"也可以得到。

使用

首先在源码目录下用cscope生成cscope索引文件,

cscope -bqR

当前目录下会生成cscope.out,cscope.in.out和cscope.po.out三个索引文件。

其中参数含义如下:

-b 只生成索引文件,并不进入cscope交互界面;

-q 生成cscope.in.out和cscope.po.out两个文件,加快查找;

-R 遍历子目录。

我只用到这三个命令,如果想了解更多,可以察看help或man文档。

现在就可以用了,如果你不想给自己找一些不必要的麻烦,你应该在有cscope.out,cscope.in.out和cscope.po.out的目录直接运行Vim:

vim .(或者vim ./)

在这里再介绍一个Vim插件NERD tree,此插件可以使vim中的目录更好看,效果图如下:

在Vim中,cscope使用最多的命令是find,可以简写为f。想要获取Vim中cscope的其他命令,可以输入:

:cs help

来获取,结果如下:

cscope 命令:

add  :添加一个新的数据库             (用法: add file|dir [pre-path] [flags])
find :查询一个模式                   (用法: find c|d|e|f|g|i|s|t name)
c: Find functions calling this function
d: Find functions called by this function
e: Find this egrep pattern
f: Find this file
g: Find this definition
i: Find files #including this file
s: Find this C symbol
t: Find this text string
help :显示此信息                     (用法: help)
kill :结束一个连接                   (用法: kill #)
reset:重置所有连接                   (用法: reset)
show :显示连接                       (用法: show)

我经常使用的有:

c 查找一个函数被那个函数调用,此命令仅限于函数对函数。我一般会用s来代替c,因为可能结构体中也有使用了该函数,那么c命令是查不到的,而s就可以。

f 查找一个文件。

g 查找某个函数的定义处。

s 查找一个标示符,结果会包括c、g命令的结果和其他地方使用了此标示符的地方(标示符不同于字符串,它是独立存在的,并不是一个字符串的一部分)。

t 此命令是最耗时的命令,它在代码中查找所有含有此字符串的地方。

最后当你找到你要找的项,输入数字标号就会跳转到你要着的那一项。

实例

代码:Linux内核代码,版本3.5.4

具体函数为fs/btrfs/acl.c文件中的第一个函数btrfs_get_acl。

查找此函数的定义处

在Vim中输入:

:cs f g btrfs_get_acl

查找此函数的定义处,显示如下:

Cscope tag: btrfs_get_acl
#   行    文件名 / 上下文 / 行
1     31  fs/btrfs/acl.c <<btrfs_get_acl>>
struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
2   3100  fs/btrfs/ctree.h <<btrfs_get_acl>>
#define btrfs_get_acl NULL

我们发现有两处,但仔细看看,第二项并不是你要找的,第一项才是你要找的。

查找此函数被那些函数调用

:cs f c btrfs_get_acl

显示如下:

Cscope tag: btrfs_get_acl
#   行    文件名 / 上下文 / 行
1     88  fs/btrfs/acl.c <<btrfs_xattr_acl_get>>
acl = btrfs_get_acl(dentry->d_inode, type);
2    207  fs/btrfs/acl.c <<btrfs_init_acl>>
acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT);
3    253  fs/btrfs/acl.c <<btrfs_acl_chmod>>
acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);

其中上面的内容简单介绍一下,1、2、3是标号;后面跟着的数字是在文件中的行号;后面是文件名;双尖括号里的是调用btrfs_get_acl函数的函数;下面的一行是调用此函数的内容,有时,你可以从文件名和内容猜测是不是你要着的东西。

查找此标示符在那些地方出现

:cs f s btrfs_get_acl
显示如下:
Cscope tag: btrfs_get_acl
#   行    文件名 / 上下文 / 行
1   3095  fs/btrfs/ctree.h <<GLOBAL>>
struct posix_acl *btrfs_get_acl(struct inode *inode, int type);
2   3100  fs/btrfs/ctree.h <<GLOBAL>>
#define btrfs_get_acl NULL
3   7624  fs/btrfs/inode.c <<GLOBAL>>
.get_acl = btrfs_get_acl,
4   7629  fs/btrfs/inode.c <<GLOBAL>>
.get_acl = btrfs_get_acl,
5   7697  fs/btrfs/inode.c <<GLOBAL>>
.get_acl = btrfs_get_acl,
6   7708  fs/btrfs/inode.c <<GLOBAL>>
.get_acl = btrfs_get_acl,
7   7722  fs/btrfs/inode.c <<GLOBAL>>
.get_acl = btrfs_get_acl,
8     31  fs/btrfs/acl.c <<btrfs_get_acl>>
struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
9     88  fs/btrfs/acl.c <<btrfs_xattr_acl_get>>
acl = btrfs_get_acl(dentry->d_inode, type);
10    207  fs/btrfs/acl.c <<btrfs_init_acl>>
acl = btrfs_get_acl(dir, ACL_TYPE_DEFAULT);
11    253  fs/btrfs/acl.c <<btrfs_acl_chmod>>
acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);

从上面的查找内容可以看出,除了刚刚上面两种查找到的结果,其中还有一些其他的项。

其中第一项是此函数的声明;第二项和第八项是查找定义处时就有的;第三项到第七项是其他地方调用到地方,这些地方是结构体对它调用。

想更好的使用,还需要你去慢慢练习

分析方法

方法有多种,看你怎么用!

如果能找到资料,那我们从资料入手,这是最好的办法;

如果我们只能找到一些零散的资料,这些资料中并没有对代码的分析,只是对这个软件进行了一些功能介绍,我们可以从这些功能入手,从这些功能的每一个点入手,找关键字,然后将这些功能定位到代码中,接下来再从代码开始分析;

但有时没有任何的资料,那就要从代码中来,你可以先从代码的入口开始,一般是main函数,但Linux内核代码太大,如果这样分析的话,我们面对的是整个内核代码,这将是一个浩大的工程,你会望而却步的,所以,你要从点入手,内核代码非常规程,模块化特别好,你可以从单个模块入手,然后在这个模块中寻找更小的功能点开始。

资料搜索

首选google,其次百度。搜索是可以将想要搜索的信息精简,放小范围。

搜索多个结果进行对比。

做笔记,我喜欢用MediaWiki作为我的文档管理器,MediaWiki可以很好的对你的文档各个版本进行记录。你可以回到N天前你修改的文档。

经验积累

Linux内核中用到了许多经典的编程思想,我们会经常见到不懂的点,这些点我们可以从网上基本上都能找到,但是,有些点,我们看一遍之后几天又忘了,这时做笔记就尤为重要。

以上都是我的经验之谈,更多还需要自己实践。

转载于:https://www.cnblogs.com/snowsolf/p/Linux-kernel-analyse.html

Linux kernel分析前的准备相关推荐

  1. linux kernel基本构成的内容有下列哪些项_Linux_GUI加速(2)_Linux中的DRM-KMS分析

    在上一小节<Linux GUI加速(1)_GUI系统概述>中,我们从应用层到kernel层大致分析了linux中的图形界面的构成,并在最后给出了kernel中DRM+KMS的软件显示框架以 ...

  2. arm linux kernel 从入口到start_kernel 的代码分析

    Linux系统启动过程分析(主要是加载内核前的动作) 经过对Linux系统有了一定了解和熟悉后,想对其更深层次的东西做进一步探究.这当中就包括系统的启动流程.文件系统的组成结构.基于动态库和静态库的程 ...

  3. Linux内核学习(五):linux kernel源码结构以及makefile分析

    Linux内核学习(五):linux kernel源码结构以及makefile分析 前面我们知道了linux内核镜像的生成.加载以及加载工具uboot. 这里我们来看看linux内核的源码的宏观东西, ...

  4. linux kernel内存映射实例分析

    作者:JHJ(jianghuijun211@gmail.com) 日期:2012/08/24 欢迎转载,请注明出处 引子 现在android智能手机市场异常火热,硬件升级非常迅猛,arm cortex ...

  5. Linux 性能分析的前 60 秒

    Linux 性能分析的前 60 秒 为了解决性能问题,你登入了一台 Linux 服务器,在最开始的一分钟内需要查看什么? 在 Netflix 我们有一个庞大的 EC2 Linux 集群,还有非常多的性 ...

  6. [内存管理] linux kernel内存映射实例分析

    作者:JHJ(jianghuijun211@gmail.com ) 日期:2012/08/24 欢迎转载,请注明出处 引子 现在android智能手机市场异常火热,硬件升级非常迅猛,arm corte ...

  7. linux kernel的spinlock代码导读和分析

    文章目录 一.代码阅读分析 0.spin lock调用流程图 1.再kernel中调用spi_lock()或spin_unlock函数 2.调用raw_spin_lock()和raw_spin_unl ...

  8. linux启动参数怎么传给内核,如何启动内核(vivi与Linux kernel的参数传递情景分析)...

    vivi开发笔记(十七):vivi与Linux kernel的参数传递情景分析(上) 在上一部分提到过了,vivi作为bootloader,向内核传递启动参数是其本职工作之一.要把这个情景分析清楚,不 ...

  9. 高级Linux Kernel Inline Hook技术分析与实现

    2019独角兽企业重金招聘Python工程师标准>>> ==Ph4nt0m Security Team==Issue 0x03, Phile #0x03 of 0x07|=----- ...

最新文章

  1. xp创建虚拟服务器,Xp系统怎么创建虚拟目录?Xp系统创建虚拟目录的方法
  2. sql ROW_NUMBER() 排序函数
  3. sqlserver 事务日志已满和'PRIMARY'
  4. 上海哪个图书馆营业时间最长
  5. 【Codeforces Round #446 (Div. 2) C】Pride
  6. E103-W01产品WiFi无线模块快连技术在智能家居中的应用
  7. Java Statement PK PrepareStatement
  8. java tomcat重启linux_Linux下tomcat重启
  9. 两化融合:唐山探路重工业城市智慧转型
  10. npm install -s -d -g之间的区别
  11. 电脑桌面便签_电脑上哪些便签有提醒功能?求一款好用的电脑桌面提醒便签软件...
  12. java ole excel_Java 添加OLE对象到Excel文档
  13. android 模拟器优化,Android模拟器大幅优化 为开发者谋福利
  14. 台达PLC,触摸屏程序工程案例 含电气图 台达与伺服变频通讯实例
  15. Base64编码原理分析
  16. 高速PCB多层板叠层设计原则
  17. dot格式绘图工具 html,使用dot来绘图
  18. NGFF、M.2、NVME、SATA、PCIE、USB的层次和区别:协议?接口?
  19. Python 中类的继承
  20. windows cmd sqlplus访问Oracle数据库显示?胧淙胗没? SP2-0306: ?∠钗扌А?的问题

热门文章

  1. Qt 软键盘[模拟]之键盘触发事件
  2. ubuntu docker一键安装mysql_mysql5.6在ubuntu下的docker中安装的办法详细说明
  3. php 批量删除cookie,php批量删除cookie的简单实现方法
  4. 2020年哪个pe启动盘干净好用_2020年电压力锅哪个牌子好用又安全?电压力锅什么样的品牌好?每月更新!...
  5. 算法解读 ---- 递归(一)
  6. java生成word 框勾_Java 使用模板生成 Word 文件---基于 Freemarker 模板框架
  7. poj3076(16*16数独)
  8. 微型计算机显示器引线,微型计算机的显示器通常有两组引线,即分别是( )...
  9. 重置linux内核,Linux Kernel 驱动非授权重置统计漏洞
  10. HDU 2833 WuKong