ucore--可读ELF格式文件的baby bootloader--proj2-第三部分

    // read the 1st page off disk,读取内核elf文件的头部出来,这个地方只是读取了4KB
    readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0);

我们查看一下制作内核的时候的文件是多大

dd if=bin/kernel of=bin/ucore.img seek=1 conv=notrunc

真实的文件大小差不多在29K左右

sgy@ubuntu:~/workspace/ucore_step_by_myself$ ls bin/kernel -lh
-rwxrwxr-x 1 sgy sgy 29K Apr 17 15:00 bin/kernel

所以真正读取的数据是在下面的这几行代码。

    struct proghdr *ph, *eph;

    // load each program segment (ignores ph flags)
    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);
    }

    // call the entry point from the ELF header
    // note: does not return
    ((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))();

这几行代码什么意思,需要讲一下elf文件的格式。

程序员的自我修养—链接、装载与库.pdf-P94
ELF文件格式详解.pdf

elf文件的最开始是文件头。
在这里插入图片描述
elf文件中很重要的一个概念是段表,section header table
在这里插入图片描述
那么怎么来查看elf文件的头部呢?
readelf -h bin/kernel

sgy@ubuntu:~/workspace/ucore_step_by_myself$ readelf -h bin/kernel
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x100000
  Start of program headers:          52 (bytes into file)
  Start of section headers:          26828 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         16
  Section header string table index: 13
sgy@ubuntu:~/workspace/ucore_step_by_myself$

对照elf文件头结构体的代码实现一起看会清晰一点

/* file header */
struct elfhdr {
    uint32_t e_magic;     // must equal ELF_MAGIC
    uint8_t e_elf[12];
    uint16_t e_type;      // 1=relocatable, 2=executable, 3=shared object, 4=core image
    uint16_t e_machine;   // 3=x86, 4=68K, etc.
    uint32_t e_version;   // file version, always 1
    uint32_t e_entry;     // entry point if executable
    uint32_t e_phoff;     // file position of program header or 0
    uint32_t e_shoff;     // file position of section header or 0
    uint32_t e_flags;     // architecture-specific flags, usually 0
    uint16_t e_ehsize;    // size of this elf header
    uint16_t e_phentsize; // size of an entry in program header
    uint16_t e_phnum;     // number of entries in program header or 0
    uint16_t e_shentsize; // size of an entry in section header
    uint16_t e_shnum;     // number of entries in section header or 0
    uint16_t e_shstrndx;  // section number that contains section name strings
};

其中我感觉比较重要的几个变量
e_entry
程序的入口地址,操作系统在加载完elf可执行程序之后从这个地址开始执行指令。对应下面这个值

Entry point address:               0x100000

e_shoff
就是前面说的很重要的结构,段表。

Start of section headers:          26828 (bytes into file)---0x68cc
发布了17 篇原创文章 · 获赞 3 · 访问量 3545

猜你喜欢

转载自blog.csdn.net/sgy1993/article/details/89356299
今日推荐