diff -Naur busybox.orig/examples/depmod busybox/examples/depmod
--- busybox.orig/examples/depmod	2008-05-28 21:53:36 +0000
+++ busybox/examples/depmod	2008-05-28 21:59:30 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Simple depmod, use to generate modprobe.conf
+# Simple depmod, use to generate modules.dep
 #
 # Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
 #
diff -Naur busybox.orig/modutils/Config.in busybox/modutils/Config.in
--- busybox.orig/modutils/Config.in	2008-05-27 22:37:51 +0000
+++ busybox/modutils/Config.in	2008-05-28 22:18:50 +0000
@@ -11,6 +11,14 @@
 	help
 	  depmod generates modules.dep (FIXME: elaborate)
 
+config FEATURE_DEPMOD_DONT_APPEND_UNAME_R
+	bool "Do not append kernel version to modules directory"
+	default n
+	depends on DEPMOD
+	help
+	  By default depmod looks modules at /lib/modules/<kernel-version> directory.
+	  When this option is enabled <kernel-version> is not appended, making depmod more configurable.
+
 config INSMOD
 	bool "insmod"
 	default n
diff -Naur busybox.orig/modutils/depmod.c busybox/modutils/depmod.c
--- busybox.orig/modutils/depmod.c	2008-05-28 21:55:14 +0000
+++ busybox/modutils/depmod.c	2008-06-01 16:53:39 +0000
@@ -1,7 +1,9 @@
 /* vi: set sw=4 ts=4: */
 /*
  * depmod - generate modules.dep
- * Copyright (c) 2008 Bernhard Fischer
+ * Copyright (c) 2008 Bernhard Fischer and Vladimir Dronnikov
+ *
+ * Dependencies resolution support by Vladimir Dronnikov <dronnikov@gmail.com>.
  *
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
@@ -11,43 +13,53 @@
 #include <libbb.h>
 #include <sys/utsname.h> /* uname() */
 
-/*
- * 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
- */
+struct module_dep {
+	struct module_dep *link;
+	char *path;
+	char *name;
+	llist_t *dep;
+};
+
 struct globals {
-	llist_t *lst; /* modules without their corresponding extension */
-	size_t moddir_base_len; /* length of the "-b basedir" */
+	struct module_dep *deps; // modules dependencies
 };
 #define G (*(struct globals*)&bb_common_bufsiz1)
 /* We have to zero it out because of NOEXEC */
 #define INIT_G() memset(&G, 0, sizeof(G))
 
-static int fill_lst(const char *modulename, struct stat ATTRIBUTE_UNUSED *sb,
-					void ATTRIBUTE_UNUSED *data, int ATTRIBUTE_UNUSED depth)
-{
-	/* We get a file here. If the file does not have ".ko" but an
-	 * intermittent dentry has, it's just their fault.
-	 */
-	if (strrstr(modulename, ".ko") != NULL)
-		llist_add_to(&G.lst, xstrdup(modulename + G.moddir_base_len));
-	return TRUE;
-}
+/*
+ * Theory of operation:
+ * - iterate over all modules {
+ *	record full path and basename
+ * 	collect "depends=" entries
+ * }
+ * - iterate over all modules {
+ *	resolve implict dependencies: i.e. if A depends on B and B depends on C then A depends on C and B!
+ * }
+ * - iterate over all modules {
+ *	dump full paths for dependencies
+ * }
+ */
 
 static int fileAction(const char *fname, struct stat *sb,
-					void *data, int ATTRIBUTE_UNUSED depth)
+					void ATTRIBUTE_UNUSED *data, int ATTRIBUTE_UNUSED depth)
 {
 	size_t len = sb->st_size;
 	void *the_module;
 	char *ptr;
 	int fd;
-	char *depends, *deps;
+	struct module_dep *dep;
 
 	if (strrstr(fname, ".ko") == NULL) /* not a module */
 		goto skip;
 
+	dep = xzalloc(sizeof(struct module_dep));
+	dep->path = xstrdup(fname);
+	ptr = dep->name = (char *)basename(dep->path);
+	ptr[strlen(ptr)-sizeof(".ko")+1] = '\0';
+	dep->link = G.deps;
+	G.deps = dep;
+
 /*XXX: FIXME: does not handle compressed modules!
  * There should be a function that looks at the extension and sets up
  * open_transformer for us.
@@ -63,52 +75,55 @@
 		bb_perror_msg_and_die("mmap");
 
 	ptr = the_module;
-
-	fprintf((FILE*)data, "%s:", fname + G.moddir_base_len);
-//bb_info_msg("fname='%s'", fname + G.moddir_base_len);
 	do {
 		/* search for a 'd' */
 		ptr = memchr(ptr, 'd', len - (ptr - (char*)the_module));
 		if (ptr == NULL) /* no d left, done */
-			goto none;
+			break;
 		if (strncmp(ptr, "depends=", sizeof("depends=")-1) == 0)
 			break;
 		++ptr;
 	} while (1);
-	deps = depends = xstrdup (ptr + sizeof("depends=")-1);
-//bb_info_msg(" depends='%s'", depends);
-	while (deps) {
-		llist_t * _lst = G.lst;
-
-		ptr = strsep(&deps, ",");
-		while (_lst) {
-			/* Compare the recorded filenames ignoring ".ko*" at the end.  */
-			char *tmp = bb_get_last_path_component_nostrip(_lst->data);
-			if (strncmp(ptr, tmp, strrstr(tmp, ".ko") - tmp) == 0)
-				break; /* found it */
-			_lst = _lst->link;
-		}
-		if (_lst) {
-//bb_info_msg("[%s] -> '%s'", (char*)ptr, _lst->data);
-			fprintf((FILE*)data, " %s", _lst->data);
+	// collect dependencies module names
+	if (ptr && ptr[sizeof("depends=")-1]) {
+		char *s = xstrdup(ptr + sizeof("depends=")-1);
+		while (s) {
+			ptr = strsep(&s, ",");
+			llist_add_to_end(&G.deps->dep, ptr);
 		}
-		// DVV N.B. despite anything, get next dependency, plz.
-		deps += len; // DVV N.B. this line being within the above if(){} causes endless loop if dependency is not "verified".
 	}
-	free(depends);
-	fprintf((FILE*)data, "\n");
- none:
+
 	munmap(the_module, sb->st_size);
  skip:
 	return TRUE;
 }
 
+static void print_deps(FILE *filedes, llist_t *d, llist_t **seen)
+{
+#define D ((struct module_dep *)(d->data))
+	while (d) {
+		llist_t *l;
+		print_deps(filedes, D->dep, seen);
+		for (l = *seen; l; l = l->link) {
+			if (0 == strcmp(l->data, D->name))
+				break;
+		}
+		if (!l) {
+			llist_add_to(seen, (void *)(D->name));
+			fprintf(filedes, " %s.%s", D->path, D->name + strlen(D->name) + 1);
+//			fprintf(filedes, " %s", D->name);
+		}
+		d = d->link;
+	}
+}
+
 int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int depmod_main(int ATTRIBUTE_UNUSED argc, char **argv)
 {
 	int ret;
-	char *moddir_base = NULL, *moddir, *system_map, *chp;
+	char *moddir = (char *)CONFIG_DEFAULT_MODULES_DIR, *system_map;
 	FILE *filedes = stdout;
+	struct module_dep *d;
 	enum {
 		ARG_a = (1<<0), /* All modules, ignore mods in argv */
 		ARG_A = (1<<1), /* Only emit .ko that are newer than modules.dep file */
@@ -118,66 +133,71 @@
 		ARG_n = (1<<5)  /* dry-run, print to stdout only */
 	};
 
-	getopt32(argv, "aAb:eF:n", &moddir_base, &system_map);
+	getopt32(argv, "aAb:eF:n", &moddir, &system_map);
 	argv += optind;
 
+	// goto moddir
+	xchdir(moddir);
+
 	/* got a version to use? */
 	if (*argv && (sscanf(*argv, "%d.%d.%d", &ret, &ret, &ret) == 3)) {
-		moddir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, *argv++);
-	} else {
+		xchdir(*argv++);
+	} else if (!ENABLE_FEATURE_DEPMOD_DONT_APPEND_UNAME_R) {
 		struct utsname uts;
 		if (uname(&uts) < 0)
 			bb_simple_perror_msg_and_die("uname");
-		moddir = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, uts.release);
+		xchdir(uts.release);
 	}
 	/* If no modules are given on the command-line, -a is on per default.  */
 	option_mask32 |= *argv == NULL;
 
-	if (option_mask32 & ARG_b) {
-		G.moddir_base_len = strlen(moddir_base);
-		if (ENABLE_FEATURE_CLEAN_UP) {
-			chp = moddir;
-			moddir = concat_path_file(moddir_base, moddir);
-			free (chp);
-		} else
-			moddir = concat_path_file(moddir_base, moddir);
-	}
-
 	if (!(option_mask32 & ARG_n)) { /* --dry-run */
-		chp = concat_path_file(moddir, CONFIG_DEFAULT_DEPMOD_FILE);
-		filedes = xfopen(chp, "w");
-		if (ENABLE_FEATURE_CLEAN_UP)
-			free(chp);
+		filedes = xfopen(CONFIG_DEFAULT_DEPMOD_FILE, "w");
 	}
+
+	// collect explicit dependencies
 	ret = EXIT_SUCCESS;
-	/* We have to do a full walk to collect all needed data.  */
-	if (!recursive_action(moddir,
-			ACTION_RECURSE, /* flags */
-			fill_lst, /* file action */
-			NULL, /* dir action */
-			NULL, /* user data */
-			0)) { /* depth */
-		if (ENABLE_FEATURE_CLEAN_UP)
-			ret = EXIT_FAILURE;
-		else
-			return EXIT_FAILURE;
-	}
 	do {
-		chp = option_mask32 & ARG_a ? moddir : *argv++;
-		if (!recursive_action(chp,
+		char *cwd = xrealloc_getcwd_or_warn(NULL);
+		if (!(option_mask32 & ARG_a))
+			cwd = concat_path_file(cwd, *argv++);
+		if (!recursive_action(cwd,
 				ACTION_RECURSE, /* flags */
 				fileAction, /* file action */
 				NULL, /* dir action */
-				(void*)filedes, /* user data */
+				NULL, /* user data */
 				0)) { /* depth */
 			ret = EXIT_FAILURE;
 		}
 	} while (!(option_mask32 & ARG_a) && *argv);
 
+	// now we've collected all deps -> resolve implicit deps
+	for (d = G.deps; d; d = d->link) {
+		llist_t *m;
+		for (m = d->dep; m; m = m->link) {
+			struct module_dep *r;
+			for (r = G.deps; r; r = r->link) {
+				// find dep chain by name
+				if (0 == strcmp(r->name, m->data)) {
+					// found! replace name with chain
+					m->data = (void *)r;
+					break;
+				}
+			}
+		}
+	}
+
+	// output dependencies in modules.dep format
+	for (d = G.deps; d; d = d->link) {
+		llist_t *seen = NULL;
+		fprintf(filedes, "%s.%s:", d->path, d->name + strlen(d->name) + 1);
+//		fprintf(filedes, "%s:", d->name);
+		print_deps(filedes, d->dep, &seen);
+		fprintf(filedes, "\n");
+	}
+
 	if (ENABLE_FEATURE_CLEAN_UP) {
 		fclose_if_not_stdin(filedes);
-		llist_free(G.lst, free);
-		free(moddir);
 	}
 	return ret;
 }
