Xv6链接器脚本

阅读材料

  • Xv6代码:kernel.ld

链接器脚本:kernel.ld

链接后可执行文件的布局

首先指定输出的可执行文件架构为RISC-V,指定整个内核程序的入口点为_entry(定义在entry.S)

OUTPUT_ARCH( "riscv" )
ENTRY( _entry )

指定地址从0x80000000开始,低于该地址的物理地址空间用于MMIO 

. = 0x80000000;

代码段

代码段是存放内核源码编译后生成的机器指令,这里又细分为2部分

  1. .text段:内核文件中所有.c.S文件编译后生成的的二进制文件
  2. trampsec段trampoline.S文件汇编后生成的二进制文件,且特别要求该段大小一定要在一页之内(4096bytes)

最后导出etext符号,用于标记内核代码段的结束,后续内核虚拟内存初始化(vm.c)时会用到这个符号

  .text : {
    *(.text .text.*)
    . = ALIGN(0x1000);
    _trampoline = .;
    *(trampsec)
    . = ALIGN(0x1000);
    ASSERT(. - _trampoline == 0x1000, "error: trampoline larger than one page");
    PROVIDE(etext = .);
  }

数据段

数据段细分为3个部分:

  1. .rodata:存储只能读不能写的数据
  2. .data:存放已初始化的全局变量和已初始化的局部静态变量
  3. .bss:存放未初始化的全局变量和未初始化的局部静态变量

最后导出end符号,用于标记内核数据段的结束,后续内核物理内存初始化(kalloc.c)时会用到这个符号

  .rodata : {
    . = ALIGN(16);
    *(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
    . = ALIGN(16);
    *(.rodata .rodata.*)
  }

  .data : {
    . = ALIGN(16);
    *(.sdata .sdata.*) /* do not need to distinguish this from .data */
    . = ALIGN(16);
    *(.data .data.*)
  }

  .bss : {
    . = ALIGN(16);
    *(.sbss .sbss.*) /* do not need to distinguish this from .bss */
    . = ALIGN(16);
    *(.bss .bss.*)
  }

  PROVIDE(end = .);

参考文献

【裸机开发】链接脚本(.lds文件)的基本语法-CSDN博客

The xv6 Kernel-12 Linking the Kernel_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值