kopia lustrzana https://github.com/stlink-org/stlink
Cleanroom for flashloaders done
rodzic
43ddace8f5
commit
36bb77dd6f
|
@ -0,0 +1,38 @@
|
||||||
|
# Note that according to the original GPLed code, compiling is noted to be
|
||||||
|
# as simple as gcc -c, this fails with my tests where this will lead to a wrong
|
||||||
|
# address read by the program.
|
||||||
|
# This makefile will save your time from dealing with compile errors
|
||||||
|
# Adjust CC if needed
|
||||||
|
|
||||||
|
CC = /opt/local/gcc-arm-none-eabi-8-2018-q4-major/bin/arm-none-eabi-gcc
|
||||||
|
|
||||||
|
CFLAGS_thumb1 = -mcpu=Cortex-M0 -Tlinker.ld -ffreestanding -nostdlib
|
||||||
|
CFLAGS_thumb2 = -mcpu=Cortex-M3 -Tlinker.ld -ffreestanding -nostdlib
|
||||||
|
|
||||||
|
all: stm32vl.o stm32f0.o stm32l.o stm32f4.o stm32f4_lv.o stm32l4.o stm32f7.o stm32f7_lv.o
|
||||||
|
|
||||||
|
stm32vl.o: stm32f0.s
|
||||||
|
$(CC) stm32f0.s $(CFLAGS_thumb2) -o stm32vl.o
|
||||||
|
stm32f0.o: stm32f0.s
|
||||||
|
$(CC) stm32f0.s $(CFLAGS_thumb1) -o stm32f0.o
|
||||||
|
stm32l.o: stm32lx.s
|
||||||
|
$(CC) stm32lx.s $(CFLAGS_thumb2) -o stm32l.o
|
||||||
|
stm32f4.o: stm32f4.s
|
||||||
|
$(CC) stm32f4.s $(CFLAGS_thumb2) -o stm32f4.o
|
||||||
|
stm32f4_lv.o: stm32f4lv.s
|
||||||
|
$(CC) stm32f4lv.s $(CFLAGS_thumb2) -o stm32f4_lv.o
|
||||||
|
stm32l4.o: stm32l4.s
|
||||||
|
$(CC) stm32l4.s $(CFLAGS_thumb2) -o stm32l4.o
|
||||||
|
stm32f7.o: stm32f7.s
|
||||||
|
$(CC) stm32f7.s $(CFLAGS_thumb2) -o stm32f7.o
|
||||||
|
stm32f7_lv.o: stm32f7lv.s
|
||||||
|
$(CC) stm32f7lv.s $(CFLAGS_thumb2) -o stm32f7_lv.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *.o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*. Entry Point *./
|
||||||
|
ENTRY( mycopy )
|
||||||
|
|
||||||
|
|
||||||
|
/*. Specify the memory areas .*/
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RAM ( xrw) : ORIGIN = 0x20000000 , LENGTH = 64K
|
||||||
|
}
|
|
@ -7,26 +7,34 @@
|
||||||
#define FLASH_REGS_BANK2_OFS 0x40
|
#define FLASH_REGS_BANK2_OFS 0x40
|
||||||
#define FLASH_BANK2_START_ADDR 0x08080000
|
#define FLASH_BANK2_START_ADDR 0x08080000
|
||||||
|
|
||||||
/* from openocd, contrib/loaders/flash/stm32.s */
|
/* flashloaders/stm32f0.s -- compiled with thumb2 */
|
||||||
static const uint8_t loader_code_stm32vl[] = {
|
static const uint8_t loader_code_stm32vl[] = {
|
||||||
0x08, 0x4c, /* ldr r4, STM32_FLASH_BASE */
|
0x16, 0x4f, 0x3c, 0x68,
|
||||||
0x1c, 0x44, /* add r4, r3 */
|
0x16, 0x4f, 0x3e, 0x68,
|
||||||
/* write_half_word: */
|
0x36, 0x19, 0x16, 0x4f,
|
||||||
0x01, 0x23, /* movs r3, #0x01 */
|
0x3d, 0x68, 0x2d, 0x19,
|
||||||
0x23, 0x61, /* str r3, [r4, #STM32_FLASH_CR_OFFSET] */
|
0x4f, 0xf0, 0x01, 0x07,
|
||||||
0x30, 0xf8, 0x02, 0x3b, /* ldrh r3, [r0], #0x02 */
|
0x33, 0x68, 0x3b, 0x43,
|
||||||
0x21, 0xf8, 0x02, 0x3b, /* strh r3, [r1], #0x02 */
|
0x33, 0x60, 0x03, 0x88,
|
||||||
/* busy: */
|
0x0b, 0x80, 0x4f, 0xf0,
|
||||||
0xe3, 0x68, /* ldr r3, [r4, #STM32_FLASH_SR_OFFSET] */
|
0x02, 0x07, 0xc0, 0x19,
|
||||||
0x13, 0xf0, 0x01, 0x0f, /* tst r3, #0x01 */
|
0xc9, 0x19, 0x4f, 0xf0,
|
||||||
0xfb, 0xd0, /* beq busy */
|
0x01, 0x07, 0x2b, 0x68,
|
||||||
0x13, 0xf0, 0x14, 0x0f, /* tst r3, #0x14 */
|
0x3b, 0x42, 0xfa, 0xd0,
|
||||||
0x01, 0xd1, /* bne exit */
|
0x4f, 0xf0, 0x04, 0x07,
|
||||||
0x01, 0x3a, /* subs r2, r2, #0x01 */
|
0x3b, 0x42, 0x04, 0xd0,
|
||||||
0xf0, 0xd1, /* bne write_half_word */
|
0x4f, 0xf0, 0x01, 0x07,
|
||||||
/* exit: */
|
0xd2, 0x1b, 0x00, 0x2a,
|
||||||
0x00, 0xbe, /* bkpt #0x00 */
|
0xe6, 0xd1, 0x4f, 0xf0,
|
||||||
0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */
|
0x01, 0x07, 0x33, 0x68,
|
||||||
|
0xbb, 0x43, 0x33, 0x60,
|
||||||
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
|
0x00, 0x20, 0x02, 0x40,
|
||||||
|
0x10, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x00, 0x00, 0x00,
|
||||||
|
0x50, 0x00, 0x00, 0x20,
|
||||||
|
0x54, 0x00, 0x00, 0x20,
|
||||||
|
0x58, 0x00, 0x00, 0x20
|
||||||
};
|
};
|
||||||
|
|
||||||
/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */
|
/* flashloaders/stm32f0.s -- thumb1 only, same sequence as for STM32VL, bank ignored */
|
||||||
|
@ -47,157 +55,132 @@ static const uint8_t loader_code_stm32vl[] = {
|
||||||
0x00, 0x30, // nop /* add r0,#0 */
|
0x00, 0x30, // nop /* add r0,#0 */
|
||||||
0x00, 0x30, // nop /* add r0,#0 */
|
0x00, 0x30, // nop /* add r0,#0 */
|
||||||
#endif
|
#endif
|
||||||
0x0A, 0x4C, // ldr r4, STM32_FLASH_BASE
|
0x13, 0x4f, 0x3c, 0x68,
|
||||||
0x01, 0x25, // mov r5, #1 /* FLASH_CR_PG, FLASH_SR_BUSY */
|
0x13, 0x4f, 0x3e, 0x68,
|
||||||
0x04, 0x26, // mov r6, #4 /* PGERR */
|
0x36, 0x19, 0x13, 0x4f,
|
||||||
// write_half_word:
|
0x3d, 0x68, 0x2d, 0x19,
|
||||||
0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */
|
0x12, 0x4f, 0x33, 0x68,
|
||||||
0x2B, 0x43, // orr r3, r5
|
0x3b, 0x43, 0x33, 0x60,
|
||||||
0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR |= FLASH_CR_PG */
|
0x03, 0x88, 0x0b, 0x80,
|
||||||
0x03, 0x88, // ldrh r3, [r0] /* r3 = *sram */
|
0x10, 0x4f, 0xc0, 0x19,
|
||||||
0x0B, 0x80, // strh r3, [r1] /* *flash = r3 */
|
0xc9, 0x19, 0x0e, 0x4f,
|
||||||
// busy:
|
0x2b, 0x68, 0x3b, 0x42,
|
||||||
0xE3, 0x68, // ldr r3, [r4, #12] /* FLASH->SR */
|
0xfb, 0xd0, 0x0e, 0x4f,
|
||||||
0x2B, 0x42, // tst r3, r5 /* FLASH_SR_BUSY */
|
0x3b, 0x42, 0x03, 0xd0,
|
||||||
0xFC, 0xD0, // beq busy
|
0x0a, 0x4f, 0xd2, 0x1b,
|
||||||
|
0x00, 0x2a, 0xeb, 0xd1,
|
||||||
0x33, 0x42, // tst r3, r6 /* PGERR */
|
0x08, 0x4f, 0x33, 0x68,
|
||||||
0x04, 0xD1, // bne exit
|
0xbb, 0x43, 0x33, 0x60,
|
||||||
|
0x00, 0xbe, 0xc0, 0x46,
|
||||||
0x02, 0x30, // add r0, r0, #2 /* sram += 2 */
|
0x00, 0x20, 0x02, 0x40,
|
||||||
0x02, 0x31, // add r1, r1, #2 /* flash += 2 */
|
0x10, 0x00, 0x00, 0x00,
|
||||||
0x01, 0x3A, // sub r2, r2, #0x01 /* count-- */
|
0x0c, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x2A, // cmp r2, #0
|
0x44, 0x00, 0x00, 0x20,
|
||||||
0xF0, 0xD1, // bne write_half_word
|
0x48, 0x00, 0x00, 0x20,
|
||||||
// exit:
|
0x4c, 0x00, 0x00, 0x20,
|
||||||
0x23, 0x69, // ldr r3, [r4, #16] /* FLASH->CR */
|
0x01, 0x00, 0x00, 0x00,
|
||||||
0xAB, 0x43, // bic r3, r5
|
0x02, 0x00, 0x00, 0x00,
|
||||||
0x23, 0x61, // str r3, [r4, #16] /* FLASH->CR &= ~FLASH_CR_PG */
|
0x04, 0x00, 0x00, 0x00
|
||||||
0x00, 0xBE, // bkpt #0x00
|
|
||||||
0x00, 0x20, 0x02, 0x40, /* STM32_FLASH_BASE: .word 0x40022000 */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32l[] = {
|
static const uint8_t loader_code_stm32l[] = {
|
||||||
// flashloaders/stm32lx.s
|
// flashloaders/stm32lx.s
|
||||||
|
|
||||||
0x04, 0xe0, // b test_done ; Go to compare
|
0x03, 0x68, 0x0b, 0x60,
|
||||||
// write_word:
|
0x4f, 0xf0, 0x04, 0x07,
|
||||||
0x04, 0x68, // ldr r4, [r0] ; Load one word from address in r0
|
0x38, 0x44, 0x39, 0x44,
|
||||||
0x0c, 0x60, // str r4, [r1] ; Store the word to address in r1
|
0x4f, 0xf0, 0x01, 0x07,
|
||||||
0x04, 0x30, // adds r0, #4 ; Increment r0
|
0xd2, 0x1b, 0x00, 0x2a,
|
||||||
0x04, 0x31, // adds r1, #4 ; Increment r1
|
0xf4, 0xd1, 0x00, 0xbe,
|
||||||
0x01, 0x3a, // subs r2, #1 ; Decrement r2
|
|
||||||
// test_done:
|
|
||||||
0x00, 0x2a, // cmp r2, #0 ; Compare r2 to 0
|
|
||||||
0xf8, 0xd8, // bhi write_word ; Loop if above 0
|
|
||||||
0x00, 0xbe, // bkpt #0x00 ; Set breakpoint to exit
|
|
||||||
0x00, 0x00
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32f4[] = {
|
static const uint8_t loader_code_stm32f4[] = {
|
||||||
// flashloaders/stm32f4.s
|
// flashloaders/stm32f4.s
|
||||||
|
|
||||||
0x07, 0x4b,
|
0xdf, 0xf8, 0x28, 0xc0,
|
||||||
|
0xdf, 0xf8, 0x28, 0xa0,
|
||||||
0x62, 0xb1,
|
0xe2, 0x44, 0x03, 0x68,
|
||||||
0x04, 0x68,
|
0x0b, 0x60, 0x00, 0xf1,
|
||||||
0x0c, 0x60,
|
0x04, 0x00, 0x01, 0xf1,
|
||||||
|
0x04, 0x01, 0xba, 0xf8,
|
||||||
0xdc, 0x89,
|
0x00, 0x30, 0x13, 0xf0,
|
||||||
0x14, 0xf0, 0x01, 0x0f,
|
0x01, 0x0f, 0xfa, 0xd0,
|
||||||
0xfb, 0xd1,
|
0xa2, 0xf1, 0x01, 0x02,
|
||||||
0x00, 0xf1, 0x04, 0x00,
|
0x00, 0x2a, 0xf0, 0xd1,
|
||||||
0x01, 0xf1, 0x04, 0x01,
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
0xa2, 0xf1, 0x01, 0x02,
|
0x00, 0x3c, 0x02, 0x40,
|
||||||
0xf1, 0xe7,
|
0x0e, 0x00, 0x00, 0x00
|
||||||
|
|
||||||
0x00, 0xbe,
|
|
||||||
|
|
||||||
0x00, 0x3c, 0x02, 0x40,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32f4_lv[] = {
|
static const uint8_t loader_code_stm32f4_lv[] = {
|
||||||
// flashloaders/stm32f4lv.s
|
// flashloaders/stm32f4lv.s
|
||||||
0x92, 0x00,
|
0xdf, 0xf8, 0x28, 0xc0,
|
||||||
|
0xdf, 0xf8, 0x28, 0xa0,
|
||||||
0x08, 0x4b,
|
0xe2, 0x44, 0x03, 0x78,
|
||||||
0x62, 0xb1,
|
0x0b, 0x70, 0x00, 0xf1,
|
||||||
0x04, 0x78,
|
0x01, 0x00, 0x01, 0xf1,
|
||||||
0x0c, 0x70,
|
0x01, 0x01, 0xba, 0xf8,
|
||||||
|
0x00, 0x30, 0x13, 0xf0,
|
||||||
0xdc, 0x89,
|
0x01, 0x0f, 0xfa, 0xd0,
|
||||||
0x14, 0xf0, 0x01, 0x0f,
|
0xa2, 0xf1, 0x01, 0x02,
|
||||||
0xfb, 0xd1,
|
0x00, 0x2a, 0xf0, 0xd1,
|
||||||
0x00, 0xf1, 0x01, 0x00,
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
0x01, 0xf1, 0x01, 0x01,
|
0x00, 0x3c, 0x02, 0x40,
|
||||||
0xa2, 0xf1, 0x01, 0x02,
|
0x0e, 0x00, 0x00, 0x00
|
||||||
0xf1, 0xe7,
|
|
||||||
|
|
||||||
0x00, 0xbe,
|
|
||||||
0x00, 0xbf,
|
|
||||||
|
|
||||||
0x00, 0x3c, 0x02, 0x40,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32l4[] = {
|
static const uint8_t loader_code_stm32l4[] = {
|
||||||
// flashloaders/stm32l4.s
|
// flashloaders/stm32l4.s
|
||||||
0x08, 0x4b, // start: ldr r3, [pc, #32] ; <flash_base>
|
0xdf, 0xf8, 0x2c, 0xc0,
|
||||||
0x72, 0xb1, // next: cbz r2, <done>
|
0xdf, 0xf8, 0x2c, 0xa0,
|
||||||
0x04, 0x68, // ldr r4, [r0, #0]
|
0xe2, 0x44, 0x03, 0x68,
|
||||||
0x45, 0x68, // ldr r5, [r0, #4]
|
0x44, 0x68, 0x0b, 0x60,
|
||||||
0x0c, 0x60, // str r4, [r1, #0]
|
0x4c, 0x60, 0x00, 0xf1,
|
||||||
0x4d, 0x60, // str r5, [r1, #4]
|
0x08, 0x00, 0x01, 0xf1,
|
||||||
0x5c, 0x8a, // wait: ldrh r4, [r3, #18]
|
0x08, 0x01, 0xba, 0xf8,
|
||||||
0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1
|
0x00, 0x30, 0x13, 0xf0,
|
||||||
0xfb, 0xd1, // bne.n <wait>
|
0x01, 0x0f, 0xfa, 0xd0,
|
||||||
0x00, 0xf1, 0x08, 0x00, // add.w r0, r0, #8
|
0xa2, 0xf1, 0x01, 0x02,
|
||||||
0x01, 0xf1, 0x08, 0x01, // add.w r1, r1, #8
|
0x00, 0x2a, 0xee, 0xd1,
|
||||||
0xa2, 0xf1, 0x01, 0x02, // sub.w r2, r2, #1
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
0xef, 0xe7, // b.n <next>
|
0x00, 0x20, 0x02, 0x40,
|
||||||
0x00, 0xbe, // done: bkpt 0x0000
|
0x12, 0x00, 0x00, 0x00
|
||||||
0x00, 0x20, 0x02, 0x40 // flash_base: .word 0x40022000
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32f7[] = {
|
static const uint8_t loader_code_stm32f7[] = {
|
||||||
// flashloaders/stm32f7.s
|
// flashloaders/stm32f7.s
|
||||||
0x08, 0x4b,
|
0xdf, 0xf8, 0x2c, 0xc0,
|
||||||
0x72, 0xb1,
|
0xdf, 0xf8, 0x2c, 0xa0,
|
||||||
0x04, 0x68,
|
0xe2, 0x44, 0x03, 0x68,
|
||||||
0x0c, 0x60,
|
0x0b, 0x60, 0x00, 0xf1,
|
||||||
0xbf, 0xf3, 0x4f, 0x8f, // DSB Memory barrier for in order flash write
|
0x04, 0x00, 0x01, 0xf1,
|
||||||
0xdc, 0x89,
|
0x04, 0x01, 0xbf, 0xf3,
|
||||||
0x14, 0xf0, 0x01, 0x0f,
|
0x4f, 0x8f, 0xba, 0xf8,
|
||||||
0xfb, 0xd1,
|
0x00, 0x30, 0x13, 0xf0,
|
||||||
0x00, 0xf1, 0x04, 0x00,
|
0x01, 0x0f, 0xfa, 0xd0,
|
||||||
0x01, 0xf1, 0x04, 0x01,
|
0xa2, 0xf1, 0x01, 0x02,
|
||||||
0xa2, 0xf1, 0x01, 0x02,
|
0x00, 0x2a, 0xee, 0xd1,
|
||||||
0xef, 0xe7,
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
0x00, 0xbe, // bkpt #0x00
|
0x00, 0x3c, 0x02, 0x40,
|
||||||
0x00, 0x3c, 0x02, 0x40,
|
0x0e, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t loader_code_stm32f7_lv[] = {
|
static const uint8_t loader_code_stm32f7_lv[] = {
|
||||||
// flashloaders/stm32f7lv.s
|
// flashloaders/stm32f7lv.s
|
||||||
0x92, 0x00, // lsls r2, r2, #2
|
0xdf, 0xf8, 0x2c, 0xc0,
|
||||||
0x09, 0x4b, // ldr r3, [pc, #36] ; (0x20000028 <flash_base>)
|
0xdf, 0xf8, 0x2c, 0xa0,
|
||||||
// next:
|
0xe2, 0x44, 0x03, 0x78,
|
||||||
0x72, 0xb1, // cbz r2, 24 <done>
|
0x0b, 0x70, 0x00, 0xf1,
|
||||||
0x04, 0x78, // ldrb r4, [r0, #0]
|
0x01, 0x00, 0x01, 0xf1,
|
||||||
0x0c, 0x70, // strb r4, [r1, #0]
|
0x01, 0x01, 0xbf, 0xf3,
|
||||||
0xbf, 0xf3, 0x4f, 0x8f, // dsb sy
|
0x4f, 0x8f, 0xba, 0xf8,
|
||||||
// wait:
|
0x00, 0x30, 0x13, 0xf0,
|
||||||
0xdc, 0x89, // ldrh r4, [r3, #14]
|
0x01, 0x0f, 0xfa, 0xd0,
|
||||||
0x14, 0xf0, 0x01, 0x0f, // tst.w r4, #1
|
0xa2, 0xf1, 0x01, 0x02,
|
||||||
0xfb, 0xd1, // bne.n e <wait>
|
0x00, 0x2a, 0xee, 0xd1,
|
||||||
0x00, 0xf1, 0x01, 0x00, // add r0, r0, #1
|
0x00, 0xbe, 0x00, 0xbf,
|
||||||
0x01, 0xf1, 0x01, 0x01, // add r1, r1, #1
|
0x00, 0x3c, 0x02, 0x40,
|
||||||
0xa2, 0xf1, 0x01, 0x02, // sub r2, r2, #1
|
0x0e, 0x00, 0x00, 0x00
|
||||||
0xef, 0xe7, // b next
|
|
||||||
// done:
|
|
||||||
0x00, 0xbe, // bkpt
|
|
||||||
0x00, 0xbf, // nop
|
|
||||||
// flash_base:
|
|
||||||
0x00, 0x3c, 0x02, 0x40 // .word 0x40023c00
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue