diff --git a/Documentation/how-to-build.rst b/Documentation/how-to-build.rst
index 252c1cf2dd424ad7da9648c0272742b32d453531..1db20eda46d7496588a15b56576b9f2a071821b3 100644
--- a/Documentation/how-to-build.rst
+++ b/Documentation/how-to-build.rst
@@ -1,3 +1,5 @@
+.. _how_to_build:
+
 How To Build
 ============
 If you just want to write MicroPython code for card10, you probably **won't**
@@ -102,6 +104,7 @@ firmware features:
   info related to BLE.
 - ``-Ddebug_core1=true``: Enable the core 1 SWD lines which are exposed on the
   SAO connector.  Only use this if you have a debugger which is modified for core 1.
+- ``-Djailbreak_card10=true``: Enable execution of .elf l0dables on core 1.
 
 .. warning::
 
diff --git a/Documentation/overview.rst b/Documentation/overview.rst
index 5a481989929c32da088f5c96ab97d886d4cfdebc..7fd03bf4aef93b5f18158256db0d964fee5fe607 100644
--- a/Documentation/overview.rst
+++ b/Documentation/overview.rst
@@ -51,6 +51,9 @@ Next to Pycardium, other bare-metal code can also run on core 1.  For example,
 a Rustcardium or C-cardium.  These l0dables must be compiled using our special
 linker script and should link against the api-caller library so they can
 interface with the :ref:`epicardium_api`.
+Note: this feature is disabled by default and has to be enabled at build time.
+To do this, run ``bootstrap.sh`` with the option ``-Djailbreak_card10=true``
+and rebuild the firmware as described in :ref:`how_to_build`.
 
 .. todo::
 
diff --git a/epicardium/meson.build b/epicardium/meson.build
index ea28d3664563816c5fa8a4294e9fb3ba9308622c..1aa5556010941d2267f8b10aafcaf9ec7683c8a2 100644
--- a/epicardium/meson.build
+++ b/epicardium/meson.build
@@ -70,6 +70,14 @@ subdir('ble/')
 
 subdir('l0der/')
 
+epicardium_cargs = []
+if get_option('jailbreak_card10')
+  epicardium_cargs += [
+    '-DJAILBREAK_CARD10=1',
+  ]
+endif
+
+
 elf = executable(
   name + '.elf',
   'cdcacm.c',
@@ -88,6 +96,7 @@ elf = executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
     '-Wl,--defsym=_write=_write_epicardium',
   ],
+  c_args: epicardium_cargs,
 )
 
 epicardium_bin = custom_target(
diff --git a/epicardium/modules/lifecycle.c b/epicardium/modules/lifecycle.c
index 483730ecad2dc75a842d23135f3e606ba5744fcc..375cfef61dd9972fbb418f72659a1e30e69ef615 100644
--- a/epicardium/modules/lifecycle.c
+++ b/epicardium/modules/lifecycle.c
@@ -88,7 +88,9 @@ static int load_stat(char *name)
  */
 static int do_load(struct load_info *info)
 {
+#if defined(JAILBREAK_CARD10) && (JAILBREAK_CARD10 == 1)
 	struct l0dable_info l0dable;
+#endif
 	int res;
 
 	if (*info->name == '\0') {
@@ -127,6 +129,7 @@ static int do_load(struct load_info *info)
 	case PL_PYTHON_INTERP:
 		core1_load(PYCARDIUM_IVT, info->name);
 		break;
+#if defined(JAILBREAK_CARD10) && (JAILBREAK_CARD10 == 1)
 	case PL_L0DABLE:
 		res = l0der_load_path(info->name, &l0dable);
 		if (res != 0) {
@@ -137,6 +140,7 @@ static int do_load(struct load_info *info)
 		core1_load(l0dable.isr_vector, "");
 
 		break;
+#endif
 	default:
 		LOG_ERR("lifecyle",
 			"Attempted to load invalid payload (%s)",
diff --git a/meson_options.txt b/meson_options.txt
index 0bff7f441774f3f6eb695dd2f29fc308af3a0d44..a626628ffdca083d0b52fc5868b4180964595ed7 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -21,3 +21,11 @@ option(
 
   description: 'Whether to enable WSF TRACE prints',
 )
+
+option(
+  'jailbreak_card10',
+  type: 'boolean',
+  value: false,
+
+  description: 'Enable execution of .elf l0dables',
+)