diff --git a/include/kernel-build.mk b/include/kernel-build.mk
index cf8737c8ee72d6c39f0c4200d58ffe434e5db49a..2ae80e54e2ef51ef64df12b0fa6d9a1b626c493b 100644
--- a/include/kernel-build.mk
+++ b/include/kernel-build.mk
@@ -67,24 +67,40 @@ define BuildKernel
 	$(Kernel/Prepare)
 	touch $$@
 
-  $(KERNEL_BUILD_DIR)/symtab.txt: FORCE
+  $(KERNEL_BUILD_DIR)/symtab.h: FORCE
+	rm -f $(KERNEL_BUILD_DIR)/symtab.h
+	touch $(KERNEL_BUILD_DIR)/symtab.h
+	+$(MAKE) $(KERNEL_MAKEOPTS) vmlinux
 	find $(LINUX_DIR) $(STAGING_DIR_ROOT)/lib/modules -name \*.ko | \
 		xargs $(TARGET_CROSS)nm | \
 		awk '$$$$1 == "U" { print $$$$2 } ' | \
-		sort -u > $$@
-
-  $(KERNEL_BUILD_DIR)/symtab.h: $(KERNEL_BUILD_DIR)/symtab.txt
+		sort -u > $(KERNEL_BUILD_DIR)/mod_symtab.txt
+	$(TARGET_CROSS)nm -n $(LINUX_DIR)/vmlinux.o | grep ' r __ksymtab' | sed -e 's,........ r __ksymtab_,,' > $(KERNEL_BUILD_DIR)/kernel_symtab.txt
+	grep -f $(KERNEL_BUILD_DIR)/mod_symtab.txt $(KERNEL_BUILD_DIR)/kernel_symtab.txt > $(KERNEL_BUILD_DIR)/sym_include.txt
+	grep -vf $(KERNEL_BUILD_DIR)/mod_symtab.txt $(KERNEL_BUILD_DIR)/kernel_symtab.txt > $(KERNEL_BUILD_DIR)/sym_exclude.txt
 	( \
 		echo '#define SYMTAB_KEEP \'; \
-		cat $(KERNEL_BUILD_DIR)/symtab.txt | \
+		cat $(KERNEL_BUILD_DIR)/sym_include.txt | \
 			awk '{print "*(__ksymtab." $$$$1 ") \\" }'; \
 		echo; \
 		echo '#define SYMTAB_KEEP_GPL \'; \
-		cat $(KERNEL_BUILD_DIR)/symtab.txt | \
+		cat $(KERNEL_BUILD_DIR)/sym_include.txt | \
 			awk '{print "*(__ksymtab_gpl." $$$$1 ") \\" }'; \
 		echo; \
 		echo '#define SYMTAB_KEEP_STR \'; \
-		cat $(KERNEL_BUILD_DIR)/symtab.txt | \
+		cat $(KERNEL_BUILD_DIR)/sym_include.txt | \
+			awk '{print "*(__ksymtab_strings." $$$$1 ") \\" }'; \
+		echo; \
+		echo '#define SYMTAB_DISCARD \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_exclude.txt | \
+			awk '{print "*(__ksymtab." $$$$1 ") \\" }'; \
+		echo; \
+		echo '#define SYMTAB_DISCARD_GPL \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_exclude.txt | \
+			awk '{print "*(__ksymtab_gpl." $$$$1 ") \\" }'; \
+		echo; \
+		echo '#define SYMTAB_DISCARD_STR \'; \
+		cat $(KERNEL_BUILD_DIR)/sym_exclude.txt | \
 			awk '{print "*(__ksymtab_strings." $$$$1 ") \\" }'; \
 		echo; \
 	) > $$@
diff --git a/target/linux/generic/patches-3.3/220-module_exports.patch b/target/linux/generic/patches-3.3/220-module_exports.patch
index be6b6ff9d9906b5795c8768c7c35525b206df865..5b87c1a3e3cc7b2e7783934a0363244a54ec1775 100644
--- a/target/linux/generic/patches-3.3/220-module_exports.patch
+++ b/target/linux/generic/patches-3.3/220-module_exports.patch
@@ -1,34 +1,25 @@
 --- a/include/asm-generic/vmlinux.lds.h
 +++ b/include/asm-generic/vmlinux.lds.h
-@@ -52,6 +52,27 @@
+@@ -52,6 +52,18 @@
  #define LOAD_OFFSET 0
  #endif
  
 +#ifndef SYMTAB_KEEP_STR
++#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_KEEP_STR *(__ksymtab_strings+*)
-+#define SYMTAB_DISCARD_STR
-+#else
-+#define SYMTAB_DISCARD_STR *(__ksymtab_strings+*)
 +#endif
 +
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#ifndef SYMTAB_DISCARD
 +#define SYMTAB_DISCARD
-+#else
-+#define SYMTAB_DISCARD *(SORT(___ksymtab+*))
-+#endif
-+
-+#ifndef SYMTAB_KEEP_GPL
-+#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_DISCARD_GPL
-+#else
-+#define SYMTAB_DISCARD_GPL *(SORT(___ksymtab_gpl+*))
++#define SYMTAB_DISCARD_STR
 +#endif
 +
  #ifndef SYMBOL_PREFIX
  #define VMLINUX_SYMBOL(sym) sym
  #else
-@@ -275,14 +296,14 @@
+@@ -275,14 +287,14 @@
  	/* Kernel symbol table: Normal symbols */			\
  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
  		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
@@ -45,7 +36,7 @@
  		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
  	}								\
  									\
-@@ -344,7 +365,7 @@
+@@ -344,7 +356,7 @@
  									\
  	/* Kernel symbol table: strings */				\
          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
@@ -54,7 +45,7 @@
  	}								\
  									\
  	/* __*init sections */						\
-@@ -676,6 +697,9 @@
+@@ -676,6 +688,9 @@
  	EXIT_TEXT							\
  	EXIT_DATA							\
  	EXIT_CALL							\
@@ -87,3 +78,14 @@
  	= MODULE_SYMBOL_PREFIX #sym;				\
  	static const struct kernel_symbol __ksymtab_##sym	\
  	__used							\
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -346,7 +346,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
+ # Linker scripts preprocessor (.lds.S -> .lds)
+ # ---------------------------------------------------------------------------
+ quiet_cmd_cpp_lds_S = LDS     $@
+-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
++      cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -C -U$(ARCH) \
+ 	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
+ 
+ $(obj)/%.lds: $(src)/%.lds.S FORCE
diff --git a/target/linux/generic/patches-3.6/220-module_exports.patch b/target/linux/generic/patches-3.6/220-module_exports.patch
index 8acb18f83d836d47b22321722baa301c85222d10..4383aa28bb4ce33e3c9f84c6fce7eaa40e9c122f 100644
--- a/target/linux/generic/patches-3.6/220-module_exports.patch
+++ b/target/linux/generic/patches-3.6/220-module_exports.patch
@@ -1,34 +1,25 @@
 --- a/include/asm-generic/vmlinux.lds.h
 +++ b/include/asm-generic/vmlinux.lds.h
-@@ -52,6 +52,27 @@
+@@ -52,6 +52,18 @@
  #define LOAD_OFFSET 0
  #endif
  
 +#ifndef SYMTAB_KEEP_STR
++#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_KEEP_STR *(__ksymtab_strings+*)
-+#define SYMTAB_DISCARD_STR
-+#else
-+#define SYMTAB_DISCARD_STR *(__ksymtab_strings+*)
 +#endif
 +
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#ifndef SYMTAB_DISCARD
 +#define SYMTAB_DISCARD
-+#else
-+#define SYMTAB_DISCARD *(SORT(___ksymtab+*))
-+#endif
-+
-+#ifndef SYMTAB_KEEP_GPL
-+#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_DISCARD_GPL
-+#else
-+#define SYMTAB_DISCARD_GPL *(SORT(___ksymtab_gpl+*))
++#define SYMTAB_DISCARD_STR
 +#endif
 +
  #ifndef SYMBOL_PREFIX
  #define VMLINUX_SYMBOL(sym) sym
  #else
-@@ -276,14 +297,14 @@
+@@ -276,14 +288,14 @@
  	/* Kernel symbol table: Normal symbols */			\
  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
  		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
@@ -45,7 +36,7 @@
  		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
  	}								\
  									\
-@@ -345,7 +366,7 @@
+@@ -345,7 +357,7 @@
  									\
  	/* Kernel symbol table: strings */				\
          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
@@ -54,7 +45,7 @@
  	}								\
  									\
  	/* __*init sections */						\
-@@ -670,6 +691,9 @@
+@@ -670,6 +682,9 @@
  	EXIT_TEXT							\
  	EXIT_DATA							\
  	EXIT_CALL							\
@@ -87,3 +78,14 @@
  	= MODULE_SYMBOL_PREFIX #sym;				\
  	static const struct kernel_symbol __ksymtab_##sym	\
  	__used							\
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -348,7 +348,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
+ # Linker scripts preprocessor (.lds.S -> .lds)
+ # ---------------------------------------------------------------------------
+ quiet_cmd_cpp_lds_S = LDS     $@
+-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
++      cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -C -U$(ARCH) \
+ 	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
+ 
+ $(obj)/%.lds: $(src)/%.lds.S FORCE
diff --git a/target/linux/generic/patches-3.7/220-module_exports.patch b/target/linux/generic/patches-3.7/220-module_exports.patch
index 89da1645d086ef0098198edd00ec540c13c24f8a..fc382c16f9bf3875652f61acf37c2ea917c6acc1 100644
--- a/target/linux/generic/patches-3.7/220-module_exports.patch
+++ b/target/linux/generic/patches-3.7/220-module_exports.patch
@@ -1,34 +1,25 @@
 --- a/include/asm-generic/vmlinux.lds.h
 +++ b/include/asm-generic/vmlinux.lds.h
-@@ -52,6 +52,27 @@
+@@ -52,6 +52,18 @@
  #define LOAD_OFFSET 0
  #endif
  
 +#ifndef SYMTAB_KEEP_STR
++#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_KEEP_STR *(__ksymtab_strings+*)
-+#define SYMTAB_DISCARD_STR
-+#else
-+#define SYMTAB_DISCARD_STR *(__ksymtab_strings+*)
 +#endif
 +
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP *(SORT(___ksymtab+*))
++#ifndef SYMTAB_DISCARD
 +#define SYMTAB_DISCARD
-+#else
-+#define SYMTAB_DISCARD *(SORT(___ksymtab+*))
-+#endif
-+
-+#ifndef SYMTAB_KEEP_GPL
-+#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
 +#define SYMTAB_DISCARD_GPL
-+#else
-+#define SYMTAB_DISCARD_GPL *(SORT(___ksymtab_gpl+*))
++#define SYMTAB_DISCARD_STR
 +#endif
 +
  #ifndef SYMBOL_PREFIX
  #define VMLINUX_SYMBOL(sym) sym
  #else
-@@ -276,14 +297,14 @@
+@@ -276,14 +288,14 @@
  	/* Kernel symbol table: Normal symbols */			\
  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
  		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
@@ -45,7 +36,7 @@
  		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
  	}								\
  									\
-@@ -345,7 +366,7 @@
+@@ -345,7 +357,7 @@
  									\
  	/* Kernel symbol table: strings */				\
          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
@@ -54,7 +45,7 @@
  	}								\
  									\
  	/* __*init sections */						\
-@@ -679,6 +700,9 @@
+@@ -679,6 +691,9 @@
  	EXIT_TEXT							\
  	EXIT_DATA							\
  	EXIT_CALL							\
@@ -87,3 +78,14 @@
  	= MODULE_SYMBOL_PREFIX #sym;				\
  	static const struct kernel_symbol __ksymtab_##sym	\
  	__used							\
+--- a/scripts/Makefile.build
++++ b/scripts/Makefile.build
+@@ -348,7 +348,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
+ # Linker scripts preprocessor (.lds.S -> .lds)
+ # ---------------------------------------------------------------------------
+ quiet_cmd_cpp_lds_S = LDS     $@
+-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
++      cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -C -U$(ARCH) \
+ 	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
+ 
+ $(obj)/%.lds: $(src)/%.lds.S FORCE