当前位置:   article > 正文

arm架构Linux5.0内核连接脚本文件vmlinux.lds.S分析

arm架构Linux5.0内核连接脚本文件vmlinux.lds.S分析


vmlinux.lds.S 是 Linux 内核中用于链接的脚本文件,用于定义内核对象文件的内存布局,即它告诉链接器如何将不同的内核代码段和数据段组合成一个最终的内核映像 vmlinux。编译内核源码生成内核文件的过程分两步,一个是“编译”,另一个是“链接”的过程,vmlinux.lds.S要做的就是告诉编译器如何链接编译好的各个内核.o文件,从而生成vmlinux文件。

准备工作

我们需要准备好vmlinux.lds.S文件,文件的位置是arch/arm64/kernel/vmlinux.lds.S。我们还可以查看该文件预处理后的连接文件,在编译完linux内核会自动生成文件是arch/arm64/kernel/vmlinux.lds。我们还可以使用下面的命令读取 vmlinux 文件中的各段地址,协助我们分析:

readelf -S vmlinux > vmlinux_elf.txt
  • 1

一、 参数

我们先直接查看预处理好的vmlinux.lds文件,可以看到开头就是下面这几行代码,这些是连接文件的参数,在vmlinux.lds.S中也可以找到一模一样的,只是放在了不同的行中而已:

OUTPUT_ARCH(aarch64)
ENTRY(_text)
jiffies = jiffies_64;
PECOFF_FILE_ALIGNMENT = 0x200;
  • 1
  • 2
  • 3
  • 4
  1. OUTPUT_ARCH(aarch64):这行指定输出文件的目标架构是 aarch64,即 64 位 ARM 架构。这是告诉链接器生成适用于 ARM 64 位处理器的内核映像。

  2. ENTRY(_text):这行指定了内核的入口点是 _text 符号。_text 通常是一个在内核代码中定义的标签,指向内核启动时第一条要执行的指令。这意味着当内核加载到内存并跳转到它的入口点时,它将开始执行 _text 标签指定的代码。

  3. jiffies = jiffies_64;: 在标准的 Linux 内核构建系统中,jiffies 作为变量通常是在 C 代码中定义和使用的。这行代码看起来像是一个赋值操作,但是在文件中没有使用到,个人猜测这是表示使用64位的jiffies。

  4. PECOFF_FILE_ALIGNMENT = 0x200;:这行设置了 PECOFF(Portable Executable for Console File Format)文件的对齐字节。PECOFF 是一种常用于 Windows 系统的文件格式,但在某些交叉编译场景下,Linux 内核可能需要以这种格式生成,以便于在某些环境中加载和执行。0x200 表示每个文件节(section)在磁盘上以 512 字节对齐,这是一个常见的对齐设置,用于优化文件的加载和内存访问性能。

二、 SECTIONS段

2.1 DISCARD节

	/DISCARD/ : {
		ARM_EXIT_DISCARD(EXIT_TEXT)
		ARM_EXIT_DISCARD(EXIT_DATA)
		EXIT_CALL
		*(.discard)
		*(.discard.*)
		*(.interp .dynamic)
		*(.dynsym .dynstr .hash .gnu.hash)
		*(.eh_frame)
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

预处理后变成:

 /DISCARD/ : {
 
 
  *(.exitcall.exit)
  *(.discard)
  *(.discard.*)
  *(.interp .dynamic)
  *(.dynsym .dynstr .hash .gnu.hash)
  *(.eh_frame)
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

结合英文注释和网上的一些言论,个人猜测/DISCARD/ 段是一个特殊的指令,用于指示链接器在生成最终的内核映像时应该忽略或丢弃某些段。这样子gcc可以通过配置来确定是否丢弃这些段,可以减小最终映像的大小或移除调试信息从而优化内核的加载时间和内存占用。如果确定丢弃,这意味着这些段不会出现在最终的程序或内核的内存映像中。

2.2 .head.text节

	. = KIMAGE_VADDR + TEXT_OFFSET;

	.head.text : {
		_text = .;
		HEAD_TEXT
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

预处理后变成:

 . = ((((((((0xffffffffffffffff)) - (((1)) << (48)) + 1) + (0)) + (0x08000000))) + (0x08000000))) + 0x00080000;
 .head.text : {
  _text = .;
  KEEP(*(.head.text))
 }
  • 1
  • 2
  • 3
  • 4
  • 5

**.head.text

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/479361
推荐阅读
相关标签