linux内核的一些知识点(中)

系统调用

内核为用户进程提供的交互接口,能够为用户进程提供受限制地访问硬件设备、申请操做系统资源以及建立进程和进程通讯等能力。linux中的每一个系统调用都对应一个系统调用号,调用号用于指明具体哪一个系统调用。linux

  • 系统调用既为应用程序提供了请求接口,又保证了系统的安全和稳定。用户空间的程序不能直接访问内核代码,内核代码驻留在受保护的内存地址中,用户进程没法访问这块内存。
  • 系统调用在用户进程和硬件设备之间增长一层,屏蔽了硬件的复杂操做,从而让应用层的使用更加便捷。

应用编程接口API

实际上应用程序通常会使用用户空间实现的应用编程接口来间接调用系统调用,API能够经过一个或若干个系统调用来实现一个接口,并且能屏蔽不一样操做系统的差别,为应用程序提供相同的接口,好比经常使用的C库。此外,POSIX标注给出了API和系统调用之间的关系,不一样的操做系统提供与POSIX兼容的库就能让应用程序实现统一的接口。算法

对硬件的管理

操做系统内核的核心任务包括对计算机扩展的硬件进行管理,好比硬盘、键盘、鼠标及其余扩展硬件。内核必需要可以与它们互相通讯,但通讯过程有个很关键的问题须要关注,就是速度问题。CPU的速度很是快,但向硬件发起一个请求并接到其响应的速度是至关慢的,如何有效让它们协同工做是硬件管理的核心问题,由于这个问题极可能会严重影响总体性能。编程

有两种实现方:轮询机制和中断机制。轮询机制是让内核按期对硬件设备进行查询,看是否须要处理,若是须要则处理,这种状况可能会让内核作不少无用功。中断机制则反过来,让硬件主动来发送信号,当硬件有事件发生时则向内核发出信号,而后内核再介入处理。内核通常也是使用中断机制来管理硬件。缓存

关于中断

中断机制让硬件能发通知给CPU,中断本质是一个特殊的电信号,处理器接收到中断后会立刻告知内核。好比点击下鼠标时鼠标控制器就会发送一个中断通知,处理器一旦检测到中断信号便中断本身当前的工做转而处理中断,而后通知操做系统鼠标产生了中断,内核得知鼠标被按下了,而后内核负责处理事件。安全

不一样设备的中断不一样,经过一个惟一的数字做为标识,也就是鼠标、键盘、硬盘的中断值都不一样,操做系统对不一样的中断进行处理。中断值也称中断请求线(IRQ),每一个IRQ都对应一个数值,好比PC上0位时钟中断、1位键盘中断。固然,也多是动态分配中断值。网络

中断由硬件打断操做系统,为硬件与操做系统提供了通讯机制。数据结构

中断处理程序

内核在响应每一个特定的中断时都会执行指定的一个函数,该函数为中断处理程序。每一个硬件有一个相应的中断处理程序,他属于设备驱动的一部分。在linux中,中断处理程序是一个C函数,这些C函数按照必定的类型声明,而后内核就能够以标准的方式调用。中断处理程序被内核调用来响应中断,它们运行在中断上下文中,在该上下文中执行的代码不可以阻塞。机器学习

中断信号随时可能发生,因此中断处理程序随时可能被运行,必须保证它快速被执行,才能快速恢复中断代码的执行。理想状态是中断能快速被响应,并且中断处理程序能快速被执行完。但中断程序要处理的工做每每有不少,好比对于网络而言,中断处理程序要将网卡的数据包拷贝获得内存中,并且还要对其进行处理后才交给合适的协议栈,最终再告知硬件已处理中断信号。异步

中断的上半部和下半部

咱们想要快速的中断响应,同时又想要在中断处理程序中完成更多的工做,这是一个矛盾体。为了解决这个问题,中断处理被分为上半部和下半部。上半部用于执行有严格时限的工做,好比应答硬件。而下半部用于处理可以延后处理的工做。上半部和下半部其实就是一种异步化处理思想,这样既可以保证响应速度,又可以完成大工做量的处理。分布式

对于网卡来讲,它的缓存大小是固定的,一旦网卡接收到数据后内核必须立刻将它们拷贝到内存中,否则将可能致使网卡的缓存爆满而数据包被丢失。鉴于这种状况,对于网卡的中断信号处理应该快速将网卡数据包拷贝到内存中,这就是上半部的工做,快速执行完后立刻结束中断处理,将处理器交还给中断前的程序。而耗时的数据包处理操做则放到下半部中,这部分能够稍后一点再处理,没有很强的时效性。

每一个设备都有本身的驱动程序,驱动程序能够经过request_irq()函数来注册中断处理程序。

中断上下文

中断上下文是指内核在执行一个中断处理程序时所处的上下文,在该上下文中不能睡眠,也不能调用某些函数。中断处理程序时打断了其它正在执行的代码,因此它必需要快速简洁地执行完毕,中断处理程序有本身的栈。

linux中断过程

硬件产生了一个中断信号,它经过总线将电信号发送给中断控制器,中断控制器会将中断信号发往处理器。处理器会当即中止正在作的事情,而后关闭中断系统并跳到预约义的位置开始执行代码,这个预约义的代码就是由内核设置的中断处理程序入口。对于每一个中断线,处理器都会跳转到对应一个惟一的入口位置。内核执行do_IRQ()函数对所接收到的中断进行响应。

系统定时器

内核大量函数都是基于时间驱动的,好比有些函数周期性地执行,这些就须要定时器来支持。系统定时器是一种可编程硬件芯片,它以固定频率产生中断,即定时器中断,它对应的中断处理程序负责更新系统时间,同时也负责执行周期性任务。定时器和时钟中断处理程序是linux内核管理机制的中枢。

定时器是管理内核流逝时间的基础,使用定时器时设置一个超时时间,而且指定超时发生时执行的函数。当定时器到时时会自动执行该函数,该函数只运行一次。

内核的时间

内核须要在硬件的帮助下才能计算和管理时间,硬件提供了系统定时器给内核来计算流逝的时间,当时钟中断发生时内核的特定中断处理程序会对其进行处理。定时器以某种频率自行触发时间中断,这个频率成为节拍率,连续两次时间中断的间隔时间为节拍。内核经过已知的节拍来计算墙上时间和系统运行时间,墙上时间便是实际时间,系统运行时间为自系统启动后开始的时间。内核也为用户空间提供了一组获取实际时间和日期的系统调用。

实时时钟

实时时钟(RTC)是用来持久存放系统时间的设备,它能够靠主板上的微型电池保持系统的计时,因此即便系统关闭了也能保持系统时间的计时。实时时钟和CMOS集成在一块儿,实时时钟与BIOS的保存设置都是经过同一个电池供电。系统启动时内核读取实时时钟来初始化墙上时间,该时间对应的变量为xtime。

基于时间的内核管理

内核不少工做都依赖于时钟中断,好比:

  • 系统运行时间的更新工做。
  • 实际时间的更新工做。
  • 在SMP结构中,均衡调度程序中运行队列的均衡工做。
  • 判断当前进程是否使用完了本身的时间片,调度工做。
  • 执行动态定时器。
  • 处理器时间的统计工做。

关于节拍率

系统定时器的节拍率提供给静态预处理定义,单位为HZ,内核再asm/param.h文件中定义。x86体系中系统定时器频率默认值为100,因此时钟中断评论为100HZ,每秒进行时钟中断100次,每10ms产生一次。不一样的体系结构节拍率可能不一样。

更高的节拍率能提供时间驱动时间的解析度,同时也提升时间驱动事件的准确度。对于linux来讲能提供更高的精度来执行poll()、select()等系统调用,也能提升进程抢占的准确度。但高节拍率会增长系统负担,由于会更加频繁地执行时钟中断处理程序,增长了电源的消耗。

jiffies

jiffies是一个全局变量,它用来记录自系统启动以来产生的节拍总数。启动时为0,而后每次时钟中断都会增长改变了的值,每秒增量为节拍率,即n赫兹。时钟中断处理程序工做大体包括:

  • 得到xtime_lock锁,对jiffies_64和墙上时间xtime进行保护。
  • 应答系统时钟。
  • 使用墙上时间更新实时时钟。
  • 累加jiffies_64。
  • 更新当前进程消耗的系统时间和用户时间。
  • 执行已到期的定时器。
  • 计算平均负载。

专一于人工智能、读书与感想、聊聊数学、计算机科学、分布式、机器学习、深度学习、天然语言处理、算法与数据结构、Java深度、Tomcat内核等。

相关文章
相关标签/搜索