通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。地址分配如下图所示
内核地址空间分布
直接映射区:线性空间中从3G开始最大896M的区间,为直接内存映射区,该区域的线性地址和物理地址存在线性转换关系:线性地址=3G+物理地址。
动态内存映射区:该区域由内核函数vmalloc来分配,特点是:线性空间连续,但是对应的物理空间不一定连续。vmalloc分配的线性地址所对应的物理页可能处于低端内存,也可能处于高端内存。
永久内存映射区:该区域可访问高端内存。访问方法是使用alloc_page(_GFP_HIGHMEM)分配高端内存页或者使用kmap函数将分配到的高端内存映射到该区域。
固定映射区:该区域和4G的顶端只有4k的隔离带,其每个地址项都服务于特定的用途,如ACPI_BASE等。
关于内核空间和用户空间,说的是linux驱动程序一般工作在内核空间,但也可以工作在用户空间。下面将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们。
Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4GLinux内核将这4G字节的空间分为两部分。将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为"内核空间"而将较低的3G字节(从虚拟地址 0x00000000到0xBFFFFFFF),供各个进程使用,称为"用户空间)。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。
Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB字节虚拟内核空间则为所有进程以及内核所共享。
内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。
内存划分为用户空间与内核空间的原因:
用户空间和内核空间置于这种非对称访问机制下有很好的安全性,能有效抵御恶意用户的窥探,也能防止质量低劣的用户程序的侵害,从而使系统运行得更稳定可靠。用户空间与内核空间的权限不同,内核空间拥有所有硬件设备的权限,用户空间只有普通硬件的权限。
Linux系统对自身进行了划分,一部分核心软件独立于普通应用程序,运行在较高的特权级别上,它们驻留在被保护的内存空间上,拥有访问硬件设备的所有权限,Linux将此称为内核空间。
相对地,应用程序则是在“用户空间”中运行。运行在用户空间的应用程序只能看到允许它们使用的部分系统资源,并且不能使用某些特定的系统功能,也不能直接访问内核空间和硬件设备,以及其他一些具体的使用限制。
您好,湖北政务网老显示返回用户空间可能是由于您的网络环境出现了问题,导致您无法正常访问湖北政务网。可能是您的网络环境出现了问题,例如网络连接不稳定、网络环境受到干扰等,都可能导致您无法正常访问湖北政务网。建议您可以检查一下您的网络环境,确保您的网络环境是稳定的,然后再尝试访问湖北政务网,如果还是无法访问,建议您可以联系湖北政务网的客服人员,以便获得更好的帮助。
本文整理和引用他人的笔记,旨在个人复习使用。
参考链接:
>
Linux虚拟内存的大小为2^32(在32位的x86机器上),内核将这4G字节的空间分为两部分。最高的1G字节(从虚地址
0xC0000000到0xFFFFFFFF)供内核使用,称为“内核空间”。而较低的3G字节(从虚地址0x00000000到
0xBFFFFFFF),供各个进程使用,称为“用户空间”。因为每个进程可以通过系统调用进入内核,因此,Linux内核空间由系统内的所有进程共享。
于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟地址空间(也叫虚拟内存)
每个进程有各自的私有用户空间(0~3G),这个空间对系统中的其他进程是不可见的。最高的1GB内核空间则为所有进程以及内核所共享。另外,进程的“用户空间”也叫“地址空间”,在后面的叙述中,我们对这两个术语不再区分。
用户空间不是进程共享的,而是进程隔离的。每个进程最大都可以有3GB的用户空间。一个进程对其中一个地址的访问,与其它进程对于同一地址的访问绝不冲
突。比如,一个进程从其用户空间的地址0x1234ABCD处可以读出整数8,而另外一个进程从其用户空间的地址0x1234ABCD处可以读出整数
20,这取决于进程自身的逻辑。
因此Linux对用户空间与内核空间的划分起到了一定程度上的冲突避免。
管道用于有学园关系的进程之间。
管道的pipe 系统调用实际上就是创建出来两个文件描述符。
当父进P1程创建出 fd[2] 时,子进程P2 会继承父进程的所有,所以也会得到pipe 的 2个 文件描述符。
所以毫无瓜葛的两个进程,一定不会访问到彼此的pipe。无法用管道进行通信。
管道一般是单工的。f[0]读,f[1]写
管道也可以适用于 兄弟进程(只要有血缘即可)。由于管道是单工的,当两个进程之间需要双向通信,则需要两跟管道。
执行
ctrl-c(2号信号) + SIGUSR1 信号 绑了一个新函数。则 ctrl-c 无效。
查看进程的信号
号信号被捕获。
将2号信号忽略掉
9号信号 kill 和19号信号 stop 不能乱搞,只能用缺省。
其它信号甚至段信号也都可以捕获。
改变程序的执行现场,修改PC指针,有些像goto,只不过返回非0值
运行结果
making segment fault
after segment fault
程序不会死。
如果不忽略 page fault
则会产生 core dump
不停的给data 赋值,同时每隔1s会有信号进来,打印 data的值。
理论上打印出来的结果同时为0,同时为1
但并非如此,是 0,1,交替随机的。
signal 异步的,随时都可以进来,所以打印出来的结果,并不是我想要的。
信号对于应用程序来说,很像中断对于内核,都是访问临界区数据
信号被屏蔽,延后执行。
写多线程的程序时,不要以为只有线程之间有竞争,其实信号也会有竞争
system v 的IPC 年代有些久远。
有血缘关系的进程 key_t 都是相同的。
Key 是私有key IPV PRIVATE
可能用消息队列,可能用共享内存,可能用信号量进行通讯。
利用 _pathname 路径,约定好一条路径。和tcp/ip地址很像,来生成一个key_t key, 用msg_get shm_get 得到共享内存or 信号量。
int id 可以理解为文件描述符 fd。
其中Sys V 的共享内存 最为常用。
一定要检查路径,如果仅仅有2个进程,你没有创建路径,两者都是 -1(相当于大家约定好了),那当然能通信拉。但更多的进程出现,则会有问题。
一定要检查返回值
依然依靠key,但是api 实在是太挫了。P&V *** 作都是 semop (posix 的 ipc跟为简洁)
POSIX 共享内存当然也需要一个名字,但并不是路径。
无论读进程还是写进程,都需要传入相同的名字。
如果是unbuntu 会在以下路径生成文件
其实 2和3 是1 的符号链接。 只要保证是一个就能互相通信
关键点,mmap 内存的属性修改为 private 后,产生写时copy,虚拟地址一样,但是物理地址已经不同了
当然 如果子进程修改了程序背景,执行了 exec,那么完全不一样了,直接修改了内存逻辑。
以上就是关于Linux的内核空间和用户空间是如何划分的(以32位系统为例)全部的内容,包括:Linux的内核空间和用户空间是如何划分的(以32位系统为例)、LINUX内核空间与用户空间分别是什么意思、为什么要把内存划分为用户空间与内核空间等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)