linux/include/asm-powerpc/posix_types.h

本文档详细介绍了 PowerPC 架构下 Linux 操作系统中 POSIX 类型的定义,包括各种基本类型如 ino_t、mode_t 和高级类型如 fsid_t 的具体实现方式。此外还提供了一些特定于 PowerPC 架构的类型定义。

linux/include/asm-powerpc/posix_types.h


  1 #ifndef _ASM_POWERPC_POSIX_TYPES_H
  2 #define _ASM_POWERPC_POSIX_TYPES_H
  3 
  4 /*
  5  * This file is generally used by user-level software, so you need to
  6  * be a little careful about namespace pollution etc.  Also, we cannot
  7  * assume GCC is being used.
  8  */
  9 
 10 typedef unsigned long   __kernel_ino_t;
 11 typedef unsigned int    __kernel_mode_t;
 12 typedef long            __kernel_off_t;
 13 typedef int             __kernel_pid_t;
 14 typedef unsigned int    __kernel_uid_t;
 15 typedef unsigned int    __kernel_gid_t;
 16 typedef long            __kernel_ptrdiff_t;
 17 typedef long            __kernel_time_t;
 18 typedef long            __kernel_clock_t;
 19 typedef int             __kernel_timer_t;
 20 typedef int             __kernel_clockid_t;
 21 typedef long            __kernel_suseconds_t;
 22 typedef int             __kernel_daddr_t;
 23 typedef char *          __kernel_caddr_t;
 24 typedef unsigned short  __kernel_uid16_t;
 25 typedef unsigned short  __kernel_gid16_t;
 26 typedef unsigned int    __kernel_uid32_t;
 27 typedef unsigned int    __kernel_gid32_t;
 28 typedef unsigned int    __kernel_old_uid_t;
 29 typedef unsigned int    __kernel_old_gid_t;
 30 
 31 #ifdef __powerpc64__
 32 typedef unsigned long   __kernel_nlink_t;
 33 typedef int             __kernel_ipc_pid_t;
 34 typedef unsigned long   __kernel_size_t;
 35 typedef long            __kernel_ssize_t;
 36 typedef unsigned long   __kernel_old_dev_t;
 37 #else
 38 typedef unsigned short  __kernel_nlink_t;
 39 typedef short           __kernel_ipc_pid_t;
 40 typedef unsigned int    __kernel_size_t;
 41 typedef int             __kernel_ssize_t;
 42 typedef unsigned int    __kernel_old_dev_t;
 43 #endif
 44 
 45 #ifdef __powerpc64__
 46 typedef long long       __kernel_loff_t;
 47 #else
 48 #ifdef __GNUC__
 49 typedef long long       __kernel_loff_t;
 50 #endif
 51 #endif
 52 
 53 typedef struct {
 54         int     val[2];
 55 } __kernel_fsid_t;
 56 
 57 #ifndef __GNUC__
 58 
 59 #define __FD_SET(d, set)        ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
 60 #define __FD_CLR(d, set)        ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
 61 #define __FD_ISSET(d, set)      (((set)->fds_bits[__FDELT(d)] & __FDMASK(d)) != 0)
 62 #define __FD_ZERO(set)  /
 63   ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
 64 
 65 #else /* __GNUC__ */
 66 
 67 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) /
 68     || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
 69 /* With GNU C, use inline functions instead so args are evaluated only once: */
 70 
 71 #undef __FD_SET
 72 static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 73 {
 74         unsigned long _tmp = fd / __NFDBITS;
 75         unsigned long _rem = fd % __NFDBITS;
 76         fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
 77 }
 78 
 79 #undef __FD_CLR
 80 static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
 81 {
 82         unsigned long _tmp = fd / __NFDBITS;
 83         unsigned long _rem = fd % __NFDBITS;
 84         fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
 85 }
 86 
 87 #undef __FD_ISSET
 88 static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set *p)
 89 { 
 90         unsigned long _tmp = fd / __NFDBITS;
 91         unsigned long _rem = fd % __NFDBITS;
 92         return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
 93 }
 94 
 95 /*
 96  * This will unroll the loop for the normal constant case (8 ints,
 97  * for a 256-bit fd_set)
 98  */
 99 #undef __FD_ZERO
100 static __inline__ void __FD_ZERO(__kernel_fd_set *p)
101 {
102         unsigned long *tmp = (unsigned long *)p->fds_bits;
103         int i;
104 
105         if (__builtin_constant_p(__FDSET_LONGS)) {
106                 switch (__FDSET_LONGS) {
107                       case 16:
108                         tmp[12] = 0; tmp[13] = 0; tmp[14] = 0; tmp[15] = 0;
109                         tmp[ 8] = 0; tmp[ 9] = 0; tmp[10] = 0; tmp[11] = 0;
110 
111                       case 8:
112                         tmp[ 4] = 0; tmp[ 5] = 0; tmp[ 6] = 0; tmp[ 7] = 0;
113 
114                       case 4:
115                         tmp[ 0] = 0; tmp[ 1] = 0; tmp[ 2] = 0; tmp[ 3] = 0;
116                         return;
117                 }
118         }
119         i = __FDSET_LONGS;
120         while (i) {
121                 i--;
122                 *tmp = 0;
123                 tmp++;
124         }
125 }
126 
127 #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
128 #endif /* __GNUC__ */
129 #endif /* _ASM_POWERPC_POSIX_TYPES_H */
<think>我们面对的问题是:用户报告在编译内核驱动模块时遇到 fatal error: asm/xxx: No such file or directory 错误,具体是找不到 /usr/include/asm-generic/posix_types.h 文件。根据引用[1]中的信息,用户可能是在交叉编译环境下(如ARM架构)遇到了头文件缺失的问题。 分析: 1. 错误信息表明编译器在 `/usr/include/asm-generic/` 目录下找不到 `posix_types.h` 文件。 2. 通常,这个文件是Linux内核头文件的一部分,属于系统头文件。在交叉编译环境中,我们需要确保目标架构的头文件可用。 3. 引用[1]中提供了一个Makefile片段,其中设置了几个重要的环境变量: - `ARCH=arm`:指定目标架构为ARM。 - `CROSS_COMPILE=arm-linux-gnueabihf-`:指定交叉编译工具链前缀。 - 还指定了内核源代码路径`KERNELDIR`和当前路径`CURRENT_PATH`。 4. 这个错误可能是因为在交叉编译时,编译器仍然尝试使用宿主系统的头文件路径(如`/usr/include`),而不是目标系统的头文件路径。 解决方案思路: 1. 确保已经为目标架构安装了正确的头文件(内核头文件)。 2. 在编译时正确指定头文件搜索路径,避免使用宿主系统的头文件。 具体步骤: 步骤1:安装目标架构的内核头文件 在Ubuntu宿主机上,我们可以通过包管理器安装针对ARM架构的内核头文件。尝试安装: ```bash sudo apt install linux-headers-generic ``` 但是,这安装的是宿主架构(如x86)的头文件。对于ARM,我们需要安装交叉编译的头文件包。通常,对于ARM架构,可以尝试安装: ```bash sudo apt install linux-headers-$(uname -r) ``` 但注意,这仍然是宿主架构的。 实际上,对于交叉编译,我们需要的是目标板的内核头文件。通常,这些头文件应该从目标板的内核源代码中获取。因此,用户应该已经有一个目标板的内核源代码树(如引用[1]中设置的`KERNELDIR=/mnt/hgfs/Ubuntu/ebf_6ull_linux`),这个路径应该包含目标内核的头文件。 步骤2:在编译时指定头文件路径 在Makefile中,我们可以通过`-I`选项添加头文件搜索路径。但是,在引用[1]的Makefile中,我们是通过`-C $(KERNELDIR)`来指定内核源代码目录的,这应该已经包含了正确的头文件。但是,错误中出现的路径是`/usr/include/asm-generic/posix_types.h`,这表明编译器仍然在搜索宿主系统的头文件目录。 为了避免使用宿主系统的头文件,我们可以尝试在编译时指定`-nostdinc`选项,然后手动添加内核头文件路径。但是,这可能会比较复杂。 一个更简单的方法是在Makefile中设置`CC`变量,使用交叉编译器的gcc,并且通过环境变量告诉编译器不要使用默认的宿主头文件路径。但是,通常交叉编译工具链已经配置了正确的头文件路径。 然而,引用[1]中已经设置了`CROSS_COMPILE=arm-linux-gnueabihf-`,那么编译器应该是`arm-linux-gnueabihf-gcc`。我们可以检查这个交叉编译器是否能找到目标架构的头文件。 步骤3:检查交叉编译器的头文件路径 我们可以手动调用交叉编译器来查看头文件搜索路径: ```bash arm-linux-gnueabihf-gcc -v -E -x c /dev/null ``` 在输出中,我们可以查看`#include <...> search starts here:`部分,看是否包含了目标架构的头文件路径。 步骤4:在Makefile中显式添加头文件路径 如果交叉编译器的默认路径中不包含所需的头文件,我们可以在Makefile中添加: ```makefile CFLAGS += -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include ``` 注意:具体路径可能根据内核源代码的布局有所不同。 步骤5:确保内核源代码已经配置并生成了头文件 在内核源代码目录中,通常需要先进行配置和编译,以生成一些头文件(例如,在内核源代码目录下执行`make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig`和`make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare`)。这一步会生成一些头文件,包括`include/generated`和`arch/arm/include/generated`等目录下的文件。 根据上述分析,我建议用户首先确保已经正确配置和准备内核源代码树,然后在Makefile中检查是否已经正确设置了内核头文件路径。如果问题仍然存在,可以尝试在Makefile中显式添加头文件路径。 具体到用户的错误信息:`fatal error: asm/xxx: No such file or directory`,这里`xxx`可能是具体的头文件名,比如`posix_types.h`。在内核源代码中,`asm-generic`目录下的头文件通常位于`include/asm-generic`和`arch/arm/include/asm`等位置。因此,我们需要确保这些路径被包含。 修改Makefile示例: ```makefile # 在原有的基础上,添加额外的头文件路径 EXTRA_CFLAGS += -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include ``` 注意:在编译内核模块时,通常使用`EXTRA_CFLAGS`来传递额外的编译选项。 但是,在引用[1]的Makefile中,并没有使用`EXTRA_CFLAGS`,而是通过`$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules`来调用内核的编译系统。在这种情况下,内核编译系统会自动设置头文件路径。因此,问题可能在于内核源代码树没有准备好。 因此,重点步骤: 1. 进入`$(KERNELDIR)`,执行`make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig`(如果还没有配置) 2. 执行`make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare`来生成必要的头文件。 如果用户已经做了这些准备步骤,那么可能是内核源代码树不完整或者配置不正确。 总结解决方案: 1. 确保目标板的内核源代码已经正确配置和准备(生成头文件)。 2. 检查交叉编译工具链是否安装正确,并且能够找到目标架构的头文件。 3. 在Makefile中,确保`KERNELDIR`指向的内核源代码路径是正确的,并且该路径下包含所需的头文件。 4. 如果问题依旧,尝试在编译命令中添加`-nostdinc`选项,并手动添加内核头文件路径(这需要谨慎,因为内核编译通常需要很多特定的路径)。 由于用户具体错误是`/usr/include/asm-generic/posix_types.h`找不到,我们可以尝试避免使用宿主头文件。在内核模块编译中,应该避免使用宿主系统的头文件,因为内核模块需要与目标内核一起工作,所以应该只使用目标内核的头文件。 因此,我们可以在Makefile中添加: ```makefile # 禁用标准头文件搜索,只使用内核头文件 EXTRA_CFLAGS += -nostdinc -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include -I$(KERNELDIR)/arch/arm/include/generated -I$(KERNELDIR)/include/generated -I$(KERNELDIR)/arch/arm/include/uapi -I$(KERNELDIR)/arch/arm/include/generated/uapi -I$(KERNELDIR)/include/uapi -I$(KERNELDIR)/include/generated/uapi ``` 但是,请注意,内核编译系统通常已经处理了这些路径,手动添加可能会破坏其他设置。所以,最佳实践是确保内核源代码树已经准备妥当。 考虑到用户使用的是类似引用[1]的Makefile,我们建议用户首先在内核源代码目录中执行`make prepare`(使用正确的ARCH和CROSS_COMPILE)。如果用户已经做了这一步,那么可能是内核版本或配置问题。 另外,注意`/usr/include/asm-generic`是宿主系统的头文件目录,而交叉编译时不应该使用它。我们可以通过设置`-nostdinc`来禁止编译器搜索标准系统头文件目录,这样就会强制使用内核源代码树中的头文件。 因此,修改Makefile,在编译模块时添加`-nostdinc`选项: ```makefile # 在调用内核编译系统时,我们可以通过EXTRA_CFLAGS传递这个选项 # 在build目标中,修改为: build: kernel_modules kernel_modules: $(MAKE) $(ENV) EXTRA_CFLAGS=-nostdinc -C $(KERNELDIR) M=$(CURRENT_PATH) modules ``` 注意:`EXTRA_CFLAGS`是内核编译系统识别的变量,用于传递额外的编译选项。 但是,使用`-nostdinc`可能会过于严格,因为内核头文件可能需要包含一些编译器自带的头文件(如`stddef.h`等)。所以,更安全的方法是只添加必要的路径,并排除宿主系统的`/usr/include`。 实际上,内核编译系统已经处理了头文件路径,所以最可能的原因还是内核源代码树没有准备好(缺少必要的生成头文件)。因此,我们首先强调准备内核源代码树。 综上所述,我们给出以下解决方案: 1. 确保内核源代码树已经正确配置并生成了头文件: ```bash cd /mnt/hgfs/Ubuntu/ebf_6ull_linux # 替换为你的KERNELDIR make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig # 如果还没有配置 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare ``` 2. 如果上述步骤不能解决问题,尝试在Makefile的编译命令中添加`-nostdinc`选项,并手动添加内核头文件路径(谨慎使用)或者检查内核头文件路径是否正确。 3. 如果用户确定宿主系统的头文件被错误引用,可以尝试在Makefile中设置: ```makefile # 禁用标准头文件 EXTRA_CFLAGS := -nostdinc ``` 4. 另外,检查`/usr/include/asm-generic/posix_types.h`在宿主系统是否存在?如果不存在,可能需要安装宿主系统的头文件(但这是宿主架构的,不应用于交叉编译)。所以,我们不应该依赖宿主系统的这个头文件。 由于用户的问题具体是`asm-generic/posix_types.h`,我们可以查看内核源代码树中是否有这个文件: 在`include/asm-generic/posix_types.h`,或者`arch/arm/include/asm-generic/`下?实际上,`asm-generic`通常在`include/`目录下。所以,在内核源代码目录下,应该有`include/asm-generic/posix_types.h`。 因此,确保`make prepare`已经执行,生成了这个文件(它应该是存在的,因为它是内核源代码的一部分,不需要生成)。 如果内核源代码树中没有这个文件,可能是内核版本问题或者源代码不完整。 最后,如果用户的内核源代码树是完整的,并且已经执行了`make prepare`,那么问题可能在于编译时没有正确覆盖宿主头文件路径。我们可以尝试在Makefile中强制指定头文件路径: ```makefile # 在Makefile中添加 EXTRA_CFLAGS += -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include ``` 但是,内核编译系统已经包含了这些路径,所以重复包含可能导致冲突。因此,优先检查内核准备步骤。 鉴于用户的问题描述,我们给出以下步骤: 步骤1:准备内核源代码树 ```bash cd /mnt/hgfs/Ubuntu/ebf_6ull_linux make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare ``` 步骤2:检查内核源代码树中是否存在`include/asm-generic/posix_types.h` ```bash ls include/asm-generic/posix_types.h ``` 步骤3:如果不存在,可能是内核配置问题,或者源代码不完整,需要重新下载或复制。 步骤4:如果存在,尝试在Makefile中显式添加头文件路径(可选,如果步骤1之后问题解决则跳过): ```makefile # 修改build规则,添加EXTRA_CFLAGS kernel_modules: $(MAKE) $(ENV) EXTRA_CFLAGS="-I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include" -C $(KERNELDIR) M=$(CURRENT_PATH) modules ``` 步骤5:如果仍然报错,尝试使用`-nostdinc`: ```makefile kernel_modules: $(MAKE) $(ENV) EXTRA_CFLAGS="-nostdinc -I$(KERNELDIR)/include -I$(KERNELDIR)/arch/arm/include" -C $(KERNELDIR) M=$(CURRENT_PATH) modules ``` 注意:使用`-nostdinc`可能会引起其他头文件缺失,需要把必要的路径都加上。内核编译系统通常已经包含了所有需要的路径,所以使用`-nostdinc`后可能还需要添加更多路径,比如编译器自带的头文件路径。因此,这种方法需要谨慎。 考虑到问题的复杂性,我们优先推荐步骤1和2。 最后,如果用户的问题仍然存在,可能需要检查内核版本与交叉编译工具链的兼容性。 生成相关问题: 1. 如何正确配置Linux内核源代码树以用于编译内核模块? 2. 交叉编译内核模块时如何设置头文件搜索路径? 3. 为什么在编译内核模块时需要避免使用宿主系统的头文件? 4. 如何检查交叉编译工具链的头文件搜索路径? 5. 在Makefile中设置`EXTRA_CFLAGS`和直接修改`CFLAGS`有什么区别? 根据以上分析,我们给出回答。 </think> ### 解决系统找不到 `/usr/include/asm-generic/posix_types.h` 文件的方法 该错误通常在交叉编译内核模块时发生,原因是编译环境未正确指向目标架构的头文件路径。以下是具体解决方案: --- #### **1. 确认并安装缺失的头文件包** ```bash # 检查头文件包是否安装 sudo apt search linux-headers-$(uname -r) # 安装对应版本的头文件包 sudo apt install linux-headers-$(uname -r) ``` 若提示架构不匹配(如宿主系统是x86而目标为ARM),需安装目标架构的头文件: ```bash sudo apt install linux-headers-arm64 # ARM64架构示例 ``` --- #### **2. 在Makefile中显式指定头文件路径** 修改模块的Makefile,添加目标架构的头文件路径: ```makefile # 添加在CFLAGS中 EXTRA_CFLAGS += -I$(KERNELDIR)/include \ -I$(KERNELDIR)/arch/arm/include \ -I$(KERNELDIR)/include/uapi \ -I$(KERNELDIR)/include/generated/uapi ``` --- #### **3. 强制使用内核树头文件(避免宿主系统路径)** 在Makefile编译命令中添加 `-nostdinc` 选项禁用系统默认路径: ```makefile kernel_modules: $(MAKE) $(ENV) EXTRA_CFLAGS=-nostdinc -C $(KERNELDIR) M=$(CURRENT_PATH) modules ``` --- #### **4. 验证内核树完整性** 确保内核源代码已正确配置并生成头文件: ```bash cd /mnt/hgfs/Ubuntu/ebf_6ull_linux # 替换为实际KERNELDIR make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare # 生成头文件 ``` --- #### **5. 创建缺失头文件的符号链接(临时方案)** ```bash # 查找内核树中的posix_types.h find $(KERNELDIR) -name posix_types.h # 创建符号链接(示例路径) sudo ln -s $(KERNELDIR)/include/asm-generic/posix_types.h /usr/include/asm-generic/ ``` --- #### **关键问题排查点** 1. 检查 `KERNELDIR` 是否指向完整的内核源代码,而非二进制文件 2. 确认 `CROSS_COMPILE` 前缀与工具链实际名称一致(如 `arm-linux-gnueabihf-gcc` 是否存在) 3. 验证目标架构头文件目录存在: ```bash ls $(KERNELDIR)/arch/arm/include # ARM架构示例 ``` > **根本原因**:交叉编译时,编译器默认搜索宿主系统的 `/usr/include` 路径,但该路径缺少目标架构的头文件。解决方案的核心是强制编译器使用内核源代码树中的目标架构头文件[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值