Jump to content

    
Sign in to follow this  
vv40in

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

Recommended Posts

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

я никогда не программировал 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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this