精华内容
下载资源
问答
  • 内核开发
    千次阅读
    2021-02-20 18:13:43

    vscode在linux下搭建内核驱动开发环境

    一、前言

    Souce insight是一个阅读、开发linux内核驱动模块的好工具,但是Source insight是收费的软件,而且没有原生linux版本,要是想在纯linux环境下进行linux驱动开发,就只能wine+Source insight,而wine版的不好用容易卡死而且cpu占用还高,我就想到用开源跨平台的vscode进行linux内核开发,体验能否和source insight一样好呢?

    二、实践

    经过搜索和自己亲身实践,最后发现vscode+global插件,可以实现和source insight相媲美的体验

    三、准备工作

    • linux内核源代码文件夹
    • linux下安装好vscode

    四、安装global软件包和vscode global插件

    我用的是deepin-linux操作系统,在终端输入apt命令安装global

    sudo apt install global

    Shell

    Copy

    在vscode的插件商店里搜索安装global插件

     

    五、打开linux源码文件夹

    利用vscode的打开文件夹的功能,打开linux内核源码的文件夹

     

    提示无法在这个工作区中监视文件更改,按照网页的提示,修改最大文件监控数就可以了,不改对开发也没什么影响

     

    六、安装c/c++扩展

    随便打开一个c文件,右下角会提示你安装c/c++扩展,点安装就可以自动安装了

     

    安装完毕,又会提示你配置 IntelliSense 设置以帮助查找缺少的标头,点配置即可,这里我配置了一个交叉编译器的地址,这个其实也没什么用,不配置也可以

     

    关闭配置页面,这个页面不配置也不影响,这个时候下面会有问题输出,不用管

     

    七、生成global数据库

    在vscode下Ctrl+Shift+P进入命令行模式,输入gl,选择Global: Rebuild Gtags Database执行

     

    过几分钟生成完毕,就会在linux源码目录下生成GTAGS、GRTAGS、GPATH三个tag数据库文件

     

     

    接着,就可以用F12愉快的跳转定义啦,输入代码的时候也会有给力的代码提示

     

    备注:global的版本要注意

    又备注:目前在使用过程中,有自定义的结构体成员比如u32这种类型的无法识别无法提示的问题,不知大家有无方法解决,可以在下方评论我

    更多相关内容
  • Linux内核开发.pdf

    2021-09-27 13:02:31
    Linux内核开发.pdf
  • 学习交流使用,当前在做嵌入式开发,希望能够和更多的人一起学习
  • 02-格物 Linux4.4内核开发手册.pdf
  • 嵌入式系统Linux内核开发实战指南(ARM平台).pdf和配合的(嵌入式系统Linux内核开发实战指南.iso)光盘镜像.受上传所限,分3卷.这是第三卷
  • 嵌入式系统Linux内核开发实战指南(ARM平台).pdf和配合的(嵌入式系统Linux内核开发实战指南.iso)光盘镜像.受上传所限,分3卷.这是第一卷
  • 嵌入式系统Linux内核开发实战指南(ARM平台).pdf和配合的(嵌入式系统Linux内核开发实战指南.iso)光盘镜像.受上传所限,分3卷.这是第二卷
  • 经典嵌入式黒皮巨著《嵌入式系统Linux内核开发实战指南(ARM平台)王洪辉著.pdf》。值得一读!
  • 何为 Linux 内核开发? 首先,初步认识下 Linux kernel Linux 内核的框架如上图。 设备子系统负责和硬件打交道。 大部分工作集中在设备子系统部分。 内核开发是什么? 广义上讲,新增或修改上图中内核部分的所有...

    此文包含 Linux 系统的学习路径和书籍推荐。

    我觉得学习 Linux 系统,内核驱动时,最开始只需要 ‘Know what, not know how ’。 不用去探究细节,只需要知道整体的框架,知道有哪些需要我们重视的内容即可。

    何为 Linux 内核开发?

    首先,初步认识下 Linux kernel

    在这里插入图片描述

    • Linux 内核的框架如上图。
    • 设备子系统负责和硬件打交道。
    • 大部分工作集中在设备子系统部分。

    内核开发是什么?

    • 广义上讲,新增或修改上图中内核部分的所有子系统。
    • 非 Linux 源码贡献者,一般来说只修改设备子系统部分。

    接下来,简单聊聊初学者需要重点关注的三个部分:设备树,字符设备,平台设备驱动。

    设备树(DTS)

    设备树相当于一份软件中描述硬件结构的配置框图。假设下图为硬件框图:
    在这里插入图片描述
    那么其软件描述的代码片段如下:

    / { // root node
        model = "Qualcomm Technologies, Inc. SDM xxx";
        compatible = "qcom,sdmxxx";
        cpus {
            ... 
            cpu@0 {
                ... 
            };
            cpu@1 {
                ... 
            };
        };
        usb@<address> {
            ... 
        };
        serial@<address> {
            ... 
        };
        gpio@<address> {
            ... 
        };
        intc: interrupt-controller@<address> {
            ... 
        };
        external-bus {
            ...
            i2c@0,0 {
                ... 
                xxx@<address> { // I2C Dev
                .... 
                };
            };
            flash@1,0 {
                ... 
            };
        };
    };
    

    字符设备驱动

    • 字符设备驱动是理解设备驱动的基础。
    • 大多数设备都可以归于字符设备。
      在这里插入图片描述

    kernel 开发需要什么样的知识储备?

    我觉得这部分可以当着 Linux 系统的学习路径了。

    C 语言

    良好的 C 语言能力是必要条件, Linux 官方推荐了如下书籍。

    • The C Programming Language
    • Practical C Programming
    • C: A Reference Manual

    不过我觉得结合如下书籍一步步学习会更适合学习:

    《啊哈 C 语言》入门书籍,号称马桶上看的 C 语言,通俗易懂。
    《The C Programming Language》的中文版 《C 程序设计语言》,英文版也是很好一个选择的,一书两用,技术和英语都学习了。我觉得这一本是学习 C 语言的朋友们,必读的一本。

    在这里插入图片描述
    3. 《C 专家编程》,这本书主要讲语法特性,告诉我们 C 语言是怎么设计出来的,看了这本书,我们可以更深刻的理解每一行代码。

    在这里插入图片描述
    4. 《C 缺陷与陷阱》,《C 专家编程 》的延续,针对性更强,告诉我们 C 语言这个工具的缺陷与陷阱,让我们使用 c 语言时更加游刃有余。
    在这里插入图片描述
    5.《数据结构与算法分析 : C语言描述》,入门数据结构与算法,也是一本经典书籍,比《算法导论》那边砖头厚的书友好得多。
    在这里插入图片描述

    GNU

    这个也可以归为 C 语言里面,内核由 GNU C 和 GNU toolchain 实现,所以如下两方面的知识是需要的。

    • GNU C 的编码规则
    • GNU 工具链的使用

    Linux 基本命令

    学习 Linux 前,我们需要先熟悉 Linux 的“命令行 + 文件”的使用模式,要想学好一个东西,开始肯定需要用好这个东西。《鸟哥的 Linux 私房菜》应该是最适合初学者的一本书了。
    在这里插入图片描述
    如果想深入的话,推荐 《Linux 系统管理技术手册》,这本书很厚,算是 Linux 运维必备的手册。
    在这里插入图片描述

    应用程序设计

    通过系统调用或者 glibc,学会自己进行程序设计。如果每个系统调用都深入地学习、看书看文档、做实验,这样坚持一段时间,啃下这些东西,就很接近操作系统的原理了,就能看到另一番风景,甚至在应用编程时会有一览宗山小的感觉。参考书籍首推《UNIX 环境高级编程》,有代码,有介绍,有原理,非常实用。
    在这里插入图片描述

    设备驱动相关知识

    设备驱动方面的知识看下《Linux 设备驱动程序》应该就差不多了, 国内宋宝华写的《Linux 设备驱动开发详解》也还可以。
    在这里插入图片描述

    内核原理

    学习内核原理的话,推荐《Linux 内核设计与实现》,《Linux 内核完全注释》,《深入理解 Linux 内核 》三本书,当然也可以只买《深入理解 Linux 内核 》, 本书言简意赅地讲述了主要的内核机制。
    在这里插入图片描述

    阅读源码

    一开始阅读代码不要纠结一城一池的得失,不要每一行都一定要搞清楚它是干嘛的,而要聚焦于核心逻辑和使用场景。

    《Linux 内核源代码情景分析》是一本很适合参考的书,这本书最大的优点是结合场景进行分析,看得见、摸得着,非常直观,唯一的缺点还是内核版本比较老
    在这里插入图片描述
    Linux内核学习资料 教学视频 点击获取
    在这里插入图片描述
    在这里插入图片描述

    Linux内核学习免费课程:https://ke.qq.com/course/3485817?flowToken=1036460

    实践

    实现一个设备驱动程序,重新实现一些系统调用,或者重新实现一个文件系统或其他子系统等等。这部分难度会比较大,需要自己搞清楚所有细节,但是只要熬出来了,进步的愉悦是难以言说的。

    总结

    其实这部分内容已经不仅仅是针对内核开发了,而是针对 Linux 系统。C 语言, Linux 命令行,应用程序设计,设备驱动,内核原理,阅读源码, 实践, 只要我们踏实地把这样七个步骤走完,基本就已经领先绝大多数人了(甚至可以说 98% 以上,我也还在路上_),工作中 Linux 系统相关的绝大多数问题也难不倒你了,接下来就是在实战中不停地被捶打,最后成为一代宗师。

    当然如果只是对内核和驱动感兴趣,应用程序设计部分可以不用花太多时间。

    C/C++Linux服务器开发/后台架构师免费学习课程:https://ke.qq.com/course/417774?flowToken=1031343

    展开全文
  • Android内核开发实践
  • Linux内核开发框架的学习资料说明
  • 麦洛克菲内核开发试讲讲义。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 详细描述vxworks内核开发文档,介绍内核开发所需要的问题,对从事vxworks开发的大有裨益
  • Thinkphp内核开发盲盒商城源码
  • "还真不对,我们平时说的Linux其实是指Linux内核,而Linux操作系统真正的称呼为GNU/linux操作系统(GNU/linux是指 ,linux内核+GNU组织的软件)。在过去的2021年,Linux内核添加了大量令人兴奋地改进,并引入了新的...

    大家每次听到Linux都会说:"哦,就是那个操作系统对吧?"还真不对,我们平时说的Linux其实是指Linux内核,而Linux操作系统真正的称呼为GNU/linux操作系统(GNU/linux是指 ,linux内核+GNU组织的软件)。在过去的2021年,Linux内核添加了大量令人兴奋地改进,并引入了新的硬件支持等。

    近日业内知名的性能测评网站Phoronix发布了2021年Linux内核的发展报告。尽管这一年Linux内核的发展令人振奋,可它实际上在内容提交次数和代码行上都比以往的数据低。下面让我们来看看每年的GitStats开发统计。

    GitStats开发统计

    截止至2021年12月31日,在Linux内核源码树上运行GitStats时,可以看到约有24.3万个作者进行了1,060,172次提交。该源码树目前由3,220万行的代码组成,涉及74,300个文件。

    图片来源Phoronix

    随着Linux内核中的新功能不断涌现以及对于硬件支持的提高,它的内核代码行数始终在以相当稳定的速度增长,并被合并进主要内核版本中。

     图片来源Phoronix

    提交量为什么减少?

    虽然2021年发布了一些令人振奋的新功能和硬件支持,但在2021年只看到了73.7k的提交,比2020年至2018年的90.2k、82.8k、80.1k下降了很多。上一次年提交量比7.3k还少的还是在2013年的70.9k。导致提交量下降的部分原因是因为2021年仅有5个主要内核发布,而某些年份有6个内核发布。要知道每年额外内核发布期的合并窗口都会带来大量的新提交产生。同时,Linux 5.16将在几周后发布,这也就意味着Linux 5.17的合并窗口在2022年的1月才会启动。

    Linux内核代码行数量变化

    除了提交量比以往少很多以外,Linux内核代码新增行数也低于去年的数据。在2021年,Linux内核代码行数增加320万行,删除130万行,低于2020年的增加400万行以及删除150万行。

    Linux内核代码高产贡献者

    像以往一样,Linus Torvalds依然还是Linux源代码树上最高产的贡献者。除了他之外,Linux内核源码树上,排名靠前的代码贡献者分别是David S. Miller、Arnd Bergmann、Christoph Hellwig、Lee Jones和Jakub Kicinski等知名的长期内核贡献者。

     图片来源GitStats

    用于内核代码提交的电子邮件数量

    2021年,有4421封不同的电子邮件与Linux内核代码提交有关,比2020年的4603封有所下降,但与2019年的4383封相比又有所增加。

    2021Linux内核科技圈趣事

    在2021年中Linux内核科技圈也发生了许多有趣的事:

    原文链接:Samsung 860/870 SSDs Continue Causing Problems For Linux Users - Phoronix

    展开全文
  • Linux内核开发_1_编译LInux内核

    千次阅读 多人点赞 2020-05-13 01:23:32
    Linux内核版本: cat /proc/version Linux version 4.15.0-20-generic (buildd@lgw01-amd64-039)\ (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 ...

    目录

    1. 准备工作

    1.1 学习环境

    1.2 下载Linux内核源码

    1.3 解压Linux内核

    1.4 目录结构介绍

    2. Linux内核配置

    2.1 配置选项

    1. make config

    2. make menuconfig

    3. make gconfig

    3 开始配置

    1. 配置解释

    General setup 通用选项

    Enable loadable module support 可加载模块

    Enable the block layer 块设备层

    System Type arm 占用配置,一般是厂家提供,与第7项代替了原有的Processor type and features

    [ ]FIQ Mode Serial Debugger,一般不选。

    6Bus support 总线支持

    x86_64_defconfig

    我的配置

    4. 编译Linux源码

    4.1 Linux编译生成文件解释

    5 运行Linux内核

    5.1 qemu

    6. 简单的文件系统和init

    建议

    编译问题收录及解决方案



    1. 准备工作

    1.1 学习环境

    本系列教程使用的环境如下:
    操作系统版本:

    Linux ubuntu 18.04
    

    Linux内核版本:

    cat /proc/version
    Linux version 4.15.0-20-generic (buildd@lgw01-amd64-039)\
     (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018
    

    学习的Linux内核版本:

    linux-4.10.15
    


    1.2 下载Linux内核源码

    首先我们需要下载Linux-4.10.15内核,我们可以直接使用wget下载:

    wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.10.15.tar.xz
    

    下载完成之后就会看到一个名为 “linux-4.10.15.tar.xz”的文件,可以看到后缀格式是.tar.xz,双重压缩格式


    1.3 解压Linux内核

    双重压缩格式,我们依次解压先用“xz”命令解压:

    xz -d linux-4.10.15.tar.xz
    

    -d是代表解压的意思
    解压完成后就会在当前目录看到一个名为“linux-4.10.15.tar”,解压完xz后还有一重tar,在使用tar命令解压一次就可以得到原内核文件,这里建议解压到/usr/src目录下,这里没有别的意思,是Linux内核开发者们给我的建议,这个在行业里是一个开发标准,一般Linux源代码都是放在这个目录下,你可以在任何发行版里的这个目录下看到他们所使用的Linux内核源码

    sudo tar -xf linux-4.10.15.tar -C /usr/src/.
    

    之后我们就可以在/usr/src目录下看到我们的linux源码了,同时还有发行版的
    在这里插入图片描述
    随后我们进入到这个目录下,查看一下这个目录的文件体系

    cd linux-4.10.15
    


    1.4 目录结构介绍

    /arch

    不同CPU架构下的核心代码。其中的每一个子目录都代表Linux支持的CPU架构

    /block

    块设备通用函数

    /crypto

    常见的加密算法的C语言实现代码,譬如crc32、md5、sha1等

    /Documentation

    说明文档,对每个目录的具体作用进行说明

    /drivers

    内核中所有设备的驱动程序,其中的每一个子目录对应一种设备驱动

    /firmware

    固件代码

    /fs

    Linux支持的文件系统代码,及各种类型的文件的操作代码。每个子目录都代表Linux支持的一种文件系统类型

    /include

    内核编译通用的头文件

    /init

    内核初始化的核心代码

    /ipc

    内核中进程间的通信代码

    /kernel

    内核的核心代码,此目录下实现了大多数Linux系统的内核函数。与处理器架构相关的内核代码在/kernel/$ARCH/kernel

    /lib

    内核共用的函数库,与处理器架构相关的库在/kernel/$ARCH/lib

    /mm

    内存管理代码,譬如页式存储管理内存的分配和释放等。与具体处理器架构相关的内存管理代码位于/arch/$ARCH/mm目录下

    /net

    网络通信相关代码

    /samples

    示例代码

    /scripts

    用于内核配置的脚本文件,用于实现内核配置的图形界面

    /security

    安全性相关的代码

    /tools

    Linux中的常用工具

    /usr

    内核启动相关的代码

    /virt

    内核虚拟机相关的代码

    2. Linux内核配置

    2.1 配置选项

    Linux内核提供了三种配置的模式

    1. make config

    此模式非常不建议使用,除非你的时间非常多,因为这个方式是通过终端输出的方式挨个,也就是逐个问你设置选项,非常的耗时,而且不方便

    我们测试一下,在终端窗口输入:

    make config

    呀哈,出了一个错:

    “Command 'make' not found, but can be installed with:”

    提示我们系统上没有make这个命令,这是因为我在学习时使用的是新系统,下载的是简洁版的,里面只带了基本的工具链,这样的第三方命令没有包含其中,所以需要我们自己下载,这里下载一下就好啦:

    sudo apt install make

    安装完成之后输入上面说的命令:

    又出错了,这次是告诉我们没有GCC:“/bin/sh: 1: gcc: not found”

    我们在安装一下,这里不需要指定gcc版本,直接输入gcc,软件仓库会给我们根据当前系统内核选择一个最优的gcc版本下来,提示y/n,选择y即可:

    sudo apt install gcc
    

    安装完成之后在接着输入“make config”:

    make config

    这次出现了一个报错:

    “scripts/basic/fixdep.c:449:1: fatal error: opening dependency file scripts/basic/.fixdep.d: Permission denied”

    不要急,一开始没有看到后面的“Permission denied”时,我以为是文件代码出错了,后面仔细一看,是告诉我们没有权限,因为是在用户目录下,所以需要加上“sudo”来获取权限

    sudo make config

    加上sudo后正确运行了:

    他会逐步询问所有的配置信息,要求你输入y/n,这样是非常耗时的,而且很多选项初学者可能根本不太了解,所以非常不建议使用这个选项,我们按下ctrl+c退出这个配置工具。

    2. make menuconfig

    这个配置工具是基于menu文字图形库编写的,非常推荐这个选项,界面友好,其次是第一次使用这个选项会提供一些默认参数,无论是对初学者还是经验丰富的开发者们来说,都是一个非常好的选择

    sudo make menuconfig

    报了一个错误信息:

    “<command-line>:0:12: fatal error: curses.h: No such file or directory”

    提示找不到curses.h,这个是menu里的库文件,这很明显告诉我们缺少menu的库

    所以这里我们安装一下:

    sudo apt install libncurses5-dev

    在此运行后输出:

    “Your display is too small to run Menuconfig!
    It must be at least 19 lines by 80 columns.
    scripts/kconfig/Makefile:28: recipe for target 'menuconfig' failed”

    意思是,这个配置工具在编写时对我们的终端窗口大小进行了限制,长和宽必须满足19*80

    这里我们把终端窗口扩大一点,或者直接f11进入全屏模式都可以(全屏模式下按f11会退出全屏模式),然后在运行:

    成功进入到配置界面

    注:linux内核中一个功能模块有三种编译方法:一种是编入、一种去去除、一种是模块化。所谓编入就是将这个模块的代码直接编译连接到zImage中去,去除就是将这个模块不编译链接到zImage中,模块化是将这个模块仍然编译,但是不会将其链接到zImage中,会将这个模块单独链接成一个内核模块.ko文件,将来linux系统内核启动起来后可以动态的加载或卸载这个模块。
    在menuconfig中选项前面的括号里,*表示编入,空白表示去除,M表示模块化。

    3. make gconfig

    sudo make gconfig

    报错:

    /bin/sh: 1: pkg-config: not found
    *
    * Unable to find the GTK+ installation. Please make sure that
    * the GTK+ 2.0 development package is correctly installed...
    * You need gtk+-2.0, glib-2.0 and libglade-2.0.
    *
    原因也很明确的告诉我们需要安装gtk+2.0的库,这里我们安装一下:

    sudo apt-get install libgtk2.0-dev libglib2.0-dev libglade2-dev

    安装完成之后运行一次看一下效果:

    sudo make gconfig

    3 开始配置

    1. 配置解释

    General setup 通用选项

    选项

    作用

    [*]Prompt for development and/or incomplete code/drivers

    设置界面中显示还在开发或者还没有完成的代码与驱动,最好选上,许多设备都需要它才能配置。

    [ ]Cross-compiler tool prefix

    交叉编译工具前缀,如果你要使用交叉编译工具的话输入相关前缀。默认不使用。嵌入式linux更不需要。

    [ ]Local version - append to kernel release

    自定义版本,也就是uname -r可以看到的版本,可以自行修改,没多大意义。

    [ ]Automatically append version information to the version string

    自动生成版本信息。这个选项会自动探测你的内核并且生成相应的版本,使之不会和原先的重复。这需要Perl的支持。由于在编译的命令make-kpkg 中我们会加入- – append-to-version 选项来生成自定义版本,所以这里选N。

    Kernel compression mode (LZMA)

    选择压缩方式。

    [ ]Support for paging of anonymous memory (swap)

    交换分区支持,也就是虚拟内存支持,嵌入式不需要。

    [*]System V IPC

    为进程提供通信机制,这将使系统中各进程间有交换信息与保持同步的能力。有些程序只有在选Y的情况下才能运行,所以不用考虑,这里一定要选。

    [*]POSIX Message Queues

    这是POSIX的消息队列,它同样是一种IPC(进程间通讯)。建议你最好将它选上。

    [*]BSD Process Accounting

    允许进程访问内核,将账户信息写入文件中,主要包括进程的创建时间/创建者/内存占用等信息。可以选上,无所谓。

    [*]BSD Process Accounting version 3 file format

    选用的话统计信息将会以新的格式(V3)写入,注意这个格式和以前的 v0/v1/v2 格式不兼容,选不选无所谓。

    [ ]Export task/process statistics through netlink (EXPERIMENTAL)

    通过通用的网络输出工作/进程的相应数据,和BSD不同的是,这些数据在进程运行的时候就可以通过相关命令访问。和BSD类似,数据将在进程结束时送入用户空间。如果不清楚,选N(实验阶段功能,下同)。

    [ ]Auditing support

    审计功能,某些内核模块需要它(SELINUX),如果不知道,不用选。

    [ ]RCU Subsystem

    一个高性能的锁机制RCU 子系统,不懂不了解,按默认就行

    [ ]Kernel .config support

    将.config配置信息保存在内核中,选上它及它的子项使得其它用户能从/proc/ config.gz中得到内核的配置,选上,重新配置内核时可以利用已有配置

    [ ]Enable access to .config through /proc/config.gz

    上一项的子项,可以通过/proc/ config.gz访问.config配置,上一个选的话,建议选上。

    16)Kernel log buffer size (16 => 64KB, 17 => 128KB)

    内核日志缓存的大小,使用默认值即可。12 => 4 KB,13 => 8 KB,14 => 16 KB单处理器,15 => 32 KB多处理器,16 => 64 KB,17 => 128 KB。

    [ ]Control Group support(有子项)

    控制组支持,使用默认即可

    Example debug cgroup subsystem

    cgroup子系统调试例子

    Namespace cgroup subsystem

    cgroup子系统命名空间

    Device controller for cgroups

    cgroups设备控制器

    Cpuset support

    只有含有大量CPU(大于16个)的SMP系统或NUMA(非一致内存访问)系统才需要它。

    [ ]enable deprecated sysfs features to support old userspace tools

    在某些文件系统上(比如debugfs)提供从内核空间向用户空间传递大量数据的接口,一般不选

    [ ]Kernel->user space relay support (formerly relayfs)

    内核系统区和用户区进行传递通讯的支持,这个选项在特定文件系统(relayfs)中提供数据接口支持,它可以支持从内核空间到用户空间的大批量数据传递的支持。不清楚可以不选。

    [ ]Namespaces support,(有子项)

    命名空间支持,允许服务器为不同的用户信息提供不同的用户名空间服务。

    []Initial RAM filesystem and RAM disk (initramfs/initrd) support

    初始RAM的文件和RAM磁盘( initramfs /initrd)支持(如果要采用initrd启动则要选择,否则可以不选),不需要,不用选。嵌入式linux一般不选。

    [ ]Optimize for size

    -Os代替-O2参数,可能会有二进制错误问题,一般不选。

    (0)Default panic timeout

    添0即可。

    [*]Configure standard kernel features (for small systems)

    特殊内核用到,可以不选,嵌入式linux则必选。

    [ ]Enable the Anonymous Shared Memory Subsystem

    启用匿名共享内存子系统,不清楚可以不选。

    [ ]Enable AIO support

    支持AIO(Asynchronous I/O 异步事件非阻塞I/O),(包含aio.h, aio_read,向内核发出读命令,aio_write向内核写命令,详细见‘AIO介绍‘文档),AIO机制为服务器端高并发应用程序提供了一种性能优化的手段。加大了系统吞吐量,所以一般用于大型服务器,一般不用选。

    [ ]Kernel Performance Events And Counters(有子项)

    性能相关的事件和计数器支持(既有硬件的支持也有软件的支持).大多数现代CPU都会通过性能计数寄存器对特定类型的硬件事件(指令执行,缓存未命中,分支预测失败)进行计数,同时又丝毫不会减慢内核和应用程序的运行速度.这些寄存器还会在某些事件计数到达特定的阈值时触发中断,从而可以对代码进行性能分析. Linux Performance Event 子系统对上述特性进行了抽象,提供了针对每个进程和每个CPU的计数器,并可以被 tools/perf/ 目录中的"perf"工具使用.

    [*]Enable VM event counters for /proc/vmstat

    允许在/proc/vmstat中包含虚拟内存事件记数器。

    [*]Enable SLUB debugging support

    支持SLUB内存分配管理器调试,

    [ ]Disable heap randomization

    禁用随即head,选不选均可。

    Choose SLAB allocator (SLUB (Unqueued Allocator)) --->

    选择内存分配管理器,强烈推荐使用SLUB。

    [ ]Profiling support

    剖面支持,用一个工具来扫描和计算计算机的剖面图,支持系统测评,一般开发人员使用,不选。

    [ ]Kprobes

    Kprobes 提供了一个强行进入任何内核例程并从中断处理器无干扰地收集信息的接口。使用 Kprobes 可以 轻松地收集处理器寄存器和全局数据结构等调试信息。开发者甚至可以使用 Kprobes 来修改 寄存器值和全局数据结构的值。

    选中后linux内核 将附带此工具

    GCOV-based kernel profiling --->

    基于GCOV的代码覆盖率,可以来审评代码

    Enable loadable module support 可加载模块

    选项

    作用

    [ ]Forced module loading

    强行加载模块,不建议选。

    [*]Module unloading

    支持模块卸载,必须选上。

    [ ]Forced module unloading

    强行卸载模块,即使内核认为这样并不安全,也就是说你可以把正在使用中的模快卸载掉。如果你不是内核开发人员或者骨灰级的玩家,不建议选。

    [ ]Module versioning suppor

    这个功能可以让你使用其它版本的内核模块,除非特殊需要,一般不选。

    [ ]Source checksum for all modules

    这个功能是为了防止更改了内核模块的代码但忘记更改版本号而造成版本冲突,现在很少使用,不选。

    Enable the block layer 块设备层

    选项

    作用

    [*]Support for large (2TB+) block devices and files

    仅在使用大于2TB的块设备时需要

    [*]Block layer SG support v4

    通用SCSI设备第四版支持。

    [*]Block layer data integrity support

    块设备数据完整性支持。

    [*]IO Schedulers --->(有子项)

    IO调度器

    [ ]Anticipatory I/O scheduler

    抢先式I/O调度器,大多数块设备只有一个物理查找磁头(例如一个单独的SATA硬盘),将多个随机的小写入流合并成一个大写入流,用写入延时换取最大的写入吞吐量.适用于大多数环境,特别是写入较多的环境(比如文件服务器)

    [ ]Deadline I/O scheduler

    期限式I/O调度器,轮询的调度器,简洁小巧,提供了最小的读取延迟和尚佳的吞吐量,特别适合于读取较多的环境(比如数据库)。

    ]CFQ I/O scheduler

    使用QoS策略为所有任务分配等量的带宽,避免进程被饿死并实现了较低的延迟,可以认为是上述两种调度器的折中.适用于有大量进程的多用户系统CFQ调度器尝试为所有进程提供相同的带宽。它将提供平等的工作环境,对于桌面系统很合适。

    Default I/O scheduler (CFQ) --->

    默认IO调度器有上面三个IO调度器:抢先式是传统的,它的原理是一有响应,就优先考虑调度。如果你的硬盘此时在运行一项工作,它也会暂停下来先响应用户。期限式则是:所有的工作都有最终期限,在这之前必须完成。当用户有响应时,它会根据自己的工作能否完成,来决定是否响应用户。CFQ则是平均分配资源,不管你的响应多急,也不管它的工作量是多少,它都是平均分配,一视同仁的。

    System Type arm 占用配置,一般是厂家提供,与第7项代替了原有的Processor type and features

    <无子选项>

    [ ]FIQ Mode Serial Debugger,一般不选。

    <无子选项>

    6Bus support 总线支持

    选项

    作用

    PCI support

    PCI总线支持,主板上最长用的插槽,最好选上,arm linux可以不选,arm一般没有PCI总线。

    PCCard (PCMCIA/CardBus) support

    微通道总线,一般老式笔记本有这种插槽,笔记本选上,arm linux 不选。

    Kernel Features 内核特征

    选项

    作用

    [ ] Tickless System (Dynamic Ticks)

    非固定平率系统,能让内核运行的更有效率,并且省电,pc下可选,特别是笔记本,arm linux一般不用选。

    [ ] High Resolution Timer Support

    支持高频率时间发生器,需要硬件兼容,但大多数PC和ARM都不支持,不选

    Memory split (2G/2G user/kernel split) --->

    内核与用户空间各占2G,内核空间0-0x7FFFFFFF,用户空间80000000-FFFFFFFF

    Preemption Model (No Forced Preemption (Server)) --->

    内核抢占模式。普通PC用户一般选2,arm linux 选1就可以。

    No Forced Preemption (Server)

    禁止内核抢占,适合服务器环境。针对于高吞吐量的设计,但有可能延时较长,适用于服务器或科学运算,或向要最大的运算能力,而不理会调度上的延时。

    Voluntary Kernel Preemption (Desktop)

    自愿内核抢占,适合普通的桌面环境。已降低吞吐量为代价,降低内核调度的最大延时,提供更快的应用程序响应,即使系统已经高负荷运转,应用程序仍然能运行的很“流畅”,适合用户桌面环境

    Preemptible Kernel (Low-Latency Desktop)

    主动内核抢占,适合运行实时程序的环境。更低的吞吐量,进一步降低内核的调度延时,使应用程序更加流畅。

    [ ]Compile the kernel in Thumb-2 mode

    编译Thumb-2 mode内核,一般不选

    *] Use the ARM EABI to compile the kernel

    与下面绑定配置。

    [*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL)

    对于嵌入式系统(jffs2 yaffs2),这两个要选上,否则很可能启动的时候报错(kernel panic- not syncing: Attempted to kill init!)

    [ ] High Memory Support (EXPERIMENTAL)(有子项)

    1G物理内存以下不选,超过1G才选。(配置略有变化,以前的选项是OFF(<1G),4G(>1G && <4G),64G(>4G))。1

    Allocate 2nd-level pagetables from highmem

    1G物理内存以下不选,超过1G(小于4G)才选

    Allocate 3nd-level pagetables from highmem

    大于4G,选择此项目。

    Memory model (Flat Memory) --->

    一般选"Flat Memory",其他选项涉及内存热插拔。

    [ ] Enable KSM for page merging

    允许linux内核识别出包含相同内容的内存页,然后合并这些内存页,将数据整合在一个位置可以多次引用,特殊功能,不用选。

    (4096) Low address space to protect from user allocation

    设置低端内存大小,默认4096即可

    [ ] Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)

    这个资料目前暂时没找到合理的解释,可以先忽略不选

    x86_64_defconfig

    这里我们可以使用Linux下一些自带的配置文件,可以使用“make x86_64_defconfig” 这样就生成了一个x86_64的amd架构的linux内核(64位),如果要生成arm平台的架构的话需要修改配置文件,这里我目前还没有打算学习arm架构的配置工作,所以先选中amd的,如果要生成i386的可以使用"make i386_defconfig"

    你可以在arch/架构名/configs目录下找到对应的配置文件,也可以直接copy到你的根目录名字改为.config就可以了,这些是Linux内核自带的一些基础配置

    我的配置

    下面这个是我的配置,因为在Linux下配置不当,虽然编译可以过但是运行会出现问题,如内核恐慌,或者VFS加载失败等,这里是我在之前实验中编译成功且运行没有问题的一次配置,如果你编译时遇到了问题,可以参考下面的配置:

    链接: 百度网盘 请输入提取码

    提取码: 6zfg

    下载后用unzip命令解压:

    unzip config.zip

    然后目录下会出现一个config的文件,在copy到我们的linux内核根目录下,copy的新名字要在前面加个“.”,这样Linux内核才能识别:

    cp config 你的linux内核目录源码/.config

    4. 编译Linux源码

    编译方法:

    sudo make bzImage -j4

    这里解释一下,如果直接sudo make是无法生成bzImage的,在之前的版本里可以,但是在4.4版本上无法这样,bzImage是x86_64架构的压缩镜像文件

    选项里“j”,代表多线程编译,n代表线程数

    如:“make -j32”

    拆分32个线程来编译这个项目,线程数量请根据自己机器的配置,如果配置不好开这么多线程,调度起来很慢,也容易卡住。

    一般情况下,建议你的处理器如果是4核,那么建议每个核分出2个线程也就是8线程

    “make j8”

    这样让你的CPU压力不至于那么大。

    如果make的时候看到输出信息,你觉得很乱不舒服,可以使用重定向“>”的方法来屏蔽这些输出信息

    make > test.txt

    当出错时make会停下来,就可以到这个文件里去查看输出信息了

    如果不想生成输出文件又想屏蔽输出信息,Linux开发者没有为我们提供这个选项,但是我们可以利用Linux系统下的dev/null 黑洞文件,把输出信息重定向进去

    make > /dev/null

    黑洞文件相当于windows回收站,但是这个文件不会保存数据,凡是进去的任何数据,就会被自动删除,找不回的.

    输入命令后,Make就会开始自动化编译

    这个期间,可以去喝杯咖啡,因为编译非常耗时

    一步到位,没有出现任何编译出错的问题,这就是选择相仿内核版本的好处

    4.1 Linux编译生成文件解释

    arch里有不同架构的文件夹,如arm,x86,x86_64,当编译完成之后这些文件的boot目录里会生成这些压缩文件,根目录下会生成vmlinux文件,这个文件是未压缩的目标文件

    下面是这些文件的作用:

    vmlinux

    编译出来的最原始的内核文件,未压缩。

    zImage

    是vmlinux经过gzip压缩后的文件。

    bzImage

    bz表示“big zImage”,不是用bzip2压缩的。两者的不同之处在于,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage。

    uImage

    U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的tag。

    vmlinuz

    是bzImage/zImage文件的拷贝或指向bzImage/zImage的链接。

    initrd

    是“initial ramdisk”的简写。一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态。

    5 运行Linux内核

    5.1 qemu

    我们精简版的操作系统是不带这些第三方工具的,所以我们先安装一下:

    sudo apt install qemu

    安装完成之后,arch下x86是指32位的Linux内核,而x86_64是指64位的内核,64位是可以运行32位程序的,未来32位架构将逐渐被淘汰

    这里通过给qemu的-kernel指定内核参数,上面我们说过编译产生的文件是压缩文件,qemu可以正确运行吗?

    答:可以,qemu会自动帮我们解析,我们只需要使用-kernel指定就好了

    -kernel是指定内核文件的意思

    qemu-system-x86_64 -kernel arch/x86/boot/bzImage
    

    运行结果:

    可以看到内核成功跑起来了,但是报了一个错误

    end Kernel painc - not syncing: VFS:Unable to mount root fso on unknown-block(0,0)

    Linux内核在运行时需要文件根系统的支持,但是这里我们并没有生成文件系统,所以Linux会报这个错误

    除了文件系统以外Linux还会在初始化完成之后并且成功加载文件系统之后会去fork一个进程,名为init,这里先不做详细讨论,后续的学习文章里对Linux内核这块做一个详细的解析

    这个init就是守护进程,所有用户空间下的进程都由它来主动创建,就类似我们刚刚打开终端产生的shell一样

    6. 简单的文件系统和init

    这里先教大家制作一个简单的文件系统和init

    Linux内核对文件系统有一定的格式要求,如NFS和SVR格式的文件系统,这是基于UNIX演化来的,所以我们需要把文件系统制作成NFS/SVR/EXT等文件系统格式,这里推荐一个命令:“CPIO”,这个命令可以帮助我们生成SVR格式的文件系统,我们的配置选项里默认使用SVR的文件系统格式。

    在制作根文件系统之前,我们需要一个init,先用c语言制作一个init:

    vim init.c

    代码:

    #include <stdio.h>
    
    int main(){
        printf("\nhello Linux Kernel!\n");
        while(1);
    }

    注意这里末尾一定要加while(1),否则无法正确执行init和输出,经过分析inux内核的0号进程(init)运行时会初始化相关工作,然后在去fork一个子进程并把cpu控制权交给子进程。

    同时,init作为父进程不能被结束,因为一旦死掉,用户态空间下就没一个进程,而这个init就是我们Linux上被称为守护进程的东西,一旦死掉,整个用户态下所有的进程都会被一并杀死。

    这样的话用户态就相当于没了,那么内核就会产生异常了,会报内核恐慌,attempted kill init这样的问题,来告诉我们init有问题

    这是我根据资料查到的Linux内核第一次调度INIt的一个过程。

    这里我们只是简单的写一个init程序,后面我们使用buysbox来完成相关初始化,目前正在研究buysbox是如何去完成这些初始化的,等研究完成,会写一篇文章来告诉大家。

    这里我们使用静态编译,因为我们等下要使用的文件系统是临时制作的,里面除了包含init以外不会有任何库,所以不可以动态加载,必须使用静态:

    gcc -static -O0 init.c -o init

    这里使用“-O0".不要让编译器给我们的init进行优化,防止编译器偷懒优化掉某些指令,但是这段代码比较少,也没啥可以优化的,也可以不加。

    这里我们制作一个临时的根目录文件:

    echo init | cpio -o --format=newc > rootfs

    注意CPIO的格式,CPIO选项 -o 是从输出流里读取数据,而echo init是把init文件输出到输出流里,然后CPIO从输出流将文件读取到rootfs里,这里 --format=newc 是指使用SVR4的格式,而>是流重定向。

    注意这里在使用这个命令前不要创建目录,不然会出错,cpio会自动帮我们生成对应格式的文件

    输出:

    1651 blocks

    如果生成成功,会告诉我们输出的文件大小

    这里给上它权限,保证qemu在运行时加载到rootfs时有足够的权限

    sudo chmod 777 rootfs

    这里我们需要使用的运行命令是:

    qemu-system-x86_64   \
         -kernel ./bzImage 内核文件
         -initrd ./rootfs  临时根文件系统
         -append "root=根文件系统 rdinit=第一个init程序"

    这里给大家解释一下这些选项的意思,-kernel上面说过了,-initrd的意思是临时的根文件系统,Linux内核在加载根文件系统之前,VFS会去使用临时的文件系统做相关的初始化工作,当一切就绪后才会去调用实际的根文件系统。

    这里我们将它指向我们的临时文件系统,我们这个简单的文件系统可以先给Linux内核使用,实际的根文件系统是通过-append选项指定的,这个选项可以给内核运行参数,其中root就是指向了根文件系统,这里我们也可以给它指定我们用于临时的文件系统,但是根文件系统不是这么简单的,所以我们上面的简单文件系统只有一个init,真正的根文件系统还需要一些其它的设备文件,这里我们先不做多讨论,后面文件系统这块我们在深入探讨。

    这里rdinit的意思是告诉内核启动后从根文件系统里寻找一个可执行程序的文件名

    我们输入命令:

    qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd ./rootfs1 -append "rdinit=/init"
    

    因为我电脑上没有根文件系统,所以root就没传参进去。

    运行结果:

    可以看到我们的“hello linux kernel!”打印出来了!

    这是一件非常值得高兴的事,因为我编译了许多天,我在一边编译一遍学习它的内核源码,虽然进度很缓慢,但是我觉得这是一件能让人成长的事情,非常值得高兴,我踩了很多坑,所以这里非常建议大家在编译时一定要选择与发行版内核相仿的Linux内核版本编译。

    因为内核向前兼容,如果你书上用的老版本代码,那么在新版本一样可以用,甚至新版本上的代码会比老版本的代码更好,更健壮,因为Linux主版本会收录许多次版本上的优点,同时也会修复许多bug,Linux在不断的完善。

    建议


    这一段话是我在经历许多天的编译Linux内核过程中习得的总结,可以跳过。
       起初我学习Linux内核的时候,是参考“Linux内核设计与实现”这本书来学的,书上使用的Linux内核版本是:“2.34.6”,这个版本已经很老了,最初我使用的是ubnutu20来编译它的,虽然编译过程中遇到了很多问题,但是都一 一解决了,最后运行时会出现许许多多的问题,如:VFS无法加载根文件系统而引起的文件恐慌,还有kill init这样的问题,最初我以为是配置的问题,在我根据查找到资料,和仔细学习了一边如何配置Linux内核后,我发现其实这些基本上用默认的就可以了。
          大多数的除了特定需求一般无需裁剪,尤其是刚入门的学生,最好是使用默认配置,后来我觉得可能是最新版的ubtunu使用的软件仓库里的lib版本太高了,虽然可以编译过,但是有一小部分的lib库可能对旧函数不支持或者说已经废弃了,这是我目前认为的原因,我只是在ubtunu上安装了旧版本的gcc,但是并没有选择降级glib等库,这可能是原因之一,但是如果我使用了旧版本的glib库还有openssl等,那么一些ubtunu上较新的软件可能使用了新版本glib库里的一些新增的特性,导致这些使用动态加载的软件们无法正常运行。
          所以最后我选择使用老版本的centOS,可是无论是centOS或者是ubtunu对这些老版本的操作系统所使用的仓库代码已经废弃了,所以在这个上面是无法下载任何lib的,我必须修改源,使用国内或者国外带有老版本仓库的源才可以,即便使用了这些,ubtunu或者centOS这些老版本的操作系统在编译过程中也会出现一些零零散散的问题,由于版本太老使用起来非常不顺手,最后我向一些Linux内核的开发者们寻求意见,他们给出的一件事建议去编译3.0或者4.0以上的Linux版本内核,因为太老的Linux内核在目前较新的操作系统平台上已经很难在编译出来了,原因是因为Linux依赖gnu的软件体系,而gnu的软件体系在不断的升级进化,每次的升级,都会被用在正在开发中最新的Linux内核,而除了原始版的Linux内核不是在Linux上编译出来的以外,其余的Linux内核版本都是在Linux内核上开发而来的,而使用的开发工具(gcc)就是那个时代最新的版本。
          其次是不同的发行版它自带的一些依赖LIB都是比较新的,因为它也要为自己的Linux内核提供一个运行环境,而问题的关键是,当我们编译Linux内核时,不确定编译器会不会把当前操作系统上的一些依赖LIB编译到Linux内核里去。
          如正在编译Linux2.6,他使用的glib是3,那么我们当前的发行版使用的是6
          一旦编译起来,gcc会从系统环境里把6的一些依赖lib链接到2.6里去了,从而导致某些函数可能在未来的运行结果或者参数要求发生了一点变化,因为有向前兼容的方法,但是这个函数或者编译器选项很可能会被废弃掉。
          
       不确定的因素很多,所以这里我给大家的建议是,如果你想编译Linux内核,最好选择一个与它使用的Linux内核版本相仿的Linux发行版来编译它
          如我选择学习Linux内核,并且选择的Linux内核版本是4.10.15,那么我需要一个与它使用的内核版本相仿的操作系统,所以这里我选择ubtunu18.04,它使用的内核版本是4.15.0。

    编译问题收录及解决方案:

    1.fatal error: openssl opensslv.h: No

    sudo apt install libssl-dev

    2. Unsupported relocation type: R_X86_64_PLT32

    原因是因为linux要进行重定位地址,就是逻辑地址空间变换成内存中的实际物理地址空间,但是如果生成pic代码,也就是动态链接的格式代码,则会生成与位置无关的偏移代码,这个代码依赖程序加载到内存的hand,同时编译器不允许进行重定位。

    所以我们要修改不让它生成pic就可以了。

    1.在根目录的Makefile文件里找到“cc”,大概在349行

    2.在后面加上“ -fno-pic”保存退出

    展开全文
  • 1.由于项目需求,需要更改内核版本并搭建内核开发环境。 当前内核版本 指定内核版本:3.10.0-327.el7.x86_64 2.下载指定内核rpm安装包 下载地址:...
  • 版 次:5 印刷时间:2013年06月01日 包 装:平装 国际标准书号ISBN:9787115318244 丛书名:图灵程序设计丛书 ...**专注XNU内核开发实践的图书 一线设备驱动程序开发人员现身说法 轻松理解内核开发的复杂难懂之处
  • 嵌入式系统Linux内核开发实战指南(ARM平台),想看就看吧
  • linux内核开发详解

    2012-06-13 21:39:23
    一个很好的linux内核开发详解,大家快来看吧,不错哦
  • linux内核开发

    2016-02-02 11:54:09
    linux内核开发
  • Linux内核开发-入门篇

    万次阅读 2019-01-09 19:17:18
    如何入门 Linux 内核 首先,让我们看看如何获取、构建并运行 Linux 内核。你可以通过两种方式来运行你自己定制的内核: 在虚拟机里运行 Linux 内核; 在真实的硬件上运行 Linux 内核。 我会对这两种...
  • Linux 内核开发

    千次阅读 2018-11-08 23:27:35
    Linux 内核开发 简介 如你所知,我从去年开始写了一系列关于 x86_64 架构汇编语言程序设计的博文。除了大学期间写过一些 Hello World 这样无实用价值的程序之外,我从来没写过哪怕一行的底层代码。那些程序也...
  • Linux内核开发工作方向
  • linux内核开发如何上手

    千次阅读 2021-02-25 16:30:11
    linux内核开发听起来就很高大上,给人的感觉也很难上手,实际上只要找对了资源,是一件很简单那的事情。这篇博文将大致的让读者了解到linux内核开发的几个基础步骤 需要准备的资源 linux内核源码 这里是下载地址 第...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 479,562
精华内容 191,824
关键字:

内核开发