关于Unix根本强大的缘由:linux
正由于以上策略和机制分离的设计理念,确保了Unix系统具有清晰的层次化结构git
现在的Unix已发展成:编程
一个支持抢占式多任务,多线程,虚拟内存,换页,动态连接和TCP/IP网络的现代化操做系统
Linux并无抛弃Unix的设计目标并保证了应用程序编程接口的一致。服务器
关于操做系统和内核网络
1)操做系统是值在整个系统中负责完成最近本功能和操做系统管理的那些部分。多线程
2)系统包含了操做系统和全部运行在她之上的应用程序。并发
3)内核有时候被称为管理者和操做核心。
一般由:异步
负责响应中断的中断服务程序 负责管理多个进程从而分享处理器时间的调度程序 负责管理进程地址空间的内存管理程序 网络、进程间通讯等系统服务程序
共同组成。分布式
系统中运行的应用程序经过系统调用来与内核通讯。模块化
这种交互关系——应用程序经过系统调用界面陷入内核——是应用程序完成其工做的基本行为方式。
内核负责管理系统的硬件设备:
当硬件设备想和系统通讯时,先发出一个异步中断信号去打断处理器的执行,继而打断内核的执行。
中断一般对应着一个中断号,内核经过这个中断号来查找相应的中断服务程序,并调用这个程序响应和处理中断。
许多系统的中断服务程序(包括Linux)都不在进程上下文中执行。它们在一个与进程无关的 专门的中断上下文中运行。——为了保证中断服务可以在第一时间响应和处理中断请求,而后快速退出。
LInux内核与Unix内核的比较
Unix内核几乎毫无例外的都是一个不可分割的静态可执行库。
Unix内核一般须要硬件系统提供页机制(MMU)以管理内存。
关于页机制(MMU),它能够增强对内存空间的保护,并保证每一个进程均可以运行不一样的虚地址空间上。
操做系统可分:单内核和微内核
单内核(Linux就是):
从总体上做为一个单独的大过程来实现,同时也运行一个单独的地址空间上。——简单,性能高
微内核:
被分红多个独立的进程,每一个过程叫作一个服务器。理想状态下只有特权服务的服务器才运行在特权模式下,其余服务器都运行在用户空间。(不过全部服务器都保持独立并运行在各自的地址空间上) 所以——须要经过消息传递处理内核通讯:系统采用进程间通讯(IPC)机制(服务器的各自独立有效的避免了一个服务器的失效祸及另外一个) 一样,模块化的系统容许一个服务器为了另外一个服务器换出
IPC机制开销多用于函数调用,又因用户空间的上下文切换,消息传递须要必定的周期。
Lnux内核与Unix内核的显著差别:
关于Linux的内核版本:
命名机制:用三个或四个点分隔的数字来表明不一样的内核版本:
第一个数字是主版本号,第二个数字是从版本号,第三数字是修订版本号,第四个数字为稳定版本号:副版本号数字为偶数,则为稳定版,若是是奇数,就是开发版。
获取Linux内核官网http://www.kernel.org
使用Git管理Linux内核源代码,Git是分布式的。
保持与内核官方代码一致:
获取最新提交到linus版本树的一个副本:
$ git clone git://git.kernel.org/pub/scm/Linux/kernel/git/torvarlds/linux-2.6.git
更新分支:
$ git pull
解压源代码:
1)压缩形式bzip2
$ tar xvjf linux-x.y.z.tar.bz2
2) 压缩形式GNU的zip:
$ tar xvzf linux.x.y.z.tar.gz
(若是是使用git,不须要下载压缩文件)
*不要以root身份对内核进行修改,而应该创建本身的主目录,仅以root身份安装新内核
打补丁的方法(一个给定版本的内核补丁老是打在前一个版本上):
$ patch -p1 < ../patch-x.y.z
编译内核
1)配置内核
这些配置有
二选一:是否开启 三选一:yes(代码编译进主内核映像,而不是做为一个模块),no,module(配置被选定)
*驱动程序通常都是三选一的配置选项。
配置选项也能够是字符串或者整数。这些选项并不控制编译过程,而只是指定内核源码能够访问的值,通常以预处理宏的形式表示。
简化内核配置命令行工具:
1)逐一配置,不推荐
$ make config
2)基于ncurse库编制的图形界面工具:
$ make menucofig
3)gtk+图形工具
$ make gconfig
这三种工具将全部配置分门别类放置。
这条命令会基于默认的配置为你的体系结构建立一个配置:
$ make deconfig
这些配置选项会被存放在内核代码树根目录下.config文件中。
在修改配置文件后或者在用配置文件配置新的代码树的时候,应该更新和验证:
$ make oldconfig
配置选项CONFIG_IKCONFIG_PROC把完整的压缩过的内核配置文件存放在/proc/config.gz——方便克隆当前的配置,启用此选项后,能够从/proc下复制出配置文件并用来编译一个新内核:
$ zcat /proc/config.gz > .config $ make oldconfig
配置好后进行:
make
减小编译垃圾的方法
1)尽可能少地看到垃圾信息,不但愿错过错误报告或警告信息
$ make > .. /detritus
2)把无用输出信息重定向到永无返回值的黑洞/dev/null
衍生多个编译做业
多个做业编译内核:
$ make -jn(n是要衍生出的做业数)
安装新内核
必定要保证随时有一个两个启动的内核,以防新编译的内核出现问题。
模块的安装时自动的,也是独立于体系结构的
以root身份运行:
% make modules_intsall
编译时会在内核树的根目录下建立System.map文件。是一份符号对照表,用以将内核符号和它们的起始地址对应起来。调试的时候,若是须要内存地址翻译成容易理解的函数名以及变量名,这会颇有用。
内核开发的独特之处
1)无libc库或无标准头文件
内核不能链接使用标准C函数库
体系结构相关的头文件集中在内核源代码树的arch/
*printf和printk之间的一个显著区别在于:
printk容许你经过一个指定一个标志来设置优先级。syslogd会根据这个优先级来决定在什么地方显示这条系统信息。
1)内核函数
inline函数会在它调用的位置上展开(这么作会消除函数调用和返回锁带来的开销)。
定义一个内核函数的时候,须要使用static做为关键字,并用inline限定它。
2)内核汇编
linux的内核混合使用了c语言和汇编语言,在偏近体系结构的底层或对执行时间严格要求严格的地方,通常使用的是汇编语言。
3)分支声明
条件选择语句:
if(error){ /*...*/ }
绝少发生的分支:
/*咱们认为error绝大多数时间都会为0*/ if(unlikely(error)){ /*...*/ }
一般为真的分支:
/*咱们认为success绝大多数时间都会为0*/ if(likely(success)){ /*...*/ }
内核中很容易产生竞争,要保证不出现竞争的时候: