VSCode搭建内核源码阅读开发环境

0. 参考链接

使用VSCode进行linux内核代码阅读和开发_vscode阅读linux内核-CSDN博客

Ubuntu下的内核编译(打造最精确的编译步骤)_ubuntu 内核编译-CSDN博客

【Linux】(Ubuntu)内核编译 && 镜像制作_ubuntu 内核编译-CSDN博客

vscode更新至1.86版本后,ssh远程连接服务器出现异常_you are about to connect to an os version that is -CSDN博客

1. 搭建Linux内核源码阅读环境

现状,Linux内核源码比较庞大,同时支持多个硬件平台(例如 kernel-/arch/xx 目录,每一个处理器指令集对应一个目录),其中又包含大量的 ‘#ifdef xxx’ 宏定义开关配置选项,往往对于一个变量名或者函数名在内核源码中对应着多个版本,搞不清楚当前到底使用的那个变量或函数版本,这使得阅读内核源代码称为一件头疼的事。

主要的解决方案有:

  1. 使用 文本浏览工具 + grep 命令来搜索内核源码,这种方式最简单,效率也最低
  2. 使用 SourceInsight 进行内核代码浏览,这种方式使用的人最多,但是在浏览内核源码文件时有多个硬件平台的头文件和源码配置,如果不做排除在进行符号跳转的时候往往会找到多个同名函数或定义。最重要的是 SourceInsight 是商业收费软件,需要付费购买才能使用。
  3. Vim + ctags ,这种方法比较高大上,但是比较适合Linux高手使用,对于初学者有可能玩不太转。
  4. VSCode + C++ Intellisense插件或者global插件,和SourceInsight类似,在源码符号跳转时往往会找到多个同名函数或定义。

阅读内核源码的主要痛点在于,查看一个内核函数或者宏,一个函数或宏对应着很多用 ‘#ifdef CONFIG_XXX’ 隔离起来的多个版本,并且在不同的硬件平台上又有不同的多种版本,造成我们不清楚当前开发的平台上到底使用的是哪一个内核函数版本。

新的方法

参考引用链接中的方法,可以使用 VSCode + RemoteSSH + Clangd 插件来构建内核源码阅读开发环境。其中 VSCode 作为强大的源码文本浏览编辑器,负责主题框架和显示。RemoteSSH访问远程服务器,实现远程代码的本地访问。Clangd 用于代码语义分析,代码补全,代码跳转等。该方案几乎克服了上面列出的几种方案的所有缺点,能够做到代码精准跳转,代码精准补全,其它的默认如代码颜色着色,代码缩进等都是VSCode自带的。另外,最重要的是这些是免费的。

除了 VSCode IDE 之外,该方案的核心是 Clangd 插件,clangd插件通过读取工程编译期间生成的 ompile_commands.json 文件来索引其中包含的源文件和关联的头文件,因此能避免所引导非编译代码造成的符号语义解析混乱。

compile_commands.json 文件就是由每个源文件的编译参数,路径等信息组成的一个json 文件,clangd 通过这个文件可以准确定位源文件引用的头文件从而精确的找到各种宏定义,函数,变量声明的准确值。

那么问题来了,编译内核的时候也没有生成 compile_commands.json 文件。在这文件在编译 cmake 工程的时候可以调用 cmake 命令时添加 -DMAKE_EXPORT_COMPILE_COMMANDS=on 参数,编译的时候回自动生成。但是内核使用的是make,这就需要另一个工具bear了,它就是专门用来生成这个 compile_commands.json 文件的。

在 Unbuntu 下直接使用 apt install bear 来安装 bear 工具就可以了。

sudo apt install bear

使用 bear 来生成内核编译 json 文件的方法也很简单,只需要在你平时编译内核的命令前加上 bear 就可以了,例如:

bear make ARCH=arm CROSS_COMPILE=arm-linux-gnu- zImage

2. 查看并下载需要的内核版本

当前想在 x86 32bit Ubuntu-14.04 Virtualbox 虚拟机上测试和开发Linux内核模块(驱动),所以我想阅读下当前我安装的 x86 32bit Ubuntu-14.04 Virtualbox 虚拟机内核编译使用的源码,并传入当前正在使用的virtualbox x86 32bit ubuntu-14.04 虚拟机的编译选型(宏开关),来准确的定义到需要的源码中的头文件,函数,变量的准确定义,排除同一个变量名(函数名)的多个声明。

查看我当前Ubuntu-14.04 虚拟机的内核版本:

##查看 /porc/version文件来查看当前Ubuntu-14.04 虚拟机的内核版本
dimon@dimon-VirtualBox:~$ cat /proc/version
Linux version 4.4.0-142-generic (buildd@lgw01-amd64-032) (gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.4) ) #168~14.04.1-Ubuntu SMP Sat Jan 19 11:28:33 UTC 2019##使用命名 uname -r 查看当前Ubuntu-14.04 虚拟机的内核版本
dimon@dimon-VirtualBox:~$ uname -r
4.4.0-142-generic
dimon@dimon-VirtualBox:~$

可以看到当前我Ubuntu-14.04 虚拟机的内核版本是 Kernl-4.4.0-142,然后去下载对应的 kernel 内核源码包。

到 Linux 内核源码网站上下载对应的 kernel-4.4.0-142 内核源码,访问内核官方网站:

The Linux Kernel Archives

访问 kernel.org 网站,下载速率可能会比较慢(原因你懂的),我们可以到国内和内核镜像站去下载对应内核版本,例如,清华镜像站,阿里云镜像站等。如下,到清华镜像下载kernkernel-4.4.0-142 内核源码。

使用 wget 命令下载需要的内核版本 

wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.4.tar.xz

 至此我需要的和我当前Virtualbox x86 32bit Ubuntu-14.04 虚拟机对应的内核源码包已经下载成功。根据你自己的虚拟机配置,也可以下载自己虚拟机Ubuntu版本对应的内核源码包。

3. 使用Clang搭建内核源码阅读环境

3.1 解压下载的内核源码包

解压下载到的kernel-4.4.0 内核源码包。

tar -xvf linux-4.4.tar.xz

如在我上一个博文中记录的,查看当前环境中 x86 32bit Ubuntu-14.04 虚拟机虚拟机的内核编译参数。当前我Ubuntu-14.04 虚拟机内核的编译参数配置文件,存放在虚拟机的如下文件目录中。

查看当前运行Linux内核的编译参数-CSDN博客

/usr/src/linux-headers-4.4.0-142-generic/.config

我们可以使用这个当前Ubuntu-14.04 内核编译参数配置文件 '.config' 加上下载的kernel-4.4.0 源码包,来自行编译出当前虚拟机对应的内核。

我们进入之前解压的kernel-4.4.0 目录,通过内核源码来编译一下内核,如上一节提到的我们在编译命令前加上 ‘bear’ 来让内核编译时生成 compile_command.json 文件。

3.2  安装必须的编译环境工具

使用 'apt install'命令安装需要的内核编译工具

sudo apt-get update
sudo apt-get install build-essential kernel-package libncurses5-dev bison flex libssl-dev
3.3 拷贝内核编译配置文件到内核源码目录

拷贝 '.config '内核编译配置文件到解压的内核源码目录。

## 进入之前解压好的内核源码目录
cd linux-4.4## 如本文之前小节所述,当前ubuntu虚拟机的内核编译配置文件就在当前虚拟机的目录
## '/usr/src/linux-headers-4.4.0-142-generic/.config'文件
##
## 当前unbuntu-14.04 内核编译的配置参数文件,将其拷贝到我们解压的内核源码目录,使用
## 这个.config 内核编译配置文件,就可以编译 ubuntu kernel 镜像
##
cp /usr/src/linux-headers-4.4.0-142-generic/.config .

使用加上了'bear'前缀的 'make zimage' 命令来编译内核镜像。

3.4 编译内核

现在我们已经下载并解压好了需要的 kernel-4.4.0 内核源码,并且从当前虚拟机的文件目录中找到了需要的内核kernel编译配置选型文件 ‘.config’,并把 .config 拷贝到了解压号的 kernel-4.4.0 源码目录。接下来,就可以使用 'make' 命令编译出 kernel-4.4.0 内核镜像 vmlinux.bin。

进入解压好的kernel-4.4.0 内核源码目录,执行命令 'make mrprope', 

## 进入之前解压好的内核源码目录
cd linux-4.4
##
make mrprope

执行 'make menuconfig',保存

make menuconfig

执行'make'命令从内核源码编译出 vmlinux.bin 内核镜像。如上所述,我们可以在 make 命令前加上 'bear' 前缀,这样让 bear 生成内核源码编译是的 compile_commands.json 文件。

bear make

等待编译执行,在虚拟机中编译内核源码的速度比较慢,在我本地编译大概花了30分钟编译完成,编译生成的内核镜像放在 'arch/x86/boot/'目录下 'vmlinux.bin' 。

dimon@dimon-VirtualBox:~/linux-4.4$ ls -l arch/x86/boot/vmlinux.bin 
-rwxrwxr-x 1 dimon dimon 6558212  4月 22 14:01 arch/x86/boot/vmlinux.bin
dimon@dimon-VirtualBox:~/linux-4.4$
3.5 获取到内核编译的compile_commands.json文件

在从内核源码编译出内核镜像'vmlinux.bin'的同时,'bear' 跟踪了了整个内核源码中被编译到的源文件的编译过程,bear 生成了网络此次内核编译的编译命令文件 'compile_commands.json'文件,该文件存放在当前内核源码编译根目录。

dimon@dimon-VirtualBox:~/linux-4.4$ ls -l compile_commands.json 
-rw------- 1 dimon dimon 32570688  4月 22 14:08 compile_commands.json
dimon@dimon-VirtualBox:~/linux-4.4$ 

4. 安装VSCode和 Remote-ssh , clangd插件

4.1 安装 VSCode 

使用搜索引擎搜索并下载 VSCode 安装包,安装 VSCode 编辑器,VSCode 是强大的集成式开发环境 IDE,可以通过安装 VSCode 插件扩展VSCode的功能。

4.2 安装VSCode remote-ssh 插件

点击 vscode 左侧窗口的扩展插件图标,在搜索栏中输入 'remote-ssh' ,搜索到 remote-ssh 插件,点击安装,等待 remote-ssh 插件安装完成。

4.3 配置 vscode remote-ssh 插件访问远程主机中内核源码

 由于我们一般是在 Winddows 环境下进行开发,通过windows环境下 ssh 远程连接代码服务器或者本地虚拟机,在Windows环境下进行代码的编辑修改,然后通过ssh在代码服务器或者本地虚拟机中进行编译。所以,需要配置 vscode remote-ssh 连接我们的远程代码服务器或者本地虚拟机。在vscode中,按下 F1 键,在输入栏中输入 'remote-ssh:connect to host' ,不用完全输入会自动补全,点击出现的选型即可。

在连接窗口输入要连接的远程主机(前面加上“用户名@”,如:test@192.168.50.170),也就是你编译linux内核的主机。

根据你的远程代码服务器或者本地虚拟机的IP地址输入要远程连接的主机,前面加上 ‘用户名@’,例如我的本地虚拟机 'ssh dimon@192.168.1.7 -A'

输入回车后,vscode 提示让用户选择把新添加的 ssh 账号保存到那个配置文件里,这里可以随意选择一个配置文件来保存ssh账号,选择那个文件都没有啥影响。

保存之后vscode再右下角弹出提示说 ssh 账号配置保存成功。我们可以点击 'connect' 来测试下是否可以连接到远程代码服务器或者虚拟机。

选择远程主机的类型,根据远程服务器或者虚拟机类型来选择,一般是 'linux'

输入远程远程服务器或者虚拟机的ssh登录密码,回车。

看下 ssh 是否登录成功。

在我的环境提示 remote-ssh 登录失败。因为我本地安装的虚拟机是 Virtualbox x86 32bit Ubunutu-14.04 系统的,remote-ssh 不支持远程主机是 32位系统的构架,最好换成64位的系统。不过如果你安装的虚拟机是 Ubuntu 18.04, 20.10 等64位的系统,这里remote-ssh 连接虚拟机应该会成功连接。

2021-09-04_unsupported architecture: i686-CSDN博客

4.4 安装Clangd 插件

vscode中点击左侧菜单栏里的扩展插件,在搜索框里输入 ‘clangd’ 搜索安装 clangd 插件。

配置 clangd ,点击 vscode extension,在已经安装的vscode插件列表里找到 'clangd' 插件,点击右侧的齿轮小图标,进入clangd配置'Extension Settings'页面。

在 'Clangd: Arguements' 下点击 "Add item",输入如下的配置。

--compile-commands-dir=${workspaceFolder}
--background-index
--completion-style=detailed
--header-insertion=never
-log=info

最后配置结果如下

5. 触发Clangd工作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/314713.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu部署jmeter与ant

为了整合接口自动化的持续集成工具,我将jmeter与ant都部署在了Jenkins容器中,并配置了build.xml 一、ubuntu部署jdk 1:先下载jdk-8u74-linux-x64.tar.gz,上传到服务器,这里上传文件用到了ubuntu 下的 lrzsz。 ubunt…

基于jenkins+docker实现CI/CD实践

项目简介 利用 Jenkins、Docker、SonarQube 和 Harbor 技术,搭建一个完整的 CI/CD 管道,实现持续集成、持续交付和持续部署的流程。通过自动化构建、测试、代码质量检查和容器化部署,将开发人员从繁琐的手动操作中解放出来,提高团…

SQLite运行时可加载扩展(三十五)

返回:SQLite—系列文章目录 上一篇:SQLite轻量级会话扩展(三十四) 下一篇:SQLite的DBSTAT 虚拟表(三十六) 1. 概述 SQLite 能够在运行时加载扩展(包括新的应用程序定义的 SQL 函数、整理序列、虚拟表和 VFS&…

【深度学习】烟雾和火焰数据集,野外数据集,超大量数据集,目标检测,YOLOv5

标注了2w张数据集,是目标检测yolo格式的,有火焰、烟雾两个目标,下图是训练时候的样子: 训练方法看这里: https://qq742971636.blog.csdn.net/article/details/138097481 数据集介绍 都是博主辛苦整理和标注的&…

C++必修:类与对象(一)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 贝蒂的主页:Betty’s blog 1. 面向过程与面向对象 1.1. 面向过程 我们之前学习的C语言就是一种面向过程的语…

SVN小乌龟汉化问题

1.首先确认中文语言包和SVN版本需要一致(点击右键 选择最后一个选项即可查看) 官网链接 点击这个官网链接可以下载对应版本的中文包 2.下载好之后直接无脑下一步安装即可 3.如果还是没有中文,找到这个文件夹,把里面的内容全部删…

【css】select实现placeholder效果

场景&#xff1a;使用select下拉选择框的时候&#xff0c;需要像其他控件一样提示默认信息。 问题&#xff1a;表单控件select没有placeholder属性。 解决方案&#xff1a;通过css实现&#xff0c;不需要js <style>select > option[disabled]{ color:#999;cursor: n…

VUE3 ref,props,生命周期

1.--ref属性 1.1代码 1.1.1子表 <template><div class"person"><h1>中国</h1><h2 ref"title2">北京</h2><h3>尚硅谷</h3><button click"showLog">点我输出h2这个元素</button>&l…

【软测学习笔记】Day01

&#x1f31f;博主主页&#xff1a;我是一只海绵派大星 &#x1f4da;专栏分类&#xff1a;前端 &#x1f4da;参考教程&#xff1a;黑马教程❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、测试介绍 1、什么是软件测试&#xff1f; 2、测试主流技能 二、测试常用分…

unity cinemachine相机 (案例 跟随角色移动)

安装相机包 打开包管理工具 在 unity registry 搜索cinemachine 会在maincamera中生成一个组件cinemachineBrain 只能通过虚拟相机操控 主相机 虚拟相机的参数 案例 1.固定相机效果 位置 在固定的地方 默认的模式 2.相机跟随人物效果 焦距设置 20 跟随设置 把playere…

Django框架之python后端框架介绍

一、网络框架及MVC、MTV模型 1、网络框架 网络框架&#xff08;Web framework&#xff09;是一种软件框架&#xff0c;用于帮助开发人员构建Web应用程序和Web服务。它提供了一系列预先编写好的代码和工具&#xff0c;以简化开发过程并提高开发效率。网络框架通常包括以下功能…

Web前端框架/库/工具

前言 俗话说&#xff1a;前端从步枪&#xff08;原生js&#xff09;到了半自动武器&#xff08;jQuery&#xff09;并进化为全自动武器&#xff08;三大框架&#xff08;angular&#xff0c;react&#xff0c;vue及其生态链&#xff09;&#xff09;。 常说工欲善其事必先利其…

python作业 切片逆转

题目&#xff1a; &#xff08;反转显示一个整数&#xff09;编写下面的函数&#xff0c;反向显示一个整数。 列如&#xff1a;reserse(3456)。编写一个测试程序&#xff0c;提示用户输入一个整数&#xff0c;然后显示它的反向数。 第一步定义一个函数&#xff1a; def rev…

AUTOSAR-SD篇

1 概述 服务发现模块的主要任务是管理在车内通信中被称为服务的功能实体的可用性&#xff0c;以及控制事件消息的发送行为。只允许向需要这些事件消息的接收器发送事件消息&#xff08;发布/订阅&#xff09;。 这里描述的解决方案也被称为SOME/IP-SD&#xff08;基于IP -服务发…

前端css中keyframes(关键帧)的简单使用

前端css中keyframes的使用 一、前言二、例子&#xff08;一&#xff09;、例子源码1&#xff08;二&#xff09;、源码1运行效果1.视频效果2.截图效果 三、结语四、定位日期 一、前言 关键帧keyframes是css动画的一种&#xff0c;主要用于定义动画过程中某一阶段的样式变化&am…

【STM32+HAL】读取电池电量

一、准备工作 有关CUBEMX的初始化配置&#xff0c;参见我的另一篇blog&#xff1a;【STM32HAL】CUBEMX初始化配置 有关定时器触发ADC模式配置&#xff0c;详见【STM32HAL】ADC采集波形实现 有关软件触发ADC模式配置&#xff0c;详见【STM32HAL】三轴按键PS2摇杆 二、所用工具…

Bytebase 2.16.0 - 支持 Oracle 和 SQL Server DML 变更的事前备份

&#x1f680; 新功能 支持 Oracle 和 SQL Server DML 变更的事前备份。 支持在 SQL 编辑器中显示存储过程和函数。 支持兼容 TDSQL 的 MySQL 和 PostgreSQL 版本。 支持把数据库密码存储在 AWS Secrets Manager 和 GCP Secret Manager。 支持通过 IAM 连接到 Google Clou…

VirtualBox7.0.16的蓝屏大坑与ssh登陆ubuntu虚拟机的办法

背景&#xff1a; 安装了最新版的VirtualBox&#xff0c;装了ubuntu系统&#xff0c;在win10下通过ssh死活无法与ubuntu进行正常登陆控制。 然后开始了踩坑。 问题1&#xff1a;ssh登陆失败&#xff0c;但是主机能ping通ubuntu&#xff0c;反过来也能ping通&#xff0c;网络…

线性代数基础1向量

1、向量是什么 1.1、向量的定义 在数学中&#xff0c;向量&#xff08;也称为欧几里得向量、几何向量、矢量&#xff09;&#xff0c;指具有大小和方向的量。它可以形象化地表示为带箭头的线段。箭头所指&#xff1a;代表向量的方向&#xff1b;线段长度&#xff1a;代表向量的…

增加PyQt5界面的交通流量预测(模型为CNN_GRU,CNN_BiGRU_ATTENTION,LSTM,Python代码)

1.效果视频&#xff1a;增加PyQt5界面的交通流量预测&#xff08;模型为CNN_GRU&#xff0c;CNN_BiGRU_ATTENTION&#xff0c;LSTM&#xff09;_哔哩哔哩_bilibili&#xff09; 2.三个模型和数据集的介绍 交通流量预测(python代码&#xff0c;压缩包中带有数据&#xff0c;CN…