Cdrom, sr_mod kernel module

I need to use a CD/DVD drive with my AGX Orin running Jetson Linux 36.3. By following the instructions here:
Sr_mod kernel module for CD/DVD drive
Compiling a single kernel module
Kernel Customization - NVIDIA Jetson Linux Developer Guide
I attempted to compile the missing sr_mod.ko kernel module.

Here are the steps I followed:

1.Download and extract kernel sources for Jetson Linux 36.3 from Jetson Linux | NVIDIA Developer
2. Copy config from /proc/config.gz
3. Run make menuconfig
4. Set LOCALVERSION to “-tegra”
5. Set BLK_DEV_SR to “m”
6. Exit menuconfig
7. Run make -j12 modules_prepare
8. Run make -j12 modules
9. Copy the compiled sr_mod.ko to /lib/modules/5.15.136-tegra/kernel/drivers/scsi/sr_mod.ko
10. Copy the compiled cdrom.ko to /lib/modules/5.15.136-tegra/kernel/drivers/cdrom/cdrom.ko
11. Run sudo depmod -a
12. Attempt to use drive

This does not work due to an apparent version mismatch as reported in dmesg:

...
cdrom: disagrees about version of symbol kmalloc_caches
cdrom: Unknown symbol kmalloc_caches (err -22)
sr_mod: disagrees about version of symbol scsi_mode_sense
sr_mod: Unknown symbol scsi_mode_sense (err -22)
...

Existing modules and my compiled modules have the same vermagic as reported by modinfo, and everything matches uname -r.
I have tried disabling MODVERSIONS and recompiling but then insmod reports insmod: ERROR: could not insert module drivers/scsi/sr_mod.ko: Invalid module format.
I am also unable to compile just the missing modules by copying /lib/modules/5.15.136-tegra/build/Module.symvers then running make -j12 M=drivers/scsi which reports ERROR: modpost: "<symbol>" [drivers/scsi/sr_mod.ko] undefined! for every symbol in sr_mod.ko.

What am I doing wrong and is what I am trying to do even possible? I would like to avoid compiling a new kernel image and flashing that if at all possible.

here’re my steps to rebuild our OOT drivers for your reference.
sudo mkdir -p /usr/src/nvidia-jetson-1.0
cd /usr/src/nvidia-jetson-1.0
sudo tar xf /tmp/kernel_oot_modules_src.tbz2
sudo tar xf /tmp/nvidia_kernel_display_driver_source.tbz2
sudo chown -R ${USER}:${USER} /usr/src/nvidia-jetson-1.0
export KERNEL_HEADERS="/usr/src/linux-headers-5.15.122-tegra-ubuntu22.04_aarch64/3rdparty/canonical/linux-jammy/kernel-source"
make ARCH=arm64 -j8 clean
make ARCH=arm64 -j8 modules
sudo make ARCH=arm64 -j8 modules_install

I would like to clarify that the sr_mod and cdrom modules are in-tree and your steps are for the out-of-tree modules. Regardless, it seems the main difference between our procedures is that you specify KERNEL_HEADERS, and ARCH. Here are my updated procedures:

export KERNEL_HEADERS="/usr/src/linux-headers-5.15.136-tegra-ubuntu22.04_aarch64/3rdparty/canonical/linux-jammy/kernel-source"
make ARCH=arm64 -j12 clean
make ARCH=arm64 -j12 modules_prepare
make ARCH=arm64 -j12 modules
sudo cp drivers/scsi/sr_mod.ko /lib/modules/5.15.136-tegra/kernel/drivers/scsi/
sudo cp drivers/cdrom/cdrom.ko /lib/modules/5.15.136-tegra/kernel/drivers/cdrom/
sudo depmod -a

After following these steps I get the same errors as before. Something I noticed is that my genereated Module.symvers is completely different from the one in /usr/src/linux-headers-5.15.136-tegra-ubuntu22.04_aarch64/3rdparty/canonical/linux-jammy/kernel-source/ despite my configuration settings and source being the same (except for the modified BLK_DEV_SR). I am not particularly familiar with the Linux kernel but I would expect these to be mostly the same. Another thing I found is that I am compiling with gcc 11.4.0 but it seems that Jetson Linux 36.3 was build with gcc 11.3.0. Do compiler versions need to match in order to build and run a module?

Try to remove the CONFIG_MODVERSIONS in the kernel config to ignore the version check.

I shared the results of disabling MODVERSIONS in my initial post.

What’s the modinof sr_mod hows?

modinfo when MODVERSIONS is enabled:

$ modinfo sr_mod
filename:       /lib/modules/5.15.136-tegra/kernel/drivers/scsi/sr_mod.ko
license:        GPL
alias:          scsi:t-0x04*
alias:          scsi:t-0x05*
alias:          block-major-11-*
license:        GPL
description:    SCSI cdrom (sr) driver
depends:        cdrom
intree:         Y
name:           sr_mod
vermagic:       5.15.136-tegra SMP preempt mod_unload modversions aarch64
parm:           xa_test:int

modinfo when MODVERSIONS is disabled:

$ modinfo sr_mod
filename:       /lib/modules/5.15.136-tegra/kernel/drivers/scsi/sr_mod.ko
license:        GPL
alias:          scsi:t-0x04*
alias:          scsi:t-0x05*
alias:          block-major-11-*
license:        GPL
description:    SCSI cdrom (sr) driver
depends:        cdrom
intree:         Y
name:           sr_mod
vermagic:       5.15.136-tegra SMP preempt mod_unload aarch64
parm:           xa_test:int

If you run the “file <filename>” command on the actual module file, what does it say?

Result of file command on sr_mod.ko compiled without MODVERSIONS:

$ file /lib/modules/5.15.136-tegra/kernel/drivers/scsi/sr_mod.ko
/lib/modules/5.15.136-tegra/kernel/drivers/scsi/sr_mod.ko: ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), BuildID[sha1]=9015e4dd7f0e433af65f171db9ab01e61dfa9d0f, with debug_info, not stripped

Do you also replace the /boot/Image that build by remove MODVERSIONS?

I did not since no such file was generated by make -j12 modules. If possible, I would like to avoid building the full image and just build the missing drivers as modules which I could drop into stock Jetson Linux.

I might be missing this, but did you match your build configuration to that of the existing kernel before you made any module additions? Any configuration that the old kernel had needs to be exactly matched, including CONFIG_LOCALVERSION, and only then have the modules added to the config. The file command says it was indeed built for the correct architecture, and those modules have been around for a long time, so I figure that it is likely the code itself is not an issue.

I created the base configuration with zcat /proc/config.gz > .config. After I use make menuconfig to update that configuration, here are the differences:

  • GCC version updated to 11.4.0 from 11.3.0 (CONFIG_CC_VERSION_TEXT and CONFIG_GCC_VERSION reflect this)
  • CONFIG_LOCALVERSION is now “-tegra”
  • CONFIG_MODVERSIONS and CONFIG_ASM_MODVERSIONS are unset
  • CONFIG_CDROM is now “m”
  • CONFIG_BLK_DEV_SR is now “m”

Other than that the config is identical to the existing kernel.

That seems correct. Also, a change from 11.3 to 11.4 compiler shouldn’t make any difference in this case. However, I don’t know which compiler is mentioned in docs. If for example docs require a version 7.x or 9.x compiler, then 11.3 or 11.4 would likely be an issue, but I am kind of grasping on that (I don’t have any reason other than “check the compiler version the docs say to use”). Also, “menuconfig” is dependency-aware, so that too should not be a problem.

There is one other place I can think of that this could go wrong and not be obvious: Environment variables. The build inherits from the environment. I don’t have a specific answer, but I’ll give an example: If you are natively compiling, and “export ARCH=arm64”, then this will cause a failure to load; however, if you cross compile, and “export ARCH=arm64”, then this would be both helpful and mandatory.

Something else to consider: If enabling this as a module did find a dependency, and another module was built, and if you did not copy that other module in place first, then the module you built might fail due to unknown symbols. I would not expect “Invalid module format”, but I would expect the part with:

cdrom: Unknown symbol kmalloc_caches (err -22)
sr_mod: Unknown symbol scsi_mode_sense (err -22)

(note that I did not include the “disagrees about version” part; this is a mystery)

One other thing: I’m fairly certain that building support for any filesystem type, and for cdrom, does not require any change to the kernel’s integrated (“=y” in config) features. If for some reason this was a requirement, then it wouldn’t be enough to build modules. This is fairly certain to not be an issue with your configuration change.

Another possibility is if the source code you are using is not the same source code as the kernel that is trying to load the modules. I did not follow this, but if you check your L4T release with “head -n 1 /etc/nv_tegra_release”, and then go to the URL for your L4T:
https://developer.nvidia.com/linux-tegra
…are you using that kernel source?

For R36.x I would think this would match mainline, but if you download from NVIDIA and not from a third party source repo, something might have changed.

I am compiling natively and the setting or unsetting of ARCH has not seemed to make a difference, but for what its worth the latest builds have been with ARCH unset.

The sr_mod module requires the cdrom module, and cdrom does not appear to have any dependencies. I made sure to copy both .ko files to their respective locations.

The L4T release command produces the following output:

$ head -n 1 /etc/nv_tegra_release
# R36 (release), REVISION: 3.0, GCID: 36191598, BOARD: generic, EABI: aarch64, DATE: Mon May  6 17:34:21 UTC 2024

This seems to correspond with the 36.3 sources I downloaded: https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/sources/public_sources.tbz2.

Mismatch between my kernel and the source I am building seems like the most likely culprit. According to Working With Sources — NVIDIA Jetson Linux Developer Guide, this is the repo I am looking for: https://nv-tegra.nvidia.com/r/3rdparty/canonical/linux-jammy and the commit for 36.3 is a94cb003c59eecfd2d1de20c6d3e6b38b0110b92. I will clone this repo and checkout to the 36.3 tag and report back if that solves my problem.

If you manually insmod the cdrom module, does it succeed? If that succeeds, then does the insmod of sr_mod succeed? If we can break it down to the first module failing, or not failing, then we can look at the second module. If the second module succeeds, but mounting a CDROM fails, then we can look at that. From the module error messages in your first post it seems like a module insmod will fail, but I’m wondering if it fails the same if you purposely try to install the dependency (cdrom) first (maybe it isn’t that module at fault).

Incidentally, I see you’ve run “depmod -a”. Make sure you run this each time you change any module file. You can then try modprobe of the cdrom module first (instead of insmod), followed by modprobe of the next dependency (sr_mod). There is one additional bit of information to consider for modprobe: You can run it with “modprobe --dump-modversions” for a given module, and see what it claims is needed. Then, if you run lsmod and find an unrelated module which does load, and which is unrelated to this, find out what the output is for “modprobe --dump-modversions” on that other file. We can compare that dump side-by-side between a working module and a failing module and see if this notes something changing.

Building from the git source results in the same errors, and produces identical Modules.symvers. Manually installing cdrom before sr_mod also does not help; both modules have the same error messages as before. I ran modprobe --dump-modversions on pwm-meson.ko (picked a random module) from the running kernel and from my built modules. All symbol versions match except for _dev_err.

Where is the original kernel source from? Is it the source which is published under the L4T release? See “head -n 1 /etc/nv_tegra_release” for the L4T release; the source would be under that release here:
https://developer.nvidia.com/linux-tegra

If the first module in the dependency has an issue, then don’t even try to load the second which depends on it until the first is fixed. What is the exact output for the --dump-modversions of the first module to insmod? What is the same output on your example random module?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.