Trouble Making nvhost_vi a Module

Edit: October 12, 2016

Looks like soc_platform is on it’s way out all together and the documentation is outdated, so this question is irrelevant.


While trying to follow the instructions in the “Tegra Driver Package Developer Guide” I discovered that nvhost_vi is built in to the default 24.2 kernel and it can’t be removed like the instructions say to do. Figuring it would be an easy fix I tried to recompile the kernel following the instructions here: Compiling Tegra X1/X2 source code - RidgeRun Developer Connection

If I make nvhost_vi a module (CONFIG_VIDEO_TEGRA_VI=m) the make zImage process fails with the following errors:

drivers/built-in.o: In function `tegra_vi_v4l2_init':
/home/wilkinsw/L4T/64_TX1/Linux_for_Tegra_64_tx1/sources/kernel_source/drivers/media/platform/tegra/camera/mc_common.c:192: undefined reference to `tegra_vi_get'
drivers/built-in.o: In function `tegra_channel_update_clknbw':
/home/wilkinsw/L4T/64_TX1/Linux_for_Tegra_64_tx1/sources/kernel_source/drivers/media/platform/tegra/camera/channel.c:850: undefined reference to `tegra_vi_get'
Makefile:794: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

I couldn’t find any references to these errors, but they seemed to be caused by CONFIG_VIDEO_TEGRA_VI being set to module, as setting it back to built-in made the compilation complete successfully.

Here’s the contents of kernel_source/drivers/media/platform/tegra/vi/Makefile

COV_PROFILE := y
ccflags-y += -Idrivers/video/tegra/host
ccflags-y += -Idrivers/media/platform/tegra
ccflags-y += -Werror

ifeq ($(CONFIG_ARCH_TEGRA_18x_SOC),y)
ccflags-y += -I../kernel-t18x/drivers/video/tegra/host/
endif

obj-y += vi_irq.o
obj-y += tegra_vi.o

nvhost-vi-objs += vi.o
obj-$(CONFIG_VIDEO_TEGRA_VI) += nvhost-vi.o

It seems that vi.o only gets included in “nvhost-vi-objs” and doesn’t get included as built-in if nvhost is set to a module. By adding obj-y += vi.o to the Makefile the compilation of zImage finishes successfully. But trying to make modules causes the shit to hit the fan again…

Building modules, stage 2.
  MODPOST 28 modules
WARNING: drivers/media/platform/tegra/vi/nvhost-vi: 'tegra_vi_get' exported twice. Previous export was in vmlinux
ERROR: "vi2_channel_capture_frame_init" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_power_off" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_power_on" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_error_status" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_done" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_stop_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_start_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_frame_enable" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_setup" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_frame" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_ec_init" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_tpg_start_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_status" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_error" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_error_recover" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_stop_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_ec_recover" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
/home/wilkinsw/L4T/64_TX1/Linux_for_Tegra_64_tx1/sources/kernel_source/scripts/Makefile.modpost:88: recipe for target '__modpost' failed
make[1]: *** [__modpost] Error 1

Anyone successfully gotten nvhost to be a module? Or do we not need to do that anymore?

I don’t know the history of nvhost-vi.ko, but here are some observations…

I see nvhost-vi.ko was available in the default kernel up to and including only the 32-bit user space of R23.1. Starting with initial 64-bit user space support, this seems to have gone away (and there would be differences in module loading that may have needed working out when going pure 64-bit). The original nvhost-vi.ko would have been in module subdirectory “drivers/video/tegra/host/vi/”, and this would correspond to a similar directory in build source. In R23.2 and more recent the “vi/” subdirectory does not exist in the kernel source. I suspect that as of R23.2 this feature was completely changed, and that the documentation referring to this module was probably current up to R23.1 but incorrect on releases after that.

What seems a bit more interesting is that CONFIG_VIDEO_TEGRA_VI within tegra12_defconfig (older 32-bit) is set to ‘Y’ for R24.2, but is completely missing from tegra21_defconfig (what a JTX1 should use). Speculating, perhaps that configuration item was obsoleted and functionality distributed to elsewhere (a different CONFIG_ item). It seems this kernel config was not intended to be part of the 64-bit kernel.

Following that trend, R24.2 kernel source has subdirectory “drivers/media/platform/tegra/vi/”. I see what seems to be the same files (or approximately) in this media directory rather than in the host directory. Again, it seems that “vi/” subdirectory files and features are being refactored/rearranged.

So the question occurs, what was it that the feature had to be created as a module for, and does it still apply to the R24.2 kernel? What was your end goal? There may be a different way of doing the same thing now.

Thanks for the reply! I’ve read a lot of your posts :)

I’m trying to figure out how to install a driver for Aptina’s mt9m021 camera. I’m hoping to use a driver that was released by Aptina in 2013 for the Beaglebone Black.

So far I can build the driver as a module and install it via modprobe. I figured out how to instantiate the i2c part of it by adding a i2c_board_info struct and putting an i2c_new_device call into __init, but I’m struggling with getting it registered as a /dev/videoX device.

The developer guide provides some hints about modifying the board file at kernel_source/arch/arm/mach-tegra/board-t210ref-camera.c

I put my module in it, but that board file seems to be related to SOC_Camera_Module, which the documentation suggests is not compatible with nvhost. Thus I was trying to compile the kernel without nvhost.

My ultimate goal is figuring out how to get my camera to show up as a /dev/videoX device.

The Beaglebone Black is 32-bit, the 64-bit kernel space for a JTX1 would likely require this to be modified to work correctly. Was the driver from the kernel source which came with the JTX1, or is it a driver which was added to the kernel from an outside source? If you added this yourself there may be more steps than simply compiling. Also, if this driver is being added separately and is not something which came with the existing kernel, what kernel version did it come from? Note that the nvhost-vi.ko does exist on the 32-bit builds.

The driver was not from the kernel source that came with the JTX1. I found the code for it here:
http://www.staroceans.org/myprojects/aptina-driver/MT9M021/Angstrom/mt9m021.c

The release notes indicate that it worked with Kernel version 3.1.2
http://www.staroceans.org/myprojects/aptina-driver/MT9M021/Angstrom/README_Beagleboard-xM_mt9m021.txt

I’m willing to modify the driver, but I’m having trouble determining which OV5693 driver to use as a template.
kernel_source/drivers/media/i2c/ov5693.c (Enabled in tegra21_defconfig)
kernel_source/drivers/media/i2c/soc_camera/ov5693_v4l2.c (Used as an example in the documentation)

After more digging I found out that soc_platform is on its way out all together and I should be trying to figure out media devices instead.

I have a similar issue as Ater. I am trying to use a module supplied by Econ for the TX1.
The module is for a ar1820 camera. We are currently in the process of upgrading to Jetpack 2.3.

Econ supplied some scripts to load and unload the modules but they don’t work. (see script below)

Script for loading module

#!/bin/bash
sudo dmesg -C
sudo modprobe -r nvhost_vi
sudo modprobe soc_camera
sudo insmod /home/ubuntu/ar1820_v4l2.ko
sudo modprobe tegra_camera
dmesg

Script for unloading module

#!/bin/bash
sudo dmesg -C
sudo modprobe -r tegra_camera
sudo rmmod ar1820_v4l2
sudo modprobe -r soc_camera
dmesg

They attempt to unload nvhost_vi and it won’t unload since it is built in and not as a module

modprobe: FATAL: Module nvhost_vi is builtin.

When I build the kernel with nvhost_vi (CONFIG_VIDEO_VI=m) as a module the zImage no longer builds.
See Errors below:

WARNING: drivers/media/platform/tegra/vi/nvhost-vi: 'tegra_vi_get' exported twice. Previous export was in vmlinux
ERROR: "vi2_channel_capture_frame_init" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_power_off" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_power_on" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_error_status" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_done" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_stop_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_start_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_frame_enable" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_setup" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_capture_frame" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_ec_init" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_tpg_start_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_status" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_error" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "csi2_error_recover" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_stop_streaming" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
ERROR: "vi2_channel_ec_recover" [drivers/media/platform/tegra/vi/nvhost-vi.ko] undefined!
make[2]: *** [__modpost] Error 1
make[1]: *** [modules] Error 2
make: *** [sub-make] Error 2

Any advice on how to build it as a module?

You have to export those functions by the EXPORT_SYMBOL() after those functions declarative files.