linux 用户空间?centos创建用户

Linux的内核空间和用户空间是如何划分的(以32位系统为例)

通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。地址分配如下图所示

内核地址空间分布

直接映射区:线性空间中从3G开始最大896M的区间,为直接内存映射区,该区域的线性地址和物理地址存在线性转换关系:线性地址=3G+物理地址。

动态内存映射区:该区域由内核函数vmalloc来分配,特点是:线性空间连续,但是对应的物理空间不一定连续。vmalloc分配的线性地址所对应的物理页可能处于低端内存,也可能处于高端内存。

永久内存映射区:该区域可访问高端内存。访问方法是使用alloc_page(_GFP_HIGHMEM)分配高端内存页或者使用kmap函数将分配到的高端内存映射到该区域。

固定映射区:该区域和4G的顶端只有4k的隔离带,其每个地址项都服务于特定的用途,如ACPI_BASE等。

linux用户空间内存原则

在用户空间中动态申请内存的函数为malloc(),这个函数在各种操作系统上的使用都是一致的,malloc()申请的内存的释放函数为free()。对于Linux而言,C库的malloc()函数一般通过brk()和mmap()两个系统调用从内核申请内存。由于用户空间C库的malloc算法实际上具备一个二次管理能力,所以并不是每次申请和释放内存都一定伴随着对内核的系统调用。如,应用程序可以从内核拿到内存后,立即调用free(),由于free()之前调用了mallopt(M_TRIM_THRESHOLD,一1)和mallopt(M_MMAP_MAX,0),这个free()并不会把内存还给内核,而只是还给了C库的分配算法(内存仍然属于这个进程),因此之后所有的动态内存申请和释放都在用户态下进行。另外,Linux内核总是采用按需调页(Demand Paging),因此当malloc()返回的时候,虽然是成功返回,但是内核并没有真正给这个进程内存,这个时候如果去读申请的内存,内容全部是0,这个页面的映射是只读的。只有当写到某个页面的时候,内核才在页错误后,真正把这个页面给这个进程。在Linux内核空间中申请内存涉及的函数主要包括kmalloc()、get free pages()和vmalloc()等。kmalloc()和_get_free pages()(及其类似函数)申请的内存位于DMA和常规区域的映射区,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在较简单的转换关系。而vmalloc()在虚拟内存空间给出一块连续的内存区,实质上,这片连续的虚拟内存在物理内存中并不一定连续,而vmalloc()申请的虚拟内存和物理内存之间也没有简单的换算关系。

linux内存管理之用户空间与内核空间详解

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

Linux内核使用段页式地址映射模型,进程代码中的地址为逻辑地址,通过段页式映射后,才能真正访问物理内存。

Linux内核地址空间通常分为用户空间和内核空间,其中用户空间范围为0~3G,内核空间范围为3~4G。注意,这里指的是32位Linux内核的地址空间划分,64位内核的地址空间划分有所不同。

内核空间的高端内存概念源于物理内存的限制。当内核模块代码或线程访问内存时,逻辑地址需要一对一映射到物理内存地址。例如,逻辑地址0xc0000003对应物理地址0×3,以此类推。如果内核逻辑地址空间为0xc0000000~0xffffffff,那么物理内存范围只能访问0×0~0×40000000,即最多访问1G物理内存。若安装8G物理内存,内核只能访问前1G内存,后面的7G内存无法访问。

为了解决这个问题,x86架构将内核地址空间划分为三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_HIGHMEM即为高端内存区域,它是内存高端内存概念的来源。

在x86结构中,内核地址空间分为如下三部分:

ZONE_DMA:内存开始的16MB

ZONE_NORMAL:从16MB到896MB

ZONE_HIGHMEM:从896MB至结束

Linux内核高端内存的理解在于,通过将高端内存划分为特定区域,如ZONE_HIGHMEM,允许内核使用有限的地址空间访问所有物理内存。当内核想访问超过896MB的物理内存时,它可以在高端内存区域找到相应的空闲逻辑地址空间,借用一段时间来映射到物理内存,完成访问后释放这段逻辑地址空间,以便其他进程或代码使用。

例如,内核想要访问从物理地址0×80000000开始的1MB内存,可以找到一段1MB大小的空闲逻辑地址空间,借用一段时间进行映射,完成访问后释放这段逻辑地址空间。

高端内存的基本思想是借用一段地址空间建立临时映射,用完后释放,实现循环使用,从而访问所有物理内存。

在Linux内核管理中,高端内存的使用涉及到复杂的地址映射和释放机制。为了支持高端内存,内核将内存划分为VMALLOC_START~VMALLOC_END、KMAP_BASE~FIXADDR_START和FIXADDR_START~4G等部分。对于高端内存的映射,有三种方式:映射到“内核动态映射空间”、持久内核映射和临时映射。

通过使用这些映射方式,Linux内核能够高效地管理高端内存,实现访问所有物理内存的功能。当进程或内核模块占用逻辑地址空间不释放时,系统会提醒释放,以避免内存资源的浪费。

综上所述,Linux内存管理中的用户空间与内核空间通过虚拟内存机制和地址映射模型实现隔离,内核使用特定的地址空间和映射技术访问所有物理内存,而用户进程则受限于用户空间。这种设计保证了系统的稳定性和安全性,同时也支持了多进程和多任务的高效运行。

阅读剩余
THE END