build: Add infrastructure for the bootloader program and libcommon.
authorTilman Sauerbeck <tilman@code-monkey.de>
Sun, 16 Jun 2019 17:18:09 +0000 (19:18 +0200)
committerTilman Sauerbeck <tilman@code-monkey.de>
Sun, 7 Jul 2019 07:58:39 +0000 (09:58 +0200)
This builds, but does not produce a useful binary.

.gitignore [new file with mode: 0644]
SConscript.libcommon [new file with mode: 0644]
SConscript.target [new file with mode: 0644]
SConstruct [new file with mode: 0644]
src/bootloader/bootloader.ld [new file with mode: 0644]
src/bootloader/main.rs [new file with mode: 0644]
src/bootloader/start.c [new file with mode: 0644]
src/common/lib.rs [new file with mode: 0644]
src/common/startup.c [new file with mode: 0644]
thumbv6m-none-eabi.json [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..fe83278
--- /dev/null
@@ -0,0 +1,2 @@
+.sconsign.dblite
+build-target
diff --git a/SConscript.libcommon b/SConscript.libcommon
new file mode 100644 (file)
index 0000000..902af89
--- /dev/null
@@ -0,0 +1,20 @@
+Import('env')
+env = env.Clone()
+
+source_files_rs = [
+    'src/common/lib.rs', # Must be listed first (see below).
+]
+
+source_files_c = [
+    'src/common/startup.c',
+]
+
+libcommon_rlib = env.Rustc('libcommon.rlib', source_files_rs[0])
+
+for f in source_files_rs:
+    Depends(libcommon_rlib, f)
+
+libcommon_a = env.Library('libcommon.a', source_files_c)
+
+for f in source_files_c:
+    Depends(libcommon_a, f)
diff --git a/SConscript.target b/SConscript.target
new file mode 100644 (file)
index 0000000..6dd2f41
--- /dev/null
@@ -0,0 +1,70 @@
+import os
+
+Import('env')
+env = env.Clone()
+
+host = os.environ.get('HOST', 'arm-none-eabi-')
+
+d = {
+    'CC': 'gcc',
+    'LD': 'ld',
+    'AR': 'ar',
+    'RANLIB': 'ranlib',
+    'OBJCOPY': 'objcopy',
+}
+
+for k, v in d.items():
+    env[k] = host + v
+
+env.Append(CCFLAGS = [
+    '-mcpu=cortex-m0plus',
+    '-mthumb',
+    '-ffunction-sections',
+    '-fdata-sections',
+    '-Os',
+])
+
+env.Append(LINKFLAGS = [
+    '-mcpu=cortex-m0plus',
+    '-mthumb',
+    '-specs=nano.specs',
+    '-specs=nosys.specs',
+    '-nostdlib',
+    '-nostartfiles',
+])
+
+env.Append(RUSTCFLAGS = [
+    '-C', 'opt-level=s',
+    '--target=thumbv6m-none-eabi',
+    '-L', '$LIBPATH',
+])
+
+env.Append(LINKFLAGS = [
+    '-Wl,--gc-sections'
+])
+
+SConscript('SConscript.libcommon', exports='env', duplicate=0)
+
+libbootloader_source_files = [
+    'src/bootloader/main.rs', # Must be listed first (see below).
+]
+
+libbootloader = env.Rustc('libbootloader.a', libbootloader_source_files[0])
+
+for f in libbootloader_source_files:
+    Depends(libbootloader, f)
+
+Depends(libbootloader, 'libcommon.rlib')
+Depends(libbootloader, 'libcommon.a')
+
+bootloader_env = env.Clone()
+
+bootloader_env.Append(LINKFLAGS = [
+    '-Tsrc/bootloader/bootloader.ld',
+])
+
+bootloader_elf = bootloader_env.Program('gps-watch-bootloader.elf', 'src/bootloader/start.c', LIBS = ['bootloader', 'common'])
+
+bootloader_bin = bootloader_env.Objcopy(bootloader_elf)
+
+Default(bootloader_bin)
diff --git a/SConstruct b/SConstruct
new file mode 100644 (file)
index 0000000..7f486b2
--- /dev/null
@@ -0,0 +1,38 @@
+import SCons
+import os
+
+root_env = Environment(ENV = {'PATH': os.environ['PATH']})
+
+# Beautify output.
+if ARGUMENTS.get('V', '0') != '1':
+    root_env['CCCOMSTR'] = '    CC $TARGET'
+    root_env['RUSTCCOMSTR'] = '    RUSTC $TARGET'
+    root_env['LINKCOMSTR'] = '    LINK $TARGET'
+    root_env['ARCOMSTR'] = '    AR $TARGET'
+    root_env['RANLIBCOMSTR'] = '    RANLIB $TARGET'
+    root_env['OBJCOPYCOMSTR'] = '    OBJCOPY $TARGET'
+
+# Make colored output of e.g. gcc work.
+root_env['ENV']['TERM'] = os.environ.get('TERM')
+
+root_env.Append(CCFLAGS = [
+    '-std=gnu99',
+    '-Wall',
+    '-Wextra',
+    '-Wwrite-strings',
+])
+
+root_env.Append(RUSTC = 'rustc')
+
+root_env.Append(BUILDERS = { 'Rustc': Builder(
+    action=Action('$RUSTC $RUSTCFLAGS -o $TARGET $SOURCE', '$RUSTCCOMSTR'))})
+
+root_env.Append(BUILDERS = { 'Objcopy': Builder(
+    action=Action('$OBJCOPY -O binary $OBJCOPYFLAGS $SOURCES $TARGET', '$OBJCOPYCOMSTR'),
+    suffix='.bin',
+    src_suffix='.elf')})
+
+env = root_env.Clone()
+env['variant_dir'] = 'build-target'
+env['LIBPATH'] = env['variant_dir']
+SConscript('SConscript.target', exports='env', variant_dir=env['variant_dir'], duplicate=0)
diff --git a/src/bootloader/bootloader.ld b/src/bootloader/bootloader.ld
new file mode 100644 (file)
index 0000000..5744429
--- /dev/null
@@ -0,0 +1,201 @@
+/* This is a copy of
+ *   CMSIS/Device/ARM/ARMCM0plus/Source/GCC/gcc_arm.ld
+ * taken from
+ *   git://github.com/ARM-software/CMSIS
+ */
+
+/* Linker script to configure memory regions. */
+MEMORY
+{
+  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000   /* 256k */
+  RAM (rwx)  : ORIGIN = 0x20000000, LENGTH = 0x08000   /*  32k */
+}
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a)
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ *   Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ *   __exidx_start
+ *   __exidx_end
+ *   __copy_table_start__
+ *   __copy_table_end__
+ *   __zero_table_start__
+ *   __zero_table_end__
+ *   __etext
+ *   __data_start__
+ *   __preinit_array_start
+ *   __preinit_array_end
+ *   __init_array_start
+ *   __init_array_end
+ *   __fini_array_start
+ *   __fini_array_end
+ *   __data_end__
+ *   __bss_start__
+ *   __bss_end__
+ *   __end__
+ *   end
+ *   __HeapLimit
+ *   __StackLimit
+ *   __StackTop
+ *   __stack
+ *   __Vectors_End
+ *   __Vectors_Size
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+       .text :
+       {
+               KEEP(*(.vectors))
+               __Vectors_End = .;
+               __Vectors_Size = __Vectors_End - __Vectors;
+               __end__ = .;
+
+               *(.text*)
+
+               KEEP(*(.init))
+               KEEP(*(.fini))
+
+               /* .ctors */
+               *crtbegin.o(.ctors)
+               *crtbegin?.o(.ctors)
+               *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+               *(SORT(.ctors.*))
+               *(.ctors)
+
+               /* .dtors */
+               *crtbegin.o(.dtors)
+               *crtbegin?.o(.dtors)
+               *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+               *(SORT(.dtors.*))
+               *(.dtors)
+
+               *(.rodata*)
+
+               KEEP(*(.eh_frame*))
+       } > FLASH
+
+       .ARM.extab :
+       {
+               *(.ARM.extab* .gnu.linkonce.armextab.*)
+       } > FLASH
+
+       __exidx_start = .;
+       .ARM.exidx :
+       {
+               *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+       } > FLASH
+       __exidx_end = .;
+
+       /* To copy multiple ROM to RAM sections,
+        * uncomment .copy.table section and,
+        * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
+       /*
+       .copy.table :
+       {
+               . = ALIGN(4);
+               __copy_table_start__ = .;
+               LONG (__etext)
+               LONG (__data_start__)
+               LONG (__data_end__ - __data_start__)
+               LONG (__etext2)
+               LONG (__data2_start__)
+               LONG (__data2_end__ - __data2_start__)
+               __copy_table_end__ = .;
+       } > FLASH
+       */
+
+       /* To clear multiple BSS sections,
+        * uncomment .zero.table section and,
+        * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
+       /*
+       .zero.table :
+       {
+               . = ALIGN(4);
+               __zero_table_start__ = .;
+               LONG (__bss_start__)
+               LONG (__bss_end__ - __bss_start__)
+               LONG (__bss2_start__)
+               LONG (__bss2_end__ - __bss2_start__)
+               __zero_table_end__ = .;
+       } > FLASH
+       */
+
+       __etext = .;
+
+       .data : AT (__etext)
+       {
+               __data_start__ = .;
+               *(vtable)
+               *(.data*)
+
+               . = ALIGN(4);
+               /* preinit data */
+               PROVIDE_HIDDEN (__preinit_array_start = .);
+               KEEP(*(.preinit_array))
+               PROVIDE_HIDDEN (__preinit_array_end = .);
+
+               . = ALIGN(4);
+               /* init data */
+               PROVIDE_HIDDEN (__init_array_start = .);
+               KEEP(*(SORT(.init_array.*)))
+               KEEP(*(.init_array))
+               PROVIDE_HIDDEN (__init_array_end = .);
+
+
+               . = ALIGN(4);
+               /* finit data */
+               PROVIDE_HIDDEN (__fini_array_start = .);
+               KEEP(*(SORT(.fini_array.*)))
+               KEEP(*(.fini_array))
+               PROVIDE_HIDDEN (__fini_array_end = .);
+
+               KEEP(*(.jcr*))
+               . = ALIGN(4);
+               /* All data end */
+               __data_end__ = .;
+
+       } > RAM
+
+       .bss :
+       {
+               . = ALIGN(4);
+               __bss_start__ = .;
+               *(.bss*)
+               *(COMMON)
+               . = ALIGN(4);
+               __bss_end__ = .;
+       } > RAM
+
+       .heap (COPY):
+       {
+               __HeapBase = .;
+               __end__ = .;
+               end = __end__;
+               KEEP(*(.heap*))
+               __HeapLimit = .;
+       } > RAM
+
+       /* .stack_dummy section doesn't contains any symbols. It is only
+        * used for linker to calculate size of stack sections, and assign
+        * values to stack symbols later */
+       .stack_dummy (COPY):
+       {
+               KEEP(*(.stack*))
+       } > RAM
+
+       /* Set stack top to end of RAM, and stack limit move down by
+        * size of stack_dummy section */
+       __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+       __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+       PROVIDE(__stack = __StackTop);
+
+       /* Check if data + heap + stack exceeds RAM limit */
+       ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+}
diff --git a/src/bootloader/main.rs b/src/bootloader/main.rs
new file mode 100644 (file)
index 0000000..198eb44
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#![no_std]
+#![crate_type="staticlib"]
+#[link(name="libcommon.rlib")]
+
+extern crate common;
+
+#[no_mangle]
+pub unsafe extern fn main() {
+    loop {
+    }
+}
diff --git a/src/bootloader/start.c b/src/bootloader/start.c
new file mode 100644 (file)
index 0000000..5363ac0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+extern void main();
+
+__attribute__((noreturn)) void
+_start (void)
+{
+       main();
+
+       for (;;) {
+       }
+}
diff --git a/src/common/lib.rs b/src/common/lib.rs
new file mode 100644 (file)
index 0000000..3ed90e8
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#![no_std]
+#![crate_name="common"]
+#![crate_type="rlib"]
+#![feature(lang_items)]
+
+#[lang="eh_personality"]
+extern fn eh_personality() {
+}
+
+#[lang="panic_fmt"]
+#[no_mangle]
+pub fn rust_begin_unwind(_fmt: &core::fmt::Arguments, _file_line: &(&'static str, usize)) -> ! {
+    loop {
+    }
+}
diff --git a/src/common/startup.c b/src/common/startup.c
new file mode 100644 (file)
index 0000000..daa8906
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2019 Tilman Sauerbeck (tilman at code-monkey de)
+ *
+ * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include <stdint.h>
+
+void Reset_Handler (void);
+void NMI_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void HardFault_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SVC_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PendSV_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SysTick_Handler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+
+void DMA0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DMA3_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void FTFA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PMC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void LLWU_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2C0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2C1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SPI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void SPI1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void UART2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void ADC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void CMP0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM1_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TPM2_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void RTC_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void RTC_Seconds_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PIT_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void I2S0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void USB0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void DAC0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void TSI0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void MCG_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void LPTMR0_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PORTA_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+void PORTC_PORTD_IRQHandler (void) __attribute__ ((weak, alias("Dummy_Handler")));
+
+extern void _start (void) __attribute__((noreturn));
+
+extern uint32_t __etext;
+extern uint32_t __data_start__;
+extern uint32_t __data_end__;
+extern uint32_t __bss_start__;
+extern uint32_t __bss_end__;
+extern uint32_t __StackTop;
+
+__attribute__ ((section(".vectors")))
+const void * __Vectors[48] =
+{
+       &__StackTop, /* Initial stack pointer */
+
+       (void *) Reset_Handler,
+       (void *) NMI_Handler,
+       (void *) HardFault_Handler,
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) SVC_Handler,
+       (void *) (0UL), /* Reserved */
+       (void *) (0UL), /* Reserved */
+       (void *) PendSV_Handler,
+       (void *) SysTick_Handler,
+
+       (void *) DMA0_IRQHandler,
+       (void *) DMA1_IRQHandler,
+       (void *) DMA2_IRQHandler,
+       (void *) DMA3_IRQHandler,
+       (void *) (0UL), /* Reserved */
+       (void *) FTFA_IRQHandler,
+       (void *) PMC_IRQHandler,
+       (void *) LLWU_IRQHandler,
+       (void *) I2C0_IRQHandler,
+       (void *) I2C1_IRQHandler,
+       (void *) SPI0_IRQHandler,
+       (void *) SPI1_IRQHandler,
+       (void *) UART0_IRQHandler,
+       (void *) UART1_IRQHandler,
+       (void *) UART2_IRQHandler,
+       (void *) ADC0_IRQHandler,
+       (void *) CMP0_IRQHandler,
+       (void *) TPM0_IRQHandler,
+       (void *) TPM1_IRQHandler,
+       (void *) TPM2_IRQHandler,
+       (void *) RTC_IRQHandler,
+       (void *) RTC_Seconds_IRQHandler,
+       (void *) PIT_IRQHandler,
+       (void *) I2S0_IRQHandler,
+       (void *) USB0_IRQHandler,
+       (void *) DAC0_IRQHandler,
+       (void *) TSI0_IRQHandler,
+       (void *) MCG_IRQHandler,
+       (void *) LPTMR0_IRQHandler,
+       (void *) (0UL), /* Reserved */
+       (void *) PORTA_IRQHandler,
+       (void *) PORTC_PORTD_IRQHandler,
+};
+
+void
+Reset_Handler (void)
+{
+       uint32_t *src, *dst;
+
+       src = &__etext;
+       dst = &__data_start__;
+
+       /* Initialize data. */
+       while (dst < &__data_end__)
+               *dst++ = *src++;
+
+       /* Clear bss. */
+       for (dst = &__bss_start__; dst < &__bss_end__; dst++)
+               *dst = 0;
+
+       _start();
+}
+
+void
+Dummy_Handler (void)
+{
+       for (;;) {
+       }
+}
diff --git a/thumbv6m-none-eabi.json b/thumbv6m-none-eabi.json
new file mode 100644 (file)
index 0000000..918798f
--- /dev/null
@@ -0,0 +1,15 @@
+{
+    "arch": "arm",
+    "data-layout": "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64",
+    "executables": true,
+    "os": "none",
+    "pre-link-args": ["-Wl,-("],
+    "post-link-args": ["-Wl,-)"],
+    "target-endian": "little",
+    "target-pointer-width": "32",
+    "cpu": "cortex-m0",
+    "llvm-target": "thumbv6m-none-eabi",
+    "features": "+strict-align",
+    "relocation-model": "static",
+    "no-compiler-rt": true
+}