现在的位置: 首页 > 综合 > 正文

嵌入式实时Hypervisor:XtratuM (11)

2018年04月28日 ⁄ 综合 ⁄ 共 1769字 ⁄ 字号 评论关闭

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;

}

   

}

 

抱歉!评论已关闭.