0

I have build a Linux kernel for the beaglebone black using buildroot. Now I would like to develop a hello world Linux kernel module application:

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
    printk(KERN_ALERT "Hello, world\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_ALERT "Goodbye, cruel world\n");
}

module_init(hello_init);
module_exit(hello_exit);

The problem is I still keep missing some header files. After finally gathering them all, I get an error that the code is not compilable (many errors, I don't want to paste them all). What I was wondering is either I am really including the right files?

At the moment I have:

/home/lukasz/brl/Machine/beaglebone/build/linux-headers-a75d8e93056181d512f6c818e8627bd4554aaf92/include
/home/lukasz/brl/Machine/beaglebone/build/uboot-2018.01/arch/x86/include
/home/lukasz/brl/Machine/beaglebone/build/linux-headers-a75d8e93056181d512f6c818e8627bd4554aaf92/arch/arm/include/generated
/home/lukasz/brl/Machine/beaglebone/build/linux-headers-a75d8e93056181d512f6c818e8627bd4554aaf92/arch/arm/include
/home/lukasz/brl/Machine/beaglebone/build/linux-a75d8e93056181d512f6c818e8627bd4554aaf92/include

Its a bit odd to me that the C include files and asm files are so scattered around within the directory. Are there some mistakes in my understanding of the topic here?

My Linux version:

# uname -a
Linux buildroot 4.9.59 #1 SMP Fri Oct 5 11:55:54 CEST 2018 armv7l GNU/Linux
halfer
  • 19,824
  • 17
  • 99
  • 186
Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74
  • which toolchain are you using to compile the module? are you compiling the code directly on the beagle or the host device? if you wish to compile the module on the beagle than you need to make sure you build buildroot with gcc and dev directories. if you wish to compile on the host make sure that you build the buildroot toolchain and use it to compile the module usually when such an error occurs it points to a wrong toolchain – Omer Dagan Dec 18 '18 at 13:16
  • Thanks for ansfer. At first I wanted to build on the target, but wasnt able to make the gcc "appear" in my build. So i xcompile using the toolchain created by buildroot – Łukasz Przeniosło Dec 18 '18 at 13:27
  • Btw, a regular hello world c application compiles on host and runs on target correctly – Łukasz Przeniosło Dec 18 '18 at 13:31

1 Answers1

3

To compile a kernel module, you need the real kernel sources, not just the kernel header files. You have to build from the kernel source directory with M= pointing to the source of your modules. And together with your module source, you of course also need a working Makefile. These steps are explained in any of the dozens of how-to-write-a-kernel-module guides, e.g. this one.

For cross-compilation, you also need to pass the appropriate arguments so that the kernel knows for which architecture to build and which cross-compiler to use. At the very least, this means you have to give the ARCH= and CROSS_COMPILE= options when building. Sometimes you need additional options (e.g. to point to the appropriate depmod tool).

To simplify this, Buildroot offers kernel module infrastructure. In the simplest case, you can just create a Config.in file containing

config BR2_PACKAGE_HELLOMOD
        bool "hellomod"
        depends on BR2_LINUX_KERNEL

and a hellomod.mk file containing

HELLOMOD_SITE = /path/to/hellomod/source

$(eval $(kernel-module))
$(eval $(generic-package))

You also have to source the Config.in from package/Config.in in the Buildroot tree. Or better yet, use an external tree so you don't have to modify Buildroot itself.

Arnout
  • 2,927
  • 16
  • 24
  • I am not sure if kernel sources are a prerequisite, I have got stuff to work with out the sources and just the appropriate headers. – yashC Dec 19 '18 at 05:44
  • Well, you indeed don't need the full sources. But the uapi headers are definitely not enough. You need at least `include/`, `arch/xxx/asm`, top-level `Makefile`, part of `scripts/`, ... – Arnout Dec 19 '18 at 09:08
  • Hello, thank you for answer. At this point I dont want to compile my module into the kernel at kernel build time, but just compile it separately and try to load it in runtime. The things you mention seem to be higher level stuff that I would need to settle, but once everything is working. I am not certain either my headers dirs are correct. Is there any reference how to crosscompile a module using the tools provided by buildroot (and which files to include)? – Łukasz Przeniosło Dec 19 '18 at 11:56
  • On my host device I was able to build a test module using provided tutorial: http://devarea.com/linux-kernel-development-and-writing-a-simple-kernel-module/ . I think my problem with xcompiling is that I dont have the build directory in the lib/modules dir. Is there any specific way to build those? – Łukasz Przeniosło Dec 19 '18 at 12:33
  • As written in the answer: once the module compiles correctly natively following e.g. the devarea.com guide, you can include it in Buildroot as a cross-compiled module by using the kernel-module infrastructure. Documentation of that is referenced in the answer, and summarized as well. What more do you need? – Arnout Dec 19 '18 at 15:10
  • But thats the end way of providing modules- compiling them statically. I am trying to cross compile the module and add it using insmod during runtime. Also, I cannot compile it natively, since the host is x86 and the target is Arm. – Łukasz Przeniosło Dec 19 '18 at 19:31
  • It is not possible to compile external modules (that are not part of the Linux tree) statically into the kernel. The instructions are for compiling them as modules, which you load with modprobe or insmod. – Arnout Dec 22 '18 at 20:10