如何为我的 64 位 linux 内核找到 task_size?
How can I find the task_size for my 64-bit linux kernel?
我想知道有多少space留给内核,多少留给用户进程
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
hole caused by [48:63] sign extension
ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB)
... unused hole ...
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
... unused hole ...
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
直接映射覆盖系统中的所有内存,最高可达
内存地址(这意味着在某些情况下它还可以包括 PCI 内存
洞)。
vmalloc space懒同步到不同的PML4页面
使用页面错误处理程序的进程,其中 init_level4_pgt 作为
参考。
当前的 X86-64 实现仅支持 40 位地址 space,
但我们最多支持 46 位。这在页表中扩展为 MBZ space。
所以,简而言之,用户 space 获得 247 字节 = 128TiB,内核获得 512MiB。地址的其余部分 space 与一些无法使用的漏洞一起进入系统的各个部分。
您还可以在此处阅读有关 64 位系统的信息。
x86_64 Canonical address space
TASK_SIZE定义在https://elixir.bootlin.com/linux/v4.16.7/source/arch/arm/include/asm/memory.h#L40中,可以通过以下代码访问。请将其编译为内核模块。
TASK_SIZE.c
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Open Source");
MODULE_DESCRIPTION("Module for TASK_SIZE");
static int __init find_task_size_init(void);
static void __exit find_task_size_exit(void);
static int
__init find_task_size_init(void)
{
printk(KERN_INFO "Memory TASK_SIZE: 0x%lx\n", TASK_SIZE);
return 0;
}
static void
__exit find_task_size_exit(void)
{
printk(KERN_INFO "module exits ok !\n");
}
module_init(find_task_size_init);
module_exit(find_task_size_exit);
生成文件
ifneq ($(KERNELRELEASE),)
# call from kernel build system
lifo-objs := main.o
obj-m := TASK_SIZE.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
echo $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
endif
clean:
rm -rf *.o *~ core .depend *.mod.o .*.cmd *.ko *.mod.c .tmp_versions *.markers *.symvers modules.order
depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
# dmesg -k -w # In the first console shell
[ 2570.156990] Memory TASK_SIZE: 0x7ffffffff000
[ 2573.164671] module exits ok !
# make # In the second console shell
# insmod TASK_SIZE.ko
# rmmod TASK_SIZE
我想知道有多少space留给内核,多少留给用户进程
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
hole caused by [48:63] sign extension
ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB)
... unused hole ...
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
... unused hole ...
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
直接映射覆盖系统中的所有内存,最高可达 内存地址(这意味着在某些情况下它还可以包括 PCI 内存 洞)。
vmalloc space懒同步到不同的PML4页面 使用页面错误处理程序的进程,其中 init_level4_pgt 作为 参考。
当前的 X86-64 实现仅支持 40 位地址 space, 但我们最多支持 46 位。这在页表中扩展为 MBZ space。
所以,简而言之,用户 space 获得 247 字节 = 128TiB,内核获得 512MiB。地址的其余部分 space 与一些无法使用的漏洞一起进入系统的各个部分。
您还可以在此处阅读有关 64 位系统的信息。 x86_64 Canonical address space
TASK_SIZE定义在https://elixir.bootlin.com/linux/v4.16.7/source/arch/arm/include/asm/memory.h#L40中,可以通过以下代码访问。请将其编译为内核模块。
TASK_SIZE.c
#include <linux/module.h>
#include <linux/memory.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Open Source");
MODULE_DESCRIPTION("Module for TASK_SIZE");
static int __init find_task_size_init(void);
static void __exit find_task_size_exit(void);
static int
__init find_task_size_init(void)
{
printk(KERN_INFO "Memory TASK_SIZE: 0x%lx\n", TASK_SIZE);
return 0;
}
static void
__exit find_task_size_exit(void)
{
printk(KERN_INFO "module exits ok !\n");
}
module_init(find_task_size_init);
module_exit(find_task_size_exit);
生成文件
ifneq ($(KERNELRELEASE),)
# call from kernel build system
lifo-objs := main.o
obj-m := TASK_SIZE.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
echo $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/../include modules
endif
clean:
rm -rf *.o *~ core .depend *.mod.o .*.cmd *.ko *.mod.c .tmp_versions *.markers *.symvers modules.order
depend .depend dep:
$(CC) $(CFLAGS) -M *.c > .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
# dmesg -k -w # In the first console shell
[ 2570.156990] Memory TASK_SIZE: 0x7ffffffff000
[ 2573.164671] module exits ok !
# make # In the second console shell
# insmod TASK_SIZE.ko
# rmmod TASK_SIZE