Kernel rebuild make clean or mrproper not removing object files "*.o"

I’ve build my kernel 4.9 and would like to make a change and rebuild.
However, when I execute
make clean
or
make mrproper
then rebuild by executing
make -j4 O=$TEGRA_KERNEL_OUT zImage
the new zimage rebuilds quite quickly without re-compiling *.o files I want to rebuild everything.

For info, the reason for this is that I have added the line
CONFIG_EQOS_DISABLE_EEE=y
in the .config and would like to ensure that this change makes it’s way into the kernel image. If the change was to a .c file, then naturally, the makefile would re-compile the associated .o file, however with the change above there is no object compilation and so it is difficult to know if the change has made an impact.

I was expecting clean or mrproper commands to remove all object files and so the kernel make would rebuild everything but this is clearly not happening. Can someone help please.

Thanks

See:
https://forums.developer.nvidia.com/t/device-drivers-kconfigs-or-makefiles-at-sources-kernel-nvidia-and-sources-kernel-kernel-4-9/240456/2

FYI, zImage is a compressed version of the file Image. zImage was used in 32-bit systems long ago. Now you just build Image. Regardless of which kernel you use you have to start with an initial configuration, and “clean” or “mrproper” commands are not designed to set that up. Best to mrproper and either (A) match the existing configuration if it is customized, or (B) then use target “tegra_defconfig” to get a starting configuration. After that use a menu editor and don’t directly edit the config (e.g., change to “=y” with something like target “menuconfig” or “nconfig”).

Also, if you are adding features which are integrated (with an “=y”) instead of module format (with an “=m”), then you probably want to change the output of “uname -r” to a new suffix. For example, if “uname -r” is “4.9.140-tegra”, then the suffix is “-tegra”, and the CONFIG_LOCALVERSION should probably be something new. As an example you could use “-tegra_no_eqos”.

When modules are installed they go to:
/lib/modules/$(uname -r)/kernel

By changing CONFIG_LOCALVERSION from 4.9.140-tegra (or whatever it is) to 4.9.140-tegra_no_eqos, the module install location would change:

# Old location:
/lib/modules/4.9.140-tegra/kernel
# New location:
/lib/modules/4.9.140-tegra_no_eqos/kernel

This means you also have to build and install all new modules. This is often required when changing what is in the integrated kernel (the Image file, which is not dynamically loadable since it is the kernel). Sometimes this isn’t needed, but you are removing a function despite adding a feature, and so dependencies might not behave correctly if your old modules are used.

1 Like

Thank you very much for your informative response.

I set CONFIG_LOCALVERSION=“-tegra”, and am sure that my configuration is set up correctly, with respect to building and flashing. Although I have experience building the tegra kernel I tend to follow the procedure without deviating too much. I’m happy to continue with this unless I absolutely have to.

The reason I added the line CONFIG_EQOS_DISABLE_EEE=y is because I want to address a network performance issue. This impacts our production process and is something I simply have to do. I don’t want to build this as a module. I’m simply following

Another day I might learn about the EQOS functionality, and it might be useful to know what the CONFIG_EQOS_DISABLE_EEE flag actually does and how it does it with respect to the build procedure, however, at the moment I just want to address the network performance issue to keep my managers happy, therefore want to execute a clean and rebuild.

If I change a built in driver source file this will be re-compiled and this provides a good indication that this is going into the newly built kernel image, however it is difficult to see the effects of the CONFIG_EQOS_DISABLE_EEE in the build, so I thought it would be an idea to do a complete rebuild.

However, in general, I think it would be useful in future to know how to execute a make clean, or make mrproper to remove all output generated from the a build. Perhaps I need an environmental variable to be set, however, I have no problems building. The problem is cleaning.

Was the “=y” set from a configuration editor (such as “make menuconfig”)? If not, then dependencies will probably break. Also, I recommend a new CONFIG_LOCALVERSION and rebuilding all modules since you are integrating a feature which can be invasive to other drivers. Changing the output of “uname -r” is also a definitive method to know if the new kernel Image file is in place (remember, don’t use zImage on 64-bit Jetsons).

For specific questions you should also mention which L4T release this is being used in (see “head -n 1 /etc/nv_tegra_release”).

These expand on kernel build:

There are many ways to build the kernel. Related to your question, I recommend that in the original kernel source location that this be owned by root and not writable by anyone else (but readable). From there execute “sudo make mrproper”, which will make this a pristine source for anyone using it.

From then on, all compile operations would be best if performed by someone who is not root/sudo.

Once the source is pristine and only root can edit this, all commands would be with the “O=/some/where/temporary” option. Config editor changes, temporary output, so on, would end up there instead of in the source. The “/some/where/temporary” location would require write permission for whoever performs the build. Ten different developers could build their own content in their own home directories and never interfere with each other. Or one user could have ten different locations for ten different test configurations. Or one location could be recursively deleted to start over or to save space. In such a case, if you have configured the way you want, then the only file you need to back up before deleting that temp location is the “/some/where/temporary/.config” file (which is tiny, and each developer could share just that file).

Some notes:

  • make O=/some/where/temporary mrproper” will clean everything at the temp location, including removal of the .config.
  • make O=/some/where/temporary clean” will remove built temporary content at the temp location, but it will leave the .config in place.
  • If you have a saved read-only standard configuration saved as a “.config” file, then you can use a symbolic link or direct copy of that .config to the “O=/some/where/temporary” location to set up again.
  • If you want to start over all you have to do is recursively delete “/some/where/temporary”, recreate it, and build (if you have a saved “.config”, then just place that there).
  • Sometimes people modify the actual kernel source’s “tegra_defconfig” file when they get an option modification they like. This isn’t wrong, but you could instead just create a “tegra_custom” (or similar name) file and make that. It is dangerous in a multi-developer environment to change tegra_defconfig (this does work well for an individual developer).
  • I prefer to save my current .config and delete the entire temporary location. It is easy to script this, and to even have a git repository or subversion repo in the command to make sure you get the right .config when there is more than one.
  • It is easy to write a script which outputs the manual commands to perform for clean, build, so on, and when it works, have an option to actually do this (a “what if” default, and a “really do it” option).
1 Like

Thanks very much again for your detailed response. I am going to investigate your comments further as I think this will enhance my understanding of the process.

Am I correct in thinking that make clean or make mrproper will not delete the files generated during the build? If so, I can delete the build folders and do a clean checkout and build.

When building I always use make menuconfig to generate the config file, then if I want to make an additional change I will modify the generated .config file in the images folder. In this case I modified tegra_defconfig, so this takes takes care of everything.

When I execute make zImage, this also generates a new image file and both get copied onto the jetson during the build and flash process, so I don’t think there is an issue there.

Regarding the CONFIG_EQOS=y and CONFIG_EQOS_DISABLE_EEE=y entries in the .config files, these are not built as modules, because this would require “=m”. Setting “=y” means that they will be built into zImage and image binaries. Is this correct?

Problem solved. The solution is obvious now.

To successfully perform a kernel make clean, the path to the output folder needs to be specified in the same manner as for building e.g.

make O=…/Linux_for_Tegra/images clean
make O=…/Linux_for_Tegra/images mrproper

As part of my build process, based on some guide I found, I have always called “make mrproper” without knowing what it was for. I didn’t realise that this was a more advanced clean. Consequently this was having no effect and it probably didn’t matter because the kernel was still being built.

Thanks for your help.

Think of “clean” as removing generated content, although not the configuration. “mrproper” is what you would use before shipping the source to avoid your own customizations from being mixed in; it is indeed a “more advanced clean”, and removes configuration as well. Both delete generated content (to different degrees) in the “O=/somewhere” location (or in the actual source if not using “O=/somewhere”).

There are many image types which can be generated, and pretty much all of them generate a non-compressed file first, followed by any compressed type. Although you could create a zImage, which also gets the Image, it is wasted time and disk space since zImage is not used with the 64-bit builds (I think historically this is due to much of the boot chain still being 32-bit, and there was no guarantee that decompression of a 64-bit file in a 32-bit environment would succeed without truncation). You are correct though that it isn’t a problem, but it is less efficient.

Yes, if “=y” is selected, then the content is always there in the Image file. There is no possibility of unload or load. With “=m”, then the module must be loaded, and if not in use, can be unloaded. Keep in mind though that if you edit this directly in the file, without an editor that has an understanding of Kconfig dependencies, that you are likely to completely break things. “make menuconfig” or “make nconfig” are editors which understand Kconfig, and if you are not allowed “=y” or not allowed “=m”, then it is because the code was not included for that format to work. Not everything can be integrated (“=y”), and not everything can be modular (“=m”); it depends on the code.

When you remove a feature which is “=y” (integrated), then I very highly recommend rebuilding all modules. In the case of a feature being added with “=y”, I still recommend rebuilding the whole Image and modules, although it might work without this. In your case the addition of an “=y” is removing a feature…this “=y” “enables disable of feature”. So I recommend building both the Image and the modules for that change. If at some later time in the future you were to add or remove a module, then you probably would not need to rebuild the Image.

Incidentally, on a running Jetson, you will see a reflection of the build options for the kernel at:
/proc/config.gz

This is actually a driver looking like a file in RAM. On a default Jetson, as it ships, a copy of this file which is then uncompressed (gunzip), that config should match the “tegra_defconfig” target. However, if you are working on a Jetson which has been modified, and you are uncertain about its configuration, then you could use that as a starting point (mrproper followed by copy, decompress, and rename to .config of “/proc/config.gz”) instead of target “tegra_defconfig”.

1 Like