昨天回复了一封电子邮件,有朋友问个问题很有代表性,内核初始化时会将896M前的物理页面作一一映射,那么用户进程分配到896M前的页面建立用户映射时是否要清除内核的一一映射。

关于这个问题,我的前面的文章已经有了解释,但是不甚详细,现在通过一个例子详细解释一下。实际上并不需要清除内核的一一映射,内核的一一映射只有内核自己使用,而且带来了很多的方便,内核巧妙的通过一一映射快速的执行内核路径,其实内核的一一映射也只有内核自己知道,用户进程根本涉及不到,内核只要管理好自己的内存没有什么是不可以的。页面的页表映射是硬件MMU的机制,而OS内核中拥有的是内存管理机制,二者并不冲突,它们都是独立的机制,并且层次不同,完全可以独立存在,比如你可以在没有MMU的嵌入式设备上实现复杂的内存管理,同时你也可以在同一个硬件MMU下实现不同的内存管理,比如windows和linux的就不同,我的观点大致总结如下(缺漏的部分前面的文章中有):在linux中内核一般不会介入用户的策略,它只是提供机制,向上就到系统调用接口为止,它没有upcall接口;只要用户不会访问内核,内核不会随意访问用户内存就不会有冲突,用户是难缠的,而且行为是不确定的,内核的行为是确定的,用户显然不能访问内核内存,但是内核却可以访问用户内存,然而内核十分清楚自己拥有哪些内存,比如初始化的时候将896以下页面作了一一映射,可是内核不一定用得了那么多,当用户进程需要内存时,完全可以从还在伙伴系统的512M处拽一个页面分配之并且映射到用户空间同时保留着内核的一一映射,这时这个512M处的页面已经从伙伴系统脱离了,内核如果这时也需要内存是不会被分配到该页面的,这样就不会有冲突,如果该页面本来就由内核所使用,那么它就不会在伙伴系统也不可能分配到用户进程,这么来说也不会有冲突,linux的内存管理和硬件的 MMU是两码事,如果说有联系那就是映射,影射仅仅是一个纽带和一个适配器而已。

下面我就通过一个例子来说明,当然要写内核模块了,我的机器是512M内存,少于896M,也就是全部作了一一映射。我们首先执行以下命令得到insmod程序的一些信息,因为模块加载是在insmod进程的上下文中:

[root@zhaoya ~]#objdump -d /sbin/insmod

...

08048ab0 <.fini>:

8048ab0: 55 push %ebp

8048ab1: 89 e5 mov %esp,%ebp

8048ab3: 53 push %ebx

...//0xcebe0000

我们看到进程地址空间0x8048ab3处是53,我们如果直接访问0x8048ab3,那么得到的就是53,这是显然的,但是我们还可以得到0x8048ab3所在页面的内核一一映射地址,然后访问那个地址看是不是还是53,如果是,那么就说明用户页面可能存在两份映射,接下来写一个模块:

#include

#include

#include

#include

#include

#include

static __init int test_init(void)

{

char * user_addr = (char *)0x8048ab3; //常规访问这个地址

printk("%x/n",*str);

struct page *page;

int n = get_user_pages(current, current->mm, user_addr, 1, 0, 1,&page,NULL);

printk("count:%d/n",n);

if(n>0)

{

unsigned long addr = page_address(page);

printk("address:%X/n",addr);

unsigned char * p = (unsigned char *)(address + user_addr&0xfff) ;//最后加入偏移

printk("%x/n",*p); //按照内核一一映射访问页面的内核地址

}

return 0;

}

static __exit void test_exit(void)

{

return ;

}

module_init(test_init);

module_exit(test_exit);

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("Zhaoya");

MODULE_DESCRIPTION("kernel map");

MODULE_VERSION("Ver 0.1");

我们实在没有必要用cr3得到页目录,然后用二级或者三级乃至多级页面映射的方式去得到页面,那是非常复杂的,而且和体系结构相关,如果非要那样做的话首先你必须熟悉你的机器,其次还要熟悉C语言,幸运的是,内核提供了get_user_pages这个函数,我们可以轻而易举的根据虚拟地址得到页面。结果当然显而易见了,两次打印都是53,如果觉得不保险可以多试几个虚拟地址。

实际上一个页面保持多个映射并不是稀罕事,原因还是前面说的,内存管理和MMU管理是两码事。比如共享内存页面就可能保持多个映射。

本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273945

关于内核页表和进程页表的一个问题相关推荐

  1. arm linux 进程页表,linux内存管理(五)arm页表

    最近比较忙,好多天没更新了,后面可能还需要20多篇文章才能把整个内存管理讲透. 前面讲述了一个通用的页表机制,以及简单介绍了TLB.今天会介绍arm的页表机制,这里特指32位arm. 目前内核提供了一 ...

  2. linux 进程装入 物理内存 页表,linux进程空间一步步探究.doc

    linux进程空间一步步探究.doc linux 进程地址空间的一步步探究 讲师:程姚根 我们知道,在32位机器上linux操作系统中的进程的地址空间大小是4G,其中0-3G是用户空间,3G-4G是内 ...

  3. linux 进程切换 页表 重,进程切换分析(2):TLB处理

    进程切换分析(2):TLB处理 作者:linuxer 发布于:2017-2-9 12:05 分类:进程管理 一.前言 进程切换是一个复杂的过程,本文不准备详细描述整个进程切换的方方面面,而是关注进程切 ...

  4. windows内核情景分析---进程线程2

    二.线程调度与切换 众所周知:Windows系统是一个分时抢占式系统,分时指每个线程分配时间片,抢占指时间片到期前,中途可以被其他更高优先级的线程强制抢占. 背景知识:每个cpu都有一个TSS,叫'任 ...

  5. windows内核情景分析---进程线程1

    本篇主要讲述进程的启动过程.线程的调度与切换.进程挂靠 一.进程的启动过程: BOOL CreateProcess ( LPCTSTR lpApplicationName,               ...

  6. 【Linux 内核笔记】进程管理

    文章目录 进程创建 进程终结 孤儿进程 小结 clone()-fork()-exec()-exit() 子进程结束ZOMBIE 父进程wait4() 进程描述符task_struct进程所有信息 由t ...

  7. 计算机组成原理:简单页表和多级页表(虚拟内存的映射)

    我们的指令和数据,都必须先加载到内存,才会被CPU拿去执行.但是程序并不能直接访问到物理内存.从这里可以知道,程序是怎么装载到内存中执行的. 我们的内存需要被分成固定大小的页(Page),然后才通过虚 ...

  8. 【操作系统/计组】页面大小 与 页表项 ( 二级页表 、多级页表 )

    [操作系统/计组]页面大小 与 页表项 结论1(一级页表) 结论2(二级.多级页表) 例题 首先,不论一级页表还是多级页表: 页面大小 = 2^(页内地址位数) 页号有多少,页就有多少个 用于存放页的 ...

  9. linux一个进程通知另外一个进程,Linux进程通信学习笔记

    一.为什么需要进程通信 1)数据传输 一个进程需要把它的数据发送给另一个进程. 2)资源共享 多个进程之间共享同样的资源. 3)通知事件 一个进程向另外一个进程发送消息,通知它发生了某事件. 4)进程 ...

最新文章

  1. docker 中删除dead状态的容器
  2. Docker for Windows 使用 VMware WorkStation
  3. LWIP再探----内存池管理
  4. mysql数据库常见错误码大全
  5. Spring中的异步和事务性事件侦听器
  6. 用友u8服务器优化,用友U8v10.1运行速度慢的问题及解决方法
  7. CS224n —— lecture2的重难点讲解
  8. react学习系列1 修改create-react-app配置支持stylus 1
  9. 总结G1垃圾收集器面试题
  10. 碱性干电池的内阻测试方法_电池内阻怎么测
  11. 权威认证闭环 | 国内首家DevSecOps体系全栈产品通过CWE国际兼容性认证
  12. 电脑怎么打出冒号符号_电脑键盘怎么打出冒号符号
  13. ubuntu16.04系统下配置caffe的GPU环境,训练mobileNet-SSD并在EAIDK-310嵌入式上推理
  14. Mac系统安装numpy
  15. 对象存储界的“百变星君”来了,非结构化数据存储还是事儿吗?
  16. 希尔伯特曲线 java_希尔伯特曲线(示例代码)
  17. AudioRecord的用法
  18. 设有n个人围坐一圈并按顺时针方向从1到n编号
  19. 计算机网络--数据链路层[微课堂]
  20. 什么是IaaS,PaaS,SaaS?

热门文章

  1. dtrace-stap-book
  2. 最大子段和 分治与动态规划
  3. Spring AOP功能和目标
  4. 获取自定义data的几种属性
  5. 关于js渲染网页时爬取数据的思路和全过程(附源码)
  6. Homogeneous Coordinates(齐次坐标)
  7. 驱动学习 - 加载.卸载驱动
  8. Swift - 获取、改变按钮的标题文本(UIButton点击切换title)
  9. UNIX环境高级编程8.9竞争条件
  10. 编译linux内核时出错