Jump to content

    

сборка бонарника для PROM

всем доброго здоровья!

я никогда не программировал prom-ы. а оказалось, что тут дело серьезное! :help:

 

у меня в исходниках на С есть некий статический буфер (неконстантный).

при сборке с использованием прилагающимся к компилятору ld-скриптом (если оставить в нём ram) получается бинарник (после objcopy) длиной аж 1Гб :07: ! начале, как положено - код, а статические даннные помещены в конец - в ram.

я выкинул ram из ld-скрипта. получился бинарник соответствующего размера. только, боюсь, что придется повозиться с пересылкой static-data в ram (если вообще будет работать :05: ).

и еще. у меня и нет никакого start-up кода и никакими библиотеками не пользуюсь. может дело еще в этом ?

 

вопрос: а как это делается , т.е. как сообще автоматизируется сборка и перенос static-data в ram?

Share this post


Link to post
Share on other sites
всем доброго здоровья!

И вам!

я никогда не программировал prom-ы. а оказалось, что тут дело серьезное! :help:

Чтобы понять это нужно обладать способностью к телепатии. К сожалению я ею не владею :).

Итак, попробую догадаться.

Вы имеете пример (для какого процессора?), без использования ОС, на С, предназначенный для загрузки в ОЗУ. И хотите перекомпилировать его для флеш и прошить.

Я угадал?

у меня в исходниках на С есть некий статический буфер (неконстантный).

при сборке с использованием прилагающимся к компилятору ld-скриптом (если оставить в нём ram) получается бинарник (после objcopy) длиной аж 1Гб :07: ! начале, как положено - код, а статические даннные помещены в конец - в ram.

я выкинул ram из ld-скрипта. получился бинарник соответствующего размера. только, боюсь, что придется повозиться с пересылкой static-data в ram (если вообще будет работать :05: ).

и еще. у меня и нет никакого start-up кода и никакими библиотеками не пользуюсь. может дело еще в этом ?

 

вопрос: а как это делается , т.е. как сообще автоматизируется сборка и перенос static-data в ram?

Потому как в Вашем вопросе мало конкретной информации придется начать издалека.

1. Компилятор (кстати какой? предполагаю gcc) из каждого *.c файла сделает *.o файл.

2. Линкер (предполагаю ld) возмет эти *.o файлы и, в соответствии со скриптом, разместит их содержимое в памяти. Получим *.elf файл.

3. objcopy возмет этот *.elf файл, и перепишет секции .text (собственно код) и .data (инициализируемые переменные) в другой файл - *.bin. Этот файл является копией всего адресного пространства процессора. Если у Вас ARM то это 4G. Естественно, если Ваша программа "умещается" в 1G то размер будет 1G.

Естественно Вам это не подходит :).

В таком случае нужно

1. Переписать скрипт линкера так, чтобы секция .data в выходном бинарике размещалась сразу за секцией .text.

2. Написать в стартап файле - это асм - кусочек, который при каждом включении питания перенесет секцию .data из флеш в ОЗУ, на то место где ее ожидает программа.

Если у Вас ARM то поищите в этой ветке и соседней про ARM, такие вопросы уже встречались и там можно найти примеры.

Пока будете тренироваться, воспользуйтесь objdump, readelf для просмотра заголовков секций. Там указаны LMA и VMA.

LMA - Load memory address Адрес памяти, куда прошивать эту секцию

VMA - Virtual memory address. Адрес памяти, где эта секция должнабыть во время выполнения программы.

Перенос данных из LMA в VMA - это задача стартап кода.

Еще полезно смотреть дизассемблер objdump -SD prg.elf > prg.dump

Share this post


Link to post
Share on other sites

большое спасибо за ответ!

 

И вам!

 

Чтобы понять это нужно обладать способностью к телепатии. К сожалению я ею не владею :).

Итак, попробую догадаться.

Вы имеете пример (для какого процессора?), без использования ОС, на С, предназначенный для загрузки в ОЗУ. И хотите перекомпилировать его для флеш и прошить.

Я угадал?

Потому как в Вашем вопросе мало конкретной информации придется начать издалека.

1. Компилятор (кстати какой? предполагаю gcc) из каждого *.c файла сделает *.o файл.

2. Линкер (предполагаю ld) возмет эти *.o файлы и, в соответствии со скриптом, разместит их содержимое в памяти. Получим *.elf файл.

3. objcopy возмет этот *.elf файл, и перепишет секции .text (собственно код) и .data (инициализируемые переменные) в другой файл - *.bin. Этот файл является копией всего адресного пространства процессора. Если у Вас ARM то это 4G. Естественно, если Ваша программа "умещается" в 1G то размер будет 1G.

Естественно Вам это не подходит :).

В таком случае нужно

1. Переписать скрипт линкера так, чтобы секция .data в выходном бинарике размещалась сразу за секцией .text.

2. Написать в стартап файле - это асм - кусочек, который при каждом включении питания перенесет секцию .data из флеш в ОЗУ, на то место где ее ожидает программа.

Если у Вас ARM то поищите в этой ветке и соседней про ARM, такие вопросы уже встречались и там можно найти примеры.

Пока будете тренироваться, воспользуйтесь objdump, readelf для просмотра заголовков секций. Там указаны LMA и VMA.

LMA - Load memory address Адрес памяти, куда прошивать эту секцию

VMA - Virtual memory address. Адрес памяти, где эта секция должнабыть во время выполнения программы.

Перенос данных из LMA в VMA - это задача стартап кода.

Еще полезно смотреть дизассемблер objdump -SD prg.elf > prg.dump

 

насчет недостаточости информации в моем вопросе Вы совершенно правы.

1. я прошиваю bios в prom sparc32 (точнее сказать нет возможности).

2. bios запускает Linux (точнее сказать нет )(этот Linux не требует Open-Firmware)

3. стандартный набор компиляторов gcc (точнее сказать нет возможности)

 

Пока будете тренироваться, воспользуйтесь objdump, readelf для просмотра заголовков секций. Там указаны LMA и VMA.

LMA - Load memory address Адрес памяти, куда прошивать эту секцию

VMA - Virtual memory address. Адрес памяти, где эта секция должнабыть во время выполнения программы.

Перенос данных из LMA в VMA - это задача стартап кода.

Еще полезно смотреть дизассемблер objdump -SD prg.elf > prg.dump

да..! это для меня новость!

 

 

1. Переписать скрипт линкера так, чтобы секция .data в выходном бинарике размещалась сразу за секцией .text.

2. Написать в стартап файле - это асм - кусочек, который при каждом включении питания перенесет секцию .data из флеш в ОЗУ, на то место где ее ожидает программа.

я написал код перемещения секци .data (но проверить пока невозможно),

но и самое главное я не понимаю !!! :help: -

не могли бы Вы объяснить как может программа ожидать свои данные в совершенно другом месте, чем они были изначально расположены? как я понимаю, наверное, для этого надо что-то где-то указать.

заранее спасибо!

 

 

вот что дал readelf.exe :

 

[Nr] Name Type Addr Off Size ES Flg Lk Inf Al

[ 2] .data PROGBITS 0001ad20 01ada0 000b50 00 WA 0 0 8

 

There is no dynamic section inthis file

There are no relocations in this file.

There are no unwind sections in this file.

 

а вот что дал objdump.exe -x:

 

Sections:

Idx Name Size VMA LMA File off Algn

0 .text 0001ad20 00000000 00000000 00000080 2**5

CONTENTS, ALLOC, LOAD, CODE

1 .data 00000b50 0001ad20 0001ad20 0001ada0 2**3

CONTENTS, ALLOC, LOAD, DATA

 

получается, что VMA==LMA и нЕкуда перемещать.

 

как же сделать, чтобы VMA был в области RAM ? :help:

 

 

у меня вот такой ld-скрит (после того как я изменил .data>ram на .data>rom).

 

/* linkcmds

*

* $Id: linkcmds,v 1.8.2.1 2000/05/24 17:06:38 joel Exp $

*/

OUTPUT_ARCH(sparc)

__DYNAMIC = 0;

 

/*

* The memory map looks like this:

* +--------------------+ <- low memory

* | .text |

* | etext |

* | ctor list | the ctor and dtor lists are for

* | dtor list | C++ support

* | _endtext |

* +--------------------+

* | .data | initialized data goes here

* | _sdata |

* | _edata |

* +--------------------+

* | .bss |

* | __bss_start | start of bss, cleared by crt0

* | _end | start of heap, used by sbrk()

* +--------------------+

* | heap space |

* | _ENDHEAP |

* | stack space |

* | __stack | top of stack

* +--------------------+ <- high memory

*/

 

 

/*

* User modifiable values:

*

* _CLOCK_SPEED in Mhz (used to program the counter/timers)

*

* _PROM_SIZE size of PROM (permissible values are 128K, 256K,

* 512K, 1M, 2M, 4M, 8M and 16M)

* _RAM_SIZE size of RAM (permissible values are 256K, 512K,

* 1M, 2M, 4M, 8M, 16M, and 32M)

*

*/

 

/* Default values, can be overridden */

 

_PROM_SIZE = 256K;

_RAM_SIZE = 2M;

 

_RAM_START = 0x02000000;/*???*/

/*********_RAM_START = 0x040000000;*/

_RAM_END = _RAM_START + _RAM_SIZE;

 

_PROM_START = 0x00000000;

_PROM_END = _PROM_START + _PROM_SIZE;

 

/*

* Alternate names without leading _.

*/

 

PROM_START = _PROM_START;

PROM_SIZE = _PROM_SIZE;

PROM_END = _PROM_END;

 

RAM_START = _RAM_START;

RAM_SIZE = _RAM_SIZE;

RAM_END = _RAM_END;

 

_LEON_REG = 0x80000000;

LEON_REG = 0x80000000;

_ERC32_MEC = 0x1f80000;

ERC32_MEC = 0x1f80000;

 

/* these are the maximum values */

 

MEMORY

{

rom : ORIGIN = 0x00000000, LENGTH = 256K

ram : ORIGIN = 0x40000000, LENGTH = 1024M

}

 

/*

* stick everything in ram (of course)

*/

SECTIONS

{

. = 0x0;

.text 0x0 :

{

CREATE_OBJECT_SYMBOLS

text_start = .;

_text_start = .;

*(.text)

*(.text.*)

. = ALIGN (16);

 

*(.eh_frame)

. = ALIGN (16);

 

*(.gnu.linkonce.t*)

 

__CTOR_LIST__ = .;

LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)

*(.ctors)

*(.ctors.*)

LONG(0)

__CTOR_END__ = .;

__DTOR_LIST__ = .;

LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)

*(.dtors)

*(.dtors.*)

LONG(0)

__DTOR_END__ = .;

 

_rodata_start = . ;

*(.rodata*)

*(.fixup)

*(.gnu.linkonce.r*)

_erodata = ALIGN( 0x10 ) ;

 

_ro_init_data_start = . ;

*(.ro_init_data*)

_ro_init_data_end = .;

 

etext = ALIGN(0x10);

_etext = .;

*(.init)

*(.fini)

*(.lit)

*(.shdata)

. = ALIGN (16);

_endtext = .;

 

} > rom

.dynamic : { *(.dynamic) } >ram

.got : { *(.got) } >ram

.plt : { *(.plt) } >ram

.hash : { *(.hash) } >ram

.dynrel : { *(.dynrel) } >ram

.dynsym : { *(.dynsym) } >ram

.dynstr : { *(.dynstr) } >ram

.hash : { *(.hash) } >ram

 

.data :

{

data_start = .;

_data_start = .;

_sdata = . ;

 

KEEP (*(.vectors))

 

*(.data)

*(.data.*)

*(.gnu.linkonce.d*)

*(.gcc_except_table)

KEEP(*( SORT (.ecos.table.*))) ;

. = ALIGN(0x10);

edata = .;

_edata = .;

} > rom

.shbss :

{

*(.shbss)

} > ram

.bss :

{

__bss_start = ALIGN(0x8);

_bss_start = .;

bss_start = .;

*(.bss)

*(.bss.*)

*(COMMON)

end = .;

_end = ALIGN(0x8);

__end = ALIGN(0x8);

__bss_end = ALIGN(0x8);

__heap1 = .;

} > ram

.jcr . (NOLOAD) : { *(.jcr) }

.stab . (NOLOAD) :

{

[ .stab ]

}

.stabstr . (NOLOAD) :

{

[ .stabstr ]

}

}

Share this post


Link to post
Share on other sites

:tort: :santa2: :tort:

 

УРА!!! заработало!!!

 

вот что дал мне objdump.exe -x:

 

Idx Name Size VMA LMA File off Algn

1 .data 00000120 40000000 00018700 000187a0 2**3

 

я сделал в ld-скрипте : > ram AT > rom (см ниже):

 

.data :

{

....

} > ram AT > rom

 

всем спасиба!!! :tort: :beer:

теперь только осталось проверить - будет ли всё это работать ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this