内核头文件

英文的原来的网址:http://kernelnewbies.org//KernelHeaders

KernelHeaders

Header files in the Linux kernel are used for two purposes:

  1. to define interfaces between components of the kernel, and

  2. to define interfaces between the kernel and user space

Internal modules

Internal interfaces between modules are defined anywhere in below linux/include/ or linux/arch/*/include/. Interfaces between source files in a single module should be put into the same directory as the module source code, which avoids polluting the global header space.

External modules

In order to build external kernel modules, you need the exact version of the headers from the kernel that the modules are built for. http://lwn.net/Articles/21823/ explains how to write an external Makefile to use those headers. When you do this, the kernel Makefiles will automatically choose the correct include path for both source and build directory and for using the include/asm headers from the right architecture.

While traditionally the kernel source was installed in /usr/src/linux, this is no longer supported for building external modules. Instead, your Makefile should point to /lib/modules/${kver}/build, where ${kver} is the exact version string of the kernel, e.g. the output of uname -r for the currently running kernel.

User space programs

In general, user space programs are built against the header files provided by the distribution, typically from a package named glibc-devel, glibc-kernheaders or linux-libc-dev. These header files are often from an older kernel version, and they cannot safely be replaced without rebuilding glibc as well. In particular, installing /usr/include/linux as a symbolic link to /usr/src/linux/include or /lib/modules/*/build/include/linux is highly discouraged as it frequently breaks rebuilding applications. For instance, older kernels had the architecture specific header files in include/asm-${arch} instead of arch/${arch}/include/asm and had on a symlink to the architecture specific directory.

The correct way to package the header files for a distribution is to run 'make headers_install' from the kernel source directory to install the headers into /usr/include and then rebuild the C library package, with a dependency on the specific version of the just installed kernel headers.

If you are distributing a user space program that depends on a specific version of some kernel headers, e.g. because your program runs only on patched or very recent kernels, you cannot rely on the headers in /usr/include. You also cannot use the header files from /usr/src/linux/include or /lib/modules/*/build/include/ because they have not been prepared for inclusion in user space. The kernel should warn you about this if you try it and point you to this Wiki page. The correct way to address this problem is to isolate the specific interfaces that you need, e.g. a single header file that is patched in a new kernel providing the ioctl numbers for a character device used by your program. In your own program, add a copy of that source file, with a notice that it should be kept in sync with new kernel versions. If your program is not licensed under GPLv2, make sure you have permission from the author of that file to distribute it under the license of your own program. Since your program now depends on kernel interfaces that may not be present in a regular kernel, it's a good idea to add run-time checks that make sure the kernel understands the interface and give a helpful error message if there is no fallback to an older interface.

Tell others about this page:

翻译后:中文

网址:http://blog.chinaunix.net/uid-28663607-id-3552656.html

昨天,同事在编译应用层程序(V4L2相关)的时候出现了一个这样的警告:


  1. */2.6.37/include/linux/types.h:13:2: warning: #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
     然后问我这个怎么消除。我也是第一次注意到这个警告(以前可能有出现,可能我没有注意吧)。然后我根据后面提供的网址,研读了一下这份英文资料,发现这个原来是头文件的使用不当产生的。 英文资料翻译如下:

  1. 内核头文件

  2. Linux内核中的头文件用于两个目的:

  3. 1、定义内核组件间的接口,和
  4. 2、定义内核与用户空间的接口

  5. 内部模块

  6. 模块间的内部接口在linux/include/ 或 linux/arch/*/include/ 下都有定义。一个单独模块的源文件间的接口应该同模块源码置于同一目录下,避免污染全局头文件空间。

  7. 外部模块

  8. 为了编译外部内核模块,你需要来自该模块所针对内核的头文件。Driver porting: compiling external modules 解释了如何编写一个外置的Makefile来使用这些头文件。照此做法,内核Makefile将为源码和编译目录自动选择正确的包含路径,并从正确的构架中使用include/asm头文件。

  9. 传统的内核源码安装在/usr/src/linux下,这不再支持外部模块的编译。相反,你的Makefile应该指向/lib/modules/${kver}/build,其中${kver}是内核确切的版本字符串,例如:对于当前正在运行的内核,就是“uname -r”的输出。

  10. 用户空间程序

  11. 一般来说,用户空间程序是针对发行版提供的头文件编译的,通常源于glibc-devel、glibc-kernheaders 或 linux-libc-dev。这些头文件通常来源于旧版内核,并不能安全地在不重新编译glibc的情况下被替换。特别地,作为一个到/usr/src/linux/include或/lib/modules/*/build/include/linux的符号链接/usr/include/linux,是极不推荐使用的。因为它经常使重新编译的应用程序损坏。例如,旧内核使用include/asm-${arch}存放架构特定的头文件,而不是现在的arch/${arch}/include/asm ,且没有符号链接到架构特定的目录。

  12. 为一个发行版打包头文件正确的方法是在内核源码目录下运行 'make headers_install'来安装头文件到/usr/include,并依赖这个刚刚安装的特定版本的内核头文件重新编译C库包。

  13. 如果你正在发布一个依赖某个特定版本内核头文件的用户空间程序,比如因为你的程序只运行在打过补丁或者最新的内核上,你不能依赖/usr/include中的头文件。你也不能使用来自/usr/src/linux/include 或/lib/modules/*/build/include/的头文件,因为他们还没有为用户空间的包含做好准备。若你尝试这么做了,内核会警告你并指引你到这个Wiki页解决这个问题的正确方法是独立出你需要的特定接口,比如一个打过补丁的新内核并为你的应用程序提供字符设备ioctl号的独立头文件。在你自己的程序中添加一份这个源文件的拷贝,并说明这个应该和新内核版本保持一致。如果你的程序不遵循GPLv2证书,请保证你得到了这个文件作者的许可:可在你自己程序的证书下发布它。因为你的程序现在依赖的内核接口并不在常规内核中。在这种情况下,一个推荐的做法是通过运行时检测来保证内核知道这个接口并在无法向下兼容旧接口的时候给出有用的错误信息。

   看了这个说明,我就明白了,我同事直接使用了内核源码中没有处理过的头文件。而我一般都是使用编译器中自动包含的头文件,那个是通过 ' make headers_install ' 安装的,所以一般不会出这样的警告。

   后来,我让同事使用以下的方法解决了这个警告

  1. 1、在内核源码根目录下运行: 'make headers_install',这样内核Makefile会把提供给应用程序的头文件提取并放在内核源码的“usr/include”目录下。
  2. (请勿担心git会发现文件增加了,usr目录中的.gitignore文件已经让git忽略了其下的include文件夹)

  3. 2、在编译应用程序的时候,在GCC的CFLAG参数中添加“-I(内核源码路径)/usr/include”,这样编译器就知道在编译时找到相关的头文件了。
----------------------------------------------------------------------------------------------
  平时我们在编译应用程序的时候,不可避免的会使用内核头文件,比如v4l2,字符驱动等等。此时直接的使用内核源码中include目录下的头文件,可能就会有警告。这个警告现在看来仅在" include/linux/types.h"中存在,因为这个文件中包含了很多内核自定义的类型,你的应用程序如果也做了这样的定义就可能出现问题。此时你就应该使用内核帮你处理过的专门提供给用户空间的头文件,这个就是为什么 'make headers_install'会将头文件(默认)放在usr(用户)目录下的原因。

  关于这个头文件的问题,其实是有一段历史故事的: 《内核头文件传奇》。挺有意思的,大家看过后就知道内核头文件的使用为什么是这样了。



<think>好的,我现在需要帮助用户解决在Kali Linux上安装内核头文件的问题。首先,我得回忆一下之前提供的引用内容。引用[1]提到了使用apt-get命令安装特定版本的内核头文件,命令是apt-get install linux-headers-`uname -r`或者用$(uname -r)。引用[2]提到了复制generated目录下的内容到include/linux/,这可能是在安装后需要进行的额外步骤。引用[3]是关于Debian安全更新源的配置,可能在某些情况下需要添加正确的源才能成功安装。 用户现在的问题是询问如何在Kali Linux上安装内核头文件。根据引用[1],直接使用apt-get安装应该是最直接的方法。不过,我需要确保用户知道如何正确执行这些命令,可能需要先更新系统,或者处理可能的依赖问题。此外,有时候内核头文件的版本必须与当前运行的内核完全匹配,所以使用uname -r获取版本号是关键步骤。 另外,引用[2]中的复制步骤可能是在某些旧版本或特定情况下需要手动操作,但现代Kali Linux可能已经不需要这个步骤了。不过,为了全面起见,我应该提到这一点,以防用户遇到问题。 还有,引用[3]提到的源配置,如果用户遇到安装失败,可能需要检查软件源是否正确,并确保有可用的更新源。特别是如果用户使用的是较旧的Kali版本,可能需要调整源列表。 接下来,我需要组织这些信息,分步骤说明安装过程。首先推荐标准方法,使用apt-get安装。然后,如果遇到问题,检查内核版本是否匹配,可能需要手动下载头文件。最后,处理可能的依赖问题和配置软件源。 同时,用户可能需要了解为什么需要安装内核头文件,比如编译驱动程序或某些安全工具,但用户的问题主要是如何安装,所以可能不需要深入解释用途,除非用户后续提问。 最后,生成相关问题,考虑用户可能的后续疑问,比如验证安装、处理安装错误、更新内核后的操作等。</think>### Kali Linux内核头文件安装方法 在Kali Linux中安装内核头文件需要确保内核版本与头文件版本完全匹配,以下是具体步骤: #### 第一步:标准安装方法 1. **更新系统** 执行命令确保系统处于最新状态: ```bash sudo apt update && sudo apt full-upgrade -y ``` 2. **安装内核头文件** 使用`uname -r`动态获取当前内核版本,并安装对应头文件: ```bash sudo apt install linux-headers-$(uname -r) -y ``` 该命令通过变量替换自动匹配当前内核版本[^1]。 #### 第二步:验证安装 1. **检查安装路径** 成功安装后,头文件会存储在`/usr/src/`目录下: ```bash ls /usr/src/linux-headers-$(uname -r) ``` 2. **手动补充文件(特殊需求)** 在旧版本系统(如Kali Rolling 2016)中可能需要手动操作: ```bash cd /usr/src/linux-headers-$(uname -r) cp -rf include/generated/* include/linux/ ``` 该操作确保头文件完整性[^2]。 #### 第三步:异常处理方案 | 问题现象 | 解决方案 | |---------|----------| | `E: Package not found` | 检查`/etc/apt/sources.list`是否包含官方源[^3] | | 内核版本不匹配 | 通过`apt search linux-headers`查看可用版本 | | 依赖错误 | 执行`sudo apt --fix-broken install`修复依赖链 | #### 关键原理说明 内核头文件包含构建内核模块所需的宏和函数声明,其版本必须与当前运行的`kernel image`完全一致。使用动态版本号获取`$(uname -r)`可避免手动输入错误,这是模块编译工作的基础要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值