VMCOREINFO

它是什么?

VMCOREINFO 是一个特殊的 ELF 注释节。它包含来自内核的各种信息,例如结构大小、页面大小、符号值、字段偏移量等。这些数据被打包到一个 ELF 注释节中,并被诸如 crash 和 makedumpfile 之类的用户空间工具用来分析内核的内存布局。

常用变量

init_uts_ns.name.release

Linux 内核的版本。用于查找构建内核的相应源代码。例如,crash 使用它来查找相应的 vmlinux 以便处理 vmcore。

PAGE_SIZE

页面的大小。它是内存管理设施使用的最小数据单元。它通常为 4096 字节大小,并且页面在 4096 字节上对齐。用于计算页面地址。

init_uts_ns

UTS 命名空间,用于隔离系统中与 uname(2) 系统调用相关的两个特定元素。它以用于存储 uname(2) 系统调用返回的信息的数据结构命名。

用户空间工具可以从中获取内核名称、主机名、内核版本号、内核版本、架构名称和操作系统类型。

(uts_namespace, name)

name 成员的偏移量。Crash 实用程序和 Makedumpfile 从此获取 init_uts_ns.name 的起始地址。

node_online_map

一个数组 node_states[N_ONLINE],表示系统中在线节点的集合,每个节点编号一个位位置。用于跟踪系统中哪些节点在线。

swapper_pg_dir

内核的全局页面目录指针。用于将虚拟地址转换为物理地址。

_stext

定义文本部分的开头。通常,_stext 表示内核起始地址。用于将直接内核映射中的虚拟地址转换为物理地址。

VMALLOC_START

存储 vmalloc 区域的基地址。makedumpfile 获取此值,因为它对于 vmalloc 转换是必要的。

mem_map

通过将物理地址视为 mem_map 数组中的索引,将其转换为 struct pages。将物理地址右移 PAGE_SHIFT 位会将其转换为页帧号,该页帧号是该 mem_map 数组的索引。

用于将地址映射到相应的 struct page。

contig_page_data

Makedumpfile 从此符号获取 pglist_data 结构,该结构用于描述内存布局。

用户空间工具使用它在转储内存时排除空闲页面。

mem_section|(mem_section, NR_SECTION_ROOTS)|(mem_section, section_mem_map)

mem_section 数组的地址、其长度、结构大小和 section_mem_map 偏移量。

它存在于稀疏内存映射模型中,并且它在某种程度上类似于 mem_map 变量,它们都用于转换地址。

MAX_PHYSMEM_BITS

定义最大支持的物理地址空间内存。

page

page 结构的大小。struct page 是一个重要的数据结构,它被广泛用于计算连续内存。

pglist_data

pglist_data 结构的大小。此值用于检查 pglist_data 结构是否有效。它也用于检查内存类型。

zone

zone 结构的大小。此值用于检查是否已找到 zone 结构。它也用于排除空闲页面。

free_area

free_area 结构的大小。它指示 free_area 结构是否有效。在排除空闲页面时很有用。

list_head

list_head 结构的大小。在事后分析会话中迭代列表时使用。

nodemask_t

nodemask_t 类型的大小。用于计算在线节点的数量。

(page, flags|_refcount|mapping|lru|_mapcount|private|compound_order|compound_head)

用户空间工具根据这些变量的偏移量计算它们的值。这些变量在排除不必要的页面时使用。

(pglist_data, node_zones|nr_zones|node_mem_map|node_start_pfn|node_spanned_pages|node_id)

在 NUMA 机器上,每个 NUMA 节点都有一个 pg_data_t 来描述其内存布局。在 UMA 机器上,有一个描述整个内存的单个 pglist_data。

这些值用于检查内存类型并计算内存映射的虚拟地址。

(zone, free_area|vm_stat|spanned_pages)

每个节点被分成许多称为区域的块,这些区域表示内存中的范围。区域由结构体 zone 描述。

用户空间工具根据这些变量的偏移量计算所需的值。

(free_area, free_list)

free_list 成员的偏移量。此值用于计算空闲页面的数量。

每个区域都有一个名为 free_area[NR_PAGE_ORDERS] 的 free_area 结构数组。free_list 表示空闲页面块的链表。

(list_head, next|prev)

list_head 成员的偏移量。list_head 用于定义循环链表。用户空间工具需要这些来遍历列表。

(vmap_area, va_start|list)

vmap_area 成员的偏移量。它们携带特定于 vmalloc 的信息。Makedumpfile 从此获取 vmalloc 区域的起始地址。

(zone.free_area, NR_PAGE_ORDERS)

空闲区域描述符。用户空间工具使用此值来迭代 free_area 范围。NR_PAGE_ORDERS 由区域伙伴分配器使用。

prb

指向 printk 环形缓冲区(结构体 printk_ringbuffer)的指针。这可能指向静态启动环形缓冲区或动态分配的环形缓冲区,具体取决于发生核心转储的时间。用户空间工具使用它来读取活动的内核日志缓冲区。

printk_rb_static

指向静态启动 printk 环形缓冲区的指针。如果 @prb 具有不同的值,则这对于查看可能已在动态分配的环形缓冲区中覆盖的初始启动消息很有用。

clear_seq

上一次清除命令后 printk() 记录的序列号。它表示上一次 SYSLOG_ACTION_CLEAR 之后的第一个记录,例如由 ‘dmesg -c’ 发出的命令。用户空间工具使用它来转储 dmesg 日志的子集。

printk_ringbuffer

printk_ringbuffer 结构的大小。此结构包含访问内核日志缓冲区的各个组件所需的所有信息。

(printk_ringbuffer, desc_ring|text_data_ring|dict_data_ring|fail)

printk 环形缓冲区各个组件的偏移量。用户空间工具使用它来查看内核日志缓冲区,而无需声明结构。

prb_desc_ring

prb_desc_ring 结构的大小。此结构包含有关记录描述符集的信息。

(prb_desc_ring, count_bits|descs|head_id|tail_id)

描述记录描述符集的字段的偏移量。用户空间工具使用它来遍历描述符,而无需声明结构。

prb_desc

prb_desc 结构的大小。此结构包含有关单个记录描述符的信息。

(prb_desc, info|state_var|text_blk_lpos|dict_blk_lpos)

描述记录描述符的字段的偏移量。用户空间工具使用它来读取描述符,而无需声明结构。

prb_data_blk_lpos

prb_data_blk_lpos 结构的大小。此结构包含有关文本或字典数据(数据块)在各自数据环内的位置信息。

(prb_data_blk_lpos, begin|next)

描述数据块位置的字段的偏移量。用户空间工具使用它来定位数据块,而无需声明结构。

printk_info

printk_info 结构的大小。此结构包含记录的所有元数据。

(printk_info, seq|ts_nsec|text_len|dict_len|caller_id)

提供记录元数据的字段的偏移量。用户空间工具使用它来读取信息,而无需声明结构。

prb_data_ring

prb_data_ring 结构的大小。此结构包含有关一组数据块的信息。

(prb_data_ring, size_bits|data|head_lpos|tail_lpos)

描述一组数据块的字段的偏移量。用户空间工具使用它来访问数据块,而无需声明结构。

atomic_long_t

atomic_long_t 结构的大小。用户空间工具使用它来复制完整的结构,无论其特定于体系结构的实现如何。

(atomic_long_t, counter)

atomic_long_t 变量的长值的偏移量。用户空间工具使用它来访问长值,而无需特定于体系结构的声明。

(free_area.free_list, MIGRATE_TYPES)

页面的迁移类型数量。 free_list 由数组描述。工具使用它来计算可用页面的数量。

NR_FREE_PAGES

在 linux-2.6.21 或更高版本中,可用页面的数量位于 vm_stat[NR_FREE_PAGES] 中。 用于获取可用页面的数量。

PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_slab|PG_hwpoision|PG_head_mask|PG_hugetlb

页面属性。 这些标志用于过滤各种不需要转储的页面。

PAGE_BUDDY_MAPCOUNT_VALUE(~PG_buddy)|PAGE_OFFLINE_MAPCOUNT_VALUE(~PG_offline)

更多页面属性。 这些标志用于过滤各种不需要转储的页面。

x86_64

phys_base

用于将导出的内核符号的虚拟地址转换为其对应的物理地址。

init_top_pgt

用于遍历整个页表并将虚拟地址转换为物理地址。 init_top_pgt 有点类似于 swapper_pg_dir,但它仅在 x86_64 中使用。

pgtable_l5_enabled

用户空间工具需要知道崩溃内核是否处于 5 级分页模式。

node_data

这是一个 struct pglist_data 数组,存储所有 NUMA 节点信息。 Makedumpfile 从中获取 pglist_data 结构。

(node_data, MAX_NUMNODES)

系统中节点的最大数量。

KERNELOFFSET

内核随机化偏移量。 用于计算页面偏移量。 如果禁用 KASLR,则此值为零。

KERNEL_IMAGE_SIZE

目前 Makedumpfile 未使用。 用于通过 Crash 计算模块虚拟地址。

sme_mask

AMD 特定于 SME 支持:它表示安全内存加密掩码。 Makedumpfile 工具需要知道崩溃内核是否已加密。 如果在第一个内核中启用了 SME,则崩溃内核的页表条目(pgd/pud/pmd/pte)包含内存加密掩码。 这用于删除 SME 掩码并获取真实的物理地址。

目前,sme_mask 存储 C 位位置的值。 如果需要,可以将其他与 SME 相关的信息放入该变量中。

例如

[ misc                ][ enc bit  ][ other misc SME info       ]
0000_0000_0000_0000_1000_0000_0000_0000_0000_0000_..._0000
63   59   55   51   47   43   39   35   31   27   ... 3

x86_32

X86_PAE

表示是否启用了物理地址扩展。 它具有更高的页表查找开销,并且每个进程也消耗更多的页表空间。 用于在将虚拟地址转换为物理地址时检查是否在崩溃内核中启用了 PAE。

ARM64

VA_BITS

虚拟地址的最大位数。 用于计算虚拟内存范围。

kimage_voffset

内核虚拟映射和物理映射之间的偏移量。 用于将虚拟地址转换为物理地址。

PHYS_OFFSET

指示内存起始处的物理地址。 类似于 kimage_voffset,用于将虚拟地址转换为物理地址。

KERNELOFFSET

内核随机化偏移量。 用于计算页面偏移量。 如果禁用 KASLR,则此值为零。

KERNELPACMASK

用于从内核虚拟地址提取指针身份验证代码的掩码。

TCR_EL1.T1SZ

指示由 TTBR1_EL1 寻址的内存区域的大小偏移量。 区域大小为 2^(64-T1SZ) 字节。

TTBR1_EL1 是 ARMv8-A 架构指定的表基址寄存器,用于查找较高 VA 范围内的虚拟地址的页表(有关详细信息,请参阅 ARMv8 ARM 文档)。

MODULES_VADDR|MODULES_END|VMALLOC_START|VMALLOC_END|VMEMMAP_START|VMEMMAP_END

用于获取正确的范围

MODULES_VADDR ~ MODULES_END-1:内核模块空间。 VMALLOC_START ~ VMALLOC_END-1:vmalloc() / ioremap() 空间。 VMEMMAP_START ~ VMEMMAP_END-1:vmemmap 区域,用于 struct page 数组。

arm

ARM_LPAE

它指示崩溃内核是否支持大的物理地址扩展。 用于将虚拟地址转换为物理地址。

s390

lowcore_ptr

一个数组,包含指向每个 CPU 的 lowcore 的指针。 用于打印 psw 和所有寄存器信息。

high_memory

用于从 high_memory 符号获取 vmalloc_start 地址。

(lowcore_ptr, NR_CPUS)

CPU 的最大数量。

powerpc

node_data|(node_data, MAX_NUMNODES)

参见上文。

contig_page_data

参见上文。

vmemmap_list

vmemmap_list 维护整个 vmemmap 物理映射。 用于获取 vmemmap 列表计数和填充的 vmemmap 区域信息。 如果 vmemmap 地址转换信息存储在崩溃内核中,则用于转换 vmemmap 内核虚拟地址。

mmu_vmemmap_psize

页面的大小。 用于将虚拟地址转换为物理地址。

mmu_psize_defs

页面大小定义,即 4k、64k 或 16M。

用于进行 vtop 转换。

vmemmap_backing|(vmemmap_backing, list)|(vmemmap_backing, phys)|(vmemmap_backing, virt_addr)

vmemmap 虚拟地址空间管理没有传统的页表来跟踪哪些虚拟 struct page 由物理映射支持。 虚拟到物理的映射以简单的链表格式跟踪。

用户空间工具在计算 vmemmap 区域的数量时需要知道 list、phys 和 virt_addr 的偏移量。

mmu_psize_def|(mmu_psize_def, shift)

struct mmu_psize_def 的大小以及 mmu_psize_def 成员的偏移量。

用于 vtop 转换。

sh

node_data|(node_data, MAX_NUMNODES)

参见上文。

X2TLB

指示崩溃的内核是否启用了 SH 扩展模式。

RISCV64

VA_BITS

虚拟地址的最大位数。 用于计算虚拟内存范围。

PAGE_OFFSET

指示直接映射的 RAM 区域的虚拟内核起始地址。

phys_ram_base

指示物理 RAM 的起始地址。

va_kernel_pa_offset

指示内核虚拟映射和物理映射之间的偏移量。用于将虚拟地址转换为物理地址。