1.BootLoader&app内容:
BootLoader启动文件:start.s
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD 0
DCD Reset_Handler ; Reset Handler
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT mymain
LDR SP, =(0x20000000+0x1000)
BL mymain
ENDP
start_app PROC
EXPORT start_app
; set vector base address as 0x08040000
ldr r3, =0xE000ED08
str r0, [r3]
ldr sp, [r0] ; read val from new vector
ldr r1, [r0, #4] ; read val from "new vector + 4“
BX r1
ENDP
END
BootLoader的Main文件
#include "uart.h"
typedef unsigned int __be32;
typedef unsigned char uint8_t;
#define IH_MAGIC 0x27051956 /* Image Magic Number */
#define IH_NMLEN 32 /* Image Name Length */
typedef struct image_header {
__be32 ih_magic; /* Image Header Magic Number */
__be32 ih_hcrc; /* Image Header CRC Checksum */
__be32 ih_time; /* Image Creation Timestamp */
__be32 ih_size; /* Image Data Size */
__be32 ih_load; /* Data Load Address */
__be32 ih_ep; /* Entry Point Address */
__be32 ih_dcrc; /* Image Data CRC Checksum */
uint8_t ih_os; /* Operating System */
uint8_t ih_arch; /* CPU architecture */
uint8_t ih_type; /* Image Type */
uint8_t ih_comp; /* Compression Type */
uint8_t ih_name[IH_NMLEN]; /* Image Name */
} image_header_t;
unsigned int be32_to_cpu(unsigned int x)
{
unsigned char *p = (unsigned char *)&x;
unsigned int le;
le = (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + (p[3]);
return le;
}
extern void start_app(unsigned int new_vector);
void delay(int d)
{
while(d--);
}
void copy_app(void *src, void *dest, unsigned int len)
{
unsigned char *pcDest = dest ;
unsigned char *pcSrc =src ;
while (len --)
{
*pcDest = *pcSrc;
pcSrc++;
pcDest++;
}
}
void relocate_and_start_app(unsigned int pos)
{
image_header_t *head;
unsigned int load;
unsigned int size;
unsigned int new_pos = pos+sizeof(image_header_t);
/* 读出头部 */
head = (image_header_t *)pos;
/* 解析头部 */
load = be32_to_cpu(head->ih_load);
size = be32_to_cpu(head->ih_size);
putstr("load = ");
puthex(load);
putstr("\r\n");
putstr("size = ");
puthex(size);
putstr("\r\n");
/* 把程序复制到RAM */
copy_app((unsigned char *)new_pos, (unsigned char *)load, size);
/* 跳转执行 */
start_app(new_pos);
}
int mymain()
{
unsigned int app_pos = 0x08001000;
uart_init();
putstr("bootloader\r\n");
/* start app */
relocate_and_start_app(app_pos);
//start_app(new_vector);
return 0;
}
APP的启动文件:
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors DCD 0x20000000+0x1000
DCD Reset_Handler ; Reset Handler
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT mymain
IMPORT memcpy
IMPORT |Image$$RW_IRAM1$$Base|
IMPORT |Image$$RW_IRAM1$$Length|
IMPORT |Load$$RW_IRAM1$$Base|
; relocate data section
LDR R0, = |Image$$RW_IRAM1$$Base| ; DEST
LDR R1, = |Load$$RW_IRAM1$$Base| ; SORUCE
LDR R2, = |Image$$RW_IRAM1$$Length| ; LENGTH
BL memcpy
;LDR SP, =(0x20000000+0x10000)
;BL mymain
ldr pc, =mymain
ENDP
END
APP的散列文件:
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08001040 0x00001000 { ; load region size_region
ER_IROM1 0x20000000 0x1000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20001000 0x100 { ; RW data
.ANY (+RW +ZI)
}
}
APP 的mian文件:
#include "uart.h"
char buf[50] = "www.100ask.net";
void delay(int d)
{
while(d--);
}
void memcpy(void *dest, void *src, unsigned int len)
{
unsigned char *pcDest = dest;
unsigned char *pcSrc = src;
while (len --)
{
*pcDest = *pcSrc;
pcSrc++;
pcDest++;
}
}
int mymain()
{
char c = 'A';
uart_init();
int (*fp)(char c);
fp = putchar;
putstr(buf);
while (1)
{
fp(c++);
putchar(c++);
delay(1000000);
if (c == 'B')
c = 'A';
}
return 0;
}
2.反汇编与bin对应关系:
0x08001164是通过:0x08001000+0x40(头部大小)+0x124(代码段+常量)得到的。
数据段存放的内容是“www.100ask.net”
3.使用BootLoader引导app时,需要注意app的散列文件:
如果散列文件如下设置:
数据段的地址是独立设置的,那么RAM运行app时,要先做重定位:
源码教程如下: