Binary_ds类分析

Binary_ds类定义简化表

namespace Boot {

 

class Binary_ds

{

public:

  Binary_ds(char const *name)

  : _ds(L4Re::chkcap(L4Re::Util::Env_ns().query<L4Re::Dataspace>(name),

                     "Kernel binary not found", -l4_EIO));

  bool is_elf_binary();

  bool is_elf64();

  l4_addr_t load_as_elf(Vmm::Ram_ds *ram);

  l4_addr_t load_as_raw(Vmm::Ram_ds *ram, l4_addr_t ram_offset);

  void const *get_header() const;

  l4virtio::Ptr<void> get_upper_bound();

  ~Binary_ds();

 

private:

  Ldr::Elf_ehdr const *as_elf_header() const;

  L4Re::Util::Auto_cap<L4Re::Dataspace>::Cap _ds;

  L4Re::Rm::Auto_region<char *> _header;

  l4virtio::Ptr<void> _end;

  struct Region;

  Region _loaded_range_vmm;

};

 

} // namespace

 

 

构造函数——Binary_ds

Binary_ds(char const *name)    //name为内核镜像名字

  : _ds(L4Re::chkcap(L4Re::Util::Env_ns().query<L4Re::Dataspace>(name),

                     "Kernel binary not found", -l4_EIO))  //通过内核镜像名获取相应能力权限,并赋值给类的私有变量“_ds”

  {

/*初始化vmm的start和end为0*/

    _loaded_range_vmm.start = 0;

    _loaded_range_vmm.end = 0;

    // Map the first page which should contain all headers necessary

    // to interpret the binary.

    auto *e = L4Re::Env::env();  //在pkg\L4Re-core\L4Re\include\env中定义,原型:static Env const *env(),获取当前task的运行时环境信息

    L4Re::chksys(e->rm()->attach(&_header, l4_PAGESIZE, L4Re::Rm::Search_addr,

                                 l4::Ipc::make_cap_rw(_ds.get())));  //attach函数在pkg\L4Re-core\L4Re\include\rm中定义,Attach a data space to a region,映射包含镜像头信息的第一页,映射好的虚拟地址存在“_header”变量中。

  }

 

Elf的load函数

  l4_addr_t load_as_elf(Vmm::Ram_ds *ram)

  {

    auto const *eh = as_elf_header();

 

    l4_addr_t img_start = (l4_addr_t)(-1L);

    l4_addr_t img_end = 0;

    

    //迭代器,逐个条目(程序段信息)传递给lambda函数处理

    eh->iterate_phdr([this,ram,&img_start,&img_end](Ldr::Elf_phdr ph) {

      if (ph.type() == PT_LOAD)

        {

          l4_addr_t dest = ram->boot2ram(ph.paddr());  //记录程序段需要加载的物理地址

          if (dest > ram->size() || dest + ph.memsz() > ram->size())

            L4Re::chksys(-l4_ERANGE, "Binary outside VM RAM region");

 

          l4_addr_t gupper = ph.paddr() + ph.memsz();

          if (gupper > img_end)

            img_end = gupper;

 

          if (ph.paddr() < img_start)

            img_start = ph.paddr();

 

          Dbg(Dbg::Mmio, Dbg::Info, "bin")

            .printf("Copy in ELF binary section @0x%lx from 0x%lx/0x%lx\n",

                    dest, ph.offset(), ph.filesz());

          // 在这之前主要是更新img的start和end地址;下面这句是拷贝程序段到内存

          L4Re::chksys(ram->ram()->copy_in(dest, _ds.get(),

                                           ph.offset(), ph.filesz()));

        }

    });

   

    //设置_loaded_range_vmm的起始和结束地址

    _loaded_range_vmm.start = (l4_addr_t)ram->access(ram->boot2guest_phys<void>(img_start));

    _end = ram->boot2guest_phys<void>(img_end);

    _loaded_range_vmm.end =   (l4_addr_t)ram->access(_end);

    return eh->entry();  //返回elf的入口地址

  }

 

不带elf头image的load函数

  l4_addr_t load_as_raw(Vmm::Ram_ds *ram, l4_addr_t ram_offset)

  {

    l4virtio::Ptr<void> start(ram->vm_start() + ram_offset);

    _end = ram->load_file(_ds.get(), start, nullptr);  //直接拷贝全部数据

    _loaded_range_vmm.start = (l4_addr_t)ram->access(start);

    _loaded_range_vmm.end =   (l4_addr_t)ram->access(_end);

    return start.get();

  }

 

析构函数

~Binary_ds()

  {

    if (_loaded_range_vmm.start !=0 && _loaded_range_vmm.end != 0)

      l4_cache_coherent(_loaded_range_vmm.start,

                        _loaded_range_vmm.end);  //通过系统调用对内存进行释放

  }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值