当前位置: 技术问答>linux和unix
Linux内核模块里的读写函数
来源: 互联网 发布时间:2016-07-23
本文导语: 我现在看一个软件GPS接收机的源代码,是用Linux内核模块写的。在其中的读函数里,程序直接用copy_to_user将数据从内核态拷贝到用户态,我想知道其具体是如何操作的呢?数据在内核态是什么意思,拷贝到用户态又是...
我现在看一个软件GPS接收机的源代码,是用Linux内核模块写的。在其中的读函数里,程序直接用copy_to_user将数据从内核态拷贝到用户态,我想知道其具体是如何操作的呢?数据在内核态是什么意思,拷贝到用户态又是什么意思?
另外,我注意到,在中断服务程序里有这样的代码:用inw_p直接从芯片的寄存器内读取数据,供中断服务程序使用。这样,就有两个读取的函数了,请问这二者有何区别,又有没有什么联系呢?我一直对数据如何从硬件(寄存器)上转移到用户上不太清楚,希望有朋友解惑!甚谢!
另外,我注意到,在中断服务程序里有这样的代码:用inw_p直接从芯片的寄存器内读取数据,供中断服务程序使用。这样,就有两个读取的函数了,请问这二者有何区别,又有没有什么联系呢?我一直对数据如何从硬件(寄存器)上转移到用户上不太清楚,希望有朋友解惑!甚谢!
|
ls的说的 x86 cpu的特权级5 ,真是闻所未闻
linux内存模型可以很容易搜索到。32位的cpu可寻址4G地址空间。对于每个进程来说,都可以访问4G的地址空间。其中又分为用户空间和内存空间,配置内核时可以指定分配方式。一般采用3G用户空间,1G内核空间的分配方式。每个进程的3G的用户空间是私有的,1G的内核空间是所有进程共享的。分界地址就是0xc0000000
。用户空间不能访问高于0xc0000000的地址空间,会报段错误。
用户空间使用驱动程序,是通过读写设备文件实现的。用户态的read()最终会调用内核struct file_operations里注册的read函数。这个相信lz也不是完全不知道。用户态write()的第二个参数是缓冲区指针指向的用户态的内存空间,内核驱动里的write传入的第二个参数就是这个用户态的缓冲区地址。内核如果直接对这个用户态地址进行操作,不能保证进程在睡眠时属于它的内存空间不被置换出去,很可能造成读内存错误,所以要靠copy_from_user将其读入内核中的一段内存空间。内核也不能直接操作用户态的内存,所以对应用户程序的read,要使用copy_to_user将内核空间数据传递给用户空间内存。
第二个问题,关于中断中的读取和驱动原有的read,他们是不一样的
中断是由硬件触发的,驱动原有的read是用户自己写程序去读的
即中断读是响应硬件要求驱动去读,原来的read是响应用户编程去读。
一般是设备每准备好一次数据,就触发一次中断,驱动程序读取设备信息存储起来,等到用户程序读取的时候一次返回所有数据。
linux内存模型可以很容易搜索到。32位的cpu可寻址4G地址空间。对于每个进程来说,都可以访问4G的地址空间。其中又分为用户空间和内存空间,配置内核时可以指定分配方式。一般采用3G用户空间,1G内核空间的分配方式。每个进程的3G的用户空间是私有的,1G的内核空间是所有进程共享的。分界地址就是0xc0000000
。用户空间不能访问高于0xc0000000的地址空间,会报段错误。
用户空间使用驱动程序,是通过读写设备文件实现的。用户态的read()最终会调用内核struct file_operations里注册的read函数。这个相信lz也不是完全不知道。用户态write()的第二个参数是缓冲区指针指向的用户态的内存空间,内核驱动里的write传入的第二个参数就是这个用户态的缓冲区地址。内核如果直接对这个用户态地址进行操作,不能保证进程在睡眠时属于它的内存空间不被置换出去,很可能造成读内存错误,所以要靠copy_from_user将其读入内核中的一段内存空间。内核也不能直接操作用户态的内存,所以对应用户程序的read,要使用copy_to_user将内核空间数据传递给用户空间内存。
第二个问题,关于中断中的读取和驱动原有的read,他们是不一样的
中断是由硬件触发的,驱动原有的read是用户自己写程序去读的
即中断读是响应硬件要求驱动去读,原来的read是响应用户编程去读。
一般是设备每准备好一次数据,就触发一次中断,驱动程序读取设备信息存储起来,等到用户程序读取的时候一次返回所有数据。