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