QUOTE (spongebob @ Apr 27 2012, 13:19)

Записи -Wl,--section-start=.data=0x802000 и -Wl,--section-start,.data=0x802000 эквивалентны?
Т. е., синтаксис указания начала расположения секций имеет несколько вариантов?
Да, эквивалентны. Это синтаксис
ключа -Wl передачи параметров программой-драйвером (avr-)gcc программе-линкеру (avr-)ld:
QUOTE
-Wl,option
Pass option as an option to the linker. If option contains commas, it is split into multiple options at the commas. You can use this syntax to pass an argument to the option. For example, `-Wl,-Map,output.map' passes `-Map output.map' to the linker. When using the GNU linker, you can also get the same effect with `-Wl,-Map=output.map'.
QUOTE (spongebob @ Apr 27 2012, 13:19)

Как на самом деле выглядят секции .data, .bss, .noinit?
Как области памяти.
QUOTE (spongebob @ Apr 27 2012, 13:19)

Как я понимаю, данные из .data копируются в определенный момент времени в ОЗУ, инициализируя переменные. Когда копируются и кем?
Да, верно понимаете. Копируются библиотечным стартап-кодом, который вызывается по вектору сброса и выполняется перед запуском main(). Этот код является
частью avr-libc. Аналогично там же обнуляется секция .bss
QUOTE (spongebob @ Apr 27 2012, 13:19)

А для чего нужна секция .noinit? Ведь есть же .data и .bss.
Для переменных, которые не нужно обнулять или инициализировать. Например, чтобы восстановить по их содержимому состояние программы после аварийного сброса по собаке или это может быть внешняя ОЗУ с батарейкой.
QUOTE (spongebob @ Apr 27 2012, 13:19)

Правильно ли я понимаю, что все глобальные или статические переменные, которые инициализированы программистом попадают в .data, а неинициализированные глобальные и статические переменные попадают в .bss и инициализируются нулями (по стандарту Си)?
Да, правильно. Современные компиляторы могут помещать явно инициализированные нулем глобальные переменные в .bss вместо .data, чтобы не хранить их начальные значения и сэкономить таким образом память кода.
QUOTE (spongebob @ Apr 27 2012, 13:19)

А что происходит с локальными инициализированными переменными? Они же создаются на стеке, кто их и когда инициализирует?
Исполняемый код функции во время ее исполнения, как правило непосредственно перед использованием локальной переменной. А вот место в стеке резервируется сразу под все локальные переменные на входе в функцию, чтобы не дергать указатель стека на каждую переменную. Естественно, компилятор использует одно и то же место на стеке под разные локальные переменные у которых не пересекается время жизни.
QUOTE (spongebob @ Apr 27 2012, 13:19)

Зачем нужны .finiN, если мы в main() обычно делаем while(1) {};?
На случай, если вы захотите выйти из main(). Если вы из main() не выходите - можете удалить их из линкерного скрипта и сэкономить пару байтов кода. А можете подменить библиотечный exit() выключая в нем питание и тогда сможете выключать прибор выходя из main(). Перед выключением будут штатно и в нужном порядке вызываться деструкторы глобальных объектов. Мало ли, может быть вам это нужно. Например, закрыть файлы и отмонтировать файловую систему, предварительно сделав запись об отключении в деструкторе объекта-системного журнала событий. Программы бывают разные.