2 * Common modutils related functions for busybox
4 * Copyright (C) 2008 by Timo Teras <timo.teras@iki.fi>
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
11 extern int init_module(void *module
, unsigned long len
, const char *options
);
12 extern int delete_module(const char *module
, unsigned int flags
);
14 # include <sys/syscall.h>
15 # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
16 # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
19 void FAST_FUNC
replace(char *s
, char what
, char with
)
28 char* FAST_FUNC
replace_underscores(char *s
)
34 int FAST_FUNC
string_to_llist(char *string
, llist_t
**llist
, const char *delim
)
39 while ((tok
= strsep(&string
, delim
)) != NULL
) {
42 llist_add_to_end(llist
, xstrdup(tok
));
48 char* FAST_FUNC
filename2modname(const char *filename
, char *modname
)
56 modname
= xmalloc(MODULE_NAME_LEN
);
57 from
= bb_get_last_path_component_nostrip(filename
);
58 for (i
= 0; i
< (MODULE_NAME_LEN
-1) && from
[i
] != '\0' && from
[i
] != '.'; i
++)
59 modname
[i
] = (from
[i
] == '-') ? '_' : from
[i
];
65 char* FAST_FUNC
parse_cmdline_module_options(char **argv
, int quote_spaces
)
78 options
= xrealloc(options
, optlen
+ 2 + strlen(var
) + 2);
80 val
= strchrnul(var
, '=');
83 * modprobe (module-init-tools version 3.11.1) compat:
85 * var="val with spaces", not "var=val with spaces"
86 * (note: var *name* is not checked for spaces!)
88 if (*val
) { /* has var=val format. skip '=' */
94 optlen
+= sprintf(options
+ optlen
, fmt
, (int)(val
- var
), var
, val
);
96 /* Remove trailing space. Disabled */
97 /* if (optlen != 0) options[optlen-1] = '\0'; */
101 #if ENABLE_FEATURE_INSMOD_TRY_MMAP
102 void* FAST_FUNC
try_to_mmap_module(const char *filename
, size_t *image_size_p
)
104 /* We have user reports of failure to load 3MB module
105 * on a 16MB RAM machine. Apparently even a transient
106 * memory spike to 6MB during module load
107 * is too big for that system. */
112 fd
= xopen(filename
, O_RDONLY
);
115 /* st.st_size is off_t, we can't just pass it to mmap */
116 if (st
.st_size
<= *image_size_p
) {
117 size_t image_size
= st
.st_size
;
118 image
= mmap(NULL
, image_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
119 if (image
== MAP_FAILED
) {
121 } else if (*(uint32_t*)image
!= SWAP_BE32(0x7f454C46)) {
122 /* No ELF signature. Compressed module? */
123 munmap(image
, image_size
);
126 /* Success. Report the size */
127 *image_size_p
= image_size
;
137 * -errno on open/read error,
138 * errno on init_module() error
140 int FAST_FUNC
bb_init_module(const char *filename
, const char *options
)
150 //TODO: audit bb_init_module_24 to match error code convention
151 #if ENABLE_FEATURE_2_4_MODULES
152 if (get_linux_version_code() < KERNEL_VERSION(2,6,0))
153 return bb_init_module_24(filename
, options
);
156 image_size
= INT_MAX
- 4095;
158 image
= try_to_mmap_module(filename
, &image_size
);
162 errno
= ENOMEM
; /* may be changed by e.g. open errors below */
163 image
= xmalloc_open_zipped_read_close(filename
, &image_size
);
169 init_module(image
, image_size
, options
);
172 munmap(image
, image_size
);
178 int FAST_FUNC
bb_delete_module(const char *module
, unsigned int flags
)
181 delete_module(module
, flags
);
185 const char* FAST_FUNC
moderror(int err
)
188 case -1: /* btw: it's -EPERM */
189 return "no such module";
191 return "invalid module format";
193 return "unknown symbol in module, or unknown parameter";
195 return "module has wrong symbol version";
197 return "kernel does not support requested operation";
199 if (err
< 0) /* should always be */
201 return strerror(err
);