Search code examples
assemblystartupldavravr-gcc

AVR: Creating and understanding minimum startup code and linker scripts from scratch


EDITED AND SHORTENED

My goal is to write the minimum necessary startup-code and linker script "from scratch" for a system which is new to me and reach main(). I only want to use the available documentation. No IDE or code generation. I picked the Attiny 2313. I am not trying to flash the code yet, just cross-compile and link.

The toolchain I am trying to use is avr-gcc, objdump for checking and GNU LD for linking.

The specific questions I want to ask are the following:

  1. Does the compiler already know symbols of fuse bits like CKEL, SUT and SREG? Do I have to declare them myself? I read avr-gcc documentation and gnu-as-documentation.

  2. I found that for avr, a variety of memory-sections is created: .text, .data, .bss, .eeprom, .noinit, .initN, .finiN, .note.gnu.avr.deviceinfo. Should I expect that any of these memory-sections is in use? Or is it even mandatory that all sections are in use?


Solution

  • AVR's have lots unique design descisions which make them very fun to code in assembler. At its core, an AVR cpu does two things: fetch instructions, and execute them. As the device boots up, the program counter points at address 0x0000 (reset vector). And if no jmp/rjmp or some other branching instruction is there, it will fetch the next instruction in address 0x0001 and execute it.

    For starting out I would focus on learning the instruction set and especially instructions concerned with Memory (lds, sts, in, out, ld, st, ldi) and don't think about interrupt vectors or any peripherals as it can get overwhelming pretty quick. After that try to make analogues of stuff you know in other languages, like defining a static array and filling it with numbers from 0 to n, simple stuff like that, so that you actually get to successfully compile some programs and have the ability to debug in the simulator (also included in microchip studio)

    In general, the concepts you need to focus on are (most important to least):

    1. Arithmetic instructions
    2. Branching (JMP/RJMP/BREQ/BRNE etc)
    3. Volatile Memory instructions (listed above)
    4. Pointers (X,Y,Z And their iusage with ld/st instructions)
    5. The stack pointer (PUSH/POP instructions)
    6. Routines (CALL/RCALL/RET instructions)
    7. Interrupts and interrupt routines (RETI instruction and the vector )

    There are many many more concepts to understand. I would also recommend watching some youtube videos for examples of simple code you can compile and debug where someone takes you through some of it step by step.