Building 3rd party linux kernel modules: changes with kernels after 4.9? - linux

I've been building my own kernels on Ubuntu for years, using make-kpkg from the kernel-package package. All I had to do after installing the linux-image and linux-headers packages was to correct the /lib/modules/4.x.y/{source,build} symlinks so they pointed to the /usr/src/linux-headers-4.x.y directory instead of to the source tree (which I'd trash because HUGE).
Last kernel I did this with was 4.9.30 (with Con Kolivas's patches). Doing the same with 4.15.7 and 4.14.23 works for some 3rd party modules (for instance, ZFS) but not with others, like the driver for the RTL8812au WIFI adapter (or even the host kernel extensions from VirtualBox 5.2.8-121009~Ubuntu~trusty). There, I'm seeing this:
make ARCH=x86_64 CROSS_COMPILE= -C /lib/modules/4.14.23-ck1-mainline-core2-rjvb/build M=/path/to/rtl8812au_rtl8821au-git modules
make[1]: Entering directory `/usr/src/linux-headers-4.14.23-ck1-mainline-core2-rjvb'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /path/to/rtl8812au_rtl8821au-git/.tmp_versions ; rm -f /home/bertin/work/src/Scratch/RTL881x/rtl8812au_rtl8821au-git/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/path/to/rtl8812au_rtl8821au-git
make[2]: *** No rule to make target `/path/to/rtl8812au_rtl8821au-git/core/rtw_io.o', needed by `/path/to/rtl8812au_rtl8821au-git/8812au.o'. Stop.
make[1]: *** [_module_/path/to/rtl8812au_rtl8821au-git] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-4.14.23-ck1-mainline-core2-rjvb'
make: *** [modules] Error 2
This happens with the latest kernel-package version I could find on launchpad.
Two explanations (both of which are probably not wrong):
1. the tree installed in /usr/src/linux-headers-4.1x.y* is somehow incomplete
2. something has to be changed in the 3rd party extension module
I'd go with 2) were it not for the fact that apparently at least one of the various 8812au driver repos builds just fine against 4.14 and 4.15, and I must assume that this holds too for VirtualBox. (There are some reports of the error I'm seeing but in an older version, supposedly fixed in 5.2.7 .)
Any idea what is being excluded from the /usr/src/linux-headers-4.1x.y directory? Or what would need to be changed in the module build system?
I'd really love to get it to work again because even clean full kernel source tree is almost 10x bigger...
The RTL 8812au driver source I'm working with: github.com/RJVB/rtl8812au_rtl8821au .

Related

"FATAL: cannot determine kernel version" when updating initramfs

I download linux kernel-5.0.0 and try to compile and install it on my Ubuntu-18.04.3
the commands i used in /usr/src/linux-5.0:
sudo make mrproper
sudo make menuconfig
sudo make -j4
sudo make modules_install
sudo make install
at the result of last command, there is a error:
* dkms: running auto installation service for kernel 5.0.02173611831
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 5.0.02173611831 /boot/vmlinuz-5.0.02173611831
update-initramfs: Generating /boot/initrd.img-5.0.02173611831
FATAL: cannot determine kernel version
I have no idea why this is a "FATAL: cannot determine kernel version" and how can i fix it.
At the beginning, i skip it but then I find that the "cannot determine kernel version" always show up once i open vim like this.
when i open vim
by the way, the strange numbers 5.0.02173611831 are (the kernel version) + (my numbers in university), i did the config when "sudo make menuconfig" as my teacher ask.
I had this error "FATAL: cannot determine kernel version", it turned out to be a misuse of 'cpp' in a ./configure script.
Other uses were like
# Double quotes because CPP needs to be expanded
for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
But this error came from a line
kernsrcver=`(echo "#include <$utsrelease>";
echo "kernsrcver=UTS_RELEASE") |
cpp -I $kernelbuild/include |
grep "^kernsrcver=" | cut -d \" -f 2`
I changed the cpp line to (and it worked):
cpp -I $kernelbuild/include -E - |

Makefile for kernel kecho command issue

This a makefile for compiling the kernel module.
# Makefile – makefile of our first driver
#
# if KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
obj-m = first-driver.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /lib/modules/2.6.32-504.8.1.el6.x86_64/build
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
#echo kernel first-driver is ready
#$(kecho) 'Kernel: $# is ready'
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif
.PHONY : install remove
install :
sudo insmod first-driver.ko
remove :
sudo rmmod first-driver
Here I have used echo and kecho as per kernel makefile documantation but it giving the following error:
make -C /lib/modules/2.6.32-504.8.1.el6.x86_64/build SUBDIRS=/home/betatest/Device-Driver-Test modules
make[1]: Entering directory '/usr/src/kernels/2.6.32-504.8.1.el6.x86_64'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory '/usr/src/kernels/2.6.32-504.8.1.el6.x86_64'
kernel first-driver is ready
make: Kernel: default is ready: Command not found
Makefile:16: recipe for target 'default' failed
make: *** [default] Error 127
I am using GNU make version 4.1 and gcc version 4.4.7 where am I going wrong. Thanks.....
What is kecho variable's is assigned to? in the line #$(kecho) 'Kernel: $# is ready' kecho's value is null so the make considers only #$(kecho) 'Kernel: $# is ready' as a rule.
Did you forget to assign kecho to something at the beginning of the file? Like
kecho='echo'

Makefile:10: recipe for target 'modules' failed on multiple debian distros

FIXED
The problem was that I had spaces somewhere in the path to my source directory.
In this case, "Source Builds" had a space and screwed everything up.
Make sure you don't have any spaces anywhere in your folder names between root and your make directory.
So this error:
make[1]: ** No rule to make target 'Builds/ digimend-kernel-drivers-master'. Stop.
Came from the space in: ~/Source Builds/digimend-kernel-drivers-master
debian wheezy, jessie and now simplice 6 sid
I installed the build essentials package
the linux headers package for my kernel
ive tried on kernel 3.2.04, 3.16 and now 3.12
gcc version 4.9.2 (Debian 4.9.2-8)
GNU Make 4.0
this is what i get when i try to make.
willy#semplice:~/Source Builds/digimend-kernel-drivers-master$ make
make -C /lib/modules/3.12-7.semplice.0-desktop-686/build SUBDIRS=/home/willy/Source Builds/digimend-kernel-drivers-master modules
make[1]: Entering directory '/usr/src/linux-headers-3.12-7.semplice.0-desktop-686'
make[1]: *** No rule to make target 'Builds/digimend-kernel-drivers-master'. Stop.
make[1]: Leaving directory '/usr/src/linux-headers-3.12-7.semplice.0-desktop-686'
Makefile:10: recipe for target 'modules' failed
make: *** [modules] Error 2
Heres the makefile
ifneq ($(KERNELRELEASE),)
obj-m := hid-huion.o hid-uclogic.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
UDEV_RULES := /lib/udev/rules.d/70-hid-rebind.rules
DEPMOD_CONF := /etc/depmod.d/digimend.conf
HID_REBIND := /sbin/hid-rebind
modules modules_install clean:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $#
install: modules_install
install -D -m 0644 digimend.conf $(DEPMOD_CONF)
depmod -a
install hid-rebind $(HID_REBIND)
install -m 0644 hid-rebind.rules $(UDEV_RULES)
udevadm control --reload
uninstall:
rm -vf $(UDEV_RULES) $(HID_REBIND) $(DEPMOD_CONF) \
/lib/modules/*/extra/hid-huion.ko \
/lib/modules/*/extra/hid-uclogic.ko
udevadm control --reload
depmod -a
endif
what is going on here... I am getting sad
FIXED
The problem was that I had spaces somewhere in the path to my source directory.
In this case, "Source Builds" had a space and screwed everything up.
Make sure you don't have any spaces anywhere in your folder names between root and your make directory.
So this error:
make[1]: ** No rule to make target 'Builds/ digimend-kernel-drivers-master'. Stop.
Came from the space in: ~/Source Builds/digimend-kernel-drivers-master
– user4369678

Make: Command not found, but command exists?

So I have a make file which uses arm-eabi-none-xxx commands, but when I run make I get a "Command not Found" error:
bash-4.2$ make
arm-none-eabi-as -I source/ source/mailbox.s -o build/mailbox.o
make: arm-none-eabi-as: Command not found
make: *** [build/mailbox.o] Error 127
Weird bit, is the command exists and is in my path (the following is in the same directory as the makefile):
bash-4.2$ arm-none-eabi-as --version
GNU assembler (Sourcery G++ Lite 2008q3-66) 2.18.50.20080215
This assembler was configured for a target of `arm-none-eabi'.
And I can run the command that make is running:
bash-4.2$ arm-none-eabi-as -I source/ source/mailbox.s -o build/mailbox.o
bash-4.2$ ls build/
README mailbox.o
So. I read that make uses the shell to execute commands if ./ is in the current path, so I've tried that but no good. Originally I couldn't run arm-none-eabi-as at all as it's a 32-bit binary and I'm running on a 64 bit system (Slackware 14.0) but I followed the instructions here to install the 32-bit libraries etc..
So the question... what stupid schoolboy mistake am I making?
Did you run 'make' as sudo, or root? In that case, it doesn't work for me.
What I had to do was mkdir a 'build' folder, and simply run 'make'. It worked.

Building ARM GNU Cross compiler

A similiar (less descriptive) post is here.
I'm trying to roll my own tool chain using recent releases on Ubuntu and was hoping there was enough of a Linux community here that I could get specific advice on certain problems as they come up.
With everyone's help I'd like to see this turn into a useful reference eventually.
First off "Crosstool" to which nearly everyone refers is a little (2006) out of date and "Crosstool-NG" which seems to now be carrying the torch fails on my machine. I'd rather debug the process itself than a script (which it would seem requires me to understand the process).
Below are basic steps of what I've got working so far; at present I'm stuck trying to compile the first pass GCC.
Where it's failing ...
It's failing because the cross compiled library containing "crti.o" is missing:
# ./gcc-4.4.1/configure --target=arm-linux --disable-thread --enable-langauges=c
/bin/bash ../../../gcc-4.4.1/libgcc/../mkinstalldirs .
/usr/src/gnu-4.4.1-build/./gcc/xgcc -B ........
/usr/local/arm-linux/bin/ld: crti.o No such file: No such file or directory
collect2: ld returned 1 exit status
make[2]: *** [libgcc_s.so] Error 1
make[2]: Leaving directory `/usr/src/gnu/gcc-4.4.1-build/arm-linux/libgcc'
make[1]: *** [all-target-libgcc] Error 2
make[1]: Leaving directory `/usr/src/gnu/gcc-4.4.1-build'
make: *** [all] Error 2
Build steps
On a 'freshly' configured Ubuntu 9.04 installation, here are the steps I've done so far:
#New configuration of Ubuntu 9.04
sudo updatedb
sudo apt-get install build-essential subversion
# For kernel configuration
sudo apt-get install libncurses5-dev
# For building GCC
sudo apt-get install libgmp3-dev libmpfr-dev
#Get Linux Headers for GCC/GLIBC compilations
# I use a hacked Linux from Artilla,
pushd ~ && svn co http://.../linux m501-linux && cd !$
make ARCH=arm m501_defconfig
make ARCH=arm menuconfig
sudo mkdir /usr/local/arm-linux/include
sudo cp -dR include/asm-arm /usr/local/arm-linux/include/asm
sudo cp -dR include/linux /usr/local/arm-linux/include/linux
cd /usr/local/arm-linux/
sudo ln -s include sys-include
popd
#Get sources:
cd /usr/src/
sudo su root
mkdir gnu
ftp ftp.gnu.org
# get gnu/binutils/binutils-2.19.1.tar.bz2
# get gnu/gcc/gcc-4.4.1/gcc-4.4.1.tar.bz2
# get gnu/glibc/glibc-2.10.1.tar.bz2
# get gnu/gdb/gdb-6.8.tar.bz2
#Build Binutils
bzcat binutils-2.19.1.tar.bz2 | tar -xv
mkdir binutils-2.19.1-build && cd !$
cp ../binutils-2.19.1/gas/config/tc-arm.c ./tc-arm.c
sed -r 's/(as_bad[ \t]*\()(.+\[.+\]\))/\1\"%s\",\2/' < ./tc-arm.c > ../binutils-2.19.1/gas/config/tc-arm.c
rm ./tc-arm.c
../binutils-2.19.1/configure --target=arm-linux
make && make install && cd ..
#Build GCC
bzcat gcc-4.4.1.tar.bz2 | tar -xv
mkdir gcc-4.4.1-build && cd !$
../gcc-4.4.1/configure --target=arm-linux --disable-thread --enable-langauges=c -with-headers=/usr/local/arm-linux/include
make
Welcome, you're not alone.
The story
I don't know why ARM cross-compiling is such a nightmare. It's not my opinion, let's see, what others say...
Building a gcc / glibc cross-toolchain
for use in embedded systems
development used to be a scary
prospect, requiring iron will, days if
not weeks of effort, lots of Unix and
Gnu lore, and sometimes willingness to
take dodgy shortcuts. ( http://www.kegel.com/crosstool/ )
My ARM computer (GuruPlug) is running on Debian, so I just need a standard G++ compiler, without any tweaks.
I'm using 32-bit Ubuntu on my notebook. There are deb packages for AVR cross-compiler, or even for Z80, but none for ARM - why? OK, we have to compile one. Let's go. The compilation process of the toolchain is a bit confusing for me. 14k lines long Makefile, thank you.
After some days (and nights) I've failed.
The solution
Finally, I've found an out-of-the box soluion. I've just downloaded the lite edition of this stuff: http://www.codesourcery.com/sgpp/lite_edition.html and now I'm happy. It has an ugly installer, but it works. It says:
arm-none-linux-gnueabi-g++ (Sourcery G++ Lite 2010q1-202) 4.4.1, which is an up-to-date G++ version.
(My friend has a Mac, and he has also failed compiling the toolchain after fighting with it for a week. He is now using this compiler on a VM running Ubuntu.)
Here is the HelenOS arm-32 toolchain installation script, this should do what you want with very little fiddling. I'm using it on Ubuntu now (I'm one of the HelenOS developers). It was written by Martin Decky:
#!/bin/bash
# Cross-Compiler Toolchain for ${PLATFORM}
# by Martin Decky <martin#decky.cz>
#
# GPL'ed, copyleft
#
check_error() {
if [ "$1" -ne "0" ]; then
echo
echo "Script failed: $2"
exit
fi
}
if [ -z "${CROSS_PREFIX}" ] ; then
CROSS_PREFIX="/usr/local"
fi
BINUTILS_VERSION="2.19.1"
GCC_VERSION="4.3.3"
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz"
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2"
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2"
GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2"
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/"
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/"
PLATFORM="arm"
WORKDIR=`pwd`
TARGET="${PLATFORM}-linux-gnu"
PREFIX="${CROSS_PREFIX}/${PLATFORM}"
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}"
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}"
OBJDIR="${WORKDIR}/gcc-obj"
echo ">>> Downloading tarballs"
if [ ! -f "${BINUTILS}" ]; then
wget -c "${BINUTILS_SOURCE}${BINUTILS}"
check_error $? "Error downloading binutils."
fi
if [ ! -f "${GCC_CORE}" ]; then
wget -c "${GCC_SOURCE}${GCC_CORE}"
check_error $? "Error downloading GCC Core."
fi
if [ ! -f "${GCC_OBJC}" ]; then
wget -c "${GCC_SOURCE}${GCC_OBJC}"
check_error $? "Error downloading GCC Objective C."
fi
if [ ! -f "${GCC_CPP}" ]; then
wget -c "${GCC_SOURCE}${GCC_CPP}"
check_error $? "Error downloading GCC C++."
fi
echo ">>> Creating destionation directory"
if [ ! -d "${PREFIX}" ]; then
mkdir -p "${PREFIX}"
test -d "${PREFIX}"
check_error $? "Unable to create ${PREFIX}."
fi
echo ">>> Creating GCC work directory"
if [ ! -d "${OBJDIR}" ]; then
mkdir -p "${OBJDIR}"
test -d "${OBJDIR}"
check_error $? "Unable to create ${OBJDIR}."
fi
echo ">>> Unpacking tarballs"
tar -xvzf "${BINUTILS}"
check_error $? "Error unpacking binutils."
tar -xvjf "${GCC_CORE}"
check_error $? "Error unpacking GCC Core."
tar -xvjf "${GCC_OBJC}"
check_error $? "Error unpacking GCC Objective C."
tar -xvjf "${GCC_CPP}"
check_error $? "Error unpacking GCC C++."
echo ">>> Compiling and installing binutils"
cd "${BINUTILSDIR}"
check_error $? "Change directory failed."
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls"
check_error $? "Error configuring binutils."
make all install
check_error $? "Error compiling/installing binutils."
echo ">>> Compiling and installing GCC"
cd "${OBJDIR}"
check_error $? "Change directory failed."
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --without-headers --disable-shared
check_error $? "Error configuring GCC."
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc
check_error $? "Error compiling/installing GCC."
echo
echo ">>> Cross-compiler for ${TARGET} installed."
Sorry for any line wrapping, should be easy to fix. If you want a pastebin or http link to get it, just leave a comment.
You should really have put more effort with using crosstool-NG, since the crosstool mailing list is very reactive. Since understanding the whole process is a huge task, understanding how to use a tool that you might reuse is IMHO more interesting.
I recently built a GNU toolchain for ARM using crosstool-ng. It took a bit of trial and error to figure out which versions of the toolchain components would play nice together, but I finally got it working with the following versions:
binutils 2.19.1
gcc 4.3.2
gmp 4.2.2
linux kernel 2.6.29.1
mpfr 2.3.1
uClibc 0.9.30.1
See if these work for you too.
Also, OpenWrt as a part of it's build process creates a cross-compiling toolchain. You may want to try that, selecting one of the ARM-based boards as a target, even if you aren't interested in making a wireless router.
If you're really want to build entire toolchain for yourself:
http://frank.harvard.edu/~coldwell/toolchain/
http://ftp.snapgear.org/pub/snapgear/tools/arm-linux/build-arm-linux-3.4.4
Take in mind, though, as you should search for toolchain compatibilty matrix or you may run into weird compilation errors.
If you still have the option for crosstool-ng, this is what I'm was working on for last few days:
http://blog.stranadurakov.com/2009/08/04/how-to-arm-linux/
Here you will find my crosstool-ng configuration file, which had worked for me.
I've had good luck using buildroot to build toolchains and libraries for cross-compiling Linux. Buildroot uses the lightweight uclibc C library rather than glibc, so it might not work for your purposes. (And getting the toolchain this way might not be quite as exciting and compiling it yourself.)
This was a bit of red-herring. Apparently cross-compling a tool chain for an existing system with a working GLIBC doesn't require GLIBC to be recompiled. I honestly don't know how I ignored this fact.
So even though I still don't know how to cross compile GCC and GLIBC, as I only need GCC I'm going to mark this as closed.
If I can, I'll come back to this post and mark what I eventually did.
EDIT:
Checkout this.

Resources