diff --git a/py/mpconfig.h b/py/mpconfig.h
index 1eb2acf538933571581233541e9544a44a96aed5..6ff0692915b5d8f903da3cad29548a24aa75cfec 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -107,6 +107,10 @@ typedef long long mp_longint_impl_t;
 #define MICROPY_PATH_MAX (512)
 #endif
 
+// Additional builtin function definitions - see runtime.c:builtin_table for format.
+#ifndef MICROPY_EXTRA_BUILTINS
+#define MICROPY_EXTRA_BUILTINS
+#endif
 /*****************************************************************************/
 /* Miscellaneous settings                                                    */
 
diff --git a/py/runtime.c b/py/runtime.c
index d15a38e089eac4d422530b787c1bc15ecde4ca78..b473a951f320de1dc43a971eb9dc162707ea98d9 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -144,6 +144,9 @@ STATIC const mp_builtin_elem_t builtin_table[] = {
     { MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj },
     { MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj },
 
+    // Extra builtins as defined by a port
+    MICROPY_EXTRA_BUILTINS
+
     { MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel
 };
 
diff --git a/unix/file.c b/unix/file.c
index 0d11de6332b7867d54538262136db8c2a0717173..21dd7647489ac439ca4527f2567ff22216c887bb 100644
--- a/unix/file.c
+++ b/unix/file.c
@@ -136,8 +136,6 @@ mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args) {
 MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_open_obj, 1, 2, mp_builtin_open);
 
 void file_init() {
-    rt_store_name(MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj);
-
     mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys);
     rt_store_attr(m_sys, MP_QSTR_stdin, fdfile_new(STDIN_FILENO));
     rt_store_attr(m_sys, MP_QSTR_stdout, fdfile_new(STDOUT_FILENO));
diff --git a/unix/main.c b/unix/main.c
index 192a0e6e8b96cae639fb9256a7e67f6b70a6617d..716c7b11426ff6c31c1c05ba96eb765ae0d8d238 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -29,7 +29,6 @@
 // Stack top at the start of program
 void *stack_top;
 
-extern const mp_obj_fun_native_t mp_builtin_open_obj;
 void file_init();
 void microsocket_init();
 void time_init();
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index dc92970104e529bc8b8f6a08b8b8b4ec41800874..5b2503f4dae79d78a9f29a1b65e500f3f3d0a8fc 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -36,3 +36,8 @@ typedef const void *machine_const_ptr_t; // must be of pointer size
 typedef double machine_float_t;
 
 machine_float_t machine_sqrt(machine_float_t x);
+
+struct _mp_obj_fun_native_t;
+extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
+#define MICROPY_EXTRA_BUILTINS \
+    { MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj },