`
xitong
  • 浏览: 6203877 次
文章分类
社区版块
存档分类
最新评论

Linux必备的内核知识

 
阅读更多

用户模式和内核模式

执行进程的模式有两种:用户模式和内核模式。你编写的代码和执行所链接的库运行在用户模式下。需要内核服务时执行的内核代码只能在内核模式下运行。这是为了安全性考虑,用户模式可以确保一个进程只能访问自己的内存空间,如果破坏了自己内部结构,它也只能影响到自己,而不涉及其它的进程,更不会影响到整个系统。在用户模式下,进程能访问的内存称为用户空间

内核需要维护数据结构以控制系统中每个进程,它提供了一个所有进程共享的内存区域,为了保证安全性,内核代码和数据结构必须严格独立于用户代码和数据,只有内存代码可以在内核模式下运行,访问的共享内核数据以及执行权限指令。把进程在内核模式下访问的内存区域叫做内核空间。内核空间只有一个,在内核模式下的进程才能访问,但是内核空间是每个进程所特有的。

典型的32环境下的虚拟地址(3G/1G分配方式):

0xFFFFFFFF

Linux内核 内核空间(内存1G)

0xC0000000

0xBFFFFFFFF

进程A|B|C 用户空间(内存3G)

0x00000000

系统调用

进程通过系统调用进入和退出内核模式,许多POSIX函数是系统调用的简单封装,如open,close,ictol,write和read等。驱动设备只能在内核模式下执行,应用程序不能直接调用设备驱动程序,而是使用预定义的系统调用间接的访问驱动程序代码。

下面是系统调用read的一个例子:

#include <syscall.h>

….

n = syscall(SYS_read, fd, buffer, length)

Linux提供的系统调用列表由内核版本决定,并且不随时间变化而变化。然而,用于创建系统调用的机制却会因为不同处理器体系结构而不同。系统调用函数是一个用于创建系统调用的汇编代码的封装。命令strace对于追踪系统调用非常有用,因为利用它可以知道当前任务执行的情况。

通常用户代码先将参数压入堆栈或者保存在预定义的寄存器中,然后在使用中断调用系统调用处理器。中断处理器将进程转入到内核模式,并调用适当的系统调用。在内核模式下,它从寄存器中读取参数或使用特定的函数从用户空间复制参数。可移植程序不能直接使用系统调用,而是依赖库为其实现系统调用。系统调用随着操作系统版本变化而变化,库的调用则无需这些变化。

Linux使用syscall技术称为应用程序二进制接口(ABI),它并不是Linux所独有的。该技术可以用于其它操作系统,甚至是BOIS系统。它与API是不同的,API要求链接兼容的函数,而ABI步要求链接步需要运行的代码。这是可执行程序无需重建就可以在许多不同内核中运行的原因之一。一个运行在2.2内核下的静态链接的可执行程序可能在2.6内核下仍然可以运行,因为大多数常见的系统调用接口从不会变化。

用户空间和内核空间的数据传递

用户模式下的内核空间是不可见的,当访问用户空间时,内核模式也必须格外注意。因此,通过系统调用传送数据非常的麻烦。虽然简单的参数可以通过寄存器传递,但是大型的内存必须通过复制,导致效率相当的低下。一些系统调用(read/write)需要在用户模式和内核模式之间传递大量数据,虽然这些额外的复制作用不大,但是它能维持内核空间和用户空间的相对独立。

虽然复制在短期看来会降低程序的性能,但从长远来看它有助于性能的提高,例如文件系统高速缓存,当数据写入文件时,数据被写入磁盘之前会先写入到内核空间,所以write这个动作可以在后台完成,应用程序可以通过flush来刷新用户空间的缓冲,使得程序继续执行。

进程调度程序

解决多任务操作系统问题的算法叫做程序调度(Scheduler),Linux内核提供多种调度算法,并且允许用户在系统安装时选择合适的调度算法。

调度程序的调用通常嵌入到系统调用中,并在进程需要等待事件时发生。一个与设备进行大量通信的进程会经常调用调度程序,由于设备的速度很慢,进程的大部分运行时间都浪费在等待过程中,这样运行时不会耗费太多的CPU时间。

注:何为协同多任务处理(Cooperativer multitasking)

一个进程若不进行I/O,那就会占用大量的CPU时间,从而使得其它进程无法使用CPU,此时需要采用抢占式任务处理(Preemptive multitasking)。

每个Linux进程都有一个执行时间片或quantum,当一个进程因为时间片使用完被内核停止执行时,这个进程被抢占,如果有一个享有更高优先级的进程在就绪队列中,内核同样可以抢占正在执行的进程。一个进程也可以自动放弃CPU,可以通过sched_yield系统调用来放弃CPU。也可以通过其它系统调用(sleep)来实现对CPU的放弃。当进程在内核模式下等待一个事件时,称为阻塞(blocking)。一个阻塞进程既不会占用CPU,也不会被调度程序使用。

所有抢占式多任务处理操作系统都实现了按优先级调度策略。高优先权的进程总是比低优先级的进程先被调度。虽然用户可以影响进程的优先级,但进程的优先级最终还是由内核决定。Linux内核通过使用动态优先级(Dynamic Priority),不断提高和降低正在运行进程的优先级,从而使得低优先级的进程也能运行。

Linux内核调度策略一个重要目的是保证所有进程都有机会被调度,也就是说每个任务都有相应的使用CPU的时间。进程的有效优先级就是静态优先级和额外值之和,这个额外值可正可负。

ps命令选项中-C显示进程与参数的配对项,如-C <proc_name>,-o用于控制输出的格式,如etime,pid,pri,cmd。

内核允许用户通过使用一个名为nice的数值来影响调度程序关于优先级的调度。正的nice可以降低优先级,负的nice可以提高优先级。请查看ice和renice命令。

实时优先权

响应时间是指软件响应外部事件的时间,比如中断。严格的响应时间的应用程序通常被称为实时应用程序。Linux中实时进程的优先级范围是41-139,实时优先级越大,优先级越高。实时优先级在整个生命周期中值是不变的。

在设计实时进程时,必须确定它的调度策略,POSIX为实时进程指定了两种策略:先进先出(FIFO)和时间片法(round robin)。

创建实时进程的方法就是使用chrt命令,chrt在内部调用fork和exec和POSIX函数来设置优先级,函数如下:

int sched_setscheduler(pid_t pid, int policy, const struct sched_param*p);

int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param*p);

int sched_get_priority_min/max(int policy);

第一个为进程服务,第二个为线程服务。

# sodu chrt --fifo 50 ./chewer &

进程状态

在进程的生命周期中,进程经历几种不同的状态,使用ps命令或cat /proc文件系统查看,进程状态如下:

R-运行或将要运行

S-被中断等待一个事件,可能会被一个信号激活

D-被中断等待一个事件,不会被信号激活

T-由于任务的控制或者外部追踪而被终止,比如ptrace

Z-僵死,但是它的父进程没有调用wait函数。

一个进程处于不可中断状态是一件危险的事情,只能重启计算机来修补。

当一个进程退出时并不完全小时,而是等到父进程发出wait系统调用才会完全消失,否则一直会处于僵死状态,等待它的父进程终止它。僵死进程步占用内存和进程资源,但是可以铜鼓ps命令显示出来,它被init收养(adopted),init进程会定期的调用wait命令来回收这些未被撤销的进程。

内核能追踪每个进程的运行时间,内核记录每个进程分别用在用户空间和内核空间的时间,命令time很有用。如果进程在用户空间耗费太多时间,就不能抱怨内核。造成这样的结果可能是代码或者连接的库函数问题,而不是内核的原因。用strace来跟踪为何会在系统调用上耗费太多的时间的问题。如果代码因为设备阻塞或者系统调用而运行太慢,几乎没有什么方法可以提高代码的运行速度,最好避免做那些调用,也可以试一试对应用程序采用线程方法或者异步I/O操作。

Linux内核时钟标准单位为jiffy,内部时钟有硬件计数器以一定频率产生中断得到,这个频率在内核编译时已经确定,它存储在HZ的宏中。中断频率的提高会增加CPU的使用,加快消耗电池的电量速度。可以使用make memuconfig进行时间频率设置。

使用sysfs的示例:一个用于追踪内部时钟的小模块。

Hz.c:

#include "linux/module.h"

int user_hz = USER_HZ;

int hz = HZ;

module_param(user_hz, int, 0444);

module_param(hz, int, 0444);

Makefile:

all:

make -C /lib/modules/`uname -r`/build M=`pwd` modules

obj-m+=hz.o

编译、安装和查看:

# make

# insmod hz.ko

# cat /sys/module/hz/parameters/user_hz

# cat /sys/module/hz/parameters/hz

Intel的物理地址扩展(PAE)

在电脑上安装的RAM数量不受限制,只是受制于主板上的DIMM数量,处理器可以选址的物理内存数量受限。通常,CPU的字长决定了这个限制,一个32为机器只能存储32位的指针,因此物理地址限制为4GB。

当需要增加DRAM大于4GB的解决办法是转换为64位体系结构,这意味着你的所有应用程序放到一个新的平台上,这是个相当高的解决方案。

Intel公司的Physical Address Extension(PAE)技术允许处理器通过页面地址从20bit扩展到24bit,从而可以寻址64GB的RAM,页面大小可以改变,所以偏移量仍然为12bit,这意味着有效物理地址为36bits。因为逻辑地址必须符合32为寄存器,处理器仍然只能选址4GB的虚拟内存。

MMU和操作系统使用页面地址管理页面,所以分配给缓存或者进程页面时候,操作系统可以随意使用24bits的页面地址,因此,系统可以用的虚拟内存是有效的64GB。

注:pmap命令查看内存分配,# jobs -x pmap %1

内核调试工具:

# mkswap, swapon, swapoff – 用于分区交换的工具

# nice,renice,chrt – 用于影响调度行为的工具

# pmap – 用于显示进程虚拟内存的工具

# ps,time,times – 用于显示进程在用户态和内核态的花费时间

# strace – 用于分析程序进行系统调用行为的一种绝佳工具

内核调试API:

# clock_getres, clock_gettime – 高分辨率的POSIX时钟

# getrusage,times – 查看资源使用情况的库函数

# mallopt – 属于GNU的API,用于设置动态分配内存行为

# mlock, munlock – 用于在ram总锁定页

# mmap, msync, madvise – 内存在RAM和磁盘上如何释放

# pthread_setschedparam – 为线程选择一个时序安排策略

# sysconf – 显示系统常量的配置细节内容

分享到:
评论

相关推荐

    Linux内核源代码情景分析

    该资源是详细介绍Linux的内核的源代码,以及对内核代码的进行分析,是linux系统入门的必备知识。

    AT_T汇编语言教程----学习内核必备知识

    AT_T汇编语言 理解linux内核的必备知识

    LINUX内核源代码情景分析

    该资源着重于对Linux系统内核源代码进行情景描述和情景分析,是linux系统入门的必备知识。

    详解linux内核链表之list.h

    深入内核,必备知识。

    linux内核设计与实现 2 中文 part4

    linux内核学习入门级书,需要了解一定的操作系统知识,了解i386硬件架构,好书不多说,学习内核必备

    linux内核设计与实现 2 中文 part2

    linux内核学习入门级书,需要了解一定的操作系统知识,了解i386硬件架构,好书不多说,学习内核必备

    linux内核设计与实现 2 中文 part3

    linux内核学习入门级书,需要了解一定的操作系统知识,了解i386硬件架构,好书不多说,学习内核必备

    linux内核设计与实现 2 中文 part1

    linux内核学习入门级书,需要了解一定的操作系统知识,了解i386硬件架构,好书不多说,学习内核必备

    Linux系统基础知识梳理

    但是学好它却是程序员必备修养之一。 Linux 对比 Windows稳定且有效率;免费(或少许费用);漏洞少且快速修补;多任务多用户;更加安全的用户与文件权限策略;适合小内核程序的嵌入系统;相对不耗资源。 Linux概念...

    Linux kernel pdf 每一行都完全注释-初学者必备

    第2 章 LINUX 内核体系结构 13 21 LINUX 内核模式 13 22 LINUX 内核系统体系结构 14 23 LINUX 内核进程控制 15 24 LINUX 内核对内存的使用方法 16 25 LINUX 内核源代码的目录结构 18 26 内核系统与用户程序的关系 23...

    GNU_Linux编程指南.pdf

    首先介绍了在Linux上编程必备的编程工具,然后在库函数、系统调用以及内核上阐述Linux编程知识,并专门讲述了包括TCP/IP、UDP以及多播套接口在内的网络编程知识;图形界面也是本书的重点内容,本书着重讲述了文本...

    后端程序员必备的 Linux 基础知识 常见命令.docx

    1.操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是...4.操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理 。

    Linux常用命令大全新手必备.docx

    一、基础知识 1.1 Linux系统的文件结构 /bin 二进制文件,系统常规命令 /boot 系统启动分区,系统启动时读取的文件 /dev 设备文件 /etc 大多数配置文件 /home 普通用户的家目录 /lib 32位函数库 /lib64 64位库 /...

    LINUX开发工具箱:项目开发的最有效途径

    开源工具的下载和安装 从源代码构架 查找帮助 编辑和保存源文件 开发者必备内核知识 进程 进程通信 使用shell调试IPC 性能优化 调试

    嵌入式Linux应用开发完全手册.part4

    《嵌入式Linux应用开发完全手册》全面介绍了嵌入式Linux系统开发过程中,从底层系统支持到上层GUI应用的方方面面,内容涵盖Linux操作系统的安装及相关工具的使用、配置,嵌入式编程所需要的基础知识(交叉编译工具的...

    嵌入式Linux应用开发完全手册.part2

    《嵌入式Linux应用开发完全手册》全面介绍了嵌入式Linux系统开发过程中,从底层系统支持到上层GUI应用的方方面面,内容涵盖Linux操作系统的安装及相关工具的使用、配置,嵌入式编程所需要的基础知识(交叉编译工具的...

    GNU_linux编程指南

    首先介绍了在Linux上编程必备的编程工具,然后在库函数、系统调用以及内核上阐述Linux编程知识,并专门讲述了包括TCP/IP、UDP以及多播套接口在内的网络编程知识;图形界面也是本书的重点内容,本书着重讲述了文本...

    CentOS.5系统管理-part2

    第1部分 基础篇 ...2.1 安装Linux之前的必备知识 2.1.1 磁盘分区 2.1.2 静态分区的缺点 2.1.3 逻辑卷管理(LVM) 2.2 服务器方式安装CentOS 5 2.2.1 下载CentOS 5 2.2.2 使用安装光盘启动系统 2.3 安装后的基本配置

    linux 设备驱动开发及参考代码

    中文版,学习驱动开发必备,需要有具备一定的内核知识。

    Android底层开发技术实战详解--内核、移植和驱动.(电子工业.王振丽).part3

    1.4.2 和Android密切相关的Linux内核知识 10 1.5 分析Linux内核源代码很有必要 14 1.5.1 源代码目录结构 14 1.5.2 浏览源代码的工具 16 1.5.3 为什么用汇编语言编写内核代码 17 1.5.4 Linux...

Global site tag (gtag.js) - Google Analytics