
PFN_ALIGN是 Linux 内核中用于将地址向上对齐到页边界的宏。它与PFN_DOWN、PFN_UP同属include/linux/pfn.h中的页帧号工具集但作用略有不同它直接操作地址返回对齐后的地址而不是页帧号。定义与原理#define PFN_ALIGN(x) (((x) (PAGE_SIZE - 1)) PAGE_MASK)或者等价地#define PFN_ALIGN(x) ((x PAGE_SIZE - 1) ~(PAGE_SIZE - 1))在 x86 架构下PAGE_SIZE为 4096PAGE_MASK为~4095因此PFN_ALIGN(x) (x 4095) ~4095核心作用将任意地址向上取整到最近的页边界。如果地址已经落在页边界上则返回该地址本身。表达式结果说明PFN_ALIGN(0)0已经是页边界PFN_ALIGN(1)4096向上对齐到下一页PFN_ALIGN(4095)4096仍在第 0 页内对齐到第 1 页起始PFN_ALIGN(4096)4096已经是页边界不变PFN_ALIGN(4097)8192向上对齐到下一页与其他宏的对比宏作用示例PFN_ALIGN(x)地址向上对齐到页边界返回地址PFN_ALIGN(4095) 4096PFN_DOWN(x)地址向下取整为页帧号返回PFNPFN_DOWN(4095) 0PFN_UP(x)地址向上取整为页帧号返回PFNPFN_UP(4095) 1PFN_PHYS(x)页帧号转换为物理地址PFN_PHYS(1) 4096它们之间的关系可以用一个公式概括PFN_ALIGN(x) PFN_PHYS(PFN_UP(x))也就是说PFN_ALIGN等价于先向上取整得到页帧号再将该页帧号转换回物理地址。内核中的典型用途内存分配确保分配的内存起始地址按页对齐满足硬件或 DMA 的要求。void *buf kmalloc(size PAGE_SIZE); void *aligned (void *)PFN_ALIGN((unsigned long)buf);计算映射范围确定一段内存区域需要映射的页边界。start_page PFN_DOWN(start); end_page PFN_DOWN(PFN_ALIGN(end) - 1);DMA 缓冲区对齐设备 DMA 操作通常要求缓冲区按页对齐PFN_ALIGN用于确保满足这一要求。使用注意PFN_ALIGN是向上取整可能返回比输入地址更大的值。该宏假设输入是地址物理或虚拟地址均可取决于上下文返回的是对齐后的地址。如果需要向下对齐到页边界可以使用PFN_DOWN(x) PAGE_SHIFT或直接x PAGE_MASK。与round_up(x, PAGE_SIZE)功能相似但PFN_ALIGN更明确地表达了页对齐的语义。