2014-09-29 17 views
5

QEMU kullanarak sparc sanal makinede RTEMS (gerçek zamanlı işletim sistemi) uygulaması çalıştırmayı deniyordum. Neredeyse oradayım ve saatlerce çalıştığını gördüm. Ancak bazı baskıları çıkardıktan sonra çalışmaz ve daha sonra kaldırılan baskılar nedeniyle olmadığını fark ettim. Veriler, RTEMS görüntüsü ve QEMU emülasyonu modeli arasında doğru bir şekilde geçmiyor. (QEMU sürüm 1.5.50 ve Q9U sürümü 2.0.0'dan alınmış lan9118.c modeli ile çalışıyorum. Ben biraz lan9118 modifed.)
QEMU modelinde, bellek bölgesinde opQemu uygulamasından geçirilen CPU yazma değeri garip

struct MemoryRegionOps { 
    /* Read from the memory region. @addr is relative to @mr; @size is 
    * in bytes. */ 
    uint64_t (*read)(void *opaque, 
        hwaddr addr, 
        unsigned size); 
    /* Write to the memory region. @addr is relative to @mr; @size is 
    * in bytes. */ 
    void (*write)(void *opaque, 
        hwaddr addr, 
        uint64_t data, 
        unsigned size); 
... 
} 

gibi Rtems uygulamasında tanımlandığı gibidir, i TX_FIFO_PORT aşağıdaki gibi tanımlanır

 *TX_FIFO_PORT = cmdA; 
     *TX_FIFO_PORT = cmdB; 

gibi cihaza mal.

#define TX_FIFO_PORT     (volatile ulong *)(SMSC9118_BASE + 0x20) 

yazmaya zaman, örneğin, beklenen

cmdA : 0x2a300200 and cmdB : 0x2a002a00, 

değerler

cmdA : 0x0002302a and cmdB : 0x002a002a. (Just endian converted values) 

Ancak yazma fonksiyonu görmek değerleri (QEMU giriş)

olan
cmdA : 0x02000200 and cmdB : 0x2a002a00 respectively. 

Gözlenen değerler h ave endian dönüştürülmemiş ve hatta ilk değer farklıdır (16 bit daha düşük). Sorun ne olabilir?
Herhangi bir ipucu derinden takdir edilecektir.

+0

İlişkili olmayan işlevsellik eklediğinizde/kaldırdığınızda veriler aniden bozulursa, büyük olasılıkla bir yığın taşması vardır. – Lundin

+0

QEMU'da, her aygıt modeli yazma ve okuma işlevini sağlar, ayrıca aygıtın endianlıkla ilgili olarak aygıttan nasıl aktarılacağını belirtir. Aşağıdaki gibi belirtilmiştir.statik const MemoryRegionOps lan9118_mem_ops = { .read = lan9118_readl, .write = lan9118_writel, .endianness = DEVICE_NATIVE_ENDIAN, }; ' –

cevap

0

Garip bir şekilde, cihaza yazmadan önce RTEMS'de cmdA ve cmdB için endian dönüşümünü yorumlayarak düzelttim. (Bu, endian dönüşümüyle tamamlandı ... Bilmiyorum) Yani neredeyse 'çalışıyor'. Neyse, burada QEMU işlemcisinde CPU yazma/okuma verisi alışverişi ve deivce hakkında bir ipucu.
QEMU'da, her aygıt modeli yazma ve okuma işlevini sağlar, ayrıca aygıtın endianlıkla ilgili olarak aygıttan nasıl aktarılacağını belirtir. Aşağıdaki gibi belirtilmiştir. İşte

static const MemoryRegionOps lan9118_mem_ops = { 
    .read = lan9118_readl, 
    .write = lan9118_writel, 
    .endianness = DEVICE_NATIVE_ENDIAN, 
}; 

Ben [email protected] posta listesinden Peter Meydell alınan e-posta kopyasıdır.

------------------------

Bu bellek bölgesi için MemoryRegionOps yapı olan .endianness alanı oluşturuyor bağlıdır

. DEVICE_NATIVE_ENDIAN, cihazın konuk işlemcinin yerel endianitesine [*] benzer şekilde değerleri görmesi anlamına gelir; bu nedenle, eğer misafir 32 bit'lik bir 0x12345678 yazma yaparsa, o zaman yazma işlevinin argümanında 0x12345678 olarak görünür. DEVICE_BIG_ENDIAN, CPU az endian ise, kelimenin bytesine geçirileceği anlamına gelir. DEVICE_LITTLE_ENDIAN, CPU'nun büyük bir endian olması durumunda, kelimenin bytesine geçirileceği anlamına gelir. İkincisi, CPU'nunki ile aynı olmayan belirli bir endensiteye sahip olan cihazlar veya otobüsler için yararlıdır (örn. PCI her zaman çok enderdir).