当前位置: 首页 > news >正文

I211学习笔记

查看PCIE设备的BAR

通过cpu spc查看PCIE配置寄存器存放信息,可以看到在**0x80000000L偏移10h处便是映射的内存地址**:

这个地址有多种方法查看,在RU下可以通过F6直接打开对应设备的寄存器基地址查看,也可以通过编程IO方式查看,主要是要知道base address + bus + dev +fun。再根据addr = Ox80000000 L | (bus<<16) | (dev<<11) | (fun<<8)|offset 计算。

RU下查看

通过打印pci的配置空间查看

在ubuntu下可以通过命令查看pcie设备内存映射的地址

lspci -vv

访问I211的控制寄存器、状态寄存器等


读取某一个PCIe设备(比如网卡)的控制寄存器、状态寄存器。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>

#define I211_BAR0_ADDR 0xf7500000
#define I211_BAR0_SIZE (128 * 1024)  // 128KB

// I211寄存器偏移
#define I211_REG_CTRL     0x0000  // Device Control
#define I211_REG_STATUS   0x0008  // Device Status
#define I211_REG_EERD     0x0014  // EEPROM Read
#define I211_REG_ICR      0x00C0  // Interrupt Cause Read
#define I211_REG_MAC_L    0x5400  // MAC地址低32位
#define I211_REG_MAC_H    0x5404  // MAC地址高16位

// 寄存器访问
uint32_t read_reg32(volatile void *base, uint32_t offset) {
    return *(volatile uint32_t*)((uint8_t*)base + offset);
}

void write_reg32(volatile void *base, uint32_t offset, uint32_t value) {
    *(volatile uint32_t*)((uint8_t*)base + offset) = value;
}

int main() {
    int fd;
    void *base_addr;

    // 打开物理内存
    fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd == -1) {
        printf("Error opening /dev/mem: %s\n", strerror(errno));
        return -1;
    }


    // 映射BAR0地址空间
    base_addr = mmap(NULL, I211_BAR0_SIZE, PROT_READ | PROT_WRITE, 
                     MAP_SHARED, fd, I211_BAR0_ADDR);
    if (base_addr == MAP_FAILED) {
        printf("Error mapping memory: %s\n", strerror(errno));
        close(fd);
        return -1;
    }

    // 读取控制寄存器
    uint32_t ctrl = read_reg32(base_addr, I211_REG_CTRL);
    printf("Control Register (0x%04X): 0x%08X\n", I211_REG_CTRL, ctrl);

    // 读取状态寄存器
    uint32_t status = read_reg32(base_addr, I211_REG_STATUS);
    printf("Status Register (0x%04X): 0x%08X\n", I211_REG_STATUS, status);

    // 读取MAC地址
    uint32_t mac_l = read_reg32(base_addr, I211_REG_MAC_L);
    uint32_t mac_h = read_reg32(base_addr, I211_REG_MAC_H);
    printf("MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
           (uint8_t)(mac_l),
           (uint8_t)(mac_l >> 8),
           (uint8_t)(mac_l >> 16),
           (uint8_t)(mac_l >> 24),
           (uint8_t)(mac_h),
           (uint8_t)(mac_h >> 8));

    // 清理
    munmap(base_addr, I211_BAR0_SIZE);
    close(fd);

    return 0;
}

编译运行

gcc -o GetNetInfo GetNetInfo.c 
./GetNetInfo 

相关文章:

  • vue3:request.js中请求方法,api封装请求,方法请求
  • 28.Vulmap:Web 漏洞扫描与验证工具
  • Unity | 工具类:单例总结
  • Windows安装MySQL5.7.26教程图解
  • LeetCode 解题思路 20(Hot 100)
  • 再学:合约继承 、抽象合约 solidity接口、库、事件 合约重入攻击
  • C语言论递归函数及其本质
  • 【FAQ】HarmonyOS SDK 闭源开放能力 —Map Kit(6)
  • 中兴B860AV3.2-T/B860AV3.1-T2_S905L3-B_2+8G_安卓9.0_先线刷+后卡刷固件-完美修复反复重启瑕疵
  • Linux--内核进程O(1)调度队列
  • 20分钟上手DeepSeek开发:SpringBoot + Vue2快速构建AI对话系统
  • 画册相册图库摄影画廊H5开源版开发
  • 论文阅读:SCI 1区 RADAR: Robust AI-Text Detection via Adversarial Learning
  • TypeScript + Vue:类风格组件如何引领前端新潮流?
  • 植物知识分享论坛毕设
  • Python基础语法全解析:从入门到实践
  • Qt中打开windows的cmd窗口并显示
  • Git 使用SSH登陆
  • 工厂方法模式和抽象工厂模式详解
  • 【从零开始学习计算机科学与技术】计算机网络(六)传输层
  • 东部沿海大省浙江,为何盯上内河航运?
  • 尹锡悦宣布退出国民力量党
  • 就规范涉企行政执法专项行动有关问题,司法部发布解答
  • 总奖金池百万!澎湃与七猫非虚构写作与现实题材征文大赛征稿启动
  • 泽连斯基抵达安卡拉,称乌将派出最高级别代表团参与谈判
  • 端午假期购票日历发布,今日可购买5月29日火车票