免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: javacool
打印 上一主题 下一主题

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

论坛徽章:
0
31 [报告]
发表于 2009-04-16 11:16 |只看该作者

回复 #30 albcamus 的帖子

> 因为从道理上讲, kernel为什么那么蠢, 一上来就把可用内存全给映射了? 没必要嘛。

呵呵,这不是蠢,这是为了方便。kernel可以随时access他想要访问的物理memory

>试想, 内核得到用户传来的, void *p,需要访问它,难道:
>
> 1) 查页表,知道物理page;
> 2) map 这个page到kernel的某个地址
> 3) 用新map的kernel地址去访问
>
> 我觉得这太蠢了,任何一个OS都不会这样。

查到物理page后,就可以通过page phy addr + PAGE_OFFSET得到这个物理页在kernel中的virtual address. kernel就可以访问这块物理地址了。

具体可以参考  __copy_to_user() -> __copy_to_user_ll() . 通过user address 得到 struct page, 再得到 kernel virtual address就可以进行copy了。

论坛徽章:
0
32 [报告]
发表于 2009-04-16 11:23 |只看该作者

回复 #31 eexplorer 的帖子

我所说的都是没有high memory的条件下(i386)。如果是high memory的话,因为一开始并没有映射到kernel的virtual address space [3G, 3G+896M)来。所以kernel要access high memory的话,就要作额外的映射了。

论坛徽章:
0
33 [报告]
发表于 2009-04-16 12:23 |只看该作者
我问一个问题, 我机器只有512M的物理内存, 按照你的说法, 在boot时都映射到kernel了。

后来init之后,有了用户进程, 再从这些物理内存分配一些映射到用户空间。 也就是,分配给进程的内存, 既有到用户空间的映射, 也有到内核空间的映射: 2对1。

OK, 我们知道, Linux从来不swap out 映射到内核的内存。 如果上面的描述成立, 是不是Linux就没有swappable的内存了? 是不是linux的swap分区在没有highmem的32位机器上, 就是个摆设? 是不是这种情形下, Linux永远都执行不了firefox、thunderbird、evolution程序?

Think it。

[ 本帖最后由 albcamus 于 2009-4-16 12:24 编辑 ]

论坛徽章:
0
34 [报告]
发表于 2009-04-16 12:50 |只看该作者

回复 #33 albcamus 的帖子

> 我问一个问题, 我机器只有512M的物理内存, 按照你的说法, 在boot时都映射到kernel了。

这里所谓的映射只不过是将page table [3G,3G+896M)的entry映射到物理地址[0,896M)。
只是为了方便kernel访问物理内存而已。

但是kernel并没有用掉所有物理memory,所有空闲的物理内存都在buddy system里。

是不是决定要把某个page swap out,需要用到struct page的信息。

论坛徽章:
0
35 [报告]
发表于 2009-04-16 13:09 |只看该作者
>这里所谓的映射只不过是将page table [3G,3G+896M)的entry映射到物理地址[0,896M)。
>只是为了方便kernel访问物理内存而已。

一句话: 建立页表了没有?

论坛徽章:
0
36 [报告]
发表于 2009-04-16 13:17 |只看该作者
原帖由 albcamus 于 2009-4-16 13:09 发表
>这里所谓的映射只不过是将page table [3G,3G+896M)的entry映射到物理地址[0,896M)。
>只是为了方便kernel访问物理内存而已。

一句话: 建立页表了没有?


建了页表映射,就此而已。我已经说了code在kernel_physical_mapping_init()这个函数里,上面还有注释,自己去看。。。

论坛徽章:
0
37 [报告]
发表于 2009-04-16 15:22 |只看该作者
原帖由 eexplorer 于 2009-4-16 11:16 发表
> 因为从道理上讲, kernel为什么那么蠢, 一上来就把可用内存全给映射了? 没必要嘛。

具体可以参考  __copy_to_user() -> __copy_to_user_ll() . 通过user address 得到 struct page, 再得到 kernel virtual address就可以进行copy了。



刚才看了一下Solaris ddi_copyin的实现,实际上是直接访问用户空间的address的,不需要再映射到内核内存的虚拟地址。这是因为能保证在当前用户空间的上下文来做这个copy,这时当前页表拥有该进程的虚拟地址的记录,可以查到物理地址,所以不需要做再次的映射。Linux应该也是类似的,不会需要再查一次表。


但Solaris里并不是全依靠copyin的方式来访问用户内存,比如存储驱动,用户到内核是零copy,所以会有bp_mapin这样的函数,可以把用户空间的地址映射到内存空间。

论坛徽章:
0
38 [报告]
发表于 2009-04-16 15:35 |只看该作者

回复 #37 Solaris12 的帖子

>这是因为能保证在当前用户空间的上下文来做这个copy,这时当前页表拥有该进程的虚拟地址的记
>录,可以查到物理地址,所以不需要做再次的映射。Linux应该也是类似的,不会需要再查一次
> 表。

通过进程page table可以得到物理地址,得到后,如何在kernel space你如何去access这块物理memory?

kernel也是通过mmu去access他的,所以他事先就建好了映射。
kernel virtual addr [3G, 3G+896M) -> [0,896M)

linux也不需要再去查一次page table。因为他已经为[0, 896M)的物理地址空间建好了线性映射。 所以,phy_addr + 3G,就是kernel在自己的空间里去access这块物理memory所需要的virtual address.

论坛徽章:
0
39 [报告]
发表于 2009-04-16 15:57 |只看该作者
原帖由 eexplorer 于 2009-4-16 15:35 发表
>这是因为能保证在当前用户空间的上下文来做这个copy,这时当前页表拥有该进程的虚拟地址的记
>录,可以查到物理地址,所以不需要做再次的映射。Linux应该也是类似的,不会需要再查一次
> 表。

通过进程pa ...


这样吧, 能分析一下copy_from_user的代码,看看到底是不是 用内核地址去访问用户内存的吗?

论坛徽章:
0
40 [报告]
发表于 2009-04-16 17:06 |只看该作者
原帖由 albcamus 于 2009-4-16 15:57 发表


这样吧, 能分析一下copy_from_user的代码,看看到底是不是 用内核地址去访问用户内存的吗?


稍微看了一下,对asm不太熟,对于copy_from_user(), 注释里说了"user context only", 所以copy_from/to_user 一般是用于system call, 所以kernel使用process page table 应给是没有问题,并通过user address 来access user space memory是可以的。 (但是通过我说的 user addr -> phy addr -> kernel virtual addr也是可以的,see __copy_to_user_ll() with CONFIG_X86_WP_WORKS_OK defined, kernel 就是通过get_users_pages来得到对应于这个user addr的struct page, 然后在通过kmap_atomic()得到对应的kernel virtual address).

上面说了在system call里,copy_from_user一般用于读取user space传进来的参数。但是在一些aio操作中,kernel想要access user space memory的话,就必须通过get_user_pages()现得到所对应的struct page,在通过kmap_atomic()得到这个page所对应的kernel virtual address.
因为这是已经不是在原来的user process context中了。

另外一个地方就是,kernel通过buddy system 分配一个page, 他也需要将这个page来得到kernel virtual address来访问这个page对应的物理地址。在slab中会用到kmem_getpages(),可以参考。

所以,kernel肯定是把low memory [0,896M)的物理地址线性的map到[3G,3G+896M)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP