C语言的Linux内核函数virt_to_phys() nbuff_pull()

virt_to_phys()

将虚拟地址转换为物理地址,以便与硬件设备进行更直接的交互。它不能在用户空间中使用,因为用户空间程序无法直接访问物理内存。在设备驱动开发中会比较常见。
虚拟地址:这是应用程序使用的地址。程序访问的内存地址通常都是虚拟地址。
物理地址:这是实际的硬件内存地址。
内核空间 vs 用户空间:操作系统将内存划分为内核空间和用户空间。用户态进程只能访问用户空间的地址,而内核态进程(或操作系统内核)可以访问整个地址空间。

#include <linux/mm.h>  // 可能需要包含这个头文件
phys_addr_t phys_addr = virt_to_phys(void *virt_addr);

其中,phys_addr_t 通常在内核头文件中定义(例如 #include <linux/types.h>)。在大多数情况下,phys_addr_t 被定义为一个无符号整型,用于表示物理内存地址。

typedef unsigned long long phys_addr_t;

在某些32位系统上,它可能是一个32位的无符号整数,而在某些64位系统上,它可能是一个64位的无符号整数。

nbuff_pull

nbuff_pull() 的主要功能是移动缓冲区中的数据指针,使数据区域前移。 改变了缓冲区中的“起始位置”和“长度”,但并不实际删除数据。

示例
假设有一个网络数据包缓冲区 buff,其结构如下:

| Ethernet Header | IP Header | Payload |
|-----------------|------------|---------|
^
|
buff

调用 nbuff_pull(buff, sizeof(Ethernet Header)) 后,缓冲区将变成如下状态:

| Ethernet Header | IP Header | Payload |
----------------|------------|---------|
               ^
               |
             buff

此时,缓冲区 buff 的起始位置前移,使得原本的 IP 头部成为新的缓冲区起始数据,而原以太网头部信息就被“移除”了。

1. 调整数据起始位置:。例如,如果原来缓冲区指向的位置是 0,则调用 nbuff_pull(buff, len) 后,数据指针将指向第 len 个字节处。
2.减少缓冲区的有效长度:数据指针前移后,缓冲区的有效数据长度会减小,对应长度减去 len 字节。

#include <some_network_library.h>

void process_packet(struct nbuff *buff) {
    // 假设 Ethernet Header 长度为14字节
    int eth_header_length = 14;
    
    // 移除 Ethernet Header,调整缓冲区起始位置
    nbuff_pull(buff, eth_header_length);
    
    // 现在可以从 IP 头部开始处理数据了
    process_ip_header(buff);
}

数据完整性:nbuff_pull() 不会实际删除数据,只是调整指针和长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值