LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: sybaselu

UNIX/Linux系统下的设备驱动程序

[复制链接]
 楼主| 发表于 2005-8-22 15:49:01 | 显示全部楼层
1:x86上对于I/O端口采用的是独立编址而不是统一,这样对I/O端口的访问是用inb(),outb()/inw(),outw()/inl(),outl()(分别对应8,16,32位机)
2:获取内存用vmalloc()为什么返回的是virtual address而不是phscial address呢? 如果是虚拟地址那么该地址的段号,页号是如何得到的,因为我们OS所说的虚拟地址(逻辑地址),是指源码(名地址)经过编译形成目标程序(虚拟地址,这种地址是在访问该目标程序前根据系统采用的何种虚拟存储器而进行编的,如有页号的/段号的/段页号的)再到MEM中(物理地址),而用vmalloc() 这些又是 如何得到的?
回复 支持 反对

使用道具 举报

发表于 2005-8-22 16:27:29 | 显示全部楼层
感觉你对虚拟地址的理解不对,虚拟地址和物理地址之间的转换是CPU的Paging Unit事,内核通过Page Table来管理。搞不清楚你说的源码,编译是什么意思。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-22 17:22:45 | 显示全部楼层
虚拟地址与物理地址的转换先放一边不说。其实很简单,用kmalloc()与vmalloc()一样返回的都是虚拟地址,我想问得是这种虚拟地址的段号,页号是如何得到的,通过什么得到的。
回复 支持 反对

使用道具 举报

发表于 2005-8-22 18:50:26 | 显示全部楼层
内核中每个内存页都有一个对应的struct page。对于x86所有的struct page包含在一个数组中,struct page在数组的位置跟物理地址对应的(物理地址>>AGE_SHIFT)。内核以一定的方式组织struct page,可以很容易的得到空闲的内存页。vmalloc在申请到空闲内存后,通过更改page table来实现CPU对虚拟地址和物理地址的装换(内核预留了一部分虚拟地址给vmalloc用)。
回复 支持 反对

使用道具 举报

发表于 2005-8-22 20:34:23 | 显示全部楼层
Post by sybaselu
虚拟地址与物理地址的转换先放一边不说。其实很简单,用kmalloc()与vmalloc()一样返回的都是虚拟地址,我想问得是这种虚拟地址的段号,页号是如何得到的,通过什么得到的。

不要纠缠什么段号了,linux基本忽略了段的存在,当然为了安全考虑,而做的修改除外.
关于页号,一个虚拟地址右移12位就是页号了
回复 支持 反对

使用道具 举报

发表于 2005-8-22 23:41:53 | 显示全部楼层
Post by rickxbx
不要纠缠什么段号了,linux基本忽略了段的存在,当然为了安全考虑,而做的修改除外.
关于页号,一个虚拟地址右移12位就是页号了


是物理地址右移12位!
回复 支持 反对

使用道具 举报

发表于 2005-8-23 09:31:35 | 显示全部楼层
Post by daemeon
是物理地址右移12位!

我说的页号是page table entry
你指的可能是mem_map数组了的下标了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-23 18:23:25 | 显示全部楼层
总结一下:硬件驱动程序肯定是要对硬件的I/O端口(寄存器)或设备内存进行读写,那么对于x86来说是通过专门的函数in_b()/out_b(), in_w()/out_w(),in_l()/out_l(),(分别用于8/16/32位机的)所以说不用对他们的地址进行内存映射。而另一种对硬件读写的机制就是将其端口或设备内存映射成Cpu可访问到的或预留的内存地址空间上(这样的目的自然有他的好处)-----这段内存地址被称作是I/O内存,由于映射成内存地址后是作为虚拟地址(这是由iormap()函数来实现的)使用或返回,这样对这些硬件上的端口(寄存器)的访问是通过类似下面的函数,readb(),writeb()/readw(),write()/readl(),writel()来实现的,而不能取这段地址指针访问他们,因为这样很不安全(书上说的)。如果这段I/O内存的访问不是通过页号来访问的(有这种情况发生),那么这就跟没映射一样,只能当作I/O端口来使用了---------------------纯属个人理解,不代表他人意见。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-8-29 18:33:07 | 显示全部楼层
昨天看了一下书又发现了新的问题没搞明白。
1:是整个物理RAM分成内核虚拟地址和内核逻辑地址吗? 为什么要这样分? 内核虚拟地址又与用户作业的虚拟地址有何区别。从驱动程序第二版书中来看,这样分的目的是因为在32位机上用虚拟地址无法表示更多的用户逻辑空间,位数受到了限制。而且从关于“mmap()和DMA”那章给出的图看的出来,物理RAM分成低端和高端内存,其中虚拟地址部分占有高端部分,逻辑地址占有低端部分,且高端的虚拟地址有部分地址重复映射到低端内存中,而低端的逻辑地址却没有(书中后来提到高端内存部分无法实现逻辑地址)这又作何解释?
2:内核函数和用户空间部分的函数返回的是内核虚拟地址或内核逻辑地址后,用这返回的内存指针能直接访问物理RAM吗?  
3:实际上还有许多没弄懂的地方,暂时先问这么多!谢谢
回复 支持 反对

使用道具 举报

发表于 2005-8-29 18:44:24 | 显示全部楼层
Post by sybaselu
昨天看了一下书又发现了新的问题没搞明白。
1:是整个物理RAM分成内核虚拟地址和内核逻辑地址吗? 为什么要这样分? 内核虚拟地址又与用户作业的虚拟地址有何区别。从驱动程序第二版书中来看,这样分的目的是因为在32位机上用虚拟地址无法表示更多的用户逻辑空间,位数受到了限制。而且从关于“mmap()和DMA”那章给出的图看的出来,物理RAM分成低端和高端内存,其中虚拟地址部分占有高端部分,逻辑地址占有低端部分,且高端的虚拟地址有部分地址重复映射到低端内存中,而低端的逻辑地址却没有(书中后来提到高端内存部分无法实现逻辑地址)这又作何解释?

不是很明白"内核逻辑地址"这个概念.

Post by sybaselu

2:内核函数和用户空间部分的函数返回的是内核虚拟地址或内核逻辑地址后,用这返回的内存指针能直接访问物理RAM吗?

你所谓的直接访问是什么意思? 需要cpu参与吗? 如果需要cpu参与,那么在保护模式下,不管你是什么地址,cpu 都按虚拟地址对待
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表