linux内核2.6和linux内核4.0的区别

Linux 内核的 2.6 和 4.0 版本之间的差异非常广泛,因为这两个版本之间有很多的迭代和改进。下面是一些比较明显的区别:

  1. 发布时间:

    • 2.6:2003 年发布。
    • 4.0:2015 年发布。
  2. 性能和可扩展性:

    • 4.0 版本在性能和可扩展性上都进行了大量优化,更好地支持了多处理器、多核心、NUMA 等现代硬件特性。
  3. Live Patching:

    • 在 4.0 中,内核引入了一种叫做 Live Patching 的新功能,它允许用户在不重启系统的情况下应用安全补丁。
  4. 文件系统:

    • 2.6 中,Ext3 是主要的文件系统,但随后 Ext4 在后续版本中成为了默认文件系统。4.0 中对 Ext4 进行了进一步的优化。
    • Btrfs 文件系统在 2.6 中刚开始出现,但在 4.0 版本中得到了进一步的完善和优化。
  5. 内存管理:

    • 4.0 对 Transparent Huge Pages (THP) 进行了改进,对 NUMA 系统进行了优化。
  6. 设备驱动:

    • 4.0 包括了更多的设备驱动,特别是对于新硬件的支持。
  7. 网络:

    • 4.0 对多种网络协议和功能进行了优化,如 TCP、IPv6 等。
  8. 容器技术:

    • 虽然容器技术在 2.6 中已经有了,但是到了 4.0,这项技术得到了进一步的发展和完善,尤其是与 Docker 和其他容器工具的集成。
  9. 安全:

    • 4.0 增加了更多的安全功能,如 seccomp、namespace 的改进等。
  10. 系统调用和APIs:

  • 4.0 版本引入了新的系统调用和APIs,同时废弃了一些旧的。

以上只是这两个版本之间的部分差异。实际上,这两个版本之间还有很多细节上的变化和改进。总之,从 2.6 到 4.0,Linux 内核经历了巨大的发展,不仅在性能和稳定性上有所提高,还引入了许多新的功能和技术。

在驱动开发上的不同

ChatGPT

在驱动开发上,Linux 内核 2.6 与 4.0 之间的变化也非常显著。这其中涉及到的核心概念、框架、APIs 和策略都有所更新和优化。以下列出了一些主要的差异:

  1. Device Tree (设备树):

    • 尤其针对 ARM 架构,Device Tree 成为了描述硬件的标准方式,减少了针对特定硬件平台的硬编码。
  2. 更好的硬件支持:

    • 随着时间的推移,新的硬件和技术不断涌现。4.0 内核增加了对许多新硬件的支持,这也意味着驱动开发人员需要适应这些新硬件。
  3. Generic PHY Framework (通用PHY框架):

    • 这是一个新的框架,用于处理各种物理层接口。
  4. Pin Control (pinctrl) 子系统:

    • 在 4.0 中,pinctrl 子系统提供了一个统一的方式来管理和配置 SoC 的引脚。
  5. 驱动模型的改进:

    • 2.6 开始引入了一个新的驱动模型,但到了 4.0,这个模型已经更加稳定和完善。
  6. Platform Drivers 和 Device Drivers 的区分:

    • 在 2.6 和 4.0 之间,对于平台驱动和设备驱动的处理方式也有所改进和区分。
  7. 新的内核APIs:

    • 随着内核的发展,一些老的APIs被废弃,而新的APIs被引入。这意味着驱动开发人员需要不断更新和维护他们的代码。
  8. 更好的电源管理:

    • 4.0 版本对于电源管理提供了更多的功能和策略,如 Runtime PM、系统休眠/唤醒等。
  9. Bus Types (总线类型):

    • 新的总线类型如 Greybus 被引入,而老的总线可能不再受到强烈的支持或优化。
  10. 更强的错误处理和调试支持:

  • 4.0 版本提供了更多的工具和机制来帮助驱动开发者诊断问题,如 Tracepoints、ftrace、perf 等。

总的来说,从 2.6 到 4.0,Linux 的驱动开发面临了许多新的挑战和机会。这些变化反映了硬件、软件和行业标准的不断进化,也使得驱动开发更为复杂。但同时,这也为驱动开发人员提供了更多的资源、工具和框架,使得开发过程更加高效和稳定。

查看内核版本

ChatGPT

要在Linux系统中查看内核版本,您可以使用命令行工具。以下是几种常用的方法:

  1. 使用 uname 命令:

     

    bashCopy code

    uname -r

    这将显示当前运行的内核版本。

  2. 查看 /proc/version 文件:

     

    bashCopy code

    cat /proc/version

    这将显示更详细的内核版本信息,包括编译日期、GCC版本等。

  3. 使用 dmesg 命令: 如果你想看到系统启动时的内核版本信息,你可以使用dmesg命令,然后从输出的开始部分查找:

     

    bashCopy code

    dmesg | grep "Linux version"

这些命令应该可以帮助你确定Linux系统上的内核版本。

ubantu 的module.h

ChatGPT

在 Ubuntu 和其他 Linux 发行版中,module.h 是内核头文件,主要用于模块编程。这个文件定义了一些用于内核模块操作的基本结构、宏和函数。

如果您在 Ubuntu 上进行内核模块开发,您可能需要这个头文件。通常,这个文件位于 /usr/src/linux-headers-$(uname -r)/include/linux/ 目录中,但前提是您已经安装了相应的内核头文件包。

要在 Ubuntu 上安装内核头文件,您可以使用以下命令:

 

bashCopy code

sudo apt update sudo apt install linux-headers-$(uname -r)

安装完成后,您可以找到 module.h 和其他内核头文件。如果您对内核模块编程或这个文件的内容有更深入的问题,请随时提问。

linux-headers-3.13.0-32

ChatGPT

linux-headers-3.13.0-32 是 Ubuntu 14.04 LTS (Trusty Tahr) 中的一个特定版本的内核头文件包。这些头文件主要用于那些需要与特定内核版本相对应的编译模块的场景。

如果您想在 Ubuntu 14.04 上安装这个特定版本的内核头文件,您可以使用以下命令:

 

bashCopy code

sudo apt update sudo apt install linux-headers-3.13.0-32-generic

请注意,如果您使用的是一个不同的Ubuntu版本或其他Linux发行版,这个包可能不可用,或者包名可能有所不同。

另外,由于 Ubuntu 14.04 已经达到了其生命周期的结束,所以默认的存档源可能不再提供这个包。如果您在安装时遇到问题,您可能需要从 Ubuntu 的旧版本存档中获取它,或者考虑升级到一个新的Ubuntu版本。

在 Ubuntu 14.04编写一个模块

ChatGPT

编写一个基础的 Linux 内核模块并在 Ubuntu 14.04 上加载它涉及以下步骤:

  1. 准备开发环境: 首先,确保您安装了必要的内核头文件和工具:
 

bashCopy code

sudo apt update sudo apt install linux-headers-$(uname -r) build-essential

  1. 编写模块代码: 创建一个新的文件,例如 hello_module.c,并添加以下内容:
 

cCopy code

#include <linux/module.h> // 必要的头文件 #include <linux/kernel.h> // KERN_INFO #include <linux/init.h> // init、exit 宏 MODULE_LICENSE("GPL"); // 模块许可证 MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple Hello World module"); static int __init hello_init(void) { printk(KERN_INFO "Hello, world!\n"); return 0; // 加载成功返回0 } static void __exit hello_exit(void) { printk(KERN_INFO "Goodbye, world!\n"); } module_init(hello_init); // 指定加载函数 module_exit(hello_exit); // 指定卸载函数

  1. 编写 Makefile: 为了编译模块,您需要一个 Makefile。创建一个新文件名为 Makefile,并添加以下内容:
 

makeCopy code

obj-m += hello_module.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

  1. 编译模块: 在终端中,导航到您的源代码目录并运行 make
 

bashCopy code

make

成功后,您应该在当前目录中看到一个名为 hello_module.ko 的文件。

  1. 加载和卸载模块: 使用以下命令将模块加载到内核中:
 

bashCopy code

sudo insmod hello_module.ko

检查 dmesg 输出,您应该看到 "Hello, world!" 消息。

使用以下命令从内核中卸载模块:

 

bashCopy code

sudo rmmod hello_module

再次检查 dmesg,您应该看到 "Goodbye, world!" 消息。

以上就是在 Ubuntu 14.04 上编写、编译和加载一个简单的 Linux 内核模块的基本步骤。这只是一个起始点,内核模块编程有很多其他的概念和功能可以探索。

obj-m :=和obj-m += 不同

ChatGPT

在 Linux 内核模块编程的 Makefile 中,obj-m 是一个特殊的变量,用于定义要编译为模块的对象文件。obj-y 是定义要直接链接到内核的对象文件。同样地,还有 obj-nobj-,分别用于表示不编译和条件编译的对象。

现在,来看 :=+= 的区别:

  1. obj-m :=

    当你使用 := 时,你实际上是在为 obj-m 赋一个新值。这意味着之前对 obj-m 的任何赋值都将被覆盖。简而言之,它设置了一个新值。

    例如:

     

    makefileCopy code

    obj-m := module1.o obj-m := module2.o

    在这个例子中,最终只有 module2.o 会被编译为一个模块,因为它覆盖了先前的赋值。

  2. obj-m +=

    当你使用 += 时,你是在向 obj-m 追加值。这意味着先前对 obj-m 的赋值不会被覆盖,新值会被添加到列表的末尾。

    例如:

     

    makefileCopy code

    obj-m += module1.o obj-m += module2.o

    在这个例子中,module1.omodule2.o 都将被编译为模块。

总结,:= 用于设置新值,而 += 用于追加值。在大多数内核模块的 Makefile 中,你会看到使用 +=,因为它允许你在多个地方逐步构建模块列表,而不是每次都重新设置它。

ifneq ($(KERNELRELEASE),) 何解

ChatGPT

在内核模块的 Makefile 中,经常可以看到如下结构:

 

makefileCopy code

ifneq ($(KERNELRELEASE),) # 内核构建系统的规则部分 else # 外部模块构建的规则部分 endif

这个结构是为了处理两种不同的编译场景。让我们详细解释一下:

  1. ifneq ($(KERNELRELEASE),) 检查 KERNELRELEASE 变量是否已经设置。KERNELRELEASE 是内核构建系统在构建过程中设置的一个变量,它包含正在构建的内核版本。

  2. 内核构建系统的规则部分:

    如果 KERNELRELEASE 已经被设置,这意味着我们当前处于内核构建系统的上下文中。这部分的规则是针对整个内核或内核模块构建的。

  3. 外部模块构建的规则部分:

    如果 KERNELRELEASE 没有被设置,我们不在内核构建系统的上下文中。这部分通常包含命令,例如调用内核构建系统来构建一个外部模块,例如:

     

    makefileCopy code

    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

这种方法的好处是,它允许同一个 Makefile 在两个不同的上下文中工作:一次是作为一个外部模块的构建脚本,一次是作为内核构建系统的一部分。这简化了模块的构建流程,因为不需要为两种情况维护两个不同的 Makefile。

如何查看$(KERNELRELEASE)

ChatGPT

$(KERNELRELEASE) 是在 Linux 内核构建过程中设置的一个变量,它包含了正在构建的内核的版本。它并不是一个常规的环境变量,所以你不能在常规的 shell 会话中直接查看它,例如使用 echo $KERNELRELEASE。这是一个为 Makefile 设定的变量。

但如果你想在构建内核模块时查看其值,你可以在 Makefile 中添加一个简单的规则来打印它。例如:

 

makefileCopy code

print-kernelrelease: @echo $(KERNELRELEASE)

然后,在你的 Makefile 所在的目录中运行:

 

bashCopy code

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) print-kernelrelease

这将使用当前运行的内核版本构建目标,并打印 $(KERNELRELEASE) 的值。

另外,如果你只是想知道你的系统上当前正在运行的内核版本,你可以简单地使用 uname -r 命令。

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

ChatGPT

这个命令是用来编译 Linux 内核模块的。让我们逐步解释这个命令的每一部分:

  1. make: 这是 GNU Make 工具,用于处理 Makefile 并执行相关命令。

  2. -C /lib/modules/$(shell uname -r)/build: -C 选项告诉 make 更改到指定的目录并在那里查找 Makefile/lib/modules/$(shell uname -r)/build 是当前系统正在运行的内核版本的内核头文件和构建文件的位置。

    其中,$(shell uname -r) 是一个 shell 命令,它返回当前运行的内核版本。

  3. M=$(PWD): 这告诉内核构建系统你的外部模块的源代码位于哪里。$(PWD) 是一个环境变量,代表当前目录。

  4. modules: 这是你想要执行的目标。对于内核构建系统,modules 目标意味着它将尝试编译指定目录(由 M 变量指定)中的所有内核模块。

综上所述,这个命令的作用是:在当前目录中查找源代码,然后在内核构建系统的上下文中编译这些源代码为内核模块。成功编译后,它会产生一个 .ko 文件(例如,mymodule.ko),这是一个可加载的内核模块。你可以使用 insmodrmmod 命令来加载和卸载这个模块。

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

ChatGPT

这个命令用于清理之前在 Linux 内核模块编译过程中产生的中间文件和输出。

让我们解析一下这个命令的各个部分:

  1. make: 这是 GNU Make 工具,用于处理 Makefile 并执行相关命令。

  2. -C /lib/modules/$(shell uname -r)/build: -C 选项告诉 make 更改到指定的目录并在那里查找 Makefile/lib/modules/$(shell uname -r)/build 是当前系统正在运行的内核版本的内核头文件和构建文件的位置。

    $(shell uname -r) 是一个 shell 命令,它返回当前运行的内核版本。

  3. M=$(PWD): 这告诉内核构建系统你的外部模块的源代码位于哪里。$(PWD) 是一个环境变量,代表当前目录。

  4. clean: 这是你想要执行的目标。对于内核构建系统,clean 目标表示它应该清理指定目录(由 M 变量指定)中的所有构建产物,例如 .o (对象文件)、.ko (内核模块)、以及其他的临时文件。

简而言之,该命令用于清理当前目录中的所有与内核模块编译相关的临时文件和输出,使得目录回到一个“干净”的状态。这通常在重新编译模块之前或者当你不再需要这些编译产物时执行。

/lib/modules/$(shell uname -r)/build

ChatGPT

/lib/modules/$(shell uname -r)/build 是一个指向 Linux 内核源代码树的符号链接,其中 $(shell uname -r) 返回当前系统正在运行的内核版本。

具体解释一下:

  1. /lib/modules/: 这是所有安装的 Linux 内核模块的基本存储位置。每个内核版本都有其自己的子目录。

  2. $(shell uname -r): 这是一个命令,它在 shell 中运行 uname -r 并返回结果。uname -r 返回当前运行的内核版本,例如 "5.4.0-26-generic"。

  3. /build: 对于每个内核版本的子目录,build 是一个符号链接,它指向用于构建该特定版本的内核的源代码树。

因此,/lib/modules/$(shell uname -r)/build 指向的是你当前运行的 Linux 内核版本的源代码目录。当你想要编译内核模块时,这个路径经常被用作参考路径,因为它包含了内核构建系统和内核配置文件,这些都是编译内核模块所必需的。

不过,要注意的是,如果你只是安装了内核,但没有安装相关的内核头文件包,那么这个 /build 链接可能不存在或不可用。在 Ubuntu 和其他基于 Debian 的系统上,可以使用以下命令来安装当前运行的内核的头文件:

 

bashCopy code

sudo apt update sudo apt install linux-headers-$(uname -r)

安装这些头文件后,/build 链接应该会指向正确的位置。

/lib/modules/$(shell uname -r)/build 可以找到 module.h

ChatGPT

/lib/modules/$(shell uname -r)/build 是当前运行的内核版本的源代码和头文件的路径。其中,module.h 是定义内核模块操作的关键头文件。

要在这个路径下找到 module.h,你可能需要查看 include/linux/ 子目录。具体地说,你可以在以下路径找到它:

 

bashCopy code

/lib/modules/$(shell uname -r)/build/include/linux/module.h

这个文件包含了内核模块开发所需的基本宏和函数定义,例如 module_init(), module_exit(), MODULE_LICENSE(), 等等。

如果你在该路径下没有找到 module.h 或者 /build 链接似乎不存在或不正确,那么可能是因为你没有为当前运行的内核版本安装内核头文件。在基于 Debian 的系统(如 Ubuntu)上,你可以使用以下命令来安装它们:

 

bashCopy code

sudo apt update sudo apt install linux-headers-$(uname -r)

安装完成后,你应该能在上述路径中找到 module.h 文件。

共计8个压缩包 本压缩包是:part01.rar 出版社:人民邮电出版社 ·页码:368 页 ·出版日期:2008年 ·ISBN:7115187118/9787115187116 ·条形码:9787115187116 ·包装版本:1版 ·装帧:平装 ·开本:16 ·中文:中文 ·附带品描述:附光盘一张 ·市场价格:49元 内容简介 Linux内核Linux操作系统中最核心的部分,用于实现对硬件部件的编程控制和接口操作。《Linux2.6内核标准教程》深入、系统地讲解了 Linux内核的工作原理,对Linux内核的核心组件逐一进行深入讲解。 全书共8章,首先讲解Linux系统的引导过程;然后对Linux内核的3大核心模块——内存管理、进程管理、中断和异常处理进行了深入的分析; 在此基础上,对时间度量、系统调用进行了分析和讨论;最后讲解了Linux内核中常见的同步机制,使读者掌握每处理器变量和RCU这两种新的 同步机制。 《Linux2.6内核标准教程》适合Linux内核爱好者、Linux驱动开发人员、Linux系统工程师参考使用,也可以作为计算机及相关专业学生深入学 习操作系统的参考书。 引用: 目录 第1章 Linux内核学习基础 1 1.1 为什么研究Linux内核 2 1.1.1 Linux的历史来源 2 1.1.2 Linux的发展现状 3 1.1.3 Linux的前景展望 3 1.2 选择什么版本进行研究 3 1.3 内核基本结构 4 1.3.1 内核在操作系统中的地位 4 1.3.2 Linux 2.6内核源代码目录树简介 5 1.3.3 Linux 2.6内核的新特性 8 1.4 如何阅读本书 9 1.4.1 内核探索工具 10 1.4.2 推荐阅读方法 12 第2章 引导过程分析 14 2.1 内核镜像的构建过程 15 2.1.1 编译内核的步骤及分析 15 2.1.2 内核镜像构建过程分析 16 2.2 系统引导过程分析 18 2.2.1 傀儡引导扇区 18 2.2.2 探测系统资源 21 2.2.3 解压内核镜像 35 2.2.4 进入保护模式 40 2.2.5 系统最终初始化 47 2.3 系统引导过程总结 47 第3章 内存管理 50 3.1 基础知识 51 3.1.1 存储器地址 51 3.1.2 分段机制 52 3.1.3 分页机制 59 3.2 内核页表的初始化过程 65 3.2.1 启用分页机制 65 3.2.2 构建内核页表 68 3.3 物理内存的描述方法 76 3.3.1 内存节点 77 3.3.2 内存区域 81 3.3.3 物理页框 85 3.4 物理内存的初始化过程 86 3.4.1 探测系统物理内存 87 3.4.2 初始化内存分配器 89 3.5 物理内存的分配与回收 101 3.5.1 伙伴分配算法 101 3.5.2 对象缓冲技术 103 3.6 内核地址空间 105 3.6.1 常规映射地址空间 105 3.6.2 固定映射地址空间 107 3.6.3 长久内核映射空间 109 3.6.4 临时内核映射空间 116 3.6.5 非连续映射地址空间 119 第4章 进程管理 128 4.1 进程与线程的概念 129 4.1.1 程序与进程 129 4.1.2 进程与线程 129 4.2 进程描述符 131 4.2.1 进程标识符 132 4.2.2 进程的状态 132 4.2.3 进程上下文 134 4.2.4 当前进程 139 4.3 进程的组织形式 143 4.3.1 进程标识符构成的哈希表 143 4.3.2 所有进程构成的双向链表 148 4.3.3 执行态进程组成的运行队列 149 4.3.4 阻塞态进程组成的等待队列 152 4.4 进程的创建过程 155 4.4.1 进程创建的接口函数 156 4.4.2 进程创建的处理过程 162 4.5 进程调度算法 177 4.5.1 进程的分类 178 4.5.2 进程优先级 178 4.5.3 时间片分配 181 4.5.4 进程调度时机 182 4.6 进程切换过程分析 183 4.6.1 选取合适进程 183 4.6.2 完成上下文切换 184 4.7 空闲进程的初始化 187 4.7.1 空闲进程的内核态栈 187 4.7.2 空闲进程的内存描述符 188 4.7.3 空闲进程的硬件上下文 190 4.7.4 空闲进程的任务状态段 190 第5章 中断和异常 192 5.1 基础知识 193 5.1.1 中断和异常的定义 193 5.1.2 中断和异常的分类 193 5.1.3 中断和异常的对比 194 5.2 处理机制 195 5.2.1 IA32架构下的处理机制 195 5.2.2 Linu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值