vim开发内核环境

开发环境 Ubuntu 16.04

ctags+cscope

ctags程序通过程序代码生成标签,可以简单将其是为索引。索引用于生成函数、变量、 类成员、宏等的索引,用于管理数据库。利用数据库信息在vim或emacs中查找源代码的函数、变量等数据是,索引可以让搜索变得容易。

ctags 支持的程序包括 C, C++, 汇编等。

  • 安装ctags

sudo apt install ctags

通过ctags生成标签的命令是ctags -R。不过,对于下载的linux内核,不仅有ARM结构,还带有x86在内多种结构代码。解决方法是使用内核源码提供的生成各种结构的ctags标签的脚本:

cd linux-2.6.24
make tags ARCH=x86_64

也可以生成arm架构,使用make tags ARCH=arm

此时在当前目录下生成一个tags文件

ctags只能进行单方向搜索,无法搜索调用的函数;无法输出调用该函数的函数;无法输出该函数调用的函数。

cscopectags诗风相似,但补充了ctags的不足。

sudo apt install cscope

同样,执行以下命令生成

make cscope ARCH=x86_64

将分析文件等目录保存在cscope.files文件之后,就可以用cscope

vim 插件

https://www.vim.org 网站搜索

  • Source Explorer插件(srcexpl.vim

  • NERD tree插件(``)

  • Tag List插件(taglist.vim

创建~/.vim目录,然后将下载的插件复制到该目录下

mkdir ~/.vim
cp Download/SrcExpl-5.3.zip ~/.vim/
cp Download/NERD_tree.zip ~/.vim/
cp Download/taglist_46.zip ~/.vim/

然后进入~/.vim目录创建 plugin 子目录

cd ~/.vim
mkdir plugin
unzip SrcExpl-5.3.zip
unzip NERD_tree.zip
unzip taglist_46.zip

配置vim环境

  • 检查ctagscscope执行文件位置:

$ whereis ctags
ctags: /usr/bin/ctags /usr/share/man/man1/ctags.1.gz

$ whereis cscope
cscope: /usr/bin/cscope /usr/share/man/man1/cscope.1.gz
  • 编辑~/.vimrc

"---------------------------
"vim environment
"---------------------------
set nu            "line number
set ai            "auto indent
set ts=4        "tab size
set bg=dark        "backgroud color

"---------------------------
" ctags database path
"---------------------------
set tags=/home/huatai/src/linux-2.6.24/tags   "ctags db

"---------------------------
" cscope database path
"---------------------------
set csprg=/usr/bin/cscope        "cscope
set csto=0                        "cscope DB search first
set cst                            "cscope DB tag DB search
set nocsverb                    "verbose off

"---------------------------
" Tag List environment
"---------------------------
filetype on                        "vim filetype on
nmap <F7> :TlistToggle<CR>        "F7 key = Tag List Toogling
let Tlist_Ctags_Cmd = "/usr/bin/ctags"  "ctags program
let Tlist_Inc_inwidth = 0        "window width change off
let Tlist_Exit_OnlyWindow = 0    "tag/file finish choice taglist
let Tlist_Auto_Open = 0            "when vim start, window open=off
let Tlist_Use_Right_Window = 1

"---------------------------
" Source Exlorer environment
"---------------------------
nmap <F8> :SrcExplToggle<CR>    "F8 Key = SrcExpl Toogleing
"nmap <C-H> <C-W>h                "move to left window
"nmap <C-J> <C-W>j                "move to down window
"nmap <C-K> <C-W>k                "move to up window
"nmap <C-L> <C-W>l                "move to right window
nnoremap <C-H> <C-W><C-H>
nnoremap <C-J> <C-W><C-J>
nnoremap <C-K> <C-W><C-K>
nnoremap <C-L> <C-W><C-L>

let g:SrcExpl_winHeight = 8     "set SrcExpl Window high
let g:SrcExpl_refreshTime = 100    "refreshing time = 100ms
let g:SrcExpl_jumpKey = "<ENTER>" "jump to definition
let g:SrcExpl_gobackKey = "<SPACE>" "back
let g:SrcExpl_isUpdateTags = 0     "tag file update = off

"---------------------------
" NERD Tree environment
"---------------------------
let NERDTreeWinPos = "left"        "NERD Tree at left
nmap <F9> :NERDTreeToggle<CR>    "F9 Key = NERD Tree Toggling

然后打开vim之后,按下F7F8F9可以切换出Tag ListSource ExporerNERD Tree分割窗口。

使用ctrl+h/j/k/l可以在各个窗口间切换。

原文中使用了nmap <C-L> <C-W>l来映射窗口切换快捷键,但是我在Mac上iTerm2中使用遇到不能切换,反而是将屏幕分割的问题。改成nnoremap <C-H> <C-W><C-H>才解决。

代码浏览

在光标切换到奥Tag List窗口后,通过进入vim的ex模式(按下Esc键),然后在下方窗口输入:/start_kernel,就能够移动到start_kernel符号,此时按下Enter键,代码文件窗口就会显示定义start_kernel的位置。

在代码中移动光标放到函数或变量上时,下方的Source Explorer窗口就会显示定义相应符号的位置。例如,光标移动到start_kernel(void)函数时,下方的Source Explorer窗口显示的时start_kernel符号定义的文件。

移动到下端窗口(ctrl+j),选择列表中的1项(Enter键),在代码中就会显示该文件。此时,通过不断ctrl+j转跳可以不断浏览引用该函数的文件。

如果要回退到当前状态之前的位置,则按下空格键(space bar)就可以回到之前状态。

ctags

使用ctrl+]可以根据当前光标所在的关键字跳转到它的定义处。

当使用这种方法浏览整个代码库时,vim会为访问过的标签维护一个历史列表。使用ctrl-t按键就会回退当上一个定义处。再次按下ctrl-t就会返回原位。

cscope

当光标移动到某个符号时,如果Source Explorer窗口显示Definition Not Found信息(表示无法查找该符号),则可以通过cscope指令得到相关文件列表。

方法是先切换到ex模式,然后输入:cs find s kthread_create_list

这里使用cscope提供多种<querytype>,使用方法如下:

: cs find <querytype> <name>
  • s 查找C符号

  • g 查找定义(definition)

  • d 查找被该函数调用的(called)函数

  • c 查找调用该函数的(calling)函数

  • t 查找文本字符串(text string)

  • e 查找egrep犯事

  • f 查找文件

  • i 查找用#include包含该文件的文件

如果想获得cscope的帮助,可以在vim中转换为ex模式,然后通过:help cscope查看详细信息

参考

  • 《ARM Linux内核源码剖析》

Last updated