嵌入式實時Hypervisor:XtratuM (11)

1.1.1              共享內存

共享內存(Share Memory)是類似FIFO的數據傳輸設備[43]。共享內存採用的主要技術是內存映射。在共享內存中,由於所有高層的虛擬內存都基於底層物理內存,因此,物理內存是共享內存系統中最重要部分。在XtratuM系統中,物理內存是由Linux內核管理,因此,系統可以採用Linux內核APIs分配物理內存。爲了提高系統分配物理內存的效率和成功率。共享內存的建立遵循以下準則:

l        物理內存的分配應該先於域的加載。也就是說,高層應用域無需物理內存分配而可以直接應用共享內存;

l        物理內存可以使用非連續物理內存;

l        共享內存的大小應該是PAGE_SIZE或者是該值的整數倍。

爲了避免XtratuM內核太大,共享內存使用的物理內存由共享內存模塊直接管理,並且與XtratuM內核分離。共享內存通過調用內核函數vmalloc()函數分配物理內存。由於共享內存使用的是塊物理內存,動態管理機制被引用。用戶可以通過make menuconfig的相應配置選項設置共享內存大小。在XtratuM系統,共有8個默認共享內存,並且共享內存的默認大小是128K。在系統中,vmalloc()函數被採用進行物理內存分配而沒有選用kmalloc()函數,這是由於vmalloc()函數分配連續的虛擬內存空間,但是並不能保證分配的物理內存連續,而kmalloc()函數不僅可以分配連續的虛擬內存空間,而且物理內存分配亦連續。因此,kmalloc()函數的使用,尤其是分配大塊內存時,其失敗率相對較高,爲此,共享內存中採用vmalloc()函數。類似於FIFO,頁表內存的分配也是通過__get_free_page()函數。

域中的低地址已經被FIFO,堆,事件以及其它資源佔用,因此,共享內存的默認虛擬地址是從0x 3000000開始。並且,由於共享內存是採用vmalloc()函數分配,所得地址爲內核虛擬地址,爲了將該地址轉換成物理地址,系統採用了kvirt_to_phy()函數。

static inline unsigned long kvirt_to_phy(unsigned long vaddr)

{

unsigned long ret = 0UL;

  pgd_t *pgd;

  pud_t *pud;

  pmd_t *pmd;

  pte_t pte;

 

  pgd = pgd_offset_k(vaddr);

 

  if(! pgd_none(*pgd)) {

    pud = pud_offset(pgd, vaddr);

    if(!pud_none(*pud)) {

      pmd = pmd_offset(pud, vaddr);

      if(!pmd_none(*pmd)) {

        pte = *(pte_offset_kernel(pmd, vaddr));

          if(pte_present(pte)) {

ret=(unsigned long) age_address(pte_page(pte));

            ret |= (vaddr & (PAGE_SIZE - 1));

          }

       }

    }

  }

  return ret;   

}

內存通過vmalloc()函數分配,並且相應虛擬地址可以通過kvirt_to_phy()函數轉換爲物理地址,接下來的任務就是將對應的物理內存映射到域空間地址。映射任務是在域加載時完成。

Int load_domain_sys(…)

{

   

    /* share memory map */

    vaddress = DEFAULT_SHM_ADDRESS;

    shm_ctlpage_map(gd, vaddress, alloc_page);

    event->shm_ctladdr = vaddress;

    vaddress += PAGE_SIZE;

    for(i = 0; i < SHM_COUNT; i++) {

           shm_datapage_map(gd, vaddress+i*buffer_size, alloc_page, index);

           event->shm_dataddr[i] = vaddress+i*buffer_size;

}

   

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章