cross compile raspberry pi kernel module - linux

So I have been trying to learn more about developing linux drivers with Linux Device Drivers version 3. Using a spare Rasberry Pi (b) I had kicking around.
I used http://www.raspberrypi.org/documentation/linux/kernel/building.md to build the the kernel in my ~/kernelWork/kernel folder. I have also compiled the kernel and have it running on my raspberry pi to avoid compatibility issues.
The issue I have is I know I need to cross compile the module source to work with the ARM architecture, but I'm not sure where to point the -C flag of the command
make -C ~/kernel-2.6 M=`pwd` modules
command to make my module with. I took a look into my arch folder of my kernel, and looked in the ARM directory included there, but from there I'm not sure where to go.
So in short, after I have built my kernel where do I point the -C flag to cross compile my module.

I had to set my Makefile to cross compile with the settings
all:
make ARCH=arm CROSS_COMPILE=${CCPREFIX} -C /home/jacob/kernelWork/kernel M=$(PWD) modules
clean:
make -C /home/jacob/kernelWork/kernel M=$(PWD) clean
As well as setting my environment variables KERNEL_SRC and CCPREFIX to my kernel source, and the raspberry compiler I pulled from the git source. This page has the full details
http://bchavez.bitarmory.com/archive/2013/01/16/compiling-kernel-modules-for-raspberry-pi.aspx

Related

error message "-mrecord-mcount" when cross-compile out of kernel module

I'm trying to build an out-of-kernel module and cross-compile it.
So, I'm working on VM, Ubuntu, and I upgraded the running kernel to 5.15.6.
Now, I'm trying to cross-compile my very simple "Hello world" module.
Its Makefile is simply:
obj-m += yanivModule.o
and the building command is:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C /lib/modules/5.15.6/build/ M=$PWD modules
and I keep running into this error message:
arm-linux-gnueabihf-gcc: error: unrecognized command line option ‘-mrecord-mcount’; did you mean ‘-frecord-marker=4’?
Does anyone know what "-mrecord-mcount" means how to fix it?
I tried to disable the "CONFIG_FTRACE_MCOUNT_RECORD" and "CONFIG_HAVE_FTRACE_MCOUNT_RECORD" configuration flag as I read somewhere it might be related (and by name it actually might be), but it didn't solve the error.
I'm kind of lost here since in the tutorial video I'm following, it's done with no issues at all.
Update:
I managed to fix the issue, but I'm not sure why it got fixed that way, and why the way I described before didn't work.
I downloaded the kernel of beaglebone board from github:
https://github.com/beagleboard/linux/tree/5.10
and then built it using:
make ARCH=arm bb.org_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- C /home/.../beaglebone-linux-5.10/ M=$PWD modules
and only then, building the module, when -C is the new downloaded kernel tree - has succeeded with no issues.
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C /home/.../beaglebone-linux-5.10/ M=$PWD modules
So now, I'm left with 2 questions:
What, step fixed the issue and what was missing from the previous way I tried? was it using the bb.org_defconfig configuration file?
Why this bb.org_defconfig configuration file is missing from the latest Linux kernel source tree?

Intel Galileo adding kernel header files to the cross compile toolchain

im on BSP v1.1
yocto is 1.6
I'm trying to set up the cross compile toolchain to compile character driver code
but the output i get is
[mark#localhost ~]$ ${CC} first.c -o first
first.c:1:24: fatal error: linux/init.h: No such file or directory
.#include
^ compilation terminated.
I think the issue is that
the header is not in the toolchain
/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/include/linux/~
there is no at this location
I think something has to be added as IMAGE_INSTALL or IMAGE_FEATURE but i dont know what
am I on the right track ?
does anyone know what i have to add ?
or am i completely off tracks altogether?
Well, first and foremost, you can never build a kernel module by just running ${CC} on it. You should always use a Makefile, which redirects most of its work to the kernel source Makefil.
Create a Makefile for you module, consisting of something similar to:
obj-m += hello-1.o
all:
make -C $(KERNEL_SRC M=$(PWD) modules
clean:
make -C $(KERNEL_SRC) M=$(PWD) clean
Example taken from The Linux Kernel Module Programming Guide (Note that the actual commands needs to have a tab character for indentation).
Then you'll have to define KERNEL_SRC to be /opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel/, either in the Makefile, or from your make call. (Using a variable like KERNEL_SRC will ensure that your module recipe automatically picks the right location when building using bitbake).
To manually build your kernel module:
Source the environment-* file for your SDK.
Go to you modules directory.
KERNEL_SRC=/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel LDFLAGS="" make
However, this will fail, as fixdep can't be found. We'll fix this manually.
cd /opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel
make silentoldconfig scripts
Go back to your modules directory.
KERNEL_SRC=/opt/iot-devkit/1.6.1/sysroots/i586-poky-linux/usr/src/kernel LDFLAGS="" make
This should now produce hello.ko which you should be able to insmod on the Galileo board.

How to compile a modified kernel which is different from the one installed on our computer?

I am currently working on linux kernel 3.11.0-12. But I am adding a system call by modifying the source code I downloaded from kernel.org of linux-2.6.26. I want to compile the modified 2.6.26 kernel to test my new system call. How should i do it?
1)If you want to build kernel for same architecture on which you are working then..
go into your linux source folder and fire below commands....
To Clean:
make distclean
To write config:
make defconfig
To build Kernel:
make uImage
or make vmlinux which image you want to build
2)for arm architecture...
To Clean:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
To write config:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig
To build Kernel:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage
3) using second step you can build linux kernel for any platform with any toolchain
just use ARCH= CROSS_COMPILE= macro as per requirement......
I assume you use a vanilla kernel and that you are working on a module. Vanilla or not, you need the configuration file for the target kernel.
Just download the source, copy the kernel configuration file to <kernel_source>/.config and build the kernel once, since you need the configuration- and header-files for an out of kernel source build. Use make modules_prepare.
Then run make -C <full_path_to_kernel_source> M=$PWD to build the module.
Take a look at here for more detailed information.

Cross compile FTDI VCP Driver for embedded linux arm

I'm trying to cross compile the FTDI VCP Driver for my embedded arch linux arm machine. I downloaded the source files from http://www.ftdichip.com/Drivers/VCP.htm onto my host machine which is running kernel:
2.6.32-54-generic-pae
When running the Makefile, I get errors related to kernel headers, ie: asm/thread_info.h file not found. I realize that this means that my asm symlink is broken, so I tried linking it to
linux-headers-2.6.32-54/include/asm-generic
but the contents of that directory does not include thread_info.h either, which I'm trying to find.
Has anyone cross compiled the FTDI VCP Driver for embedded arch linux arm using Ubuntu as their host and can point me in the right direction? I'm new to building kernel modules and cross compiling and any help would be appreciated.
If anyone requires more information I'd be more than happy to add it.
make ARCH=arm menuconfig
Make and install modules: make modules and make modules_install
Don't forget: insmod usbserial.ko and insmod ftdi_sio.ko if you need to, and depmod -a to have them load after a power cycle.
Don't forget to include your cross compiling chains.
Basically u need cross-compile kernel in host x86 machine.
First check the source code is already configured and built if so.
make ARCH=arm menuconfig
window ll appear and enable ftdi in driver .
if source code is clean.
then u need to copy /proc/config.gz file from target machine to host and untar it.
copy to source top folder like `cp config .config'
make ARCH=arm menuconfig
and enable your driver
After this make ARCH=arm CROSS_COMPILE=<your tool chain> zImage
e.g make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- zImage
make ARCH=arm CROSS_COMPILE=<your tool chain> modules
e.g make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules
The FTDI "VCP" driver has been a part of the linux kernel for a good while now. You don't need to download anything, except for the kernel itself. As long as you can cross-compile your kernel, you're all set.

Driver/module cross compilation

I am trying to cross compile a driver for an arm based board. In the make file the search path for include files is that of the host machine's kernel i.e it points to the linux headers that come with ubuntu.
I also have the kernel source tree of target board present on the host system(i7/ubuntu).
My Question is that which include path is needed for cross compilation (native system's linux headers path or the path to the kernel source tree of board ?
Does same thing applies to all modules including drivers?
Here is a Makefile for an out of tree driver. The architecture, toolchain and kernel dir specified :
ifneq ($(KERNELRELEASE),)
# We were called by kbuild
obj-m += fpgacam.o
else # We were called from command line
KDIR := path/to/your/target/kernel
PWD := $(shell pwd)
CROSS=arm-none-linux-gnueabi-
default:
#echo ' Building Cam drivers for 2.6 kernel.'
#echo ' PLEASE IGNORE THE "Overriding SUBDIRS" WARNING'
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) ARCH=arm CROSS_COMPILE=$(CROSS) modules
install:
./do_install.sh *.ko
endif # End kbuild check
######################### Version independent targets ##########################
clean:
rm -f -r *.o *.ko .*cmd .tmp* core *.i
When make is called from the module directory, the command line path is taken, and make is redirected to the kernel directory build system using make -C. The kernel build system then the different variable passed to it to go back into the module directory with everything setup (include path, toolchain etc ..) to compile a module. This second time through the Makefile, the kbuild path is taken, and the module is built as if it was in-tree.
Compiling with your build-system's headers is spectacularly bad news, and may subtle binary incompatibilities that manifest themselves as seemingly bizarre crashes on the target.
As you've already discovered, the kernel is already hardened against this and will refuse to load modules built against the wrong headers. You'll need to build using the same source tree as the existing kernel - including any patches. You might as well at this point rebuild the entire kernel.
The kernel tree is self-contained, so simply cross-compiling it in place will work. If you're adding a driver it's probably easiest to compile it in-tree.
If you want to build any user-space components, you have two solutions:
Pass the --sysroot=<dir> option to gcc, where <dir> is the system root of your target system
Build gcc and binutils to use as their default sysroot
The latter approach is the one that Angstrom uses, and it save a lot of butt-hurt.
You might want to try using crosstool-ng
It takes care of the majority of the work. You only need to bother about the configuration settings you want to enable for kernel compilation.
Here another reference: link

Resources