linux内核与进程.docx

上传人:b****1 文档编号:36784 上传时间:2023-04-28 格式:DOCX 页数:58 大小:211.53KB
下载 相关 举报
linux内核与进程.docx_第1页
第1页 / 共58页
linux内核与进程.docx_第2页
第2页 / 共58页
linux内核与进程.docx_第3页
第3页 / 共58页
linux内核与进程.docx_第4页
第4页 / 共58页
linux内核与进程.docx_第5页
第5页 / 共58页
linux内核与进程.docx_第6页
第6页 / 共58页
linux内核与进程.docx_第7页
第7页 / 共58页
linux内核与进程.docx_第8页
第8页 / 共58页
linux内核与进程.docx_第9页
第9页 / 共58页
linux内核与进程.docx_第10页
第10页 / 共58页
linux内核与进程.docx_第11页
第11页 / 共58页
linux内核与进程.docx_第12页
第12页 / 共58页
linux内核与进程.docx_第13页
第13页 / 共58页
linux内核与进程.docx_第14页
第14页 / 共58页
linux内核与进程.docx_第15页
第15页 / 共58页
linux内核与进程.docx_第16页
第16页 / 共58页
linux内核与进程.docx_第17页
第17页 / 共58页
linux内核与进程.docx_第18页
第18页 / 共58页
linux内核与进程.docx_第19页
第19页 / 共58页
linux内核与进程.docx_第20页
第20页 / 共58页
亲,该文档总共58页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

linux内核与进程.docx

《linux内核与进程.docx》由会员分享,可在线阅读,更多相关《linux内核与进程.docx(58页珍藏版)》请在冰点文库上搜索。

linux内核与进程.docx

linux内核与进程

Linux内核与进程

——Linux源代码分析

 

姓名:

李琳09171206

米婧09171211

宋春晓09171214

陶荣09171216

郑佳男09171219

专业:

计算机科学与技术专业

班级:

计科092班

 

各人员分工:

李琳:

Linux内核源代码的各子目录的内容;

宋春晓、米婧:

Linux启动和初始化部分源代码的内容,根据这个分析Linux进程调度有关函数的源代码,如schedule()函数、goodness()函数,以及它们引用的头文件的分析;

陶荣:

Linux的进程调度算法及其实现所用的主要数据结构

郑佳男:

Linux进程创建的分析

 

内容简介:

一、Linux内核简要介绍

二、Linux的启动和初始化

三、Linux进程调度

四、Linux进程创建

 

一、Linux内核介绍

1.1——Linux内核的特征

Linux是个人计算机和工作站上的Unix类操作系统。

但是,它绝不是简化的Unix。

相反,Linux是强有力和具有创新意义的Unix类操作系统。

它不仅继承了Unix的特征,而且在许多方面超过了Unix。

作为Unix类操作系统,Linux内核具有下列基本特征:

 1.Linux内核的组织形式为整体式结构。

也就是说整个Linux内核由很多过程组成,每个过程可以独立编译,然后用连接程序将其连接在一起成为一个单独的目标程序。

从信息隐藏的观点看,她没有任何程度的隐藏—每个过程都对其它过程可见。

这种结构的最大特点是内部结构简单,子系统间易于访问,因此内核的工作效率较高。

另外,基于过程的结构也有助于不同的人参与不同过程的开发,从这个角度来说,Linux内核又是开放式的结构,她允许任何人对其进行修正、改进和完善。

 2.Linux的进程调度方式简单而有效。

可以说Linux在追求效率方面孜孜不倦,体现在调度方式上也是别具一格。

对于用户进程,Linux采用简单的动态优先级调度方式;对于内核中的例程(如设备驱动程序、中断服务程序等)则采用了一种独特的机制—软中断机制,这种机制保证了内核例程的高效运行。

 3. Linux支持内核线程(或称守护进程)。

内核线程是在后台运行而又无终端或登录shell和它结合在一起的进程。

有许多标准的内核线程,其中有一些周期地运行来完成特定的任务(如swapd),而其余一些则连续地运行,等待处理某些特定的事件(如inetd和lpd)。

内核线程可以说是用户进程,但和一般的用户进程又有不同,它象内核一样不被换出,因此运行效率较高。

 4.Linux支持多种平台的虚拟内存管理。

内存管理是和硬件平台密切相关的部分,为了支持不同的硬件平台而又保证虚拟存储管理技术的通用性,Linux的虚拟内存管理为不同的硬件平台提供了统一的接口,因此把Linux内核移植到一个新的硬件平台并不是一件很困难的事。

 5.Linux内核另一个独具特色的部分是虚拟文件系统(VFS)。

虚拟文件系统不仅为多种逻辑文件系统(如ext2,fat等)提供了统一的接口,而且为各种硬件设备(作为一种特殊文件)也提供了统一接口。

 6. Linux的模块机制使得内核保持独立而又易于扩充。

模块机制可以使内核很容易地增加一个新的模块(如一个新的设备驱动程序),而无需重新编译内核;同时,模块机制还可以把一个模块按需添加到内核或从内核中卸下,这使得我们可以按需要定制自己的内核。

 7.增加系统调用以满足你特殊的需求。

一般来说,系统调用是操作系统的设计者提供给用户使用内核功能的接口,但Linux开放的源代码也允许你设计自己的系统调用,然后把它加入到内核。

 8.网络部分面向对象的设计思想使得Linux内核支持多种协议、多种网卡驱动程序变得容易。

1.2——Linux内核在整个操作系统中的位置

Linux的内核不是孤立的,必须把它放在整个系统中去研究,图1.1显示了Linux内核在整

个操作系统的位置:

用户进程

系统调用接口

 

硬件

图1.2Linux内核在整个操系统中的位置

由图1.1可以看出,Linux操作系统由四个部分组成:

1.用户进程—用户应用程序是运行在Linux操作系统最高层的一个庞大的软件集合,当一个用户程序在操作系统之上运行时,它成为操作系统中的一个进程。

2.系统调用接口—在应用程序中,可通过系统调用来调用操作系统内核中特定的过程,以实现特定的服务。

例如,在程序中安排一条创建进程的系统调用,则操作系统内核便会为之创建一个新进程。

系统调用本身也是由若干条指令构成的过程。

但它与一般的过程不同,主要区别是:

系统调用是运行在内核态(或叫系统态),而一般过程是运行在用户态。

在Linux中,系统调用是内核代码的一部分。

3.Linux内核—这是本书要讨论的重点。

内核是操作系统的灵魂,它负责管理磁盘上的文件、内存,负责启动并运行程序,负责从网络上接收和发送数据包等等。

简言之,内核实际是抽象的资源操作到具体硬件操作细节之间的接口。

4.硬件—这个子系统包括了Linux安装时需要的所有可能的物理设备。

例如,CPU、内存、硬盘、网络硬件等等。

上面的这种划分把整个Linux操作系统分为四个层次。

把用户进程也纳入操作系统的范围内是因为用户进程的运行和操作系统密切相关,而系统调用接口可以说是操作系统内核的扩充,硬件则是操作系统内核赖以生存的物质条件。

这四个层次的依赖关系表现为:

上层依赖下层。

1.3——Linux内核的抽象结构

Linux内核由5个主要的子系统组成:

如图1.2

图1.2Linux内核子系统及其之间的关系

1.进程调度(SCHED)控制着进程对CPU的访问。

当需要选择下一个进程运行时,由调度程序选择最值得运行的进程。

可运行进程实际是仅等待CPU资源的进程,如果某个进程在等待其他资源,则该进程是不可运行进程。

Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。

2.内存管理(MM)允许多个进程安全地共享主内存区域。

Linux的内存管理支持虚拟内存,即在计算机中运行的程序,其代码、数据和堆栈的总量可以超过实际内存的大小,操作系统只将当前使用的程序块保留在内存中,其余的程序块则保留在磁盘上。

必要时,操作系统负责在磁盘和内存之间交换程序块。

内存管理从逻辑上可以分为硬件无关的部分和硬件相关的部分。

硬件无关的部分提供了进程的映射和虚拟内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。

3.虚拟文件系统(VirtulFileSystemVFS)隐藏了各种不同硬件的具体细节,为所有设备提供了统一的接口,VFS还支持多达数十种不同的文件系统,这也是Linux较有特色的一部分。

虚拟文件系统可分为逻辑文件系统和设备驱动程序。

逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬件控制器所编写的设备驱动程序模块。

4.网络接口(NET)提供了对各种网络标准协议的存取和各种网络硬件的支持。

网络接口可分为网络协议和网络驱动程序两部分。

网络协议部分负责实现每一种可能的网络传输协议,网络设备驱动程序负责与硬件设备进行通信,每一种可能的硬件设备都有相应的设备驱动程序。

5.进程间通信(IPC)支持进程间各种通信机制。

从图1.2可以看出,处于中心位置的是进程调度,所有其它的子系统都依赖于它,因为每个子系统都需要挂起或恢复进程。

一般情况下,当一个进程等待硬件操作完成时,它被挂起;当操作真正完成时,进程被恢复执行。

例如,当一个进程通过网络发送一条消息时,网络接口需要挂起发送进程,直到硬件成功地完成消息的发送,当消息被发送出去以后,网络接口给进程返回一个代码,表示操作的成功或失败。

其它子系统(内存管理,虚拟文件系统及进程间通信)以相似的理由依赖于进程调度。

各个子系统之间的依赖关系如下:

·进程调度与内存管理之间的关系:

这两个子系统互相依赖。

在多道程序环境下,程序要运行必须为之创建进程,而创建进程的第一件事,就是要将程序和数据装入内存。

·进程间通信与内存管理的关系:

进程间通信子系统要依赖内存管理支持共享内存通信机制,这种机制允许两个进程除了拥有自己的私有内存,还可存取共同的内存区域。

·虚拟文件系统与网络接口之间的关系:

虚拟文件系统利用网络接口支持网络文件系统(NFS),也利用内存管理支持RAMDISK设备。

·内存管理与虚拟文件系统之间的关系:

内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期地由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。

当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。

1.4——Linux内核源代码

1.4.1——Linux内核源代码的结构

除了图1.2所显示的依赖关系以外,内核中的所有子系统还要依赖一些共同的资源,但在图中并没有显示出来。

这些资源包括所有子系统都用到的过程,例如,分配和释放内存空间的过程,打印警告或错误信息的过程,还有系统的调试例程等等。

Linux内核源代码位于/usr/src/linux目录下,其结构分布如图1.3所示,每一个目录或子目录可以看作一个模块,其目录之间的连线表示“子目录或子模块”的关系。

下面是对每一个目录的简单描述。

include/子目录包含了建立内核代码时所需的大部分包含文件,这个模块利用其它模块重建内核。

init/子目录包含了内核的初始化代码,这是内核开始工作的起点。

arch/子目录包含了所有硬件结构特定的内核代码,如图1.3,arch/子目录下有i386和alpha模块等等。

drivers/目录包含了内核中所有的设备驱动程序,如块设备,scsi设备驱动程序等等。

fs/目录包含了所有文件系统的代码,如:

ext2,vfat模块的代码等等。

net/目录包含了内核的连网代码。

mm/目录包含了所有的内存管理代码。

ipc/目录包含了进程间通信的代码。

kernel/目录包含了主内核代码

图1.3显示了八个目录,即init,kernel,mm,ipc,drivers,fs,arch及net的包含文件都在"include/"目录下。

在Linux内核中包含了drivers,fs,arch及net模块,这就使得Linux内核既不是一个层次式结构,也不是一个微内核结构,而是一个“整体式”结构。

因为系统调用可以直接调用内核层,因此,该结构使得整个系统具有较高的性能,其缺点是内核修改起来比较困难,除非遵循严格的规则和编码标准。

在图1.3中所显示的模块结构,代表了一种工作分配单元,利用这种结构,我们期望LinusTorvalds能维护和增强内核的核心服务,即,init/,kernel/,mm/及ipc/,其它的模块drivers,fs,arch及net也可以作为工作单元,例如,可以分配一组人对块文件系统进行维护和进一步的开发,而另一组人对scsi文件系统进行完善。

图1.3类似于Linux的自愿者开发队伍一起工作来增强和扩展整个系统的框架。

图1.4Linux源代码的分布结构

1.4.2——Linux内核源代码的各子目录

根目录部分有以下子目录:

/usr目录包含所有的命令、程序库、文档和其它文件。

这些文件在正常操作中不会被改变的。

这个目录也包含你的Linux发行版本的主要的应用程序,譬如,Netscape。

/var目录包含在正常操作中被改变的文件:

假脱机文件、记录文件、加锁文件、临时文件和页格式化文件等。

/home目录包含用户的文件:

参数设置文件、个性化文件、文档、数据、EMAIL、缓存数据等。

这个目录在系统省级时应该保留。

/proc目录整个包含虚幻的文件。

它们实际上并不存在磁盘上,也不占用任何空间。

(用ls–l可以显示它们的大小)当查看这些文件时,实际上是在访问存在内存中的信息,这些信息用于访问系统

/bin系统启动时需要的执行文件(二进制),这些文件可以被普通用户使用。

/sbin系统执行文件(二进制),这些文件不打算被普通用户使用。

(普通用户仍然可以使用它们,但要指定目录。

/etc操作系统的配置文件目录。

/root系统管理员(也叫超级用户或根用户)的Home目录。

/dev设备文件目录。

LINUX下设备被当成文件,这样一来硬件被抽象化,便于读写、网络共享以及需要临时装载到文件系统中。

正常情况下,设备会有一个独立的子目录。

这些设备的内容会出现在独立的子目录下。

LINUX没有所谓的驱动符。

/lib根文件系统目录下程序和核心模块的共享库。

/boot用于自举加载程序(LILO或GRUB)的文件。

当计算机启动时(如果有多个操作系统,有可能允许你选择启动哪一个操作系统),这些文件首先被装载。

这个目录也会包含LINUX核(压缩文件vmlinuz),但LINUX核也可以存在别处,只要配置LILO并且LILO知道LINUX核在哪儿。

/opt可选的应用程序,譬如,REDHAT5.2下的KDE(REDHAT6.0下,KDE放在其它的XWINDOWS应用程序中,主执行程序在/usr/bin目录下)

/tmp临时文件。

该目录会被自动清理干净。

/lost+found在文件系统修复时恢复的文件

“/usr”目录下比较重要的部分有:

/usr/X11R6X-WINDOWS系统(version11,release6)

/usr/X11同/usr/X11R6(/usr/X11R6的符号连接)

/usr/X11R6/bin大量的小X-WINDOWS应用程序(也可能是一些在其它子目录下大执行文件的符号连接)。

/usr/docLINUX的文档资料(在更新的系统中,这个目录移到/usr/share/doc)。

/usr/share独立与你计算机结构的数据,譬如,字典中的词。

/usr/bin和/usr/sbin类似与“/”根目录下对应的目录(/bin和/sbin),但不用于基本的启动(譬如,在紧急维护中)。

大多数命令在这个目录下。

/usr/local本地管理员安装的应用程序(也可能每个应用程序有单独的子目录)。

在“main”安装后,这个目录可能是空的。

这个目录下的内容在重安装或升级操作系统后应该存在。

/usr/local/bin可能是用户安装的小的应用程序,和一些在/usr/local目录下大应用程序的符号连接。

/proc目录的内容:

/proc/cpuinfo关于处理器的信息,如类型、厂家、型号和性能等。

/proc/devices当前运行内核所配置的所有设备清单。

/proc/dma当前正在使用的DMA通道。

/proc/filesystems当前运行内核所配置的文件系统。

/proc/interrupts正在使用的中断,和曾经有多少个中断。

/proc/ioports当前正在使用的I/O端口。

举例,使用下面的命令能读出系统的CPU信息。

cat/proc/cpuinfo

/bin

bin是binary的缩写。

这个目录沿袭了UNIX系统的结构,存放着使用者最经常使用的命令。

例如cp、ls、cat,等等。

/boot

这里存放的是启动Linux时使用的一些核心文件。

/dev

dev是device(设备)的缩写。

这个目录下是所有Linux的外部设备,其功能类似DOS下的.sys和Win下的.vxd。

在Linux中设备和文件是用同种方法访问的。

例如:

/dev/hda代表第一个物理IDE硬盘。

/etc

这个目录用来存放系统管理所需要的配置文件和子目录。

/home

用户的主目录,比如说有个用户叫wang,那他的主目录就是/home/wang也可以用~wang表示。

/lib

这个目录里存放着系统最基本的动态链接共享库,其作用类似于Windows里的.dll文件。

几乎所有的应用程序都须要用到这些共享库。

/lost+found

这个目录平时是空的,当系统不正常关机后,这里就成了一些无家可归的文件的避难所。

对了,有点类似于DOS下的.chk文件。

/mnt

这个目录是空的,系统提供这个目录是让用户临时挂载别的文件系统。

/proc

这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。

也就是说,这个目录的内容不在硬盘上而是在内存里。

/root

系统管理员(也叫超级用户)的主目录。

作为系统的拥有者,总要有些特权啊!

比如单独拥有一个目录。

/sbin

s就是SuperUser的意思,也就是说这里存放的是系统管理员使用的管理程序。

/tmp

这个目录不用说,一定是用来存放一些临时文件的地方了。

/usr

这是最庞大的目录,我们要用到的应用程序和文件几乎都存放在这个目录下。

其中包含以下子目录;

/usr/X11R6

存放X-Window的目录;

/usr/bin

存放着许多应用程序;

/usr/sbin

给超级用户使用的一些管理程序就放在这里;

/usr/doc

这是Linux文档的大本营;

/usr/include

Linux下开发和编译应用程序需要的头文件,在这里查找;

/usr/lib

存放一些常用的动态链接共享库和静态档案库;

/usr/local

这是提供给一般用户的/usr目录,在这里安装软件最适合;

/usr/man

man在Linux中是帮助的同义词,这里就是帮助文档的存放目录;

/usr/src

Linux开放的源代码就存在这个目录,爱好者们别放过哦!

/var

这个目录中存放着那些不断在扩充着的东西,为了保持/usr的相对稳定,那些经常被修改的目录可以放在这个目录下,实际上许多系统管理员都是这样干的。

顺带说一下系统的日志文件就在/var/log目录中。

总结来说:

·用户应该将文件存在/home/user_login_name目录下(及其子目录下)。

·本地管理员大多数情况下将额外的软件安装在/usr/local目录下并符号连接在/usr/local/bin下的主执行程序。

·系统的所有设置在/etc目录下。

·不要修改根目录(“/”)或/usr目录下的任何内容,除非真的清楚要做什么。

这些目录最好和LINUX发布时保持一致。

·大多数工具和应用程序安装在目录:

/bin,/usr/sbin,/sbin,/usr/x11/bin,/usr/local/bin。

·所有的文件在单一的目录树下。

没有所谓的“驱动符”。

Linux下文件夹部署详解-[]/bin指令文件(适用于所有用户的)

/etc系统配置文件

/sbin指令文件(适用于root用户的)

/home(用户主目录,新建用户后,该用户的源文件默认建立在此目录下)

/boot内核和启动文件

/dev设备文件,用于和地层驱动打叫道的

/usr应用程序放置目录

/mnt光驱

/tmp临时文件

/rootroot用户主目录

/opt空文件夹

/proc内存中实际参数和内核的映象,此文件夹的文件不宜改动

/lib类库,用于动态加载内核

/lost+found恢复误删除文件

另外,用ls指令查看文件的颜色,及其意义:

蓝色为文件夹;绿色是可执行文件;浅蓝色是链接文件;红框文件是加了SUID位,任意限权;红色为压缩文件;褐色为设备文件。

.开头的是隐含文件。

二、Linux的启动和初始化

2.1——Linux的启动过程、用户登录过程

2.1.2——Linux的启动过程

在进行schedule分析之前有必要简单说明一下系统启动过程,内存分配使用等。

这样才能自然过渡到schedule模块。

首先是Linux各个功能模块之间的依赖关系:

 

可见进程调度是整个内核的核心。

在这一部分,要说明的是,pc是怎样把操作系统从硬盘装载到内存中,并启动进程调度模块的。

然后才是后面对schedule的具体分析。

首先,启动操作系统部分,涉及到到三个文件:

/arch/i386/boot/bootsect.s、/arch/i386/boot/setup.s、/arch/i386/boot/compressed/head.s。

编译安装好一个Linux系统后,bootsect.s模块被放置在可启动设备的第一个扇区(磁盘引导扇区,512字节)。

那么下面开始启动过程,三个文件在内存中的分布与位置的移动如下图。

 

在经过上图这一系列过程后,程序跳转到system模块中的初始化程序init中执行,即/init/main.c文件。

该程序执行一系列的初始化工作,如寄存器初始化、内存初始化、中断设置等。

之后内存的分配如下图:

 此后,CPU有序地从内存中读取程序并执行。

前面的main从内核态移动到户态后,操作系统即建立了任务0,即进程调度程序。

之后再由schedule模块进行整个Linux操作系统中进程的创建(fork),调度(schedule),销毁(exit)及各种资源的分配与管理等操作了。

值得一说的是schedule将创建的第一个进程是init(pid=1),请注意它不是前面的/init/main.c程序段。

如果是在GNU/Debian系统下,init进程将依次读取rcS.d,rcN.d(rc0.d~rc6.d其中一个文件夹中的所有脚本),rc.local三个runcommand脚本等,之后系统的初始化就完成了,一系列系统服务被启动了,系统进入单用户或者多用户状态。

然后init读取/etc/inittab,启动终端设备((exec)getty)供用户登陆,如debian中会启动6个tty,你可以用组合键ctrl+alt+Fn(F1~F6)来切换。

2.1.2——Linux的用户登录过程

如果是终端登录的话,当用户键入用户名后,getty的工作就完成了。

然后它会调用login程序,并将用户名传给login。

login能执行多项工作。

因为它得到了用户名,于是可以调用getpwnam取得命令文件登录项,然后调用getpass(3)以显示提示“Password:

”,接着用户键入口令,它再调用crypt(3)将口令加密,并与该用户在阴影口令文件中pw_passwd字段比较。

如果是网络登录的话,作为系统调用的一部分,init调用一个shell,执行rc脚本,启动守护进程inetd。

脚本结束后,inetd的父进程变为init。

接着inetd等待TCP/IP连接,当一个连接请求到达时,它执行一次fork,生成子进程执行适当的程序。

比如,一个telnet请求到达主机,那么就会fork并exec一个telnetd服务进程。

然后,telnetd打开一个伪终端设备,并用fork分成两个进程。

父进程处理网络连接的通信,子进程则执行login程序,处理用户的登录与身份验证,过程和上一段的“终端登录”基本一样。

到这里就知道了Linux怎样启动进程调度模块了,也知道了进程调度模块启动的第一个进程init及之后的系统初始化和登陆流程。

下面就回过头来分析schedule代码及其相关函数调用。

2.2——Linux进程调度有关函数的源代码

2.2.1——schedule()函数和goodness()函数

函数goodness()就是用来衡量一个处于可运行状态的进程值得运行的程度。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2