py, unix: Convert sys module to static representation.
diff --git a/py/builtin.h b/py/builtin.h
index a298444..bf65b48 100644
--- a/py/builtin.h
+++ b/py/builtin.h
@@ -42,3 +42,4 @@
 extern const mp_obj_module_t mp_module_math;
 extern const mp_obj_module_t mp_module_micropython;
 extern const mp_obj_module_t mp_module_struct;
+extern const mp_obj_module_t mp_module_sys;
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 6972448..578e73f 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -28,8 +28,6 @@
 
 #define PATH_SEP_CHAR '/'
 
-mp_obj_t mp_sys_path;
-
 mp_import_stat_t stat_dir_or_file(vstr_t *path) {
     //printf("stat %s\n", vstr_str(path));
     mp_import_stat_t stat = mp_import_stat(vstr_str(path));
@@ -48,9 +46,7 @@
     // extract the list of paths
     uint path_num = 0;
     mp_obj_t *path_items;
-    if (mp_sys_path != MP_OBJ_NULL) {
-        mp_obj_list_get(mp_sys_path, &path_num, &path_items);
-    }
+    mp_obj_list_get(mp_sys_path, &path_num, &path_items);
 
     if (path_num == 0) {
         // mp_sys_path is empty, so just use the given file name
diff --git a/py/builtintables.c b/py/builtintables.c
index e2007f3..23c34ed 100644
--- a/py/builtintables.c
+++ b/py/builtintables.c
@@ -134,6 +134,7 @@
 #if MICROPY_ENABLE_FLOAT
     { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math },
 #endif
+    { MP_OBJ_NEW_QSTR(MP_QSTR_sys), (mp_obj_t)&mp_module_sys },
 
     // extra builtin modules as defined by a port
     MICROPY_EXTRA_BUILTIN_MODULES
diff --git a/py/modsys.c b/py/modsys.c
new file mode 100644
index 0000000..7f8cd68
--- /dev/null
+++ b/py/modsys.c
@@ -0,0 +1,48 @@
+#include "misc.h"
+#include "mpconfig.h"
+#include "qstr.h"
+#include "obj.h"
+#include "builtin.h"
+#include "runtime.h"
+#include "objlist.h"
+
+#if MICROPY_ENABLE_MOD_SYS
+
+// These should be implemented by ports, specific types don't matter,
+// only addresses.
+struct _dummy_t;
+extern struct _dummy_t mp_sys_stdin_obj;
+extern struct _dummy_t mp_sys_stdout_obj;
+extern struct _dummy_t mp_sys_stderr_obj;
+
+mp_obj_list_t mp_sys_path_obj;
+mp_obj_list_t mp_sys_argv_obj;
+
+STATIC const mp_map_elem_t mp_module_sys_globals_table[] = {
+    { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sys) },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_path), (mp_obj_t)&mp_sys_path_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_argv), (mp_obj_t)&mp_sys_argv_obj },
+
+    { MP_OBJ_NEW_QSTR(MP_QSTR_stdin), (mp_obj_t)&mp_sys_stdin_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_stdout), (mp_obj_t)&mp_sys_stdout_obj },
+    { MP_OBJ_NEW_QSTR(MP_QSTR_stderr), (mp_obj_t)&mp_sys_stderr_obj },
+};
+
+STATIC const mp_obj_dict_t mp_module_sys_globals = {
+    .base = {&mp_type_dict},
+    .map = {
+        .all_keys_are_qstrs = 1,
+        .table_is_fixed_array = 1,
+        .used = sizeof(mp_module_sys_globals_table) / sizeof(mp_map_elem_t),
+        .alloc = sizeof(mp_module_sys_globals_table) / sizeof(mp_map_elem_t),
+        .table = (mp_map_elem_t*)mp_module_sys_globals_table,
+    },
+};
+
+const mp_obj_module_t mp_module_sys = {
+    .base = { &mp_type_module },
+    .name = MP_QSTR_sys,
+    .globals = (mp_obj_dict_t*)&mp_module_sys_globals,
+};
+
+#endif
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 2c118b4..119d017 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -120,6 +120,11 @@
 #define MICROPY_ENABLE_MOD_STRUCT (1)
 #endif
 
+// Whether to provide "sys" module
+#ifndef MICROPY_ENABLE_MOD_SYS
+#define MICROPY_ENABLE_MOD_SYS (1)
+#endif
+
 // Whether to support slice object and correspondingly
 // slice subscript operators
 #ifndef MICROPY_ENABLE_SLICE
diff --git a/py/py.mk b/py/py.mk
index 23ba9eb..09b4056 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -82,6 +82,7 @@
 	modmath.o \
 	modmicropython.o \
 	modstruct.o \
+	modsys.o \
 	vm.o \
 	showbc.o \
 	repl.o \
diff --git a/py/runtime.c b/py/runtime.c
index 053367e..ed01193 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -53,17 +53,6 @@
 
     // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New())
     dict_locals = dict_globals = &dict_main;
-
-#if MICROPY_CPYTHON_COMPAT
-    // Precreate sys module, so "import sys" didn't throw exceptions.
-    mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys);
-    // Avoid warning of unused var
-    (void)m_sys;
-#endif
-    // init sys.path
-    // for efficiency, left to platform-specific startup code
-    //mp_sys_path = mp_obj_new_list(0, NULL);
-    //mp_store_attr(m_sys, MP_QSTR_path, mp_sys_path);
 }
 
 void mp_deinit(void) {
diff --git a/py/runtime.h b/py/runtime.h
index 867d633..bf3d3da 100644
--- a/py/runtime.h
+++ b/py/runtime.h
@@ -60,8 +60,12 @@
 
 mp_obj_t mp_make_raise_obj(mp_obj_t o);
 
-extern mp_obj_t mp_sys_path;
 mp_map_t *mp_loaded_modules_get(void);
 mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level);
 mp_obj_t mp_import_from(mp_obj_t module, qstr name);
 void mp_import_all(mp_obj_t module);
+
+extern struct _mp_obj_list_t mp_sys_path_obj;
+extern struct _mp_obj_list_t mp_sys_argv_obj;
+#define mp_sys_path ((mp_obj_t)&mp_sys_path_obj)
+#define mp_sys_argv ((mp_obj_t)&mp_sys_argv_obj)