diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ec347560f05a6dcdc503b3df0b05e82f201ad629..befcff6798ac4ae32802a84471a3821014f32ca1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,12 +5,9 @@ build:
     before_script:
         - echo "deb http://deb.debian.org/debian stretch-backports main" >> /etc/apt/sources.list
         - apt update -qq
-        - apt install -y -qq gcc-arm-none-eabi python3-pip
+        - apt install -y -qq gcc-arm-none-eabi python3-pip git
         - apt install -y -qq -t stretch-backports meson
         - pip3 install crc16
     script:
-        - cd bootloader
-        - make
-        - cd ..
-        - meson --cross-file card10-cross.ini build/
+        - ./bootstrap.sh
         - ninja -C build/
diff --git a/bootloader/.gdbinit b/bootloader/.gdbinit
index 85b92cf79c0f29f412a886e093c13da55dfc1bcc..6f3712683961c71d507e894e3b32aa4046a050fc 100644
--- a/bootloader/.gdbinit
+++ b/bootloader/.gdbinit
@@ -1,3 +1,3 @@
-file build/max32665.elf
+file ../build/bootloader/bootloader.elf
 target remote localhost:3333
 
diff --git a/bootloader/Makefile b/bootloader/Makefile
deleted file mode 100644
index 65d7b58b8b3ef326e9016f601905cab73fe7df90..0000000000000000000000000000000000000000
--- a/bootloader/Makefile
+++ /dev/null
@@ -1,132 +0,0 @@
-################################################################################
- # Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
- #
- # Permission is hereby granted, free of charge, to any person obtaining a
- # copy of this software and associated documentation files (the "Software"),
- # to deal in the Software without restriction, including without limitation
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
- # and/or sell copies of the Software, and to permit persons to whom the
- # Software is furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included
- # in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- # IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
- # OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- # OTHER DEALINGS IN THE SOFTWARE.
- #
- # Except as contained in this notice, the name of Maxim Integrated
- # Products, Inc. shall not be used except as stated in the Maxim Integrated
- # Products, Inc. Branding Policy.
- #
- # The mere transfer of this software does not imply any licenses
- # of trade secrets, proprietary technology, copyrights, patents,
- # trademarks, maskwork rights, or any other form of intellectual
- # property whatsoever. Maxim Integrated Products, Inc. retains all
- # ownership rights.
- #
- # $Date: 2018-08-10 21:35:48 +0000 (Fri, 10 Aug 2018) $ 
- # $Revision: 36863 $
- #
- ###############################################################################
-
-# This is the name of the build output file
-ifeq "$(PROJECT)" ""
-PROJECT=max32665
-endif
-
-# Specify the target processor
-ifeq "$(TARGET)" ""
-TARGET=MAX32665
-endif
-
-# Create Target name variables
-TARGET_UC:=$(shell echo $(TARGET) | tr a-z A-Z)
-TARGET_LC:=$(shell echo $(TARGET) | tr A-Z a-z)
-
-# Select 'GCC' or 'IAR' compiler
-COMPILER=GCC
-
-# Specify the board used
-ifeq "$(BOARD)" ""
-#BOARD=EvKit_V1
-BOARD=card10
-endif
-
-# This is the path to the CMSIS root directory
-ifeq "$(MAXIM_PATH)" ""
-LIBS_DIR=../lib/sdk/Libraries
-else
-LIBS_DIR=/$(subst \,/,$(subst :,,$(MAXIM_PATH))/Firmware/$(TARGET_UC)/Libraries)
-endif
-CMSIS_ROOT=$(LIBS_DIR)/CMSIS
-
-# Source files for this test (add path to VPATH below)
-SRCS  = main.c
-SRCS += mscmem.c
-SRCS += bootloader-usb.c
-SRCS += crc16-ccitt.c
-SRCS += ../lib/card10/mx25lba.c
-
-# Where to find source files for this test
-VPATH = . 
-
-# Where to find header files for this test
-IPATH = .
-
-IPATH += ../lib/card10
-VPATH += ../lib/card10
-
-# Enable assertion checking for development
-PROJ_CFLAGS+=-DMXC_ASSERT_ENABLE
-
-# Specify the target revision to override default
-# "A2" in ASCII
-# TARGET_REV=0x4132
-
-# Use this variables to specify and alternate tool path
-#TOOL_DIR=/opt/gcc-arm-none-eabi-4_8-2013q4/bin
-
-# Use these variables to add project specific tool options
-#PROJ_CFLAGS+=--specs=nano.specs
-#PROJ_LDFLAGS+=--specs=nano.specs
-
-# Point this variable to a startup file to override the default file
-#STARTUPFILE=start.S
-
-# Set MXC_OPTIMIZE to override the default optimization level
-#MXC_OPTIMIZE_CFLAGS=-Og
-
-# Point this variable to a linker file to override the default file
-LINKERFILE=$(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/GCC/$(TARGET_LC)_boot.ld
-
-################################################################################
-# Include external library makefiles here
-
-# Include the BSP
-BOARD_DIR=$(LIBS_DIR)/Boards/$(BOARD)
-include $(BOARD_DIR)/board.mk
-
-# Include the peripheral driver
-PERIPH_DRIVER_DIR=$(LIBS_DIR)/$(TARGET_UC)PeriphDriver
-include $(PERIPH_DRIVER_DIR)/periphdriver.mk
-
-#include the FAT32 libraries
-FAT32_DRIVER_DIR=../lib/ff13
-include $(FAT32_DRIVER_DIR)/fat32.mk
-
-MAXUSB_DIR=$(LIBS_DIR)/MAXUSB
-include $(MAXUSB_DIR)/maxusb.mk
-
-################################################################################
-# Include the rules for building for this target. All other makefiles should be
-# included before this one.
-include $(CMSIS_ROOT)/Device/Maxim/$(TARGET_UC)/Source/$(COMPILER)/$(TARGET_LC).mk
-
-# The rule to clean out all the build products.
-distclean: clean
-	$(MAKE) -C ${PERIPH_DRIVER_DIR} clean
diff --git a/bootloader/build_image.sh b/bootloader/build_image.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6d3e53ef85d247062c3b066c3b7170091c44a0e3
--- /dev/null
+++ b/bootloader/build_image.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+
+PYTHON="$1"
+ELF="$2"
+BIN="$3"
+
+arm-none-eabi-objcopy -O binary "$ELF" "$BIN"
+"$PYTHON" "$(dirname "$0")/crc_patch.py" "$BIN"
diff --git a/bootloader/meson.build b/bootloader/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..d97a221787468c619ad732344865f363dd0f1f5f
--- /dev/null
+++ b/bootloader/meson.build
@@ -0,0 +1,22 @@
+name = 'bootloader'
+
+executable(
+  name + '.elf',
+  'main.c',
+  'mscmem.c',
+  'bootloader-usb.c',
+  'crc16-ccitt.c',
+  dependencies: [
+    libcard10,
+    max32665_startup_boot,
+    libff13,
+    maxusb,
+  ],
+  link_whole: [max32665_startup_boot_lib, board_card10_lib],
+  link_args: [
+    '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
+  ],
+)
+
+# build_image.sh
+build_image = [files('./build_image.sh'), python3]
diff --git a/hw-tests/bmatest/build_image b/hw-tests/bmatest/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/bmatest/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/bmatest/meson.build b/hw-tests/bmatest/meson.build
index 0f3899a241f43665aa20c5708f20a5bb97548f7f..9559f67daab678362be407db8375d8d93d5fb57b 100644
--- a/hw-tests/bmatest/meson.build
+++ b/hw-tests/bmatest/meson.build
@@ -1,6 +1,6 @@
 name = 'bmatest'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   dependencies: [libcard10, max32665_startup],
@@ -9,3 +9,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/bmetest/build_image b/hw-tests/bmetest/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/bmetest/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/bmetest/meson.build b/hw-tests/bmetest/meson.build
index ed1e72b98faa0f931ea3484bad18b201db2c6bb5..86e15050123c0ed45d5e9d06a4f7452c11ffc129 100644
--- a/hw-tests/bmetest/meson.build
+++ b/hw-tests/bmetest/meson.build
@@ -1,6 +1,6 @@
 name = 'bmetest'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   dependencies: [libcard10, max32665_startup],
@@ -9,3 +9,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/ecgtest/build_image b/hw-tests/ecgtest/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/ecgtest/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/ecgtest/meson.build b/hw-tests/ecgtest/meson.build
index 7e4f32d00573a1a2105dc9023848c9295904d0de..9b2f80f3f1a7671d0fb44ec9e0395b9b0119d17a 100644
--- a/hw-tests/ecgtest/meson.build
+++ b/hw-tests/ecgtest/meson.build
@@ -1,6 +1,6 @@
 name = 'ecgtest'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   dependencies: [libcard10, max32665_startup],
@@ -9,3 +9,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/hello-freertos/meson.build b/hw-tests/hello-freertos/meson.build
index fae1dbd229d6223d59a409503b8801edfce7a1e2..457a676815e787efba07fe1d445802e38286d521 100644
--- a/hw-tests/hello-freertos/meson.build
+++ b/hw-tests/hello-freertos/meson.build
@@ -16,7 +16,7 @@ sources = files(
   'main.c',
 )
 
-executable(
+elf = executable(
   name + '.elf',
   sources,
   include_directories: freertos_sdk_includes,
@@ -27,3 +27,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/hello-world/build_image b/hw-tests/hello-world/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/hello-world/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/hello-world/meson.build b/hw-tests/hello-world/meson.build
index 7519ca62510228c5a911a369a2ffbb9887abc4f0..2c687cb0291b8943f465fa5ce7441516cec3330d 100644
--- a/hw-tests/hello-world/meson.build
+++ b/hw-tests/hello-world/meson.build
@@ -1,6 +1,6 @@
 name = 'hello-world'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   dependencies: [libcard10, max32665_startup],
@@ -9,3 +9,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/imutest/build_image b/hw-tests/imutest/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/imutest/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/imutest/meson.build b/hw-tests/imutest/meson.build
index 18825ee67a0f7e04269bf8a610c14401417d2343..d87e43d01b47c275f61f8fdf203e4b1d59199530 100644
--- a/hw-tests/imutest/meson.build
+++ b/hw-tests/imutest/meson.build
@@ -1,6 +1,6 @@
 name = 'imutest'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   dependencies: [libcard10, max32665_startup],
@@ -9,3 +9,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/hw-tests/ips/build_image b/hw-tests/ips/build_image
deleted file mode 100755
index 7764693994906af62868cb9f4d67d6417f1fffb8..0000000000000000000000000000000000000000
--- a/hw-tests/ips/build_image
+++ /dev/null
@@ -1,6 +0,0 @@
-name=$(basename `pwd`)
-ninja -C ../../build -t clean hw-tests/$name/$name.elf
-ninja -C ../../build hw-tests/$name/$name.elf
-arm-none-eabi-objcopy -O binary ../../build/hw-tests/$name/$name.elf ../../build/hw-tests/$name/$name.bin
-cp ../../build/hw-tests/$name/$name.bin card10.bin
-../../bootloader/crc_patch.py card10.bin
diff --git a/hw-tests/ips/meson.build b/hw-tests/ips/meson.build
index 10ff3cf7731acececa4a83f338b8b5519ed63007..d4c782f47720cc7bc675cdf9d69b39b60ff34178 100644
--- a/hw-tests/ips/meson.build
+++ b/hw-tests/ips/meson.build
@@ -1,6 +1,6 @@
 name = 'ips'
 
-executable(
+elf = executable(
   name + '.elf',
   'main.c',
   'image/image.c',
@@ -11,3 +11,11 @@ executable(
     '-Wl,-Map=' + meson.current_build_dir() + '/' + name + '.map',
   ],
 )
+
+custom_target(
+  name + '.bin',
+  build_by_default: true,
+  output: name + '.bin',
+  input: elf,
+  command: [build_image, '@INPUT@', '@OUTPUT0@'],
+)
diff --git a/lib/card10/meson.build b/lib/card10/meson.build
index 07c9e3e3fcaad99a147d3660fee5799cd48f86f5..8e6ce61f03e0853b705fd3e0870e95db3649b97e 100644
--- a/lib/card10/meson.build
+++ b/lib/card10/meson.build
@@ -31,3 +31,31 @@ libcard10 = declare_dependency(
   link_with: lib,
   dependencies: deps,
 )
+
+##########################################################
+
+includes = include_directories(
+  './',
+)
+
+sources = files(
+  'mx25lba.c',
+)
+
+deps = [
+    board_card10,
+    periphdriver,
+]
+
+lib = static_library(
+  'mx25lba',
+  sources,
+  include_directories: includes,
+  dependencies: deps,
+)
+
+mx25lba = declare_dependency(
+  include_directories: includes,
+  link_with: lib,
+  dependencies: deps,
+)
diff --git a/lib/card10/mscmem.h b/lib/card10/mscmem.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d4a6e943ecf5614c16e2ea4626d19baf34a23ef
--- /dev/null
+++ b/lib/card10/mscmem.h
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *
+ * Description: Communications Device Class ACM (Serial Port) over USB
+ * $Id: descriptors.h 31172 2017-10-05 19:05:57Z zach.metzinger $
+ *
+ *******************************************************************************
+ */
+
+/**
+ * @file    mscmem.h
+ * @brief   Memory routines used by the USB Mass Storage Class example.
+ *          See the msc_mem_t structure in msc.h for function details.
+ */
+
+#ifndef __MSC_MEM_H__
+#define __MSC_MEM_H__
+
+#include <stdint.h>
+
+int mscmem_init(void);
+int mscmem_start(void);
+int mscmem_stop(void);
+uint32_t mscmem_size(void);
+int mscmem_read(uint32_t lba, uint8_t* buffer);
+int mscmem_write(uint32_t lba, uint8_t* buffer);
+int mscmem_ready(void);
+
+#endif  /* __MSC_MEM_H__ */
diff --git a/lib/ff13/meson.build b/lib/ff13/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..48a2634991bfaee9e3f3eee91409eba5dd8a7b48
--- /dev/null
+++ b/lib/ff13/meson.build
@@ -0,0 +1,23 @@
+includes = include_directories(
+  './Source/',
+)
+
+sources = files(
+  './Source/diskio.c',
+  './Source/ff.c',
+  './Source/ffsystem.c',
+  './Source/ffunicode.c',
+)
+
+lib = static_library(
+  'ff13',
+  sources,
+  include_directories: includes,
+  dependencies: [periphdriver, mx25lba],
+)
+
+libff13 = declare_dependency(
+  include_directories: includes,
+  link_with: lib,
+  dependencies: [periphdriver, mx25lba],
+)
diff --git a/lib/meson.build b/lib/meson.build
index e2f7c313470b22b1f46247970113ac2c29c968bf..80fd654a828e4e01c14ccf9548df96491fe47cc1 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -7,3 +7,4 @@ subdir('./vendor/Maxim/MAX77650/')
 subdir('./gfx/')
 
 subdir('./card10/')
+subdir('./ff13/')
diff --git a/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/meson.build b/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/meson.build
index 9f9b1f64f2e74448f68a8b009f9474ecd1d6ae41..4fef47d4ef088c6eb51c93e7634c03d1efd6601c 100644
--- a/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/meson.build
+++ b/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/meson.build
@@ -66,3 +66,17 @@ max32665_startup_core1 = declare_dependency(
     '--entry', 'Reset_Handler',
   ],
 )
+
+#############################################################
+# For the bootloader
+#############################################################
+
+# We can just reuse the same lib here
+max32665_startup_boot_lib = max32665_startup_lib
+
+max32665_startup_boot = declare_dependency(
+  link_args: [
+    '-T', meson.current_source_dir() + 'Source/GCC/max32665_boot.ld',
+    '--entry', 'Reset_Handler',
+  ],
+)
diff --git a/lib/sdk/Libraries/MAXUSB/meson.build b/lib/sdk/Libraries/MAXUSB/meson.build
new file mode 100644
index 0000000000000000000000000000000000000000..6df655d6978c03a658b2f6a4c6d86fc937c35e26
--- /dev/null
+++ b/lib/sdk/Libraries/MAXUSB/meson.build
@@ -0,0 +1,33 @@
+includes = include_directories(
+  'include/core/musbhsfc',
+  'include/core',
+  'include/devclass',
+  'include/enumerate',
+  'include/util',
+  'include/dbg_log',
+)
+
+sources = files(
+  'src/core/musbhsfc/usb.c',
+  'src/core/usb_event.c',
+  'src/dbg_log/dbg_log.c',
+  'src/devclass/cdc_acm.c',
+  'src/devclass/hid_kbd.c',
+  'src/devclass/hid_raw.c',
+  'src/devclass/msc.c',
+  'src/enumerate/enumerate.c',
+  'src/util/fifo.c',
+)
+
+lib = static_library(
+  'maxusb',
+  sources,
+  include_directories: includes,
+  dependencies: periphdriver,
+)
+
+maxusb = declare_dependency(
+  include_directories: includes,
+  link_with: lib,
+  dependencies: periphdriver,
+)
diff --git a/lib/sdk/meson.build b/lib/sdk/meson.build
index b78dc88f303266b52edfd30f8c255c0d3aca2d68..e71031e577d7942f506dd1deae8124dec3dcb15c 100644
--- a/lib/sdk/meson.build
+++ b/lib/sdk/meson.build
@@ -4,3 +4,5 @@ subdir('./Libraries/CMSIS/Device/Maxim/MAX32665/')
 subdir('./Libraries/Boards/card10/')
 
 subdir('./Libraries/FreeRTOS/')
+
+subdir('./Libraries/MAXUSB/')
diff --git a/meson.build b/meson.build
index 0cb5a984fa08e582ef5ae817d5bac343a04e7213..b8ea87e9386f46387c2d19a60d02d2e970f9b3e8 100644
--- a/meson.build
+++ b/meson.build
@@ -27,7 +27,9 @@ add_global_link_arguments(
   language: 'c',
 )
 
-python3 = import('python').find_installation('python3')
+# python3 = import('python').find_installation('python3')
+python3 = 'python3'
 
 subdir('lib/')
+subdir('bootloader/')
 subdir('hw-tests/')