AVR - How to program an AVR chip in Linux
I don't have the time for a full explanation, but I can give you cookbook-style the commands I use on my Linux box to program AVRs:

Preparations


On Ubuntu, make sure several required packages are installed: sudo apt-get install avr-libc avrdude binutils-avr gcc-avr srecord optionally throw in gdb-avr simulavr for debug and simulation.
I started to create a directory  in which all my ATtiny projects find a home: mkdir ~/attiny: cd ~/attiny
For each project I create a dedicated subfolder (and I don't mind long names): mkdir waveShare4digit8segmentDisplay; cd waveShare4digit8segmentDisplay


Create source


Edit the source file with your favorite text editor: vi project.cpp


Settings

The commands below heavily rely on environment variables, to keep maintenance easy.


The base name of the files used/created: src=project
Common compiler flags: cflags="-g -DF_CPU=${avrFreq} -Wall -Os - Werror -Wextra"


The variables below may need to be changed depending on the exact programmer you use. Refer to the man pages for details.


baud=19200 The baudrate your programmer communicates at with the PC: 
programmerDev=/dev/ttyUSB003 The device name where your programmer is located. Check dmesg output for details.
programmerType=avrisp This may be different for your exact programmer. 


The variables below depend on the exact controller you want to program:


avrType=attiny2313 Check avrdude -c $programmerType for supported devices.
avrFreq=1000000 Check the controller's datasheet for default clock.


Compile


First step is to create an object file: avr-gcc ${cflags) -mmcu=${avrType) -Wa,-ahlmns=${src).lst -c -o ${src).o ${src).cpp
Second step is to create an ELF file: avr-gcc ${cflags) -mmcu=${avrType) -o ${src).elf ${src).o
Third step is to create an Intel Hex file, this is the file that is actually sent to the programmer: avr-objcopy -j .text -j .data -O ihex ${src).elf ${src).flash.hex


Programming


Final step is to program the device: avrdude -p${avrType} -c${programmerType} -P${programmerDev} -b${baud} -v -U flash:w:${src}.flash.hex


Makefile

As an alternative to remembering the commands, I cooked up a makefile to my personal liking, you can save it under the name Makefile (mind the capital M). It works as follows:


make makefile Edit the makefile;
make edit Edit the source file;
make flash Program the device's flash memory;
make help List other commands.


Here is the makefile:

baud=19200
src=project
avrType=attiny2313
avrFreq=4000000 # 4MHz for accurate baudrate timing
programmerDev=/dev/ttyUSB003
programmerType=arduino

cflags=-g -DF_CPU=$(avrFreq) -Wall -Os -Werror -Wextra

memoryTypes=calibration eeprom efuse flash fuse hfuse lfuse lock signature application apptable boot prodsig usersig

.PHONY: backup clean disassemble dumpelf edit eeprom elf flash fuses help hex makefile object program

help:
    @echo 'backup       Read all known memory types from controller and write it into a file. Available memory types: $(memoryTypes)'
    @echo 'clean        Delete automatically created files.'
    @echo 'disassemble  Compile source code, then disassemble object file to mnemonics.'
    @echo 'dumpelf      Dump the contents of the .elf file. Useful for information purposes only.'
    @echo 'edit     Edit the .cpp source file.'
    @echo 'eeprom       Extract EEPROM data from .elf file and program the device with it.'
    @echo 'elf      Create $(src).elf'
    @echo 'flash        Program $(src).hex to controller flash memory.'
    @echo 'fuses        Extract FUSES data from .elf file and program the device with it.'
    @echo 'help     Show this text.'
    @echo 'hex      Create all hex files for flash, eeprom and fuses.'
    @echo 'object       Create $(src).o'
    @echo 'program      Do all programming to controller.'

edit:
    vi $(src).cpp

makefile:
    vi Makefile

#all: object elf hex

clean: 
    rm $(src).elf $(src).eeprom.hex $(src).fuses.hex $(src).lfuse.hex $(src).hfuse.hex $(src).efuse.hex $(src).flash.hex $(src).o
    date

object:
    avr-gcc $(cflags) -mmcu=$(avrType) -Wa,-ahlmns=$(src).lst -c -o $(src).o $(src).cpp 

elf: object
    avr-gcc $(cflags) -mmcu=$(avrType) -o $(src).elf $(src).o
    chmod a-x $(src).elf 2&gt;&amp;1

hex:    elf
    avr-objcopy -j .text -j .data -O ihex $(src).elf $(src).flash.hex
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex $(src).elf $(src).eeprom.hex
    avr-objcopy -j .fuse -O ihex $(src).elf $(src).fuses.hex --change-section-lma .fuse=0
    srec_cat $(src).fuses.hex -Intel -crop 0x00 0x01 -offset  0x00 -O $(src).lfuse.hex -Intel
    srec_cat $(src).fuses.hex -Intel -crop 0x01 0x02 -offset -0x01 -O $(src).hfuse.hex -Intel
    srec_cat $(src).fuses.hex -Intel -crop 0x02 0x03 -offset -0x02 -O $(src).efuse.hex -Intel

disassemble: elf
    avr-objdump -s -j .fuse $(src).elf
    avr-objdump -C -d $(src).elf 2&gt;&amp;1

eeprom: hex
    #avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
    date

fuses: hex
    avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U lfuse:w:$(src).lfuse.hex
    #avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U hfuse:w:$(src).hfuse.hex
    #avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U efuse:w:$(src).efuse.hex
    date

dumpelf: elf
    avr-objdump -s -h $(src).elf

program: flash eeprom fuses

flash: hex
    avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U flash:w:$(src).flash.hex
    date

backup:
    @for memory in $(memoryTypes); do \
        avrdude -p $(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U $$memory:r:./$(avrType).$$memory.hex:i; \
    done


It may be seem necessary to run avrdude as root, if that happens it justifies a question in its own. It can be solved with udev but requires a bit specific information from how the programmer is recognized by the operating system.

Hello World

Let me throw in an 'Hello World' that makes a controller pin 2 (PB3) (eg. ATtiny13, ATtiny45, ATtiny85) toggle at 1Hz. Attach an LED and series resistor to the pin and the LED should start to blink.


make edit


i

#include &lt;avr/io.h&gt;
#include &lt;util/delay.h&gt;

int main(void)
{
  DDRB = 0x08;

  while (1) {
    PORTB = 0x00; _delay_ms(500);
    PORTB = 0x08; _delay_ms(500);
  }
}


&lt;ESC&gt;:wq


make flash


Done.