返回

Linux从头学06:多图解析代码重定位技术,让程序能够移动到任意内存地址

开发工具

在上一篇文章《Linux从头学05:系统启动过程中的几个神秘地址,你知道是什么意思吗?》中,我们以几个重要的内存地址为线索,介绍了x86系统在上电开机之后,下一个环节应该是引导程序(bootloader)。而启动程序最核心的一个功能,就是将内核镜像文件从磁盘加载到内存,并且跳转到内核代码执行,即操作系统内核的启动

作为操作系统内核来说,它是如何执行程序的呢?又是如何在内存中分配执行空间的呢?

代码重定位概述

程序的代码和数据在内存中被存储为一系列连续的字节。当程序被加载到内存时,操作系统会将这些字节分配到一个连续的内存区域,这个区域被称为程序的虚拟地址空间 。程序的虚拟地址空间是独立于实际物理内存的,它可以被映射到物理内存的任何位置。

当程序被执行时,CPU会将程序的虚拟地址翻译成物理地址。这个过程称为地址转换 。地址转换是由内存管理单元(MMU)完成的。MMU是一个硬件设备,它位于CPU和内存之间。

代码重定位是一种技术,它允许程序在内存中的任何位置运行,而无需重新编译。当程序被加载到内存时,操作系统会将程序的代码和数据移动到内存中的一个新位置。这个过程称为重定位

重定位有两种主要类型:

  • 静态重定位 :在程序被加载到内存之前完成。
  • 动态重定位 :在程序运行时完成。

静态重定位

静态重定位是在程序被加载到内存之前完成的。当程序被编译时,编译器会将程序的代码和数据分配到虚拟地址空间中的特定位置。当程序被加载到内存时,操作系统会将程序的代码和数据移动到内存中的一个新位置。这个新位置由操作系统的内存管理单元(MMU)决定。

静态重定位的主要优点是它可以提高程序的安全性。当程序被加载到内存时,操作系统会检查程序的代码和数据是否位于内存中的正确位置。如果程序的代码或数据位于错误的位置,操作系统就会阻止程序运行。

动态重定位

动态重定位是在程序运行时完成的。当程序运行时,操作系统可能会将程序的代码和数据移动到内存中的一个新位置。这个新位置由操作系统的内存管理单元(MMU)决定。

动态重定位的主要优点是它可以提高程序的灵活性。当程序运行时,操作系统可以将程序的代码和数据移动到内存中的任何位置。这使得程序可以适应不同的内存配置。

Linux中的代码重定位

Linux内核使用动态重定位来加载和执行程序。当Linux内核加载程序时,它会将程序的代码和数据移动到内存中的一个新位置。这个新位置由Linux内核的内存管理单元(MMU)决定。

Linux内核还使用代码重定位来实现地址空间布局随机化(ASLR)。ASLR是一种安全机制,它可以防止攻击者预测程序的代码和数据在内存中的位置。ASLR通过在每次程序被加载到内存时将程序的代码和数据移动到内存中的一个随机位置来实现。

结论

代码重定位是操作系统中的核心技术之一。它允许程序在内存中的任何位置运行,而无需重新编译。代码重定位可以提高程序的安全性、可靠性和可移植性。