【问题标题】:How to compile a kernel module for Raspberry pi?如何为树莓派编译内核模块?
【发布时间】:2013-12-08 15:56:44
【问题描述】:

我在为树莓派编译内核模块时遇到问题。我想用树莓派本身编译一个“hello world”内核模块。

我正在使用 raspbian wheezy 3.6.11+。

我尝试按照http://elinux.org/RPi_Kernel_Compilation 的指示进行操作。

这是我正在使用的 Makefile:

obj-m += hello-1.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

这里是hello-1.c的源代码:

/*  
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h>   /* Needed by all modules */
#include <linux/kernel.h>   /* Needed for KERN_INFO */

int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");

    /* 
     * A non 0 return means init_module failed; module can't be loaded. 
     */
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}

这是我尝试制作项目时得到的结果:

root@raspberrypi:/home/pi/hello-module# make
make -C /lib/modules/3.6.11+/build M=/home/pi/hello-module modules
make: *** /lib/modules/3.6.11+/build: No such file or directory.  Stop.
make: *** [all] Error 2

我尝试在 /lib/modules/3.6.11+ 创建构建目录

make -C /lib/modules/3.6.11+/build M=/home/pi/hello-module modules
make[1]: Entering directory `/lib/modules/3.6.11+/build'
make[1]: *** No rule to make target `modules'.  Stop.
make[1]: Leaving directory `/lib/modules/3.6.11+/build'
make: *** [all] Error 2

我安装了 GNU Make 3.81 和 gcc (Debian 4.6.3-14+rpi1) 4.6.3。我还使用

安装了 linux 源

sudo apt-get install linux-source

对我可以做些什么来编译它有什么想法吗?

【问题讨论】:

  • 在 Raspberry 上,modules 目录中没有“build”子目录。我可以在我的 RPI 上确认这一点。因此,问题是:使用模块构建所需的数据创建它的“正确”方法是什么?
  • 既然您已经得到了一些具体的答案,这里简要概述一下问题的原因。您正在使用 Raspberry Pi 基金会的内核(Raspbian 中的 raspberrypi-firmware 包),它不提供制作内核模块所需的头文件。您可以使用rpi-source 工具安装它们。或者改用Raspian的内核+头文件(在/etc/apt/sources.lst中的wheezy main contrib ...之后添加一个firmware条目,更新包,删除raspberrypi-firmware,安装raspberrypi-firmware-nokernel
  • question and the answer 中的精彩说明我编译成a script

标签: linux makefile raspberry-pi kernel-module raspbian


【解决方案1】:

这是我在 Raspbian 上构建 Hello World kernel module 的步骤。

  1. 执行sudo rpi-update

    详情请见https://github.com/Hexxeh/rpi-update rpi-update。您必须使用最新的固件和相关的内核才能执行下一步。

  2. 安装并运行rpi-source 以安装构建您正在运行的最新内核的源代码。这将在/lib/modules 中为您正在运行的内核创建正确的条目。注意:你不需要是 root 来运行它,但是脚本将使用sudo 执行某些任务,并且在脚本执行期间将请求 root 密码。

    安装说明rpi-source可以在https://github.com/notro/rpi-source/wiki找到

执行完这些步骤后,您应该能够make Hello World 内核模块。

johnma@raspberrypi ~/HelloWorld $ make
make -C /lib/modules/3.12.19+/build M=/home/johnma/HelloWorld modules
make[1]: Entering directory `/home/johnma/linux-c3db7205bcd8988cf7c185e50c8849542554b1f5'
  CC [M]  /home/johnma/HelloWorld/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/johnma/HelloWorld/hello.mod.o
  LD [M]  /home/johnma/HelloWorld/hello.ko
make[1]: Leaving directory `/home/johnma/linux-c3db7205bcd8988cf7c185e50c8849542554b1f5'

johnma@raspberrypi ~/HelloWorld $ sudo insmod hello.ko
johnma@raspberrypi ~/HelloWorld $ tail -1 /var/log/syslog
May 15 13:45:39 raspberrypi kernel: [59789.169461] Hello World :)

johnma@raspberrypi ~/HelloWorld $ sudo rmmod hello.ko
johnma@raspberrypi ~/HelloWorld $ tail -1 /var/log/syslog
May 15 13:46:10 raspberrypi kernel: [59819.503503] Goodbye World!

【讨论】:

  • 谢谢,这对我来说效果很好。我唯一遇到的问题是运行rpi-source。我遇到了一个 Python 错误,说它找不到 /proc/config.gz。运行 sudo modprobe configs 修复它。
【解决方案2】:

编译模块时,-C 参数应该指向构建内核的源代码树(不要清理它!)。如果你在 pi 上构建它,它可能在你的主目录下的目录中。

/lib/modules/&lt;version&gt; 下的build 目录是 Debian 主义,其中提供了源代码树的精简版本,并提供了足够的上下文来构建模块。来自 Raspberry Pi Foundation 内核的内核不附带 build 目录。

它们可能有点过时了,但 raspbian 提供了一个内核作为 Debian 风格的软件包,其中应该包括您可以用来构建内核模块的 build 目录。

sudo aptitude install linux-image-rpi-rpfv linux-headers-rpi-rpfv

【讨论】:

    【解决方案3】:

    您首先需要内核头文件(和相应的内核二进制文件)来构建您的模块。
    正如 Greg 所说,raspbian 发行版提供了这些软件包:

    sudo apt-get install linux-image-rpi-rpfv linux-headers-rpi-rpfv
    

    然后,告诉 raspbian 引导您新安装的内核(对我来说是 3.10-3-rpi)。
    将此附加到 /boot/config.txt 的末尾并重新启动您的 Pi:

    # Parameters to boot on raspbian kernel (linux-image-rpi-rpfv package)
    kernel=vmlinuz-3.10-3-rpi
    initramfs initrd.img-3.10-3-rpi followkernel
    

    然后,修改您的 Makefile 以指向新安装的内核头文件:

    KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
    
    obj-m := hello-1.o
    
    all:
        @$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) modules
    
    clean:      
        @$(MAKE) -C $(KERNEL_HEADERS) M=$(PWD) clean
    

    【讨论】:

    • Then, tell raspbian to boot your newly installed kernel (3.10-3-rpi for me). 你怎么知道版本?
    【解决方案4】:

    这很痛苦。我必须编译并安装内核模式驱动程序。经过长时间的搜索,我从here 获得了 pi 2 (3.18.7-v7+) 的标头。

    sudo apt-get install dkms build-essential
    wget http://www.niksula.hut.fi/~mhiienka/Rpi/linux-headers-rpi/linux-headers-3.18.7-v7%2b_3.18.7-v7%2b-2_armhf.deb
    sudo dpkg -i linux-headers-3.18.7-v7+_3.18.7-v7+-2_armhf.deb
    

    【讨论】:

    • 安装 linux 头文件时出现以下错误:“./arch/arm/include/asm/memory.h:24:25: fatal error: mach/memory.h: No such file或目录”。有什么想法吗?
    【解决方案5】:

    我遇到了同样的问题,只是通过sudo apt-get install raspberrypi-kernel-headers解决它

    【讨论】:

      【解决方案6】:

      我在我的 RPI 上使用完全相同的内核处理完全相同的样本。我设法在我的 RPI 上编译了模块,但是当我发出 insmod 时,我收到了一个错误。我按照 XUbuntu 虚拟机上的说明 here(使用我的 RPI 的内核版本 3.6.y),它运行良好。不知道为什么直接在 RPI 上编译不起作用,这将是另一天的问题。

      我必须更改 Makefile 以匹配新环境。

      obj-m += hello-1.o
      
      all:
              make ARCH=arm CROSS_COMPILE=${CCPREFIX} -C /home/cstick/rpi/linux-rpi-3.6.y M=$(PWD) modules
      clean:
              make -C /home/cstick/rpi/linux-rpi-3.6.y M=$(PWD) clean
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-01
        • 2017-05-29
        • 2017-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        相关资源
        最近更新 更多