使用Clion 阅读/修改/注释 Linux 内核源码

2023-11-03

前言

其实,bootlin就是一个听不错的阅读源码的工具了,可以非常方便的帮我们查阅函数、宏的定义、引用等等。而且是基于浏览器,对我们本机的配置没有什么过高的要求。

但是如果想要做一些注释,修改,那我们就要将源码下载到本地了,这个时候我们可能就需要其他的工具了。

Clion我最熟悉的C/C++ IDE,我非常喜欢Jetbrains家族的IDE,因此使用Clion来阅读/注释/修改源码,就成了我的首选,很可惜的是,Linux kernel是通过Makefile进行构建的,然后Clion是用的是CMake,因此如果我们想要借助Clion来阅读源码,就需要生成Linux kernel的Cmake文件!

目前来看,可以成功的实现使用Clion来阅读/注释/修改源码,但是不能成功的进行编译,因此编译还得用make,不过这个无伤大雅!

配置要求

Clion需要大量的缓存内核文件,因此我们必须保证本机有足够的内存,并调高Clion的堆内存配置,本机至少要有8G内存,Clion堆内存至少调整到4G以上。配置方法:

点击CLion的状态栏上的"Help->Change Memory Settings",然后修改"MAX Heap Size",如下图所示,我将其调整到了8G,我本机有24G。然后重启配置生效!

源码准备

安装编译必须的工具

sudo apt update && sudo apt upgrade
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

下载源码,最好到The Linux Kernel Archives下载源码的压缩包,然后再解压!

tar -zxf linux-5.14.2.tar.xz
cd linux-5.14.2

使用本机的配置文件来配置内核

cp /boot/config-$(uname -r) .config
make menuconfig

上述过程其实就是编译内核的步骤。

注意:
直接使用ubuntu的.config在编译时可能遇到如下的错误:

make[1]: *** No rule to make target 'debian/certs/benh@debian.org.cert.pem', needed by 'certs/x509_certificate_list'

此时需要编辑一下.config,将CONFIG_SYSTEM_TRUSTED_KEYS置为空:

CONFIG_SYSTEM_TRUSTED_KEYS = ""

生成CMakeLists.txt

安装bear工具,bear可以根据追踪make编译的过程,生成compile_commands.json文件,然后我们在通过其他工具通过compile_commands.json最终生成CMakeLists.txt

sudo apt-get install bear

使用bear,make编译内核。最新的bear应该需要在bear和make之间加上"–"。make的"-j12"表示启用12个线程同时编译,这取决你本机的core数,这个过程需要很久!

bear make  -j12

2020年 9月21日更新
之前我一直使用 make -j12来编译内核,在我这台拥有12个core的机器上,编译时间也长达30分钟,直到前几天我才发现,这样其实是非常蠢的,因为make -j12其实默认编译了所有的内容,但是如果我们仅仅编译内核,只需要编译vmlinux即可,后面为了使用qemu来调试,在加上bzImage就行了,即make -j12 vmlinux bzImage,这样一来,编译的时间只需要不到5分钟,最终生成Cmakea文件也只有5MB左右,这样Clion就可以无需那么高的内存配置了!

克隆kernel-grok项目

cd ~
git clone https://github.com/habemus-papadum/kernel-grok

回到内核目录,生成CMakeLists.txt

cd linux-5.14.2
~/kernel-grok/generate_cmake  ## creates CMakeLists.txt

修改CMakeLists.txt

这个时候需要我们手动添加一些参数配置

在文件的最开头添加以下内容:

cmake_minimum_required(VERSION 2.8.8)
project(kernel)

set(SYSROOT sysroot)
SET(CMAKE_C_COMPILER "gcc")
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_FLAGS  ${CMAKE_C_FLAGS} " --sysroot=${SYSROOT}" )

include_directories("include")
include_directories("include/uapi")
include_directories("arch/x86/include")
include_directories("arch/x86/include/uapi")
include_directories("arch/x86/include/generated")
include_directories("arch/x86/include/generated/uapi")

add_definitions(-D__KERNEL__)

添加内容主要包括:

  1. 修改sysroot,这需要首先在CMakeLists.txt的同目录下创建一个名为sysroot的空目录,然后设置编译参数"–sysroot=${SYSROOT}",这是因为sysroot其实是C标准头文件的位置,显然内核是不需要这些东西的,他们存在反而会干扰clion寻找正确头的文件,产生一下不必要得冲突
  2. 添加头文件路径,如果不进行这一步,那么clion将会出现大量的错误,提示找不到头文件或者变量、常量、函数等。具体添加的内容是我反复测试过的,添加这些内容后基本上保证头文件寻找正确,其中后四个是与架构相关的,x84_64可放心使用
  3. 使用C90的C语言标准,一开始我使用的是Clion的默认C标准,一直没有出过问题,但是昨天一下子就出现大量报错,不排除是因为我升级了最新的Clion 2021.2.2 ,最终加上了set(CMAKE_C_STANDARD 90)才恢复正常

启动CLion

点击状态栏"File->Open",然后选中我们创建的CMakeLists.txt,确定后选择"Open as Project"

然后Clion会自动加载Cmake,目前最终会加载失败,因为这个方法并不能用来编译内核!

这时候查看内核源码,正常是没有任何红色报错信息,可以正常的进行跳转和自动补全。

问题

除去不能编译外,还有一个问题,那就是编译选项的宏定义,显示不正常:

上面是task_struct中的一段代码,clion的代码显示表明找不到CONFIG_MEMCG,因此也就没有定义memcg_data,但是按住Ctrl是可以跳转到CONFIG_MEMCG的定义的,就在include/generated/autoconf.h中,这个很奇怪!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Clion 阅读/修改/注释 Linux 内核源码 的相关文章

  • 有谁知道在哪里定义硬件、版本和序列号。 /proc/cpuinfo 的字段?

    我想确保我的 proc cpuinfo 是准确的 目前它输出 Hardware am335xevm Revision 0000 Serial 0000000000000000 我可以在代码中的哪里更改它以给出实际值 这取决于 Linux 的
  • ubuntu:升级软件(cmake)-版本消歧(本地编译)[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我的机器上安装了 cmake 2 8 0 来自 ubuntu 软件包 二进制文件放置在 usr bin cmake 中 我需要将 cmake 版本至少
  • 如何授予 apache 使用 NTFS 分区上的目录的权限?

    我在一台带有 20GB 硬盘的旧机器上运行 Linux Lubutu 12 10 我有一个 1 TB 外部硬盘 上面有一个 NTFS 分区 在该分区上 有一个 www 目录 用于保存我的网页内容 它在启动时自动安装为 media t515
  • 将 jar 作为 Linux 服务运行 - init.d 脚本在启动应用程序时卡住

    我目前正在致力于在 Linux VM 上实现一个可运行的 jar 作为后台服务 我已经使用了找到的例子here https gist github com shirish4you 5089019作为工作的基础 并将 start 方法修改为
  • 在我的 index.php 中加载 CSS 和 JS 等资源时出现错误 403

    我使用的是 Linux Elementary OS 并在 opt 中安装了 lampp My CSS and JS won t load When I inspect my page through browser The console
  • jq中如何分组?

    这是 json 文档 name bucket1 clusterName cluster1 name bucket2 clusterName cluster1 name bucket3 clusterName cluster2 name bu
  • Linux 上有关 getBounds() 和 setBounds() 的 bug_id=4806603 的解决方法?

    在 Linux 平台上 Frame getBounds 和 Frame setBounds 的工作方式不一致 这在 2003 年就已经有报道了 请参见此处 http bugs java com bugdatabase view bug do
  • CoAP数据包的大小是多少?

    我是这项技术的新手 有人可以帮助我了解一些疑问吗 Q 1 CoAP数据包的大小是多少 我知道有 4 字节固定标头 但是包括标头 选项和负载在内的最大大小限制是多少 Q 2 有像MQTT那样的Keep Alive的概念吗 它在UDP上工作 它
  • 需要一些建议来开始在 ARM(使用 Linux)平台上编程

    我 也许 很快就会在托管 Linux 发行版的 ARM 平台上工作 我不知道哪个发行版 我知道该项目涉及视频流 但我无法告诉你更多信息 其实我只收到通知 还没见到任何人 我从来没有在这样的平台上工作过 所以我的想法是在项目开始之前进行测试
  • waitpid() 的作用是什么?

    有什么用waitpid 它通常用于等待特定进程完成 或者如果您使用特殊标志则更改状态 基于其进程 ID 也称为pid 它还可用于等待一组子进程中的任何一个 无论是来自特定进程组的子进程还是当前进程的任何子进程 See here http l
  • 在两次之间每分钟执行一次 Cronjob

    我需要在 crontab 中每分钟运行一个 bash 脚本8 45am and 9 50am每天的 Code 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 8 home pull sh gt ho
  • 快速像素绘图库

    我的应用程序以每像素的方式生成 动画 因此我需要有效地绘制它们 我尝试过不同的策略 库 但结果并不令人满意 尤其是在更高分辨率的情况下 这是我尝试过的 SDL 好的 但是慢 OpenGL 像素操作效率低下 xlib 更好 但仍然太慢 svg
  • Urwid:使光标不可见

    我正在使用 urwid 它是一个用于在 ncurses 中设计终端用户界面的 Python 框架 但有一件事我在 urwid 中无法做到 而这在 Curses 中很容易做到 使光标不可见 现在 选择按钮时光标是可见的 而且看起来很丑 有办法
  • 在 C++ linux 中将 STRINGS 写入串口

    我知道这个问题遍布互联网 但仍然没有任何东西能让我完全解决这个问题 我想用 C linux 将数据写入 Propeller 板的串行端口 从控制台获取输入时程序运行良好 但是当我向它写入字符串时总是返回 ERROR Invalid comm
  • Mcrt1.o和Scrt1.o有什么用?

    我坚持使用以下两个文件 即 Mcrt1 o 和 Scrt1 o 谁能帮我知道这两个文件的用途 如何使用它 我们以 gcrt1 o 为例 在使用 pg 选项编译进行性能测试时非常有用 谢谢 表格的文件 crt o总是 C 运行时启动代码 大部
  • 如何编译一个简单的 multiboot2 裸机可执行文件?

    我想开始写一个操作系统内核 然后 我找到了一个document http nongnu askapache com grub phcoder multiboot pdf引入 multiboot2 规范 有三个示例代码文件 名为boot S
  • 如何在 GNU/Linux 上设置 Subversion (SVN) 服务器 - Ubuntu [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一台运行 Ubuntu 的笔记本电脑 我想将其用作 Subversion 服务器 既让我自己在本地承诺 也让其他人远程承诺 要使其
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • Fedora dnf 更新不起作用?

    当我尝试使用 update 命令更新 Fedora 22 时 sudo dnf update 我收到以下错误 错误 无法同步存储库 更新 的缓存 无法准备内部镜像列表 Curl 错误 6 无法解析主机名 无法解析主机 mirrors fed
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐

  • JavaWeb-form传值(从一个jsp页面传数据到另一个jsp页面)

    第一个页面 login jsp
  • OkHttpClient获取文件并下载

    需要调用第三方接口获取文件 本地通过网页直接下载 public Result doExcelExport String repoId HttpServletResponse response try if StringUtils isBla
  • nginx配置指南

    nginx conf配置 找到Nginx的安装目录下的nginx conf文件 该文件负责Nginx的基础功能配置 配置文件概述 Nginx的主配置文件 conf nginx conf 按以下结构组织 配置块 功能描述 全局块 与Nginx
  • 行为型设计模式之策略模式【设计模式系列】

    系列文章目录 C 技能系列 Linux通信架构系列 C 高性能优化编程系列 深入理解软件架构设计系列 高级C 并发线程编程 设计模式系列 期待你的关注哦 现在的一切都是为将来的梦想编织翅膀 让梦想在现实中展翅高飞 Now everythin
  • C++基础---递归函数

    1 递归函数 1 1 递归函数的定义 递归函数 即在函数体中出现调用自身的函数 即函数Func Type a 直接或间接调用函数本身 递归函数 在数学上 关于递归函数的定义如下 对于某一函数f x 其定义域是集合A 那么若对于A集合中的某一
  • centos安装常见软件

    安装tar yum install y tar 安装zip yum install unzip y 安装上传 yum y install lrzsz y 安装git 方式一 yum install git y 方式二 开发会用的软件 yum
  • STM32F1应用DMA——串口收发不定长数据

    STM32F1应用DMA 串口收发不定长数据 使用STM32自带DMA传输数据 可以减轻CPU负担 只需设置一些参数即可发送想要发送的数据 以下是STM32F1系列芯片测试过的部分代码 可实现DMA串口收发数据 下图来自STM32官网的手册
  • webrtc中peerconnection_client生成vs工程文件

    下面是将peerconnection client从整个webrtc工程文件中分离出来的过程记录 一 webrtc项目的本地编译 生成Ninja配置文件 gn gen target x64 args is clang false use l
  • Matplotlib绘制动图以及绘制平滑曲线

    文章目录 绘制动图 FuncAnimation 方法 ArtistAnimation 方法 绘制平滑曲线 使用 scipy ndimage gaussian filter1d 高斯核类绘制平滑曲线 使用 scipy interpolate
  • python怎么做多个矩阵_用Python程序添加两个矩阵

    用Python程序添加两个矩阵 在此程序中 您将学习使用嵌套循环和Next列表理解来添加两个矩阵 并显示它们 要理解此示例 您应该了解以下Python编程主题 在Python中 我们可以将矩阵实现为嵌套列表 列表内的列表 我们可以将每个元素
  • openmpi编译安装

    概念原理 OpenMPI是一个免费的 开源的MPI实现 兼容MPI 1和MPI 2标准 OpenMPI由开源社区开发维护 支持大多数类型的HPC平台 并具有很高的性能 功能描述 OpenMPI借助TCP IP网络连接的多台计算机 以此分发数
  • 经典多模态模型

    整点传统多模态学习 下游任务 在讲模型之前 我们先说说 传统多模态任务是下游任务 图文检索 Image Text Retrieval 里面包含图像到文本检索 文本到图像检索 给定一个数据库 搜索到ground truth的图像文本对 因为是
  • NDIS网络数据监控程序NDISMonitor(2)-----驱动与应用的中间层NdisHook

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 本工程是驱动vpcknt的一个封闭层而已 比较简单 一 导出的API接口分析 1 Start 1 加载驱动vpcknt sys vpckn
  • List转换String,String转List的几种方法

    一 List转String的方法 将一个Java集合List转换为String方法比较多 可以使用String join StringBuilder Stream流等方法 下面举几个常用的示例 1 使用String join 方法 impo
  • c51语言的指针分几类,- 第五课 C51变量

    sfr P1 0x90 这里没有使用预定义文件 sbit P1 0 P1 0 而是自己定义特殊寄存器 sbit P1 7 0x90 7 之前我们使用的预定义文件其实就是这个作用 sbit P1 1 0x91 这里分别定义P1端口和P10 P
  • react-router-dom v6的变化

    react router dom v6 原文地址 1 useNavigate替代useHistory 在v6版本useHistory被新hookuseNavigate代替 用法也发生的很大的变化 v5 import useHistory f
  • 如何画出频谱图 matlab

    如何画出频谱图 matlab matlab 代码 绘制出的图片 matlab 代码 fs 100 sample frequency Hz t 0 1 fs 10 1 fs 10 second span time vector x 1 3 s
  • R中prophet包说明文档(一)

    名称 自动预测过程 版本 0 2 1 日期 2017 11 08 描述 实现了一个时间序列的预测过程 基于能够拟合年度 周等周期以及假期等因素的非线性趋势的加法模型 模型要求至少一年以上的周期性历史数据 prophet模型对于缺失值 趋势突
  • PHP实现网站访问量计数器 两种方法

    1 原生 简单的网站访问量计数器实现 具体如下 首先说明思路 1 用户向服务器发出访问请求 2 服务器读取访问次数文件 1 向客户端返回 3 服务器保存新的浏览次数 4 新用户访问 重复123即可 解决方案 主要算法 1 数据文件 coun
  • 使用Clion 阅读/修改/注释 Linux 内核源码

    前言 其实 bootlin就是一个听不错的阅读源码的工具了 可以非常方便的帮我们查阅函数 宏的定义 引用等等 而且是基于浏览器 对我们本机的配置没有什么过高的要求 但是如果想要做一些注释 修改 那我们就要将源码下载到本地了 这个时候我们可能