diff --git a/common/drivers/vga_textmode.c b/common/drivers/vga_textmode.c
index 852d82ee..501d9006 100644
--- a/common/drivers/vga_textmode.c
+++ b/common/drivers/vga_textmode.c
@@ -252,6 +252,8 @@ static void text_deinit(struct term_context *_ctx, void (*_free)(void *, size_t)
     }
 }
 
+static struct textmode_context term_local_struct;
+
 void vga_textmode_init(bool managed) {
     if (quiet || allocations_disallowed) {
         return;
@@ -265,7 +267,13 @@ void vga_textmode_init(bool managed) {
         current_video_mode = 0x3;
     }
 
-    struct textmode_context *ctx = (void *)term;
+    if (term != NULL) {
+        term->deinit(term, pmm_free);
+        term = NULL;
+    }
+
+    struct textmode_context *ctx = &term_local_struct;
+    term = &term_local_struct.term;
 
     if (ctx->back_buffer == NULL) {
         ctx->back_buffer = ext_mem_alloc(VD_ROWS * VD_COLS);
diff --git a/common/lib/gterm.c b/common/lib/gterm.c
index 1d9d50d4..6b9165c5 100644
--- a/common/lib/gterm.c
+++ b/common/lib/gterm.c
@@ -497,7 +497,7 @@ static void loop_external(size_t xstart, size_t xend, size_t ystart, size_t yend
 static void loop_margin(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_margin); }
 static void loop_internal(size_t xstart, size_t xend, size_t ystart, size_t yend) { genloop(xstart, xend, ystart, yend, blend_internal); }
 
-static void *generate_canvas(void) {
+static void generate_canvas(void) {
     if (background) {
         bg_canvas_size = fbinfo.framebuffer_width * fbinfo.framebuffer_height * sizeof(uint32_t);
         bg_canvas = ext_mem_alloc(bg_canvas_size);
@@ -527,21 +527,15 @@ static void *generate_canvas(void) {
         }
 
         loop_internal(margin, gradient_stop_x, margin, gradient_stop_y);
-
-        return bg_canvas;
+    } else {
+        bg_canvas = NULL;
     }
-
-    return NULL;
 }
 
 static bool last_serial = false;
 static char *last_config = NULL;
 
 bool gterm_init(char *config, size_t width, size_t height) {
-    if (term_backend != GTERM) {
-        term->deinit(term, pmm_free);
-    }
-
     if (quiet || allocations_disallowed) {
         return false;
     }
@@ -573,9 +567,15 @@ bool gterm_init(char *config, size_t width, size_t height) {
         return true;
     }
 
+    if (term != NULL) {
+        term->deinit(term, pmm_free);
+        term = NULL;
+    }
+
     // We force bpp to 32
-    if (!fb_init(&fbinfo, width, height, 32))
+    if (!fb_init(&fbinfo, width, height, 32)) {
         return false;
+    }
 
     // Ensure this is xRGB8888, we only support that for the menu
     if (fbinfo.red_mask_size    != 8
@@ -583,8 +583,9 @@ bool gterm_init(char *config, size_t width, size_t height) {
      || fbinfo.green_mask_size  != 8
      || fbinfo.green_mask_shift != 8
      || fbinfo.blue_mask_size   != 8
-     || fbinfo.blue_mask_shift  != 0)
+     || fbinfo.blue_mask_shift  != 0) {
         return false;
+    }
 
     last_serial = serial;
     last_config = config;
@@ -762,14 +763,12 @@ no_load_font:;
         }
     }
 
-    uint32_t *canvas = generate_canvas();
-
-    term->deinit(term, pmm_free);
+    generate_canvas();
 
     term = fbterm_init(ext_mem_alloc,
                 (void *)(uintptr_t)fbinfo.framebuffer_addr,
                 fbinfo.framebuffer_width, fbinfo.framebuffer_height, fbinfo.framebuffer_pitch,
-                canvas,
+                bg_canvas,
                 ansi_colours, ansi_bright_colours,
                 &default_bg, &default_fg,
                 font, font_width, font_height, font_spacing,
@@ -777,6 +776,9 @@ no_load_font:;
                 margin);
 
     pmm_free(font, FONT_MAX);
+    if (bg_canvas != NULL) {
+        pmm_free(bg_canvas, bg_canvas_size);
+    }
 
     if (serial) {
         term->cols = term->cols > 80 ? 80 : term->cols;
diff --git a/common/lib/print.s2.c b/common/lib/print.s2.c
index 3c4f67b8..c6ba7294 100644
--- a/common/lib/print.s2.c
+++ b/common/lib/print.s2.c
@@ -222,7 +222,9 @@ out:
 #if defined (BIOS)
         if (stage3_loaded) {
 #endif
-            term_write(term, print_buf, print_buf_i);
+            if (term != NULL) {
+                term_write(term, print_buf, print_buf_i);
+            }
 #if defined (BIOS)
         } else {
             s2_print(print_buf, print_buf_i);
diff --git a/common/lib/term.c b/common/lib/term.c
index b7aa454f..8b0acef0 100644
--- a/common/lib/term.c
+++ b/common/lib/term.c
@@ -3,10 +3,7 @@
 #include <stdbool.h>
 #include <lib/term.h>
 #include <lib/real.h>
-#include <lib/image.h>
 #include <lib/misc.h>
-#include <lib/gterm.h>
-#include <drivers/vga_textmode.h>
 #include <lib/print.h>
 #include <mm/pmm.h>
 
@@ -15,7 +12,7 @@ int term_backend = _NOT_READY;
 
 struct term_context *term;
 
-static struct textmode_context term_local_struct;
+static struct term_context term_local_struct;
 
 // --- notready ---
 
@@ -63,9 +60,10 @@ static void notready_deinit(struct term_context *ctx, void (*_free)(void *, size
 void term_notready(void) {
     if (term != NULL) {
         term->deinit(term, pmm_free);
+        term = NULL;
     }
 
-    term = &term_local_struct.term;
+    term = &term_local_struct;
 
     term->raw_putchar = notready_raw_putchar;
     term->clear = notready_clear;
diff --git a/common/protos/chainload.c b/common/protos/chainload.c
index e097f6f0..2221c458 100644
--- a/common/protos/chainload.c
+++ b/common/protos/chainload.c
@@ -217,6 +217,7 @@ noreturn void efi_chainload_file(char *config, struct file_handle *image) {
     fclose(image);
 
     term->deinit(term, pmm_free);
+    term = NULL;
 
     size_t req_width = 0, req_height = 0, req_bpp = 0;
 
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 82049f0f..1b67fee4 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -736,6 +736,7 @@ FEAT_START
 FEAT_END
 
     term->deinit(term, pmm_free);
+    term = NULL;
 
     if (!fb_init(&fb, req_width, req_height, req_bpp)) {
         panic(true, "limine: Could not acquire framebuffer");
diff --git a/common/protos/linux.c b/common/protos/linux.c
index 0750e17e..eb47437b 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -496,6 +496,7 @@ noreturn void linux_load(char *config, char *cmdline) {
     ///////////////////////////////////////
 
     term->deinit(term, pmm_free);
+    term = NULL;
 
     struct screen_info *screen_info = &boot_params->screen_info;
 
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 8a6d609d..84b5c6df 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -303,6 +303,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
     multiboot1_info->flags |= (1 << 9);
 
     term->deinit(term, pmm_free);
+    term = NULL;
 
     if (header.flags & (1 << 2)) {
         size_t req_width  = header.fb_width;
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 98a98547..5bbc4f90 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -506,6 +506,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
         tag->common.size = sizeof(struct multiboot_tag_framebuffer);
 
         term->deinit(term, pmm_free);
+        term = NULL;
 
         if (fbtag) {
             size_t req_width = fbtag->width;