36 #include <avr/pgmspace.h>
37 #include <avr/interrupt.h>
38 #include "dev/rs232.h"
45 #define R_AVR_7_PCREL 2
46 #define R_AVR_13_PCREL 3
49 #define R_AVR_LO8_LDI 6
50 #define R_AVR_HI8_LDI 7
51 #define R_AVR_HH8_LDI 8
52 #define R_AVR_LO8_LDI_NEG 9
53 #define R_AVR_HI8_LDI_NEG 10
54 #define R_AVR_HH8_LDI_NEG 11
55 #define R_AVR_LO8_LDI_PM 12
56 #define R_AVR_HI8_LDI_PM 13
57 #define R_AVR_HH8_LDI_PM 14
58 #define R_AVR_LO8_LDI_PM_NEG 15
59 #define R_AVR_HI8_LDI_PM_NEG 16
60 #define R_AVR_HH8_LDI_PM_NEG 17
63 #define ELF32_R_TYPE(info) ((unsigned char)(info))
68 #define PRINTF(...) printf(__VA_ARGS__)
73 static struct mmem module_heap;
89 return (
char*)
MMEM_PTR(&module_heap);
99 return (
void *)0x8000;
104 #define INCLUDE_APPLICATE_SOURCE 1
106 #if (FLASHEND > USHRT_MAX) && (__SIZEOF_POINTER__ <= 2)
107 #undef INCLUDE_APPLICATE_SOURCE
108 #define INCLUDE_APPLICATE_SOURCE 0
110 #if (__SIZEOF_POINTER__ > 2)
111 #define INCLUDE_32BIT_CODE 1
114 #if INCLUDE_APPLICATE_SOURCE
116 BOOTLOADER_SECTION
void
119 unsigned char buf[SPM_PAGESIZE];
120 unsigned short* flashptr = (
unsigned short *) mem;
131 for (flashptr=(
unsigned short *)mem; flashptr < (
unsigned short *) mem + size; flashptr += SPM_PAGESIZE) {
132 memset (buf, 0, SPM_PAGESIZE);
133 cfs_read(fd, buf, SPM_PAGESIZE);
141 boot_page_erase (flashptr);
142 boot_spm_busy_wait ();
144 unsigned short *origptr = flashptr;
148 for(i = 0; i < SPM_PAGESIZE; i+=2) {
149 boot_page_fill (flashptr, (uint16_t)((buf[i+1] << 8) | buf[i]));
155 boot_page_write (origptr);
156 boot_spm_busy_wait();
160 boot_spm_busy_wait ();
170 write_ldi(
int fd,
unsigned char *instr,
unsigned char byte)
172 instr[0] = (instr[0] & 0xf0) | (byte & 0x0f);
173 instr[1] = (instr[1] & 0xf0) | (byte >> 4);
174 cfs_write (fd, instr, 2);
181 struct elf32_rela *rela,
char *addr)
184 unsigned char instr[4];
187 cfs_read(fd, instr, 4);
190 type = ELF32_R_TYPE(rela->r_info);
192 addr += rela->r_addend;
197 PRINTF(PSTR (
"elfloader-avr.c: unsupported relocation type: "));
198 PRINTF(
"%d\n", type);
201 case R_AVR_7_PCREL: {
207 int16_t a = (((int)addr - rela->r_offset -2) / 2);
208 instr[0] |= (a << 3) & 0xf8;
209 instr[1] |= (a >> 5) & 0x03;
210 cfs_write(fd, instr, 2);
213 case R_AVR_13_PCREL: {
218 int16_t a = (int)addr / 2;
219 a -= rela->r_offset / 2;
221 instr[0] |= a & 0xff;
222 instr[1] |= (a >> 8) & 0x0f;
223 cfs_write(fd, instr, 2);
228 instr[0] = (int)addr & 0xff;
229 instr[1] = ((int)addr >> 8) & 0xff;
231 cfs_write(fd, instr, 2);
235 addr = (
char *)((
int)addr >> 1);
236 instr[0] = (int)addr & 0xff;
237 instr[1] = ((int)addr >> 8) & 0xff;
239 cfs_write(fd, instr, 2);
243 write_ldi(fd, instr, (
int)addr);
246 write_ldi(fd, instr, (
int)addr >> 8);
249 #if INCLUDE_32BIT_CODE
251 write_ldi(fd, instr, (
int)addr >> 16);
255 case R_AVR_LO8_LDI_NEG:
256 addr = (
char *) (0 - (
int)addr);
257 write_ldi(fd, instr, (
int)addr);
259 case R_AVR_HI8_LDI_NEG:
260 addr = (
char *) (0 - (
int)addr);
261 write_ldi(fd, instr, (
int)addr >> 8);
264 #if INCLUDE_32BIT_CODE
265 case R_AVR_HH8_LDI_NEG:
266 addr = (
char *)(0 - (
int)addr);
267 write_ldi(fd, instr, (
int)addr >> 16);
271 case R_AVR_LO8_LDI_PM:
272 write_ldi(fd, instr, (
int)addr >> 1);
274 case R_AVR_HI8_LDI_PM:
275 write_ldi(fd, instr, (
int)addr >> 9);
278 #if INCLUDE_32BIT_CODE
279 case R_AVR_HH8_LDI_PM:
280 write_ldi(fd, instr, (
int)addr >> 17);
284 case R_AVR_LO8_LDI_PM_NEG:
285 addr = (
char *) (0 - (
int)addr);
286 write_ldi(fd, instr, (
int)addr >> 1);
288 case R_AVR_HI8_LDI_PM_NEG:
289 addr = (
char *) (0 - (
int)addr);
290 write_ldi(fd, instr, (
int)addr >> 9);
293 #if INCLUDE_32BIT_CODE
294 case R_AVR_HH8_LDI_PM_NEG:
295 addr = (
char *) (0 - (
int)addr);
296 write_ldi(fd, instr, (
int)addr >> 17);
308 instr[2] = (
u8_t) ((
int)addr) & 0xff;
309 instr[3] = ((int)addr) >> 8;
310 cfs_write(fd, instr, 4);
314 PRINTF(PSTR (
"Unknown relocation type!\n"));
320 elfloader_unload(
void) {