This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Getting rid of interrupt vector table for AVR bootloader
- From: "Mark van de Veerdonk" <uhuh at vianetworks dot nl>
- To: <binutils at sources dot redhat dot com>
- Date: Mon, 24 Feb 2003 12:05:25 +0100
- Subject: Getting rid of interrupt vector table for AVR bootloader
Hello,
I'm trying to create a bootloader for the Atmel ATmega64 microcontroller. I
want to write it in C, not assembly. For a normal program, the GNU linker
(for avr) creates an image that includes all the interrupt vectors. Since a
bootloader program will not start at address 0, I do not want the interrupt
vector table. And that's something I haven't been able to achieve properly.
So far, I've been able to get rid of the vector table at the start of the
image. That's good. But it seems the linker has moved the table to the end
of the image. And that's not what I want but now I'm at a loss... Why is the
vector table added although it is no longer specified in the linker script?
I've created a linker script that tells ld that text section starts at
address 0xf800 and which has a modified text section description. It leaves
out the all C++ related initialization and finilization code (just to be
sure) and the .vectors section. I've included the relevant parts of the
script at the end of this mail.
The result is partially successful. Much to my surprise, it seems the linker
has now moved the interrupt vector table to the end of the image! You can
see in the disassembled resulting code I've appended to this mail. I can
remove the vector table manually from the image, but that would be a last
resort solution. What do I need to do to get rid of the interrupt vector
table all together? Thanx!
regards,
Mark
**********************************************************************
Start of linker script:
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)
MEMORY
{
text (rx) : ORIGIN = 0xf800, LENGTH = 2K
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
}
**********************************************************************
text section in the linker file:
.text :
{
/*
*(.vectors)
__ctors_start = . ;
*(.ctors)
__ctors_end = . ;
__dtors_start = . ;
*(.dtors)
__dtors_end = . ;
*/
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
*(.init0) /* Start here after reset. */
*(.init1)
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
*(.init3)
*(.init4) /* Initialize data and BSS. */
*(.init5)
/*
*(.init6) /* C++ constructors. */
*/
*(.init7)
*(.init8)
*(.init9) /* Call main(). */
*(.text)
. = ALIGN(2);
*(.text.*)
. = ALIGN(2);
*(.fini9) /* _exit() starts here. */
*(.fini8)
*(.fini7)
/*
*(.fini6) /* C++ destructors. */
*/
*(.fini5)
*(.fini4)
*(.fini3)
*(.fini2)
*(.fini1)
*(.fini0) /* Infinite loop after program termination. */
_etext = . ;
} > text
**********************************************************************
Disassembled code (with comments):
init2 code:
+00007C00: 2411 CLR R1 Exclusive OR
+00007C01: BE1F OUT 0x3F,R1 Out to I/O location
+00007C02: EFCF SER R28 Load immediate
+00007C03: E1D0 LDI R29,0x10 Load immediate
+00007C04: BFDE OUT 0x3E,R29 Out to I/O location
+00007C05: BFCD OUT 0x3D,R28 Out to I/O location
init4 code:
+00007C06: E011 LDI R17,0x01 Load immediate
+00007C07: E0A0 LDI R26,0x00 Load immediate
+00007C08: E0B1 LDI R27,0x01 Load immediate
+00007C09: E6EC LDI R30,0x6C Load immediate
+00007C0A: EFF8 LDI R31,0xF8 Load immediate
+00007C0B: C002 RJMP +0x0002 Relative jump
+00007C0C: 9005 LPM R0,Z+ Load program memory and
postincrement
+00007C0D: 920D ST X+,R0 Store indirect and
postincrement
+00007C0E: 30A0 CPI R26,0x00 Compare with immediate
+00007C0F: 07B1 CPC R27,R17 Compare with carry
+00007C10: F7D9 BRNE +0x7B Branch if status flag
cleared
+00007C11: E011 LDI R17,0x01 Load immediate
+00007C12: E0A0 LDI R26,0x00 Load immediate
+00007C13: E0B1 LDI R27,0x01 Load immediate
+00007C14: C001 RJMP +0x0001 Relative jump
+00007C15: 921D ST X+,R1 Store indirect and
postincrement
+00007C16: 30A0 CPI R26,0x00 Compare with immediate
+00007C17: 07B1 CPC R27,R17 Compare with carry
+00007C18: F7E1 BRNE +0x7C Branch if status flag
cleared
init9 code:
+00007C19: 940C7C24 JMP 0x00007C24 Jump
+00007C1B: 940C7C36 JMP 0x00007C36 Jump
A very exciting subroutine I coded:
+00007C1D: 01FC MOVW R30,R24 Copy register pair
+00007C1E: 8180 LDD R24,Z+0 Load indirect with
displacement
+00007C1F: 8191 LDD R25,Z+1 Load indirect with
displacement
+00007C20: 9601 ADIW R24,0x01 Add immediate to word
+00007C21: 8380 STD Z+0,R24 Store indirect with
displacement
+00007C22: 8391 STD Z+1,R25 Store indirect with
displacement
+00007C23: 9508 RET Subroutine return
The main() code (also very exciting):
+00007C24: EFCF SER R28 Load immediate
+00007C25: E1D0 LDI R29,0x10 Load immediate
+00007C26: BFDE OUT 0x3E,R29 Out to I/O location
+00007C27: BFCD OUT 0x3D,R28 Out to I/O location
+00007C28: E0C0 LDI R28,0x00 Load immediate
+00007C29: E0D0 LDI R29,0x00 Load immediate
+00007C2A: 01CE MOVW R24,R28 Copy register pair
+00007C2B: 940E7C1D CALL 0x00007C1D Call subroutine
+00007C2D: 9621 ADIW R28,0x01 Add immediate to word
+00007C2E: 31C4 CPI R28,0x14 Compare with immediate
+00007C2F: 05D1 CPC R29,R1 Compare with carry
+00007C30: F3CC BRLT +0x79 Branch if status flag set
+00007C31: E080 LDI R24,0x00 Load immediate
+00007C32: E090 LDI R25,0x00 Load immediate
+00007C33: 940C7C35 JMP 0x00007C35 Jump
fini0 code:
+00007C35: CFFF RJMP -0x0001 Relative jump
the vector table?!?!?:
+00007C36: 940C7C00 JMP 0x00007C00 Jump
+00007C38: 940C7C1B JMP 0x00007C1B Jump
+00007C3A: 940C7C1B JMP 0x00007C1B Jump
+00007C3C: 940C7C1B JMP 0x00007C1B Jump
+00007C3E: 940C7C1B JMP 0x00007C1B Jump
+00007C40: 940C7C1B JMP 0x00007C1B Jump
+00007C42: 940C7C1B JMP 0x00007C1B Jump
+00007C44: 940C7C1B JMP 0x00007C1B Jump
+00007C46: 940C7C1B JMP 0x00007C1B Jump
+00007C48: 940C7C1B JMP 0x00007C1B Jump
+00007C4A: 940C7C1B JMP 0x00007C1B Jump
+00007C4C: 940C7C1B JMP 0x00007C1B Jump
+00007C4E: 940C7C1B JMP 0x00007C1B Jump
+00007C50: 940C7C1B JMP 0x00007C1B Jump
+00007C52: 940C7C1B JMP 0x00007C1B Jump
+00007C54: 940C7C1B JMP 0x00007C1B Jump
+00007C56: 940C7C1B JMP 0x00007C1B Jump
+00007C58: 940C7C1B JMP 0x00007C1B Jump
+00007C5A: 940C7C1B JMP 0x00007C1B Jump
+00007C5C: 940C7C1B JMP 0x00007C1B Jump
+00007C5E: 940C7C1B JMP 0x00007C1B Jump
+00007C60: 940C7C1B JMP 0x00007C1B Jump
+00007C62: 940C7C1B JMP 0x00007C1B Jump
+00007C64: 940C7C1B JMP 0x00007C1B Jump
+00007C66: 940C7C1B JMP 0x00007C1B Jump
+00007C68: 940C7C1B JMP 0x00007C1B Jump
+00007C6A: 940C7C1B JMP 0x00007C1B Jump
+00007C6C: 940C7C1B JMP 0x00007C1B Jump
+00007C6E: 940C7C1B JMP 0x00007C1B Jump
+00007C70: 940C7C1B JMP 0x00007C1B Jump
+00007C72: 940C7C1B JMP 0x00007C1B Jump
+00007C74: 940C7C1B JMP 0x00007C1B Jump
+00007C76: 940C7C1B JMP 0x00007C1B Jump
+00007C78: 940C7C1B JMP 0x00007C1B Jump
+00007C7A: 940C7C1B JMP 0x00007C1B Jump
Uninitialized program space from here on...