2团
Published on 2024-08-15 / 12 Visits
0
0

rCore学习—链接文件内容解析

1.前言

在 ELF(Executable and Linkable Format)文件中,常见的段(Sections)包括:

  1. .text:包含可执行代码(指令)。

  2. .rodata:包含只读数据,如字符串字面量和常量。

  3. .data:包含已初始化的全局和静态变量。

  4. .bss:包含未初始化的全局和静态变量。这个段在文件中不占空间,但在内存中分配。

  5. .symtab:包含符号表,其中包括函数和变量的信息。

  6. .strtab:包含字符串表,存储符号的名称。

  7. .rel.text:包含 .text 段的重定位信息。

  8. .rel.data:包含 .data 段的重定位信息。

  9. .debug:包含调试信息。

  10. .comment:包含版本控制信息。

  11. .plt:过程链接表(Procedure Linkage Table),用于动态链接。

  12. .got:全局偏移表(Global Offset Table),用于动态链接。

  13. .init:包含初始化代码段。

  14. .fini:包含终结代码段。

这些段帮助组织 ELF 文件中的不同类型的数据和代码,使链接器和加载器更容易处理文件。

2.链接原始文件

OUTPUT_ARCH(riscv)
ENTRY(_start)
BASE_ADDRESS = 0x80200000;

SECTIONS
{
    . = BASE_ADDRESS;
    skernel = .;

    stext = .;
    .text : {
        *(.text.entry)
        *(.text .text.*)
    }

    . = ALIGN(4K);
    etext = .;
    srodata = .;
    .rodata : {
        *(.rodata .rodata.*)
        *(.srodata .srodata.*)
    }

    . = ALIGN(4K);
    erodata = .;
    sdata = .;
    .data : {
        *(.data .data.*)
        *(.sdata .sdata.*)
    }

    . = ALIGN(4K);
    edata = .;
    .bss : {
        *(.bss.stack)
        sbss = .;
        *(.bss .bss.*)
        *(.sbss .sbss.*)
    }

    . = ALIGN(4K);
    ebss = .;
    ekernel = .;

    /DISCARD/ : {
        *(.eh_frame)
    }
}

3.链接文件内容解析

ld 文件是 GNU 链接器(GNU linker)的脚本文件,用于定义如何将目标文件链接成最终的可执行文件。它指定了输出文件的结构、各个段的地址和排列方式等。以下是 ld 文件的一些关键部分和它们的作用:

  1. OUTPUT_ARCH:指定输出文件的架构类型。

  2. ENTRY:指定程序的入口点。

  3. BASE_ADDRESS:定义一个基地址,用于设置段的起始地址。

  4. SECTIONS:定义各个段的布局和内容。

以下是章节2中的脚本文件内容解析:

OUTPUT_ARCH(riscv)          // 指定输出文件的架构为 RISC-V
ENTRY(_start)               // 指定程序的入口点为 _start
BASE_ADDRESS = 0x80200000;  // 定义基地址为 0x80200000

SECTIONS
{
    . = BASE_ADDRESS;       // 设置当前地址为基地址
    skernel = .;            // 定义符号 skernel,表示内核的起始地址

    stext = .;              // 定义符号 stext,表示文本段的起始地址
    .text : {               // 定义 .text 段
        *(.text.entry)      // 包含所有 .text.entry 段
        *(.text .text.*)    // 包含所有 .text 和 .text.* 段
    }

    . = ALIGN(4K);          // 将当前地址对齐到 4K 边界
    etext = .;              // 定义符号 etext,表示文本段的结束地址
    srodata = .;            // 定义符号 srodata,表示只读数据段的起始地址
    .rodata : {             // 定义 .rodata 段
        *(.rodata .rodata.*) // 包含所有 .rodata 和 .rodata.* 段
        *(.srodata .srodata.*) // 包含所有 .srodata 和 .srodata.* 段
    }

    . = ALIGN(4K);          // 将当前地址再次对齐到 4K 边界

这个 linker.ld 文件定义了一个 RISC-V 架构的可执行文件的链接布局。它指定了程序的入口点 _start,并定义了 .text 和 .rodata 段的布局和对齐方式。

4.引用

rCore学习章节:https://learningos.cn/rCore-Tutorial-Guide-2024S/chapter1/4mini-rt-baremetal.html


Comment