diff -puNrb openwrt/target/linux/mr-mips/base-files/etc/hotplug2-init.rules openwrt-new/target/linux/mr-mips/base-files/etc/hotplug2-init.rules
--- openwrt/target/linux/mr-mips/base-files/etc/hotplug2-init.rules	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/base-files/etc/hotplug2-init.rules	2014-01-09 14:06:32.000000000 +0000
@@ -0,0 +1,8 @@
+$include /etc/hotplug2-common.rules
+
+DEVICENAME ~~ (hvc) {
+	nothrottle
+	makedev /dev/%DEVICENAME% 0666
+	next
+}
+
diff -puNrb openwrt/target/linux/mr-mips/base-files/etc/inittab openwrt-new/target/linux/mr-mips/base-files/etc/inittab
--- openwrt/target/linux/mr-mips/base-files/etc/inittab	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/base-files/etc/inittab	2014-01-09 14:05:57.000000000 +0000
@@ -0,0 +1,4 @@
+::sysinit:/etc/init.d/rcS S boot
+::shutdown:/etc/init.d/rcS K stop
+hvc0::askfirst:/bin/ash --login
+
diff -puNrb openwrt/target/linux/mr-mips/config-3.10 openwrt-new/target/linux/mr-mips/config-3.10
--- openwrt/target/linux/mr-mips/config-3.10	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/config-3.10	2014-01-11 10:24:10.000000000 +0000
@@ -0,0 +1,1528 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/mips 3.10.49 Kernel Configuration
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+CONFIG_ZONE_DMA=y
+# CONFIG_MIPS_ALCHEMY is not set
+# CONFIG_AR7 is not set
+# CONFIG_ATH79 is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_JZ4740 is not set
+# CONFIG_LANTIQ is not set
+# CONFIG_LASAT is not set
+# CONFIG_MACH_LOONGSON is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_NEC_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_POWERTV is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+CONFIG_MIPS_MIKROTIK=y
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_NLM_XLR_BOARD is not set
+# CONFIG_NLM_XLP_BOARD is not set
+# CONFIG_SOFT_PCI_IO is not set
+CONFIG_MAPPED_KERNEL=y
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_CSRC_R4K=y
+# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+# CONFIG_MIPS_MACHINE is not set
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_GPIO=y
+CONFIG_CPU_BIG_ENDIAN=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=4
+
+#
+# CPU selection
+#
+CONFIG_CPU_MIPS32_R1=y
+# CONFIG_CPU_MIPS32_R2 is not set
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_SYS_HAS_CPU_MIPS32_R2=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+
+#
+# Kernel type
+#
+CONFIG_32BIT=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MIPS_MT_DISABLED=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
+CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+# CONFIG_USE_OF is not set
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_IRQ_FORCED_THREADING=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_JUMP_LABEL is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_DEADLINE=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="deadline"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_PCI_PRI is not set
+# CONFIG_PCI_PASID is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_RAPIDIO is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_TRAD_SIGNALS=y
+
+#
+# Power management options
+#
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_HIBERNATION is not set
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_UNIX_DIAG is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
+# CONFIG_IP_PIMSM_V1 is not set
+# CONFIG_IP_PIMSM_V2 is not set
+CONFIG_ARPD=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+# CONFIG_TCP_CONG_BIC is not set
+# CONFIG_TCP_CONG_CUBIC is not set
+# CONFIG_TCP_CONG_WESTWOOD is not set
+# CONFIG_TCP_CONG_HTCP is not set
+# CONFIG_TCP_CONG_HSTCP is not set
+# CONFIG_TCP_CONG_HYBLA is not set
+# CONFIG_TCP_CONG_VEGAS is not set
+# CONFIG_TCP_CONG_SCALABLE is not set
+# CONFIG_TCP_CONG_LP is not set
+# CONFIG_TCP_CONG_VENO is not set
+# CONFIG_TCP_CONG_YEAH is not set
+# CONFIG_TCP_CONG_ILLINOIS is not set
+# CONFIG_DEFAULT_WESTWOOD is not set
+# CONFIG_DEFAULT_RENO is not set
+# CONFIG_DEFAULT_TCP_CONG is not set
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_ACCT is not set
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_PROCFS=y
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+# CONFIG_NF_CT_PROTO_DCCP is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+CONFIG_NF_CONNTRACK_FTP=m
+# CONFIG_NF_CONNTRACK_H323 is not set
+CONFIG_NF_CONNTRACK_IRC=m
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_SNMP is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+# CONFIG_NETFILTER_TPROXY is not set
+CONFIG_NETFILTER_XTABLES=m
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+# CONFIG_NETFILTER_XT_CONNMARK is not set
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
+# CONFIG_NETFILTER_XT_TARGET_CT is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_HL is not set
+# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
+# CONFIG_NETFILTER_XT_TARGET_LED is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ECN is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_HL is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_NF_CONNTRACK_PROC_COMPAT=y
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_RPFILTER is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_NF_NAT=m
+CONFIG_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_REDIRECT is not set
+CONFIG_NF_NAT_FTP=m
+CONFIG_NF_NAT_IRC=m
+# CONFIG_NF_NAT_TFTP is not set
+# CONFIG_NF_NAT_AMANDA is not set
+# CONFIG_NF_NAT_PPTP is not set
+# CONFIG_NF_NAT_H323 is not set
+# CONFIG_NF_NAT_SIP is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+CONFIG_IP_NF_RAW=m
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_BRIDGE_NF_EBTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+# CONFIG_NET_DSA is not set
+CONFIG_VLAN_8021Q=y
+# CONFIG_VLAN_8021Q_GVRP is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_MULTIQ is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFB is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+# CONFIG_NET_SCH_DRR is not set
+# CONFIG_NET_SCH_MQPRIO is not set
+# CONFIG_NET_SCH_CHOKE is not set
+# CONFIG_NET_SCH_QFQ is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+# CONFIG_OPENVSWITCH is not set
+CONFIG_BQL=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+CONFIG_HAMRADIO=y
+
+#
+# Packet Radio protocols
+#
+# CONFIG_AX25 is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+# CONFIG_NFC is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_NVME is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_VIRTIO_BLK is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_RBD is not set
+
+#
+# Misc devices
+#
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_INTEL_MID_PTI is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_EEPROM_93XX46 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+
+#
+# Altera FPGA firmware download module
+#
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_SCSI_MOD is not set
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_CORE=y
+# CONFIG_BONDING is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_MII is not set
+# CONFIG_NET_TEAM is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_VIRTIO_NET is not set
+# CONFIG_ARCNET is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_VORTEX is not set
+# CONFIG_TYPHOON is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_ACENIC is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_PCNET32 is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_ATL2 is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_B44 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2X is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_BNA is not set
+# CONFIG_NET_CALXEDA_XGMAC is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_CHELSIO_T4 is not set
+# CONFIG_CHELSIO_T4VF is not set
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_ENIC is not set
+# CONFIG_DM9000 is not set
+# CONFIG_DNET is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_DL2K is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_BE2NET is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
+# CONFIG_NET_VENDOR_HP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_E100 is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_IXGB is not set
+# CONFIG_IXGBE is not set
+# CONFIG_NET_VENDOR_I825XX is not set
+# CONFIG_IP1000 is not set
+# CONFIG_JME is not set
+# CONFIG_RBKORINA is not set
+# CONFIG_ADM5120_ETH is not set
+# CONFIG_CRETHER is not set
+CONFIG_MT_VETH=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_MLX4_EN is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_KSZ884X_PCI is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NS83820 is not set
+# CONFIG_NET_VENDOR_8390 is not set
+# CONFIG_AX88796 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_PCH_GBE is not set
+# CONFIG_ETHOC is not set
+CONFIG_NET_PACKET_ENGINE=y
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_QLCNIC is not set
+# CONFIG_QLGE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_8139CP is not set
+# CONFIG_8139TOO is not set
+# CONFIG_R8169 is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_R6040 is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_SEEQ8005 is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_SC92031 is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_SIS900 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SFC is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_SMSC9420 is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_STMMAC_ETH is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NIU is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_TLAN is not set
+# CONFIG_NET_VENDOR_TOSHIBA is not set
+# CONFIG_TC35815 is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_MICREL_KS8995MA is not set
+CONFIG_PPP=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_FILTER=y
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=m
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_TR is not set
+CONFIG_WLAN=y
+# CONFIG_ATMEL is not set
+# CONFIG_PRISM54 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_ISDN_I4L is not set
+# CONFIG_ISDN_CAPI is not set
+# CONFIG_ISDN_DRV_GIGASET is not set
+# CONFIG_HYSDN is not set
+# CONFIG_MISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_PCI is not set
+# CONFIG_SERIAL_8250_NR_UARTS is not set
+# CONFIG_SERIAL_8250_RUNTIME_UARTS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_ADM5120 is not set
+# CONFIG_SERIAL_AR9330 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_CORE is not set
+# CONFIG_SERIAL_CORE_CONSOLE is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_PCH_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_TTY_PRINTK is not set
+CONFIG_HVC_DRIVER=y
+CONFIG_HVC_IRQ=y
+CONFIG_HVC_META=y
+CONFIG_VIRTIO_CONSOLE=y
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_SPI_DEBUG is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_RB400 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_TOPCLIFF_PCH is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_VX855 is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_ML_IOH is not set
+# CONFIG_GPIO_RDC321X is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_SSB_POSSIBLE is not set
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+# CONFIG_BCMA_POSSIBLE is not set
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_MC13XXX is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_MFD_TIMBERDALE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_VGA_ARB_MAX_GPUS= is not set
+# CONFIG_DRM is not set
+# CONFIG_STUB_POULSBO is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_RB400 is not set
+# CONFIG_LEDS_RB_MIPSEL is not set
+# CONFIG_LEDS_DAC124S085 is not set
+# CONFIG_LEDS_LT3593 is not set
+# CONFIG_LEDS_OT200 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_VIRTIO=y
+CONFIG_VIRTIO_RING=y
+
+#
+# Virtio drivers
+#
+CONFIG_VIRTIO_PCI=y
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+# CONFIG_ET131X is not set
+# CONFIG_ECHO is not set
+# CONFIG_R8187SE is not set
+# CONFIG_RTLLIB is not set
+# CONFIG_VT6655 is not set
+# CONFIG_VME_BUS is not set
+# CONFIG_DX_SEP is not set
+# CONFIG_IIO is not set
+# CONFIG_XVMALLOC is not set
+# CONFIG_ZRAM is not set
+# CONFIG_CRYSTALHD is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_STAGING_MEDIA is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+
+#
+# Hardware Spinlock drivers
+#
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTR is not set
+CONFIG_SQUASHFS_ZLIB=y
+# CONFIG_SQUASHFS_LZO is not set
+# CONFIG_SQUASHFS_XZ is not set
+# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_META_FS=y
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_STACKTRACE is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_CMDLINE_BOOL=y
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_SPINLOCK_TEST is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_USER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+CONFIG_ZLIB_INFLATE=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_DQL=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+#
+
+CONFIG_CMDLINE="init=/etc/preinit"
+# CONFIG_CMDLINE_OVERRIDE is not set
diff -puNrb openwrt/target/linux/mr-mips/image/Makefile openwrt-new/target/linux/mr-mips/image/Makefile
--- openwrt/target/linux/mr-mips/image/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/image/Makefile	2014-01-09 14:00:54.000000000 +0000
@@ -0,0 +1,15 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/image.mk
+
+define Image/BuildKernel
+	cp $(KDIR)/vmlinux.elf $(TARGET_DIR)/kernel
+endef
+
+$(eval $(call BuildImage))
+
diff -puNrb openwrt/target/linux/mr-mips/Makefile openwrt-new/target/linux/mr-mips/Makefile
--- openwrt/target/linux/mr-mips/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/Makefile	2014-01-09 14:09:04.000000000 +0000
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2007-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+ARCH:=mips
+BOARD:=mr-mips
+BOARDNAME:=Mikrotik MetaROUTER MIPS
+FEATURES:=targz
+
+LINUX_VERSION:=3.10.49
+
+include $(INCLUDE_DIR)/target.mk
+$(eval $(call BuildTarget))
+
diff -puNrb openwrt/target/linux/mr-mips/patches-3.10/000-linux-metarouter.patch openwrt-new/target/linux/mr-mips/patches-3.10/000-linux-metarouter.patch
--- openwrt/target/linux/mr-mips/patches-3.10/000-linux-metarouter.patch	1970-01-01 01:00:00.000000000 +0100
+++ openwrt-new/target/linux/mr-mips/patches-3.10/000-linux-metarouter.patch	2014-01-11 08:49:06.000000000 +0000
@@ -0,0 +1,3265 @@
+diff -puNrb linux-3.10.49/arch/mips/include/asm/checksum.h linux-3.10.49-minimal/arch/mips/include/asm/checksum.h
+--- linux-3.10.49/arch/mips/include/asm/checksum.h	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/checksum.h	2014-01-11 07:00:34.000000000 +0000
+@@ -14,6 +14,7 @@
+ #include <linux/in6.h>
+ 
+ #include <asm/uaccess.h>
++#include <asm/unaligned.h>
+ 
+ /*
+  * computes the checksum of a memory block at buff, length len,
+@@ -105,23 +106,23 @@ static inline __sum16 ip_fast_csum(const
+ 	unsigned int csum;
+ 	int carry;
+ 
+-	csum = word[0];
+-	csum += word[1];
+-	carry = (csum < word[1]);
++	csum = get_unaligned(word + 0);
++	csum += get_unaligned(word + 1);
++	carry = (csum < get_unaligned(word + 1));
+ 	csum += carry;
+ 
+-	csum += word[2];
+-	carry = (csum < word[2]);
++	csum += get_unaligned(word + 2);
++	carry = (csum < get_unaligned(word + 2));
+ 	csum += carry;
+ 
+-	csum += word[3];
+-	carry = (csum < word[3]);
++	csum += get_unaligned(word + 3);
++	carry = (csum < get_unaligned(word + 3));
+ 	csum += carry;
+ 
+ 	word += 4;
+ 	do {
+-		csum += *word;
+-		carry = (csum < *word);
++		csum += get_unaligned(word);
++		carry = (csum < get_unaligned(word));
+ 		csum += carry;
+ 		word++;
+ 	} while (word != stop);
+@@ -208,42 +209,90 @@ static __inline__ __sum16 csum_ipv6_magi
+ 
+ 	"	addu	%0, %6		# csum\n"
+ 	"	sltu	$1, %0, %6	\n"
+-	"	lw	%1, 0(%2)	# four words source address\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 3(%2)	# four words source address\n"
++	"	lwr	%1, 0(%2)	# four words source address\n"
++#else
++	"	lwl	%1, 0(%2)	# four words source address\n"
++	"	lwr	%1, 3(%2)	# four words source address\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 4(%2)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 7(%2)	\n"
++	"	lwr	%1, 4(%2)	\n"
++#else
++	"	lwl	%1, 4(%2)	\n"
++	"	lwr	%1, 7(%2)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 8(%2)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 11(%2)	\n"
++	"	lwr	%1, 8(%2)	\n"
++#else
++	"	lwl	%1, 8(%2)	\n"
++	"	lwr	%1, 11(%2)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 12(%2)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 15(%2)	\n"
++	"	lwr	%1, 12(%2)	\n"
++#else
++	"	lwl	%1, 12(%2)	\n"
++	"	lwr	%1, 15(%2)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 0(%3)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 3(%3)	\n"
++	"	lwr	%1, 0(%3)	\n"
++#else
++	"	lwl	%1, 0(%3)	\n"
++	"	lwr	%1, 3(%3)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 4(%3)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 7(%3)	\n"
++	"	lwr	%1, 4(%3)	\n"
++#else
++	"	lwl	%1, 4(%3)	\n"
++	"	lwr	%1, 7(%3)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 8(%3)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 11(%3)	\n"
++	"	lwr	%1, 8(%3)	\n"
++#else
++	"	lwl	%1, 8(%3)	\n"
++	"	lwr	%1, 11(%3)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+ 
+-	"	lw	%1, 12(%3)	\n"
++#ifdef __MIPSEL__
++	"	lwl	%1, 15(%3)	\n"
++	"	lwr	%1, 12(%3)	\n"
++#else
++	"	lwl	%1, 12(%3)	\n"
++	"	lwr	%1, 15(%3)	\n"
++#endif
+ 	"	addu	%0, $1		\n"
+ 	"	addu	%0, %1		\n"
+ 	"	sltu	$1, %0, %1	\n"
+diff -puNrb linux-3.10.49/arch/mips/include/asm/io.h linux-3.10.49-minimal/arch/mips/include/asm/io.h
+--- linux-3.10.49/arch/mips/include/asm/io.h	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/io.h	2014-01-11 07:01:40.000000000 +0000
+@@ -206,6 +206,7 @@ static inline void __iomem * __ioremap_m
+ 		if (!size || last_addr < phys_addr)
+ 			return NULL;
+ 
++#ifndef CONFIG_MAPPED_KERNEL
+ 		/*
+ 		 * Map uncached objects in the low 512MB of address
+ 		 * space using KSEG1.
+@@ -213,6 +214,7 @@ static inline void __iomem * __ioremap_m
+ 		    flags == _CACHE_UNCACHED)
+ 			return (void __iomem *)
+ 				(unsigned long)CKSEG1ADDR(phys_addr);
++#endif
+ 	}
+ 
+ 	return __ioremap(offset, size, flags);
+@@ -625,4 +627,41 @@ extern void (*_dma_cache_inv)(unsigned l
+  */
+ #define xlate_dev_kmem_ptr(p)	p
+ 
++#ifdef CONFIG_SOFT_PCI_IO
++
++unsigned _pci_inb(unsigned long port);
++unsigned _pci_inw(unsigned long port);
++unsigned _pci_inl(unsigned long port);
++void _pci_outb(unsigned char value, unsigned long port);
++void _pci_outw(unsigned short value, unsigned long port);
++void _pci_outl(unsigned value, unsigned long port);
++
++#define inb	_pci_inb
++#define inb_p	_pci_inb
++#define __mem_inb	_pci_inb
++#define __mem_inb_p	_pci_inb
++#define inw	_pci_inw
++#define inw_p	_pci_inw
++#define __mem_inw	_pci_inw
++#define __mem_inw_p	_pci_inw
++#define inl	_pci_inl
++#define inl_p	_pci_inl
++#define __mem_inl	_pci_inl
++#define __mem_inl_p	_pci_inl
++
++#define outb	_pci_outb
++#define outb_p	_pci_outb
++#define __mem_outb	_pci_outb
++#define __mem_outb_p	_pci_outb
++#define outw	_pci_outw
++#define outw_p	_pci_outw
++#define __mem_outw	_pci_outw
++#define __mem_outw_p	_pci_outw
++#define outl	_pci_outl
++#define outl_p	_pci_outl
++#define __mem_outl	_pci_outl
++#define __mem_outl_p	_pci_outl
++
++#endif
++
+ #endif /* _ASM_IO_H */
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/cpu-feature-overrides.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/cpu-feature-overrides.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/cpu-feature-overrides.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/cpu-feature-overrides.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,6 @@
++#ifndef __ASM_MACH_RB_CPU_FEATURE_OVERRIDES_H
++#define __ASM_MACH_RB_CPU_FEATURE_OVERRIDES_H
++
++#define cpu_has_dsp		0
++
++#endif /* __ASM_MACH_RB_CPU_FEATURE_OVERRIDES_H */
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/irq.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/irq.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/irq.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/irq.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,16 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2003 by Ralf Baechle
++ */
++#ifndef __ASM_MACH_RB_IRQ_H
++#define __ASM_MACH_RBC_IRQ_H
++
++#define I8259A_IRQ_BASE 0
++#define MIPS_CPU_IRQ_BASE 0
++
++#define NR_IRQS	168
++
++#endif /* __ASM_MACH_RB_IRQ_H */
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/kernel-entry-init.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/kernel-entry-init.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/kernel-entry-init.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/kernel-entry-init.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,44 @@
++#ifndef __ASM_MACH_RB_KERNEL_ENTRY_H
++#define __ASM_MACH_RB_KERNEL_ENTRY_H
++
++.macro	kernel_entry_setup
++#ifdef CONFIG_MAPPED_KERNEL
++	.set	push
++	.set	mips32r2
++	/* check whether we are running under 0xc0000000 address space */
++	lui	t0, 0xf000
++	bal	1f
++1:	and	t1, ra, t0
++	li	t0, 0xc0000000
++	beq	t0, t1, 2f
++	/* set up 0xc0000000 address space */
++	mtc0	t0, CP0_ENTRYHI
++	li	t0, 0x1f
++	mtc0	t0, CP0_ENTRYLO0
++	li	t0, 0x0010001f
++	mtc0	t0, CP0_ENTRYLO1
++	li	t0, PM_64M
++	mtc0	t0, CP0_PAGEMASK
++	li	t0, 0
++	mtc0	t0, CP0_INDEX
++	li	t0, 2
++	mtc0	t0, CP0_WIRED
++	ehb
++	tlbwi
++
++	li	t0, 0xc8000000
++	mtc0	t0, CP0_ENTRYHI
++	li	t0, 0x0020001f
++	mtc0	t0, CP0_ENTRYLO0
++	li	t0, 0x0030001f
++	mtc0	t0, CP0_ENTRYLO1
++	li	t0, 1
++	mtc0	t0, CP0_INDEX
++	ehb
++	tlbwi
++2:
++	.set	pop
++#endif
++.endm
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/kmalloc.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/kmalloc.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/kmalloc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/kmalloc.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,4 @@
++#ifndef __ASM_MACH_RB_KMALLOC_H
++#define __ASM_MACH_RB_KMALLOC_H
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/mangle-port.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/mangle-port.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/mangle-port.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/mangle-port.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,36 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2003, 2004 Ralf Baechle
++ */
++#ifndef __ASM_MACH_GENERIC_MANGLE_PORT_H
++#define __ASM_MACH_GENERIC_MANGLE_PORT_H
++
++#ifdef CONFIG_CPU_LITTLE_ENDIAN
++
++#define __swizzle_addr_b(port)	(port)
++#define __swizzle_addr_w(port)	(port)
++#define __swizzle_addr_l(port)	(port)
++#define __swizzle_addr_q(port)	(port)
++
++#else
++
++#define __swizzle_addr_b(port)  ((port) ^ 3)
++#define __swizzle_addr_w(port)  ((port) ^ 2)
++#define __swizzle_addr_l(port)  (port)
++#define __swizzle_addr_q(port)  (port)
++
++#endif
++
++#define ioswabb(a,x)		(x)
++#define __mem_ioswabb(a,x)	(x)
++#define ioswabw(a,x)		(x)
++#define __mem_ioswabw(a,x)	cpu_to_le16(x)
++#define ioswabl(a,x)		(x)
++#define __mem_ioswabl(a,x)	cpu_to_le32(x)
++#define ioswabq(a,x)		(x)
++#define __mem_ioswabq(a,x)	cpu_to_le32(x)
++
++#endif /* __ASM_MACH_GENERIC_MANGLE_PORT_H */
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/spaces.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/spaces.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/spaces.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/spaces.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,30 @@
++#ifndef _ASM_MACH_RB_SPACES_H
++#define _ASM_MACH_RB_SPACES_H
++
++#include <linux/const.h>
++
++#define PHYS_OFFSET		_AC(0, UL)
++
++#ifdef CONFIG_MAPPED_KERNEL
++#define CAC_BASE		_AC(0xc0000000, UL)
++#else
++#define CAC_BASE		_AC(0x80000000, UL)
++#endif
++#define IO_BASE			_AC(0xa0000000, UL)
++#define UNCAC_BASE		_AC(0xa0000000, UL)
++
++#ifndef MAP_BASE
++#define MAP_BASE		_AC(0xd0000000, UL)
++#endif
++
++#define HIGHMEM_START		_AC(0x20000000, UL)
++
++#define PAGE_OFFSET		(CAC_BASE + PHYS_OFFSET)
++
++#ifndef CONFIG_MAPPED_KERNEL
++#define FIXADDR_TOP		((unsigned long)(long)(int)0xfffe0000)
++#else
++#define FIXADDR_TOP		((unsigned long)(long)(int)0xdffe0000)
++#endif
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/mach-rb/war.h linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/war.h
+--- linux-3.10.49/arch/mips/include/asm/mach-rb/war.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/mach-rb/war.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,18 @@
++#ifndef __ASM_MIPS_MACH_RB_WAR_H
++#define __ASM_MIPS_MACH_RB_WAR_H
++
++#define R4600_V1_INDEX_ICACHEOP_WAR	0
++#define R4600_V1_HIT_CACHEOP_WAR	0
++#define R4600_V2_HIT_CACHEOP_WAR	0
++#define R5432_CP0_INTERRUPT_WAR		0
++#define BCM1250_M3_WAR			0
++#define SIBYTE_1956_WAR			0
++#define MIPS4K_ICACHE_REFILL_WAR	0
++#define MIPS_CACHE_SYNC_WAR		0
++#define TX49XX_ICACHE_INDEX_INV_WAR	0
++#define RM9000_CDEX_SMP_WAR		0
++#define ICACHE_REFILLS_WORKAROUND_WAR   0
++#define R10000_LLSC_WAR			0
++#define MIPS34K_MISSED_ITLB_WAR		0
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/rb/boards.h linux-3.10.49-minimal/arch/mips/include/asm/rb/boards.h
+--- linux-3.10.49/arch/mips/include/asm/rb/boards.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/rb/boards.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,66 @@
++#ifndef _ASM_RB_BOARDS_H
++#define _ASM_RB_BOARDS_H
++
++#define MACH_GROUP_MT_RB500    1	/* Mikrotik RB500 */
++#define MACH_GROUP_MT_RB100    2	/* Mikrotik RB100 */
++#define MACH_GROUP_MT_CR       3	/* Mikrotik CR */
++#define MACH_GROUP_MT_RB400    4
++#define MACH_GROUP_MT_VM       6
++#define MACH_GROUP_MT_RB700    7
++
++
++#define  MACH_MT_RB500		0
++#define  MACH_MT_RB500R5	1
++#define  MACH_MT_RB100		2
++#define  MACH_MT_RB150		3
++#define  MACH_MT_RB133		4
++#define  MACH_MT_RB133C		5
++#define  MACH_MT_MR		6
++#define  MACH_MT_RB192		7
++#define  MACH_MT_CR1		8
++#define  MACH_MT_RB411		10
++#define  MACH_MT_RB433		11
++#define  MACH_MT_RB433U		12	/* RB433 + USB */
++#define  MACH_MT_RB450		13
++#define  MACH_MT_RB493		15
++#define  MACH_MT_RB450G		16
++#define  MACH_MT_RB411U		17
++#define  MACH_MT_RB493G		18
++#define  MACH_MT_RB750G		19
++#define  MACH_MT_RB435G		20
++#define  MACH_MT_RB750		23
++#define  MACH_MT_RB711		24
++#define  MACH_MT_RB_OMNI	25
++#define  MACH_MT_RB_SXT5D	26
++#define  MACH_MT_RB_GROOVE	27
++#define  MACH_MT_RB_OMNI_5FE	28	/* OmniTIK U-5HnD */
++#define  MACH_MT_RB711R3	29
++#define  MACH_MT_RB751G		30
++#define  MACH_MT_RB711G		31
++#define  MACH_MT_RB411L		33
++#define  MACH_MT_RB750GL	35
++#define  MACH_MT_RB411G		36
++#define  MACH_MT_RB951		37
++#define  MACH_MT_GROOVE52	38
++#define  MACH_MT_RB2011G	39
++#define  MACH_MT_RB912G		40
++#define  MACH_MT_RB433GL	41
++#define  MACH_MT_RB433UL	42
++#define  MACH_MT_RB_SXTG	43
++#define  MACH_MT_RB751		44
++#define  MACH_MT_RB_GROOVE_5S	45
++#define  MACH_MT_RB433L		46
++#define  MACH_MT_RB411UL	47
++#define  MACH_MT_RB2011L	49
++#define  MACH_MT_RB2011LS	50
++#define  MACH_MT_RB951G		52
++#define  MACH_MT_RB2011US	53
++#define  MACH_MT_SXT2D		58
++#define  MACH_MT_SXT5N		59
++#define  MACH_MT_RB2011R5	61
++#define  MACH_MT_CRS125G	63
++
++extern unsigned long mips_machgroup;
++extern unsigned long mips_machtype;
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/rb/booter.h linux-3.10.49-minimal/arch/mips/include/asm/rb/booter.h
+--- linux-3.10.49/arch/mips/include/asm/rb/booter.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/rb/booter.h	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,19 @@
++#ifndef _ASM_BOOTER_H
++#define _ASM_BOOTER_H
++
++#define ID_HW_OPTIONS		0x00000015
++
++#define HW_OPT_UART_ABSENT	(1 << 0)
++#define HW_OPT_HAS_VOLTAGE	(1 << 1)
++#define HW_OPT_HAS_USB		(1 << 2)
++#define HW_OPT_HAS_ATTINY	(1 << 3)
++#define HW_OPT_NO_NAND		(1 << 14)
++#define HW_OPT_HAS_LCD		(1 << 15)
++#define HW_OPT_HAS_POE_OUT	(1 << 16)
++#define HW_OPT_HAS_uSD		(1 << 17)
++#define HW_OPT_HAS_SFP		(1 << 20)
++#define HW_OPT_HAS_WIFI		(1 << 21)
++
++int read_booter_cfg(unsigned id, void *buf, int amount);
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/include/asm/string.h linux-3.10.49-minimal/arch/mips/include/asm/string.h
+--- linux-3.10.49/arch/mips/include/asm/string.h	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/include/asm/string.h	2014-01-11 07:04:24.000000000 +0000
+@@ -108,8 +108,9 @@ strncmp(__const__ char *__cs, __const__ 
+ 	__asm__ __volatile__(
+ 	".set\tnoreorder\n\t"
+ 	".set\tnoat\n"
+-	"1:\tlbu\t%3,(%0)\n\t"
+-	"beqz\t%2,2f\n\t"
++	"1:\tbeqz\t%2,2f\n\t"
++	"nop\n\t"
++	"lbu\t%3,(%0)\n\t"
+ 	"lbu\t$1,(%1)\n\t"
+ 	"subu\t%2,1\n\t"
+ 	"bne\t$1,%3,3f\n\t"
+diff -puNrb linux-3.10.49/arch/mips/include/asm/vm.h linux-3.10.49-minimal/arch/mips/include/asm/vm.h
+--- linux-3.10.49/arch/mips/include/asm/vm.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/include/asm/vm.h	2014-01-11 07:04:31.000000000 +0000
+@@ -0,0 +1,43 @@
++#ifndef MT_VM_H
++#define MT_VM_H
++
++#define VIRQ_BASE	64
++
++#define hypercall(name, nr, ...)		\
++	asm(					\
++		".global " #name ";"		\
++		".align 2;"			\
++		".set	push;"			\
++		".set	noreorder;"		\
++		".type " #name ",@function;"	\
++		".ent " #name ",0;"		\
++		#name ": .frame $sp,0,$ra;"	\
++		"li $3, " #nr ";"		\
++		"li $2, -22;"			\
++		"mtc0 $0, $1;"			\
++		"jr $ra;"			\
++		"nop;"				\
++		".end " #name ";"		\
++		".size " #name ",.-" #name ";"	\
++		".set	pop"			\
++        );					\
++	asmlinkage extern int name(__VA_ARGS__);
++
++/* NOTE: do not allow vdma_descr to span multiple pages, so align it */
++struct vdma_descr {
++	unsigned addr;
++	unsigned size;
++	unsigned next;
++} __attribute__((aligned(16)));
++
++#define DONE		0x80000000
++
++static inline unsigned get_virq_nr(unsigned hwirq)
++{
++	return VIRQ_BASE + hwirq;
++}
++
++extern int vm_running(void);
++#define hc_yield() asm volatile ("wait")
++
++#endif
+diff -puNrb linux-3.10.49/arch/mips/Kbuild.platforms linux-3.10.49-minimal/arch/mips/Kbuild.platforms
+--- linux-3.10.49/arch/mips/Kbuild.platforms	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/Kbuild.platforms	2014-01-11 07:04:57.000000000 +0000
+@@ -31,6 +31,7 @@ platforms += sni
+ platforms += txx9
+ platforms += vr41xx
+ platforms += wrppmc
++platforms += rb
+ 
+ # include the platform specific files
+ include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
+diff -puNrb linux-3.10.49/arch/mips/Kconfig linux-3.10.49-minimal/arch/mips/Kconfig
+--- linux-3.10.49/arch/mips/Kconfig	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/Kconfig	2014-01-11 07:08:23.000000000 +0000
+@@ -713,6 +713,23 @@ config MIKROTIK_RB532
+ 	  Support the Mikrotik(tm) RouterBoard 532 series,
+ 	  based on the IDT RC32434 SoC.
+ 
++config MIPS_MIKROTIK
++	bool "Support for Mikrotik RB boards"
++	select CEVT_R4K
++	select CSRC_R4K
++	select DMA_NONCOHERENT
++	select HW_HAS_PCI
++	select IRQ_CPU
++	select SYS_HAS_CPU_MIPS32_R1
++	select SYS_HAS_CPU_MIPS32_R2
++	select SYS_SUPPORTS_LITTLE_ENDIAN
++	select SYS_SUPPORTS_BIG_ENDIAN
++	select SYS_SUPPORTS_32BIT_KERNEL
++	select ZONE_DMA
++	select ARCH_REQUIRE_GPIOLIB
++	help
++	  Say Y here to support all Mikrotik mips based routerboards
++
+ config WR_PPMC
+ 	bool "Wind River PPMC board"
+ 	select CEVT_R4K
+@@ -838,6 +855,14 @@ config NLM_XLP_BOARD
+ 
+ endchoice
+ 
++config SOFT_PCI_IO
++	bool "PCI IO software emulation on RB4xx"
++	depends on MIPS_MIKROTIK
++
++config MAPPED_KERNEL
++	bool "Mapped kernel support"
++	depends on MIPS_MIKROTIK
++
+ source "arch/mips/alchemy/Kconfig"
+ source "arch/mips/ath79/Kconfig"
+ source "arch/mips/bcm47xx/Kconfig"
+@@ -1164,6 +1189,7 @@ config MIPS_L1_CACHE_SHIFT
+ 	default "4" if MACH_DECSTATION || MIKROTIK_RB532 || PMC_MSP4200_EVAL || SOC_RT288X
+ 	default "6" if MIPS_CPU_SCACHE
+ 	default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
++	default "4" if MIPS_MIKROTIK
+ 	default "5"
+ 
+ config HAVE_STD_PC_SERIAL_PORT
+@@ -1230,7 +1256,7 @@ config CPU_LOONGSON2F
+ config CPU_MIPS32_R1
+ 	bool "MIPS32 Release 1"
+ 	depends on SYS_HAS_CPU_MIPS32_R1
+-	select CPU_HAS_PREFETCH
++#	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_HIGHMEM
+ 	help
+@@ -1247,7 +1273,7 @@ config CPU_MIPS32_R1
+ config CPU_MIPS32_R2
+ 	bool "MIPS32 Release 2"
+ 	depends on SYS_HAS_CPU_MIPS32_R2
+-	select CPU_HAS_PREFETCH
++#	select CPU_HAS_PREFETCH
+ 	select CPU_SUPPORTS_32BIT_KERNEL
+ 	select CPU_SUPPORTS_HIGHMEM
+ 	select HAVE_KVM
+diff -puNrb linux-3.10.49/arch/mips/kernel/backtrace.c linux-3.10.49-minimal/arch/mips/kernel/backtrace.c
+--- linux-3.10.49/arch/mips/kernel/backtrace.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/backtrace.c	2014-01-11 07:08:45.000000000 +0000
+@@ -0,0 +1,156 @@
++#include <linux/module.h>
++#include <linux/oprofile.h>
++#include <linux/mm.h>
++#include <asm/page.h>
++#include <asm/processor.h>
++#include <asm/uaccess.h>
++
++#define INSTR_JR_RA	0x03e00008
++#define INSTR_JRHB_RA	0x03e00408
++#define INSTR_ADDIU_SP	0x241d0000
++#define INSTR_SW_RA_SP	0xafbf0000
++#define INSTR_MOVE_RA_ZERO	0x0000f821
++#define REGS_MASK	0x03e00000
++#define IMM16_MASK	0x0000ffff
++
++#define REG_SP		29
++#define TO_REGS(x)	((x) << 21)
++
++static inline int fetch_u32(void *val, void *ptr, int usermode)
++{
++	if (((unsigned) ptr & 3) != 0)
++		return -EFAULT;
++
++	if (usermode)
++		return get_user(*(unsigned *) val, (unsigned *) ptr);
++
++	if (KSEGX(ptr) == KSEG3)
++		return __get_user(*(unsigned *) val, (unsigned *) ptr);
++
++	if (KSEGX(ptr) != KSEG0 && KSEGX(ptr) != KSEG2)
++		return -EFAULT;
++
++	if ((unsigned long) ptr < PAGE_OFFSET)
++		return -EFAULT;
++	if ((unsigned long) ptr  > (unsigned long) high_memory)
++		return -EFAULT;
++
++	return __get_user(*(unsigned *) val, (unsigned *) ptr);
++}
++
++static inline int is_bcond(unsigned i)
++{
++    unsigned c = (i >> 26) & 7;
++    switch (i >> 29) {
++    case 0:
++	if (c == 1)
++	    return (i & (1 << 19)) == 0;
++	/* fall trough */
++    case 2:
++	return c >= 4;
++    }
++    return 0;
++}
++
++static inline unsigned *find_prev_branch(unsigned *instr, unsigned *limit,
++					 int usermode)
++{
++    unsigned i = 0;
++    unsigned *target = instr;
++
++    for (--instr; instr > limit; --instr) {
++	if (fetch_u32(&i, instr, usermode))
++	    return 0;
++
++	if (is_bcond(i)) {
++	    if (instr + 1 + (short) i == target) {
++		return instr;
++	    }
++	} else if ((i & ~(IMM16_MASK | REGS_MASK)) == INSTR_ADDIU_SP) {
++	    if ((i & REGS_MASK) != TO_REGS(REG_SP)) {
++		/* not simple sp adjustment, probably switching stack here */
++		return 0;
++	    }
++	    /* check if frame start has been hit */
++	    if ((short) (i & IMM16_MASK) < 0) {
++		return 0;
++	    }
++	}
++    }
++    return 0;
++}
++
++unsigned long find_prev_frame(unsigned long pc, unsigned long ra,
++			      unsigned long *sp, int usermode)
++{
++    int storedRA = -1;
++    int frameSize = 0;
++    unsigned *instr;
++    unsigned *limit = (unsigned *) (pc - 4096);
++    unsigned i = 0;
++    int imm;
++
++    if (!fetch_u32(&i, (unsigned *) pc, usermode)) {
++	if ((i & ~(IMM16_MASK | REGS_MASK)) == INSTR_ADDIU_SP
++	    && (short) (i & IMM16_MASK) < 0) {
++	    /* we are at the beging of function, reserving stack */
++	    return ra;
++	}
++    }
++
++    for (instr = (unsigned *) pc - 1; instr > limit; --instr) {
++	if (fetch_u32(&i, instr, usermode))
++	    break;
++
++	if (i == INSTR_JR_RA || i == INSTR_JRHB_RA) {
++	    /* found prev func end */
++	    break;
++	} else if ((i & ~IMM16_MASK) == INSTR_SW_RA_SP) {
++	    /* remember where previous RA was stored */
++	    storedRA = (short) (i & IMM16_MASK);
++	} else if ((i & ~(IMM16_MASK | REGS_MASK)) == INSTR_ADDIU_SP) {
++	    if ((i & REGS_MASK) != TO_REGS(REG_SP)) {
++		/* not simple sp adjustment, probably switching stack here */
++		return 0;
++	    }
++
++	    imm = (short) (i & IMM16_MASK);
++	    if (imm >= 0) {
++		/* found prev func end (poping back stack frame),
++		   or end of our own func in other of it's threads (chunks) */
++		if (storedRA != -1)
++		    break;
++
++		instr = find_prev_branch(instr + 1, limit, usermode);
++		if (instr == 0) {
++		    /* no branch to us was found,
++		       it means we are at the begining of the frame */
++		    break;
++		}
++	    } else {
++		frameSize = -imm;
++		break;
++	    }
++	} else if (i == INSTR_MOVE_RA_ZERO) {
++	    /* we have come to the end of the world,
++	       __start() func sets up RA wrongly */
++	    return 0;
++	}
++    }
++
++    if (frameSize > 0) {
++	/* if we hit addiu sp,-X first, we have stack frame */
++
++	if (storedRA != -1) {
++	    if (fetch_u32(&ra, (char *) *sp + storedRA, usermode))
++		return 0;
++	    if (ra == 0)
++		return 0;
++	}
++	*sp += frameSize;
++	return ra;
++    }
++    return ra;
++}
++
++EXPORT_SYMBOL(find_prev_frame);
+diff -puNrb linux-3.10.49/arch/mips/kernel/cevt-r4k.c linux-3.10.49-minimal/arch/mips/kernel/cevt-r4k.c
+--- linux-3.10.49/arch/mips/kernel/cevt-r4k.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/cevt-r4k.c	2014-01-11 07:09:06.000000000 +0000
+@@ -112,6 +112,14 @@ static int c0_compare_int_pending(void)
+  * so wait up to worst case number of cycle counter ticks for timer interrupt
+  * changes to propagate to the cause register.
+  */
++#define back_to_back_c0_hazard4() \
++	do { \
++		back_to_back_c0_hazard(); \
++		back_to_back_c0_hazard(); \
++		back_to_back_c0_hazard(); \
++		back_to_back_c0_hazard(); \
++	} while (0)
++
+ #define COMPARE_INT_SEEN_TICKS 50
+ 
+ int c0_compare_int_usable(void)
+@@ -137,7 +145,7 @@ int c0_compare_int_usable(void)
+ 	if (c0_compare_int_pending()) {
+ 		cnt = read_c0_count();
+ 		write_c0_compare(cnt);
+-		back_to_back_c0_hazard();
++		back_to_back_c0_hazard4();
+ 		while (read_c0_count() < (cnt  + COMPARE_INT_SEEN_TICKS))
+ 			if (!c0_compare_int_pending())
+ 				break;
+@@ -149,7 +157,7 @@ int c0_compare_int_usable(void)
+ 		cnt = read_c0_count();
+ 		cnt += delta;
+ 		write_c0_compare(cnt);
+-		back_to_back_c0_hazard();
++		back_to_back_c0_hazard4();
+ 		if ((int)(read_c0_count() - cnt) < 0)
+ 		    break;
+ 		/* increase delta if the timer was already expired */
+@@ -165,7 +173,7 @@ int c0_compare_int_usable(void)
+ 		return 0;
+ 	cnt = read_c0_count();
+ 	write_c0_compare(cnt);
+-	back_to_back_c0_hazard();
++	back_to_back_c0_hazard4();
+ 	while (read_c0_count() < (cnt + COMPARE_INT_SEEN_TICKS))
+ 		if (!c0_compare_int_pending())
+ 			break;
+diff -puNrb linux-3.10.49/arch/mips/kernel/head.S linux-3.10.49-minimal/arch/mips/kernel/head.S
+--- linux-3.10.49/arch/mips/kernel/head.S	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/kernel/head.S	2014-01-11 07:09:14.000000000 +0000
+@@ -146,7 +146,7 @@ EXPORT(__image_cmdline)
+ 	.fill	0x400
+ #endif /* CONFIG_IMAGE_CMDLINE_HACK */
+ 
+-	__REF
++	__HEAD
+ 
+ NESTED(kernel_entry, 16, sp)			# kernel entry point
+ 
+diff -puNrb linux-3.10.49/arch/mips/kernel/Makefile linux-3.10.49-minimal/arch/mips/kernel/Makefile
+--- linux-3.10.49/arch/mips/kernel/Makefile	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/kernel/Makefile	2014-01-11 07:09:28.000000000 +0000
+@@ -5,7 +5,7 @@
+ extra-y		:= head.o vmlinux.lds
+ 
+ obj-y		+= cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \
+-		   prom.o ptrace.o reset.o setup.o signal.o syscall.o \
++		   prom.o ptrace.o reset.o setup.o signal.o syscall.o backtrace.o \
+ 		   time.o topology.o traps.o unaligned.o watch.o vdso.o
+ 
+ ifdef CONFIG_FUNCTION_TRACER
+diff -puNrb linux-3.10.49/arch/mips/kernel/module.c linux-3.10.49-minimal/arch/mips/kernel/module.c
+--- linux-3.10.49/arch/mips/kernel/module.c	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/kernel/module.c	2014-01-11 07:09:36.000000000 +0000
+@@ -29,6 +29,7 @@
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+ #include <linux/spinlock.h>
++#include <linux/mm.h>
+ #include <linux/jump_label.h>
+ 
+ #include <asm/pgtable.h>	/* MODULE_START */
+@@ -182,7 +183,10 @@ static inline bool is_phys_addr(void *pt
+ #ifdef CONFIG_64BIT
+ 	return (KSEGX((unsigned long)ptr) == CKSEG0);
+ #else
+-	return (KSEGX(ptr) == KSEG0);
++	unsigned addr = (unsigned) ptr;
++	return addr && (addr < VMALLOC_START || addr > VMALLOC_END);
++//	return (KSEGX(ptr) == KSEG0);
++
+ #endif
+ }
+ 
+diff -puNrb linux-3.10.49/arch/mips/kernel/proc.c linux-3.10.49-minimal/arch/mips/kernel/proc.c
+--- linux-3.10.49/arch/mips/kernel/proc.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/proc.c	2014-01-11 07:09:50.000000000 +0000
+@@ -13,6 +13,7 @@
+ #include <asm/idle.h>
+ #include <asm/mipsregs.h>
+ #include <asm/processor.h>
++#include <asm/time.h>
+ #include <asm/prom.h>
+ 
+ unsigned int vced_count, vcei_count;
+@@ -20,6 +21,7 @@ unsigned int vced_count, vcei_count;
+ static int show_cpuinfo(struct seq_file *m, void *v)
+ {
+ 	unsigned long n = (unsigned long) v - 1;
++	unsigned cpu_khz = mips_hpt_frequency / 500;
+ 	unsigned int version = cpu_data[n].processor_id;
+ 	unsigned int fp_vers = cpu_data[n].fpu_id;
+ 	char fmt [64];
+@@ -46,6 +48,8 @@ static int show_cpuinfo(struct seq_file 
+ 	seq_printf(m, fmt, __cpu_name[n],
+ 		      (version >> 4) & 0x0f, version & 0x0f,
+ 		      (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
++	seq_printf(m, "cpu MHz\t\t\t: %u.%03u\n",
++		   cpu_khz / 1000, (cpu_khz % 1000));
+ 	seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
+ 		      cpu_data[n].udelay_val / (500000/HZ),
+ 		      (cpu_data[n].udelay_val / (5000/HZ)) % 100);
+diff -puNrb linux-3.10.49/arch/mips/kernel/time.c linux-3.10.49-minimal/arch/mips/kernel/time.c
+--- linux-3.10.49/arch/mips/kernel/time.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/time.c	2014-01-11 07:09:56.000000000 +0000
+@@ -70,6 +70,7 @@ EXPORT_SYMBOL(perf_irq);
+  */
+ 
+ unsigned int mips_hpt_frequency;
++EXPORT_SYMBOL(mips_hpt_frequency);
+ 
+ /*
+  * This function exists in order to cause an error due to a duplicate
+diff -puNrb linux-3.10.49/arch/mips/kernel/traps.c linux-3.10.49-minimal/arch/mips/kernel/traps.c
+--- linux-3.10.49/arch/mips/kernel/traps.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/traps.c	2014-01-11 07:10:14.000000000 +0000
+@@ -91,6 +91,8 @@ void (*board_ebase_setup)(void);
+ void (*board_ebase_setup)(void);
+ void __cpuinitdata(*board_cache_error_setup)(void);
+ 
++#define CONFIG_RAWBACKTRACE
++#ifdef CONFIG_RAWBACKTRACE
+ static void show_raw_backtrace(unsigned long reg29)
+ {
+ 	unsigned long *sp = (unsigned long *)(reg29 & ~3);
+@@ -144,6 +146,25 @@ static void show_backtrace(struct task_s
+ 	printk("\n");
+ }
+ 
++#else
++
++static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
++{
++	unsigned long sp = regs->regs[29];
++	unsigned long ra = regs->regs[31];
++	unsigned long pc = regs->cp0_epc;
++	int depth = 16;
++
++	printk("Call Trace:\n");
++	while (depth-- && pc) {
++	    print_ip_sym(pc);
++	    pc = find_prev_frame(pc, ra, &sp, 0);
++	    ra = 0;
++	}
++	printk("\n");
++}
++#endif
++
+ /*
+  * This routine abuses get_user()/put_user() to reference pointers
+  * with at least a bit of error checking ...
+@@ -367,6 +388,7 @@ void __noreturn die(const char *str, str
+ 	if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
+ 		sig = 0;
+ 
++	oops_enter();
+ 	console_verbose();
+ 	raw_spin_lock_irq(&die_lock);
+ #ifdef CONFIG_MIPS_MT_SMTC
+@@ -1487,7 +1509,7 @@ void __init *set_except_vector(int n, vo
+ #endif
+ 		u32 *buf = (u32 *)(ebase + 0x200);
+ 		unsigned int k0 = 26;
+-		if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
++		if ((handler & jump_mask) == ((KSEG0ADDR(ebase) + 0x200) & jump_mask)) {
+ 			uasm_i_j(&buf, handler & ~jump_mask);
+ 			uasm_i_nop(&buf);
+ 		} else {
+@@ -1727,6 +1749,7 @@ void __cpuinit per_cpu_trap_init(void)
+ 	 *  o read IntCtl.IPTI to determine the timer interrupt
+ 	 *  o read IntCtl.IPPCI to determine the performance counter interrupt
+ 	 */
++#ifdef CONFIG_CPU_MIPSR2
+ 	if (cpu_has_mips_r2) {
+ 		cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
+ 		cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
+@@ -1734,11 +1757,17 @@ void __cpuinit per_cpu_trap_init(void)
+ 		if (cp0_perfcount_irq == cp0_compare_irq)
+ 			cp0_perfcount_irq = -1;
+ 	} else {
++#endif
+ 		cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
+ 		cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ;
+ 		cp0_perfcount_irq = -1;
++#ifdef CONFIG_CPU_MIPSR2
+ 	}
++#endif
+ 
++#ifdef CONFIG_MIPS_MIKROTIK
++	cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
++#endif
+ #ifdef CONFIG_MIPS_MT_SMTC
+ 	}
+ #endif /* CONFIG_MIPS_MT_SMTC */
+@@ -1833,7 +1862,7 @@ void __init trap_init(void)
+ #define KVM_GUEST_KSEG0     0x40000000
+         ebase = KVM_GUEST_KSEG0;
+ #else
+-        ebase = CKSEG0;
++        ebase = CAC_BASE;
+ #endif
+ 		if (cpu_has_mips_r2)
+ 			ebase += (read_c0_ebase() & 0x3ffff000);
+diff -puNrb linux-3.10.49/arch/mips/kernel/unaligned.c linux-3.10.49-minimal/arch/mips/kernel/unaligned.c
+--- linux-3.10.49/arch/mips/kernel/unaligned.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/kernel/unaligned.c	2014-01-11 07:10:25.000000000 +0000
+@@ -106,6 +106,24 @@ static u32 unaligned_action;
+ #endif
+ extern void show_registers(struct pt_regs *regs);
+ 
++#define RATE_BURST (10*5*HZ)
++#define RATE_COST (5*HZ)
++
++static int un_ratelimit(void) {
++	static unsigned toks = RATE_BURST;
++	static unsigned last_msg;
++
++	unsigned now = jiffies;
++	toks += now - last_msg;
++	if (toks > RATE_BURST) toks = RATE_BURST;
++
++	if (toks >= RATE_COST) {
++		toks -= RATE_COST;
++		return 1;
++	}
++	return 0;
++}
++
+ #ifdef __BIG_ENDIAN
+ #define     LoadHW(addr, value, res)  \
+ 		__asm__ __volatile__ (".set\tnoat\n"        \
+@@ -1549,10 +1579,23 @@ sigill:
+ 	    ("Unhandled kernel unaligned access or invalid instruction", regs);
+ 	force_sig(SIGILL, current);
+ }
++
++extern asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
++				     unsigned long address);
++
+ asmlinkage void do_ade(struct pt_regs *regs)
+ {
+-	unsigned int __user *pc;
++	unsigned int __user *pc = NULL;
+ 	mm_segment_t seg;
++	unsigned long badvaddr = regs->cp0_badvaddr;
++
++	/* We are running in VM protected enviroment and
++	   we hit KSEG0, or KSEG3 address */
++	if ((badvaddr & 3) == 0 && KSEGX(badvaddr) == KSEG3) {
++		do_page_fault(regs, (regs->cp0_cause & 0x7c) == 20,
++			      badvaddr);
++		return;
++	}
+ 
+ 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS,
+ 			1, regs, regs->cp0_badvaddr);
+@@ -1567,6 +1610,10 @@ asmlinkage void do_ade(struct pt_regs *r
+ 	if (unaligned_action == UNALIGNED_ACTION_SIGNAL)
+ 		goto sigbus;
+ 
++	if (!user_mode(regs) && un_ratelimit())
++		printk(KERN_WARNING "unaligned data access %lx at %p %pS\n",
++			badvaddr, pc, (void *)pc);
++
+ 	/*
+ 	 * Do branch emulation only if we didn't forward the exception.
+ 	 * This is all so but ugly ...
+diff -puNrb linux-3.10.49/arch/mips/kernel/vmlinux.lds.S linux-3.10.49-minimal/arch/mips/kernel/vmlinux.lds.S
+--- linux-3.10.49/arch/mips/kernel/vmlinux.lds.S	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/kernel/vmlinux.lds.S	2014-01-11 07:10:42.000000000 +0000
+@@ -51,6 +51,7 @@ SECTIONS
+ 	/* read-only */
+ 	_text = .;	/* Text and read-only data */
+ 	.text : {
++	        HEAD_TEXT
+ 		TEXT_TEXT
+ 		SCHED_TEXT
+ 		LOCK_TEXT
+diff -puNrb linux-3.10.49/arch/mips/lib/iomap.c linux-3.10.49-minimal/arch/mips/lib/iomap.c
+--- linux-3.10.49/arch/mips/lib/iomap.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/lib/iomap.c	2014-01-11 08:11:06.000000000 +0000
+@@ -25,6 +25,8 @@
+ 
+ #define PIO_MASK	0x0ffffUL
+ 
++//#ifndef CONFIG_MIPS_MIKROTIK
++
+ unsigned int ioread8(void __iomem *addr)
+ {
+ 	return readb(addr);
+@@ -194,6 +196,8 @@ void iowrite32_rep(void __iomem *addr, c
+ 
+ EXPORT_SYMBOL(iowrite32_rep);
+ 
++//#endif
++
+ /*
+  * Create a virtual mapping cookie for an IO port range
+  *
+diff -puNrb linux-3.10.49/arch/mips/mm/cache.c linux-3.10.49-minimal/arch/mips/mm/cache.c
+--- linux-3.10.49/arch/mips/mm/cache.c	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/arch/mips/mm/cache.c	2014-01-11 07:11:16.000000000 +0000
+@@ -50,6 +50,7 @@ void (*flush_icache_all)(void);
+ EXPORT_SYMBOL_GPL(local_flush_data_cache_page);
+ EXPORT_SYMBOL(flush_data_cache_page);
+ EXPORT_SYMBOL(flush_icache_all);
++EXPORT_SYMBOL(flush_icache_range);
+ 
+ #ifdef CONFIG_DMA_NONCOHERENT
+ 
+diff -puNrb linux-3.10.49/arch/mips/mm/c-r4k.c linux-3.10.49-minimal/arch/mips/mm/c-r4k.c
+--- linux-3.10.49/arch/mips/mm/c-r4k.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/c-r4k.c	2014-01-11 07:11:25.000000000 +0000
+@@ -1013,7 +1013,9 @@ static void __cpuinit probe_pcache(void)
+ 			      c->dcache.linesz;
+ 		c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);
+ 
++#ifdef CONFIG_CPU_HAS_PREFETCH
+ 		c->options |= MIPS_CPU_PREFETCH;
++#endif
+ 		break;
+ 	}
+ 
+diff -puNrb linux-3.10.49/arch/mips/mm/dma-default.c linux-3.10.49-minimal/arch/mips/mm/dma-default.c
+--- linux-3.10.49/arch/mips/mm/dma-default.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/dma-default.c	2014-01-11 07:11:38.000000000 +0000
+@@ -14,6 +14,10 @@
+ #include <linux/module.h>
+ #include <linux/scatterlist.h>
+ #include <linux/string.h>
++#ifdef CONFIG_MAPPED_KERNEL
++#include <linux/hardirq.h>
++#include <linux/sched.h>
++#endif
+ #include <linux/gfp.h>
+ #include <linux/highmem.h>
+ 
+@@ -68,11 +72,9 @@ static gfp_t massage_gfp_flags(const str
+ 	/* ignore region specifiers */
+ 	gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+ 
+-#ifdef CONFIG_ISA
+ 	if (dev == NULL)
+ 		dma_flag = __GFP_DMA;
+ 	else
+-#endif
+ #if defined(CONFIG_ZONE_DMA32) && defined(CONFIG_ZONE_DMA)
+ 	     if (dev->coherent_dma_mask < DMA_BIT_MASK(32))
+ 			dma_flag = __GFP_DMA;
+@@ -135,8 +137,15 @@ static void *mips_dma_alloc_coherent(str
+ 
+ 		if (!plat_device_is_coherent(dev)) {
+ 			dma_cache_wback_inv((unsigned long) ret, size);
++#ifndef CONFIG_MAPPED_KERNEL
+ 			if (!hw_coherentio)
+ 				ret = UNCAC_ADDR(ret);
++#else
++			if (!in_interrupt())
++				ret = ioremap((unsigned long) *dma_handle, size);
++			else
++				ret = UNCAC_ADDR(ret);
++#endif
+ 		}
+ 	}
+ 
+@@ -162,10 +171,24 @@ static void mips_dma_free_coherent(struc
+ 	if (dma_release_from_coherent(dev, order, vaddr))
+ 		return;
+ 
++#ifndef CONFIG_MAPPED_KERNEL
+ 	plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
+ 
+ 	if (!plat_device_is_coherent(dev) && !hw_coherentio)
+ 		addr = CAC_ADDR(addr);
++#else
++	if (!plat_device_is_coherent(dev)) {
++		pgd_t *pgd = init_mm.pgd + __pgd_offset(addr);
++		pud_t *pud = pud_offset(pgd, addr);
++		pmd_t *pmd = pmd_offset(pud, addr);
++		pte_t *pte = pte_offset(pmd, addr);
++		
++		if (pte_present(*pte)) {
++			addr = (unsigned long) pfn_to_kaddr(pte_pfn(*pte));
++			iounmap(vaddr);
++		}
++	}
++#endif
+ 
+ 	free_pages(addr, get_order(size));
+ }
+diff -puNrb linux-3.10.49/arch/mips/mm/fault.c linux-3.10.49-minimal/arch/mips/mm/fault.c
+--- linux-3.10.49/arch/mips/mm/fault.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/fault.c	2014-01-11 07:11:48.000000000 +0000
+@@ -85,6 +85,12 @@ asmlinkage void __kprobes do_page_fault(
+ 		goto VMALLOC_FAULT_TARGET;
+ #endif
+ 
++#ifdef CONFIG_MAPPED_KERNEL
++	/* in case we touched other VM memory */
++	if (KSEGX(address) == KSEG2)
++		goto VMALLOC_FAULT_TARGET;
++#endif
++
+ 	/*
+ 	 * If we're in an interrupt or have no user
+ 	 * context, we must not take the fault..
+diff -puNrb linux-3.10.49/arch/mips/mm/init.c linux-3.10.49-minimal/arch/mips/mm/init.c
+--- linux-3.10.49/arch/mips/mm/init.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/init.c	2014-01-11 07:12:34.000000000 +0000
+@@ -44,6 +44,10 @@
+ #include <asm/tlb.h>
+ #include <asm/fixmap.h>
+ 
++#ifdef CONFIG_MIPS_MIKROTIK
++#include <asm/rb/boards.h>
++#endif
++
+ /* Atomicity and interruptability */
+ #ifdef CONFIG_MIPS_MT_SMTC
+ 
+@@ -173,7 +177,7 @@ void *kmap_coherent(struct page *page, u
+ 
+ #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+ 
+-void kunmap_coherent(void)
++void kunmap_coherent()
+ {
+ #ifndef CONFIG_MIPS_MT_SMTC
+ 	unsigned int wired;
+@@ -333,6 +337,10 @@ void __init paging_init(void)
+ 
+ #ifdef CONFIG_ZONE_DMA
+ 	max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
++#if defined(CONFIG_MIPS_MIKROTIK)
++//	if (mips_machgroup != MACH_GROUP_MT_RB100)
++		max_zone_pfns[ZONE_DMA] = max_low_pfn;
++#endif
+ #endif
+ #ifdef CONFIG_ZONE_DMA32
+ 	max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
+diff -puNrb linux-3.10.49/arch/mips/mm/ioremap.c linux-3.10.49-minimal/arch/mips/mm/ioremap.c
+--- linux-3.10.49/arch/mips/mm/ioremap.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/ioremap.c	2014-01-11 07:12:48.000000000 +0000
+@@ -127,6 +127,7 @@ void __iomem * __ioremap(phys_t phys_add
+ 	if (!size || last_addr < phys_addr)
+ 		return NULL;
+ 
++#ifndef CONFIG_MAPPED_KERNEL
+ 	/*
+ 	 * Map uncached objects in the low 512mb of address space using KSEG1,
+ 	 * otherwise map using page tables.
+@@ -149,6 +150,7 @@ void __iomem * __ioremap(phys_t phys_add
+ 			if(!PageReserved(page))
+ 				return NULL;
+ 	}
++#endif
+ 
+ 	/*
+ 	 * Mappings have to be page-aligned
+diff -puNrb linux-3.10.49/arch/mips/mm/tlb-r4k.c linux-3.10.49-minimal/arch/mips/mm/tlb-r4k.c
+--- linux-3.10.49/arch/mips/mm/tlb-r4k.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/mm/tlb-r4k.c	2014-01-11 07:13:13.000000000 +0000
+@@ -408,7 +408,9 @@ void __cpuinit tlb_init(void)
+ 	 *     be set to fixed-size pages.
+ 	 */
+ 	write_c0_pagemask(PM_DEFAULT_MASK);
++#ifndef CONFIG_MAPPED_KERNEL
+ 	write_c0_wired(0);
++#endif
+ 	if (current_cpu_type() == CPU_R10000 ||
+ 	    current_cpu_type() == CPU_R12000 ||
+ 	    current_cpu_type() == CPU_R14000)
+diff -puNrb linux-3.10.49/arch/mips/oprofile/common.c linux-3.10.49-minimal/arch/mips/oprofile/common.c
+--- linux-3.10.49/arch/mips/oprofile/common.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/oprofile/common.c	2014-01-11 07:14:43.000000000 +0000
+@@ -11,10 +11,14 @@
+ #include <linux/init.h>
+ #include <linux/oprofile.h>
+ #include <linux/smp.h>
++#include <asm/ptrace.h>
+ #include <asm/cpu-info.h>
++#include <asm/rb/boards.h>
+ 
+ #include "op_impl.h"
+ 
++extern int __init hrtimer_oprofile_init(struct oprofile_operations *);
++
+ extern struct op_mips_model op_model_mipsxx_ops __weak;
+ extern struct op_mips_model op_model_loongson2_ops __weak;
+
+@@ -70,11 +74,30 @@ static void op_mips_stop(void)
+ 	on_each_cpu(model->cpu_stop, NULL, 1);
+ }
+ 
++void mt_op_mips_backtrace(struct pt_regs * const regs, unsigned int depth)
++{
++	unsigned long ra = regs->regs[31];
++	unsigned long pc = regs->cp0_epc;
++	unsigned long sp = regs->regs[29];
++	int usermode = user_mode(regs);
++
++	while (depth-- && pc) {
++	    pc = find_prev_frame(pc, ra, &sp, usermode);
++	    if (pc) oprofile_add_trace((unsigned long) pc);
++	    ra = 0;
++	}
++}
++
+ int __init oprofile_arch_init(struct oprofile_operations *ops)
+ {
+ 	struct op_mips_model *lmodel = NULL;
+ 	int res;
+ 
++	ops->backtrace = mt_op_mips_backtrace;
++
++	if (hrtimer_oprofile_init(ops) == 0)
++		return 0;
++
+ 	switch (current_cpu_type()) {
+ 	case CPU_5KC:
+ 	case CPU_M14KC:
+diff -puNrb linux-3.10.49/arch/mips/oprofile/Makefile linux-3.10.49-minimal/arch/mips/oprofile/Makefile
+--- linux-3.10.49/arch/mips/oprofile/Makefile	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/oprofile/Makefile	2014-01-11 07:15:11.000000000 +0000
+@@ -4,6 +4,7 @@ DRIVER_OBJS = $(addprefix ../../../drive
+ 		oprof.o cpu_buffer.o buffer_sync.o \
+ 		event_buffer.o oprofile_files.o \
+ 		oprofilefs.o oprofile_stats.o \
++		hrtimer.o \
+ 		timer_int.o )
+ 
+ oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
+diff -puNrb linux-3.10.49/arch/mips/rb/irq.c linux-3.10.49-minimal/arch/mips/rb/irq.c
+--- linux-3.10.49/arch/mips/rb/irq.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/irq.c	2014-01-11 08:43:14.000000000 +0000
+@@ -0,0 +1,108 @@
++#include <linux/init.h>
++#include <linux/linkage.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/bitops.h>
++#include <linux/module.h>
++#include <asm/signal.h>
++#include <asm/mipsregs.h>
++#include <asm/irq_cpu.h>
++#include <asm/bootinfo.h>
++#include <asm/vm.h>
++#include <asm/rb/boards.h>
++
++asmlinkage void plat_irq_dispatch(void) {
++	unsigned pending = read_c0_status() & read_c0_cause() & 0xfe00;
++
++	if (pending)
++		do_IRQ(fls(pending) - (9 - MIPS_CPU_IRQ_BASE));
++}
++
++volatile unsigned long virqs;
++EXPORT_SYMBOL(virqs);
++
++static void ack_virq(struct irq_data *d)
++{
++	clear_bit(d->irq - VIRQ_BASE, &virqs);
++}
++
++static inline void unmask_virq(struct irq_data *d)
++{
++}
++
++static inline void mask_virq(struct irq_data *d)
++{
++}
++
++static struct irq_chip virq_controller = {
++	.name	= "virq",
++	.irq_ack	= ack_virq,
++	.irq_unmask     = unmask_virq,
++	.irq_mask	= mask_virq,
++};
++
++static irqreturn_t virq_cascade_irq(int irq, void *dev_id)
++{
++	unsigned i;
++	unsigned irqs = virqs;
++
++	for (i = 0; irqs; ++i) {
++		if (irqs & (1 << i)) {
++			do_IRQ(i + VIRQ_BASE);
++			irqs ^= (1 << i);
++		}
++	}
++	return IRQ_HANDLED;
++}
++
++static struct irqaction virq_cascade  = {
++	.handler = virq_cascade_irq,
++	.name = "virq-cascade",
++};
++
++static void soft_irq_ack(struct irq_data *d)
++{
++	clear_c0_cause(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
++}
++
++static inline void unmask_soft_irq(struct irq_data *d)
++ {
++	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
++	irq_enable_hazard();
++ }
++ 
++static inline void mask_soft_irq(struct irq_data *d)
++{
++	clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
++	irq_disable_hazard();
++}
++
++static struct irq_chip soft_irq_controller = {
++	.name	= "MIPS",
++	.irq_ack	= soft_irq_ack,
++	.irq_unmask     = unmask_soft_irq,
++	.irq_mask	= mask_soft_irq,
++};
++
++extern void ont_arch_init_irq(void);
++
++void __init arch_init_irq(void)
++{
++	unsigned i;
++
++	switch (mips_machgroup) {
++	case MACH_GROUP_MT_VM:
++		mips_cpu_irq_init();
++		break;
++	}
++
++	if (mips_machgroup != MACH_GROUP_MT_RB500 &&
++	    mips_machgroup != MACH_GROUP_MT_RB100) {
++		irq_set_chip_and_handler(1, &soft_irq_controller, handle_percpu_irq);
++		setup_irq(1, &virq_cascade);
++		
++		for (i = VIRQ_BASE;  i < VIRQ_BASE + 32; ++i)
++			irq_set_chip_and_handler(i, &virq_controller,
++						 handle_edge_irq);
++	}
++}
+diff -puNrb linux-3.10.49/arch/mips/rb/Makefile linux-3.10.49-minimal/arch/mips/rb/Makefile
+--- linux-3.10.49/arch/mips/rb/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/Makefile	2014-01-11 08:15:03.000000000 +0000
+@@ -0,0 +1 @@
++obj-y += prom.o platform.o irq.o
+diff -puNrb linux-3.10.49/arch/mips/rb/Platform linux-3.10.49-minimal/arch/mips/rb/Platform
+--- linux-3.10.49/arch/mips/rb/Platform	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/Platform	2014-01-11 07:18:49.000000000 +0000
+@@ -0,0 +1,13 @@
++#
++# Mikrotik RB100/RB500 boards
++#
++platform-$(CONFIG_MIPS_MIKROTIK) += rb/
++platform-$(CONFIG_MIPS_MIKROTIK) += rb/vm/
++cflags-$(CONFIG_MIPS_MIKROTIK) += -I$(srctree)/arch/mips/include/asm/mach-rb
++ifdef CONFIG_MAPPED_KERNEL
++load-$(CONFIG_MIPS_MIKROTIK) += 0xffffffffc0101000
++OBJCOPYFLAGS += --change-addresses=0xc0000000
++else
++load-$(CONFIG_MIPS_MIKROTIK) += 0xffffffff80101000
++endif
++
+diff -puNrb linux-3.10.49/arch/mips/rb/platform.c linux-3.10.49-minimal/arch/mips/rb/platform.c
+--- linux-3.10.49/arch/mips/rb/platform.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/platform.c	2014-01-11 08:04:11.000000000 +0000
+@@ -0,0 +1,18 @@
++#include <linux/platform_device.h>
++#include <linux/serial.h>
++#include <linux/serial_8250.h>
++#include <linux/spi/spi.h>
++#include <linux/mtd/partitions.h>
++#include <linux/spi/flash.h>
++#include <linux/i2c-gpio.h>
++#include <asm/bootinfo.h>
++#include <asm/rb/boards.h>
++#include <asm/rb/booter.h>
++#include <asm/serial.h>
++
++int rb_platform_init(void)
++{
++	return 0;
++}
++
++arch_initcall(rb_platform_init);
+diff -puNrb linux-3.10.49/arch/mips/rb/prom.c linux-3.10.49-minimal/arch/mips/rb/prom.c
+--- linux-3.10.49/arch/mips/rb/prom.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/prom.c	2014-01-11 08:48:36.000000000 +0000
+@@ -0,0 +1,152 @@
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/console.h>
++#include <asm/bootinfo.h>
++#include <asm/rb/boards.h>
++#include <linux/bootmem.h>
++#include <linux/ioport.h>
++#include <linux/ctype.h>
++#include <linux/irq.h>
++#include <linux/initrd.h>
++
++#define FREQ_TAG   "HZ="
++#define BOARD_TAG  "board="
++
++#define SR_NMI	0x00180000
++
++extern void rbvm_setup(void);
++
++extern char arcs_cmdline[COMMAND_LINE_SIZE];
++
++extern unsigned long totalram_pages;
++extern unsigned long mips_hpt_frequency;
++
++unsigned char mips_mac_address[6];
++
++unsigned long mips_machgroup __read_mostly = 0;
++EXPORT_SYMBOL(mips_machgroup);
++
++const char *get_system_type(void)
++{
++	switch (mips_machgroup) {
++	case MACH_GROUP_MT_VM:
++		return "Mikrotik VM";
++	}
++	return "unknown routerboard";
++}
++
++void __init prom_init(void)
++{
++	int argc = fw_arg0;
++	char **argv = (char **) fw_arg1;
++	unsigned char board_type[16];
++
++	unsigned i, offset = 0;
++
++	set_io_port_base(KSEG1);
++
++	memset(board_type, 0, sizeof(board_type));
++
++	/* HZ must be parsed here because otherwise is too late */
++	for (i = 0; (i < argc && argv[i] != NULL); i++) {
++		if (strncmp(argv[i], FREQ_TAG, sizeof(FREQ_TAG) - 1) == 0) {
++			mips_hpt_frequency = 
++			    simple_strtoul(argv[i] + sizeof(FREQ_TAG) - 1, 0, 10);
++			continue;
++		}
++		if (strncmp(argv[i], BOARD_TAG, sizeof(BOARD_TAG) - 1) == 0) {
++			strncpy(board_type, argv[i] + sizeof(BOARD_TAG) - 1,
++				sizeof(board_type));
++		}
++		offset += snprintf(arcs_cmdline + offset, sizeof(arcs_cmdline) - offset,
++				   "%s ", argv[i]);
++	}
++
++	mips_machgroup = MACH_GROUP_MT_VM;
++	mips_machtype = 0;
++}
++
++void __init prom_free_prom_memory(void)
++{
++	unsigned long addr, end;
++	extern char _text;
++
++	/*
++	 * Free everything below the kernel itself but leave
++	 * the first page reserved for the exception handlers.
++	 */
++
++	end = __pa(&_text);
++	addr = PAGE_SIZE;
++
++	while (addr < end) {
++		ClearPageReserved(virt_to_page(__va(addr)));
++		init_page_count(virt_to_page(__va(addr)));
++		free_page((unsigned long)__va(addr));
++		addr += PAGE_SIZE;
++		++totalram_pages;
++	}
++}
++
++void __init plat_mem_setup(void)
++{
++#ifdef CONFIG_BLK_DEV_INITRD
++	extern int _end;
++	u32 *initrd_header;
++
++	initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
++	if (initrd_header[0] == 0x494E5244) {
++		initrd_start = (unsigned long) (initrd_header + 2);
++                initrd_end = initrd_start + initrd_header[1];
++	}
++#endif    
++
++	switch (mips_machgroup) {
++	case MACH_GROUP_MT_VM:
++		rbvm_setup();
++		break;
++	}
++}
++
++void __init plat_time_init(void)
++{
++}
++
++static int __init setup_kmac(char *s)
++{
++	int i, j;
++	unsigned char result, value;
++
++	for (i = 0; i < 6; i++) {
++		if (s[0] == '\0' || s[1] == '\0') return 0;
++		if (i != 5 && s[2] != ':') return 0;
++
++		result = 0;
++		for (j = 0; j < 2; j++) {
++			if (!isxdigit(*s)) return 0;
++
++			value = isdigit(*s) ? *s - '0' :
++				toupper(*s) - 'A' + 10;
++			if (value >= 16) return 0;
++
++			result = result * 16 + value;
++                        s++;
++                }
++
++                s++;
++                mips_mac_address[i] = result;
++        }
++
++        return *s == '\0';
++}
++
++__setup("kmac=", setup_kmac);
++
++EXPORT_SYMBOL(mips_mac_address);
++
++unsigned long long sched_clock(void)
++{
++	return read_c0_count() * 1000000000 / mips_hpt_frequency;
++}
+diff -puNrb linux-3.10.49/arch/mips/rb/vm/Makefile linux-3.10.49-minimal/arch/mips/rb/vm/Makefile
+--- linux-3.10.49/arch/mips/rb/vm/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/vm/Makefile	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1 @@
++obj-y	 := setup.o
+diff -puNrb linux-3.10.49/arch/mips/rb/vm/setup.c linux-3.10.49-minimal/arch/mips/rb/vm/setup.c
+--- linux-3.10.49/arch/mips/rb/vm/setup.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/arch/mips/rb/vm/setup.c	2014-01-11 05:37:12.000000000 +0000
+@@ -0,0 +1,142 @@
++#include <linux/interrupt.h>
++#include <linux/sched.h>
++#include <asm/reboot.h>
++#include <asm/vm.h>
++#include <asm/rb/boards.h>
++
++#define BUF_SIZE	256
++#define BUF_COUNT	4
++
++hypercall(vm_create_queue, 4, unsigned id, unsigned irq,
++		 unsigned tx, unsigned rx);
++hypercall(vm_release_queue, 5, unsigned id);
++hypercall(vm_running, 6, void);
++hypercall(vm_setup_irqs, 14, unsigned *irqs, unsigned count);
++
++static volatile struct vdma_descr tx_chain[BUF_COUNT];
++static volatile struct vdma_descr rx_chain[BUF_COUNT];
++static unsigned char tx_buffers[BUF_COUNT][BUF_SIZE];
++static unsigned char rx_buffers[BUF_COUNT][BUF_SIZE];
++
++static unsigned cur_tx;
++static unsigned cur_rx;
++
++static int send_message(const unsigned char *buf, int len)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	/* drop some data if full buffer */
++	while (tx_chain[cur_tx].size & DONE)
++		asm volatile ("wait");
++
++	len = min_t(int, len, BUF_SIZE);
++	memcpy(tx_buffers[cur_tx], buf, len);
++	tx_chain[cur_tx].size = len | DONE;
++
++	cur_tx = (cur_tx + 1) % BUF_COUNT;
++
++	local_irq_restore(flags);
++
++	return len;
++}
++
++static int recv_message(char *buf, int len)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++
++	if (!(rx_chain[cur_rx].size & DONE)) {
++		local_irq_restore(flags);
++		return 0;
++	}
++	
++	len = min_t(int, len, rx_chain[cur_rx].size & ~DONE);
++	memcpy(buf, rx_buffers[cur_rx], len);
++
++	rx_chain[cur_rx].size = BUF_SIZE;
++	cur_rx = (cur_rx + 1) % BUF_COUNT;
++
++	local_irq_restore(flags);
++
++	return len;
++}
++
++static irqreturn_t ctrl_interrupt(int irq, void *dev_id)
++{
++	struct task_struct *init;
++	char buf[256];
++	int len;
++
++	len = recv_message(buf, sizeof(buf));
++	if (len <= 0)
++		return IRQ_HANDLED;
++
++	if (strncmp(buf, "restart", len) == 0) {
++		printk("RESTART\n");
++		init = find_task_by_pid_ns(1, &init_pid_ns);
++		if (init)
++			send_sig(SIGINT, init, 1);
++	} else if (strncmp(buf, "halt", len) == 0) {
++	    printk("HALT\n");
++		init = find_task_by_pid_ns(1, &init_pid_ns);
++		if (init)
++			send_sig(SIGWINCH, init, 1);
++	}
++
++	return IRQ_HANDLED;
++}
++
++static void rbvm_machine_restart(char *command)
++{
++	char msg[] = "restart";
++
++	send_message(msg, sizeof(msg));
++}
++
++static void rbvm_machine_halt(void)
++{
++	char msg[] = "halt";
++
++	send_message(msg, sizeof(msg));
++}
++
++void __init rbvm_setup(void)
++{
++	extern unsigned long virqs;
++	int i;
++
++	vm_setup_irqs((unsigned *) &virqs, 32);
++
++	for (i = 0; i < BUF_COUNT; ++i) {
++		rx_chain[i].addr = (unsigned) rx_buffers[i];
++		rx_chain[i].size = BUF_SIZE;
++		rx_chain[i].next = (unsigned) &rx_chain[i + 1];
++		
++		tx_chain[i].addr = (unsigned) tx_buffers[i];
++		tx_chain[i].size = 0;
++		tx_chain[i].next = (unsigned) &tx_chain[i + 1];
++	}
++	rx_chain[BUF_COUNT - 1].next = (unsigned) &rx_chain[0];
++	tx_chain[BUF_COUNT - 1].next = (unsigned) &tx_chain[0];
++
++	vm_create_queue(0, 0, (unsigned) &tx_chain[0],
++			(unsigned) &rx_chain[0]);
++
++	_machine_restart = rbvm_machine_restart;
++	_machine_halt = rbvm_machine_halt;
++}
++
++int __init init_ctrl_interrupt(void)
++{
++	if (mips_machgroup != MACH_GROUP_MT_VM)
++		return 0;
++
++	if (request_irq(VIRQ_BASE + 0, ctrl_interrupt, 0, "ctrl", (void *) 1))
++		return -EBUSY;
++	return 0;
++
++}
++arch_initcall(init_ctrl_interrupt);
+diff -puNrb linux-3.10.49/drivers/block/loop.c linux-3.10.49-minimal/drivers/block/loop.c
+--- linux-3.10.49/drivers/block/loop.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/drivers/block/loop.c	2014-01-11 07:26:26.000000000 +0000
+@@ -372,6 +372,9 @@ do_lo_receive(struct loop_device *lo,
+ 	struct file *file;
+ 	ssize_t retval;
+ 
++	pgoff_t index;
++	pgoff_t last_index;
++
+ 	cookie.lo = lo;
+ 	cookie.page = bvec->bv_page;
+ 	cookie.offset = bvec->bv_offset;
+@@ -386,6 +389,11 @@ do_lo_receive(struct loop_device *lo,
+ 	file = lo->lo_backing_file;
+ 	retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor);
+ 
++	/* HACK: try to free up page cache from tripple buffers */
++	index = pos >> PAGE_CACHE_SHIFT;
++	last_index = (pos + bsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
++	invalidate_mapping_pages(file->f_mapping, index, last_index);
++
+ 	return retval;
+ }
+ 
+diff -puNrb linux-3.10.49/drivers/char/Kconfig linux-3.10.49-minimal/drivers/char/Kconfig
+--- linux-3.10.49/drivers/char/Kconfig	2014-01-11 05:33:54.000000000 +0000
++++ linux-3.10.49-minimal/drivers/char/Kconfig	2014-01-11 07:26:40.000000000 +0000
+@@ -156,6 +156,13 @@ config PPDEV
+ 	  If unsure, say N.
+ 
+ source "drivers/tty/hvc/Kconfig"
++config HVC_META
++	bool "MetaROUTER Hypervisor Console support"
++	depends on METAROUTER || MIPS_MIKROTIK
++	select HVC_DRIVER
++	select HVC_IRQ
++	default y
++
+ 
+ config VIRTIO_CONSOLE
+ 	tristate "Virtio console"
+@@ -606,4 +613,3 @@ config TILE_SROM
+ 	  how to partition a single ROM for multiple purposes.
+ 
+ endmenu
+-
+diff -puNrb linux-3.10.49/drivers/net/ethernet/Kconfig linux-3.10.49-minimal/drivers/net/ethernet/Kconfig
+--- linux-3.10.49/drivers/net/ethernet/Kconfig	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/drivers/net/ethernet/Kconfig	2014-01-11 07:30:08.000000000 +0000
+@@ -85,6 +85,11 @@ config LANTIQ_ETOP
+ 	---help---
+ 	  Support for the MII0 inside the Lantiq SoC
+ 
++config MT_VETH
++	bool "MetaROUTER Virtual Ethernet support"
++	depends on METAROUTER || MIPS_MIKROTIK
++	default y
++
+ source "drivers/net/ethernet/marvell/Kconfig"
+ source "drivers/net/ethernet/mellanox/Kconfig"
+ source "drivers/net/ethernet/micrel/Kconfig"
+diff -puNrb linux-3.10.49/drivers/net/ethernet/Makefile linux-3.10.49-minimal/drivers/net/ethernet/Makefile
+--- linux-3.10.49/drivers/net/ethernet/Makefile	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/drivers/net/ethernet/Makefile	2014-01-11 07:30:34.000000000 +0000
+@@ -35,6 +35,7 @@ obj-$(CONFIG_NET_VENDOR_XSCALE) += xscal
+ obj-$(CONFIG_IP1000) += icplus/
+ obj-$(CONFIG_JME) += jme.o
+ obj-$(CONFIG_KORINA) += korina.o
++obj-$(CONFIG_MT_VETH) += mtveth.o
+ obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
+ obj-$(CONFIG_NET_VENDOR_MARVELL) += marvell/
+ obj-$(CONFIG_NET_VENDOR_MELLANOX) += mellanox/
+diff -puNrb linux-3.10.49/drivers/net/ethernet/mtveth.c linux-3.10.49-minimal/drivers/net/ethernet/mtveth.c
+--- linux-3.10.49/drivers/net/ethernet/mtveth.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/drivers/net/ethernet/mtveth.c	2014-01-11 07:30:48.000000000 +0000
+@@ -0,0 +1,284 @@
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/interrupt.h>
++#include <asm/vm.h>
++
++#define MAX_IFACES	8
++
++#define TXBUF_COUNT	1024
++#define RXBUF_COUNT	128
++
++#define RXBUF_SIZE	1600
++
++extern int vm_create_queue(unsigned id, unsigned irq,
++			   unsigned tx, unsigned rx);
++extern int vm_release_queue(unsigned id);
++
++#define CMD_NEWIFACE	0
++#define CMD_DELIFACE	1
++
++struct ctrl_msg {
++	unsigned cmd;
++	unsigned short id;
++	unsigned char hwaddr[6];
++} __attribute__((packed));
++
++static volatile struct vdma_descr rx_descr[RXBUF_COUNT];
++static volatile struct vdma_descr tx_descr[TXBUF_COUNT];
++static struct sk_buff *rx_skbs[RXBUF_COUNT];
++static struct sk_buff *tx_skbs[TXBUF_COUNT];
++
++static unsigned last_tx;
++static atomic_t cur_tx;
++static unsigned cur_rx;
++static unsigned max_tx;
++
++static struct net_device *devs[MAX_IFACES];
++
++struct veth_private {
++	unsigned id;
++	atomic_t pending_tx;
++};
++
++static void ctrl_receiver(struct work_struct *work);
++
++static struct sk_buff_head ctrl_queue;
++static DECLARE_WORK(ctrl_work, ctrl_receiver);
++
++static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct veth_private *veth = netdev_priv(dev);
++	unsigned cur = atomic_read(&cur_tx) % TXBUF_COUNT;
++    
++	if (skb_padto(skb, ETH_ZLEN))
++		return NETDEV_TX_OK;
++
++	if (tx_descr[cur].size & DONE) {
++		dev->stats.tx_dropped++;
++		dev_kfree_skb_any(skb);
++		return NETDEV_TX_OK;
++	}
++
++	if (skb_headroom(skb) < 2) {
++		struct sk_buff *s = skb;
++		skb = skb_realloc_headroom(s, 2);
++		dev_kfree_skb_any(s);
++	} else {
++		skb = skb_unshare(skb, GFP_ATOMIC);
++	}
++	if (!skb) {
++		dev->stats.tx_dropped++;
++		return NETDEV_TX_OK;
++	}
++	*(u16 *) skb_push(skb, 2) = veth->id;
++
++	dev->stats.tx_packets++;
++	dev->stats.tx_bytes += skb->len;
++
++	tx_descr[cur].addr = (unsigned) skb->data;
++	tx_descr[cur].size = skb->len | DONE;
++
++	if (tx_skbs[cur]) {
++		/* should not happen */
++		dev->stats.tx_dropped++;
++		dev_kfree_skb_any(skb);
++		return NETDEV_TX_BUSY;
++	}
++
++	tx_skbs[cur] = skb;
++	atomic_add(1, &cur_tx);
++
++	if (atomic_add_return(1, &veth->pending_tx) >= max_tx) {
++		netif_stop_queue(dev);
++
++		/* in case we got rewaken right before stop */
++		if (atomic_read(&veth->pending_tx) < max_tx)
++			netif_wake_queue(dev);
++	}
++
++	return 0;
++}
++
++static irqreturn_t veth_interrupt(int irq, void *dev_id)
++{
++	unsigned cur;
++
++	while (last_tx != atomic_read(&cur_tx)) {
++		unsigned last = last_tx % TXBUF_COUNT;
++		struct net_device *dev;
++		struct veth_private *veth;
++
++		if (tx_descr[last].size & DONE)
++			break;
++
++		dev = tx_skbs[last]->dev;
++		veth = netdev_priv(dev);
++		dev_kfree_skb_irq(tx_skbs[last]);
++		tx_skbs[last] = NULL;
++
++		++last_tx;
++
++		if (atomic_sub_return(1, &veth->pending_tx) < max_tx)
++			netif_wake_queue(dev);
++	}
++
++	cur = cur_rx % RXBUF_COUNT;
++	while ((rx_descr[cur].size & DONE)) {
++		struct sk_buff *skb = rx_skbs[cur];
++		struct net_device *dev;
++		unsigned id;
++
++		skb_put(skb, rx_descr[cur].size & ~DONE);
++		if (skb->len < 2) {
++			dev_kfree_skb_irq(skb);
++			goto next;
++		}
++
++		id = *(u16 *) skb->data;
++		skb_pull(skb, 2);
++
++		if (id == 0) {
++			__skb_queue_tail(&ctrl_queue, skb);
++			schedule_work(&ctrl_work);
++			goto next;
++		}
++		if (id >= MAX_IFACES || !devs[id]) {
++			dev_kfree_skb_irq(skb);
++			goto next;
++		}
++		dev = devs[id];
++
++		skb->dev = dev;
++		skb->protocol = eth_type_trans(skb, dev);
++
++		dev->last_rx = jiffies;
++		++dev->stats.rx_packets;
++		dev->stats.rx_bytes += skb->len;
++
++		netif_rx(skb);
++
++	  next:
++		skb = dev_alloc_skb(RXBUF_SIZE);
++		rx_skbs[cur] = skb;
++		if (skb) {
++			rx_descr[cur].addr = (unsigned) skb->data;
++			rx_descr[cur].size = RXBUF_SIZE;
++		} else {
++			rx_descr[cur].size = 0;
++		}
++
++		++cur_rx;
++		cur = cur_rx % RXBUF_COUNT;
++	}
++
++	return IRQ_HANDLED;
++}
++
++static const struct net_device_ops veth_netdev_ops = {
++	.ndo_start_xmit		= veth_xmit,
++};
++
++static int veth_alloc_dev(unsigned id, const unsigned char *hwaddr)
++{
++	struct veth_private *veth;
++	struct net_device *dev;
++	int err;
++
++	//SET_NETDEV_DEV(dev, &pdev->dev);
++	//platform_set_drvdata(pdev, dev);
++
++	dev = alloc_etherdev(sizeof(struct veth_private));
++	if (!dev)
++		return -ENOMEM;
++
++	veth = netdev_priv(dev);
++	veth->id = id;
++	atomic_set(&veth->pending_tx, 1);
++	memcpy(dev->dev_addr, hwaddr, 6);
++	dev->netdev_ops = &veth_netdev_ops;
++
++	err = register_netdev(dev);
++	if (err < 0) {
++		printk("cannot register net device %u\n", err);
++		goto netdev_err;
++	}
++
++	devs[id] = dev;
++	return 0;
++
++  netdev_err:
++	free_netdev(dev);
++	return err;
++}
++
++static int recv_ctrl_msg(struct sk_buff *skb)
++{
++	struct ctrl_msg *msg = (struct ctrl_msg *) skb->data;
++
++	if (skb->len < sizeof(struct ctrl_msg))
++		return -EINVAL;
++
++	if (msg->cmd == CMD_NEWIFACE) {
++		if (msg->id >= MAX_IFACES || devs[msg->id])
++			return -EBUSY;
++
++		veth_alloc_dev(msg->id, msg->hwaddr);
++		return 0;
++	} else if (msg->cmd == CMD_DELIFACE) {
++		struct net_device *dev;
++
++		if (msg->id >= MAX_IFACES || !devs[msg->id])
++			return -EINVAL;
++		
++		dev = devs[msg->id];
++		devs[msg->id] = NULL;
++
++		unregister_netdev(dev);
++	}
++	return -EINVAL;
++}
++
++static void ctrl_receiver(struct work_struct *work)
++{
++	struct sk_buff *skb;
++
++	while ((skb = skb_dequeue(&ctrl_queue)))
++		recv_ctrl_msg(skb);
++}
++
++int veth_init(void)
++{
++	unsigned i;
++
++	if (vm_running() != 0)
++		return 0;
++
++	skb_queue_head_init(&ctrl_queue);
++
++	if (request_irq(get_virq_nr(3), veth_interrupt, IRQF_SHARED,
++			"veth", (void *) 1))
++		return -EBUSY;
++
++	for (i = 0; i < TXBUF_COUNT; ++i) {
++		tx_descr[i].addr = 0;
++		tx_descr[i].size = 0;
++		tx_descr[i].next = (unsigned) &tx_descr[i + 1];
++	}
++	for (i = 0; i < RXBUF_COUNT; ++i) {
++		rx_skbs[i] = dev_alloc_skb(RXBUF_SIZE);
++		rx_descr[i].addr = (unsigned) rx_skbs[i]->data;
++		rx_descr[i].size = RXBUF_SIZE;
++		rx_descr[i].next = (unsigned) &rx_descr[i + 1];
++	}
++	tx_descr[TXBUF_COUNT - 1].next = (unsigned) &tx_descr[0];
++	rx_descr[RXBUF_COUNT - 1].next = (unsigned) &rx_descr[0];
++	
++	vm_create_queue(3, 3,
++			(unsigned) &tx_descr[0], (unsigned) &rx_descr[0]);
++
++	max_tx = TXBUF_COUNT / MAX_IFACES;
++
++	return 0;
++}
++module_init(veth_init);
+diff -puNrb linux-3.10.49/drivers/tty/hvc/hvc_console.c linux-3.10.49-minimal/drivers/tty/hvc/hvc_console.c
+--- linux-3.10.49/drivers/tty/hvc/hvc_console.c	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/drivers/tty/hvc/hvc_console.c	2014-01-11 07:33:14.000000000 +0000
+@@ -588,7 +588,7 @@ static int hvc_chars_in_buffer(struct tt
+  * there has been no input for some time.
+  */
+ #define MIN_TIMEOUT		(10)
+-#define MAX_TIMEOUT		(2000)
++#define MAX_TIMEOUT		(200)
+ static u32 timeout = MIN_TIMEOUT;
+ 
+ #define HVC_POLL_READ	0x00000001
+diff -puNrb linux-3.10.49/drivers/tty/hvc/hvc_meta.c linux-3.10.49-minimal/drivers/tty/hvc/hvc_meta.c
+--- linux-3.10.49/drivers/tty/hvc/hvc_meta.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/drivers/tty/hvc/hvc_meta.c	2014-01-11 07:33:36.000000000 +0000
+@@ -0,0 +1,135 @@
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/mm.h>
++#include <linux/bootmem.h>
++#include <linux/slab.h>
++#include <asm/vm.h>
++#include <asm/irq.h>
++#include "hvc_console.h"
++
++extern int vm_create_queue(unsigned id, unsigned irq,
++			   unsigned tx, unsigned rx);
++extern int vm_release_queue(unsigned id);
++
++#define BUF_SIZE	4096
++
++static volatile struct vdma_descr tx_descr;
++static volatile struct vdma_descr rx_descr;
++
++static unsigned rx_offset;
++static DEFINE_SPINLOCK(lock);
++
++static int put_chars(u32 vtermno, const char *buf, int count)
++{
++	unsigned long flags;
++	int i;
++
++	spin_lock_irqsave(&lock, flags);
++
++#ifdef __powerpc__
++	for (i = 0; i < 2000000; ++i) {
++#else
++	for (i = 0; i < 2; ++i) {
++#endif
++		unsigned size = xchg(&tx_descr.size, 0);
++
++		if (!(size & DONE)) {
++			count = min(count, BUF_SIZE);
++			memcpy((char *) tx_descr.addr, buf, count);
++			tx_descr.size = count | DONE;
++
++			spin_unlock_irqrestore(&lock, flags);
++			return count;
++		}
++
++		if (size == (BUF_SIZE | DONE)) {
++			if (i == 0) {
++				tx_descr.size = size;
++				hc_yield();
++				continue;
++			} else {
++				unsigned drop = BUF_SIZE / 4;
++				size = BUF_SIZE - drop;
++				memcpy((char *) tx_descr.addr,
++				       (char *) tx_descr.addr + drop,
++				       size);
++			}
++		}
++
++		size &= ~DONE;
++		count = min(BUF_SIZE - (int) size, count);
++		memcpy((char *) tx_descr.addr + size, buf, count);
++		tx_descr.size = (size + count) | DONE;
++
++		spin_unlock_irqrestore(&lock, flags);
++		return count;
++	}
++
++	spin_unlock_irqrestore(&lock, flags);
++	return 0;
++}
++
++static int get_chars(u32 vtermno, char *buf, int count)
++{
++	unsigned long flags;
++	unsigned size;
++
++	spin_lock_irqsave(&lock, flags);
++
++	if (!(rx_descr.size & DONE)) {
++		spin_unlock_irqrestore(&lock, flags);
++		return -EAGAIN;
++	}
++	
++	size = (rx_descr.size & ~DONE) - rx_offset;
++	count = min(count, (int) size);
++
++	memcpy(buf, (char *) rx_descr.addr + rx_offset, count);
++
++	if (count == size) {
++		rx_descr.size = BUF_SIZE;
++		rx_offset = 0;
++	} else {
++		rx_offset += count;
++	}
++
++	spin_unlock_irqrestore(&lock, flags);
++	return count;
++}
++
++static struct hv_ops cons = {
++	.put_chars = put_chars,
++	.get_chars = get_chars,
++	.notifier_add = notifier_add_irq,
++	.notifier_del = notifier_del_irq,
++};
++
++static int __init cons_init(void)
++{
++	if (vm_running() != 0)
++		return 0;
++
++	rx_descr.addr = (unsigned) kmalloc(BUF_SIZE, GFP_KERNEL);
++	rx_descr.size = BUF_SIZE;
++	rx_descr.next = (unsigned) &rx_descr;
++	
++	tx_descr.addr = (unsigned) kmalloc(BUF_SIZE, GFP_KERNEL);
++	tx_descr.size = 0;
++	tx_descr.next = (unsigned) &tx_descr;
++
++	vm_create_queue(1, 1,
++			(unsigned) &tx_descr, (unsigned) &rx_descr);
++
++	return hvc_instantiate(0, 0, &cons);
++}
++console_initcall(cons_init);
++
++int vm_init(void)
++{
++	if (vm_running() == 0) 
++		hvc_alloc(0, get_virq_nr(1), &cons, 256);
++	return 0;
++}
++module_init(vm_init);
+diff -puNrb linux-3.10.49/drivers/tty/hvc/Makefile linux-3.10.49-minimal/drivers/tty/hvc/Makefile
+--- linux-3.10.49/drivers/tty/hvc/Makefile	2012-06-01 08:16:13.000000000 +0100
++++ linux-3.10.49-minimal/drivers/tty/hvc/Makefile	2014-01-11 07:33:59.000000000 +0000
+@@ -8,6 +8,7 @@ obj-$(CONFIG_HVC_BEAT)		+= hvc_beat.o
+ obj-$(CONFIG_HVC_DRIVER)	+= hvc_console.o
+ obj-$(CONFIG_HVC_IRQ)		+= hvc_irq.o
+ obj-$(CONFIG_HVC_XEN)		+= hvc_xen.o
++obj-$(CONFIG_HVC_META)		+= hvc_meta.o
+ obj-$(CONFIG_HVC_IUCV)		+= hvc_iucv.o
+ obj-$(CONFIG_HVC_UDBG)		+= hvc_udbg.o
+ obj-$(CONFIG_HVC_BFIN_JTAG)	+= hvc_bfin_jtag.o
+diff -puNrb linux-3.10.49/fs/Kconfig linux-3.10.49-minimal/fs/Kconfig
+--- linux-3.10.49/fs/Kconfig	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/fs/Kconfig	2014-01-11 07:36:36.000000000 +0000
+@@ -217,6 +217,7 @@ source "fs/pstore/Kconfig"
+ source "fs/exofs/Kconfig"
+ source "fs/f2fs/Kconfig"
+ source "fs/efivarfs/Kconfig"
++source "fs/metafs/Kconfig"
+ 
+ endif # MISC_FILESYSTEMS
+ 
+diff -puNrb linux-3.10.49/fs/Makefile linux-3.10.49-minimal/fs/Makefile
+--- linux-3.10.49/fs/Makefile	2014-01-11 05:33:53.000000000 +0000
++++ linux-3.10.49-minimal/fs/Makefile	2014-01-11 07:37:06.000000000 +0000
+@@ -62,6 +62,7 @@ obj-$(CONFIG_PROFILING)		+= dcookies.o
+ obj-$(CONFIG_DLM)		+= dlm/
+  
+ # Do not add any filesystems before this line
++obj-$(CONFIG_META_FS)		+= metafs/
+ obj-$(CONFIG_FSCACHE)		+= fscache/
+ obj-$(CONFIG_REISERFS_FS)	+= reiserfs/
+ obj-$(CONFIG_EXT3_FS)		+= ext3/ # Before ext2 so root fs can be ext3
+diff -puNrb linux-3.10.49/fs/metafs/inode.c linux-3.10.49-minimal/fs/metafs/inode.c
+--- linux-3.10.49/fs/metafs/inode.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/fs/metafs/inode.c	2014-01-11 05:37:13.000000000 +0000
+@@ -0,0 +1,909 @@
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/statfs.h>
++#include <linux/pagemap.h>
++#include <linux/namei.h>
++#include <linux/slab.h>
++#include <linux/mount.h>
++#include <asm/vm.h>
++
++#define CMD_GETINODE		0
++#define CMD_RELEASE_INODE	1
++#define CMD_LOOKUP		2
++#define CMD_READPAGE		3
++#define CMD_READLINK		4
++#define CMD_READDIR		5
++#define CMD_WRITEPAGE		6
++#define CMD_CREATE		7
++#define CMD_UNLINK		8
++#define CMD_SYMLINK		9
++#define CMD_RENAME		10
++#define CMD_SETINODE		11
++#define CMD_STATFS		12
++#define CMD_HLINK		13
++#define CMD_FSYNC		14
++
++struct hptime {
++	unsigned sec;
++	unsigned nsec;
++};
++
++struct getinode_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++} __attribute__((packed));
++
++struct inode_rep {
++	int status;
++	unsigned long long ino;
++	unsigned long long size;
++	unsigned mode;
++	unsigned nlink;
++	unsigned uid;
++	unsigned gid;
++	unsigned rdev;
++	struct hptime atime;
++	struct hptime mtime;
++	struct hptime ctime;
++	unsigned long blksize;
++	unsigned long long blocks;
++} __attribute__((packed));
++
++struct setinode_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++	unsigned long long size;
++	unsigned mode;
++	unsigned uid;
++	unsigned gid;
++	unsigned rdev;
++} __attribute__((packed));
++
++struct lookup_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long parent_ino;
++	char name[0];
++} __attribute__((packed));
++
++struct create_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long parent_ino;
++	unsigned mode;
++	unsigned dev;
++	char name[0];
++} __attribute__((packed));
++
++struct unlink_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long parent_ino;
++	char name[0];
++} __attribute__((packed));
++
++struct symlink_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long parent_ino;
++	unsigned namelen;
++	char names[0];
++} __attribute__((packed));
++
++struct hlink_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long parent_ino;
++	unsigned long long ino;
++	char name[0];
++} __attribute__((packed));
++
++struct rename_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long old_parent_ino;
++	unsigned long long new_parent_ino;
++	unsigned old_namelen;
++	char names[0];
++} __attribute__((packed));
++
++struct readpage_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++	unsigned long long offset;
++	unsigned size;
++} __attribute__((packed));
++
++struct writepage_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++	unsigned long long offset;
++	unsigned size;
++} __attribute__((packed));
++
++struct fsync_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++} __attribute__((packed));
++
++struct readlink_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++} __attribute__((packed));
++
++struct readlink_rep {
++	int status;
++	char target[0];
++} __attribute__((packed));
++
++struct readdir_req {
++	unsigned short id;
++	unsigned short cmd;
++	unsigned long long ino;
++	unsigned long long offset;
++	unsigned size;
++} __attribute__((packed));
++
++struct dirnode {
++	unsigned long long ino;
++	unsigned long long offset;
++	unsigned char type;
++	unsigned short len;
++	char name[0];
++} __attribute__((packed));
++
++struct readdir_rep {
++	int status;
++	unsigned long long offset;
++	struct dirnode entries[0];
++} __attribute__((packed));
++
++struct statfs_req {
++	unsigned short id;
++	unsigned short cmd;
++} __attribute__((packed));
++
++struct statfs_rep {
++	int status;
++	unsigned blocks;
++	unsigned bfree;
++} __attribute__((packed));
++
++#define BUF_COUNT	16
++
++extern int vm_create_queue(unsigned id, unsigned irq,
++			   unsigned tx, unsigned rx);
++extern int vm_release_queue(unsigned id);
++
++static volatile struct vdma_descr rx_descr[BUF_COUNT];
++static volatile struct vdma_descr tx_descr[BUF_COUNT];
++
++#define MFS_ID(sb) ((unsigned) sb->s_fs_info)
++
++
++static void mfs_update_inode(struct inode *i, struct inode_rep *rep);
++static struct inode *mfs_new_inode(struct super_block *sb,
++				   struct inode_rep *rep);
++
++static void start_new_request(unsigned *tx_idx, unsigned tx_slots,
++			      unsigned *rx_idx, unsigned rx_slots)
++{
++	static DEFINE_MUTEX(mfs_lock);
++	static unsigned cur_tx;
++	static unsigned cur_rx;
++
++	mutex_lock(&mfs_lock);
++
++	*tx_idx = cur_tx;
++	cur_tx += tx_slots;
++
++	*rx_idx = cur_rx;
++	cur_rx += rx_slots;
++
++	mutex_unlock(&mfs_lock);
++}
++
++static void prepare_receive(unsigned idx, void *resp, unsigned rp_size)
++{
++	idx = idx & (BUF_COUNT - 1);
++
++	rx_descr[idx].addr = (unsigned) resp;
++	rx_descr[idx].size = rp_size;
++}
++
++static void post_request(unsigned idx, const void *req, unsigned rq_size)
++{
++	idx = idx & (BUF_COUNT - 1);
++
++	while (tx_descr[idx].size & DONE) {
++		hc_yield();
++	}
++
++	tx_descr[idx].addr = (unsigned) req;
++	tx_descr[idx].size = rq_size | DONE;
++}
++
++static unsigned wait_for_reply(unsigned idx)
++{
++	idx = idx & (BUF_COUNT - 1);
++
++	while (!(rx_descr[idx].size & DONE)) {
++		hc_yield();
++	}
++	return rx_descr[idx].size & ~(PAGE_MASK<<1);
++}
++
++static unsigned send_request(const void *req, unsigned rq_size,
++			     void *resp, unsigned rp_size)
++{
++	unsigned tx;
++	unsigned rx;
++
++	start_new_request(&tx, 1, &rx, 1);
++	prepare_receive(rx, resp, rp_size);
++	post_request(tx, req, rq_size);
++	return wait_for_reply(rx);
++}
++
++static struct kmem_cache *mfs_inode_cachep;
++
++static struct inode *mfs_alloc_inode(struct super_block *sb)
++{
++	return kmem_cache_alloc(mfs_inode_cachep, GFP_KERNEL);
++}
++
++static void mfs_destroy_inode(struct inode *inode)
++{
++	kmem_cache_free(mfs_inode_cachep, inode);
++}
++
++static struct dentry *mfs_lookup(struct inode *dir,
++				 struct dentry *dentry, unsigned int dummy)
++{
++	unsigned size = sizeof(struct lookup_req) + dentry->d_name.len;
++	unsigned char buf[size];
++	struct lookup_req *req = (struct lookup_req *) buf;
++	struct inode_rep rep;
++	struct inode *inode = NULL;
++	struct dentry *res = NULL;
++	unsigned ret;
++
++	req->id = MFS_ID(dir->i_sb);
++	req->cmd = CMD_LOOKUP;
++	req->parent_ino = dir->i_ino;
++	memcpy(req->name, dentry->d_name.name, dentry->d_name.len);
++
++	rep.status = -EINVAL;
++	ret = send_request(req, size, &rep, sizeof(rep));
++	if (ret == sizeof(rep) && rep.status == 0)
++		inode = mfs_new_inode(dir->i_sb, &rep);
++	d_add(dentry, inode);
++	return res;
++}
++
++static int mfs_create_file(struct inode *dir, struct dentry *dentry,
++			   int mode, dev_t dev)
++{
++	unsigned size = sizeof(struct create_req) + dentry->d_name.len;
++	unsigned char buf[size];
++	struct create_req *req = (struct create_req *) buf;
++	struct inode_rep rep;
++	struct inode *inode = NULL;
++	unsigned ret;
++
++	req->id = MFS_ID(dir->i_sb);
++	req->cmd = CMD_CREATE;
++	req->parent_ino = dir->i_ino;
++	req->mode = mode;
++	req->dev = (unsigned) dev;
++	memcpy(req->name, dentry->d_name.name, dentry->d_name.len);
++
++	rep.status = -EINVAL;
++	ret = send_request(req, size, &rep, sizeof(rep));
++	if (ret < sizeof(rep))
++		return rep.status;
++
++	inode = mfs_new_inode(dir->i_sb, &rep);
++	d_instantiate(dentry, inode);
++	return 0;
++}
++
++static int mfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
++		      bool dummy)
++{
++	return mfs_create_file(dir, dentry, mode, MKDEV(0, 0));
++}
++
++static int mfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++	unsigned size = sizeof(struct unlink_req) + dentry->d_name.len;
++	unsigned char buf[size];
++	struct unlink_req *req = (struct unlink_req *) buf;
++	int err = -EINVAL;
++    
++	req->id = MFS_ID(dir->i_sb);
++	req->cmd = CMD_UNLINK;
++	req->parent_ino = dir->i_ino;
++	memcpy(req->name, dentry->d_name.name, dentry->d_name.len);
++
++	send_request(req, size, &err, sizeof(err));
++	return err;
++}
++
++static int mfs_symlink(struct inode *dir, struct dentry *dentry,
++		       const char *target)
++{
++	unsigned tlen = strlen(target);
++	unsigned size = sizeof(struct symlink_req) + dentry->d_name.len + tlen;
++	unsigned char buf[size];
++	struct symlink_req *req = (struct symlink_req *) buf;
++	struct inode_rep rep;
++	struct inode *inode = NULL;
++	unsigned ret;
++    
++	req->id = MFS_ID(dir->i_sb);
++	req->cmd = CMD_SYMLINK;
++	req->parent_ino = dir->i_ino;
++	req->namelen = dentry->d_name.len;
++	memcpy(req->names, dentry->d_name.name, dentry->d_name.len);
++	memcpy(req->names + req->namelen, target, tlen);
++
++	rep.status = -EINVAL;
++	ret = send_request(req, size, &rep, sizeof(rep));
++	if (ret < sizeof(rep))
++		return rep.status;
++
++	inode = mfs_new_inode(dir->i_sb, &rep);
++	d_instantiate(dentry, inode);
++	return 0;
++}
++
++static int mfs_link(struct dentry *old_dentry, struct inode *dir,
++		    struct dentry *dentry)
++{
++	unsigned size = sizeof(struct hlink_req) + dentry->d_name.len;
++	unsigned char buf[size];
++	struct hlink_req *req = (struct hlink_req *) buf;
++	struct inode_rep rep;
++	unsigned ret;
++    
++	req->id = MFS_ID(dir->i_sb);
++	req->cmd = CMD_HLINK;
++	req->parent_ino = dir->i_ino;
++	req->ino = old_dentry->d_inode->i_ino;
++	memcpy(req->name, dentry->d_name.name, dentry->d_name.len);
++
++	rep.status = -EINVAL;
++	ret = send_request(req, size, &rep, sizeof(rep));
++	if (ret < sizeof(rep))
++		return rep.status;
++
++	mfs_update_inode(old_dentry->d_inode, &rep);
++
++	atomic_inc(&old_dentry->d_inode->i_count);
++	d_instantiate(dentry, old_dentry->d_inode);
++	return 0;
++}
++
++static int mfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
++{
++	return mfs_create_file(dir, dentry, mode | S_IFDIR, MKDEV(0, 0));
++}
++
++static int mfs_rmdir(struct inode *dir, struct dentry *dentry)
++{
++	return mfs_unlink(dir, dentry);
++}
++
++static int mfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
++		     dev_t rdev) {
++	return mfs_create_file(dir, dentry, mode, rdev);
++}
++
++static int mfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++		      struct inode *new_dir, struct dentry *new_dentry)
++{
++	unsigned size = sizeof(struct rename_req) +
++	    old_dentry->d_name.len + new_dentry->d_name.len;
++	unsigned char buf[size];
++	struct rename_req *req = (struct rename_req *) buf;
++	int err = -EINVAL;
++    
++	req->id = MFS_ID(old_dir->i_sb);
++	req->cmd = CMD_RENAME;
++	req->old_parent_ino = old_dir->i_ino;
++	req->new_parent_ino = new_dir->i_ino;
++	req->old_namelen = old_dentry->d_name.len;
++	memcpy(req->names, old_dentry->d_name.name, old_dentry->d_name.len);
++	memcpy(req->names + req->old_namelen,
++	       new_dentry->d_name.name, new_dentry->d_name.len);
++
++	send_request(req, size, &err, sizeof(err));
++	return err;
++}
++
++static int mfs_readdir(struct file *file, void *dirent, filldir_t filldir)
++{
++	struct readdir_req req;
++	struct readdir_rep *rep;
++	struct dirnode *dn;
++	unsigned len;
++	int res = -EINVAL;
++
++	rep = kmalloc(PAGE_SIZE, GFP_KERNEL);
++	if (!rep)
++		return -ENOMEM;
++
++	req.id = MFS_ID(file->f_dentry->d_inode->i_sb);
++	req.cmd = CMD_READDIR;
++	req.ino = file->f_dentry->d_inode->i_ino;
++	req.offset = file->f_pos;
++	req.size = PAGE_SIZE;
++
++	len = send_request(&req, sizeof(req), rep, PAGE_SIZE);
++	if (len <= sizeof(*rep)) {
++		if (len >= sizeof(int))
++			res = rep->status;
++		goto eod;
++	}
++	
++	dn = rep->entries;
++	res = 0;
++	while ((char *) dn + sizeof(struct dirnode) < (char *) rep + len) {
++		if ((char *) dn + dn->len > (char *) rep + len)
++			break;
++		if (filldir(dirent, dn->name, dn->len - sizeof(struct dirnode),
++			    dn->offset, dn->ino, dn->type) < 0)
++			break;
++		++res;
++		dn = (struct dirnode *) ((unsigned char *) dn + dn->len);
++	}
++	file->f_pos = rep->offset;
++
++  eod:
++	kfree(rep);
++	return res;
++}
++
++static int mfs_readpage(struct file *file, struct page *page)
++{
++	struct readpage_req req;
++	void *buf;
++	int res = -EIO;
++	unsigned len;
++	unsigned tx;
++	unsigned rx;
++
++	buf = kmap(page);
++	if (!buf)
++		goto err_out;
++
++	req.id = MFS_ID(file->f_dentry->d_inode->i_sb);
++	req.cmd = CMD_READPAGE;
++	req.ino = file->f_dentry->d_inode->i_ino;
++	req.offset = page_offset(page);
++	req.size = PAGE_SIZE;
++
++	start_new_request(&tx, 1, &rx, 2);
++	prepare_receive(rx, &res, sizeof(res));
++	prepare_receive(rx + 1, buf, PAGE_SIZE);
++	post_request(tx, &req, sizeof(req));
++
++	if (wait_for_reply(rx) < sizeof(res)) {
++		res = -EINVAL;
++		goto err_out;
++	}
++	if (res) {
++		memset(buf, 0, PAGE_SIZE);
++		SetPageError(page);
++		goto err_buf;
++	}
++	len = wait_for_reply(rx + 1);
++
++	memset(buf + len, 0, PAGE_SIZE - len);
++	SetPageUptodate(page);
++
++  err_buf:
++	kunmap(page);
++	flush_dcache_page(page);
++  err_out:
++	unlock_page(page);
++	return res;
++}
++
++static int mfs_write_begin(struct file *file, struct address_space *mapping,
++			   loff_t pos, unsigned len, unsigned flags,
++			   struct page **pagep, void **fsdata)
++{
++	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
++
++	*pagep = grab_cache_page_write_begin(mapping, index, flags);
++	if (!*pagep)
++		return -ENOMEM;
++
++	// FIXME: do prereading
++
++	return 0;
++}
++
++static int mfs_write_end(struct file *file, struct address_space *mapping,
++			 loff_t pos, unsigned blen, unsigned copied,
++			 struct page *page, void *fsdata)
++{
++	struct inode *i = file->f_dentry->d_inode;
++	struct writepage_req req;
++	void *buf;
++	int len = -EFAULT;
++	unsigned tx;
++	unsigned rx;
++	unsigned size;
++
++	flush_dcache_page(page);
++
++	buf = kmap(page);
++	if (!buf)
++		return -EINVAL;
++
++	req.id = MFS_ID(i->i_sb);
++	req.cmd = CMD_WRITEPAGE;
++	req.ino = file->f_dentry->d_inode->i_ino;
++	req.offset = pos;
++	req.size = blen;
++
++	start_new_request(&tx, 2, &rx, 1);
++	prepare_receive(rx, &len, sizeof(len));
++	post_request(tx, &req, sizeof(req));
++	post_request(tx + 1, buf + (pos & (PAGE_CACHE_SIZE - 1)), blen);
++	wait_for_reply(rx);
++
++	if (len >= 0) {
++		if (len != blen) {
++			SetPageError(page);
++			ClearPageUptodate(page);
++		} else {
++			SetPageUptodate(page);
++		}
++
++		size = req.offset + len;
++		if (size > i_size_read(i)) i_size_write(i, size);
++	}
++
++	kunmap(page);
++	unlock_page(page);
++	page_cache_release(page);
++	return len;
++}
++
++static int mfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
++{
++ 	struct inode *inode = file->f_mapping->host;
++	struct fsync_req req;
++	int err;
++
++	err = filemap_write_and_wait_range(inode->i_mapping, start, end);
++	if (err)
++		return err;
++
++	req.id = MFS_ID(file->f_mapping->host->i_sb);
++	req.cmd = CMD_FSYNC;
++	req.ino = file->f_mapping->host->i_ino;
++
++	err = -EINVAL;
++	send_request(&req, sizeof(req), &err, sizeof(err));
++	return err;
++}
++
++static void *mfs_follow_link(struct dentry *dentry, struct nameidata *nd)
++{
++	struct readlink_req req;
++	struct readlink_rep *rep;
++	int len;
++
++	rep = kmalloc(256, GFP_KERNEL);
++	if (!rep)
++		return ERR_PTR(-ENOMEM);
++
++	req.id = MFS_ID(dentry->d_inode->i_sb);
++	req.cmd = CMD_READLINK;
++	req.ino = dentry->d_inode->i_ino;
++	
++	rep->status = -EINVAL;
++	len = send_request(&req, sizeof(req), rep, 255);
++	if (len < sizeof(*rep) + 1) {
++		kfree(rep);
++		return ERR_PTR(rep->status);
++	}
++
++	*((char *) rep + len) = 0;
++	nd_set_link(nd, rep->target);
++	return NULL;
++}
++
++static void mfs_put_link(struct dentry *direntry,
++			 struct nameidata *nd, void *cookie)
++{
++	char *p = nd_get_link(nd);
++
++	if (!IS_ERR(p))
++		kfree(p - sizeof(struct readlink_rep));
++}
++
++static int mfs_setattr(struct dentry *dentry, struct iattr *attr)
++{
++	struct setinode_req req;
++	struct inode_rep rep;
++	struct inode *i = dentry->d_inode;
++	unsigned ia = attr->ia_valid;
++	unsigned len;
++
++	req.id = MFS_ID(i->i_sb);
++	req.cmd = CMD_SETINODE;
++	req.ino = i->i_ino;
++	req.mode = ia & ATTR_MODE ? attr->ia_mode : i->i_mode;
++	req.uid = ia & ATTR_UID ? attr->ia_uid.val : i->i_uid.val;
++	req.gid = ia & ATTR_GID ? attr->ia_gid.val : i->i_gid.val;
++	req.size = ia & ATTR_SIZE ? attr->ia_size : i->i_size;
++
++	len = send_request(&req, sizeof(req), &rep, sizeof(rep));
++	if (len < sizeof(rep))
++		return -EINVAL;
++	    
++	if (rep.status)
++		return rep.status;
++
++	mfs_update_inode(i, &rep);
++	return 0;
++}
++
++static const struct file_operations mfs_dir_fops = {
++	.read		= generic_read_dir,
++	.readdir	= mfs_readdir,
++};
++
++static const struct inode_operations mfs_dir_ops = {
++	.lookup		= mfs_lookup,
++	.create		= mfs_create,
++	.link		= mfs_link,
++	.unlink		= mfs_unlink,
++	.symlink	= mfs_symlink,
++	.mkdir		= mfs_mkdir,
++	.rmdir		= mfs_rmdir,
++	.mknod		= mfs_mknod,
++	.rename		= mfs_rename,
++	.setattr	= mfs_setattr,
++};
++
++static const struct inode_operations mfs_file_ops = {
++	.setattr	= mfs_setattr,
++};
++
++static const struct file_operations mfs_fops = {
++	.llseek		= generic_file_llseek,
++	.read		= do_sync_read,
++	.write		= do_sync_write,
++	.aio_read	= generic_file_aio_read,
++	.aio_write	= generic_file_aio_write,
++	.mmap		= generic_file_readonly_mmap,
++	.splice_read	= generic_file_splice_read,
++	.fsync		= mfs_fsync,
++};
++
++static const struct address_space_operations mfs_aops = {
++	.readpage	= mfs_readpage,
++	.write_begin	= mfs_write_begin,
++	.write_end	= mfs_write_end,
++};
++
++static const struct inode_operations mfs_link_ops = {
++	.readlink	= generic_readlink,
++	.follow_link	= mfs_follow_link,
++	.put_link	= mfs_put_link,
++	.setattr	= mfs_setattr,
++};
++
++static void mfs_update_inode(struct inode *i, struct inode_rep *rep)
++{
++	i->i_ino = rep->ino;
++	i->i_mode = rep->mode;
++	set_nlink(i, rep->nlink);
++	i->i_uid.val = rep->uid;
++	i->i_gid.val = rep->gid;
++	i->i_size = rep->size;
++	i->i_atime.tv_sec = rep->atime.sec;
++	i->i_atime.tv_nsec = rep->atime.nsec;
++	i->i_mtime.tv_sec = rep->mtime.sec;
++	i->i_mtime.tv_nsec = rep->mtime.nsec;
++	i->i_ctime.tv_sec = rep->ctime.sec;
++	i->i_ctime.tv_nsec = rep->ctime.nsec;
++	i->i_blkbits = ffs(rep->blksize);
++	i->i_blocks = rep->blocks;
++
++	if (i->i_sb->s_flags & MS_RDONLY)
++		i->i_mode &= ~0222;
++}
++
++static struct inode *mfs_new_inode(struct super_block *sb,
++				   struct inode_rep *rep)
++{
++	struct inode *i = new_inode(sb);
++	if (!i) return NULL;
++
++	mfs_update_inode(i, rep);
++
++	if (S_ISREG(rep->mode)) {
++		i->i_op = &mfs_file_ops;
++		i->i_fop = &mfs_fops;
++		i->i_data.a_ops = &mfs_aops;
++	} else if (S_ISDIR(rep->mode)) {
++		i->i_op = &mfs_dir_ops;
++		i->i_fop = &mfs_dir_fops;
++	} else if (S_ISLNK(rep->mode)) {
++		i->i_op = &mfs_link_ops;
++	} else {
++		init_special_inode(i, rep->mode, (dev_t) rep->rdev);
++	}
++
++	insert_inode_hash(i);
++	return i;
++}
++
++static struct inode *mfs_getinode(struct super_block *sb,
++				  unsigned long long ino)
++{
++	struct getinode_req req;
++	struct inode_rep rep;
++	unsigned len;
++
++	req.id = MFS_ID(sb);
++	req.cmd = CMD_GETINODE;
++	req.ino = ino;
++	len = send_request(&req, sizeof(req), &rep, sizeof(rep));
++
++	if (len < sizeof(rep) || rep.status)
++		return NULL;
++
++	return mfs_new_inode(sb, &rep);
++}
++
++static void mfs_put_super(struct super_block *sb)
++{
++}
++
++static int mfs_statfs(struct dentry *dentry, struct kstatfs *buf)
++{
++	struct statfs_req req;
++	struct statfs_rep rep;
++	struct super_block *sb = dentry->d_sb;
++	unsigned len;
++
++	req.id = MFS_ID(sb);
++	req.cmd = CMD_STATFS;
++	rep.status = -EINVAL;
++	len = send_request(&req, sizeof(req), &rep, sizeof(rep));
++
++	if (len < sizeof(rep) || rep.status)
++		return rep.status;
++
++	buf->f_type = sb->s_magic;
++	buf->f_bsize = 512;
++	buf->f_blocks = rep.blocks;
++	buf->f_bfree = rep.bfree;
++	buf->f_bavail = rep.bfree;
++	buf->f_namelen = 255;
++
++	return 0;
++}
++
++static const struct super_operations mfs_ops = {
++	.alloc_inode	= mfs_alloc_inode,
++	.destroy_inode	= mfs_destroy_inode,
++	.put_super	= mfs_put_super,
++	.statfs		= mfs_statfs,
++};
++
++static int mfs_fill_super(struct super_block *sb, void *data, int silent)
++{
++	struct inode *root;
++	unsigned id;
++
++	if (*(char *) data == '/') ++data;
++	id = simple_strtoul((char *) data, NULL, 10);
++
++	sb->s_magic = 0xdeadbeef;
++	sb->s_op = &mfs_ops;
++	if (id == 0)
++		sb->s_flags |= MS_RDONLY;
++	sb->s_fs_info = (void *) id;
++
++	root = mfs_getinode(sb, 0);
++	if (!root)	    
++		goto out;
++
++	sb->s_root = d_make_root(root);
++	if (!sb->s_root)
++		goto outiput;
++
++	return 0;
++
++  outiput:
++	iput(root);
++  out:
++	return -EINVAL;
++}
++
++static struct dentry *mfs_mount(struct file_system_type *fs_type, int flags,
++				const char *dev_name, void *data)
++{
++	return mount_nodev(fs_type, flags, (void *) dev_name, mfs_fill_super);
++}
++
++static struct file_system_type mfs_fs_type = {
++	.owner		= THIS_MODULE,
++	.name		= "metafs",
++	.mount		= mfs_mount,
++	.kill_sb	= kill_block_super,
++	.fs_flags	= FS_REQUIRES_DEV,
++};
++
++static void init_once(void *foo)
++{
++	struct inode * inode = (struct inode *) foo;
++
++	inode_init_once(inode);
++}
++
++static int __init init_mfs_fs(void)
++{
++	unsigned i;
++	int err;
++
++	if (vm_running() != 0)
++		return 0;
++
++	printk("MFS init\n");
++	mfs_inode_cachep = kmem_cache_create("metafs_inode_cache",
++					     sizeof(struct inode),
++					     0, (SLAB_RECLAIM_ACCOUNT|
++						 SLAB_MEM_SPREAD),
++					     init_once);
++	if (!mfs_inode_cachep)
++		return -ENOMEM;
++
++	for (i = 0; i < BUF_COUNT; ++i) {
++		tx_descr[i].addr = 0;
++		tx_descr[i].size = 0;
++		tx_descr[i].next = (unsigned) &tx_descr[i + 1];
++
++		rx_descr[i].addr = 0;
++		rx_descr[i].size = DONE;
++		rx_descr[i].next = (unsigned) &rx_descr[i + 1];
++	}
++	tx_descr[BUF_COUNT - 1].next = (unsigned) &tx_descr[0];
++	rx_descr[BUF_COUNT - 1].next = (unsigned) &rx_descr[0];
++	
++	vm_create_queue(2, -1u,
++			(unsigned) &tx_descr[0], (unsigned) &rx_descr[0]);
++
++        err = register_filesystem(&mfs_fs_type);
++	if (err != 0) {
++		kmem_cache_destroy(mfs_inode_cachep);
++		return err;
++	}
++
++	return 0;
++}
++
++static void __exit exit_mfs_fs(void)
++{
++	unregister_filesystem(&mfs_fs_type);
++	kmem_cache_destroy(mfs_inode_cachep);
++}
++
++module_init(init_mfs_fs);
++module_exit(exit_mfs_fs);
+diff -puNrb linux-3.10.49/fs/metafs/Kconfig linux-3.10.49-minimal/fs/metafs/Kconfig
+--- linux-3.10.49/fs/metafs/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/fs/metafs/Kconfig	2014-01-11 05:37:13.000000000 +0000
+@@ -0,0 +1,3 @@
++config META_FS
++	depends on METAROUTER || MIPS_MIKROTIK
++	tristate "MetaFS on Mikrotik MetaRouters"
+diff -puNrb linux-3.10.49/fs/metafs/Makefile linux-3.10.49-minimal/fs/metafs/Makefile
+--- linux-3.10.49/fs/metafs/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.49-minimal/fs/metafs/Makefile	2014-01-11 05:37:13.000000000 +0000
+@@ -0,0 +1,3 @@
++obj-y += metafs.o
++
++metafs-objs := inode.o
