diff options
| author | Sam Ravnborg <sam@mars.ravnborg.org> | 2006-01-28 16:15:55 -0500 |
|---|---|---|
| committer | Sam Ravnborg <sam@mars.ravnborg.org> | 2006-02-19 03:51:18 -0500 |
| commit | 040fcc819a2e7783a570f4bdcdd1f2a7f5f06837 (patch) | |
| tree | 58a6cb2e7394c589c8ef49b308512c83af0c7087 | |
| parent | 5c3ead8c72788d36d34c9f1689fb529d1339b405 (diff) | |
kbuild: improved modversioning support for external modules
With following patch a second option is enabled to obtain
symbol information from a second external module when a
external module is build.
The recommended approach is to use a common kbuild file but
that may be impractical in certain cases.
With this patch one can copy over a Module.symvers from one
external module to make symbols (and symbol versions) available
for another external module.
Updated documentation in Documentation/kbuild/modules.txt
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
| -rw-r--r-- | Documentation/kbuild/modules.txt | 87 | ||||
| -rw-r--r-- | scripts/Makefile.modpost | 7 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 123 |
3 files changed, 158 insertions, 59 deletions
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt index 87d858df4e34..fcccf2432f98 100644 --- a/Documentation/kbuild/modules.txt +++ b/Documentation/kbuild/modules.txt | |||
| @@ -23,7 +23,10 @@ In this document you will find information about: | |||
| 23 | === 6. Module installation | 23 | === 6. Module installation |
| 24 | --- 6.1 INSTALL_MOD_PATH | 24 | --- 6.1 INSTALL_MOD_PATH |
| 25 | --- 6.2 INSTALL_MOD_DIR | 25 | --- 6.2 INSTALL_MOD_DIR |
| 26 | === 7. Module versioning | 26 | === 7. Module versioning & Module.symvers |
| 27 | --- 7.1 Symbols fron the kernel (vmlinux + modules) | ||
| 28 | --- 7.2 Symbols and external modules | ||
| 29 | --- 7.3 Symbols from another external module | ||
| 27 | === 8. Tips & Tricks | 30 | === 8. Tips & Tricks |
| 28 | --- 8.1 Testing for CONFIG_FOO_BAR | 31 | --- 8.1 Testing for CONFIG_FOO_BAR |
| 29 | 32 | ||
| @@ -89,7 +92,8 @@ when building an external module. | |||
| 89 | make -C $KDIR M=$PWD modules_install | 92 | make -C $KDIR M=$PWD modules_install |
| 90 | Install the external module(s). | 93 | Install the external module(s). |
| 91 | Installation default is in /lib/modules/<kernel-version>/extra, | 94 | Installation default is in /lib/modules/<kernel-version>/extra, |
| 92 | but may be prefixed with INSTALL_MOD_PATH - see separate chapter. | 95 | but may be prefixed with INSTALL_MOD_PATH - see separate |
| 96 | chapter. | ||
| 93 | 97 | ||
| 94 | make -C $KDIR M=$PWD clean | 98 | make -C $KDIR M=$PWD clean |
| 95 | Remove all generated files for the module - the kernel | 99 | Remove all generated files for the module - the kernel |
| @@ -433,7 +437,7 @@ External modules are installed in the directory: | |||
| 433 | => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf | 437 | => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf |
| 434 | 438 | ||
| 435 | 439 | ||
| 436 | === 7. Module versioning | 440 | === 7. Module versioning & Module.symvers |
| 437 | 441 | ||
| 438 | Module versioning is enabled by the CONFIG_MODVERSIONS tag. | 442 | Module versioning is enabled by the CONFIG_MODVERSIONS tag. |
| 439 | 443 | ||
| @@ -443,11 +447,80 @@ when a module is loaded/used then the CRC values contained in the kernel are | |||
| 443 | compared with similar values in the module. If they are not equal then the | 447 | compared with similar values in the module. If they are not equal then the |
| 444 | kernel refuses to load the module. | 448 | kernel refuses to load the module. |
| 445 | 449 | ||
| 446 | During a kernel build a file named Module.symvers will be generated. This | 450 | Module.symvers contains a list of all exported symbols from a kernel build. |
| 447 | file includes the symbol version of all symbols within the kernel. If the | ||
| 448 | Module.symvers file is saved from the last full kernel compile one does not | ||
| 449 | have to do a full kernel compile to build a module version's compatible module. | ||
| 450 | 451 | ||
| 452 | --- 7.1 Symbols fron the kernel (vmlinux + modules) | ||
| 453 | |||
| 454 | During a kernel build a file named Module.symvers will be generated. | ||
| 455 | Module.symvers contains all exported symbols from the kernel and | ||
| 456 | compiled modules. For each symbols the corresponding CRC value | ||
| 457 | is stored too. | ||
| 458 | |||
| 459 | The syntax of the Module.symvers file is: | ||
| 460 | <CRC> <Symbol> <module> | ||
| 461 | Sample: | ||
| 462 | 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod | ||
| 463 | |||
| 464 | For a kernel build without CONFIG_MODVERSIONING enabled the crc | ||
| 465 | would read: 0x00000000 | ||
| 466 | |||
| 467 | Module.symvers serve two purposes. | ||
| 468 | 1) It list all exported symbols both from vmlinux and all modules | ||
| 469 | 2) It list CRC if CONFIG_MODVERSION is enabled | ||
| 470 | |||
| 471 | --- 7.2 Symbols and external modules | ||
| 472 | |||
| 473 | When building an external module the build system needs access to | ||
| 474 | the symbols from the kernel to check if all external symbols are | ||
| 475 | defined. This is done in the MODPOST step and to obtain all | ||
| 476 | symbols modpost reads Module.symvers from the kernel. | ||
| 477 | If a Module.symvers file is present in the directory where | ||
| 478 | the external module is being build this file will be read too. | ||
| 479 | During the MODPOST step a new Module.symvers file will be written | ||
| 480 | containing all exported symbols that was not defined in the kernel. | ||
| 481 | |||
| 482 | --- 7.3 Symbols from another external module | ||
| 483 | |||
| 484 | Sometimes one external module uses exported symbols from another | ||
| 485 | external module. Kbuild needs to have full knowledge on all symbols | ||
| 486 | to avoid spitting out warnings about undefined symbols. | ||
| 487 | Two solutions exist to let kbuild know all symbols of more than | ||
| 488 | one external module. | ||
| 489 | The method with a top-level kbuild file is recommended but may be | ||
| 490 | impractical in certain situations. | ||
| 491 | |||
| 492 | Use a top-level Kbuild file | ||
| 493 | If you have two modules: 'foo', 'bar' and 'foo' needs symbols | ||
| 494 | from 'bar' then one can use a common top-level kbuild file so | ||
| 495 | both modules are compiled in same build. | ||
| 496 | |||
| 497 | Consider following directory layout: | ||
| 498 | ./foo/ <= contains the foo module | ||
| 499 | ./bar/ <= contains the bar module | ||
| 500 | The top-level Kbuild file would then look like: | ||
| 501 | |||
| 502 | #./Kbuild: (this file may also be named Makefile) | ||
| 503 | obj-y := foo/ bar/ | ||
| 504 | |||
| 505 | Executing: | ||
| 506 | make -C $KDIR M=`pwd` | ||
| 507 | |||
| 508 | will then do the expected and compile both modules with full | ||
| 509 | knowledge on symbols from both modules. | ||
| 510 | |||
| 511 | Use an extra Module.symvers file | ||
| 512 | When an external module is build a Module.symvers file is | ||
| 513 | generated containing all exported symbols which are not | ||
| 514 | defined in the kernel. | ||
| 515 | To get access to symbols from module 'bar' one can copy the | ||
| 516 | Module.symvers file from the compilation of the 'bar' module | ||
| 517 | to the directory where the 'foo' module is build. | ||
| 518 | During the module build kbuild will read the Module.symvers | ||
| 519 | file in the directory of the external module and when the | ||
| 520 | build is finished a new Module.symvers file is created | ||
| 521 | containing the sum of all symbols defined and not part of the | ||
| 522 | kernel. | ||
| 523 | |||
| 451 | === 8. Tips & Tricks | 524 | === 8. Tips & Tricks |
| 452 | 525 | ||
| 453 | --- 8.1 Testing for CONFIG_FOO_BAR | 526 | --- 8.1 Testing for CONFIG_FOO_BAR |
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index bf96a61d4b86..563e3c5bd8dd 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost | |||
| @@ -39,7 +39,8 @@ include .config | |||
| 39 | include scripts/Kbuild.include | 39 | include scripts/Kbuild.include |
| 40 | include scripts/Makefile.lib | 40 | include scripts/Makefile.lib |
| 41 | 41 | ||
| 42 | symverfile := $(objtree)/Module.symvers | 42 | kernelsymfile := $(objtree)/Module.symvers |
| 43 | modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers | ||
| 43 | 44 | ||
| 44 | # Step 1), find all modules listed in $(MODVERDIR)/ | 45 | # Step 1), find all modules listed in $(MODVERDIR)/ |
| 45 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) | 46 | __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) |
| @@ -54,7 +55,9 @@ quiet_cmd_modpost = MODPOST | |||
| 54 | cmd_modpost = scripts/mod/modpost \ | 55 | cmd_modpost = scripts/mod/modpost \ |
| 55 | $(if $(CONFIG_MODVERSIONS),-m) \ | 56 | $(if $(CONFIG_MODVERSIONS),-m) \ |
| 56 | $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ | 57 | $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ |
| 57 | $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ | 58 | $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ |
| 59 | $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ | ||
| 60 | $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ | ||
| 58 | $(filter-out FORCE,$^) | 61 | $(filter-out FORCE,$^) |
| 59 | 62 | ||
| 60 | .PHONY: __modpost | 63 | .PHONY: __modpost |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 4a2f2e38d27f..976adf152db3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -20,6 +20,8 @@ int modversions = 0; | |||
| 20 | int have_vmlinux = 0; | 20 | int have_vmlinux = 0; |
| 21 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ | 21 | /* Is CONFIG_MODULE_SRCVERSION_ALL set? */ |
| 22 | static int all_versions = 0; | 22 | static int all_versions = 0; |
| 23 | /* If we are modposting external module set to 1 */ | ||
| 24 | static int external_module = 0; | ||
| 23 | 25 | ||
| 24 | void fatal(const char *fmt, ...) | 26 | void fatal(const char *fmt, ...) |
| 25 | { | 27 | { |
| @@ -45,6 +47,18 @@ void warn(const char *fmt, ...) | |||
| 45 | va_end(arglist); | 47 | va_end(arglist); |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 50 | static int is_vmlinux(const char *modname) | ||
| 51 | { | ||
| 52 | const char *myname; | ||
| 53 | |||
| 54 | if ((myname = strrchr(modname, '/'))) | ||
| 55 | myname++; | ||
| 56 | else | ||
| 57 | myname = modname; | ||
| 58 | |||
| 59 | return strcmp(myname, "vmlinux") == 0; | ||
| 60 | } | ||
| 61 | |||
| 48 | void *do_nofail(void *ptr, const char *expr) | 62 | void *do_nofail(void *ptr, const char *expr) |
| 49 | { | 63 | { |
| 50 | if (!ptr) { | 64 | if (!ptr) { |
| @@ -100,6 +114,9 @@ struct symbol { | |||
| 100 | unsigned int crc; | 114 | unsigned int crc; |
| 101 | int crc_valid; | 115 | int crc_valid; |
| 102 | unsigned int weak:1; | 116 | unsigned int weak:1; |
| 117 | unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */ | ||
| 118 | unsigned int kernel:1; /* 1 if symbol is from kernel | ||
| 119 | * (only for external modules) **/ | ||
| 103 | char name[0]; | 120 | char name[0]; |
| 104 | }; | 121 | }; |
