struct resource 内核资源描述符
struct resource是 Linux 内核中用于描述和统一管理各种系统资源如I/O端口、内存区域、IRQ号、DMA通道等的核心数据结构。它的定义位于include/linux/ioport.h文件中其结构体定义如下struct resource { resource_size_t start; /* 资源的起始地址 */ resource_size_t end; /* 资源的结束地址 */ const char *name; /* 资源的名称 */ unsigned long flags; /* 资源的类型和属性标志 */ struct resource *parent, *sibling, *child; /* 指向资源树中的父、兄弟、子节点 */ };字段含义详解字段类型描述startresource_size_t资源的起始地址对于I/O端口、内存等地址空间资源或编号对于IRQ、DMA等。endresource_size_t资源的结束地址。start和end共同定义了资源的地址范围。nameconst char *资源的描述性名称通常会被导出到用户空间例如你在/proc/iomem或/proc/ioports中看到的名称。flagsunsigned long用于标识资源的类型如IORESOURCE_MEM、IORESOURCE_IO和属性如IORESOURCE_BUSY、IORESOURCE_READONLY的位掩码。这是资源管理中最关键的字段之一。parentstruct resource *指向资源树中该节点的父节点。资源组织成一棵树形结构。siblingstruct resource *指向同一父节点下的兄弟资源节点的链表指针。childstruct resource *指向该资源节点的第一个子节点。资源树结构内核将所有的同类型资源如所有I/O内存组织成一棵资源树。其中parent、sibling和child这三个字段正是为了构建这棵树每个资源都有一个父节点parent根节点通常是全局的如iomem_resource。子节点之间通过sibling指针链接成一个链表。每个父节点通过child指针指向它的第一个子节点。这个树形结构有效地管理了资源的层次关系和冲突检测。flags常用标志说明flags字段定义了资源的类型和属性常见的标志位包括标志宏定义含义IORESOURCE_IO0x00000100I/O端口空间。IORESOURCE_MEM0x00000200内存地址空间。IORESOURCE_IRQ0x00000400中断号IRQ。IORESOURCE_DMA0x00000800DMA通道。IORESOURCE_BUSY0x80000000该资源已被驱动程序占用。IORESOURCE_READONLY0x00004000资源为只读。在code_resource、data_resource和bss_resource正是通过struct resource来精确描述内核自身各段在物理内存中的地址范围并通过flags标识类型为IORESOURCE_MEM然后被添加到全局的iomem_resource资源树中最终通过/proc/iomem文件呈现给用户。code_resource.start __pa_symbol(_text);code_resource.end __pa_symbol(_etext)-1;data_resource.start __pa_symbol(_etext);data_resource.end __pa_symbol(_edata)-1;bss_resource.start __pa_symbol(__bss_start);bss_resource.end __pa_symbol(__bss_stop)-1;这段代码的作用是为内核的代码段.text、数据段.data和BSS段.bss分别建立物理地址范围的资源描述符。它通过__pa_symbol宏将内核各段符号的虚拟地址转换为物理地址并填充到对应的struct resource结构体中。这段代码位于arch/x86/kernel/setup.c的setup_arch函数中执行时机非常早是内核初始化自身内存布局的关键一步。代码解析code_resource记录内核代码段的物理地址范围。start __pa_symbol(_text)起始地址是内核代码段的开始。end __pa_symbol(_etext)-1结束地址是代码段结束符号的前一个字节。data_resource记录内核数据段的物理地址范围。start __pa_symbol(_etext)起始地址紧跟在代码段之后。end __pa_symbol(_edata)-1结束地址是数据段结束符号的前一个字节。bss_resource记录内核BSS段未初始化全局变量的物理地址范围。start __pa_symbol(__bss_start)起始地址是BSS段的开始。end __pa_symbol(__bss_stop)-1结束地址是BSS段结束符号的前一个字节。代码中的-1是因为end字段表示的是最后一个有效字节的地址而_etext、_edata等符号通常指向其段结束位置之后的一个字节。内核各段布局与链接脚本这些_text、_etext等符号由内核链接脚本vmlinux.lds.S定义它们共同描绘了内核在内存中的完整布局符号段含义_text.text代码段的起始地址。_etext.text代码段的结束地址之后是只读数据段。_edata.data数据段的结束地址之后是BSS段。__bss_start.bssBSS段的起始地址。__bss_stop.bssBSS段的结束地址。核心作用建立内核资源表这些struct resource对象如code_resource、data_resource、bss_resource是内核资源管理子系统的一部分。通过将它们注册到资源树中内核能够提供信息查询接口用户和系统程序可以通过/proc/iomem文件查看这些段在物理内存中的确切位置和大小。防止资源冲突明确告知内核的内存管理模块这些物理地址范围已被内核自身占用不应被其他设备驱动或内存分配器重复分配。为内存管理和调试提供支撑当内核需要映射物理地址或进行内存转储时这些资源描述符提供了可靠的内核自身定位信息。因此这段看似简单的赋值代码实际上是内核将自己“烙印”到物理内存地图上的一个过程确保了后续所有内存管理操作的基础是清晰和正确的。