免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7881 | 回复: 8
打印 上一主题 下一主题

[内存管理] 内核态直接访问用户空间地址(0x08048100)会怎么样? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-27 19:07 |只看该作者 |倒序浏览
假设一个用户进程的地址0x0804_8100放的是一个int变量,其值是5,其对应物理地址是0xAAA;
那系统调用后,在内核态直接访问0x08048100这个地址会怎么样?(假设做的操作是*0x0804_8100 = 10)
内核态时MMU会将地址0x08048100解释到物理地址什么位置上?

论坛徽章:
0
2 [报告]
发表于 2013-09-27 19:32 |只看该作者
本帖最后由 Huntsmen 于 2013-09-27 19:36 编辑

个人理解是:
在内核态能够直接操作的地址一定必须是0xc0000000-0xffffffff之间的,这个范围之外的地址都会发生缺页异常,要访问用户态的地址空间的话,只能先将用户地址空间转换到内核地址空间;
用户空间地址-》物理地址-》内核空间地址-》操作
比如在内核态要将0x08048100处的赋值10;
先通过0x08048100查页表得到其物理地址A,
如果A<896M,那么就 *(0xc000_0000+A)=10;
如果A>896M(高端内存),就需要通过内核动态映射区将物理地址A映射到内核地址空间B,然后*B=10;
B的值在范围(0xc0000000+896M,0xffffffff)之间;

不知道我的理解是否正确,请高手指点,谢谢!

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
3 [报告]
发表于 2013-09-27 21:50 |只看该作者
本帖最后由 arm-linux-gcc 于 2013-09-27 21:53 编辑

回复 2# Huntsmen


    就是直接读取地址的,通过系统调用进入内核的,仍然是和app属于同一个执行流,即是同一个进程,也即页表没有变化,所以完全可以直接读取
所谓缺页异常都是因为访问了页表没有映射的那些虚拟地址,但是在这个进程页表中,3G以下的区域是映射了的,所以完全可以直接读写

缺页异常需要在开启MMU的情况下才会有,假如你在uboot里面,你去直接读写那种根本不存在任何东西的地址,也是不会发生任何错误的。


论坛徽章:
0
4 [报告]
发表于 2013-09-27 23:51 |只看该作者
回复 3# arm-linux-gcc

你的意思是如果是系统调用的话,*0x0804_10000=10是可以正确执行的,
但是如果是在中断、kernel thread中执行这个语句就会产生缺页?


   

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:58:11
5 [报告]
发表于 2013-09-28 17:59 |只看该作者
回复 4# Huntsmen


    中断和kthread不能去读取user space,因为当kthread去读取user space时,user space可能已经切换到别的进程了

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
6 [报告]
发表于 2013-09-28 21:29 |只看该作者
回复 5# arm-linux-gcc

内核态无所不能吧,只是中断、kthread没有这种需求而已,因为他不知道current是那个进程。
   

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
7 [报告]
发表于 2013-09-29 16:06 |只看该作者
回复 1# Huntsmen
只要页面有对应的物理页面,内核可以随便搞

   

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
8 [报告]
发表于 2013-09-30 09:08 |只看该作者
arm-linux-gcc 发表于 2013-09-28 17:59
回复 4# Huntsmen


kthread的说法有问题吧

kthread本来就没有userspace mm, 它用的是上一个有userspace mm的进程的……  你本来也无法知道这是哪一个进程的mm, 而不是怕被切走。  

论坛徽章:
0
9 [报告]
发表于 2013-09-30 12:23 |只看该作者
每个进程你可以理解为一个上下文,内核是提供服务的,当然他也管理进程。
内核提供服务的方式是系统调用。假如你自己实现一个系统调用对0x08048100进行相关的操作。同时这个0x08048100是外部传入的(就像你说的0x08048100是有值的)
内核操作这个地址的代码被某个进程使用的时候,关键看这个进程的对应地址是否真的有值,即页表是有映射的。如果有可以访问,如果没有那就会有问题。

如果你吧这段访问地址的代码放到一个已有的并且常用的系统调用中,即使你自己写的程序在用户控件0x08048100有值(映射了),但是其他程序使用此系统调用的时候他的0x08048100可能没有映射。所以会有问题。

可以参考copy_from_user等函数对用户空间地址的检查处理。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP