操作系统笔记(二)Bootload加载ELF文件

操作系统笔记(二)Bootload加载ELF文件

ctime:2020-04-29 15:34:46 +0900|1588142086

标签(空格分隔): 技术 操作系统


练习4 分析bootloader如何加载ELF文件

  • 上一步,进入保护模式之后,跳转到此处,开始引导启动系统
  • 首先从硬盘中,读入一定数量的数据(ELF文件,也就是系统镜像)(512字节*8,相当于读入8个扇区的内容),放在ELFHDR处
    • readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);
    • 读完需要校验以下读入的是不是ELF文件,通过检查e_magic字段

ELFHDR的地址是 0x10000,仅仅是一个暂存地址。

ELF文件的文件头格式:

struct elfhdr {
  uint magic;  // must equal ELF_MAGIC
  uchar elf[12];
  ushort type;
  ushort machine;
  uint version;
  uint entry;  // 程序入口的虚拟地址
  uint phoff;  // program header 表的位置偏移
  uint shoff;
  uint flags;
  ushort ehsize;
  ushort phentsize;
  ushort phnum; //program header表中的入口数目
  ushort shentsize;
  ushort shnum;
  ushort shstrndx;
};

一个ELF文件中分为好几个段,程序段、数据段等,每个数据段的定义:

struct proghdr {
  uint type;   // 段类型
  uint offset;  // 段相对文件头的偏移值
  uint va;     // 段的第一个字节将被放到内存中的虚拟地址
  uint pa;
  uint filesz;
  uint memsz;  // 段在内存映像中占用的字节数
  uint flags;
  uint align;
};

通过ELF文件头中的phoff,可以找到第一个段描述的地址,而phnum提供了段的数量,因此通过遍历就可以获得所有的段的信息。

接下来把每个段给读出来,每个段要放在什么位置由每个段的va字段来决定。

    ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff);
    eph = ph + ELFHDR->e_phnum;
    for (; ph < eph; ph ++) {
        readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset);
    }

数据复制完成后,跳转到程序的入口点执行。

    ((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();

程序的入口点e_entry由链接文件中设定。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值