在远程一台老服务器时,由于存储空间有限,装远程vscode属实有点吃力,只能终端看,就把N年前写过的这篇草稿文找出来更新了一遍,个人还是建议使用界面话的工具阅读代码(例如vscode、sourceinsight等),但vim+cscope+ctags 阅读源码的方式也可以学习一下,毕竟有些场景用这个效率还是很高的。通过以下配置和技巧,实现高效、便捷的代码阅读体验:
一、准备工作
1. 安装必要工具
# Ubuntu/Debian
sudo apt-get install vim cscope universal-ctags
# CentOS/RHEL
sudo yum install vim cscope universal-ctags
# Arch Linux
sudo pacman -S vim cscope universal-ctags
cscope 和 universal-ctags 都是用于代码阅读和导航的工具,常与 Vim 搭配使用,但它们的功能侧重点不同,适合互补使用:
✅ cscope 的功能
cscope 是一个交互式的代码浏览工具,主要用于 C/C++ 项目,支持以下功能:
| 功能 | 说明 |
|---|---|
| 查找函数定义 | 定位函数、变量、宏等的定义位置 |
| 查找函数调用 | 查找调用某个函数的所有位置 |
| 查找被调用的函数 | 查找某个函数内部调用了哪些函数 |
| 查找符号 | 查找函数名、变量名、宏等符号出现的位置 |
| 查找字符串 | 查找指定的字符串 |
| 查找包含文件 | 查找包含某个头文件的所有文件 |
| 查找文件 | 快速打开某个文件 |
| 支持正则表达式搜索 | 类似 egrep,但速度更快 |
cscope的优势在于函数调用关系的查找,这是ctags无法直接做到的。
✅ universal-ctags 的功能
universal-ctags 是 ctags 的现代维护版本,支持更多语言(如 C、C++、Python、Go、Rust 等),功能包括:
| 功能 | 说明 |
|---|---|
| 跳转到定义 | 快速跳转到函数、变量、类等的定义处 |
| 生成 tags 文件 | 生成 tags 文件供 Vim 使用 |
| 支持多种语言 | 比 cscope 更广泛的语言支持 |
| 支持结构体、类、成员等 | 能识别复杂的语法结构 |
| 与 Vim 集成良好 | 支持 Ctrl+] 跳转、Ctrl+o 返回等操作 |
ctags的优势在于快速跳转到定义,但不能查找函数调用关系
2. 生成内核源码索引
进入内核源码目录,生成索引文件:
cd /path/to/linux-kernel-source
# 生成 cscope 索引
cscope -Rbq
# 生成 ctags 索引
ctags -R
✅ 生成的 cscope 索引内容如下:
cscope.out:主数据库文件,包含符号、函数、变量等信息。cscope.in.out和cscope.po.out:是cscope的辅助索引文件,用于加速查找
✅ 生成的 ctags索引内容如下:
tags文件是代码的“目录”或“地图”,让你可以快速跳转到任何符号的定义处。
二、Vim 配置(~/.vimrc)
" 基本设置
"开启语法高亮,让不同类型的代码(如关键字、注释、字符串)显示不同颜色,提升可读性
syntax on
"显示行号,方便定位、调试、跳转
set number
"高亮当前光标所在行,更容易跟踪你正在查看的代码行
set cursorline
"自动将当前工作目录切换为当前打开文件所在的目录,方便使用相对路径。
set autochdir
"Tab 键显示为 4 个空格宽度
set tabstop=4
"自动缩进时使用 4 个空格
set shiftwidth=4
"将 Tab 转换为空格,避免不同编辑器或环境下 Tab 显示不一致
set expandtab
" 启用文件类型检测和插件,根据文件类型(如 .c、.py)自动加载对应的插件和缩进规则
filetype plugin indent on
" ctags 和 cscope 设置
"告诉 Vim 在当前目录查找 tags 文件,用于跳转到函数/变量定义
set tags=./tags
"启用 cscope 支持,让 Vim 优先使用 cscope 数据库进行符号查找
set cscopetag
" 添加 cscope 数据库,如果当前目录存在 cscope.out 文件,就加载它,用于函数调用、定义等查找
if filereadable("cscope.out")
cs add cscope.out
endif
" 快捷键映射
" 查找函数定义(cs find g是 cscope 的查找定义命令)
nnoremap <F6> :cs find g <C-R><C-W><CR>
" 查找函数调用
nnoremap <F5> :cs find c <C-R><C-W><CR>
" 查找符号
nnoremap <F7> :cs find s <C-R><C-W><CR>
" 查找字符串
nnoremap <F8> :cs find t <C-R><C-W><CR>
" 返回上一个位置
nnoremap <C-o> <C-o>
" 代码折叠,根据语法结构自动折叠代码(如函数、类、结构体等)
set foldmethod=syntax
" 默认展开所有折叠,只有你手动折叠的代码才会收起
set foldlevel=99
三、常用操作技巧
1. 代码导航
- 跳转到定义:将光标放在函数或变量上,按
Ctrl+]或F6 - 返回原位置:按
Ctrl+o或Ctrl+t - 查找调用:将光标放在函数名上,按
F5 - 查找符号:按
F7
2. 代码搜索
- 搜索当前单词:按
*或# - 全局搜索:
:vimgrep /pattern/ **/*.c然后:copen
3. 窗口管理
- 水平分割:
:split - 垂直分割:
:vsplit - 切换窗口:
Ctrl+w+ 方向键(实际测试发现是按住ctrl点击两次w键便会自动跳,与方向键无关)
4. 代码折叠
- 折叠代码:
zc,在大括号处执行 - 展开代码:
zo - 全部折叠:
zM - 全部展开:
zR
四、推荐插件(可选)
使用插件管理器(如 vim-plug)安装:
call plug#begin('~/.vim/plugged')
" 文件浏览器
Plug 'scrooloose/nerdtree'
" 代码补全
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" 语法高亮增强
Plug 'sheerun/vim-polyglot'
" 状态栏美化
Plug 'vim-airline/vim-airline'
call plug#end()
五、实用技巧
-
快速注释:
- 可视模式选中行,按
gc(需要插件支持)
- 可视模式选中行,按
-
快速跳转:
:tag function_name跳转到指定函数
-
查看调用栈:
:cscope find c function_name
-
查看结构体定义:
- 将光标放在结构体名上,按
F6
- 将光标放在结构体名上,按
-
查看宏定义:
- 将光标放在宏上,按
F6
- 将光标放在宏上,按
六、示例工作流程
-
打开内核源码文件:
vim init/main.c -
查找
start_kernel函数定义:
- 将光标放在
start_kernel上,按F6
- 查看调用关系:
- 在函数定义处按
F5查看调用情况
- 查看相关结构体:
- 将光标放在结构体名上,按
F6
-
返回原位置:
- 按
Ctrl+o
- 按
通过以上配置和技巧,你可以高效地使用 Vim 阅读和分析 Linux 内核源码。建议多加练习,熟练掌握这些操作后,阅读效率会大幅提升。
✅ 进阶优化建议
1. 使用 cscope 的增量更新(避免每次全量生成)
Linux 内核代码量巨大,全量生成 cscope.out 很慢。你可以使用 cscope -Rbkq 先生成一次,后续只更新变动的文件:
# 只更新变动的文件
find . -name "*.c" -o -name "*.h" | cscope -Rbkq -i-
2. 使用 cscope_maps.vim 插件增强体验
官方提供的 cscope_maps.vim 插件(GitHub 地址)可以更优雅地集成 cscope 到 Vim,支持:
- 自动加载多个
cscope.out文件(适合多模块内核) - 提供
:CscopeFind命令,避免手动cs find
安装方式(使用 vim-plug):
Plug 'brookhong/cscope.vim'
3. 结合 LSP 和 coc.nvim 实现智能跳转
虽然 ctags 和 cscope 很快,但对复杂 C 语法(如宏、内联函数)支持有限。你可以用 coc.nvim + coc-clangd 实现更精确的跳转:
# 安装 clangd(需 LLVM)
sudo apt install clangd
# 安装 coc-clangd
:CocInstall coc-clangd
在 coc-settings.json 中配置内核头文件路径:
{
"clangd.arguments": [
"--compile-commands-dir=./",
"--header-insertion=never"
]
}
4. 使用 vim-fugitive 查看 Git 历史
Linux 内核使用 Git 管理,安装 vim-fugitive 后可直接在 Vim 中查看代码历史:
Plug 'tpope/vim-fugitive'
常用命令:
:Gblame查看某行代码的最后修改记录:Glog查看整个文件的提交历史
5. 用 vim-tmux 或 vim-terminal 分屏调试
在阅读内核时,可能需要同时查看 dmesg 或 gdb 输出。用 Vim 8 的终端功能:
:terminal # 在 Vim 内打开终端
或配合 tmux:
tmux split-window -h # 水平分屏
⚠️ 常见坑 & 解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
F6 跳转失败 | 未生成 tags 或 cscope.out | 确认在源码根目录执行了 ctags -R 和 cscope -Rbq |
Ctrl+] 跳转到错误定义 | 多个同名符号 | 用 :tselect 手动选择,或改用 coc.nvim 的 LSP 跳转 |
cscope 查找结果为空 | 未包含 .h 文件 | 用 find . -name "*.c" -o -name "*.h" > cscope.files 再生成索引 |
| Vim 打开大文件卡顿 | 语法高亮导致 | 用 :syntax off 临时关闭,或安装 vim-fastfold 插件 |
coc.nvim 提示找不到头文件 | 未配置 compile_commands.json | 用 bear -- make 生成,或手动指定 -I 路径 |
🎯 高效工作流示例(结合 LSP + cscope)
-
打开文件:
vim kernel/sched/core.c -
跳转到
schedule()定义:- 按
gd(LSP 跳转)或F6(cscope) - 若 LSP 失败,自动 fallback 到
cscope
- 按
-
查看调用关系:
:CocList references(LSP)- 或按
F5(cscope 查找调用)
-
查看 Git 历史:
:Gblame查看某行修改记录:Glog查看整个函数的演变
-
调试时:
:terminal打开dmesg -w实时查看日志- 用
:make编译内核,错误直接跳转到对应文件
📌 总结
| 工具 | 适用场景 |
|---|---|
| cscope | 查找函数调用、全局符号、文件依赖 |
| ctags | 快速跳转到定义 |
| LSP (coc.nvim) | 精确跳转、补全、诊断(需配置) |
| vim-fugitive | 查看 Git 历史、追溯代码变更 |
| tmux/终端 | 分屏调试、日志监控 |
如果你有特定需求(如调试驱动、追踪某个子系统),可以进一步优化配置。



1847

被折叠的 条评论
为什么被折叠?



