您的位置:首页 > 运维架构 > Linux

『阿男的Linux内核世界』*12 Kernel Space和User Space*

2017-01-06 00:00 176 查看
『阿男的Linux内核世界』*12 Kernel Space和User Space*

阿男在这篇文章里面给大家讲讲Linux的Kernel Space和User Space。我们知道,Linux操作系统和早期的Windows系统相比起来,最大的特色就是「基本上不会死机」。

稍微年龄比较大的计算机用户,都会知道DOS和早期的Windows操作系统是有多容易死机。所谓死机,就是系统完全失去响应,只能通过重新启动计算机来达到重启操作系统的效果。这其实很大程度上就是因为操作系统和运行在上面的程序没有很好地分离造成的。

早期的操作系统,会把计算机的所有硬件资源交给运行在上面的程序,因此应用程序如果有bug,那么应用程序失去响应就意味着整个计算机失去响应了,这个时候操作系统是没办法从应用程序手里要回操作权的。

而Linux操作系统从一开始的设计就是把内核和运行在上面的程序给分隔开。我们之前学了一些Process的相关知识,知道了其实每一个Process都运行在一个操作系统提供给它的虚拟资源里面:每一个Process都拥有一摸一样的内存空间,每一个Process也都觉得自己独占CPU资源。而实际上这个虚拟的内存模型是Kernel提供的,真正和物理内存打交道是Kernel的事情。另一方面,每一个程序也并没有独占CPU资源,Kernel会用scheduler来按一定顺序轮流执行各个Process,而不是只把资源交给一个Process。

因为Kernel对Process有绝对的控制和管理权,所以并不会发生Process的bug导致「死机」的情况出现,因为我们总是可以强行kill掉某一个不响应的Process。

因此,Kernel Space的编码要远比User Space的编码难度高得多,因为我们是和实际的计算机硬件打交道,一个不小心就可能造成系统级别的死机,这也是为什么Linus至今要掌握着Kernel的commit审核以及合并权限。因为很多新手可能会给内核贡献危险的代码,导致Kernel的崩溃;或者是把危险的接口暴露到User Space,这样一个User Space的程序就可能真的会导致Kernel的崩溃,这些都是操作系统级别不能忍的事情。

有的时候Linus的火气很大,但是也可以理解,作为掌管着这么重要代码的人,有的时候看到会导致内核出问题的代码真的会很生气。

我们需要知道,我们日常使用的C语言里面的各种函数,最终都是调用操作系统的system call来完成的。也就是说,libc库是User Space的,有些事情注定它的能力有限,毕竟Kernel才是掌管着真正硬件资源的层面。

所以新手经常会问,为什么我不能在kernel代码里使用
printf
?其实
printf
是libc提供的,通过调用kernel里面的system call来实现的功能,kernel是给
printf
提供功能的层面,要比
libc
低一层,自然用不了
libc
里面的东西。

还有就是Linux里面的代码必须要考虑硬件中断的问题。在User Space,程序所使用的资源都是Kernel管理下的「虚拟」资源,所以不用担心程序会被一些硬件中断意外打断的情况。除非我们特意编写跟信号和中断相关的代码,否则是不用考虑这些问题的。但Kernel就不同,因为它是和真正的硬件资源打交道,所以就必须考虑各种硬件中断的问题,程序的执行会不会被打断,要不要使用CPU提供的开中断和关中断功能等等,这些都要考虑。

最后还有指令集的范围,拿Intel的CPU指令集为例,有好多指令是交给Kernel使用,不提供给User Space的程序的,比如
CLI/STI
HLT
这些和中断相关的指令。还有一些寄存器也是User Space的程序访问不到的,比如保存
IDT
,interrupte table,这种信息的寄存器。这些在Intel的官方CPU手册里面都有说明,阿男后续再位大家介绍。像这些资源,User Space的program是访问不到的。

关于Kernel Space和User Space,就先讲这么多吧,阿男后续会为大家详细展开来讲解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息