免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: javacool

kernel 中如何访问管理pci memory [复制链接]

论坛徽章:
0
发表于 2009-04-13 21:47 |显示全部楼层
原帖由 albcamus 于 2009-4-13 17:51 发表

1. MMIO是 *设备内存* 和 虚拟地址之间建立的影射, 和系统RAM一点关系都没有 — 而Linux的那些ZONE_XXX, 只是用来划分系统RAM的。

2. 32 x86上显卡driver, 传统方式是在xorg里头, 读取/dev/mem,找到显卡的 设备内存, 然后mmap到 *用户空间*, 来访问的。 这样不占用内核虚拟地址空间。  但是32位x86上使用in-kernel显卡driver的情况我就不清楚了。 ...



对于1,我这里的说法有概念错误,我原本的意思是想问, MMIO的物理内存如果是映射入内核空间的话,一般是映射到内核虚拟地址空间那128M的高端呢,还是896M那部分区间?

我个人理解是128M那部分不是永久映射,一般给用户进程用,上下文切换时也会映射到不同的物理内存,但很多驱动调用ioremap以后应该会一直需要访问MMIO对应的虚拟地址空间,所以,似乎是需要映射到896那部分的。


对于2,谢谢你的回复,显卡这个是比较特殊的。

[ 本帖最后由 Solaris12 于 2009-4-13 21:51 编辑 ]

论坛徽章:
0
发表于 2009-04-14 08:30 |显示全部楼层
谢谢各位的讲解
其实就是一个问题,在kernel下如何映射 访问高于1G的physical 地址(32下同时memory 同时小于4G )
MMIO的 pci extension memory 和 system memory 都有可能位于大于1G的physical 地址上

对于system memory 有ZONE_HIGHMEM

对于pci extension memory 1. 可以像albcamus版主说的 将其映射到用户空间,
                            2. 但如果我们想映射在内核空间,而此时内核空间又全部映射给了system memory(system memory  > 896M)   这时系统将如何处理?

我想第二个问题就是ls刚才说的问题

[ 本帖最后由 javacool 于 2009-4-14 08:33 编辑 ]

论坛徽章:
0
发表于 2009-04-14 11:15 |显示全部楼层
原帖由 javacool 于 2009-4-14 08:30 发表

对于pci extension memory 1. 可以像albcamus版主说的 将其映射到用户空间,
                            2. 但如果我们想映射在内核空间,而此时内核空间又全部映射给了system memory(system memory  > 896M)   这时系统将如何处理?

我想第二个问题就是ls刚才说的问题

对 ...


对于1,显卡的确很特殊,大部分其它设备的内存空间都是映射入内核的。

对于2,你的说法不大正确,Linux内核内存也是按需分配和影射的,不存在一下子都把896M影射的情况,不然只有1G物理内存的机器怎么办?
所以我猜想,驱动调用ioremap的时候,自己PCI的内存会影射入这896M的空间。

因为我没看过Linux内核的代码,但我觉得看ioremap怎么实现肯定能得到答案。

论坛徽章:
0
发表于 2009-04-14 15:28 |显示全部楼层
我看到system init 中 pagetable_init()确实会把 0-896M的 physical memory 全部映射到kernel space c0000000以上,这并不影响用户态也映射这些physcial address, kernel这样做只是方便管理这些system memory,关于高于1G 的physical memory 映射 我找到一张图 不知道能否说明问题

[ 本帖最后由 javacool 于 2009-4-14 15:33 编辑 ]
kernel mapping.JPG

论坛徽章:
0
发表于 2009-04-14 15:35 |显示全部楼层
汗 图片粘帖的不太好 不过点进去可以看到

论坛徽章:
0
发表于 2009-04-14 17:14 |显示全部楼层
原帖由 javacool 于 2009-4-14 15:28 发表
我看到system init 中 pagetable_init()确实会把 0-896M的 physical memory 全部映射到kernel space c0000000以上,这并不影响用户态也映射这些physcial address,...


你的图我看不到,不知道有什么问题,但用户内存和内核内存差别还是很大的,如果一个机器只有896M物理内存,Linux全部映射到c0000000以上,那用户空间要分配内存怎么办呢?谁可以告诉我?

你说的不影响用户态映射,难道是用户进程分配用户内存的时候,遇到物理地址低于896M的时候会重新映射到虚拟内存的用户空间? 如果是这样我就明白了。

[ 本帖最后由 Solaris12 于 2009-4-14 18:05 编辑 ]

论坛徽章:
0
发表于 2009-04-14 18:03 |显示全部楼层
原帖由 javacool 于 2009-4-14 08:30 发表
  2. 但如果我们想映射在内核空间,而此时内核空间又全部映射给了system memory(system memory  > 896M)   这时系统将如何处理?

...


刚才看了一下ioremap的code, 应该是调用 get_vm_area_caller 从虚拟地址空间分配虚拟地址来映射的,

而这个映射的范围是VMALLOC_START到 VMALLOC_END, 从宏定义名字看,似乎是那128M的区间去分配的。

论坛徽章:
0
发表于 2009-04-15 00:31 |显示全部楼层
原帖由 fantry_t 于 2009-4-14 22:20 发表

1.像大家讨论的那样,物理内存被内核指令访问和被用户进程访问用的页表是各自独立的,这个比较重要。也即用户空间进程访问物理内存时,不会用到内核刚启动时候建立起来的一一映射的页表,而是自己建立了另外一个页表。 ...


对于32位x86来说,每个用户进程独立的页表里应该都包含内核内存的映射,也就是说所有用户进程4G地址空间里,3G-4G是共享内核的地址空间。假设一个机器只有896M内存,如果内核一上来就把他们都映射到3G-4G之间的内核地址空间,那用户空间内存是怎么映射的?

ioremap的实现我今天看了一遍,应该可以回答楼主的问题,关键是我不理解Linux内核内存这896M映射的问题,如果没人解答我只好有时间自己再看看代码了。

论坛徽章:
0
发表于 2009-04-15 09:55 |显示全部楼层
是的 谢谢fantry_t  的解答,我觉得系统映射896M内存是为了方便访问和管理physical memory,因为这样地址映射非常简单两者就差一个PAGE_OFFSET,而这种映射并不妨碍用户空间映射相同的地址。只要内核不会写已经被用户空间映射的物理内存就好了。实际上真正每个进程的页表是拷贝kernel的页表3G-4G和自己的0-3G产生的

也谢谢Solaris12 和albcamus的解答和帮助,分只能给一个人啦

论坛徽章:
0
发表于 2009-04-15 09:56 |显示全部楼层
kernel mapping.JPG 我在贴一下那张图 呵呵

[ 本帖最后由 javacool 于 2009-4-15 09:59 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP