moduleparam: Save information about built-in modules in separate file
authorAlexey Gladkov <gladkov.alexey@gmail.com>
Mon, 29 Apr 2019 16:11:14 +0000 (18:11 +0200)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Tue, 7 May 2019 12:50:24 +0000 (21:50 +0900)
Problem:

When a kernel module is compiled as a separate module, some important
information about the kernel module is available via .modinfo section of
the module.  In contrast, when the kernel module is compiled into the
kernel, that information is not available.

Information about built-in modules is necessary in the following cases:

1. When it is necessary to find out what additional parameters can be
passed to the kernel at boot time.

2. When you need to know which module names and their aliases are in
the kernel. This is very useful for creating an initrd image.

Proposal:

The proposed patch does not remove .modinfo section with module
information from the vmlinux at the build time and saves it into a
separate file after kernel linking. So, the kernel does not increase in
size and no additional information remains in it. Information is stored
in the same format as in the separate modules (null-terminated string
array). Because the .modinfo section is already exported with a separate
modules, we are not creating a new API.

It can be easily read in the userspace:

$ tr '\0' '\n' < modules.builtin.modinfo
ext4.softdep=pre: crc32c
ext4.license=GPL
ext4.description=Fourth Extended Filesystem
ext4.author=Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others
ext4.alias=fs-ext4
ext4.alias=ext3
ext4.alias=fs-ext3
ext4.alias=ext2
ext4.alias=fs-ext2
md_mod.alias=block-major-9-*
md_mod.alias=md
md_mod.description=MD RAID framework
md_mod.license=GPL
md_mod.parmtype=create_on_open:bool
md_mod.parmtype=start_dirty_degraded:int
...

Co-Developed-by: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
Signed-off-by: Gleb Fotengauer-Malinovskiy <glebfm@altlinux.org>
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com>
Acked-by: Jessica Yu <jeyu@kernel.org>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
.gitignore
Documentation/dontdiff
Documentation/kbuild/kbuild.txt
Makefile
include/asm-generic/vmlinux.lds.h
include/linux/module.h
include/linux/moduleparam.h
scripts/link-vmlinux.sh

index e7bb6c6edbae40a4ec883a004d3f15055ce64194..2fb1765c33b0a239250c9f7e140f293cbb2b7f40 100644 (file)
@@ -58,6 +58,7 @@ modules.builtin
 /vmlinuz
 /System.map
 /Module.markers
+/modules.builtin.modinfo
 
 #
 # RPM spec file (make rpm-pkg)
index ef25a066d9525a91456a9645ebf80a63f1c8a421..512fa0239ebf6be0e167a61579f225a1f7359048 100644 (file)
@@ -178,6 +178,7 @@ mktables
 mktree
 modpost
 modules.builtin
+modules.builtin.modinfo
 modules.order
 modversions.h*
 nconf
index 8a3830b39c7d488f736ad86d943425058d7b7199..9c230ea719634e762a230e1ab73bc4597d0d6a7a 100644 (file)
@@ -11,6 +11,11 @@ modules.builtin
 This file lists all modules that are built into the kernel. This is used
 by modprobe to not fail when trying to load something builtin.
 
+modules.builtin.modinfo
+--------------------------------------------------
+This file contains modinfo from all modules that are built into the kernel.
+Unlike modinfo of a separate module, all fields are prefixed with module name.
+
 
 Environment variables
 
index 85dd977f42324f5678ebc53b7ce50c8f850470a1..9a8b3f94633d7cfa3203d67f3686f6ab712ea633 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1308,6 +1308,7 @@ _modinst_:
        fi
        @cp -f $(objtree)/modules.order $(MODLIB)/
        @cp -f $(objtree)/modules.builtin $(MODLIB)/
+       @cp -f $(objtree)/modules.builtin.modinfo $(MODLIB)/
        $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
 
 # This depmod is only for convenience to give the initial
@@ -1348,6 +1349,7 @@ endif # CONFIG_MODULES
 
 # Directories & files removed with 'make clean'
 CLEAN_DIRS  += $(MODVERDIR) include/ksym
+CLEAN_FILES += modules.builtin.modinfo
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config usr/include include/generated          \
index f8f6f04c445379fbe9344931ce0fb0d2754c4442..bbb9e332f2fe6c4a0f7171e1549a3c0153db3150 100644 (file)
        EXIT_CALL                                                       \
        *(.discard)                                                     \
        *(.discard.*)                                                   \
+       *(.modinfo)                                                     \
        }
 
 /**
index 5bf5dcd91009eeac5f725ceb727f1f984e065458..5f7007430d35638c2872ffa103fc4be162446781 100644 (file)
@@ -253,6 +253,7 @@ extern typeof(name) __mod_##type##__##name##_device_table           \
 #define MODULE_VERSION(_version) MODULE_INFO(version, _version)
 #else
 #define MODULE_VERSION(_version)                                       \
+       MODULE_INFO(version, _version);                                 \
        static struct module_version_attribute ___modver_attr = {       \
                .mattr  = {                                             \
                        .attr   = {                                     \
index ba36506db4fb71f4b4297f81c1bcb893d30b8145..5ba250d9172ac93f470044383708d9c0235264c7 100644 (file)
    module name. */
 #ifdef MODULE
 #define MODULE_PARAM_PREFIX /* empty */
+#define __MODULE_INFO_PREFIX /* empty */
 #else
 #define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
+/* We cannot use MODULE_PARAM_PREFIX because some modules override it. */
+#define __MODULE_INFO_PREFIX KBUILD_MODNAME "."
 #endif
 
 /* Chosen so that structs with an unsigned long line up. */
 #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
 
-#ifdef MODULE
 #define __MODULE_INFO(tag, name, info)                                   \
 static const char __UNIQUE_ID(name)[]                                    \
   __used __attribute__((section(".modinfo"), unused, aligned(1)))        \
-  = __stringify(tag) "=" info
-#else  /* !MODULE */
-/* This struct is here for syntactic coherency, it is not used */
-#define __MODULE_INFO(tag, name, info)                                   \
-  struct __UNIQUE_ID(name) {}
-#endif
+  = __MODULE_INFO_PREFIX __stringify(tag) "=" info
+
 #define __MODULE_PARM_TYPE(name, _type)                                          \
   __MODULE_INFO(parmtype, name##type, #name ":" _type)
 
index dc0e8c5a140239c6a3bb13ccfbca5ab522328a28..e4383e0f476eb826cfd287e29eb1c9d4e9541c54 100755 (executable)
@@ -193,6 +193,9 @@ modpost_link vmlinux.o
 # modpost vmlinux.o to check for section mismatches
 ${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
 
+info MODINFO modules.builtin.modinfo
+${OBJCOPY} -j .modinfo -O binary vmlinux.o modules.builtin.modinfo
+
 kallsymso=""
 kallsyms_vmlinux=""
 if [ -n "${CONFIG_KALLSYMS}" ]; then