diff --git a/lib/memzip/README.md b/lib/memzip/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..287d0fc4894a2bbe1189edff240a2a28524ac3f8
--- /dev/null
+++ b/lib/memzip/README.md
@@ -0,0 +1,28 @@
+MEMZIP - a simple readonly file system
+
+memzip takes a zip file which is comprised of uncompressed files and
+and presents it as a filesystem, allowing Python files to be imported.
+
+The script make-memzip.py takes a directory name and will create a zip file
+containing uncompressed files found in the directory. It will then generate
+a C file which contains the data from the zip file.
+
+A typical addition to a makefile would look like:
+```
+SRC_C += \
+    lib/memzip/import.c \
+    lib/memzip/lexermemzip.c \
+    lib/memzip/memzip.c \
+
+OBJ += $(BUILD)/memzip-files.o
+
+MAKE_MEMZIP = ../lib/memzip/make-memzip.py
+
+$(BUILD)/memzip-files.o: $(BUILD)/memzip-files.c
+    $(call compile_c)
+
+$(BUILD)/memzip-files.c: $(shell find ${MEMZIP_DIR} -type f)
+    @$(ECHO) "Creating $@"
+    $(Q)$(PYTHON) $(MAKE_MEMZIP) --zip-file $(BUILD)/memzip-files.zip --c-file $@ $(MEMZIP_DIR)
+```
+
diff --git a/teensy/import.c b/lib/memzip/import.c
similarity index 100%
rename from teensy/import.c
rename to lib/memzip/import.c
diff --git a/teensy/lexermemzip.c b/lib/memzip/lexermemzip.c
similarity index 100%
rename from teensy/lexermemzip.c
rename to lib/memzip/lexermemzip.c
diff --git a/lib/memzip/make-memzip.py b/lib/memzip/make-memzip.py
new file mode 100755
index 0000000000000000000000000000000000000000..9730f5e008aad4a56d298f00deeb209c18c61af8
--- /dev/null
+++ b/lib/memzip/make-memzip.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+#
+# Takes a directory of files and zips them up (as uncompressed files).
+# This then gets converted into a C data structure which can be read
+# like a filesystem at runtime.
+#
+# This is somewhat like frozen modules in python, but allows arbitrary files
+# to be used.
+
+from __future__ import print_function
+
+import argparse
+import os
+import subprocess
+import sys
+import types
+
+def create_zip(zip_filename, zip_dir):
+    abs_zip_filename = os.path.abspath(zip_filename)
+    save_cwd = os.getcwd()
+    os.chdir(zip_dir)
+    if os.path.exists(abs_zip_filename):
+        os.remove(abs_zip_filename)
+    subprocess.check_call(['zip', '-0', '-r', '-D', abs_zip_filename, '.'])
+    os.chdir(save_cwd)
+
+def create_c_from_file(c_filename, zip_filename):
+    with open(zip_filename, 'rb') as zip_file:
+        with open(c_filename, 'wb') as c_file:
+            print('#include <stdint.h>', file=c_file)
+            print('', file=c_file)
+            print('const uint8_t memzip_data[] = {', file=c_file)
+            while True:
+                buf = zip_file.read(16)
+                if not buf:
+                    break
+                print('   ', end='', file=c_file)
+                for byte in buf:
+                    if type(byte) is types.StringType:
+                        print(' 0x{:02x},'.format(ord(byte)), end='', file=c_file)
+                    else:
+                        print(' 0x{:02x},'.format(byte), end='', file=c_file)
+                print('', file=c_file)
+            print('};', file=c_file)
+
+def main():
+    parser = argparse.ArgumentParser(
+        prog='make-memzip.py',
+        usage='%(prog)s [options] [command]',
+        description='Generates a C source memzip file.'
+    )
+    parser.add_argument(
+        '-z', '--zip-file',
+        dest='zip_filename',
+        help='Specifies the name of the created zip file.',
+        default='memzip_files.zip'
+    )
+    parser.add_argument(
+        '-c', '--c-file',
+        dest='c_filename',
+        help='Specifies the name of the created C source file.',
+        default='memzip_files.c'
+    )
+    parser.add_argument(
+        dest='source_dir',
+        default='memzip_files'
+    )
+    args = parser.parse_args(sys.argv[1:])
+
+    print('args.zip_filename =', args.zip_filename)
+    print('args.c_filename =', args.c_filename)
+    print('args.source_dir =', args.source_dir)
+
+    create_zip(args.zip_filename, args.source_dir)
+    create_c_from_file(args.c_filename, args.zip_filename)
+
+if __name__ == "__main__":
+    main()
+
diff --git a/teensy/memzip.c b/lib/memzip/memzip.c
similarity index 94%
rename from teensy/memzip.c
rename to lib/memzip/memzip.c
index 88c0843818c401d8d8c4ede79ee563f69650c0e9..3fbea8e1e91f93b958891db18c5437761862c002 100644
--- a/teensy/memzip.c
+++ b/lib/memzip/memzip.c
@@ -5,11 +5,11 @@
 #include "py/misc.h"
 #include "memzip.h"
 
-extern uint8_t _staticfs[];
+extern uint8_t memzip_data[];
 
 const MEMZIP_FILE_HDR *memzip_find_file_header(const char *filename) {
 
-    const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)_staticfs;
+    const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)memzip_data;
     uint8_t *mem_data;
 
     /* Zip file filenames don't have a leading /, so we strip it off */
@@ -33,7 +33,7 @@ const MEMZIP_FILE_HDR *memzip_find_file_header(const char *filename) {
 }
 
 bool memzip_is_dir(const char *filename) {
-    const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)_staticfs;
+    const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)memzip_data;
     uint8_t *mem_data;
 
     if (strcmp(filename, "/") == 0) {
diff --git a/teensy/memzip.h b/lib/memzip/memzip.h
similarity index 100%
rename from teensy/memzip.h
rename to lib/memzip/memzip.h
diff --git a/teensy/Makefile b/teensy/Makefile
index 42cb5123e556efe872a74d6fcf9dac492378aff6..9db22918c30a5be33e04c2bdbb47f37894d77201 100644
--- a/teensy/Makefile
+++ b/teensy/Makefile
@@ -78,12 +78,12 @@ SRC_C = \
 	hal_ftm.c \
 	hal_gpio.c \
 	help.c \
-	import.c \
 	main.c \
 	lcd.c \
 	led.c \
-	lexermemzip.c \
-	memzip.c \
+	lib/memzip/import.c \
+	lib/memzip/lexermemzip.c \
+	lib/memzip/memzip.c \
 	modpyb.c \
 	pin_defs_teensy.c \
 	reg.c \
@@ -92,6 +92,7 @@ SRC_C = \
 	uart.c \
 	usb.c \
 
+
 STM_SRC_C = $(addprefix stmhal/,\
 	gccollect.c \
 	input.c \
@@ -126,12 +127,13 @@ SRC_TEENSY = $(addprefix core/,\
 OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(STM_SRC_C:.c=.o) $(STM_SRC_S:.s=.o) $(SRC_TEENSY:.c=.o))
 OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
 OBJ += $(BUILD)/pins_gen.o
+OBJ += $(BUILD)/memzip-files.o
 
 all: hex
-hex: $(BUILD)/micropython-mz.hex
+hex: $(BUILD)/micropython.hex
 
 ifeq ($(ARDUINO),)
-post_compile: $(BUILD)/micropython-mz.hex
+post_compile: $(BUILD)/micropython.hex
 	$(ECHO) "Please define ARDUINO (where TeensyDuino is installed)"
 	exit 1
 
@@ -142,7 +144,7 @@ reboot:
 else
 TOOLS_PATH = $(ARDUINO)/hardware/tools
 
-post_compile: $(BUILD)/micropython-mz.hex
+post_compile: $(BUILD)/micropython.hex
 	$(ECHO) "Preparing $@ for upload"
 	$(Q)$(TOOLS_PATH)/teensy_post_compile -file="$(basename $(<F))" -path="$(abspath $(<D))" -tools="$(TOOLS_PATH)"
 
@@ -163,15 +165,12 @@ ifeq ($(MEMZIP_DIR),)
 MEMZIP_DIR = memzip_files
 endif
 
-$(BUILD)/micropython-mz.hex: $(BUILD)/micropython.hex $(shell find ${MEMZIP_DIR} -type f)
-	@$(ECHO) "Creating $@"
-	$(Q)./add-memzip.sh $< $@ ${MEMZIP_DIR}
-
 $(BUILD)/%.hex: $(BUILD)/%.elf
 	$(ECHO) "HEX $<"
 	$(Q)$(OBJCOPY) -O ihex -R .eeprom "$<" "$@"
 
 MAKE_PINS = make-pins.py
+MAKE_MEMZIP = ../lib/memzip/make-memzip.py
 BOARD_PINS = teensy_pins.csv
 AF_FILE = mk20dx256_af.csv
 PREFIX_FILE = mk20dx256_prefix.c
@@ -197,6 +196,13 @@ $(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qst
 $(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
 	$(call compile_c)
 
+$(BUILD)/memzip-files.o: $(BUILD)/memzip-files.c
+	$(call compile_c)
+
+$(BUILD)/memzip-files.c: $(shell find ${MEMZIP_DIR} -type f)
+	@$(ECHO) "Creating $@"
+	$(Q)$(PYTHON) $(MAKE_MEMZIP) --zip-file $(BUILD)/memzip-files.zip --c-file $@ $(MEMZIP_DIR)
+
 $(BUILD)/%.pp: $(BUILD)/%.c
 	$(ECHO) "PreProcess $<"
 	$(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<