如何找到64位Linux内核的task_size?

时间:2015-11-05 14:44:52

标签: linux linux-kernel 64-bit

我想知道为内核保留了多少空间以及为用户进程保留了多少空间。

2 个答案:

答案 0 :(得分:1)

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空间被懒惰地同步到不同的PML4页面中 使用页面错误处理程序的进程,init_level4_pgt为 参考

目前的X86-64实现仅支持40位地址空间, 但我们支持最多46位。这会扩展到页表中的MBZ空间。

因此,简而言之,用户空间获得247字节= 128TiB,内核获得512MiB。地址空间的其余部分会进入系统的各个部分,以及一些无法使用的漏洞。

您也可以在这里阅读64位系统。 x86_64 Canonical address space

答案 1 :(得分:0)

https://elixir.bootlin.com/linux/v4.16.7/source/arch/arm/include/asm/memory.h#L40中定义了

TASK_SIZE ,可以使用以下代码访问它。请将其编译为内核模块。

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