知识分享:一文教你如何优雅的阅读linux内核源码

首先,我目前见到的最常见的编辑器是vscode和neovim,本文所介绍的方法完美适配这两个编辑器~

阅读代码的痛点

  1. 难以正确跳转

读代码应该都遇到过一个问题就是,有时候很多的同名函数,在编译链接的过程你不知道具体链接到了哪个,虽然vscode和neovim的ctag都有全局的搜索,但是满屏的同名函数一个一个去找,实在是不优雅~

  1. 对复杂的结构嵌套没有全局视角

例如如果遇到复杂的驱动,以v4l2举例,一个struct不仅包含很多个struct,而且为了减少->的使用,还会将里面包含的struct的一些成员提到顶层,以及还会有指向父struct(暂且这么叫)的指针,如果第一次梳理源码,这种复杂的结构会给阅读代码带来了极大麻烦

  1. 不同版本之间代码变动,接口弃用,但不知道原因

在版本更新的过程中,经常遇见一些情况导致以前使用的接口在新版中弃用,那么为了更好的使用新版本,就需要对搞懂这些原因

ok,uu们如果你也苦于上面的情况,希望这篇文章能帮大家更好的阅读源码~

解决方法

优雅跳转

主要使用的是compile_commands.json这个文件,这个是clangd的lsp使用到的,其中记录了一个文件编译过程中使用到的文件,如果有这个文件,那么完成正确的跳转,就不在话下了~

  1. 首先需要编译linux源码,不管是clangd,还是交叉编译链都可以。

2.1 linux kernel源码,如果用clangd构建指定好LLVM还是可以使用下面的指令得到 compile_commands.json 这个文件的。

./scripts/gen_compile_commands.py 

2.2 但是对于 aarch64-linux-gnu-gcc 这个交叉编译链,会生成clangd无法识别的指令,所以需要在linux kernel源码目录下

touch .clangd

并且在 .clangd 中输入下面的内容

CompileFlags:       
  Remove: -mabi=lp64
  1. 再启动lsp,就可以发现可以直接跳转啦~(vscode是clangd的插件,nvim如果使用的是lazyvim,不需要额外配置)

ps:这里使用的clangd,可能在执行过程中缺少一些程序包,apt install就好

复杂的嵌套结构可视化

原理

内核每个源文件编译会生成 .xx.o.cmd 的隐藏文件,里面包含了依赖源文件和头文件列表

      如imx219.c对应的 .imx219.o.cmd  里
     3  source_drivers/media/i2c/imx219.o := ~/linux/vender/nvidia/drivers/media/i2c/imx219.c
     4
     5 deps_drivers/media/i2c/imx219.o := \
      6     $(wildcard include/config/of.h) \
      7   include/linux/slab.h \
      8     $(wildcard include/config/debug/slab.h) \
      9     $(wildcard include/config/debug/objects.h) \

主要就是使用doxygen来生成,并且可以配合一下graph软件,生成可视化的图

步骤

  1. 安装软件
 $ sudo -H pip3 install filetype pygraphviz
$ sudo apt-get install build-essential python3-dev libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev
$ sudo apt-get install python3-pygraphviz 
$ sudo apt-get install doxygen-latex doxygen-doc doxygen-gui graphviz
$ doxywizard //doxygen启动
配置
  1. 内核源码中实际编译的文件列表
//kernel_src_dump.py
#!/usr/bin/env python
import sys
import os
import os.path
import time
import re
import argparse
 
KERNEL_BASE  = os.getcwd()
KERNEL_SRC = os.getcwd()
KERNEL_OUT = os.getcwd()

def kernel_depfile_2_flist(depfile, filelist) :
    fobj = open(depfile, "r")
    for line in fobj :
        txt = line.strip()
        if 0 == len(txt) :
            continue
        if txt.startswith("cmd_") :
            continue
        if txt.startswith("deps_") :
            continue
        if txt.startswith("$(deps_") :
            continue
        if txt.endswith(".o)") :
            continue
 
        if txt.endswith(" \\") :
            txt = txt[:-2]
 
        if txt.startswith("$(wildcard ") and txt.endswith(")"):
            idx_start = len("$(wildcard ")
            tmp_txt = txt[idx_start : -1]
            pre_path = KERNEL_OUT
            relative_path = os.path.join(pre_path, tmp_txt)
            abs_path = relative_path
            if KERNEL_BASE in KERNEL_OUT:
                pre_path = KERNEL_OUT[len(KERNEL_BASE) +

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

1. 自我介绍:高通、Oppo(sp)、vivo(sp)、小米(ssp)、荣耀(26k*12+80k)、华子(报批中)、美团、韶音、经纬恒润、乐鑫、中兴、TP 2. 内容: 1.嵌入式学习的资料和路径 2.所有面试的题目和解答(持续更新)、对评论的快速解答 3.各种碎碎念 3.整理不易,buy me coffee☕️,为了回馈牛客和各个粉丝,文章都会先试读几天,热度过了再收录~

全部评论
给点花花吧,求求了~
1 回复 分享
发布于 2024-12-30 12:46 湖北
送花了
点赞 回复 分享
发布于 01-02 17:13 北京

相关推荐

评论
13
6
分享

创作者周榜

更多
牛客网
牛客企业服务