从源代码树构建 Linux 内核模块

Build a Linux Kernel Module from a source tree

我正在尝试为 linux-sunxi(Cubieboard 2、A20、Arm Cortex A8)交叉编译 Linux 内核模块(driver)。我做了什么:

  1. 阅读有关如何为 A20 构建内核的文章:http://linux-sunxi.org/Linux_Kernel#Compilation。已经搞定了,内核已经构建成功

  2. 尝试使用以下 Makefile 构建我的简单(只是 "Hello, World!")模块:

    ifeq ($(KERNELRELEASE),)
        KERNELDIR = /home/nikita/linux-sunxi/output/lib/modules/3.4.61/build
        PWD =$(shell pwd)
    modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
    clean:                    
        rm -rf *.o *.ko .tmp_versions *.mod.c modules.order  Module.symvers 
    else                      
        obj-m :=my_mod.o
    endif
    

我成功地使用了这样一个Makefile来构建宿主机的内核(KERNELDIR=/lib/modules/$(CURRENT)/build)。但这是我第一次使用 Linux headers 的内核源代码树来做 cross-compilation。我有以下错误:

CC [M]  /home/nikita/Kernel_Study/linaro_first_module/my_mod.o
In file included from /home/nikita/linux-sunxi/arch/x86/include/asm/bitops.h:16:0,
                 from include/linux/bitops.h:22,
                 from include/linux/kernel.h:19,
                 from include/linux/cache.h:4,
                 from include/linux/time.h:7,
                 from include/linux/stat.h:60,
                 from include/linux/module.h:10,
                 from /home/nikita/Kernel_Study/linaro_first_module/my_mod.c:2:
/home/nikita/linux-sunxi/arch/x86/include/asm/arch_hweight.h: In function ‘__arch_hweight64’:
/home/nikita/linux-sunxi/arch/x86/include/asm/arch_hweight.h:53:42: error: expected ‘:’ or ‘)’ before ‘POPCNT64’
  asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
                                          ^
/home/nikita/linux-sunxi/arch/x86/include/asm/alternative.h:93:18: note: in definition of macro ‘ALTERNATIVE’
       "663:\n\t" newinstr "\n664:\n"  /* replacement     */ \
                  ^
In file included from include/linux/cache.h:5:0,
                 from include/linux/time.h:7,
                 from include/linux/stat.h:60,
                 from include/linux/module.h:10,
                 from /home/nikita/Kernel_Study/linaro_first_module/my_mod.c:2:
/home/nikita/linux-sunxi/arch/x86/include/asm/processor.h: At top level:
/home/nikita/linux-sunxi/arch/x86/include/asm/cache.h:7:25: error: ‘CONFIG_X86_L1_CACHE_SHIFT’ undeclared here (not in a function)
 #define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)

以及 Linux 源代码中的许多其他错误...

我是 Linux 内核和设备 driver 的新手,这就是为什么我觉得,我错过了一些东西。总结一下,我做了什么:

  1. 克隆了源代码库。

  2. 安装了必要的包。

  3. 配置了 kmake:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- sun7i_defconfig
    
  4. 构建树:

    make -j8 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules
    
  5. 创建树:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=output modules_install
    
  6. 尝试使用上面的 Makefile 制作模块。

此外,我知道没有必要构建整个内核树来制作模块。完成Linuxheaders就够了。我说得对吗?

为什么 make 会转到 /arch/x86/?我正在为 ARM 构建这个...

我错过了什么?

必须指定一个编译器和我为其构建模块的体系结构。只需使用以下参数启动 make:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-