【问题标题】:Base address at which the linux kernel is loadedlinux内核加载的基地址
【发布时间】:2016-02-08 07:41:12
【问题描述】:

我对内核如何加载到内存有一些疑问。通过检查/proc/kallsyms,我能够找到内核中各种符号的地址。

$ cat /proc/kallsyms | head -n 10
00000000 t __vectors_start
80008240 T asm_do_IRQ
80008240 T _stext
80008240 T __exception_text_start
80008244 T do_undefinstr
80008408 T do_IPI
8000840c T do_DataAbort
800084a8 T do_PrefetchAbort
80008544 t gic_handle_irq
800085a0 T secondary_startup
  1. 有什么方法可以找到内核加载的基地址吗?
  2. 在用户空间中,假设我使用了一个带有puts 函数的libc,偏移量为0x200。当以地址0x8048000 加载到内存中时,我将能够在0x8048000 + 0x200 找到已解析的puts。内核也一样吗?即内核映像是否作为 1 个连续的 .text 部分加载到内存中?

【问题讨论】:

  • 你了解物理地址和虚拟地址的区别吗?
  • @IgnacioVazquez-Abrams 物理地址,例如:80008240(实际 RAM 地址)。虚拟地址,例如:0x08048000,需要翻译。我错过了什么吗?
  • 是的。内核在启动时加载到一个物理位置,并在运行时映射到系统上每个进程的另一个虚拟位置。
  • @IgnacioVazquez-Abrams 这并不完全正确 - 内核在 can 时随机分配内核的基本物理地址(解压缩的位置)。

标签: linux linux-kernel kernel-module elf virtual-memory


【解决方案1】:

如果您使用的是 u-boot,那么在启动时,bootloader 通常会打印内核加载地址和入口点。

Erase Group Size: 512 Bytes
reading uImage
4670784 bytes read in 469 ms (9.5 MiB/s)
reading devicetree.dtb
20597 bytes read in 17 ms (1.2 MiB/s)
Booting Linux kernel with ramdisk and devicetree
## Booting kernel from Legacy Image at 02004000 ...
   Image Name:   Linux-4.9.0-xilinx
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4670720 Bytes = 4.5 MiB
   Load Address: 10000000
   Entry Point:  10000000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 04000000
   Booting using the fdt blob at 0x4000000
   Loading Kernel Image ... OK
   Loading Device Tree to 1cb3d000, end 1cb45074 ... OK

Starting kernel ...

【讨论】:

    【解决方案2】:

    正如其他答案所述,内核基址对于特定架构是固定的。但由于许多安全问题,内核开发社区决定将其随机化。它被称为ASLR(地址空间布局随机化)。

    通过阅读您的问题(或者因为我在 2017 年阅读),您可能正在尝试查找 ASLR(或内核的 KASLR)中使用的偏移量。

    KASLR offset = address of symbol loaded in memory - address of symbol present in binary.
    

    正如您的问题所述,您已经从/proc/kallsyms 知道内存中符号的地址。

    我们可以使用nm 实用程序和 vmlinux 文件找到二进制符号的地址。

    nm vmlinux | grep do_IPI
    

    这将在 vmlinux 文件中打印符号 do_IPI 的地址。减去这两个地址将为您提供 KASLR 偏移量。

    【讨论】:

      【解决方案3】:

      对于MIPS架构

      文件Platform 包含分配有物理地址空间位置的字段/变量“load-...”。

      示例:

      openwrt/build_dir/target-mips_mips32_musl-1.1.16/linux-brcm63xx_smp/linux-4.4.14/arch/mips/bcm63xx/Platform

      #
      # Broadcom BCM63XX boards
      #
      platform-$(CONFIG_BCM63XX)  += bcm63xx/
      cflags-$(CONFIG_BCM63XX)    +=                  \
          -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
      load-$(CONFIG_BCM63XX)      := 0xffffffff80010000
      

      适用于 ARM 架构

      文件 Makefile.boot 包含分配给物理地址空间位置的字段/变量“zreladdr-y”。

      示例:

      openwrt/build_dir/target-mips_mips32_musl-1.1.16/linux-brcm63xx_smp/linux-4.4.14/arch/arm/mach-omap1/Makefile.boot

         zreladdr-y       += 0x10008000
      params_phys-y       := 0x10000100
      initrd_phys-y       := 0x10800000
      

      用于Microblaze架构

      文件 Makefile 包含分配给物理地址空间中位置的字段/变量“UIMAGE_LOADADDR”(从 Xilinx ISE 导出)。

      示例:

      openwrt/build_dir/target-mips_mips32_musl-1.1.16/linux-brcm63xx_smp/linux-4.4.14/arch/microblaze/boot/Makefile

      UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
      

      【讨论】:

        【解决方案4】:

        内核在 1MiB 的物理地址加载,该地址映射到 PAGE_OFFSET + 0x00100000(虚拟地址)。通常8MiB的虚拟空间是为内核映像保留的,从PAGE_OFFSET + 0x00100000开始

        【讨论】:

          【解决方案5】:

          在这个 ARM 内核的情况下,加载地址是 0x80008000。此外,内核是以连续方式加载的。

          【讨论】:

          • 意味着我们有 2GB 的 ARM 用户地址空间。对吗?
          猜你喜欢
          • 2021-08-17
          • 1970-01-01
          • 1970-01-01
          • 2013-03-10
          • 2020-07-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-31
          • 1970-01-01
          相关资源
          最近更新 更多