Попробую развить мысль дальше. Моя методика (описанная ниже) -- плохая. При компоновке программы с новой версией бутлоадера программа не работает с более старой. Даже если в ней ничего принципиально не менялось -- расположение функций в памяти просто другое. А ситуация старый бутлоадер + обновление программы -- типовая. Нужно делать структуру с указателями, как сказали. Кроме того, если я собираюсь экспортировать функции использующие .const сегмент, то нужно как-то менять PSVPAGE при их исполнении. Что неудобно (опять оборачивать каждую функцию ассемблером). Кроме того, мне не вернуть указатель на константные данные (если PSVPAGE у бутлоадера и рабочей программы разный). Единственное что приходит в голову -- сделать одинаковый PSVPAGE. А поскольку бутлоадер размещается в околонулевых адресах, то PSVPAGE должен быть равен нулю. Не так-то просто это. Написал в *.gld файле .const : AT(0x3000) { *(.const)...} Если менее 0x3000 -- пересекается с .text и не работает. Т.е. размер сегмента const у меня получается уже ограничен не в 0x8000, а в 0x5000 байт. Еле влезло. А если const сдвинуть ниже:
[ZX]
pic30-coff-ld: Link Error: section .const [002000 -> 006d49 ] overlaps section .text [000200 -> 002f45 ]Не совсем понимаю ошибку. Какая-то часть .text тяготеет к низу (но уже за пределами near -- первыми 0x2000 байт) и не хочет линковаться выше const, не понимаю почему. Кажется догадываюсь:
** Note that input sections *(.text) are not mapped here. ** The best-fit allocator locates them, so that .text ** may flow around PSV sections as needed. */ .text : { *(.init); *(.user_init); KEEP (*(.handle)); KEEP (*(.isr*)); *(.libc) *(.libm) *(.libdsp); /* keep together in this order */ *(.lib*); } >programИз-за комментария выше. Всё в .lib* кладётся обязательно до const. Не понимаю с какой целью. Особенно keep together in this order -- какой в этом смысл? Написал так:
.lowtext : { *(.init); *(.user_init); KEEP (*(.handle)); KEEP (*(.isr*)); } >program /* ** For PSV type sections, the Load Memory Address (LMA) ** should be specified as follows: ** ** userconst : AT(0x1234) ** { ** *(userconst); ** } >program ** ** Note that mapping PSV sections in linker scripts ** is not generally recommended. ** ** Because of page alignment restrictions, memory is ** often used more efficiently when PSV sections ** do not appear in the linker script. ** ** For more information on memory allocation, ** please refer to chapter 10, 'Linker Processing' ** in the Assembler, Linker manual (DS51317). */ .const : AT(0x1000) { ___start_const = .; *(.const); ___start_xsref = .; *(xsref); ___stop_xsref = .; ___start_fsm = .; *(fsm); ___stop_fsm = .; ___start_minit = .; *(minit); ___stop_minit = .; ___stop_const = .; } >program .text : { *(.libc) *(.libm) *(.libdsp); /* keep together in this order */ *(.lib*); } > programПомогло... Но не понимаю такого отношения к секции libc, libm и т.п. Зачем? Возвращаясь назад. Теперь т.к. const лежит от 0x1000 до чуть менее чем 0x5000 (меньше 0x8000 -- верхний лимит) PSVPAGE будет равен нулю. И я могу свободно передавать указатели на const-переменные из бутлоадера и обратно. И я могу сразу без модификации PSVPAGE вызывать функции экспортируемые бутлоадером (если они используют секцию const, что для более-менее сложного кода всегда). И могу сделать структуру со списком адресов экспортируемых функций и пытаться эту структуру расположить по фиксированному адресу (в ПЗУ). Что я ещё мог забыть?