diff --git a/bootloader/bootloader-display.c b/bootloader/bootloader-display.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c1e34fd81319f7761eb577d12a0afff7962b0cb
--- /dev/null
+++ b/bootloader/bootloader-display.c
@@ -0,0 +1,32 @@
+#include "bootloader.h"
+
+#include "GUI_Paint.h"
+#include "display.h"
+
+/*
+ * Initialize the display.
+ */
+void bootloader_display_init(void)
+{
+	;
+}
+
+/*
+ * Show the bootloader version on the display.
+ */
+void bootloader_display_header(void)
+{
+	Paint_Clear(0x0000);
+	Paint_DrawString_EN(0, 16 * 0, "Bootloader", &Font16, 0x0000, 0xffff);
+	Paint_DrawString_EN(0, 16 * 1, __DATE__, &Font16, 0x0000, 0xffff);
+	LCD_Update();
+}
+
+/*
+ * Display a line of text on the display.
+ */
+void bootloader_display_line(int line, char *string, uint16_t color)
+{
+	Paint_DrawString_EN(0, 16 * line, string, &Font16, 0x0000, color);
+	LCD_Update();
+}
diff --git a/bootloader/bootloader-usb.c b/bootloader/bootloader-usb.c
index 9c3a91dbd9e9e6f2a99232772ba00bc53d2077ff..67007d17ab3da03faff1dcbd0bc8b31b3bc5308d 100644
--- a/bootloader/bootloader-usb.c
+++ b/bootloader/bootloader-usb.c
@@ -41,8 +41,6 @@
 #include "bootloader.h"
 #include "descriptors.h"
 
-#include "display.h"
-#include "GUI_Paint.h"
 #include "card10.h"
 #include "led.h"
 
@@ -125,14 +123,12 @@ void bootloader_stop(void)
 
 void bootloader_dirty(void)
 {
-	Paint_DrawString_EN(0, 16 * 3, "Writing.", &Font16, 0x0000, 0xf000);
-	LCD_Update();
+	bootloader_display_line(3, "Writing.", 0xf000);
 }
 
 void bootloader_clean(void)
 {
-	Paint_DrawString_EN(0, 16 * 3, "Ready.  ", &Font16, 0x0000, 0xffff);
-	LCD_Update();
+	bootloader_display_line(3, "Ready.  ", 0xffff);
 }
 
 /******************************************************************************/
diff --git a/bootloader/bootloader.h b/bootloader/bootloader.h
index 07955d409ac33babda3e96899073ea5612666359..45631ea6583f8deff33dd059408d6c60210b2b2a 100644
--- a/bootloader/bootloader.h
+++ b/bootloader/bootloader.h
@@ -1,7 +1,14 @@
 #pragma once
 
-void run_usbmsc(void);
+#include <stdint.h>
+
+/* Display */
+void bootloader_display_init(void);
+void bootloader_display_header(void);
+void bootloader_display_line(int line, char *string, uint16_t color);
 
+/* USB */
+void run_usbmsc(void);
 void bootloader_stop(void);
 void bootloader_dirty(void);
 void bootloader_clean(void);
diff --git a/bootloader/main.c b/bootloader/main.c
index a8c9bba2b9de3ada0a21ead022332eb3b23e9679..5184aa3b0ae55aa24d97b0ada1d287faac2cb21c 100644
--- a/bootloader/main.c
+++ b/bootloader/main.c
@@ -1,8 +1,6 @@
 #include "bootloader.h"
 
-#include "GUI_Paint.h"
 #include "card10.h"
-#include "display.h"
 #include "led.h"
 #include "pb.h"
 #include "pmic.h"
@@ -60,16 +58,7 @@ bool check_integrity(void)
 
 	res = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ);
 	if (res != FR_OK) {
-		Paint_DrawString_EN(
-			0,
-			16 * 2,
-			"card10.bin not found",
-			&Font16,
-			0x0000,
-			0xffff
-		);
-		LCD_Update();
-
+		bootloader_display_line(2, "card10.bin not found", 0xffff);
 		printf("f_open error %d\n", res);
 		return false;
 	}
@@ -90,15 +79,7 @@ bool check_integrity(void)
 	if (crcval == 0) {
 		return true;
 	} else {
-		Paint_DrawString_EN(
-			0,
-			16 * 2,
-			"Integrity check failed",
-			&Font16,
-			0x0000,
-			0xffff
-		);
-		LCD_Update();
+		bootloader_display_line(2, "Integrity check failed", 0xffff);
 		printf("CRC check failed. Final CRC: %d\n", crcval);
 		return false;
 	}
@@ -225,20 +206,12 @@ int main(void)
 	 */
 	pmic_set_button_callback(pmic_button);
 
-	Paint_DrawString_EN(0, 16 * 0, "Bootloader", &Font16, 0x0000, 0xffff);
-	Paint_DrawString_EN(0, 16 * 1, __DATE__, &Font16, 0x0000, 0xffff);
-
-	LCD_Update();
+	bootloader_display_header();
 
 	// If the button is pressed, we go into MSC mode.
 	if (PB_Get(3)) {
-		Paint_DrawString_EN(
-			0, 16 * 2, "USB activated.", &Font16, 0x0000, 0xffff
-		);
-		Paint_DrawString_EN(
-			0, 16 * 3, "Ready.", &Font16, 0x0000, 0xffff
-		);
-		LCD_Update();
+		bootloader_display_line(2, "USB activated.", 0xffff);
+		bootloader_display_line(3, "Ready.", 0xffff);
 		run_usbmsc();
 
 		// If we return, don't try to boot. Maybe rather trigger a software reset.
@@ -252,16 +225,10 @@ int main(void)
 		if (check_integrity()) {
 			printf("Found valid application image\n");
 			if (is_update_needed()) {
-				printf("Trying to update application from external flash\n");
-				Paint_DrawString_EN(
-					0,
-					16 * 4,
-					"Updating...",
-					&Font16,
-					0x0000,
-					0xffff
+				printf("Trying to update firmware from external flash\n");
+				bootloader_display_line(
+					4, "Updating ...", 0xffff
 				);
-				LCD_Update();
 				erase_partition();
 				flash_partition();
 			} else {
@@ -271,25 +238,15 @@ int main(void)
 			printf("Integrity check failed\n");
 		}
 	} else {
-		Paint_DrawString_EN(
-			0,
-			16 * 2,
-			"Failed to mount file system",
-			&Font16,
-			0x0000,
-			0xffff
+		bootloader_display_line(
+			2, "Failed to mount filesystem", 0xffff
 		);
-		LCD_Update();
 		printf("Failed to mount the external flash\n");
 	}
 
 	printf("Trying to boot\n");
-	Paint_DrawString_EN(
-		0, 16 * 4, "Trying to boot", &Font16, 0x0000, 0xffff
-	);
-	LCD_Update();
-	//while(1);
-	// boot partition
+	bootloader_display_line(4, "Trying to boot", 0xffff);
+
 	boot((uintptr_t *)PARTITION_START);
 
 	while (1) {
diff --git a/bootloader/meson.build b/bootloader/meson.build
index e2c831efa3b62d9a962396d761bd783411e9b420..9a863cdfa8de1bb99c79bad8f783b4cd29a9e239 100644
--- a/bootloader/meson.build
+++ b/bootloader/meson.build
@@ -4,6 +4,7 @@ executable(
   name + '.elf',
   'main.c',
   'mscmem.c',
+  'bootloader-display.c',
   'bootloader-usb.c',
   'crc16-ccitt.c',
   dependencies: [