diff --git a/main/mkinitfs/APKBUILD b/main/mkinitfs/APKBUILD
index eefd14f194e3810cdaa1b218b71b39823b9e2cbb..36c069a7849b9cdc7496006874b019504104619c 100644
--- a/main/mkinitfs/APKBUILD
+++ b/main/mkinitfs/APKBUILD
@@ -1,11 +1,11 @@
 # Maintainer: Natanael Copa <ncopa@alpinelinux.org>
 pkgname=mkinitfs
-pkgver=2.8.0_git20151024
+pkgver=2.8.0_git20151025
 _ver=${pkgver%_git*}
-pkgrel=2
+pkgrel=0
 pkgdesc="Tool to generate initramfs images for Alpine"
-url=http://git.alpinelinux.org/cgit/mkinitfs
-makedepends="kmod-dev util-linux-dev linux-headers"
+url="http://git.alpinelinux.org/cgit/mkinitfs"
+makedepends="kmod-dev util-linux-dev cryptsetup-dev linux-headers"
 depends="acct busybox apk-tools>=2.0 lddtree>=1.25"
 install="$pkgname.pre-upgrade $pkgname.post-install $pkgname.post-upgrade"
 triggers="$pkgname.trigger=/usr/share/kernel/*"
@@ -37,8 +37,8 @@ package() {
 	make install DESTDIR="$pkgdir" || return 1
 }
 md5sums="1a321336d97b22257349ddd36884ec34  mkinitfs-2.8.0.tar.xz
-960550bde89e96cc6f9583fb47f05bea  git.patch"
+141a0411c74ac7533162b8a4007e2004  git.patch"
 sha256sums="5ffe4c5ec9e0ff4581e5b24301fd30d0964120d6b30ee78ea79f31ff48eeab73  mkinitfs-2.8.0.tar.xz
-2cda01897e16116e8dc10e8a76dbb64721f8a5764854b89a944773463f5d28b7  git.patch"
+525507c490490fd622b4f8760d212f2552570bebcdb974641d3aff65181854e5  git.patch"
 sha512sums="c103003f95c7d7d94daa41d0a81b210a0208c93d77203978554fb127a21e2f143b56990865fc53e2c5c732ef663603b297da63d31f915b1e3a3e0f3818aa8f2e  mkinitfs-2.8.0.tar.xz
-204ce7710ee4b807b1f6ef0a117f01a24b6edc90b0bc47c8b83827716f27f1491bb350e2ac36fd2aa4efffeb797edf331362c29fca2d2be966c0abe7fa09a427  git.patch"
+bdd182ef4fcd82c99f658e53c9c406bb7ad16ad6c19d3a11397699ed57c52d3e05e9d927807e02fd8980b5948fc5c37d184303a6d22b075e6b23aa5b8567af11  git.patch"
diff --git a/main/mkinitfs/git.patch b/main/mkinitfs/git.patch
index 7c512872875095427de967033905e0bb4c7fcf58..a1ba95cbe026661419e7060d962414207783305b 100644
--- a/main/mkinitfs/git.patch
+++ b/main/mkinitfs/git.patch
@@ -1,5 +1,5 @@
 diff --git a/Makefile b/Makefile
-index aaa553e..a62c294 100644
+index aaa553e..5ce1962 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -5,7 +5,7 @@ sysconfdir	?= /etc/mkinitfs
@@ -11,7 +11,14 @@ index aaa553e..a62c294 100644
  SHARE_FILES	:= initramfs-init fstab passwd group
  CONF_FILES	:= mkinitfs.conf \
  		features.d/ata.modules \
-@@ -32,6 +32,7 @@ CONF_FILES	:= mkinitfs.conf \
+@@ -25,13 +25,13 @@ CONF_FILES	:= mkinitfs.conf \
+ 		features.d/gfs2.modules \
+ 		features.d/jfs.modules \
+ 		features.d/keymap.files \
+-		features.d/kms.files \
+ 		features.d/kms.modules \
+ 		features.d/lvm.files \
+ 		features.d/lvm.modules \
  		features.d/network.files \
  		features.d/network.modules \
  		features.d/ocfs2.modules \
@@ -19,7 +26,7 @@ index aaa553e..a62c294 100644
  		features.d/raid.modules \
  		features.d/reiserfs.modules \
  		features.d/scsi.modules \
-@@ -41,7 +42,7 @@ CONF_FILES	:= mkinitfs.conf \
+@@ -41,7 +41,7 @@ CONF_FILES	:= mkinitfs.conf \
  		features.d/virtio.modules \
  		features.d/xfs.modules
  
@@ -28,7 +35,7 @@ index aaa553e..a62c294 100644
  IN_FILES	:= $(addsuffix .in,$(SCRIPTS))
  
  GIT_REV := $(shell test -d .git && git describe || echo exported)
-@@ -62,7 +63,8 @@ SED_REPLACE	:= -e 's:@VERSION@:$(FULL_VERSION):g' \
+@@ -62,7 +62,8 @@ SED_REPLACE	:= -e 's:@VERSION@:$(FULL_VERSION):g' \
  		-e 's:@datadir@:$(datadir):g'
  
  
@@ -38,7 +45,7 @@ index aaa553e..a62c294 100644
  
  clean:
  	rm -f $(SCRIPTS)
-@@ -71,6 +73,24 @@ help:
+@@ -71,6 +72,26 @@ help:
  	@echo mkinitfs $(VERSION)
  	@echo "usage: make install [DESTDIR=]"
  
@@ -50,9 +57,11 @@ index aaa553e..a62c294 100644
 +BLKID_LIBS	:= $(shell $(PKGCONF) --libs blkid)
 +LIBKMOD_CFLAGS	:= $(shell $(PKGCONF) --cflags libkmod)
 +LIBKMOD_LIBS	:= $(shell $(PKGCONF) --libs libkmod)
++CRYPTSETUP_CFLAGS := $(shell $(PKGCONF) --cflags libcryptsetup)
++CRYPTSETUP_LIBS	:= $(shell $(PKGCONF) --libs libcryptsetup)
 +
-+CFLAGS		+= $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS)
-+LIBS		= $(BLKID_LIBS) $(LIBKMOD_LIBS)
++CFLAGS		+= $(BLKID_CFLAGS) $(LIBKMOD_CFLAGS) $(CRYPTSETUP_CFLAGS)
++LIBS		= $(BLKID_LIBS) $(LIBKMOD_LIBS) $(CRYPTSETUP_LIBS)
 +
 +%.o: %.c
 +	$(CC) $(CFLAGS) -o $@ -c $<
@@ -199,6 +208,13 @@ index 8adf4df..6f28294 100644
  /usr/sbin/accton
  /usr/sbin/sa
 -
+diff --git a/features.d/kms.files b/features.d/kms.files
+deleted file mode 100644
+index 9d198b2..0000000
+--- a/features.d/kms.files
++++ /dev/null
+@@ -1 +0,0 @@
+-lib/firmware/radeon/*.bin
 diff --git a/features.d/lvm.modules b/features.d/lvm.modules
 index 92f0721..3af8ef9 100644
 --- a/features.d/lvm.modules
@@ -796,7 +812,7 @@ index 35cc96a..67a5444 100644
 -features="ata base bootchart cdrom cramfs ext2 ext3 ext4 floppy keymap kms raid scsi usb virtio"
 +features="ata base cdrom ext2 ext3 ext4 keymap kms mmc raid scsi usb virtio"
 diff --git a/mkinitfs.in b/mkinitfs.in
-index 04dc99c..14c728f 100755
+index 04dc99c..c5f6434 100755
 --- a/mkinitfs.in
 +++ b/mkinitfs.in
 @@ -36,7 +36,7 @@ feature_files() {
@@ -808,7 +824,7 @@ index 04dc99c..14c728f 100755
  	    etc/apk media/floppy media/usb newroot; do
  		dirs="$dirs $tmpdir/$i"
  	done
-@@ -115,6 +115,11 @@ initfs_kmods() {
+@@ -115,10 +115,24 @@ initfs_kmods() {
  	for file in $(find_kmods); do
  		echo "${file#/}"
  	done | sort -u | cpio -pdm "$tmpdir" || return 1
@@ -820,7 +836,20 @@ index 04dc99c..14c728f 100755
  	depmod $kernel -b "$tmpdir"
  	cd "$oldpwd"
  }
-@@ -179,7 +184,7 @@ done
+ 
++initfs_firmware() {
++	rm -rf "$tmpdir"/lib/firmware
++	mkdir -p "$tmpdir"/lib/firmware
++	find "$tmpdir"/lib/modules -type f -name "*.ko" | xargs modinfo -F firmware | sort -u | while read FW; do
++		[ -e "${basedir}/lib/firmware/${FW}" ] && install -pD "${basedir}/lib/firmware/${FW}" "$tmpdir"/lib/firmware/$FW
++	done
++	return 0
++}
++
+ initfs_apk_keys() {
+ 	mkdir -p "$tmpdir"/etc/apk/keys
+ 	cp "${basedir}etc/apk/keys/"* "$tmpdir"/etc/apk/keys/
+@@ -179,7 +193,7 @@ done
  shift $(( $OPTIND - 1 ))
  
  . $(readlink -f "$config")
@@ -829,12 +858,20 @@ index 04dc99c..14c728f 100755
  [ -n "$myfeatures" ] && features="$myfeatures"
  
  if [ -n "$list_features" ]; then
+@@ -232,6 +246,7 @@ fi
+ 
+ initfs_base \
+ 	&& initfs_kmods \
++	&& initfs_firmware \
+ 	&& initfs_apk_keys \
+ 	&& initfs_cpio
+ rc=$?
 diff --git a/nlplug-findfs.c b/nlplug-findfs.c
 new file mode 100644
-index 0000000..5f6dc5e
+index 0000000..27b9ce2
 --- /dev/null
 +++ b/nlplug-findfs.c
-@@ -0,0 +1,888 @@
+@@ -0,0 +1,1017 @@
 +
 +/*
 + * Copy me if you can.
@@ -857,6 +894,7 @@ index 0000000..5f6dc5e
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <string.h>
++#include <termios.h>
 +#include <unistd.h>
 +
 +#include <sys/eventfd.h>
@@ -872,6 +910,7 @@ index 0000000..5f6dc5e
 +
 +#include <libkmod.h>
 +#include <blkid.h>
++#include <libcryptsetup.h>
 +
 +#include "arg.h"
 +
@@ -882,9 +921,16 @@ index 0000000..5f6dc5e
 +#define FOUND_BOOTREPO	0x2
 +#define FOUND_APKOVL	0x4
 +
++#define TRIGGER_THREAD		0x1
++#define CRYPTSETUP_THREAD	0x2
++
++#define LVM_PATH	"/sbin/lvm"
++#define MDADM_PATH	"/sbin/mdadm"
++
 +static int dodebug;
 +static char *default_envp[2];
 +char *argv0;
++static int use_mdadm, use_lvm;
 +
 +#if defined(DEBUG)
 +#include <stdarg.h>
@@ -1025,12 +1071,17 @@ index 0000000..5f6dc5e
 +	char *search_device;
 +	char *crypt_device;
 +	char *crypt_name;
++	char crypt_devnode[256];
 +	char *subsystem_filter;
 +	int modalias_count;
 +	int fork_count;
 +	char *bootrepos;
 +	char *apkovls;
 +	int timeout;
++	int efd;
++	unsigned running_threads;
++	pthread_t cryptsetup_tid;
++	pthread_mutex_t cryptsetup_mutex;
 +};
 +
 +
@@ -1139,33 +1190,111 @@ index 0000000..5f6dc5e
 +static void start_mdadm(char *devnode)
 +{
 +	char *mdadm_argv[] = {
-+		"/sbin/mdadm",
++		MDADM_PATH,
 +		"--incremental",
 +		"--quiet",
 +		devnode,
 +		NULL
 +	};
-+	spawn_command(&spawnmgr, mdadm_argv, 0);
++	if (use_mdadm)
++		spawn_command(&spawnmgr, mdadm_argv, 0);
 +}
 +
 +static void start_lvm2(char *devnode)
 +{
 +	char *lvm2_argv[] = {
-+		"/sbin/lvm", "vgchange",
-+		"--activate" , "ay", "--noudevsync", "--sysinit",
++		LVM_PATH, "vgchange",
++		"--activate" , "ay", "--noudevsync", "--sysinit", "-q", "-q",
 +		NULL
 +	};
-+	spawn_command(&spawnmgr, lvm2_argv, 0);
++	if (use_lvm)
++		spawn_command(&spawnmgr, lvm2_argv, 0);
 +}
 +
-+static void start_cryptsetup(char *devnode, char *cryptdm)
++
++static int read_pass(char *pass, size_t pass_size)
 +{
-+	char *cryptsetup_argv[] = {
-+		"/sbin/cryptsetup", "luksOpen",
-+		devnode, cryptdm ? cryptdm : "crypdm", NULL
-+	};
++	struct termios old_flags, new_flags;
++	int r;
++
++	tcgetattr(STDIN_FILENO, &old_flags);
++	new_flags = old_flags;
++	new_flags.c_lflag &= ~ECHO;
++	new_flags.c_lflag |= ECHONL;
++
++	r = tcsetattr(STDIN_FILENO, TCSANOW, &new_flags);
++	if (r < 0) {
++		warn("tcsetattr");
++		return r;
++	}
++
++	if (fgets(pass, pass_size, stdin) == NULL) {
++		warn("fgets");
++		return -1;
++	}
++	pass[strlen(pass) - 1] = '\0';
++
++	if (tcsetattr(STDIN_FILENO, TCSANOW, &old_flags) < 0) {
++		warn("tcsetattr");
++		return r;
++	}
++
++	return 0;
++}
++
++static void *cryptsetup_thread(void *data)
++{
++	struct ueventconf *c = (struct ueventconf *)data;
++	uint64_t ok = CRYPTSETUP_THREAD;
++	struct crypt_device *cd;
++	int r, passwd_tries = 5;
++
++	r = crypt_init(&cd, c->crypt_devnode);
++	if (r < 0) {
++		warnx("crypt_init(%s)", c->crypt_devnode);
++		goto notify_out;
++	}
++
++	r = crypt_load(cd , CRYPT_LUKS1, NULL);
++	if (r < 0) {
++		warnx("crypt_load(%s)", c->crypt_devnode);
++		goto free_out;
++	}
++
++	while (passwd_tries > 0) {
++		char pass[1024];
++
++		printf("Enter passphrase for %s: ", c->crypt_devnode);
++		fflush(stdout);
++
++		if (read_pass(pass, sizeof(pass)) < 0)
++			goto free_out;
++		passwd_tries--;
++
++		pthread_mutex_lock(&c->cryptsetup_mutex);
++		r = crypt_activate_by_passphrase(cd, c->crypt_name,
++						 CRYPT_ANY_SLOT,
++						 pass, strlen(pass), 0);
++		pthread_mutex_unlock(&c->cryptsetup_mutex);
++
++		if (r == 0)
++			break;
++		printf("No key available with this passphrase.\n");
++	}
++
++free_out:
++	crypt_free(cd);
++notify_out:
++	write(c->efd, &ok, sizeof(ok));
++	return NULL;
++}
++
++static void start_cryptsetup(struct ueventconf *conf)
++{
++	dbg("starting cryptsetup %s -> %s", conf->crypt_devnode, conf->crypt_name);
 +	load_kmod("dm-crypt");
-+	spawn_command(&spawnmgr, cryptsetup_argv, 0);
++	pthread_create(&conf->cryptsetup_tid, NULL, cryptsetup_thread, conf);
++	conf->running_threads |= CRYPTSETUP_THREAD;
 +}
 +
 +static int is_mounted(const char *devnode) {
@@ -1343,35 +1472,50 @@ index 0000000..5f6dc5e
 +	return rc;
 +}
 +
-+static int searchdev(char *devname, const char *searchdev, char *bootrepos,
++static int is_same_device(const struct uevent *ev, const char *nodepath)
++{
++	struct stat st;
++	unsigned int maj, min;
++	if (stat(nodepath, &st) < 0)
++		return 0;
++
++	if (ev->major == NULL || ev->minor == NULL)
++		return 0;
++
++	maj = atoi(ev->major);
++	min = atoi(ev->minor);
++	return S_ISBLK(st.st_mode) && makedev(maj, min) == st.st_rdev;
++}
++
++
++static int searchdev(struct uevent *ev, const char *searchdev, char *bootrepos,
 +		     const char *apkovls)
 +{
 +	static blkid_cache cache = NULL;
 +	char *type = NULL, *label = NULL, *uuid = NULL;
-+	char devnode[256];
 +	int rc = 0;
 +
 +	if (searchdev == NULL && bootrepos == NULL && apkovls == NULL)
 +		return 0;
 +
-+	snprintf(devnode, sizeof(devnode), "/dev/%s", devname);
-+	if (searchdev && (strcmp(devname, searchdev) == 0
-+	                  || strcmp(devnode, searchdev) == 0)) {
++	if (searchdev && (strcmp(ev->devname, searchdev) == 0
++			  || strcmp(ev->devnode, searchdev) == 0
++	                  || is_same_device(ev, searchdev))) {
 +		return FOUND_DEVICE;
 +	}
 +
 +	if (cache == NULL)
 +		blkid_get_cache(&cache, NULL);
 +
-+	type = blkid_get_tag_value(cache, "TYPE", devnode);
++	type = blkid_get_tag_value(cache, "TYPE", ev->devnode);
 +
 +	if (searchdev != NULL) {
 +		if (strncmp("LABEL=", searchdev, 6) == 0) {
-+			label = blkid_get_tag_value(cache, "LABEL", devnode);
++			label = blkid_get_tag_value(cache, "LABEL", ev->devnode);
 +			if (label && strcmp(label, searchdev+6) == 0)
 +				rc = FOUND_DEVICE;
 +		} else if (strncmp("UUID=", searchdev, 5) == 0) {
-+			uuid = blkid_get_tag_value(cache, "UUID", devnode);
++			uuid = blkid_get_tag_value(cache, "UUID", ev->devnode);
 +			if (uuid && strcmp(uuid, searchdev+5) == 0)
 +				rc = FOUND_DEVICE;
 +		}
@@ -1381,7 +1525,7 @@ index 0000000..5f6dc5e
 +		dbg("%s:\n"
 +			"\ttype='%s'\n"
 +			"\tlabel='%s'\n"
-+			"\tuuid='%s'\n", devnode,
++			"\tuuid='%s'\n", ev->devnode,
 +			type ? type : NULL,
 +			label ? label : NULL,
 +			uuid ? uuid : NULL);
@@ -1389,11 +1533,11 @@ index 0000000..5f6dc5e
 +
 +	if (!rc && type) {
 +		if (strcmp("linux_raid_member", type) == 0) {
-+			start_mdadm(devnode);
++			start_mdadm(ev->devnode);
 +		} else if (strcmp("LVM2_member", type) == 0) {
-+			start_lvm2(devnode);
++			start_lvm2(ev->devnode);
 +		} else if (bootrepos) {
-+			rc = find_bootrepos(devnode, type, bootrepos, apkovls);
++			rc = find_bootrepos(ev->devnode, type, bootrepos, apkovls);
 +		}
 +	}
 +
@@ -1441,14 +1585,19 @@ index 0000000..5f6dc5e
 +
 +			snprintf(ev->devnode, sizeof(ev->devnode), "/dev/%s",
 +				 ev->devname);
-+			rc = searchdev(ev->devname, conf->search_device,
++			pthread_mutex_lock(&conf->cryptsetup_mutex);
++			rc = searchdev(ev, conf->search_device,
 +				       conf->bootrepos, conf->apkovls);
++			pthread_mutex_unlock(&conf->cryptsetup_mutex);
 +			if (rc)
 +				return rc;
 +
-+			if (searchdev(ev->devname, conf->crypt_device, NULL,
-+				      NULL))
-+				start_cryptsetup(ev->devnode, conf->crypt_name);
++			if (searchdev(ev, conf->crypt_device, NULL, NULL)) {
++				strncpy(conf->crypt_devnode,
++					conf->crypt_device[0] == '/' ? conf->crypt_device : ev->devnode,
++					sizeof(conf->crypt_devnode));
++				start_cryptsetup(conf);
++			}
 +		}
 +	}
 +	return 0;
@@ -1517,7 +1666,7 @@ index 0000000..5f6dc5e
 +static void *trigger_thread(void *data)
 +{
 +	int fd = *(int *)data;
-+	uint64_t ok = 1;
++	uint64_t ok = TRIGGER_THREAD;
 +	struct recurse_opts opts = {
 +		.searchname = "uevent",
 +		.callback = trigger_uevent_cb,
@@ -1560,7 +1709,7 @@ index 0000000..5f6dc5e
 +	struct ueventconf conf;
 +	int event_count = 0;
 +	size_t total_bytes = 0;
-+	int found = 0, trigger_running = 0;
++	int found = 0;
 +	char *program_argv[2] = {0,0};
 +	pthread_t tid;
 +	sigset_t sigchldmask;
@@ -1573,6 +1722,9 @@ index 0000000..5f6dc5e
 +	memset(&conf, 0, sizeof(conf));
 +	conf.program_argv = program_argv;
 +	conf.timeout = DEFAULT_EVENT_TIMEOUT;
++	use_lvm = access(LVM_PATH, X_OK) == 0;
++	use_mdadm = access(MDADM_PATH, X_OK) == 0;
++
 +	argv0 = strrchr(argv[0], '/');
 +	if (argv0++ == NULL)
 +		argv0 = argv[0];
@@ -1612,6 +1764,10 @@ index 0000000..5f6dc5e
 +	if (argc > 0)
 +		conf.search_device = argv[0];
 +
++	r = pthread_mutex_init(&conf.cryptsetup_mutex, NULL);
++	if (r < 0)
++		err(1, "pthread_mutex_init");
++
 +	initsignals();
 +	sigemptyset(&sigchldmask);
 +	sigaddset(&sigchldmask, SIGCHLD);
@@ -1625,18 +1781,19 @@ index 0000000..5f6dc5e
 +
 +	fds[2].fd = eventfd(0, EFD_CLOEXEC);
 +	fds[2].events = POLLIN;
++	conf.efd = fds[2].fd;
 +	pthread_create(&tid, NULL, trigger_thread, &fds[2].fd);
-+	trigger_running = 1;
++	conf.running_threads |= TRIGGER_THREAD;
 +
 +	while (1) {
-+		r = poll(fds, numfds, (spawn_active(&spawnmgr) || trigger_running) ? -1 : conf.timeout);
++		r = poll(fds, numfds, (spawn_active(&spawnmgr) || conf.running_threads) ? -1 : conf.timeout);
 +		if (r == -1) {
 +			if (errno == EINTR || errno == ERESTART)
 +				continue;
 +			err(1, "poll");
 +		}
 +		if (r == 0) {
-+			dbg("exit due to timeout");
++			dbg("exit due to timeout (%i)", conf.timeout);
 +			break;
 +		}
 +
@@ -1685,7 +1842,8 @@ index 0000000..5f6dc5e
 +			if ((found & FOUND_DEVICE)
 +			    || ((found & FOUND_BOOTREPO) &&
 +				(found & FOUND_APKOVL))) {
-+				dbg("setting timeout to 0");
++				if (conf.timeout)
++					dbg("FOUND! setting timeout to 0");
 +				conf.timeout = 0;
 +			}
 +		}
@@ -1707,14 +1865,22 @@ index 0000000..5f6dc5e
 +		}
 +
 +		if (fds[2].revents & POLLIN) {
-+			close(fds[2].fd);
-+			fds[2].fd = -1;
-+			fds[2].revents = 0;
-+			numfds--;
-+			trigger_running = 0;
-+			pthread_join(tid, NULL);
++			uint64_t tmask = 0;
++			if (read(fds[2].fd, &tmask, sizeof(tmask)) < 0)
++				warn("eventfd");
++			if (tmask & TRIGGER_THREAD) {
++				dbg("terminating trigger thread");
++				pthread_join(tid, NULL);
++			}
++			if (tmask & CRYPTSETUP_THREAD) {
++				dbg("terminating cryptsetup thread");
++				pthread_join(conf.cryptsetup_tid, NULL);
++			}
++			conf.running_threads &= ~tmask;
 +		}
 +	}
++	close(fds[2].fd);
++	pthread_mutex_destroy(&conf.cryptsetup_mutex);
 +
 +	dbg("modaliases: %i, forks: %i, events: %i, total bufsize: %zu",
 +		conf.modalias_count,