AlmaLinux 10: How to build only sata modules from kernel SRPM

Hello.

I would like to build the sata_nv kernel module for AlmaLinux 10.1 but without building everything.

When I follow these steps it builds the sata_nv.ko file properly in drivers/ata from source root directory, but it takes 20GB and 5 hours of build to build everything:

cd /root
dnf group install “Development Tools” -y
dnf -y builddep kernel
#- Download and extract the kernel SRPM sources directory
dnf -y download --source kernel
rpm -ivh kernel-.src.rpm
cd /root/rpmbuild
rpmbuild -bp /root/rpmbuild/SPECS/kernel.spec
#- Change to newly extracted root source directory
cd /root/rpmbuild/BUILD/kernel-*/linux-*/
#- Take back current .config as working basis
cp /boot/config-$(uname -r) .config
make oldconfig
#- Make menuconfig and add the NVIDIA SATA driver in console menu
make menuconfig
#- Generate all modules listed in .config
make clean
make modules

This works fine.

But my aim is to generate the drivers/ata/sata_nv.ko module without the need to build everything, only the drivers/ata kernel modules, so it would be much quicker to build.
Hence I tried to do these following steps, which work fine on an already built rpmbuild directory of 20 GB with “make modules”:

make M=drivers/ata

But doing them without the whole “make modules” or “make bzImage” commands before, it does not work:

make clean
make prepare
make M=drivers/ata

As a result I get those errors:

CC [M] drivers/ata/ata_generic.o
CC [M] drivers/ata/pata_legacy.o
MODPOST drivers/ata/Module.symvers
WARNING: Module.symvers is missing.
Modules may not have dependencies or modversions.
You may get many unresolved symbol errors.
You can set KBUILD_MODPOST_WARN=1 to turn errors into warning
if you want to proceed at your own risk.
ERROR: modpost: “strncasecmp” [drivers/ata/libata.ko] undefined!

What am I doing wrong please, or what needs to be added for only the drivers/ata modules to be built without all the rest, so that it would be much quicker to build ?

The cause is the absence of Module.symvers. make prepare / make modules_prepare does not generate Module.symvers. make M=drivers/ata modules runs modpost at the end, making the kernel’s exported symbol list (Module.symvers) essential. Without it, the build fails with errors like strncasecmp undefined.

The quickest solution is to copy and use the Module.symvers file from the kernel-devel package matching the currently running kernel:

dnf -y install “kernel-devel-uname-r == $(uname -r)” “kernel-headers-uname-r == $(uname -r)”

./scripts/config --file .config --module SATA_NV
make olddefconfig

make prepare modules_prepare
cp -v /usr/src/kernels/$(uname -r)/Module.symvers .
make -j“$(nproc)” M=drivers/ata modules

This is significantly lighter than building all modules, allowing you to build only drivers/ata (plus dependencies like libata).

Translated with DeepL.com (free version)

Thanks for your explanations.
Please note that the lines “dnf install kernel-deve-uname-r == $(uname -r)” do not work, especially for the kernel-headers-uname-r. I had to put this instead:

dnf install -y kernel-devel-$(uname -r)
dnf install -y kernel-headers-$(uname -r)

But they were already installed in my case.

Coming back to the Module.symvers file, yes I saw this error already before, and I tried already your suggestion to copy it from the kernel-devel tree into the kernel source RPM tree and build again, but it did not work.
I tried again your exact procedure, and this is what I get as error:

CC [M] drivers/ata/sata_nv.o
CC [M] drivers/ata/sata_promise.o
MODPOST drivers/ata/Module.symvers
ERROR: modpost: “devm_of_phy_get” [drivers/ata/libahci:platform.ko] undefined!
… and many other errors of the same type listed.

The only difference between your procedure and mine is that I had typed “make M=drivers/ata” and not “make M=drivers/ata modules”.

Did you try your procedure before posting this solution and does it work on your side?

P.S: I cannot do any copy/paste anymore when posting in this thread for any reason, paste does not work, since today.

I think the “disable AHCI / rewrite Makefile” approach is a workaround, not a root fix.

modpost: "devm_of_phy_get" undefined usually happens when the build inputs don’t match:

  • the kernel source tree you are compiling (SRPM tree),
  • the exact configuration used to build the running kernel,
  • and the symbol/version data (Module.symvers + generated headers) for that same kernel build.

So the first priority is to make sure the SRPM source corresponds to the exact same NVR as the running kernel (uname -r), and to reuse the matching kernel build system/output from kernel-devel without polluting /usr/src.

A safe and reproducible way is:

  • drive the build from the matching kernel-devel tree (-C /usr/src/kernels/$(uname -r)),
  • write all build artifacts into a disposable directory (O=/var/tmp/...),
  • start from the matching kernel-devel .config,
  • then build only the ATA subtree.

Example:

dnf -y install kernel-devel-$(uname -r) kernel-headers-$(uname -r)

cd /root/rpmbuild/BUILD/kernel-/linux-/ # SRPM linux source tree

out=/var/tmp/kbuild-$(uname -r)
mkdir -p “$out”
cp -v /usr/src/kernels/$(uname -r)/.config “$out/.config”

#enable sata_nv as module if needed
./scripts/config --file “$out/.config” --module SATA_NV

make -C /usr/src/kernels/$(uname -r) O=“$out” olddefconfig prepare modules_prepare
make -C /usr/src/kernels/$(uname -r) O=“$out” -j"$(nproc)" M=$PWD/drivers/ata modules

#the .ko files will be in the SRPM source tree (M= path), e.g.:
ls -l drivers/ata/sata_nv.ko

If this still fails, please confirm the exact kernel NVR (rpm -q kernel-core) and that the SRPM you unpacked is the same NVR. Any mismatch there will reproduce undefined-symbol errors regardless of O=.

Thanks for the very useful information.

I have verified and the kernel-devel and kernel SRPM have the same version, except maybe the architecture (x86_64_v2), and also the SRPM is “el10” and not “el10_1”:

# uname -r
6.12.0-124.21.1.el10_1.x86_64_v2
# pwd # from kernel-devel
/usr/src/kernels/6.12.0-124.21.1.el10_1.x86_64_v2
# pwd # from source RPM
/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64

Maybe this is causing the error?

Except this, I tried your procedure, and when coming to the “make … olddefconfig”, I get this error:

[root@localhost linux-6.12.0-124.21.1.el10.x86_64]# make -C /usr/src/kernels/$(uname -r) O="$out" olddefconfig
make: Entering directory '/usr/src/kernels/6.12.0-124.21.1.el10_1.x86_64_v2'
make[1]: Entering directory '/tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2'
***
*** The source tree is not clean, please run 'make mrproper'
*** in /usr/src/kernels/6.12.0-124.21.1.el10_1.x86_64_v2

However, when I change to /usr/src/kernels/6.12.0-124.21.1.el10_1.x86_64_v2 and type ‘make mrproper’ (after backuping the .config file), the error is still exactly the same.

The output of “rpm -q kernel-core” is this:

[root@localhost ~]# rpm -q kernel-core
kernel-core-6.12.0-124.8.1.el10_1.x86_64_v2
kernel-core-6.12.0-124.21.1.el10_1.x86_64_v2

Is the NVR mismatched?

Build/fix only SATA (ATA) modules from the AlmaLinux 10 kernel SRPM

The failures are caused by mismatched build inputs. Do not use kernel-devel as the source tree. Use the SRPM source tree as the source, and reuse the running kernel’s .config and Module.symvers.

#Get the SRPM that matches the running kernel exactly:

rpm -q --qf ‘%{SOURCERPM}\n’ kernel-core-$(uname -r)

Download/install that exact kernel-*.src.rpm, then locate the extracted source directory.

#Build only drivers/ata into a separate output directory:

dnf -y install kernel-devel-$(uname -r) kernel-headers-$(uname -r)

src=/root/rpmbuild/BUILD/kernel-*/linux-*/
out=/tmp/kbuild-$(uname -r)
mkdir -p "$out"

cp -v /usr/src/kernels/$(uname -r)/.config "$out/.config"
cp -v /usr/src/kernels/$(uname -r)/Module.symvers "$out/Module.symvers"

"$src"/scripts/config --file "$out/.config" --module SATA_NV

make -C "$src" O="$out" olddefconfig prepare modules_prepare
make -C "$src" O="$out" -j"$(nproc)" M=drivers/ata modules

ls -l "$out"/drivers/ata/*.ko

Would you like for me to make you a kmod SRPM that you can recompile on Alma 10.x? Please make a request-for-enhancement at ELRepo.and specify you need it for x86_64_v2.

Note: The reason why you need to do the rpmbuild is because we currently do not support x86_64_v2 compilations. Also doing the rpmbuild should only take a minute or two.

1 Like

Hello @redadmin .

I tried your exact procedure of comment #6 of this post.
Everything went smooth with the versions and I copied successfully the .config and Module.symvers files into the /tmp/kbuild* directory.

However, when I type this line of code:

make -C "$src" O="$out" olddefconfig prepare modules_prepare

… it provides immediately the following error:

[root@localhost linux-6.12.0-124.21.1.el10.x86_64]# make -C "$src" O="$out" olddefconfig prepare modules_prepare
make: Entering directory '/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64'
make[1]: Entering directory '/tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2'
***
*** The source tree is not clean, please run 'make mrproper'
*** in /root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64
***
make[3]: *** [/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/Makefile:660: outputmakefile] Error 1
make[2]: *** [/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/Makefile:376: __build_one_by_one] Error 2
make[1]: *** [/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/Makefile:242: __sub-make] Error 2
make[1]: Leaving directory '/tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2'
make: *** [Makefile:242: __sub-make] Error 2

So I went into the /root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64 directory, and I typed “make mrproper” as asked in the error message. This helped and the error message was gone when trying the same previous command.

So then I could type the next command:

make -C "$src" O="$out" -j"$(nproc)" M=drivers/ata modules

Unfortunately, this provided the following error:

[root@localhost linux-6.12.0-124.21.1.el10.x86_64]# make -C "$src" O="$out" -j"$(nproc)" M=drivers/ata modules
make: Entering directory '/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64'
make[1]: Entering directory '/tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2'
/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/scripts/Makefile.build:41: drivers/ata/Makefile: No such file or directory
make[3]: *** No rule to make target 'drivers/ata/Makefile'.  Stop.
make[2]: *** [/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/Makefile:1994: drivers/ata] Error 2

So I thought that this was due to some mixture where the make did not take the drivers/ata from $src but from $out, where that Makefile was not present. Hence I copied that Makefile there:

cp -v drivers/ata/Makefile /tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2/drivers/ata/

… and I ran the make modules command again. This time, it went further, but I still get stuck now with this error message:

[root@localhost linux-6.12.0-124.21.1.el10.x86_64]# make -C "$src" O="$out" -j"$(nproc)" M=drivers/ata modules
make: Entering directory '/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64'
make[1]: Entering directory '/tmp/kbuild-6.12.0-124.21.1.el10_1.x86_64_v2'
make[3]: *** No rule to make target 'drivers/ata/libata-core.o', needed by 'drivers/ata/libata.o'.  Stop.
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [/root/rpmbuild/BUILD/kernel-6.12.0-124.21.1.el10_1/linux-6.12.0-124.21.1.el10.x86_64/Makefile:1994: drivers/ata] Error 2

It seems that there is a Makefile missing somewhere, so that it cannot build the libata-core module.

Any idea how to solve this ?

Hello @tqhoang . Thanks for the proposal. I was always using the ELRepo reviously to download the kmod-* modules before AlmaLinux 10, so yes I am a bit confused now and this is why I am trying to do a fully working procedure to be able to build my own .ko module.

However if you can support x86-64_v2 in ELRepo and build some kmod-* there, that would be really great. You know, people will try AlmaLinux 10 on an old machine, as it can really work perfectly fine for low CPU usages. Then suddenly a repo is not there and the AlmaLinux 10 experience is disappointing.

Figuring out the proper procedure to build the .ko modules quickly with redadmin should be fine I hope eventually, but if you can add that x86-64_v2 support it would be really great for lot of old PCs without needing to throw them away, like a second life for them. I will try and maybe ask an enhancement as you wrote. Thanks!

Hello,

I checked whether the x86_64_v2 instruction set is supported by verifying CPU flags in /proc/cpuinfo.
I also tried reproducing the issue on AlmaLinux 10 x86_64_v2 under KVM.

Check CPU flags (x86_64_v2-related)
grep -m1 -E ‘ssse3|sse4_2|popcnt|cx16’ /proc/cpuinfo

0 Variables
kver=$(uname -r)

1 Get the matching kernel SRPM
(If the SRPM is not available via repos, download it via other means.)
dnf -y install dnf-plugins-core rpm-build
dnf -y download --disablerepo='*' --enablerepo=baseos-source "kernel-${kver%%.x86_64_v2}" || true

2 Extract SRPM + %prep
rpm -Uvh kernel-*.src.rpm
dnf -y --enablerepo=crb install \
  audit-libs-devel binutils-devel bpftool centos-sb-certs clang fuse-devel glibc-static \
  java-devel kabi-dw kernel-rpm-macros libbabeltrace-devel libbpf-devel libcap-devel \
  libcap-ng-devel libmnl-devel libnl3-devel libtraceevent-devel libtracefs-devel \
  libxml2-devel lld llvm-devel lvm2 net-tools newt-devel numactl-devel openssl \
  pciutils-devel python3-devel python3-docutils python3-pip python3-setuptools \
  python3-wheel rsync system-sb-certs systemd-boot-unsigned systemd-ukify xmlto
rpmbuild -bp ~/rpmbuild/SPECS/kernel.spec

3 Locate the extracted source tree and clean it (mrproper requirement)
src=$(echo ~/rpmbuild/BUILD/kernel-*/linux-*)
make -C "$src" mrproper

4 Prepare out-of-tree build directory (reuse running kernel's .config / Module.symvers)
out=/tmp/kbuild-$kver
rm -rf "$out"
mkdir -p "$out"
dnf -y install kernel-devel-$kver kernel-headers-$kver
cp -v /usr/src/kernels/$kver/.config        "$out/.config"
cp -v /usr/src/kernels/$kver/Module.symvers "$out/Module.symvers"

5 Enable SATA_NV as a module, then build only ATA
"$src"/scripts/config --file "$out/.config" --module SATA_NV
make -C "$src" O="$out" olddefconfig prepare modules_prepare
make -C "$src" O="$out" -j"$(nproc)" M="$src/drivers/ata" modules

6 Verify output
ls -l "$src/drivers/ata/sata_nv.ko"
modinfo "$src/drivers/ata/sata_nv.ko" | egrep 'vermagic|depends'

7 Load (taint warning if unsigned)
sudo insmod "$src/drivers/ata/libata.ko" 2>/dev/null || true
sudo insmod "$src/drivers/ata/sata_nv.ko"
dmesg | tail -n 20
lsmod | grep sata_nv

Result: modules loaded successfully.

Yes, please go ahead and make a request to ELRepo using My View - ELRepo Bugs as @tqhoang suggested. It’s worth establishing the procedure to build your kmod package for x86_64_v2. As you know from your own experience, ELRepo’s kmod packages can survive kernel updates, thanks to their kABI-tracking feature.

1 Like

Hello @redadmin , your procedure on post #10 works! Thank you so much.

In fact I tried several things and it works also in the same kernel SRPM directory. There some little corrections to do so I will provide a full procedure later with things that I had to adapt, and also compatible with all architectures. There were several things going wrong.
The kernel SRPM was not available anymore on the repo because it was too old and the SRPMs are removed from repo, so it did not work.
Also I found out that the following error was due to the fact that I tried to add “SATA_MV” instead of “SATA_NV”, and this error does only occur with SATA_MV and SATA_DWC drivers (it was not due to Module.symvers file mismatching kernel versions):
ERROR: modpost: “devm_of_phy_get” [drivers/ata/libahci:platform.ko] undefined!

But for any reason now your latest procedure works fine except some little things.

However: Why is the Module.symvers file not included by default in the kernel SRPM in the kernel source SRPM directory? I think this must really be placed there, because it would allow to avoid mismatching these files and also avoid the need to download the kernel-devel package just to copy that little file. Without this, it is not possible to quickly build the sources from kernel SRPM, so it is really lacking in my opinion. If this understanding is correct, can someone add it there, maybe at RHEL 10.1 level?

Thanks to @redadmin , I provide here an updated procedure to quickly build kernel modules in AlmaLinux 10.1 (in about 3 minutes) that should work on all architectures, especially SATA modules in this case (but you can build any module you wish the same way). The Minimal installation CD of AL10.1 needs to be installed before at least with all its default packages and running on a machine with SATA drive connected (to get the .config already setup properly). There are two phases of the procedure, and just copy-paste the contents while logged as root should generate the *.ko modules correctly:

# First thing: install required rpms and upgrade to last kernel
dnf group install "Development Tools" -y
dnf -y builddep kernel
# Upgrade to latest kernel to have its source SRPM in repo and reboot to run it
dnf -y upgrade && reboot
# Second thing: install kernel sources and build modules (3 min / 2GB HDD)
# Login again as root again and download and uncompress the kernel SRPM
cd /root
kver=$(uname -r)
kver_noext=$(echo $kver |sed -r 's/(.*)\.(.*)$/\1/')
dnf -y download --source --disablerepo='*' --enablerepo=baseos-source "kernel-$kver_noext"
# Install the kernel SRPM into /root/rpmbuild by default
rm -rf /root/rpmbuild
rpm -ivh kernel-$kver_noext.src.rpm
# Unpack the sources and apply any patches (1 minute)
rpmbuild -bp /root/rpmbuild/SPECS/kernel.spec

# Locate the extracted source tree and clean it (mrproper requirement)
src=$(echo /root/rpmbuild/BUILD/kernel-*/linux-*)
cd $src
make mrproper

# Import Module.symvers from running kernel-devel sources
dnf -y install kernel-devel-$kver kernel-headers-$kver
cp /usr/src/kernels/$kver/Module.symvers .
# Import your currently running .config file
cp /boot/config-$kver .config
# else take the .config from default kernel-devel tree sources
# cp /usr/src/kernels/$kver/.config .

# Enable SATA_NV as a module, then build only ATA modules
./scripts/config -m SATA_NV
# Instead, you can enable most of the SATA modules (except SATA_DWC and SATA_MV)
#./scripts/config -m SATA_INIC162X -m SATA_SIL24 -m SATA_QSTOR \
#  -m SATA_SX4 -m SATA_NV -m SATA_PROMISE -m SATA_SIL -m SATA_SIS \
#  -m SATA_SVW -m SATA_ULI -m SATA_VIA -m SATA_VITESSE

# Update the configuration file and prepare the build (1 minute)
make olddefconfig prepare modules_prepare
# Build the enabled ATA modules in .config file (10 seconds)
make -j$(nproc) M=drivers/ata modules
# List your resulting built module(s)
ll drivers/ata/sata*.ko

# If you then want to add other modules in the .config, do it and then type only:
make modules_prepare
make -j$(nproc) M=drivers/ata modules

Thank you @toracat , I will try posting this request there soon. However regarding the kernel modules, I think that they should simply all be available from an official manufacturer repo to avoid third-parties builds, it would be more reliable and secure I would say if it is the same entity that builds them. I am pretty much surprised that this does not exist yet, and for all modules so that we can simply use them already built in separate rpms without any compilation needed.