diff -Naur busybox.orig/include/applets.h busybox/include/applets.h
--- busybox.orig/include/applets.h	2008-06-02 19:30:56 +0000
+++ busybox/include/applets.h	2008-06-25 19:07:44 +0000
@@ -116,6 +116,7 @@
 USE_DELGROUP(APPLET_ODDNAME(delgroup, deluser, _BB_DIR_BIN, _BB_SUID_NEVER, delgroup))
 USE_DELUSER(APPLET(deluser, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_DEPMOD(APPLET(depmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_MODPROBE_NG(APPLET_ODDNAME(depmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe))
 USE_DEVFSD(APPLET(devfsd, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_DF(APPLET(df, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_APP_DHCPRELAY(APPLET(dhcprelay, _BB_DIR_USR_SBIN, _BB_SUID_NEVER))
@@ -188,6 +189,7 @@
 USE_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_INOTIFYD(APPLET(inotifyd, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_MODPROBE_NG(APPLET_ODDNAME(insmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe))
 USE_INSTALL(APPLET(install, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
 #if ENABLE_FEATURE_IP_ADDRESS \
  || ENABLE_FEATURE_IP_ROUTE \
@@ -231,6 +233,7 @@
 USE_LS(APPLET_NOEXEC(ls, ls, _BB_DIR_BIN, _BB_SUID_NEVER, ls))
 USE_LSATTR(APPLET(lsattr, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_MODPROBE_NG(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe))
 USE_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat))
 USE_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER))
@@ -249,6 +252,7 @@
 USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_MODPROBE_NG(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER)))
 USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER))
@@ -293,6 +297,7 @@
 USE_RM(APPLET_NOFORK(rm, rm, _BB_DIR_BIN, _BB_SUID_NEVER, rm))
 USE_RMDIR(APPLET_NOFORK(rmdir, rmdir, _BB_DIR_BIN, _BB_SUID_NEVER, rmdir))
 USE_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_NEVER))
+USE_MODPROBE_NG(APPLET_ODDNAME(rmmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe))
 USE_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER))
 USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER))
 USE_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
diff -Naur busybox.orig/modutils/Config.in busybox/modutils/Config.in
--- busybox.orig/modutils/Config.in	2008-06-16 21:39:23 +0000
+++ busybox/modutils/Config.in	2008-06-25 19:07:44 +0000
@@ -5,9 +5,32 @@
 
 menu "Linux Module Utilities"
 
+config MODPROBE_NG
+	bool "Simplified modutils"
+	default n
+	help
+	  New format modutils. Compatible.
+
+config FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE
+	bool "module options on cmdline"
+	default n
+	depends on MODPROBE_NG
+	help
+	  Allow insmod and modprobe take module options from command line.
+	  N.B. Very bloaty.
+
+config FEATURE_MODPROBE_NG_CHECK_ALREADY_LOADED
+	bool "skip loading of already loaded modules"
+	default n
+	depends on MODPROBE_NG
+	help
+	  Check if the module is already loaded.
+	  N.B. Racy. Slow. Bloaty.
+
 config DEPMOD
 	bool "depmod"
 	default n
+	depends on !MODPROBE_NG
 	help
 	  depmod generates modules.dep (FIXME: elaborate)
 
@@ -38,6 +61,7 @@
 config INSMOD
 	bool "insmod"
 	default n
+	depends on !MODPROBE_NG
 	help
 	  insmod is used to load specified modules in the running kernel.
 
@@ -93,12 +117,14 @@
 config RMMOD
 	bool "rmmod"
 	default n
+	depends on !MODPROBE_NG
 	help
 	  rmmod is used to unload specified modules from the kernel.
 
 config LSMOD
 	bool "lsmod"
 	default n
+	depends on !MODPROBE_NG
 	help
 	  lsmod is used to display a list of loaded modules.
 
@@ -113,6 +139,7 @@
 config MODPROBE
 	bool "modprobe"
 	default n
+	depends on !MODPROBE_NG
 	help
 	  Handle the loading of modules, and their dependencies on a high
 	  level.
@@ -196,7 +223,7 @@
 	# Simulate indentation
 	string "Default directory containing modules"
 	default "/lib/modules"
-	depends on INSMOD || RMMOD || MODPROBE || DEPMOD
+	depends on INSMOD || RMMOD || MODPROBE || MODPROBE_NG || DEPMOD
 	help
 	  Directory that contains kernel modules.
 	  Defaults to "/lib/modules"
@@ -205,7 +232,7 @@
 	# Simulate indentation
 	string "Default name of modules.dep"
 	default "modules.dep"
-	depends on INSMOD || RMMOD || MODPROBE || DEPMOD
+	depends on INSMOD || RMMOD || MODPROBE || MODPROBE_NG || DEPMOD
 	help
 	  Filename that contains kernel modules dependencies.
 	  Defaults to "modules.dep"
diff -Naur busybox.orig/modutils/Kbuild busybox/modutils/Kbuild
--- busybox.orig/modutils/Kbuild	2008-05-26 21:53:59 +0000
+++ busybox/modutils/Kbuild	2008-06-25 19:07:44 +0000
@@ -9,4 +9,5 @@
 lib-$(CONFIG_INSMOD)		+= insmod.o
 lib-$(CONFIG_LSMOD)		+= lsmod.o
 lib-$(CONFIG_MODPROBE)		+= modprobe.o
+lib-$(CONFIG_MODPROBE_NG)	+= modprobe-ng.o
 lib-$(CONFIG_RMMOD)		+= rmmod.o
diff -Naur busybox.orig/modutils/modprobe-ng.c busybox/modutils/modprobe-ng.c
--- busybox.orig/modutils/modprobe-ng.c	1970-01-01 00:00:00 +0000
+++ busybox/modutils/modprobe-ng.c	2008-06-25 19:07:44 +0000
@@ -0,0 +1,513 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * simplified depmod & modprobe
+ *
+ * Copyright (c) 2008 Vladimir Dronnikov
+ * Copyright (c) 2008 Bernhard Fischer (initial depmod code)
+ *
+ * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ */
+
+/*
+	1. Format of modules.dep.bb (draft 2)
+
+	Each module definition consist of three lines of space-delimited
+	fields.
+
+	E.g.: consider a module named X is located at PATHX, depends 
+	on D1..DN, has aliases X1..XM and must be loaded with options O1..OQ.
+	We could write this definition down as follows:
+
+	---- CUT ----
+	X X1 X2 ... XN
+	D1 D2 ... DM
+	PATHX O1 O2 ... OQ
+	---- CUT ----
+
+	If any of parts of such a modules definition is missed
+	(e.g. there is no dependencies) we just use empty line for it.
+
+	PROS:
+	* Since the definitions are uniform and has fixed format
+	such a file is parsed trivially, fast and cleanly. No internal linked
+	lists (which are of order of magnitude as large as modules.dep itself)
+	are required to handle dependencies.
+
+	* Only explicit dependencies oughta be written; the parsing engine is
+	guaranteed to expand all implicit dependencies automagically.
+	This simplifies depmod dramatically.
+
+	* The third line is out-of-box ready to be passed to insmod.
+
+	* Extensions to such a format can be done trivially: just append new
+	lines of data to each module definition.
+
+	* The module definitions are all collected in one place in a
+	human-friendly format: what is the name of module, what it requires
+	to be loaded, and how we want it to be loaded.
+
+	2. IMPORTANT!
+
+	In order to parse modules.dep.bb faster we append an extra space
+	to every line and extra EOL after the last line. This allows to convert
+	to set of lines with cheap replace(where, what, with) string operation.
+*/
+
+#include "libbb.h"
+#include <sys/utsname.h> /* uname() */
+#include <fnmatch.h>
+
+extern int init_module(void *module, unsigned long len, const char *options);
+extern int delete_module(const char *module, unsigned int flags);
+extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
+
+#define DEPMOD_FILE CONFIG_DEFAULT_DEPMOD_FILE ".bb"
+
+enum {
+	OPT_q = (1<<0), /* be quiet */
+	OPT_r = (1<<1), /* set removal instead of loading */
+	OPT_b = (1<<2), /* set base directory */
+};
+
+/*
+ * Theory of operation:
+ * - iterate over all modules and record their full path
+ * - iterate over all modules looking for "depends=" entries
+ *   for each depends, look through our list of full paths and emit if found
+ */
+
+static char* find_keyword(void *the_module, size_t len, const char *word)
+{
+	char *ptr = the_module;
+	int wlen = strlen(word);
+	while (1) {
+		/* search for the first char in word */
+		ptr = memchr(ptr, *word, len - (ptr - (char*)the_module));
+		if (ptr == NULL) /* no occurance left, done */
+			return NULL;
+		if (!strncmp(ptr, word, wlen)) {
+			ptr += wlen;
+			break;
+		}
+		++ptr;
+	}
+	return ptr;
+}
+
+static void replace(char *s, char what, char with)
+{
+	while (*s) {
+		if (what == *s)
+			*s = with;
+		++s;
+	}
+}
+
+static int fileAction(const char *fname, struct stat *sb,
+	void *fp, int ATTRIBUTE_UNUSED depth)
+{
+	size_t len = sb->st_size;
+	void *module_image;
+	char *ptr;
+	int fd;
+	size_t pos;
+
+	char *name;
+
+	if (strrstr(fname, ".ko") == NULL) /* not a module */
+		goto skip;
+
+/*XXX: FIXME: does not handle compressed modules!
+ * There should be a function that looks at the extension and sets up
+ * open_transformer for us.
+ */
+	fd = xopen(fname, O_RDONLY);
+	module_image = mmap(NULL, len, PROT_READ, MAP_SHARED
+#if defined MAP_POPULATE
+						|MAP_POPULATE
+#endif
+						, fd, 0);
+	close(fd);
+	if (module_image == MAP_FAILED)
+		bb_perror_msg_and_die("mmap");
+
+	name = xstrdup(bb_get_last_path_component_nostrip(fname));
+	ptr = strrstr(name, ".ko");
+	*ptr = '\0';
+	replace(name, '-', '_');
+
+	// module name ...
+	fprintf(fp, "%s ", name);
+
+	// ... and aliases
+	pos = 0;
+	do {
+		ptr = find_keyword(module_image + pos, len - pos, "alias=");
+		if (!ptr)
+			ptr = find_keyword(module_image + pos, len - pos, "__ksymtab_");
+		if (ptr) {
+			// FIXME: __ksymtab_gpl and __ksymtab_strings occur in many modules.
+			// What do they mean?!
+			fprintf(fp, "%s%s ", (('_' == ptr[-1]) ? "symbol:" : ""), ptr);
+		} else
+			break;
+		pos = (ptr - (char*)module_image);
+	} while (1);
+	fputc('\n', fp);
+
+	// dependencies
+	ptr = find_keyword(module_image, len, "depends=");
+	if (*ptr) {
+		char *depends = xstrdup(ptr);
+		replace(depends, ',', ' ');
+		replace(depends, '-', '_');
+		fprintf(fp, "%s", depends);
+		free(depends);
+	}
+	// filename and options
+	fprintf(fp, " \n%s %s\n", fname+2, ""); // +2 to skip "./"
+
+	free(name);
+
+	munmap(module_image, sb->st_size);
+ skip:
+	return TRUE;
+}
+
+#if ENABLE_FEATURE_MODPROBE_NG_CHECK_ALREADY_LOADED
+
+//
+// do not try to load module which is already loaded
+//
+
+// 2.4 kernels only
+static int already_loaded_24(const char *name)
+{
+	struct module_info {
+		unsigned long addr;
+		unsigned long size;
+		unsigned long flags;
+		long usecount;
+	} info;
+	size_t dummy;
+	return !query_module(name, 5 /*QM_INFO*/, &info, sizeof(info), &dummy);
+}
+
+// 2.6 kernels only
+static int already_loaded_26(const char *name)
+{
+	char *fname = xasprintf("/sys/module/%s", name);
+	struct stat st;
+	int ret = !lstat(fname, &st);
+	free(fname);
+	return ret;
+}
+
+// any kernel but works iff `wc /proc/modules` < 1024
+static int already_loaded_1024(const char *name)
+{
+	int ret = 0;
+	int len = strlen(name);
+
+	char *modules = xmalloc_open_read_close("/proc/modules", NULL);
+	if (modules) {
+		for (char *s = modules; (s = strstr(s, name)); s += len) {
+			if (' ' == s[len] && (s == s || '\n' == s[-1])) {
+				++ret;
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+// any kernel but assuming `wc /proc/modules` < BB_COMMON_BUFSIZ
+// N.B. So what?! We do not fail on false positive/negative.
+// So let it be heuristics!
+static int already_loaded_4096(const char *name)
+{
+
+// FIXME: overflow?
+#define modules bb_common_bufsiz1
+
+	int ret = 0;
+	int len = strlen(name);
+	// N.B. can't use mmap or xmalloc_open_read_close()! They report wrong file length on mem-backed /proc/modules!!!
+	if (open_read_close("/proc/modules", modules, sizeof(modules)) >= 0) {
+		for (char *s = modules; (s = strstr(s, name)); s += len) {
+			if (' ' == s[len] && (s == s || '\n' == s[-1])) {
+				++ret;
+				break;
+			}
+		}
+	}
+
+#undef modules
+
+	return ret;
+}
+
+// any kernel but bloaty
+static int already_loaded_0(const char *name)
+{
+	int ret = 0;
+	int len = strlen(name);
+
+	FILE *fp = fopen("/proc/modules", "r");
+	if (fp) {
+		char *s;
+		while ((s = xmalloc_fgets_str(fp, "\n"))) {
+			if (' ' == s[len] && 0 == strncmp(s, name, len)) {
+				free(s);
+				++ret;
+				break;
+			}
+			free(s);
+		}
+		fclose(fp);
+	}
+
+	return ret;
+}
+
+#define already_loaded already_loaded_26
+
+#else
+static int already_loaded(const char ATTRIBUTE_UNUSED *name)
+{
+	return 0;
+}
+#endif
+
+/* 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);
+	}
+}
+
+static void load_module(const char *fname, const char *options)
+{
+	size_t len = MAXINT(ssize_t);
+	char *module_image = xmalloc_open_read_close(fname, &len);
+
+	if ((!module_image || init_module(module_image, len, options) != 0) && EEXIST != errno)
+		bb_error_msg("insert '%s' %s: %s", fname, options, moderror(errno));
+
+	free(module_image);
+}
+
+/*
+ Given modules definition and module name (or alias, or symbol)
+ load/remove the module respecting dependencies
+*/
+
+#if !ENABLE_FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE
+#	define process_module(a,b,c) process_module(a,b)
+#endif
+
+static void process_module(char *modules_dep, char *name, const char *cmdline_options)
+//static void process_module(char *modules_dep, char *name
+//	USE_FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE(, const char *cmdline_options))
+{
+	// read definitions
+	char *ptr = modules_dep;
+	char *s, *deps;
+
+	replace(name, '-', '_');
+
+	// iterate thru definitions
+	while (*ptr) {
+		// matching substring exists?
+		deps = xstrdup(ptr);
+		replace(deps, ' ', '\0');
+		for (s = deps; *s; s += strlen(s)+1) {
+			if (!fnmatch(s, name, 0)) {
+				free(deps);
+				goto found;
+			}
+		}
+		free(deps);
+		// ... skip to next module definition
+		for (int i = 3; --i >= 0; )
+			ptr += strlen(ptr)+1;
+	}
+	// module matched?
+	if (*ptr) {
+ found:
+		// yes -> found module definition! replace possible aliased name with module general name
+		name = xstrdup(ptr);
+		*strchrnul(name, ' ') = '\0';
+
+		// on rmmod unload it by name
+		if (option_mask32 & OPT_r) {
+			if (delete_module(name, O_NONBLOCK|O_EXCL) && !(option_mask32 & OPT_q))
+				bb_perror_msg("remove '%s'", name);
+		}
+
+		// next line contains dependencies
+		ptr += strlen(ptr)+1;
+		// copy dependencies string
+		deps = xstrdup(ptr);
+		// transform it to string list
+		replace(deps, ' ', '\0');
+		// iterate thru dependencies, trying to load them
+		for (s = deps; *s; s += strlen(s)+1) {
+			//if (strcmp(name, s)) // N.B. Do loops ever exist?!
+				process_module(modules_dep, s, cmdline_options);
+		}
+		free(deps);
+
+		// next line contains full path and optionally :) options
+		ptr += strlen(ptr)+1;
+
+		// on insmod if module is not loaded -> load it by filename
+		if (!(option_mask32 & OPT_r) && !already_loaded(name)) {
+			// load it
+			char *options = strchrnul(ptr, ' ');
+			*options = '\0';
+#if ENABLE_FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE
+			if (cmdline_options) {
+				char *op = xasprintf("%s %s", cmdline_options, options+1);
+				load_module(ptr, op);
+				free(op);
+			} else
+#endif
+				load_module(ptr, options+1);
+			*options = ' ';
+		}
+
+		// cleanup
+		free(name);
+	}
+	// no module matched -> try to load module from specified filename
+	// N.B. this mimics insmod behaviour
+	else {
+#if ENABLE_FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE
+		load_module(name, cmdline_options);
+#else
+		load_module(name, "");
+#endif
+	}
+}
+
+int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int modprobe_main(int ATTRIBUTE_UNUSED argc, char **argv)
+{
+	int ret = EXIT_FAILURE;
+//	struct utsname uts;
+#define uts bb_common_bufsiz1
+	char *modules_dep = NULL;
+#define base_dir modules_dep
+
+	// lsmod called? ->
+	if ('l' == applet_name[0]) {
+		// just dump /proc/modules
+		xprint_and_close_file(xfopen("/proc/modules", "r"));
+		goto done;
+	}
+
+	// depmod doesn't require arguments
+	// insmod, modprobe, rmmod require at least one
+	if ('d' != applet_name[0])
+		opt_complementary = "-1";
+	// only -q (quiet) and -r (rmmod) and -b (base dir) do matter
+	getopt32(argv, "qrb:knsvaeF:", &base_dir, NULL);
+
+	// rmmod called? ->
+	if ('r' == applet_name[0]) {
+		// simulate call to modprobe -r $@
+		option_mask32 |= OPT_r;
+	}
+
+	// goto modules directory
+	base_dir = concat_path_file(base_dir, CONFIG_DEFAULT_MODULES_DIR);
+	xchdir(base_dir);
+	if (ENABLE_FEATURE_CLEAN_UP)
+		free(base_dir);
+	// depmod can take optional argument of specific kernel version
+	if ('d' == applet_name[0] && argv[optind]) {
+		xchdir(argv[optind]);
+	} else if ((uname((struct utsname *)uts) >= 0)) {
+		xchdir(((struct utsname *)uts)->release);
+	}
+
+	// if depmod called ->
+	if ('d' == applet_name[0]) {
+		// force recreating modules.dep.bb
+		unlink(DEPMOD_FILE);
+	}
+
+	// fetch definitions
+	modules_dep = xmalloc_open_read_close(DEPMOD_FILE, NULL);
+	// no modules.dep.bb (or renewal forced)? -> create it
+	if (!modules_dep) {
+		// depmod: dump modules definitions
+		// N.B. we have to use locking technique to cope race conditions
+		char *fname = xasprintf("%s.%06d", DEPMOD_FILE, getpid());
+		FILE *fp = fopen_or_warn(fname, "w");
+		if (fp && recursive_action(".", 
+			ACTION_RECURSE, /* flags */
+			fileAction, /* file action */
+			NULL, /* dir action */
+			fp, /* user data */
+			0) /* depth */
+		) {
+			fputc('\n', fp); // finalize definitions
+			fclose(fp);
+			xrename(fname, DEPMOD_FILE);
+			// depmod was called? -> we're done
+			if ('d' == applet_name[0])
+				return EXIT_SUCCESS;
+			// read definitions
+			modules_dep = xmalloc_xopen_read_close(DEPMOD_FILE, NULL);
+		}
+		if (ENABLE_FEATURE_CLEAN_UP)
+			free(fname);
+	}
+	if (modules_dep) {
+		char *options = NULL;
+		// convert to string list
+		replace(modules_dep, '\n', '\0');
+		// parse possible module options given on command line
+		argv += optind;
+		// N.B. rmmod can take multiple module names -- we should process them all.
+		// ins(mod)probe takes one module name, the rest of arguments are parameters
+		if (ENABLE_FEATURE_MODPROBE_NG_OPTIONS_ON_CMDLINE && *argv && argv[1] && !(option_mask32 & OPT_r)) {
+			char **arg = argv;
+			while (*++argv) {
+				// enclose options in quotes
+				char *s = options;
+				options = xasprintf("%s\"%s\" ", s ? s : "", *argv);
+				free(s);
+				*argv = NULL;
+			}
+			argv = arg;
+		}
+		// do load/remove modules
+		while (*argv) {
+			process_module(modules_dep, *argv++, options);
+		}
+		// cleanup
+		if (ENABLE_FEATURE_CLEAN_UP) {
+			free(modules_dep);
+			free(options);
+		}
+ done:
+		ret = EXIT_SUCCESS;
+	}
+
+	// TODO: more elaborate exitcode!
+	return ret;
+}
