Linux内核空间和用户空间

合集下载

linux操作系统的组成

linux操作系统的组成

linux操作系统的组成1.内核(Kernel)Linux内核是整个Linux操作系统的核心,它负责管理系统资源,包括硬件、内存、进程、文件系统等。

内核提供了一系列系统调用,用户空间程序可以通过这些系统调用来访问内核提供的功能。

2.用户空间(User Space)用户空间是操作系统中除内核之外的部分。

用户空间包括Shell、图形界面、应用程序等。

用户空间通过系统调用来访问内核提供的功能。

用户空间和内核之间有一个保护机制,保证用户空间程序不能直接访问内核资源,只能通过系统调用。

3.ShellShell是Linux系统中的命令解释器,它充当了用户和内核之间的接口。

用户可以在Shell中输入命令,Shell解析命令并通过系统调用调用内核提供的功能。

Linux操作系统中常用的Shell有Bash、Zsh、Fish等。

4.文件系统(File System)Linux操作系统支持多种文件系统,包括Ext2、Ext3、Ext4、Btrfs、XFS等。

文件系统是管理文件和目录的机制,它负责在硬盘上分配空间,存储文件内容和元数据。

文件系统还提供了一些额外的功能,如权限管理、链接、快速查找等。

5.设备驱动程序(Device Driver)设备驱动程序是连接硬件设备和内核的桥梁,它转换设备的IO请求为内核能够理解的形式,并向内核提供设备的状态信息。

Linux操作系统支持多种设备驱动程序,包括字符设备驱动程序、块设备驱动程序、网络设备驱动程序等。

6.命令行工具(Command-Line Tool)Linux操作系统提供了丰富的命令行工具,可以轻松地完成各种任务。

常见的命令行工具有ls、cp、mv、mkdir、rm等,还有一些高级工具,如awk、sed、grep等。

7.图形界面(Graphical User Interface)Linux操作系统提供了多种图形界面,如GNOME、KDE、Xfce、LXDE等。

图形界面提供了一种更加友好的交互方式,用户可以通过鼠标点击、拖拽等方式完成操作,极大地提高了用户的工作效率。

linux kerne malloc实现原理-概述说明以及解释

linux kerne malloc实现原理-概述说明以及解释

linux kerne malloc实现原理-概述说明以及解释1.引言1.1 概述:在现代操作系统中,内存管理是一个极其重要的组成部分。

在Linux 内核中,malloc函数是用来动态分配内存的函数之一。

本文将深入探讨Linux Kernel中malloc函数的实现原理。

malloc函数的实现原理涉及到内存分配算法、数据结构以及Linux Kernel内部机制。

深入了解malloc函数的实现原理可以帮助我们更好地理解Linux内核的内存管理机制,提高系统的性能和稳定性。

通过分析Linux Kernel中malloc函数的实现原理,我们可以深入了解内核中内存管理的机制,为我们在实际开发中更好地利用和优化内存提供指导和参考。

本文旨在通过详细的介绍和分析,帮助读者深入理解Linux Kernel中malloc函数的实现原理,为内核开发和系统优化提供参考。

1.2 文章结构文章结构部分将包括以下内容:1. Linux Kernel简介:介绍Linux Kernel的基本概念和功能,以及其在操作系统中的重要性。

2. 内存管理:讨论Linux Kernel中的内存管理机制,包括内存分配和释放方式等。

3. Malloc实现原理:深入探讨Linux Kernel中malloc函数的实现原理,从内存分配算法到数据结构的设计等方面进行详细分析。

4. 结论:总结文章要点,对Linux Kernel中malloc实现原理的重要性进行概括,并展望未来可能的发展方向。

1.3 目的本文的主要目的是深入探讨Linux Kernel中的malloc实现原理。

通过对内存管理和malloc算法的讲解,希望读者能够了解Linux Kernel中如何进行内存分配和释放操作。

通过分析malloc的实现原理,读者可以更好地理解程序中内存分配的过程,从而提高代码的效率和性能。

同时,通过对malloc算法的详细解析,读者可以了解到Linux Kernel是如何管理内存的,从而进一步优化程序的性能和可靠性。

linux设备驱动归纳总结(五):1.在内核空间分配内存

linux设备驱动归纳总结(五):1.在内核空间分配内存

一般的,用户空间使用函数malloc在堆上分配内存空间,同样的,在内核空间同样有一套类似的函数来分配空间。

下面的知识会涉及页式管理的内存机制,如果不懂的要先复习一下,在S3C2440数据手册的MMU部分有介绍。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx一、内核空间和用户空间有什么不同学c语言的时候应该学过,从用户空间看,每个进程都傻乎乎的以为自己有4G 的内存空间,其中位于高地址(3G-4G)的1G空间给内核用,另外的3G(0-3G)都是它一个人独占的。

所以用户空间很慷慨的把3G的空间分了好几个区域,如堆、栈、代码段等。

其中,malloc()分配的空间位于堆,而程序中的自动变量,如你在函数内定义的“int i”,它是放在栈上,同时。

用户空间的栈是可变栈,即随着数据的增多,对应函数的栈空间也会增多。

跟每个用户空间的进程不一样,内核只有1G的空间,同时,除了自己本身有进程运行外,内核还要允许用户空间进程调用系统调用进入内核空间去执行。

所以,内核对此相当吝啬,它规定在内核中的每个进程都只有4KB或8KB(32位下)的定长栈。

出于这样的原因,大的数据结构就不能在栈中分配,只能请求内核分配新的空间来存放数据,如函数kmalloc()。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx二、内存的基本单位是字节吗?在介绍分配内存空间的函数前,我们还要了解一下内存是怎么被划分的。

内核不仅知道用户空间中看到的1G内核空间是假的,它还知道实际的物理内存是多少(我的开发板是64M)。

所以,内核的其中一个任务就是,当这段虚假内存中的数据需要调用时,内核把这段虚拟内存与实际的物理内存对应上,运行完后又把两段内存的对应关系撤销掉给另外的虚拟内存用。

什么是Linux内核空间与用户空间

什么是Linux内核空间与用户空间

本文以32位系统为例介绍内核空间(ker n el s pa ce)和用户空间(u se r sp ac e)。

内核空间和用户空间对32位操作系统而言,它的寻址空间(虚拟地址空间,或叫线性地址空间)为4G(2的32次方)。

也就是说一个进程的最大地址空间为4G。

操作系统的核心是内核(ke rn el),它独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。

为了保证内核的安全,现在的操作系统一般都强制用户进程不能直接操作内核。

具体的实现方式基本都是由操作系统将虚拟地址空间划分为两部分,一部分为内核空间,另一部分为用户空间。

针对Li nu x 操作系统而言,最高的1G 字节(从虚拟地址0x C0000000到0xF F FF FF FF)由内核使用,称为内核空间。

而较低的 3G字节(从虚拟地址0x00000000到0xB F FF FF FF)由各个进程使用,称为用户空间。

对上面这段内容我们可以这样理解:「每个进程的 4G 地址空间中,最高1G 都是一样的,即内核空间。

只有剩余的 3G 才归进程自己使用。

」「换句话说就是,最高1G 的内核空间是被所有进程共享的!」下图描述了每个进程4G 地址空间的分配情况:为什么需要区分内核空间与用户空间在CP U 的所有指令中,有些指令是非常危险的,如果错用,将导致系统崩溃,比如清内存、设置时钟等。

如果允许所有的程序都可以使用这些指令,那么系统崩溃的概率将大大增加。

所以,C PU将指令分为特权指令和非特权指令,对于那些危险的指令,只允许操作系统及其相关模块使用,普通应用程序只能使用那些不会造成灾难的指令。

比如I nt el 的C PU将特权等级分为4个级别:R in g0~Ri n g3。

其实 L in ux系统只使用了Ri ng0 和Ri n g3两个运行级别(W in do ws系统也是一样的)。

当进程运行在 R in g3级别时被称为运行在用户态,而运行在R i ng0 级别时被称为运行在内核态。

linux操作系统体系结构

linux操作系统体系结构

linux操作系统体系结构Linux操作系统采用了一种模块化的设计,它的体系结构可以分为用户空间和内核空间两个部分。

用户空间提供了用户与操作系统之间的接口,而内核空间则负责管理系统的资源和提供各种功能的实现。

内核空间是Linux操作系统的核心,它负责管理计算机的硬件资源、处理系统的中断和异常,并为用户空间提供各种系统调用的接口。

Linux的内核是一个可靠、高效、可扩展的设计,它能够运行在多种硬件平台上。

内核包括了许多模块,每个模块负责实现一个特定的功能,比如进程管理、内存管理、文件系统等。

进程管理是Linux内核的一个关键功能,它负责创建、调度和销毁进程,并为进程之间提供通信和同步机制。

Linux采用了基于时间片的多任务调度算法,使得多个进程可以共享处理器资源,提高系统的并发性能。

而且,Linux内核还支持多线程,使得一个进程可以创建多个线程并在多个处理器上同时执行,充分发挥多核处理器的性能。

内存管理是Linux内核的另一个重要功能,它负责分配和管理系统的物理内存和虚拟内存。

Linux采用了页式存储管理机制,将物理内存划分为固定大小的页面,每个页面可以映射到不同的虚拟地址空间。

这样就可以实现进程之间的内存隔离和共享,同时还提供了一些高级的内存管理功能,比如动态内存分配和内存回收。

文件系统是Linux内核的另一个重要组成部分,它负责管理文件和目录,并提供了对这些文件和目录的访问接口。

Linux支持多种文件系统,包括Ext4、XFS、Btrfs等。

文件系统还提供了一些高级功能,比如权限管理、元数据缓存和文件系统日志等。

除了上述功能之外,Linux还提供了许多其他的功能模块,比如网络协议栈、设备驱动程序、虚拟化和容器等。

这些功能模块使得Linux 成为一个功能丰富、可定制性强的操作系统。

用户空间位于内核空间之上,它提供了用户与操作系统之间的接口。

用户空间包含了一系列的应用程序和库,这些程序和库通过系统调用与内核进行通信。

Linux用户态与内核态的交互

Linux用户态与内核态的交互

Linux 用户态与内核态的交互Linux用户态与内核态的交互2010-06-13 22:30Linux用户态与内核态的交互在Linux 2.4版以后版本的内核中,几乎全部的中断过程与用户态进程的通信都是使用netlink套接字实现的,例如iprote2网络管理工具,它与内核的交互就全部使用了netlink,著名的内核包过滤框架Netfilter在与用户空间的通读,也在最新版本中改变为netlink,无疑,它将是Linux用户态与内核态交流的主要方法之一。

它的通信依据是一个对应于进程的标识,一般定为该进程的ID。

当通信的一端处于中断过程时,该标识为0。

当使用netlink套接字进行通信,通信的双方都是用户态进程,则使用方法类似于消息队列。

但通信双方有一端是中断过程,使用方法则不同。

netlink套接字的最大特点是对中断过程的支持,它在内核空间接收用户空间数据时不再需要用户自行启动一个内核线程,而是通过另一个软中断调用用户事先指定的接收函数。

《UNIX Network Programming Volume 1-3rd Edition》第18章讲到BSD UNIX系统中routing socket的应用,这种套接字是按下面方式生成的:rt_socket=socket(AF_ROUTE,SOCK_RAW,0);然后就可以用它跟内核交互,进行网络环境管理的操作,如读取/设置/删除路由表信息,更改网关等等,但书中所列代码只在4.3BSD及以后版本的原始UNIX系统下可用,Linux虽然实现了AF_ROUTE族套接字,但用法却完全不同。

由于网上这方面知识的资料想对匮乏,现对Linux下routing socket的使用做一介绍。

由于我现在在MagicLinux1.0下工作,所以以下的讲解全部基于2.4.10内核。

Linux从v2.2开始引入这一机制,因此可以肯定从v2.2到v2.4的内核都是适用的,更新的v2.6我没有试过。

linux操作系统的体系结构

linux操作系统的体系结构

linux操作系统的体系结构Linux操作系统的体系结构Linux是一个开源的操作系统内核,它是一个多任务、多用户的操作系统。

它支持大量的硬件平台,可以运行在个人计算机、服务器、移动设备和嵌入式系统中。

Linux操作系统的核心设计是基于UNIX操作系统的设计理念,具有稳定、安全和高性能的特点。

本文将详细介绍Linux操作系统的体系结构。

一、内核空间和用户空间Linux操作系统采用了一种分层的体系结构,将操作系统分为内核空间和用户空间两部分。

内核空间是操作系统内核运行的区域,包括内核代码、驱动程序和中断处理程序等。

用户空间是用户程序运行的区域,包括应用程序、库文件和用户数据等。

内核空间和用户空间通过操作系统提供的系统调用接口进行通信。

用户程序通过系统调用接口请求操作系统提供的服务,如文件操作、进程管理和网络通信等。

操作系统在内核空间中响应这些请求,并将结果返回给用户程序。

二、进程管理Linux操作系统是一个多任务操作系统,能够同时运行多个进程。

进程是程序在操作系统中的实体,它包括代码、数据和运行环境等。

Linux操作系统通过进程管理功能对进程进行管理和调度。

进程管理功能包括创建进程、销毁进程、挂起进程、恢复进程和进程切换等。

Linux操作系统通过调度算法决定哪个进程优先执行,以实现操作系统的高效利用和公平分享。

三、内存管理Linux操作系统通过内存管理功能对内存进行管理和分配。

内存是计算机中重要的资源,操作系统需要有效地管理和分配内存。

Linux操作系统使用虚拟内存管理技术,将物理内存虚拟化为逻辑地址空间。

这样,每个进程都有自己独立的逻辑地址空间,不会相互干扰。

操作系统通过内存管理功能实现虚拟地址到物理地址的转换,并对内存进行分页、分段和交换等操作,以实现内存的高效利用和管理。

四、文件系统Linux操作系统通过文件系统管理文件和目录。

文件系统是一种组织和存储文件的方式,可以将文件组织成层次结构,方便用户访问和管理。

linux体系结构

linux体系结构

linux体系结构linux体系结构从⼤⾯上来说,linux体系结构分为:⽤户空间:C库、⽤户应⽤程序内核空间:系统调⽤接⼝、内核、硬件平台依赖代码具体来讲,linux可划分为5个部分:linux内核、GNU⼯具链、桌⾯环境、应⽤软件linux内核系统调⽤接⼝(SCI层):给应⽤⽤户提供⼀套标准的系统调⽤函数,上层⽤户可以通过这⼀套标准接⼝来访问底层内存管理:进程管理:⽂件管理:设备驱动管理:内存管理1.作⽤:管理物理内存、创建和管理虚拟内存为了使有限的物理内存满⾜应⽤程序对内存的需求,linux采⽤“虚拟内存”的内存管理⽅式实现,实现原理:交换空间:内核在硬盘上化⼀段存储空间来实现虚拟内存,这段存储空间称为“交换空间”页⾯:内存存储单元被分割成很多块,称为“页⾯”页⾯内存表:内核会维护⼀张表,来指明哪些页⾯位于物理内存,那么页⾯位于交换空间换出:物理内存---->交换空间换⼊:交换空间---->物理内存⼯作过程:1、内核将程序运⾏⽤到的页⾯就放到内存⾥,暂时不⽤就放到交换空间中(换出)。

2、当⽤到交换空间的页⾯时,就把它们调到内存中(换⼊),然后把物理内存其他⽤不到的页⾯换出到交换空间。

查看内存#cat /proc/meminfoMemTotal: 1035244 kB #物理内存1GMemFree: 786616 kB #空闲内存700M左右...SwapTotal: 2096472 kB #有2G的交换空间....查看内存使⽤情况#freetotal used free shared buffers cachedMem: 502360 489964 12396 0 53852 283372-/+ buffers/cache: 152740 349620Swap: 1015800 0 1015800共享内存页⾯:创建⼀写共享内存页⾯,⽤于多个进程共享使⽤。

#ipcs -m #查看共享内存页⾯key shmid owner perms bytes nattch status0x00000000 0 rich 600 52228 6 dest#owner:共享内存段的所有者#perms:权限进程管理参见⽂件管理linux内核⽂件管理采⽤虚拟⽂件系统(VFS),隐藏各种⽂件系统的具体细节,为⽂件操作提供统⼀的接⼝。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。

Linux内核地址映射模型x86 CPU采用了段页式地址映射模型。

进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存。

段页式机制如下图。

Linux内核地址空间划分通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。

注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。

Linux内核高端内存的由来当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,… …,逻辑地址与物理地址对应的关系为物理地址= 逻辑地址– 0xC0000000么物理地址为0×40000001的内存,内核该怎么去访问呢?代码中必须要有内存逻辑地址的,0xc0000000 ~ 0xffffffff的地址空间已经被用完了,所以无法访问物理地址0×40000000以后的内存。

显然不能将内核地址空间0xc0000000 ~ 0xfffffff全部用来简单的地址映射。

因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。

ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。

在x86结构中,三种类型的区域如下:ZONE_DMA 内存开始的16MBZONE_NORMAL 16MB~896MBZONE_HIGHMEM896MB ~ 结束Linux内核高端内存的理解前面我们解释了高端内存的由来。

Linux将内核地址空间划分为三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,高端内存HIGH_MEM地址空间范围为0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。

那么如内核是如何借助128MB高端内存地址空间是如何实现访问可以所有物理内存?当内核想访问高于896MB物理地址内存时,从0xF8000000 ~ 0xFFFFFFFF地址空间范围内找一段相应大小空闲的逻辑地址空间,借用一会。

借用这段逻辑地址空间,建立映射到想访问的那段物理内存(即填充内核PTE页面表),临时用一会,用完后归还。

这样别人也可以借用这段地址空间访问其他物理内存,实现了使用有限的地址空间,访问所有所有物理内存。

如下图。

例如内核想访问2G开始的一段大小为1MB的物理内存,即物理地址范围为0×80000000 ~ 0x800FFFFF。

访问之前先找到一段1MB大小的空闲地址空间,假设找到的空闲地址空间为0xF8700000 ~ 0xF87FFFFF,用这1MB的逻辑地址空间映射到物理地址空间0×80000000 ~ 0x800FFFFF的内存。

映射关系如下:看到这里,不禁有人会问:万一有内核进程或模块一直占用某段逻辑地址空间不释放,怎么办?若真的出现的这种情况,则内核的高端内存地址空间越来越紧张,若都被占用不释放,则没有建立映射到物理内存都无法访问了。

在香港尖沙咀有些写字楼,洗手间很少且有门锁的。

客户要去洗手间的话,可以向前台拿钥匙,方便完后,把钥匙归还到前台。

这样虽然只有一个洗手间,但可以满足所有客户去洗手间的需求。

要是某个客户一直占用洗手间、钥匙不归还,那么其他客户都无法上洗手间了。

Linux内核高端内存管理的思想类似。

Linux内核高端内存的划分内核将高端内存划分为3部分:VMALLOC_START~VMALLOC_END、KMAP_BASE~FIXADDR_START和FIXADDR_START~4G。

对于高端内存,可以通过alloc_page() 或者其它函数获得对应的page,但是要想访问实际物理内存,还得把page 转为线性地址才行(为什么?想想MMU 是如何访问物理内存的),也就是说,我们需要为高端内存对应的page 找一个线性空间,这个过程称为高端内存映射。

对应高端内存的3部分,高端内存映射有三种方式:映射到”内核动态映射空间”(noncontiguous memory allocation)这种方式很简单,因为通过vmalloc() ,在”内核动态映射空间”申请内存的时候,就可能从高端内存获得页面(参看vmalloc 的实现),因此说高端内存有可能映射到”内核动态映射空间”中。

持久内核映射(permanent kernel mapping)如果是通过alloc_page() 获得了高端内存对应的page,如何给它找个线性空间?内核专门为此留出一块线性空间,从PKMAP_BASE 到FIXADDR_START ,用于映射高端内存。

在 2.6内核上,这个地址范围是4G-8M 到4G-4M 之间。

这个空间起叫”内核永久映射空间”或者”永久内核映射空间”。

这个空间和其它空间使用同样的页目录表,对于内核来说,就是swapper_pg_dir,对普通进程来说,通过CR3 寄存器指向。

通常情况下,这个空间是4M 大小,因此仅仅需要一个页表即可,内核通过来pkmap_page_table 寻找这个页表。

通过kmap(),可以把一个page 映射到这个空间来。

由于这个空间是4M 大小,最多能同时映射1024 个page。

因此,对于不使用的的page,及应该时从这个空间释放掉(也就是解除映射关系),通过kunmap() ,可以把一个page 对应的线性地址从这个空间释放出来。

临时映射(temporary kernel mapping)内核在FIXADDR_START 到FIXADDR_TOP 之间保留了一些线性空间用于特殊需求。

这个空间称为”固定映射空间”在这个空间中,有一部分用于高端内存的临时映射。

这块空间具有如下特点:(1)每个CPU 占用一块空间(2)在每个CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个page,每个小空间用于一个目的,这些目的定义在kmap_types.h 中的km_type 中。

当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的地址作为映射地址。

这意味着一次临时映射会导致以前的映射被覆盖。

通过kmap_atomic() 可实现临时映射。

常见问题:1、用户空间(进程)是否有高端内存概念?用户进程没有高端内存概念。

只有在内核空间才存在高端内存。

用户进程最多只可以访问3G物理内存,而内核进程可以访问所有物理内存。

2、64位内核中有高端内存吗?目前现实中,64位Linux内核不存在高端内存,因为64位内核可以支持超过512GB内存。

若机器安装的物理内存超过内核地址空间范围,就会存在高端内存。

3、用户进程能访问多少物理内存?内核代码能访问多少物理内存?32位系统用户进程最大可以访问3GB,内核代码可以访问所有物理内存。

64位系统用户进程最大可以访问超过512GB,内核代码可以访问所有物理内存。

4、高端内存和物理地址、逻辑地址、线性地址的关系?高端内存只和逻辑地址有关系,和逻辑地址、物理地址没有直接关系。

5、为什么不把所有的地址空间都分配给内核?若把所有地址空间都给内存,那么用户进程怎么使用内存?怎么保证内核使用内存和用户进程不起冲突?(1)让我们忽略Linux对段式内存映射的支持。

在保护模式下,我们知道无论CPU运行于用户态还是核心态,CPU执行程序所访问的地址都是虚拟地址,MMU 必须通过读取控制寄存器CR3中的值作为当前页面目录的指针,进而根据分页内存映射机制(参看相关文档)将该虚拟地址转换为真正的物理地址才能让CPU真正的访问到物理地址。

(2)对于32位的Linux,其每一个进程都有4G的寻址空间,但当一个进程访问其虚拟内存空间中的某个地址时又是怎样实现不与其它进程的虚拟空间混淆的呢?每个进程都有其自身的页面目录PGD,Linux将该目录的指针存放在与进程对应的内存结构task_struct.(struct mm_struct)mm->pgd中。

每当一个进程被调度(schedule())即将进入运行态时,Linux内核都要用该进程的PGD指针设臵CR3(switch_mm())。

(3)当创建一个新的进程时,都要为新进程创建一个新的页面目录PGD,并从内核的页面目录swapper_pg_dir中复制内核区间页面目录项至新建进程页面目录PGD的相应位臵,具体过程如下:do_fork() --> copy_mm() --> mm_init() --> pgd_alloc() --> set_pgd_fast() --> get_pgd_slow() --> memcpy(&PGD + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t))这样一来,每个进程的页面目录就分成了两部分,第一部分为“用户空间”,用来映射其整个进程空间(0x0000 0000-0xBFFF FFFF)即3G 字节的虚拟地址;第二部分为“系统空间”,用来映射(0xC000 0000-0xFFFF FFFF)1G字节的虚拟地址。

可以看出Linux系统中每个进程的页面目录的第二部分是相同的,所以从进程的角度来看,每个进程有4G字节的虚拟空间,较低的3G字节是自己的用户空间,最高的1G字节则为与所有进程以及内核共享的系统空间。

(4)现在假设我们有如下一个情景:在进程A中通过系统调用sethostname(const char *name,seze_t len)设臵计算机在网络中的“主机名”.在该情景中我们势必涉及到从用户空间向内核空间传递数据的问题,name是用户空间中的地址,它要通过系统调用设臵到内核中的某个地址中。

让我们看看这个过程中的一些细节问题:系统调用的具体实现是将系统调用的参数依次存入寄存器ebx,ecx,edx,esi,edi(最多5个参数,该情景有两个 name和len),接着将系统调用号存入寄存器eax,然后通过中断指令“int 80”使进程A进入系统空间。

由于进程的CPU运行级别小于等于为系统调用设臵的陷阱门的准入级别3,所以可以畅通无阻的进入系统空间去执行为int 80设臵的函数指针system_call()。

相关文档
最新文档