Compiling Linux kernel - hello world - linux

I am trying to compile the Linux kernel:
http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html
I have a simple hello world program hello-1.cpp
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
But I am trying to build it using the 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
I get a couple of errors.
make -C /home/pacman/linux-2.6.34.11/2.6.35.6-45.fc14.i686/build M=/home/pacman/p1 modules
make: *** /home/pacman/linux-2.6.34.11/2.6.35.6-45.fc14.i686/build: No such file or directory. Stop.
make: * [all] Error 2
Am I forgetting to define something?

Rename hello-1.cpp to hello-1.c (modules must be written in C) and add the lines:
module_init(init_module);
module_exit(cleanup_module);

Related

No rule to make target 'lib/sha256.c' error when compiling kernel module

I am trying to compile kernel module in Fedora 28. My current kernel is 4.17.3-200.fc28.x86_64. My hello.c is
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
static int __init hello_2_init(void)
{
printk(KERN_INFO "Hello, world 2\n");
return 0;
}
static void __exit hello_2_exit(void)
{
printk(KERN_INFO "Goodbye, world 2\n");
}
module_init(hello_2_init);
module_exit(hello_2_exit);
and my Makefile is
obj−m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
I get this error when I am trying to compile. Initially I thought that the error is due to ssl library. So I installed openssl-devel for fedora. But I still get the same error.
make -C /lib/modules/4.17.3-200.fc28.x86_64/build M= modules
make[1]: Entering directory '/usr/src/kernels/4.17.3-200.fc28.x86_64'
CHK include/config/kernel.release
CHK include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
make[2]: *** No rule to make target 'lib/sha256.c', needed by 'arch/x86/purgatory/sha256.o'. Stop.
make[1]: *** [arch/x86/Makefile:263: archprepare] Error 2
make[1]: Leaving directory '/usr/src/kernels/4.17.3-200.fc28.x86_64'
make: *** [Makefile:4: all] Error 2
How can I solve this error?
obj-m := FILENAME.o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build <br/>
PWD := $(shell pwd)
all:
default
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
Try this Makefile or write in Console:
make -C /lib/modules/`uname -r`/build M=`pwd` modules obj-m=FILENAME.o
Replace FILENAME with the name of your file!

Issue on Creating module?

I am trying to learn module programming for that i used a sample program in c as
#include<linux/module.h>
#include<linux/kernel.h>
int init_module(void)
{
printk(KERN_INFO "Hello man .\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Good bye see you soon\n");
}
for compiling this c code i wrote a make file as below
obj-m + = Hello_module.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
Then i am compiling this one using make command i get following errors
joe#joe-O-E-M:~/Module_pgm$ make
make -C /lib/modules/3.19.0-25-generic/build M=/home/joe/Module_pgmmodules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-25-generic'
./scripts/Makefile.build:44: /home/joe/Module_pgmmodules/Makefile: No such file or directory
make[2]: *** No rule to make target `/home/joe/Module_pgmmodules/Makefile'. Stop.
make[1]: *** [_module_/home/joe/Module_pgmmodules] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-25-generic'
make: *** [all] Error 2
How can i resolve this problem..
You are missing a space between $(PWD) and modules. Try:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The "No such file or directory" error message shows the path it's trying to find.

make: no rule to make target

i have written a simple linux module & its make file
this is my module
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void) {
printk("<1> Hello world!\n");
return 0;
}
static void hello_exit(void) {
printk("<1> Bye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
this is my make file
obj-m :=Hello.o
KDIR = /usr/src/linux-headers-3.5.0-17
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
when i execute make -f MakeFile
it gives following o/p
make -C /usr/src/linux-headers-3.5.0-17 SUBDIRS=/home/linux/Desktop modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17'
WARNING: Symbol version dump /usr/src/linux-headers-3.5.0-17/Module.symvers
is missing; modules will have no dependencies and modversions.
scripts/Makefile.build:44: /home/linux/Desktop/Makefile: No such file or directory
make[2]: *** No rule to make target `/home/linux/Desktop/Makefile'. Stop.
make[1]: *** [_module_/home/linux/Desktop] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17'
make: *** [all] Error 2
can any one tell me how to get rid of these errors.
Thanks in advance
Make the below change in your Makefile
First check which kernel is running by typing uname -a
Then go to cd /usr/src/
then check your linux source-code name
for e.g
uname -a Linux vinay-VirtualBox 3.2.0-50-generic-pae #76-Ubuntu SMP Tue Jul 9 19:24:55 UTC 2013 i686 i686 i386 GNU/Linux
here its source-code name is linux-headers-3.2.0-50-generic-pae
same thing in your case
e.g
linux-headers-3.2.0-23 linux-headers-3.2.0-23-generic-pae
so use linux-headers-3.2.0-23-generic-pae instead of
linux-headers-3.2.0-23 i.e replace same in your makefile
i.e KDIR=/usr/src/linux-headers-3.5.0-17-generic-pae
or in order to avoid above problem use
KDIR == /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
KDIR == /lib/modules/$(shell uname -r)/build
$(MAKE) -C $(KDIR) M=$(PWD) modules
obj-m += xyz.o
KDIR:=/usr/src/linux-headers-3.5.0-46-generic
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
Are you sure /usr/src/ contains linux-headers-3.5.0-46-generic files?
if this is not the case, download:
sudo apt-get install linux-headers-3.5.0-46
sudo apt-get install linux-headers-3.5.0-46-generic

Linux device driver module compilation using gcc

I have a basic linux device driver module :
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
printk(KERN_ALERT "Hello, world \n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "Goodbye, world \n");
}
module_init(hello_init);
module_exit(hello_exit);
I am able to compile this module in traditional way which is by using a simple Makefile which uses obj-m , but I want to compile this using command line gcc. This is because I can use gcc -save-temps flag to see the intermediate generated files(this can be particularly helpful to understand as Linux kernel uses lot of preprocessor stuff).
So is there a way to compile using command line gcc ??
EDIT Attaching the Makefile I have used
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
EXTRA_CFLAGS+= -save-temps
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
obj-m := hello.o
endif
Could you try to add "EXTRA_CFLAGS" in your module's Makefile?
such as EXTRA_CFLAGS += -save-temps
Hope it help you!
I don't know how to to that directly in Makefile, but you can generate your .i file by file. From the root directory of the Linux kernel source:
make drivers/media/pci/sta2x11/sta2x11_vip.i
This will generate the .i file. To generate your module source file (which is outside the kernel tree) just use the absolute path to it:
make /path/to/hello.i
It should work

module compiling : asm/linkage.h file not found

I am trying to compile an example of "hello world" Kernel Module,
problems found on ubuntu 11.04, kernel 3.2.6, gcc 4.5.2 and fedora 16, kernel 3.2.7, gcc 4.6.7.
code:
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
static int __init hello_init (void)
{
printk("Hello module init\n");
return 0;
}
static void __exit hello_exit (void)
{
printk("Hello module exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
compiled with:
gcc -D__KERNEL__ -I /usr/src/linux/include/ -DMODULE -Wall -O2 -c hello.c -o hello.o
error:
In file included from /usr/src/linux/include/linux/kernel.h:13:0,
from /usr/src/linux/include/linux/cache.h:4,
from /usr/src/linux/include/linux/time.h:7,
from /usr/src/linux/include/linux/stat.h:60,
from /usr/src/linux/include/linux/module.h:10,
from hello.c:1: /usr/src/linux/include/linux/linkage.h:5:25: fatal error:
asm/linkage.h: file not found
then I found in /usr/src/linux/include/ there is no folder named 'asm' but 'asm-generic';
so I made a soft link 'asm' to 'asm-generic', and compiled agail:
this time the error was:
In file included from /usr/src/linux/include/linux/preempt.h:9:0,
from /usr/src/linux/include/linux/spinlock.h:50,
from /usr/src/linux/include/linux/seqlock.h:29,
from /usr/src/linux/include/linux/time.h:8,
from /usr/src/linux/include/linux/stat.h:60,
from /usr/src/linux/include/linux/module.h:10,
from hello.c:1: /usr/src/linux/include/linux/thread_info.h:53:29: fatal error:
asm/thread_info.h: file not found
So I realized I was wrong, but why ? T_T
obj-m += hello.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
is a proper way to build modules see kbuild documentation
And to see difference beetween your compiler invocation you could
cat /lib/modules/$(shell uname -r)/build/Makefile
And analyze an output
obj-m += hello.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
Here hello.c is your kernel source file. just use make to build your hello.ko module.
asm should be a link to the actual architecture you're compiling for, not to asm-generic.
You can't compile a generic kernel module, that would work on a generic architecture. You have to compile it for the particular architecture you're going to use.
I don't know why the asm didn't exist. It should be created as part of the configuration process.
You might get other errors later, if configuration is incomplete in other ways.
The asm includes (such as linkage.h) are architecture specific. There should be a set of directories under:
/usr/src/kernels/(kernel version goes here)/arch
that provide specific includes for the specific CPU architecture you are targeting your code to be compiled for.
Try adding this to your Makefile:
KVERSION :=R(shell uname -r)
and add the kernel and architecture (x86 in this example):
INCDIRS = -I./include -I/usr/src/kernels/$(KVERSION)/include -I/usr/src/kernels/$(KVERSION)/arch/x86
module compiling : asm/linkage.h file not found
This means this particular file was not found in specified DIR, which gets specified when we use -I option with make.
We can either link that asm-generic to asm, if all headers are present in asm-generic, or we can use make utility.
Make utility is preferred in case of building kernel modules.
Create a 'Makefile' in working DIR.
obj-m += hello.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
Use of -C option will change to DIR specified before reading the makefiles or doing anything else.
So to avoid this error, use -C option with DIR/lib/modules/$(shell uname -r)/build
By this your program will be able to find required files, you will get hello.ko file.
You can add this to kernel modules by
sudo insmod hello.ko
Similarly you can remove by
sudo rmmod hello

Resources