博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux系统下:IO端口,内存,PCI总线 的 读写(I/O)操作
阅读量:2029 次
发布时间:2019-04-28

本文共 8822 字,大约阅读时间需要 29 分钟。

Table of Contents


IO端口的in/out操作

/* * io.c * ver.0.1:  Dec 18, 2011  S.Ishihara */#include 
#include
#include
int main(int argc, char *argv[]){ int opt; extern char *optarg; extern int optind, opterr; int width = 1; /* default byte access */ unsigned short ioaddr; unsigned int wdata; while ((opt = getopt(argc, argv, "w:")) != -1) { if (opt == 'w') { width = atoi(optarg); } else { goto error; } } argc -= optind; argv += optind; //iopl - change I/O privilege level //该调用用于修改当前进程的操作端口的权限。 //level: 端口的权限级别。为3时可以读写端口。默认权能级别为0,用户空间不可读写。 //EINVAL:level值大于3 //ENOSYS:未实现该调用 //EPERM:调用进程权能不足。 iopl(3); //在差别 I/O 空间和内存空间的进程的 I/O 空间写入数据。 //outb() I/O 上写入 8 位数据 ( 1 字节 )。 //outw() I/O 上写入 16 位数据 ( 2 字节 ); //outl () I/O 上写入 32 位数据 ( 4 字节)。 if (argc == 1) { /* Read I/O */ ioaddr = strtoul(argv[0], NULL, 16); printf("ioaddr = %d, width = %d\n", ioaddr, width); if (width == 1) { printf("0x%04x: 0x%02x\n", ioaddr, inb(ioaddr)); } else if (width == 2) { printf("0x%04x: 0x%04x\n", ioaddr, inw(ioaddr)); } else if (width == 4) { printf("0x%04x: 0x%08x\n", ioaddr, inl(ioaddr)); } else { goto error; } } else if (argc == 2) { /* Write I/O */ ioaddr = strtoul(argv[0], NULL, 16); wdata = strtoul(argv[1], NULL, 16); if (width == 1) { outb(wdata, ioaddr); } else if(width == 2) { outw(wdata, ioaddr); } else if(width == 4) { outl(wdata, ioaddr); } else { goto error; } } else { goto error; } return 0;error: printf("Usage: io [-w WIDTH] ADDRESS [DATA]\n" "I/O read or write.\n" " -w number of byte width. permit 1(default), 2, 4\n" "\n" "This command executable only root user.\n" "I/O address possible range 16bit.\n" "\n" "Examples:\n" " io 3f8 Read I/O from address 0x3f8.\n" " io 3f8 0x31 Write I/O address 0x3f8 to 0x31.\n" " io -w4 cf8 80000000 Write I/O address 0xcf8 to 0x80000000 double word.\n" "\n"); return 1;}

内存的读写操作

/* * mem.c * ver.0.1:  Dec 26, 2011  S.Ishihara */#include 
#include
#include
#include
#include
#include
#include
#define DEV_PATH "/dev/mem"intmain(int argc, char *argv[]){ int opt; extern char *optarg; extern int optind, opterr; int width = 1; /* default byte access */ unsigned int memaddr, wdata; unsigned int pgoffset, pgaddr; unsigned int pagesize = sysconf(_SC_PAGESIZE); unsigned char *p; int fd; while ((opt = getopt(argc, argv, "w:")) != -1) { if (opt == 'w') { width = atoi(optarg); } else { goto error; } } argc -= optind; argv += optind; fd = open(DEV_PATH, O_RDWR); if (fd <= 0) { fprintf(stderr, "open error: %s\n", DEV_PATH); return 1; } if (argc == 1) { /* Read Mem */ memaddr = strtoul(argv[0], NULL, 16); pgoffset = memaddr & (pagesize -1); pgaddr = memaddr & ~(pagesize -1); p = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, fd, pgaddr); if (p < 0) { fprintf(stderr, "mmap error\n"); return 1; } if (width == 1) { printf("0x%08x: 0x%02x\n", memaddr, *(p + pgoffset)); } else if (width == 2) { printf("0x%08x: 0x%04x\n", memaddr, *((unsigned short *)(p + pgoffset))); } else if (width == 4) { printf("0x%08x: 0x%08x\n", memaddr, *((unsigned int *)(p + pgoffset))); } else { goto error; } } else if (argc == 2) { /* Write Mem */ memaddr = strtoul(argv[0], NULL, 16); pgoffset = memaddr & (pagesize -1); pgaddr = memaddr & ~(pagesize -1); p = mmap(NULL, pagesize, PROT_WRITE, MAP_SHARED, fd, pgaddr); if (p < 0) { fprintf(stderr, "mmap error\n"); return 1; } wdata = strtoul(argv[1], NULL, 16); if (width == 1) { *(p + pgoffset) = (unsigned char)wdata; } else if(width == 2) { *((unsigned short *)(p + pgoffset)) = (unsigned short)wdata; } else if(width == 4) { *((unsigned int *)(p + pgoffset)) = (unsigned int)wdata; } else { goto error; } } else { goto error; } munmap(p, pagesize); close(fd); return 0;error: printf("Usage: Mem [-w WIDTH] ADDRESS [DATA]\n" "Mem read or write.\n" " -w number of byte width. permit 1(default), 2, 4\n" "\n" "This command executable only root user.\n" "Mem address possible range 32bit.\n" "\n" "Examples:\n" " Mem a0000 Read memory from address 0xa0000.\n" " Mem a0000 31 Write memory address 0xa0000 to 0x31.\n" " Mem -w4 20000 5a5a5a5a Write memory address 0x20000 to 0x5a5a5a5a.\n" "\n"); return 1;}

PCI的读写操作

/* * pci.c * ver.0.1:  Dec 18, 2011  S.Ishihara */#include 
#include
#include
#define PCI_INDEX 0xcf8#define PCI_DATA 0xcfcunsigned charpciRead8(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); return inb(PCI_DATA + (reg & 0x03));}unsigned shortpciRead16(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); return inw(PCI_DATA + (reg & 0x02));}unsigned intpciRead32(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); return inl(PCI_DATA);}voidpciWrite8(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg, unsigned char value){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); outb(value, PCI_DATA + (reg & 0x03));}voidpciWrite16(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg, unsigned short value){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); outw(value, PCI_DATA + (reg & 0x02));}voidpciWrite32(unsigned char bus, unsigned char dev, unsigned char fnc, unsigned char reg, unsigned int value){ outl((1 << 31) + (bus << 16) + ((dev & 0x1f) << 11) +\ ((fnc & 0x07) << 8) + (reg & ~(0x03)), PCI_INDEX); outl(value, PCI_DATA);}intmain(int argc, char *argv[]){ int opt; extern char *optarg; extern int optind, opterr; int width = 1; /* default byte access */ unsigned char bus, dev, fnc, reg; unsigned int wdata; while ((opt = getopt(argc, argv, "w:")) != -1) { if (opt == 'w') { width = atoi(optarg); } else { goto error; } } argc -= optind; argv += optind; iopl(3); if (argc == 4) { /* Read Pci */ bus = strtoul(argv[0], NULL, 16); dev = strtoul(argv[1], NULL, 16); fnc = strtoul(argv[2], NULL, 16); reg = strtoul(argv[3], NULL, 16); if (width == 1) { printf("B:0x%02x/ D:0x%02x/ F:0x%02x/ R:0x%02x: 0x%02x\n", bus, dev, fnc, reg, pciRead8(bus, dev, fnc, reg)); } else if (width == 2) { printf("B:0x%02x/ D:0x%02x/ F:0x%02x/ R:0x%02x: 0x%04x\n", bus, dev, fnc, reg, pciRead16(bus, dev, fnc, reg)); } else if (width == 4) { printf("B:0x%02x/ D:0x%02x/ F:0x%02x/ R:0x%02x: 0x%08x\n", bus, dev, fnc, reg, pciRead32(bus, dev, fnc, reg)); } else { goto error; } } else if (argc == 5) { /* Write Pci */ bus = strtoul(argv[0], NULL, 16); dev = strtoul(argv[1], NULL, 16); fnc = strtoul(argv[2], NULL, 16); reg = strtoul(argv[3], NULL, 16); wdata = strtoul(argv[4], NULL, 16); if (width == 1) { pciWrite8(bus, dev, fnc, reg, wdata); } else if(width == 2) { pciWrite16(bus, dev, fnc, reg, wdata); } else if(width == 4) { pciWrite32(bus, dev, fnc, reg, wdata); } else { goto error; } } else { goto error; } return 0;error: printf("Usage: pci [-w WIDTH] BUS DEVICE FUNCTION REGISTER [DATA]\n" "Pci configuration space read or write.\n" " -w number of byte width. permit 1(default), 2, 4\n" "\n" "This command executable only root user.\n" "\n" "Examples:\n" " pci 00 1f 00 00 Read pci from bus 0x00 dev 0x1f func 0x00 reg 0x00.\n" " pci -w2 00 1f 00 10 500 Write pci bus 0x00 dev 0x1f func 0x00 reg 0x10 to 0x500.\n" "\n"); return 1;}

 

转载地址:http://kypaf.baihongyu.com/

你可能感兴趣的文章
js判断是否获得焦点
查看>>
Java泛型的学习和使用
查看>>
一文深度揭秘Redis的磁盘持久化机制
查看>>
java是编译型还是解释型语言
查看>>
Spring的BeanUtils的copyProperties方法需要注意的点
查看>>
NotePad 常用快捷键总结
查看>>
Notepad++如何让打开的文件排在左边菜单栏
查看>>
File类的常用方法【二】
查看>>
为什么说栈的速度快,堆的速度慢?栈和堆的区别是什么?
查看>>
微信支付兴起,万亿级用户交易记录存储的挑战
查看>>
Java nio 实现socket异步通信
查看>>
商品秒杀系统设计思路
查看>>
Java自带的JVM性能监控及调优工具(jps、jinfo、jstat、jmap、javap)使用介绍
查看>>
方法回调/钩子
查看>>
Java中常用缓存Cache机制的实现
查看>>
数据库设计规范化的 5 个要求
查看>>
手动启动 oracle 服务
查看>>
二 垃圾回收:第06讲:深入剖析:垃圾回收你真的了解吗?(下)
查看>>
ObjectMapper 的一些坑
查看>>
spring 几种获得bean的方法
查看>>