Update modutils with 2.6 module support

This commit is contained in:
Eric Andersen 2003-12-11 01:42:13 +00:00
parent 37f4116ecb
commit e7047887b0
4 changed files with 140 additions and 38 deletions

View File

@ -252,8 +252,8 @@ CONFIG_USE_BB_PWD_GRP=y
CONFIG_MODUTILS_OBJ=y CONFIG_MODUTILS_OBJ=y
CONFIG_DEPMOD=y CONFIG_DEPMOD=y
CONFIG_INSMOD=y CONFIG_INSMOD=y
# CONFIG_FEATURE_OLD_MODULE_INTERFACE is not set # CONFIG_FEATURE_2_2_MODULES is not set
CONFIG_FEATURE_NEW_MODULE_INTERFACE=y CONFIG_FEATURE_2_4_MODULES=y
# #
# Support new (post 2.1) Linux kernels (Forced enabled) # Support new (post 2.1) Linux kernels (Forced enabled)

View File

@ -11,32 +11,31 @@ config CONFIG_INSMOD
help help
insmod is used to load specified modules in the running kernel. insmod is used to load specified modules in the running kernel.
config CONFIG_FEATURE_OLD_MODULE_INTERFACE config CONFIG_FEATURE_2_2_MODULES
bool " Support older (pre 2.1) Linux kernels" bool " Support older (pre 2.1) Linux kernels"
default n default n
depends on CONFIG_INSMOD depends on CONFIG_INSMOD
help help
Provide insmod support for older (pre 2.1) Linux kernels. Provide insmod support for older (pre 2.1) Linux kernels.
if CONFIG_INSMOD && !CONFIG_FEATURE_OLD_MODULE_INTERFACE config CONFIG_FEATURE_2_4_MODULES
config CONFIG_FEATURE_NEW_MODULE_INTERFACE bool " Support version 2.1.x to 2.4.x Linux kernels"
default y
comment " Support new (post 2.1) Linux kernels (Forced enabled)"
endif
if CONFIG_FEATURE_OLD_MODULE_INTERFACE
config CONFIG_FEATURE_NEW_MODULE_INTERFACE
bool " Support new (post 2.1) Linux kernels"
default y default y
depends on CONFIG_INSMOD depends on CONFIG_INSMOD
help help
Support module loading for newer (post 2.1) Linux kernels. Support module loading for newer (post 2.1) Linux kernels.
endif
config CONFIG_FEATURE_2_6_MODULES
bool " Support version 2.6.x Linux kernels"
default n
depends on CONFIG_INSMOD
help
Support module loading for newer (post 2.1) Linux kernels.
config CONFIG_FEATURE_INSMOD_VERSION_CHECKING config CONFIG_FEATURE_INSMOD_VERSION_CHECKING
bool " Module version checking" bool " Module version checking"
default n default n
depends on CONFIG_INSMOD depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES )
help help
Support checking of versions for modules. This is used to Support checking of versions for modules. This is used to
ensure that the kernel and module are made for each other. ensure that the kernel and module are made for each other.
@ -44,7 +43,7 @@ config CONFIG_FEATURE_INSMOD_VERSION_CHECKING
config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
bool " Add module symbols to kernel symbol table" bool " Add module symbols to kernel symbol table"
default n default n
depends on CONFIG_INSMOD depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES )
help help
By adding module symbols to the kernel symbol table, Oops messages By adding module symbols to the kernel symbol table, Oops messages
occuring within kernel modules can be properly debugged. By enabling occuring within kernel modules can be properly debugged. By enabling
@ -55,7 +54,7 @@ config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
config CONFIG_FEATURE_INSMOD_LOADINKMEM config CONFIG_FEATURE_INSMOD_LOADINKMEM
bool " In kernel memory optimization (uClinux only)" bool " In kernel memory optimization (uClinux only)"
default n default n
depends on CONFIG_INSMOD depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES )
help help
This is a special uClinux only memory optimization that lets insmod This is a special uClinux only memory optimization that lets insmod
load the specified kernel module directly into kernel space, reducing load the specified kernel module directly into kernel space, reducing
@ -65,7 +64,7 @@ config CONFIG_FEATURE_INSMOD_LOADINKMEM
config CONFIG_FEATURE_INSMOD_LOAD_MAP config CONFIG_FEATURE_INSMOD_LOAD_MAP
bool " Enable load map (-m) option" bool " Enable load map (-m) option"
default n default n
depends on CONFIG_INSMOD depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES )
help help
Enabling this, one would be able to get a load map Enabling this, one would be able to get a load map
output on stdout. This makes kernel module debugging output on stdout. This makes kernel module debugging
@ -79,9 +78,8 @@ config CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
depends on CONFIG_FEATURE_INSMOD_LOAD_MAP depends on CONFIG_FEATURE_INSMOD_LOAD_MAP
help help
Without this option, -m will only output section Without this option, -m will only output section
load map. load map. With this option, -m will also output
With this option, -m will also output symbols symbols load map.
load map.
config CONFIG_LSMOD config CONFIG_LSMOD
bool "lsmod" bool "lsmod"
@ -92,7 +90,7 @@ config CONFIG_LSMOD
config CONFIG_FEATURE_QUERY_MODULE_INTERFACE config CONFIG_FEATURE_QUERY_MODULE_INTERFACE
bool " Support lsmod query_module interface (add 638 bytes)" bool " Support lsmod query_module interface (add 638 bytes)"
default y default y
depends on CONFIG_LSMOD && CONFIG_FEATURE_NEW_MODULE_INTERFACE depends on CONFIG_LSMOD && ( CONFIG_FEATURE_2_4_MODULES || CONFIG_FEATURE_2_6_MODULES )
help help
This will provide some extra information about each module when This will provide some extra information about each module when
running lsmod. The fields provided are address, size, flags and running lsmod. The fields provided are address, size, flags and

View File

@ -80,8 +80,24 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include "busybox.h" #include "busybox.h"
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #if !defined(CONFIG_FEATURE_2_4_MODULES) && \
# undef CONFIG_FEATURE_OLD_MODULE_INTERFACE !defined(CONFIG_FEATURE_2_2_MODULES) && \
!defined(CONFIG_FEATURE_2_6_MODULES)
#define CONFIG_FEATURE_2_4_MODULES
#endif
#if !defined(CONFIG_FEATURE_2_4_MODULES) && !defined(CONFIG_FEATURE_2_2_MODULES)
#define insmod_ng_main insmod_main
#endif
#if defined(CONFIG_FEATURE_2_4_MODULES) || defined(CONFIG_FEATURE_2_2_MODULES)
#if defined(CONFIG_FEATURE_2_6_MODULES)
extern int insmod_ng_main( int argc, char **argv);
#endif
#ifdef CONFIG_FEATURE_2_4_MODULES
# undef CONFIG_FEATURE_2_2_MODULES
# define new_sys_init_module init_module # define new_sys_init_module init_module
#else #else
# define old_sys_init_module init_module # define old_sys_init_module init_module
@ -266,7 +282,7 @@
#ifndef MODUTILS_MODULE_H #ifndef MODUTILS_MODULE_H
static const int MODUTILS_MODULE_H = 1; static const int MODUTILS_MODULE_H = 1;
#ident "$Id: insmod.c,v 1.106 2003/12/04 15:02:57 mjn3 Exp $" #ident "$Id: insmod.c,v 1.107 2003/12/11 01:42:13 andersen Exp $"
/* This file contains the structures used by the 2.0 and 2.1 kernels. /* This file contains the structures used by the 2.0 and 2.1 kernels.
We do not use the kernel headers directly because we do not wish We do not use the kernel headers directly because we do not wish
@ -399,7 +415,7 @@ struct new_module
unsigned tgt_long persist_end; unsigned tgt_long persist_end;
unsigned tgt_long can_unload; unsigned tgt_long can_unload;
unsigned tgt_long runsize; unsigned tgt_long runsize;
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
const char *kallsyms_start; /* All symbols for kernel debugging */ const char *kallsyms_start; /* All symbols for kernel debugging */
const char *kallsyms_end; const char *kallsyms_end;
const char *archdata_start; /* arch specific data for module */ const char *archdata_start; /* arch specific data for module */
@ -487,7 +503,7 @@ int delete_module(const char *);
#ifndef MODUTILS_OBJ_H #ifndef MODUTILS_OBJ_H
static const int MODUTILS_OBJ_H = 1; static const int MODUTILS_OBJ_H = 1;
#ident "$Id: insmod.c,v 1.106 2003/12/04 15:02:57 mjn3 Exp $" #ident "$Id: insmod.c,v 1.107 2003/12/11 01:42:13 andersen Exp $"
/* The relocatable object is manipulated using elfin types. */ /* The relocatable object is manipulated using elfin types. */
@ -630,7 +646,7 @@ static void *obj_extend_section (struct obj_section *sec, unsigned long more);
static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
const char *string); const char *string);
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
struct obj_symbol *sym); struct obj_symbol *sym);
#endif #endif
@ -665,7 +681,7 @@ static void arch_create_got (struct obj_file *f);
static int obj_gpl_license(struct obj_file *f, const char **license); static int obj_gpl_license(struct obj_file *f, const char **license);
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
static int arch_init_module (struct obj_file *f, struct new_module *); static int arch_init_module (struct obj_file *f, struct new_module *);
#endif #endif
@ -1626,7 +1642,7 @@ static void arch_create_got(struct obj_file *f)
#endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */ #endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */
} }
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
static int arch_init_module(struct obj_file *f, struct new_module *mod) static int arch_init_module(struct obj_file *f, struct new_module *mod)
{ {
return 1; return 1;
@ -2224,7 +2240,7 @@ old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
#ifdef CONFIG_FEATURE_OLD_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_2_MODULES
/* Fetch all the symbols and divvy them up as appropriate for the modules. */ /* Fetch all the symbols and divvy them up as appropriate for the modules. */
@ -2434,7 +2450,7 @@ old_init_module(const char *m_name, struct obj_file *f,
#define old_create_mod_use_count(x) TRUE #define old_create_mod_use_count(x) TRUE
#define old_init_module(x, y, z) TRUE #define old_init_module(x, y, z) TRUE
#endif /* CONFIG_FEATURE_OLD_MODULE_INTERFACE */ #endif /* CONFIG_FEATURE_2_2_MODULES */
@ -2720,7 +2736,7 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN])
#endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
/* Fetch the loaded modules, and all currently exported symbols. */ /* Fetch the loaded modules, and all currently exported symbols. */
@ -3041,7 +3057,7 @@ new_init_module(const char *m_name, struct obj_file *f,
#define new_create_module_ksymtab(x) #define new_create_module_ksymtab(x)
#define query_module(v, w, x, y, z) -1 #define query_module(v, w, x, y, z) -1
#endif /* CONFIG_FEATURE_NEW_MODULE_INTERFACE */ #endif /* CONFIG_FEATURE_2_4_MODULES */
/*======================================================================*/ /*======================================================================*/
@ -3075,7 +3091,7 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
return 1; return 1;
} }
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
static int static int
obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
struct obj_symbol *sym) struct obj_symbol *sym)
@ -4161,7 +4177,7 @@ extern int insmod_main( int argc, char **argv)
printf("Using %s\n", m_filename); printf("Using %s\n", m_filename);
#ifdef CONFIG_FEATURE_REALLY_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_6_MODULES
if (create_module(NULL, 0) < 0 && errno == ENOSYS) { if (create_module(NULL, 0) < 0 && errno == ENOSYS) {
optind--; optind--;
argv[optind] = m_filename; argv[optind] = m_filename;
@ -4214,7 +4230,7 @@ extern int insmod_main( int argc, char **argv)
k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL); k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL);
if (k_new_syscalls) { if (k_new_syscalls) {
#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_4_MODULES
if (!new_get_kernel_symbols()) if (!new_get_kernel_symbols())
goto out; goto out;
k_crcs = new_is_kernel_checksummed(); k_crcs = new_is_kernel_checksummed();
@ -4223,7 +4239,7 @@ extern int insmod_main( int argc, char **argv)
goto out; goto out;
#endif #endif
} else { } else {
#ifdef CONFIG_FEATURE_OLD_MODULE_INTERFACE #ifdef CONFIG_FEATURE_2_2_MODULES
if (!old_get_kernel_symbols(m_name)) if (!old_get_kernel_symbols(m_name))
goto out; goto out;
k_crcs = old_is_kernel_checksummed(); k_crcs = old_is_kernel_checksummed();
@ -4345,3 +4361,82 @@ out:
#endif #endif
return(exit_status); return(exit_status);
} }
#endif
#ifdef CONFIG_FEATURE_2_6_MODULES
#include <sys/mman.h>
#include <asm/unistd.h>
#include <sys/syscall.h>
/* We use error numbers in a loose translation... */
static const char *moderror(int err)
{
switch (err) {
case ENOEXEC:
return "Invalid module format";
case ENOENT:
return "Unknown symbol in module";
case ESRCH:
return "Module has wrong symbol version";
case EINVAL:
return "Invalid parameters";
default:
return strerror(err);
}
}
extern int insmod_ng_main( int argc, char **argv)
{
int i;
int fd;
long int ret;
struct stat st;
unsigned long len;
void *map;
char *filename, *options = bb_xstrdup("");
filename = argv[1];
if (!filename) {
bb_show_usage();
return -1;
}
/* Rest is options */
for (i = 2; i < argc; i++) {
options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2);
/* Spaces handled by "" pairs, but no way of escaping quotes */
if (strchr(argv[i], ' ')) {
strcat(options, "\"");
strcat(options, argv[i]);
strcat(options, "\"");
} else {
strcat(options, argv[i]);
}
strcat(options, " ");
}
if ((fd = open(filename, O_RDONLY, 0)) < 0) {
bb_perror_msg_and_die("cannot open module `%s'", filename);
}
fstat(fd, &st);
len = st.st_size;
map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
bb_perror_msg_and_die("cannot mmap `%s'", filename);
}
ret = syscall(__NR_init_module, map, len, options);
if (ret != 0) {
bb_perror_msg_and_die("cannot insert `%s': %s (%li)",
filename, moderror(errno), ret);
}
return 0;
}
#endif

View File

@ -25,6 +25,8 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <getopt.h> #include <getopt.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include "busybox.h" #include "busybox.h"
extern int delete_module(const char * name); extern int delete_module(const char * name);
@ -37,10 +39,17 @@ extern int rmmod_main(int argc, char **argv)
size_t pnmod = -1; /* previous number of modules */ size_t pnmod = -1; /* previous number of modules */
void *buf; /* hold the module names which we ignore but must get */ void *buf; /* hold the module names which we ignore but must get */
size_t bufsize = 0; size_t bufsize = 0;
unsigned int flags = O_NONBLOCK|O_EXCL;
/* Parse command line. */ /* Parse command line. */
while ((n = getopt(argc, argv, "a")) != EOF) { while ((n = getopt(argc, argv, "a")) != EOF) {
switch (n) { switch (n) {
case 'w': // --wait
flags &= ~O_NONBLOCK;
break;
case 'f': // --force
flags |= O_TRUNC;
break;
case 'a': case 'a':
/* Unload _all_ unused modules via NULL delete_module() call */ /* Unload _all_ unused modules via NULL delete_module() call */
/* until the number of modules does not change */ /* until the number of modules does not change */
@ -67,7 +76,7 @@ extern int rmmod_main(int argc, char **argv)
bb_show_usage(); bb_show_usage();
for (n = optind; n < argc; n++) { for (n = optind; n < argc; n++) {
if (delete_module(argv[n]) < 0) { if (syscall(__NR_delete_module, argv[n], flags) < 0) {
bb_perror_msg("%s", argv[n]); bb_perror_msg("%s", argv[n]);
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
} }