Cross compiling a kernel module - makefile

I'm trying to cross compile a helloworld kernel (2.6.x) module for ARM architecture on my intel x86 host.
The codesourcery tool chain for ARM is located at: /home/ravi/workspace/hawk/arm-2009q3
The kernel source is located at :/home/ravi/workspace/hawk/linux-omapl1
My Makefile:
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi
obj-m := Hello.o
KDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
When i run make, the .ko produced is that of my host machine which means 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.

Putting ARCH and CROSS_COMPILE in the Makefile doesn't work. You need to put them on the command line:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-

Replace
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi
by
export ARCH:=arm
export CROSS_COMPILE:=arm-none-linux-gnueabi-
this will also work if you do not want to give these parameter command line each time.

Sidenote: SUBDIRS= is deprecated in favor of M=.

could you try, you forgot to add ARCH and CROSS_COMPILE into the default and clean
ARCH=arm
COMPILER=arm-none-linux-gnueabi
obj-m := Hello.o
KERNELDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) clean

adding export at the end of your Makefile variable declarations will make them available to subshells. and add the dash to the CROSS_COMPILE prefix as JayM pointed out, and M instead of SUBDIRS as user502515 answered.
and it's generally a good idea to use := rather than = in a Makefile, so the variable only gets interpolated once. really doesn't matter in this particular case though.
ARCH := arm
CROSS_COMPILE := arm-none-linux-gnueabi-
obj-m := Hello.o
KDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
export
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean

MODULES := hola_kern.o
#guest architecture
ARCH := arm
CROSS_COMPILE := arm-linux-gnueabi-
obj-m := $(MODULES)
#path of the arm compiled kernel
ROOTDIR := /home/aldo/c/proyectos/prefixa/work/kernels/linux-omap-5f0a6e2
MAKEARCH := $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
all: modules
modules:
$(MAKEARCH) -C $(ROOTDIR) M=${shell pwd} modules
clean:
$(MAKEARCH) -C $(ROOTDIR) M=${shell pwd} clean

Related

Raspberry pi out of tree build using Rasbian stretch [duplicate]

I'm trying to cross compile a helloworld kernel (2.6.x) module for ARM architecture on my intel x86 host.
The codesourcery tool chain for ARM is located at: /home/ravi/workspace/hawk/arm-2009q3
The kernel source is located at :/home/ravi/workspace/hawk/linux-omapl1
My Makefile:
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi
obj-m := Hello.o
KDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
When i run make, the .ko produced is that of my host machine which means 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.
Putting ARCH and CROSS_COMPILE in the Makefile doesn't work. You need to put them on the command line:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
Replace
ARCH=arm
CROSS_COMPILE=arm-none-linux-gnueabi
by
export ARCH:=arm
export CROSS_COMPILE:=arm-none-linux-gnueabi-
this will also work if you do not want to give these parameter command line each time.
Sidenote: SUBDIRS= is deprecated in favor of M=.
could you try, you forgot to add ARCH and CROSS_COMPILE into the default and clean
ARCH=arm
COMPILER=arm-none-linux-gnueabi
obj-m := Hello.o
KERNELDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH) clean
adding export at the end of your Makefile variable declarations will make them available to subshells. and add the dash to the CROSS_COMPILE prefix as JayM pointed out, and M instead of SUBDIRS as user502515 answered.
and it's generally a good idea to use := rather than = in a Makefile, so the variable only gets interpolated once. really doesn't matter in this particular case though.
ARCH := arm
CROSS_COMPILE := arm-none-linux-gnueabi-
obj-m := Hello.o
KDIR := /home/ravi/workspace/hawk/linux-omapl1
PWD := $(shell pwd)
export
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
MODULES := hola_kern.o
#guest architecture
ARCH := arm
CROSS_COMPILE := arm-linux-gnueabi-
obj-m := $(MODULES)
#path of the arm compiled kernel
ROOTDIR := /home/aldo/c/proyectos/prefixa/work/kernels/linux-omap-5f0a6e2
MAKEARCH := $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
all: modules
modules:
$(MAKEARCH) -C $(ROOTDIR) M=${shell pwd} modules
clean:
$(MAKEARCH) -C $(ROOTDIR) M=${shell pwd} clean

For kernel module makefile: Use another name for the makefile and using command line parameter

I have Kernel module sources (for arm) and I would like to compile two different drivers from the same source.
The kernel in compiled with 2 source files and with cross compile.
MODULE_MAME = modulename
SRCS = drv/source.c lib/libsrc.c
OBJS = $(SRCS:.c=.o)
obj-m += $(MODULE_MAME).o
$(MODULE_MAME)-y = $(OBJS)
KDIR := /mykermelsources/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) clean
In one command, I would like to compile 2 modules.
Two choices:
Keeping 3 different Makefiles, one main that will call both other makefiles. One problem with this, I cannot make it working. make -f makefilediff or make --makefile=makefilediff give me an error.
Log:
make -C /mykermelsources/ ARCH=arm M=/home/mychardriver/ modules
make[1]: Entering directory '/mykermelsources'
scripts/Makefile.build:44: /home/mychardriver/Makefile: No such file or directory
make[2]: *** No rule to make target '/home/mychardriver//Makefile'. Stop.
make[1]: *** [_module_/home/mychardriver/] Error 2
make[1]: Leaving directory '/mykermelsources'
make: *** [all] Error 2
Transmitting command line parameter but it doesn't work. make SIDE=1
Seems the SIDE parameter/variable is never transmitted.
ifeq ($(SIDE),1)
MODULE_MAME = modulename_11
else
MODULE_MAME = modulename_22
endif
SRCS = drv/source.c lib/libsrc.c
OBJS = $(SRCS:.c=.o)a
obj-m += $(MODULE_MAME).o
$(MODULE_MAME)-y = $(OBJS)
KDIR := /mykermelsources/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) SIDE=$(SIDE) modules
clean:
$(MAKE) -C $(KDIR) ARCH=arm M=$(PWD) clean
How can I build 2 kernel modules from same multiple source files ?
Just faced this issue, and this is what I did:
For each moduleX you want to build, write a Kbuild_moduleX with the targets. Example:
obj-$(MODULE) += MODULE.o
MODULE-y := source.o
Then, in your Makefile_moduleX, do:
all:
cp Kbuild_moduleX Kbuild
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
rm Kbuild
This works because the kernel scripts will give Kbuild priority over reading Makefile.
To compile, do make -f Makefile_moduleX
Is it pretty? No. Does it work? Yes.

Making kernel object with make ARCH=i386

I have a file named dice_driver.c that I would like to make a .ko file out of it. Here's my Makefile:
obj-m := dice_driver.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
However, when I entered make ARCH=i386 into my VM on VirtualBox, as per my instructor's guidance, it says
make: Nothing to be done for 'default'.
Could anyone help me with this issue?

Proper makefile setup for external kernel modules

I'm writing a character driver to sit on top of a modified version of ahci in the source tree. I basically have something that looks like this:
topdir
|
|- Makfile
|
|- mod_ahci
| | - Makefile, codefiles
|
|- char_interface
| | - Makefile, codefiles
now, char_interface requires symbols from mod_ahci. I have the appropriate EXPORT_SYMBOL() macro use for the symbols I need to export. However, I'm having trouble getting the makefiles right to pick up the header file in mod_ahci from char_interface. My toplevel Makefile
ifneq ($(KERNELRELEASE),)
obj-y := mod_ahci/ char_interface/
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
endif
The makefile for char_interface (because the other builds just fine)
ifneq ($(KERNELRELEASE),)
ccflags-y += -I../mod_ahci
obj-m := char_interface.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
default:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules_install
endif
clean:
-sudo rmmod ahcip
-rm -f *.ko* *.mod.* *.o modules.order Modules.symvers
I have referenced various text files in the kernel documentation. For example, I'm referring to .../Documentation/kbuild/makefiles.txt right now as well as .../Documentation/kbuild/modules.txt. Whenever I build, I'm getting /home/captaink/devel/kmodtests/char_interface/char_interface.c:2:22: error: mod_ahci.h: No such file or directory. There is a file named mod_ahci.h in the directory ../mod_ahci. What am I getting wrong with my use of ccflags-y in the makefile for the char driver?
Thanks
After some digging, I found the answer to the problem. I was misunderstanding what was happening with the makefile's that I was viewing from LDD3 and the kernel documentation (which is, apparently, exactly where O'Reilly took their examples). The build system actually changes directories into /usr/src/kernels/$(uname -r)/build (or similar) because this is why my header file wasn't being found by the compiler.
I'm not saying this is an elegant way of doing this, but here's how I fixed it. The makefile in the top directory now looks like:
ifneq ($(KERNELRELEASE),)
obj-y := mod_ahci/ char_interface/
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) TOP_DIR=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
endif
And the makefile in the subdirectory containing the char driver interface looks like:
ifneq ($(KERNELRELEASE),)
ccflags-y += -I$(TOP_DIR)/mod_ahci
obj-m := char_interface.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
default:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules_install
endif
clean:
-sudo rmmod ahcip
-rm -f *.ko* *.mod.* *.o modules.order Modules.symvers
As you can tell, the makefiles have been copied extensively. The subdirectories probably don't need the "shared" makefile stuff in them because that's taken care of by the higher level makefile. Nevertheless, the modules now build and the character driver I have knows of the exported symbols I made in my modified ahci driver.
I hope this may help someone who's a neophyte, like myself, to the Linux kernel build world and Linux kernel drivers.

Is it possible to set CFLAGS to a linux kernel module Makefile?

Eg: a common device module's Makefile
obj-m:=jc.o
default:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules clean
I consider if I can set CFLAGS to the file. When I change default section to
$(MAKE) -O2 -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
But it didn't work.
Any help? Thanks a lot.
-O2 would be an option to make (or $(MAKE), as you're using it) in what you tried. Obviously, the compiler (probably gcc) needs this flag, not make.
Kbuild understands a make variable named CFLAGS_modulename.o to add specific C flags when compiling this unit. In your case, your module object will be jc.o, so you can specify:
CFLAGS_jc.o := -O2
and it should work. Add V=1 to your $(MAKE) lines to get a verbose output and you should see -O2 when jc.c is being compiled.
You can find more about compiling modules in the official documentation.
You can also use
ccflags-y := -O2
This will be applied to all of the source files compiled for your module with the Makefile. This is indirectly documented in the link provided by eepp in Section 4.2

Resources