2016-03-21 35 views
2

ARM MCU'mda başlatılmış veriler için ekstra bir ram bölümü (GNU linker betiğimde) oluşturmaya çalışıyorum. Bölümün bilinen bir adrese yerleştirilmesi gerekecek, böylece MPU'da bunun için belirli öznitelikleri ayarlayabileceğim. Tüm linker sihrinde sorun yaşıyorum. aşağıdaki gibiGNU linker betiğinde ek olarak yeniden oluşturulabilir bölüm oluşturun

bellek ayrılır:

/* Memory Spaces Definitions */ 
MEMORY 
{ 
    rom (rx) :   ORIGIN = 0x00420200, LENGTH = 0x001DFE00 
    ram (rwx) :   ORIGIN = 0x20400000, LENGTH = 0x0005e000 
    ram_nocache_section (rwx) : ORIGIN = 0x2045e000, LENGTH = 0x00002000 
    sdram(rwx):   ORIGIN = 0x70000000, LENGTH = 0x00200000 
} 

Ben işlemek için çalışıyorum "ram_nocache_section" var.

/* no cache section */ 
.ram_nocache : 
{ 
    . = ALIGN(8); 
    *(.ram_nocache) 
} > ram_nocache_section 

Bu çalışır, ancak elde edilen ikili dev aşağıdaki gibidir:

Uygun bir bölümü tanımlayabilir. 0,5 GB. Bunun nedeni, ram adresi alanının, flaş adres alanı dışında 0,5 GB olmasıdır. Bununla başa çıkmanın yolu, başlangıç ​​ram verisini 'yeniden yerleştirmektir'. Senaryo çok gibi bu gerçekleştirir:

.text : 
{ 
    ... 
} > rom 

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

Bu sihirli başlatılmış veri (ve şahmerdan fonksiyonları) iki flaş ve RAM'da ayıracaktır. Bu sadece kopyalamak için kolay olurdu, değil mi? Öyle ki:

. = ALIGN(4); 
_etext = .; 

.relocate : AT (_etext) 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram 

. = ALIGN(4); 
_eramdata = .; 

.relocate2 : AT (_eramdata) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

Bu, derlenecek, ancak ortaya çıkan ikili hala devasadır. Bunun nedeni _eramdata sembolünün bir şekilde ram içine yerleştirilmiş olması ve _etext gibi flaşın içinde olmamasıdır.

O halde ... bu document göre ben artık şöyle bir şey yapmak mümkün olmalıdır:

.relocate2 : AT (_etext + SIZEOF(.data) + SIZEOF(.ramfunc)) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

Bu alışkanlık olsa derlemek. Bunun yerine ben şöyle istenilen sonucu oluşturabilirsiniz:

.relocate2 : AT (_etext + 10k) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

Ancak bu oldukça kırılgan ve savurgan bir çözümdür.

Bunu nasıl düzgün yaparım? 'Relocate2' bölümünü normal 'relocate' bölümünün hemen yanına koymak istiyorum. Fazla atık veya önceden tanımlanmış kod limitleri olmadan.

+0

'NOINIT' özniteliği hakkında bilgi edinin. – Olaf

+0

NOINIT'in NOLOAD'a benzediğini tahmin ediyorum. Hangi değişkenlerin başlatılmasını engeller. Bu sorunu (ben kontrol ettim) çözecek ama aynı zamanda programı bozacak. (Başlangıç ​​verileri kullanıyorum.) – Illishar

+0

Ne istediğinizi net değil. Neden standart '.data' bölümünü kullanmıyorsunuz? Ve belirtilen bir yükleme belleğiniz yok. – Olaf

cevap

0

Kendimi çözüm bulmuş olabilir:

.relocate2 : AT (_etext + SIZEOF(.relocate)) 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section 

Ben zaten böyle bir şey denedim ediyorum emindim. Ama bu istediğim gibi görünüyor. Yine de en zarif çözüm değil.

+1

Bu başlangıç ​​bölümlerinin LMA'sını yerleştirmek için ['AT> rom'] 'u (https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html) kullanabilirsiniz. Init hedefine (her iki yolla) LMA kaynağının bir memcpy'sini() yapmak için bazı basit assembler ve bazı LMA etiketlerine ihtiyacınız vardır. Daha sonra linker sizin için bu eki yapacaktır ('_etext' için de aynıdır). Bunu yapmanın alternatif bir yolu, herşeyi '_etext'de koymaktır, ancak MMU/MPU için dolgu sağlar. Bu, yine de fazladan bir dolgu boyutuna sahip ikili ile sonuçlanacaktır. –

+0

AT> rom'i denedim ama linker çakışan bölümler hakkında şikayet etti. Görünüşe göre "AT> rom" ve "bölüm: AT (...)" yapısı birbiriyle çelişiyor. Sadece AT> rom olsa her ikisini de değiştirmeye çalıştım. Bu işe yarıyor. (Kodu aşağıya yazacağım.) – Illishar

+0

.txt dosyasına yazılması da kötü bir fikir değil. (Bir çeşit "bu flaş" bölümü yaratacaktır.) – Illishar

1

Bunun daha iyi inşa gibi:

. = ALIGN(4); 
_etext = .; 

.relocate : 
{ 
    . = ALIGN(4); 
    _srelocate = .; 
    *(.ramfunc .ramfunc.*); 
    *(.data .data.*); 
    . = ALIGN(4); 
    _erelocate = .; 
} > ram AT>rom 

.relocate2 : 
{ 
    . = ALIGN(4); 
    _srelocate2 = .; 
    . = ALIGN(8); 
    *(.ram_nocache) 
    . = ALIGN(4); 
    _erelocate2 = .; 
} > ram_nocache_section AT>rom 

Her iki bölüm> rom AT değiştirildi gerekiyor. (Karıştırma yok.)