i'm a beginner and i'm trying out some basics of kernel programming in linux. Today morning i've opened the module.h file in VIM, and closed without saving any changes as well. After that i'm not able to compile any of my codes. I'm getting the following error message
[root#localhost helloworld]# cc helloworld.c
helloworld.c:1:25: error: linux/module.h: No such file or directory
[root#localhost helloworld]#
Here is a sample code which was running successfully till the last day.
#include<linux/module.h>
#include<linux/kernel.h>
int init_module(void)
{
printk("HELLO WORLD");
return 0;
}
void cleanup_module(void)
{
printk("GOODBYE");
}
I searched for the module.h file like the following and it do exist
[root#localhost usr]# find . -name module.h
./src/kernels/2.6.18-194.el5-i686/include/asm-x86_64/module.h
./src/kernels/2.6.18-194.el5-i686/include/asm-i386/module.h
./src/kernels/2.6.18-194.el5-i686/include/linux/module.h
./include/sepol/policydb/module.h
./include/sepol/module.h
./include/kde/kunittest/module.h
[root#localhost usr]#
Please help me out.
I'm using CentOS in virtual box.
You're trying to compile your module with plain gcc with none of the
surrounding kbuild framework. You might have gotten something to work in the
past with this approach, but it is painful horrible awful to try to maintain
a module using anything other than pure-kbuild Makefile approaches. I've
wasted too much of my life fighting against kbuild and I don't want the same to
happen with you -- embrace kbuild and let it help you build your module. Please
read Documentation/kbuild/modules.txt before writing another line of code.
What you need to do is create a Makefile for your module. Its contents should
look like this:
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile
obj-m := modulename.o
else
# normal makefile
KDIR ?= /lib/modules/`uname -r`/build
default:
$(MAKE) -C $(KDIR) M=$$PWD
endif
I know it's a lot more complicated than most Makefiles you're used to seeing,
but it serves a dual-purpose. If you just run make in your directory, it'll
re-invoke make to use the kbuild mechanism from the currently-running kernel
(assumed to at least have a symlink from /lib/modules/.../build to the
correct location).
The re-invoked make command ($(MAKE)) will properly build your module and
save you more time than you can ever appreciate. (Really.)
Keep Documentation/kbuild/modules.txt by your side while making this work.
Note: Documentation/kbuild/modules.txt may be available at your linux system at /usr/share/linux-headers-$(uname -r)/Documentation/kbuild/modules.txt
Install the package kernel-devel:
yum install kernel-devel
After that, you should have:
/usr/src/kernels/$kernelversion/include/linux/module.h
You can then pass something like:
-I/usr/src/kernels/$(uname -r)/include
to the compiler
You may need a Makefile to compile your module.I have tried out on my personal computer(Ubuntu 10.04.4),I meet the same problem when I use gcc -c hello.c,but using a Makefile, everything will be OK.The kernel vesion is 2.6.32-54-generic
Related
I've been spending the last week trying to reach one objective that i still haven't reached.
My final goal would be to cross-compile for some architectures (in this question i will take as an example only one which is MIPSLE) a couple of kernel modules that i'd like to use on my home router, by loading them at runtime with INSMOD.
My router is missing of some iptables functionalities and that's why during the kernel compilation, who compiled it decided to get rid of them.
The current kernel version is quite obsolete: Linux version 2.6.36+ by doing /proc/version
I read a lot of documentations and still i'm not sure if it possible to compile just some modules or if it's necessary to compile the whole kernel everytime (some people said that for some modules is possible and for others with more dependencies is not, is that true ?).
In this case the kernel modules i need are located in /net/ipv4/netfilter/
Since i didn't get how to compile just kernel modules in a standalone way, i decided to cross-compile the entire kernel and take the modules i needed.
So i've downloaded the proper toolchain (uclibc mipsle toolchain) and i was successfull in compiling a simple working hello world that i've executed on my router where i have an ssh shell.
So i'm sure that the toolchain i'm using it's the correct one.
Now, since i wanted to test with a recent version of kernel i've downloaded the latest ubuntu 20 with correspective kernel and i've successfully compiled it and the kernel modules that i was speaking about before, were there inside the netfilter folder in .ko format , PERFECT !
I clearly used the /boot/config_file of my host machine as .config
So, after I've downloaded the exact same kernel version that my router has (2.6.36) and I've tried to compile it with a .config file that i've found on GitHub related to a mipsle device with my same kernel version.
Here i think we have the first problem, I tried to find the .config of my device in order to have a smooth configuration but i don't have the /boot folder and in also was not in /proc.
How can i get it?
Anyway, I've used it and the compilation didn't look like failed, but these are the last lines:
CC drivers/usb/storage/usual-tables.o
LD drivers/usb/storage/usb-storage.o
LD drivers/usb/storage/built-in.o
LD drivers/usb/built-in.o
LD drivers/video/built-in.o
LD drivers/built-in.o
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
KSYM .tmp_kallsyms1.S
AS .tmp_kallsyms1.o
LD .tmp_vmlinux2
KSYM .tmp_kallsyms2.S
AS .tmp_kallsyms2.o
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/mips/boot/vmlinux.bin
Building modules, stage 2.
MODPOST 1 modules
CC drivers/scsi/scsi_wait_scan.mod.o
LD [M] drivers/scsi/scsi_wait_scan.ko
It says "1 Modules" but I don't understand why and inside the /net/ipv4/netfilter folder now I have .o files instead of .ko like if they've not been linked.
Since i was getting mad and I didn't know what to try more after several attempts, I've decided to use the config file of my host machine (ubuntu 2020, kernel 5.4.0.26) and the compilation was successful, with .ko files inside the folder.
The problem was that obviously they were modules compiled for x86-64 instead of MIPS and other clear "problems" related to the configuration of my x86-64 machine.
So, what i think now is that the .config I've found could be broken somehow, I also tried to disable, by adding a comment, that SCSI module, but nothing, I always get the same stuff.
And obviously between each try I always did a make distclean and make clean.
What do you suggest me to do? I won't even post all the references i've read about this stuff because i could sigsegv StackOverflow's server with that amount of data.
Thanks to everyone and sorry for the wall-post.
i'm not sure if it possible to compile just some modules or if it's necessary to compile the whole kernel every time
Well, you can compile just single modules, but compiling a module requires the kernel to be already built. Once you do that one time though, you should be able to compile other modules singularly. That is, of course, if you do not wish to embed them in the kernel itself (CONFIG_XXX=y instead of CONFIG_XXX=m). You should be able to compile only the module you want like this (assuming /path/to/linux is the directory where your already built kernel source resides):
$ cd /path/to/linux
$ cd path/to/module/folder
$ make -C /path/to/linux M=$(pwd) modules
I tried to find the .config of my device in order to have a smooth configuration but i don't have the /boot folder and it also was not in /proc. How can i get it?
Where did you look precisely? The presence of /proc/config.gz depends on CONFIG_IKCONFIG_PROC (see also here). If you cannot find the file then it's most likely because that configuration option was disabled when the kernel was built. You may try look under /boot (as you already did), or under /lib/modules/$(uname -r)/build/.config, but unfortunately there's not much else to do otherwise.
I've seen people suggest trying to run modprobe configs and then check /proc/config.gz, but that seems strange since as far as I know the kernel config shouldn't be configurable to be available as a loadable module.
What do you suggest me to do?
Well, the most important thing you want right now is to find the configuration file for your router (or a compatible one). If you cannot find that, it will be pretty hard to get everything right. You might want to search for OpenWRT versions available for your router (if any), or really anywhere else on the internet as long as you can find a suitable configuration. Include your router brand and/or model in your searches. StackOverflow can't really help you that much about this though.
You can try cross-compiling a 5.4 kernel with default config plus the module you want. For example, assuming you have the right cross-compilation toolchain ready:
cd /path/to/linux
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- defconfig
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- menuconfig
# ... enable the module, tune the config ...
make -j ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix-
In any case, consider the fact that jumping from a 2.6 to a 5.4 kernel is a pretty big change, and it's likely to end up breaking everything, so be sure to make a backup of your router's firmware before trying anything.
I have a Makefile made by following this example:
cross compile kernel module
I built a 4.14 Linux kernel from an older Xilinx source, and then built a out-of-kernel module with that script, pointing it to the said 4.14 kernel sources, and filling in the blanks for my particular platform architecture.
That worked.
(It's based on this code, if that matters: dma-proxy.c)
Now I need a newer version, and got Xilinx sources with a kernel named 5.6.0-rc1.
(--branch "zynqmp-soc-for-v5.7" from here)
Building that kernel also worked fine.
If I now use a scrubbed clean directory (incl. hidden files) with my module source code and that Makefile again, pointing to the newer kernel sources, it does neither produce a .ko file nor an error message.
All I get is:
make ARCH=arm64 CROSS_COMPILE="aarch64-linux-gnu-" -C /home/sk/src/XILINX/linux-xlnx SUBDIRS=/home/sk/src/XILINX/dma-proxy/driver modules
make[1]: Entering directory '/home/sk/src/XILINX/linux-xlnx'
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
MODPOST 28 modules
make[1]: Leaving directory '/home/sk/src/XILINX/linux-xlnx'
No .ko file in my folder as it was before when building with 4.14, and it doesn't list actually compiling anything.
I find it curious that it says "MODPOST 28 modules", whereas with pointing it to kernel 4.14, it expectedly says "1 modules"
Has anything changed between 4.14 and 5.x that would cause this?
Mkay, here is the suggested makefile template by the tutorial I referenced in the question:
PWD := $(shell pwd)
obj-m += hello.o
all:
make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules
clean:
make -C $(KERNEL) SUBDIRS=$(PWD) clean
Turns out that if I replace SUBDIRS=$(PWD) with M=$(PWD), it works. Now if I google explicitly for that M variable in conjunction with building kernel modules, I do find text that show it that way. But the net is also littered with examples using SUBDIRS, and it worked for me with a fairly recent kernel (4.14).
Then I did find references hinting at this being an old way of doing it, like from here:
make -C $KDIR SUBDIRS=$PWD
Same as M=. The SUBDIRS= syntax is kept for backwards compatibility.
In fact, this seems to be really old, like, kernel 2.6.7 old. Unfortunately, fairly recent tutorials show the old way.
I am having some trouble to compile GCC. When I try to compile it, this error appears:
Makefile:26: *** missing separator. Stop.
The line 26 refers to the first line of this condition:
#if gcc
ifeq (,$(.VARIABLES)) # The variable .VARIABLES, new with 3.80, is never empty.
$(error GNU make version 3.80 or newer is required.)
endif
#endif gcc
I already tried to insert a TAB between the keywords but it didn't work. The only thing I tried and seems to work is to change the condition to:
ifeq ($(gcc),)
ifeq (,$(.VARIABLES)) # The variable .VARIABLES, new with 3.80, is never empty.
$(error GNU make version 3.80 or newer is required.)
endif
endif
Informations:
Make log: http://pastebin.com/t5eNYJd5
Make log (after changing the condition): http://pastebin.com/HHjQKdDx
My make version is: 4.0.
GCC version I am trying to build: 5.2.0
I am using fedora 22.
I've got a workaround. The problem is that the Makefile contains hundreds of '#if', therefore, I would like to know why is it using '#if' if they do not work ?
Thanks in advance.
I stumbled upon this same problem. This question is a little old and it looks like you found a workaround, but I'll document my findings here as well for the People of the Future.
Background
GCC currently requires you to perform an out-of-source build. Based on the commands shown, some of the documentation and online QA implies that this is valid:
svn checkout svn://gcc.gnu.org/svn/gcc/trunk gcc;
gcc/configure <configure options>;
make -j 8 && make install;
This nests the source directory in the build directory, but I would expect that to count as "out-of-source." Running without -j 8 still produced the problem. I did this on a RHEL6 system, using GNU make 4.2. I was attempting to build GCC 8.0.0.
Solution
I found that making the source and build directories adjacent rather than creating builddir/sourcedir resolved the problem.
Additional info
Here's are relevant snippets from the GCC build instructions:
We use srcdir to refer to the toplevel source directory for GCC; we use objdir to refer to the toplevel build/object directory.
...
If you obtained the sources via SVN, srcdir must refer to the top gcc directory, the one where the MAINTAINERS file can be found, and not its gcc subdirectory, otherwise the build will fail.
...
First, we highly recommend that GCC be built into a separate directory from the sources which does not reside within the source tree. This is how we generally build GCC; building where srcdir == objdir should still work, but doesn’t get extensive testing; building where objdir is a subdirectory of srcdir is unsupported.
Depending on your definition of "source tree", these instructions may or may not proscribe building the way I first attempted. They should probably be updated to clarify this case.
As to the specific reason that Makefile won't run, that snippet is not valid make syntax - if is not a make keyword, and referenced variables must be enclosed like so: $(varname). # simply prevents the command from being echoed.
Rather, this is supposed to be multiline interpolated bash. This StackOverflow answer shows this being done in a Makefile, but it's done as part of a recipe. I see no evidence that this is valid as a standalone entity.
In the correctly-generated Makefile, the section you posted is absent, and all interpolated bash appears in a recipe.
I am trying to install hqp on OS X, but seems the gcc compiler is quite different.
When running make, I first come to an error like malloc.h not found, I wrap the #include header like:
#if !defined(__APPLE__)
#include <malloc.h>
#endif
In this way, the first problem is solved.
But when I continue to run make, I got things like:
g++ -shared -o libhqp.so Hqp_Init.o Hqp.o sprcm.o Meschach.o spBKP.o matBKP.o bdBKP.o Hqp_impl.o Hqp_Program.o Hqp_Solver.o Hqp_Client.o Hqp_IpsFranke.o Hqp_IpsMehrotra.o Hqp_IpMatrix.o Hqp_IpSpBKP.o Hqp_IpRedSpBKP.o Hqp_IpLQDOCP.o t_mesch.o Hqp_IpSpSC.o meschext_hl.o Hqp_SqpSolver.o Hqp_SqpPowell.o Hqp_SqpSchittkowski.o Hqp_HL.o Hqp_HL_Gerschgorin.o Hqp_HL_DScale.o Hqp_HL_BFGS.o Hqp_HL_SparseBFGS.o Hqp_SqpProgram.o Hqp_Docp.o hqp_solve.o \
../meschach/*.o ../iftcl/*.o -L"/sw/lib" -Wl,-rpath,"/sw/lib" -ltclstub8.5
i686-apple-darwin11-llvm-g++-4.2: ../meschach/*.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: ../iftcl/*.o: No such file or directory
Does anyone know what component is different this time? I tried reinstall the latest version of tcl, but it seems not to be the problem. Find it really hard to google a solution...
Without actually testing the result, I got this to work using the following steps. I have to say that this set of makefiles does not work as it should, especially with regard to how the dependencies are set up.
First, edit meschach/machine.h and remove the #include <malloc.h>, or make it conditional like you did with the __APPLE__ ifdef. The only reason why malloc.h is included seems to be for malloc() and free() and those get included via stdlib.h anyway.
Then edit makedirs.in and append -I/usr/include/malloc to MES_INCDIR, leaving you with MES_INCDIR = -I.. -I/usr/include/malloc.
With these two steps in place, doing ./configure followed by make should already give you libhqp.so in the lib directory, which might be sufficient for you.
However, there is also an executable called docp in the directory hqp_docp which gets executed during the make process. It does not work because it can not find the shared libary libhqp.so. I resolved that by cd-ing into the lib directory and setting export DYLD_FALLBACK_LIBRARY_PATH=$PWD. I am not sure whether running docp is an essential part of the process though.
Finally, the building of a library called omu breaks because the linker is not passed any reference to the required library libhqp.so. I did not figure out why this would work on other systems, and I do not know whether you need that libomu at all. I just did a quick fix by adding -L../lib -lhqp to the end of the linker-command in omu/Makefile. That is the command starting with $(LD).
I hope I did not forget any of the steps I took, let me know if it still breaks for you somewhere.
I am trying to build a certain library under cygwin (OpenEXR), and I get the following error:
b44ExpLogTable.cpp:52:18: error: half.h: No such file or directory
half.h is referenced using #include <half.h>, and is actually a part of another library I successfully run make/make install on previously.
The question is -- when using #include with <>, where the preprocessor expects to find the specified file?
(I have just found it in /usr/local/include/OpenEXR, but I have no idea why preprocessor cannot).
Update: I have also found:
Makefile
ILMBASE_CXXFLAGS = -I/usr/local/include/OpenEXR
Makefile.am
INCLUDES = #ILMBASE_CXXFLAGS# \
-I$(top_builddir) \
-I$(top_srcdir)/config
This actually decreased my understanding of what the problem may be.
Update 2: So, by redefining some variables in makefile I found out that instead of $(CXXCOMPILE) make seems to run $(CXX) $(CXXFLAGS), with CXXFLAGS being just -g -O2. Ok, I have no idea how it manages to run $(CXX) $(CXXFLAGS) if this combination in not used anywhere in the makefile except in $(CXXCOMPILE) which is not run. I can add my -I to CXXFLAGS but I have a feeling that a lot more additions will be required, so I would prefer to find a root cause of the problem.
(I am not sure whether it is a Super User or Stack Overflow question, because my developer skills in C++/Linux are almost non-existent.)
Additional include directories are usually specified in CPPFLAGS. Try running ./configure CPPFLAGS=-I/usr/local/include/OpenEXR and re-running make.
You need to somehow get -I/usr/local/include/OpenEXR added to the compiler command line. That might be a simple matter of doing:
CFLAGS=-I/usr/local/include/OpenEXR make