加载linux内核的基址

加载linux内核的基址,linux,linux-kernel,kernel-module,elf,virtual-memory,Linux,Linux Kernel,Kernel Module,Elf,Virtual Memory,我对内核如何加载到内存有一些疑问。检查/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_DataAbo

我对内核如何加载到内存有一些疑问。检查
/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
  • 有没有办法找到加载内核的基址
  • 在用户空间中,假设我使用一个libc,比如说
    put
    函数的偏移量为0x200。当加载到内存中的地址
    0x8048000
    时,我将能够在
    0x8048000+0x200
    处找到已解析的
    put
    。内核也是这样吗?i、 e.内核映像是否作为一个连续的
    .text
    节加载到内存中

  • 内核加载在物理地址1MiB上,该地址映射在
    页偏移量+0x00100000
    (虚拟地址)上。通常,从
    PAGE\u OFFSET+0x00100000开始,为内核映像保留
    8MiB
    的虚拟空间。对于这个ARM内核,加载地址是0x80008000。此外,内核以连续方式加载。

    对于MIPS体系结构

    文件平台包含分配有物理地址空间中位置的字段/变量“load-…”

    例如:

    openwrt/build\u dir/target-mips\u mips32\u musl-1.1.16/linux-brcm63xx\u 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
    
    对于微玻璃体系结构

    file 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)
    

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

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

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

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

    nm vmlinux | grep do_IPI
    

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

    如果您使用u-boot,那么引导时引导加载程序通常会打印内核加载地址和入口点

    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 ...
    

    你了解物理地址和虚拟地址之间的区别吗?@IgnacioVazquez Abrams物理地址例如:80008240(实际RAM地址)。虚拟地址例如:0x08048000,需要转换。我错过什么了吗?是的。内核在启动时加载到一个物理位置,并在运行时映射到系统上每个进程的另一个虚拟位置。相关:@IgnacioVazquez Abrams这不完全正确-内核在启动时随机分配内核的基本物理地址(在解压缩的位置)。这意味着我们有2GB的ARM用户地址空间。对吗?
    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 ...