为什么需要用户空间和内核空间?
在解释之前,先举一个在我们的日常生活中很常见的一个例子,比如学校中的学生管理系统,学生只能查看自己的学习成绩,不能修改。而老师可以修改学生的成绩(当然有一定的限制,在这里只是举一个例子),但是老师不能删除别的老师的信息,而管理员可以。如果学生可以自己修改自己的成绩,那还不乱套了。如果老师可以添加别的老师,那还要管理员干啥。每一个角色有各自对应的使用权限。管理员级别最高,学生级别最低。都不能越过自己的权限,如果越过了,那么整个系统就乱了。
image.png
而linux系统一样与其一样, 在linux中,为了保护系统能够正常、稳定的运行,更好的保护内核中的内容(内核空间中有许多重要的内容,比如各种体系机构的代码、各种驱动代码,各种文件系统等。内核是系统的核心如果内核空间崩溃,那么整个系统就崩溃了)。linux系统的开发者不能保证每一个应用开发者都能很好的使用系统,也不能保证每一个应用编程人员的能力很高,因此将程序的运行空间分为用户空间和内核空间,也就是常见的用户态和内核态。他们运行在不同的级别,用户态不准直接访问内核空间中的内容,但是可以通过系统调用接口访问。在进行系统调用时,程序从用户空间进入到内核空间,在内核空间完成相应功能后再返回到用户空间。
那么既然有用户空间和内核空间,那么之间如何通信以及所占的空间又是多少?
用户空间与内核空间通信接口
在用户空间向内核空间发数据以及读取内核空间返回的数据常用的函数为read 、write ,在内核空间向用户空间返回/接收用户空间数据常用的接口为copy_to_user、copy_from_user。在Linux应用编程中read 、write非常有用,通过这个接口可以对硬件发送数据以及接收数据。在linux驱动编程中copy_to_user、copy_from_user很常用。
用户空间和内核空间地址
1)简单来说,在32位linux操作系统中,总的地址空间为4G。其中0-3G是用户空间使用,3-4G是内核空间使用,也就是用户空间和内核空间与运行在不同的地址空间,也就保证了系统的稳定性。如下图所示:
image.png
2)其实用户空间的3G空间并不是都能使用,只是理论上有这么多。我们都知道在编写C语言代码时,有些数据是存放在栈上,有些是存放在堆上、只读数据段、静态存储区等区域。如上图所示。这些栈、堆、只读数据段、静态存储区空间大小都是一定的,如果在使用时超过了它们的大小就会出错。操作系统中的内存管理器来管理这些区域。比如0地址空间就不能使用。我们在定义指针变量时通常对指针初始化为NULL,如果我们要访问这个指针变量指向的值就会出现segment fault段错误。原因就是我们访问了不改访问的内存空间。其实操作系统中的0地址是受保护的,别的程序不能随意进行访问。
后续继续更新...