2013-03-27 30 views
5

Montajda yazılmış çıplak metal bir ARM için bir açılış kodum var ve nasıl çalıştığını anlamaya çalışıyorum. İkili, harici Flash'ta yazılmıştır ve açılışta RAM'in kendi parçalarını kopyalamaktadır. Bu bağlamda, bu wikipedia entry numaralı kitabı okurken bile tam olarak yer değiştirme kavramını tam olarak anlamadım. RAM, düşük bir adres penceresine ve yüksek adres penceresindeki flaşa eşlenir. Birisi bana bağlantı kaydının değerini neden test ettiğimizi açıklayabilir mi?Montajda yer değiştirme

/* Test if we are running from an address, we are not linked at */ 
     bl check_position 
check_position: 
     mov  r0, lr     
     ldr  r1, =check_position 
     cmp  r0, r1     /* ; don't relocate during debug */ 
     beq  relocated_entry 
+0

Mükemmel iki cevap için teşekkür ederiz! Her ikisini de kabul edersem, çünkü kodun amacını (JTAG program yükleyici varsayımı doğru) ve ikincisi tam olarak nasıl çalıştığını açıklar. –

cevap

5

Benim tahminim uygulama ram çalışır ve uygulamayı ayıklarken bu yazar belki (kopyalayıp çalıştırmak için, ram doğrudan testi uygulaması yüklemeye böylece hiçbir neden bootloader ve ya JTAG çeşit kullanıyor ise bir kazaya neden olabilir).

Böyle bir şey yapmanın bir başka nedeni, sonsuz bir döngüden kaçınmaktır. Örneğin flaştan önyükleme yapmak istiyorsanız (genellikle) ancak ramdan yürütmek istiyorsanız, bunu yapmanın en kolay yolu, tüm flaşı veya tamamını bir parça flaşı kopyalamak ve sadece ram başlangıcına dalmaktır. Bunu yaptığınızda, "tekrar" ram ve dallara kopyala "döngüsüne bastığınız anlamına gelir. Bu, ikinci kez (sizi çökertebilir) önlemek için, bu tür bir döngüyü flash veya sınamadan çalıştırıyorum.

3

Bana bağlantı kaydının değerini neden test ettiğimizi anlatabilir misiniz?

bl check_position

bağlantı sicilinde PC+4 değerini yerleştirin ve check_position da PC akrabasına kontrolünü aktaracaktır. Şu ana kadar her şey PC göreceli olarak bl at ARM.

ldr r1,=check_position, literal havuzdan bir değer alır.

ldr r1,[pc, #offset] 
... 
    offset: 
    .long check_position # absolute address from assemble/link. 

Yani R0 PC bağlı sürümünü içerir ve R1 mutlak monte sürümünü içeren, gibi Ref1 gerçek kod görünüyor. Burada karşılaştırıldılar. Ayrıca, farkı hesaplamak için aritmetik kullanabilir ve şubesi sıfır değilse; ya da muhtemelen kodu mutlak hedefe kopyalayın. de çalışan Ref2 kodu ise R0 ve R1 aynıdır, sonra adresini bağladı. Bu, bl için bazı pseudo code.

mov lr,pc    ; pc is actually two instruction ahead. 
add pc,pc,#branch_offset-8 

anahtar BLlr güncellenirken dahil PC dayalı her şeyi yapmasıdır. Bu numarasını kullanmak yerine mov R0,PC kullanabiliriz, ancak PC 8 bayttır. Başka bir alternatif ise, adr R0,check_position'u kullanmaktır, bu da assembler'ın bizim için tüm adres matematiğini yapmasını sağlar.

/* Test if we are running from an address, we are not linked at */ 
check_position: 
    adr r0, check_position 
    ldr r1, =check_position 
    cmp r0, r1     /* ; don't relocate during debug */ 
    beq relocated_entry 

Ref1: gnu-montajcı kılavuzuna
Ref2 içinde Arm op-codes ve .ltorg bakınız: Bu Linux head.S ARM için yaptığını tam olarak ne olduğunu.

Düzenleme: ARM ARM'ı kontrol ettim ve PC, kodun neden böyle olduğunu göstermek için geçerli olan geçerli komut +8. Ben adr sürümü daha doğrudan ve okunabilir olduğunu düşünüyorum, ancak adr sözde op çoğu kez bu yüzden insanlar aşina olmayabilir bu yüzden kullanılmaz.

İlgili konular