常用的源代码阅读工具有:

  • lxr

  • Source Insight

  • vim+ctags

我们推荐使用vim+ctags。这里以vim+ctags为例,介绍阅读源代码的最常用的功能。

安装

首选确保自己的电脑上安装了vim-full和exuberant-ctags.对于ubuntu用户可以使用一下命令来安装:

#aptitude install vim-full exuberant-ctags

之后在内核源代码的目录下运行:

#ctags -R .

这样就可以生成一个tags文件,这个文件保存着各个函数,宏以及全局变量和文件的对应关系,vim就是根据这个文件的信息来实现类似Virtual C++中的代码索引,跳转等功能。


跳转

在源代码阅读过程中,最常用的就是跳转到一个指定的函数的代码块中。

  • 下面我们先介绍最常用的跳转功能

首选在内核源代码目录中,运行vim,然后输入:
:tj start_kernel

如果tags文件中只有一个标号为start_kernel的索引,就会直接跳转到这个start_kernel函数的定义中,如果有多个标号为 start_kernel的索引,vim会列出各个start_kernel和它所在的文件的对应关系,用户可以通过数字键来选择需要浏览的是哪一个文件 中的start_kernel。

  • 跳转快捷键

每一次通过tj xxx来跳转不方便,把光标移动到某个函数上,

然后输入:
CTRL-]

假设光标所在的位置是setup_arch,这样就直接跳转到setup_arch函数中,注意tags文件中可能有多个标号为setup_arch的索引,CTRL-]总是跳转到索引中的第一个setup_arch函数。

这时可以输入:
g-CTRL-]
先按g,然后同时按下CTRL+],这样vim就会列举出所有的setup_arch函数和文件的对应列表,让您选择浏览。
  • 查看历史记录

现在,在vim中输入:
:tags

就可以列举出当前的历史浏览记录如下:
# 到 tag 从 行 在 文件/文本
1 1 start_kernel 1 init/main.c
2 8 setup_arch 541 init/main.c
  • 跳转回上一个函数

在初步浏览了setup_arch函数之后,您可能想要回到start_kernel函数,

于是在vim中输入:
CTRL+t
这样就跳转到了上一级tag了,此后,您可能又需要浏览setup_arch函数,此时您不需要输入setup_arch也不需要把光标移动到setup_arch,
只需要在vim输入:
:tag
就可以前进到setup_arch函数中,这是因为vim把最近的浏览历史保存在一个堆栈中,您可以在vim中输入tags来查看这个堆栈。
  • 局部变量的跳转

假设您现在正浏览setup_arch代码块,由于setup_arch函数很长,您遇到一个局部变量max_low_pfn,此时您想跳转到这个 变量的定义的地方,使用CTRL-]是不行的,因为CTRL-]是根据ctags文件中的索引来跳转的,而这个索引文件只会保存全局的变量函数等信息,试 想如果局部变量也保存索引的话,那么像i,j,k这一类的变量的索引就会非常的多。此时您可以把光标移动到max_low_pfn的下面,

然后在vim中输入:
gd
此时就会跳转到setup_arch函数中的max_low_pfn定义的地方(记住Goto Definition,就记住了这个命令)。

文件跳转

Vim还能记住您浏览文件的历史记录,这样就可以方便的在各个文件直接进行跳转。您可以在vim中输入:

:ls
这样您就可以看到您曾经打开过的文件列表,每一个文件都对应一个编号,您可以通过下面的命令跳转到编号为N的文件中:
:b N

文本搜索

另外,在源代码阅读过程中,文本搜索也是最常用的功能,下面我们来介绍如何在vim中更加方便的使用文本搜索。

假设您需要在init/目录中搜索包含command_line的文件

可以在vim中输入:
:grep -r "command_line" init/ --include=*.c
--include=*.c的作用是规定只在.c的文件中搜索。之后在vim中输入:
:cw
这时vim被分成两个窗口,其中下面的显示搜索的结果,
您可以在vim中输入:
CTRL-w
在这两个窗口之间切换(您可以使用窗口-window来记住它。)。

现在把光标移动到下面的窗口,通过h,j,k,l移动光标,之后按下回车,光标下面那一行的文件就出现在上面的窗口了。


taglist

有时候,打开一个文件,我们希望能够像Virtual C++那样,把这个文件中的所有函数,宏等信息按照树形结构列举出来,同时可以方便的选择浏览。在vim中,这需要借助taglist插件。到下载最新的taglist插件,解压缩后得到两个目录,plugin和doc。您可以根据Installation的指导安装。

对于ubuntu用户,把这两个目录拷贝到/etc/vim目录下,然后在vim中输入:
:helptags /etc/vim/doc
这样是为doc中的帮助文件生成索引,以后可以在vim中通过:
:help xxx
来查看taglist的xxx的帮助文件的内容。

现在进入内核目录下(确保根目录下已经有tags文件。),然后打开某个.c文件,

此时在vim中输入:
:TlistOpen
这样就在左边出现一个窗口,以树形结构显示当前的.c文件中的宏,全局变量以及函数。同样您可以通过输入:CTRL-w 在这两个窗口之间切换。当您把光标移动到Taglist的窗口之后,可以移动光标到想要浏览的函数名上,然后按下回车,此时您就可以在左边的窗口浏览这个函数的代码了。
如果您想关闭Taglist的窗口,可以输入:
:TlistClose
或者把光标移动到Taglist的窗口,输入:
:q

在Virtual C++中,我们可以折叠或者展开树形列表中的函数、变量、宏,vim也是可以的。把光标移动到Taglist的窗口中,如果您要折叠宏的树形列表,确保光标位于宏的树形列表中的任何位置,

输入:
zc
如果要展开,就输入:
zo
您可以通过close和open来记住他们。

当您打开另外一个.c文件时,前面的那个文件的taglist和新文件的taglist都会出现在Taglist的窗口中,这样随着打开的文件的增多,taglist也会越来越多,浏览的时候很不方便,为了保证Taglist的窗口中只出现当前文件的tags,

可以在vimrc文件中加入:
let Tlist_Show_One_File = 1 "不同时显示多个文件的tag,只显示当前文件的

到此为止,您已经能够很方便的浏览源代码了,只要您坚持使用,您将会逐渐掌握更多的vim技能。

参考资料:vim中文文档 ​​​​​