diff --git a/modutils/Config.src b/modutils/Config.src
index 9b76c83..c7579c5 100644
--- a/modutils/Config.src
+++ b/modutils/Config.src
@@ -166,7 +166,7 @@ config FEATURE_MODUTILS_SYMBOLS
 config DEFAULT_MODULES_DIR
 	string "Default directory containing modules"
 	default "/lib/modules"
-	depends on DEPMOD || MODPROBE || MODINFO
+	depends on DEPMOD || MODPROBE || MODINFO || INSMOD
 	help
 	Directory that contains kernel modules.
 	Defaults to "/lib/modules"
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 8526979..d36acc4 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -45,11 +45,42 @@
 //usage:	)
 //usage:#endif
 
+#include <sys/utsname.h>
+static char *m_filename;
+static char *m_fullName;
+
+static int FAST_FUNC check_module_name_match(const char *filename,
+		struct stat *statbuf UNUSED_PARAM,
+		void *userdata, int depth UNUSED_PARAM)
+{
+	char *fullname = (char *) userdata;
+	char *tmp;
+
+	if (fullname[0] == '\0')
+		return FALSE;
+
+	tmp = bb_get_last_path_component_nostrip(filename);
+	if (strcmp(tmp, fullname) == 0) {
+		/* Stop searching if we find a match */
+		m_filename = xstrdup(filename);
+		return FALSE;
+	}
+	return TRUE;
+}
+
 int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int insmod_main(int argc UNUSED_PARAM, char **argv)
 {
 	char *filename;
 	int rc;
+int len;
+char *tmp;
+char *tmp2;
+int k_version = 0;
+struct stat st;
+struct utsname uts;
+char *m_name;
+FILE *fp;
 
 	/* Compat note:
 	 * 2.6 style insmod has no options and required filename
@@ -68,9 +99,99 @@ int insmod_main(int argc UNUSED_PARAM, char **argv)
 	if (!filename)
 		bb_show_usage();
 
-	rc = bb_init_module(filename, parse_cmdline_module_options(argv, /*quote_spaces:*/ 0));
+	/* Grab the module name */
+	tmp = xstrdup(filename);
+	len = strlen(filename);
+
+	if (uname(&uts) == 0) {
+		if (uts.release[0] == '2') {
+			k_version = uts.release[2] - '0';
+		}
+	}
+
+	if (k_version > 4 && len > 3 && tmp[len - 3] == '.'
+	 && tmp[len - 2] == 'k' && tmp[len - 1] == 'o'
+	) {
+		len -= 3;
+		tmp[len] = '\0';
+	} else
+		if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') {
+			len -= 2;
+			tmp[len] = '\0';
+		}
+
+	if (k_version > 4)
+		m_fullName = xasprintf("%s.ko", tmp);
+	else
+		m_fullName = xasprintf("%s.o", tmp);
+
+	if (!m_name) {
+		m_name = tmp;
+	}
+	free(tmp);
+
+	/* first look in /var/lib/modules */
+	tmp2 = alloca(strlen(m_fullName) + sizeof("/var/lib/modules/"));
+	strcpy(tmp2, "/var/lib/modules/");
+	strcat(tmp2, m_fullName);
+	if (stat(tmp2, &st) >= 0 && S_ISREG(st.st_mode) && (fp = fopen(tmp2, "r")) != NULL) {
+		m_filename = xstrdup(tmp2);
+		printf("insmod: preferring module %s\n", m_filename);
+	} else
+	/* Get a filedesc for the module.  Check that we have a complete path */
+	if (stat(filename, &st) < 0 || !S_ISREG(st.st_mode)
+	 || (fp = fopen_for_read(filename)) == NULL
+	) {
+		/* Hmm.  Could not open it.  First search under /lib/modules/`uname -r`,
+		 * but do not error out yet if we fail to find it... */
+		if (k_version) {	/* uname succeedd */
+			char *module_dir;
+			char *tmdn;
+
+			tmdn = concat_path_file(CONFIG_DEFAULT_MODULES_DIR, uts.release);
+			/* Jump through hoops in case /lib/modules/`uname -r`
+			 * is a symlink.  We do not want recursive_action to
+			 * follow symlinks, but we do want to follow the
+			 * /lib/modules/`uname -r` dir, So resolve it ourselves
+			 * if it is a link... */
+			module_dir = xmalloc_readlink(tmdn);
+			if (!module_dir)
+				module_dir = xstrdup(tmdn);
+			recursive_action(module_dir, ACTION_RECURSE,
+					check_module_name_match, NULL, m_fullName, 0);
+			free(module_dir);
+			free(tmdn);
+		}
+
+		/* Check if we have found anything yet */
+		if (!m_filename || ((fp = fopen_for_read(m_filename)) == NULL)) {
+			int r;
+			char *module_dir;
+
+			free(m_filename);
+			m_filename = NULL;
+			module_dir = xmalloc_readlink(CONFIG_DEFAULT_MODULES_DIR);
+			if (!module_dir)
+				module_dir = xstrdup(CONFIG_DEFAULT_MODULES_DIR);
+			/* No module found under /lib/modules/`uname -r`, this
+			 * time cast the net a bit wider.  Search /lib/modules/ */
+			r = recursive_action(module_dir, ACTION_RECURSE,
+					check_module_name_match, NULL, m_fullName, 0);
+			if (r)
+				bb_error_msg_and_die("%s: module not found", m_fullName);
+			free(module_dir);
+			if (m_filename == NULL
+			 || ((fp = fopen_for_read(m_filename)) == NULL)
+			) {
+				bb_error_msg_and_die("%s: module not found", m_fullName);
+			}
+		}
+	} else 
+		m_filename = xstrdup(filename);
+
+	rc = bb_init_module(m_filename, parse_cmdline_module_options(argv, /*quote_spaces:*/ 0));
 	if (rc)
-		bb_error_msg("can't insert '%s': %s", filename, moderror(rc));
+		bb_error_msg("can't insert '%s': %s", m_filename, moderror(rc));
 
 	return rc;
 }