0
votes

I'm trying to cross compile a module for ARM. I am using a Sabrelite as a board with 3.0.35 kernel version. I'm using open-embedded to generate the kernel image.

I have all of the toolchain needed for the cross compilation as cited below:

echo $CC :

arm-oe-linux-gnueabi-gcc -march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 --sysroot=/usr/local/oecore-x86_64/sysroots/cortexa9hf-vfp-neon-oe-linux-gnueabi

echo $CROSS_COMPILE: arm-oe-linux-gnueabi-

echo ARCH: arm

(This is just some part of my toolchain.)

This is part of my makefile:

KSRC = kaodv-mod.c kaodv-debug.c kaodv-netlink.c kaodv-queue.c kaodv-ipenc.c kaodv-expl.c

KERNEL_DIR=/home/user/script_emulation/AODV/kernel

KERNEL_INC=$(KERNEL_DIR)/include THIS_DIR=$(shell pwd)

obj-m += kaodv.o kaodv-objs := kaodv-mod.o kaodv-debug.o kaodv-netlink.o kaodv-queue.o kaodv-ipenc.o kaodv-expl.o

default:
$(MAKE) -C $(KERNEL_DIR) SUBDIRS=$(THIS_DIR) modules

when I launch it with make command, I get a module (.ko) but the weird thing is that the module generated is compiled with my host machine toolchain which means that the makefile is invoking the native compiler instead of the cross compiler. What am I doing wrong? The cross compiler's binaries are in my path.

This is part of the output I get on terminal:

CC /home/user/script_emulation/AODV/aodv-uu/lnx/kaodv.mod.o

LD [M] /home/user/script_emulation/AODV/aodv-uu/lnx/kaodv.ko

We can see there that native CC and LD is used instead of the the cross compiler tools

Can anyone suggest a solution ?

thanks

Update:

$ readelf -h kaodv.ko

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          13480 (bytes into file)
  Flags:                             0x5000000, Version5 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         33
  Section header string table index: 30
2
"CC", "LD", etc. in the KBuild output are just pretty-printing, they're not necessarily the actual commands. Use make V=1 ... to see what it's actually doing. Can you confirm the .ko file really is the wrong format, with e.g. readelf?Notlikethat
Thanks, this is the output I get: echo " ERROR: Kernel configuration is invalid."; \ echo " include/generated/autoconf.h or include/config/auto.conf are missing.";\ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ It means that I have to reconfigure my kernel (which I have already done !!! )scof007
@Notlikethat yes, the .ko file is the wrong format because, I have tested it on the target, and It simply does not work as it should bescof007
Define "does not work as it should be" ;) Could you add the output of readelf -h kaodv.ko, and any error that insmod on the target system returns, to the question?Notlikethat
Well, It is an Ad hoc network module. After the insmod command, I get no output. It seems to me that the module incorporate into the kernel perfeclty. However, as soon as I've done that, the ssh does not respond anymore, and I cannot ping my board as well. So, I use a serial debug cable. It seems that the native IP stack of the board is killed by the module. The module should runs as a user-space daemon, maintaining the kernel routing table. When I remove the module, I get an output like this: write failed broken pipe. After that, the ssh restart working again and I am able to ping it.scof007

2 Answers

1
votes

For a quick fix, change your Makefile as below.

KERNEL_DIR=/home/user/script_emulation/AODV/kernel

KERNEL_INC=$(KERNEL_DIR)/include THIS_DIR=$(shell pwd)

obj-m += kaodv.o kaodv-objs := kaodv-mod.o kaodv-debug.o kaodv-netlink.o kaodv-queue.o kaodv-ipenc.o kaodv-expl.o

default:
$(MAKE) ARCH=arm CROSS_COMPILE=arm-oe-linux-gnueabi- -C $(KERNEL_DIR) SUBDIRS=$(THIS_DIR) modules

Also make sure you set the cross compiler toolchain path before running make using

export PATH = $PATH:PathToToolchain.

Also check whether the kernel you have compiled earlier is also compiled for ARM Architecture.

0
votes

As the header shows, it's actually cross-compiled perfectly fine. If it were built with the native toolchain, the "Machine" field would contain x86_64 (or whatever your host system is), and attempting to insmod it on the target would have given an error.

The default KBuild output just uses "CC", "LD", as convenient indicators - these are only representative of which step is being performed, not the specific command-lines being invoked (see the definitions of quiet_cmd_* in Makefile.build).

The fact that the code doesn't actually work properly is a whole different problem. Given that you're porting this module from an older kernel, chances are it may need updating to account for changes in some internal interface it uses.