优秀的编程知识分享平台

网站首页 > 技术文章 正文

人间还是仙界?聊一聊linux系统的用户空间和内核空间

nanyue 2024-11-10 10:17:51 技术文章 1 ℃

关注”技术简说“,带你由浅入深学习linux内核源码。linux内核开发100讲免费教程,每周二、周四晚上9点更新视频,每周一、周三晚9点更新文章,敬请收看。进我主页点”视频“栏目即可观看。

我们生活在人间,但《西游记》里提到,在天上还有一个仙界。

人间不知道仙界的存在;而仙界知道人间的存在,神仙也可以从仙界下凡到人间,但是被严格管控的。

软件设计的灵感其实都来自于生活:用户空间就等同于我们理解的人间;而内核空间就等同于所谓的仙界。

人间在地上,仙界在天上,地理上是隔离的。

linux内核里的用户空间和内核空间也是一样。


以32位linux系统为例:

用户空间地址范围:0x00000000~0xBFFFFFFF,大小3G

内核空间地址范围:0xC0000000~0xFFFFFFFF,大小1G

有小伙伴问了,你这个地址是啥地址啊,是逻辑地址、虚拟地址、线性地址、还是物理地址咩?

当然是虚拟地址了。

  • 在intel x86下,逻辑地址,是由一个段标识符加上一个指定段内的相对地址的偏移量(offset)组成,表示为 [段标识符:段内偏移量],例如:[cs:eip]
  • 虚拟地址其实就是上述组成逻辑地址的段内偏移offset
  • 而线性地址,则是由逻辑地址经过一系列转换得到的,具体来讲就是: 线性地址=段描述符所在段的基地址+offset
  • 而物理地址,则是真正的物理内存的地址。

那么问题来了,linux内核为什么要特意划分内核空间和用户空间呢?有以下几方面的原因:

1.安全考量

整个系统中有各种资源,比如计算资源、内存资源和外设资源。而linux是多用户、多进程系统。所以,这些资源必须在受限的、被管理的状态下使用,要不然就陷入了混乱。空间隔离可以保证即便是单个应用程序出现错误也不会影响到操作系统的稳定性。

2.处理器模式不同,权限不同

前面说到内核空间代码要管理各种底层的资源,而用户空间代码更多是实现业务逻辑的。所以内核空间和用户空间代码运行时的处理器模式是不同的。

对于x86体系的cpu, 用户空间代码运行在Ring3模式(用户模式),内核空间代码运行Ring 0模式(特权模式);

对于arm体系的cpu,用户空间代码运行在usr模式(用户模式),内核空间代码运行在svc模式(特权模式);

用户模式只能正常执行程序,而特权模式才能访问外设、处理中断等。

3.核心代码和业务代码的解耦

我们在设计应用系统的时候会考虑耦合性,内核集中了这么多人的智慧,难道它们不会考虑到这一点吗?

内核代码偏重于系统和资源管理;而用户空间代码(也即应用程序)偏重于业务逻辑代码的实现。

两者分工不同,隔离也是解耦。


现在的linux系统基本都是64位的。所以,我们再稍微介绍下64位系统的内核空间和用户空间的地址分布:

64位系统的地址线有64位,但是在具体实现上,并没有使用这么多,一般来说,48位的地址线就够了。所以在这样的系统中,比如armv8-A,高64TB是内核空间,低64TB是用户空间,发现规律了没有?内核空间的的高16位都是1,用户空间的低16位都是0,这样可以方便的对用户空间和内核空间进行有效性检测,防止越界。


总结一下下:

32位linux系统的整个虚拟地址空间最大为4G,这4G的虚拟地址空间,高1G(也就是0xC0000000~0xFFFFFFFF)属于内核空间;低3G(也就是0x00000000~0xBFFFFFFF)属于用户空间,linux系统中的所有进程共用这3G的虚拟地址空间。

你说了什么?

共用?如何共用?

所有的进程共用这3G的虚拟地址空间该如何理解呢?

预知后事如何,请看下回分解。

关注”技术简说“,带你由浅入深学习linux内核源码。linux内核开发100讲免费教程,每周二、周四晚上9点更新视频,每周一、周三晚9点更新文章,敬请收看。进我主页点”视频“栏目即可观看。

Tags:

最近发表
标签列表