当前位置:  技术问答>linux和unix

请问驱动程序里怎么得到用户空间地址对应的物理地址?

    来源: 互联网  发布时间:2015-07-20

    本文导语:  read 函数的原型如下: ssize_t read (struct file *filp, char *buf, size_t count, loff_t *f_pos); 其中buf是一个用户空间的指针,请问我怎么得到这指针的物理地址呢?  谢谢! | 试试下面这段代码: unsign...

read 函数的原型如下:
ssize_t read (struct file *filp, char *buf, size_t count, loff_t *f_pos);

其中buf是一个用户空间的指针,请问我怎么得到这指针的物理地址呢? 


谢谢!

|
试试下面这段代码:
unsigned char * GetPhyAddr(struct vm_area_struct *vma, unsigned long vaddr)
{
pgd_t *pgdir; pmd_t *pmdir; pte_t *pte;
   pgdir=pgd_offset(vma->vm_mm, vaddr);
if(pgd_none(*pgdir)||pgd_bad(*pgdir))
   return -EINVAL;
pmdir=pmd_offset(pgdir,vaddr);
if(pmd_none(*pmdir)||pmd_bad(*pmdir))
   return -EINVAL;
pte=pte_offset(pmdir, vaddr);
if(pte_present(*pte))
  {
   addr=(unsigned char)pte_page(*pte);
   return addr;
  }
return -EINVAL
}

|
就是个地址映射的问题吧. 按照linux的内存管理机制,
用pgd_offset(), pmd_offset(), pte_offset()就可以实现这种转换吧.


|
你得到物理地址有用吗?在用户空间无论如何都不能访问物理地址的吧

|
如果你的代码运行在内核态,那可以用virt_to_bus()或__pa()
如果在用户态,我也不知道怎么办了.
驱动程序是在内核态的.所以可以用.

|
在内核模块编程中想要使用封装好的系统调用,需要作相应的处理.因为系统调用是供用户空间使用的,它首先会检查自己的地址是否是用户空间,如果不是则出错.楼主的问题就在这里,怎么让系统调用不检查使用的空间是否为用户空间.我当初也遇到这个问题,你看看下面的文档,是我当初在论坛上与别人讨论后总结的,你看看就很清楚了:

   在内核模块编程中使用系统调用有他的特殊性,如I/O操作,OPEN,READ,WRITE等,它会核对缓冲区是否是0-3GB(用户空间),如果不是,则报错,所以应该显示地更改这种限制,如何更改大家可以参考(来自:http://www.linux.it/kerneldocs/ksys/ksys.html)
     Before calling the function, however, a preparing step must be performed. Like any other function that transfers data to/from user space using a user-provided pointer, the system call checks whether the provided buffer is a valid address or not. During normal operation, an address that lies in the user address range (0-3GB for standard kernel configuration) is considered valid, and an address that lies in kernel address space (3GB-4GB) is not.

If the system call is invoked from kernel space, though, we must prevent the usual check to fail, because the virtual address of our destination buffer will be in kernel space, above the 3GB mark.

The field addr_limit in the task_struct structure is used to define the highest virtual address that is to be considered valid; the macros get_fs and set_fs can be used to read and write the value. The limit that must be used when invoking system calls from kernel space (in practice, the "no limit" case) is returned by the get_ds macro. See the box in this page for an explanation of the names and meanings of the macro calls.

For this reasong, kernel system calls, must be wrapped by the following code:

      mm_segment_t fs;

      fs = get_fs();     /* save previous value */
      set_fs (get_ds()); /* use kernel limit */

      /* system calls can be invoked */

      set_fs(fs); /* restore before returning to user space */

There's no need to wrap each individual system call, and group of them can occur in a row. It's important, however, that the original ``fs'' is restored before returning to user space. Otherwise, the user program that executed this code will retain permission to overwrite kernel memory by passing bogus pointers to further read (or ioctl) system calls. 

   下面是我在LKM编程中使用open系统调用的一段源代码
#define MODULE
#define __KERNEL__
#include 
#define __KERNEL_SYSCALLS__
#ifdef MODVERSIONS
#include 
#endif

#include 
#include 

#include 
#include 
#include 

#include 
#include 
#include 
#include 
#define BEGIN_KMEM { mm_segment_t old_fs = get_fs(); set_fs(get_ds());
#define END_KMEM set_fs(old_fs); }

int errno;
int init_module(void){
int err;
printk("Hello,worldn");
BEGIN_KMEM;
err=open("/usr/include/asm/uaccess.h",O_RDONLY,0);
if(err>0)
printk("open file successfuln");
END_KMEM;
return 0;
}
void cleanup_module(void){
printk("Goodbye cruel wordn");
}
在2.4.20和2.4.26上均能成功使用!
      但是,这是针对I/O系统调用的特殊性提出的解决办法,而对于其他的系统调用,如socketcall等,还需要进一步研究它的实现机制(我目前作的内核模块最核心的问题就是通过LKM实现网络通信),有谁在LKM编程中使用过SOCKET API,并且能成功insmod,能不能说一下如何实现?
     谢谢.

|
xuexi

    
 
 

您可能感兴趣的文章:

  • 知道IP地址,请问如何获取这个IP地址对应网卡的mac地址?
  • 请问怎样编程获得本机的MAC地址?还有能不能设置本机MAC地址?
  • 请问硬件原理图如何分析,获取每个芯片各自的基地址和地址空间。
  • 请问目标文件里左边的一排地址是什么意思?
  • 请问关于保护模式下逻辑地址的一个问题
  • 请问哪里可以下载IP地址段对应城市的信息?高分回报!
  • 请问,在SCOUNIX下,如何更改网卡的MAC地址?
  • 请问大家什么是internet地址族?
  • 请问要得到远程访问站点的ip地址以及所在的页面,用request的什么方法?
  • 请问jdk1.4的文档下载地址?
  • 请问:GTK有没有IP地址输入框,及状态条?
  • 请问哪位知道RedHat Advance Server2.x下载地址
  • 请问在linux下怎样修改ip地址!!急,在线等
  • 请问有没有shell命令可以知道机器的网卡地址?
  • 请问各位,在freebsd里面用什么命令查看自己的ip地址,谢谢!
  • 我没有图形界面,请问如何用ifconfig命令为网卡添加两个IP地址
  • 请问:能够在网页文件中自己定义出现在地址栏中的url吗?
  • 请问哪位知道Cloudscape下载地址?
  • 请问jBUILDER7.0的下载地址?
  • 请问同一块内存,在uboot下访问和在krnl下访问,地址是否一样?
  • 请问如何设置驱动程序和应用程序的启动顺序和优先级呢?
  • 请问shell 开发能开发什么样的程序?硬件的驱动程序是否能够开发呢?
  • 请问哪里有for mssql的jdbc驱动程序下载?
  • 我是新人,请问SQLSERVER的驱动程序是什么呀?
  • 请问谁有oracle8.0.5的jdbc驱动程序!!!!!
  • 我用的是REDHAT7.3,请问LIBODBCMY.SO这个驱动程序在哪里?
  • 请问UNIX系统下装上WINDOWS的打印机驱动程序,可否打印?
  • 请问linux中有没有可以读取BIOS信息的驱动程序!
  • 请问如何把驱动程序做成deb包?
  • 请问哪里有声卡的驱动程序下载?
  • 请问某个数据库(如oracle)的jdbc驱动程序是不是在所有平台下通用?
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请问有谁知:“空格”对应%20, “<“对应%3C,这是几进制或是什么格式的转换?
  • 请问有没有和DU或DF对应的系统调用?
  • 请问这些文件操作,对应的FTP命令是什么呀?
  • 请问unix 对应dos findfirst的函数是opendir吗?
  • 请问win32下的__int64,在linux下什么与之对应?
  • 请问图形界面下的logout对应的代码在哪里可以找到?
  • 请问:定义文件里需不需要用#include 将对应的头文件包含进来啊?
  • 请问Access数据库中的日期型字段是对应java中的哪个Date类?
  • 请问各不同的浏览器版本对应支持Java相应的哪个版本编译出来的程序?
  • 请问cf接口设备一般对应什么设备文件呢?
  • 请问linux中的系统调用号是如何跟系统调用表对应起来的
  • 请问SQL中的datetime类型于java中什么类型对应?
  • 请问:在用proc方式往数据库插入数据时,我能不能定义一个结构体,它与表的每一项对应,将结构体赋好值后,再只将这个结构体插入表中,这行不行啊?
  • 请问linux下ftell函数的对应64位函数?
  • 请问如何知道一个数字对应的是什么信号
  • 请问根据一个坐标点怎么判断对应的JTree的哪一个节点上
  • 请问:我知道路由器的telnet密码,但忘记了enable 密码,请问如何是好?
  • 请问那里有SYBASE的jbdb 2.0下载;jspsmartupload可以直接将文件上传到数据库,请问如何使用
  • 请问最新的reahat9.0是基于什么核心的?2.4?2.6?请问那里能下载?
  • 请问:请问哪里有关于linux基本操作命令讲解的资料下载,最好是幻灯片格式的.
  • 请问,我试图用#admintool&图形工具命令来安装sun workshop5.0,为什么进入的却是用户管理界面?请问具体该如何在solaris下安装应用软件
  • 请问在Redhat 9里,我从登录就是图形介面,请问如何在图形介面内进入命令行方式呢,谢谢
  • 请问玩过SOLARIS的高手门,在不正常关机后,就不能启动到windows公用桌面了,只能在命令提示模式下了,请问怎么解决这个问题啊?急~!~!
  • 请问:我在redhat下装了bochs-2.2.1-1.rpm,.装了后,想设置一下,但找不到bochsrc.fda.bxrc,请问这个文件在哪个曰录下啊。
  • 请问:在配置Qt时,很多文档都说在.profile,.login里加东西,但是我好像没有发现有这两个文件上,请问这些文件在哪个目录下啊
  • 请问:在GCC里的C程序里的变量的声明是不是只能在前面,而且相同类型的变量的声明只能放在一起?如果不是,请问怎么样可以解决这个问题.
  • 请问各位大虾,小弟今天开始学jsp了,这学期我们有java课,所以已经下载了jdk(好象是1.2),请问我的98环境怎么配置jsp环境呀?我的jdk可以运行.java程序,别的我就不知道了....谢谢!
  • 主机是WIN2000,我用的是LUNIX,请问是否可以共享上网? 如果可以请问如何设置? 500分答谢,龟儿食言!
  • 请问linux下GUI开发的问题!
  • 请问出现fstab文件丢失该怎么修复呀?
  • 请问这个方法如何调用?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3