Linux内核主要由五个子系统组成:进程调度,内存管理,虚拟文件系统,网络接口,进程间通信。

1.进程调度
(SCHED):控制进程对CPU的访问。当需要选择下一个进程运行时,由调度程序选择最值得运行的进程。可运行进程实际上是仅等待CPU资源的进程,如
果某个进程在等待其它资源,则该进程是不可运行进程。Linux使用了比较简单的基于优先级的进程调度算法选择新的进程。

2.
内存管理(MM)允许多个进程安全的共享主内存区域。Linux的内存管理支持虚拟内存,即在计算机中运行的程序,其代码,数据,堆栈的总量可以超过实际
内存的大小,操作系统只是把当前使用的程序块保留在内存中,其余的程序块则保留在磁盘中。必要时,操作系统负责在磁盘和内存间交换程序块。内存管理从逻辑
上分为硬件无关部分和硬件有关部分。硬件无关部分提供了进程的映射和逻辑内存的对换;硬件相关的部分为内存管理硬件提供了虚拟接口。

3.
虚拟文件系统(VirtualFileSystem,VFS)隐藏了各种硬件的具体细节,为所有的设备提供了统一的接口,VFS提供了多达数十种不同的文
件系统。虚拟文件系统可以分为逻辑文件系统和设备驱动程序。逻辑文件系统指Linux所支持的文件系统,如ext2,fat等,设备驱动程序指为每一种硬
件控制器所编写的设备驱动程序模块。

4.网络接口(NET)提供了对各种网络标准的存取和各种网络硬件的支持。网络接口可分为网络协议和网络驱动程序。网络协议部分负责实现每一种可能的网络传输协议。网络设备驱动程序负责与硬件设备通讯,每一种可能的硬件设备都有相应的设备驱动程序。

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


于中心位置的进程调度,所有其它的子系统都依赖它,因为每个子系统都需要挂起或恢复进程。一般情况下,当一个进程等待硬件操作完成时,它被挂起;当操作真
正完成时,进程被恢复执行。例如,当一个进程通过网络发送一条消息时,网络接口需要挂起发送进程,直到硬件成功地完成消息的发送,当消息被成功的发送出去
以后,网络接口给进程返回一个代码,表示操作的成功或失败。其他子系统以相似的理由依赖于进程调度。

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

进程调度与内存管理之间的关系:这两个子系统互相依赖。在多道程序环境下,程序要运行必须为之创建进程,而创建进程的第一件事情,就是将程序和数据装入内存。

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

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

内存管理与虚拟文件系统之间的关系:内存管理利用虚拟文件系统支持交换,交换进程(swapd)定期由调度程序调度,这也是内存管理依赖于进程调度的唯一原因。当一个进程存取的内存映射被换出时,内存管理向文件系统发出请求,同时,挂起当前正在运行的进程。

除了这些依赖关系外,内核中的所有子系统还要依赖于一些共同的资源。这些资源包括所有子系统都用到的过程。例如:分配和释放内存空间的过程,打印警告或错误信息的过程,还有系统的调试例程等等。

系统数据结构

在linux的内核的实现中,有一些数据结构使用频度较高,他们是:

task_struct.

Linux
内核利用一个数据结构(task_struct)代表一个进程,代表进程的数据结构指针形成了一个task数组(Linux中,任务和进程是相同的术
语),这种指针数组有时也称为指针向量。这个数组的大小由NR_TASKS(默认为512),表明Linux系统中最多能同时运行的进程数目。当建立新进
程的时候,Linux为新进程分配一个task_struct结构,然后将指针保存在task数组中。调度程序一直维护着一个current指针,他指向
当前正在运行的进程。

Mm_struct

每个进程的虚拟内存由一个mm_struct结构来代表,该结构实际上包含了当前执行映像的有关信息,并且包含了一组指向vm_area_struct结构的指针,vm_area_struct结构描述了虚拟内存的一个区域。

Inode


拟文件系统(VFS)中的文件、目录等均由对应的索引节点(inode)代表。每个VFS索引节点中的内容由文件系统专属的例程提供。VFS索引节点只存
在于内核内存中,实际保存于VFS的索引节点高速缓存中。如果两个进程用相同的进程打开,则可以共享inade的数据结构,这种共享是通过两个进程中数据
块指向相同的inode完成。

Linux的具体结构

所谓具体结构是指系统实现的结构。

Linux的具体结构类似于抽象结构,这种对应性是因为抽象结构来源于具体结构,我们的划分没有严格依照源代码的目录结构,且和子系统的分组也不完全匹配,但是,它很接近源代码的目录结构。

尽管前面的讨论的抽象结构显示了各个子系统之间只有很少的依赖关系,但是具体结构的5个子系统之间有高度的依赖关系。我们可以看出,具体结构中的很多依赖关系并没有在抽象结构中出现。

Linux内核源代码


前,较新而又稳定的内核版本是2.0.x和2.2.x,因为版本不同稍有差别,因此如果你想让一个新的驱动程序既支持2.0.x,又支持2.2.x,就需
要根据内核版本进行条件编译,要作到这一点,就要支持宏LINUX_VERSION_CODE,假如内核的版本用a.b.c来表示,这个宏的值就是
216a+28b+c。要用到指定内核版本的值,我们可以用KERNEL_VERSION宏,我们也可以自己去定义它。

对内核的修改用补丁文件的方式发布的。Patch实用程序用来用来对内核源文件进行一系列的修改。例如:你有2.2.9的源代码,但想移到2.2.10。就可以获得2.2.10的补丁文件,应用patch来修改2.2.9源文件。例如:

$ cd /usr/src/linux

$ patch –pl < patch-2.2.10

Linux 内核源代码的结构

Linux内核源代码位于/usr/src/linux目录下。

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

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

/arch子目录包含了所有硬件结构特定的内核代码。如:i386,alpha

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

/fs子目录包含了所有的文件系统的代码。如:ext2,vfat等。

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

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

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

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

从何处开始阅读源代码?

在Internet,有人制作了源代码导航器,为阅读源代码提供了良好的条件,站点为lxr.linux.no/source。

下面给出阅读源代码的线索:

系统的启动和初始化:


基于Intel的系统上,当loadlin.exe或LILO把内核装入到内存并把控制权传递给内核时,内核开始启动。关于这一部分请
看,arch/i386/kernel/head.S,head.S进行特定结构的设置,然后跳转到init/main.c的main()例程。

内存管理:


存管理的代码主要在/mm,但是特定结构的代码在arch/*/mm。缺页中断处理的代码在/mm/memory.c
,而内存映射和页高速缓存器的代码在/mm/filemap.c 。缓冲器高速缓存是在/mm/buffer.c
中实现,而交换高速缓存是在mm/swap_state.c和mm/swapfile.c。

内核:


核中,特定结构的代码在arch/*/kernel,调度程序在kernel/sched.c,fork的代码在kernel/fork.c,内核例程处
理程序在include/linux/interrupt.h,task_struct数据结构在inlucde/linux/sched.h中。

PCI:

PCI伪驱动程序在drivers/pci/pci.c,其定义在inclulde/linux/pci.h。每一种结构都有一些特定的PCI BIOS代码,Intel的在arch/alpha/kernel/bios32.c中。

进程间通信:


有的SystemVIPC对象权限都包含在ipc_perm数据结构中,这可以在include/linux/ipc.h中找到。SystemV消息是在
ipc/msg.c中实现。共享内存在ipc/shm.c中实现。信号量在ipc/sem.c中,管道在/ipc/pipe.c中实现。

中断处理:

内核的中断处理代码几乎所有的微处理器特有的。中断处理代码在arch/i386/kernel/irq.c中,其定义在include/asm-i386/irq.h中。

【转】Linux内核结构详解的更多相关文章

  1. Linux 目录结构详解

    Linux目录详解 Linux目录详解(RHEL5.4) 由于linux是开放源代码,各大公司和团体根据linux的核心代码做各自的操作,编程.这样就造成在根下的目录的不同.这样就造成个人不能使用他人 ...

  2. Linux目录结构详解(一)

    Linux目录结构,在逻辑上所有目录只有一个顶点,即/(根目录),是所有目录的起点.根下面类似于一个倒挂着的树的结构. Linux目录按照类别组织: 应用程序 /usr/bin 数据文件,帮助/usr ...

  3. Linux 内核 hlist 详解

    在Linux内核中,hlist(哈希链表)使用非常广泛.本文将对其数据结构和核心函数进行分析. 和hlist相关的数据结构有两个:hlist_head 和 hlist_node //hash桶的头结点 ...

  4. Linux文件目录结构详解

    整理自<鸟哥的私房菜> 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于 ...

  5. uboot引导linux内核过程详解【转】

    http://blog.chinaunix.net/uid-7828352-id-4472376.html 写的不错,尤其是uboot向linux内核传递参数的过程写的比较详细.

  6. 必须知道的Linux内核常识详解

    一.内核功能.内核发行版 1.到底什么是操作系统 (1)linux.windows.android.ucos就是操作系统: (2)操作系统本质上是一个程序,由很多个源文件构成,需要编译连接成操作系统程 ...

  7. Linux文件目录结构详解 (转)

      整理自<鸟哥的私房菜> 对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能, ...

  8. linux目录结构详解(以suse linux 10为例)

    一.文件系统结构 位于Linux系统的最顶端即根目录是/.Linux的文件系统的入口就是/,所有的目录.文件.设备都在/之下,/就是Linux文件系统的组织者,也是最上级的领导者. 它之下的子目录有: ...

  9. linux内核sysfs详解【转】

    转自:http://blog.csdn.net/skyflying2012/article/details/11783847 "sysfs is a ram-based filesystem ...

随机推荐

  1. 前端ajax的各种与后端交互的姿势

    前端中常常用的与后端交换数据的话,通常是要用到ajax这种方法的 但是交互的方式有很多种,很多取决于你后端的属性,我这儿主要列举我目前项目比较常用的两种方式 --一个是我们通用的web api和控制器 ...

  2. 纯JS实现轮播图特效——详解

    <div id="slider"> <div id="sliderImgs"> <img src="img/mi04.j ...

  3. shell入门基础&常见命令及用法

    shell shell是一个命令解释器,实际是一个程序,/bin/bash,linux中所有的命令都由它来解释,有自己的语法 shell脚本 以.sh结尾 shell语法+linux命令 注释: 单行 ...

  4. mysql 几种搜索引擎的比较

    mysql中常见的数据库引擎之间的比较  转载自 深入浅出mysql数据库 MySQL5.5以后默认使用InnoDB存储引擎,其中InnoDB和BDB提供事务安全表,其它存储引擎都是非事务安全表. 若 ...

  5. MySQL的JOIN用法

    JOIN的含义就如英文单词“join”一样,连接两张表,大致分为内连接,外连接,右连接,左连接,自然连接.这里描述先甩出一张用烂了的图,然后插入测试数据. CREATE TABLE t_blog( i ...

  6. 学习 Git的使用过程

    原文链接: http://www.cnblogs.com/NickQ/p/8882726.html 学习 Git的使用过程 初次使用 git config --global user.name &qu ...

  7. Python基本语法元素

      静态语言(C/C++.Java):脚本语言(python.JavaScript.PHP) IPO(Input.Process.Output) #:python中的注释符号:'''    ''':多 ...

  8. 用kubeadm构建k8s集群部署

    一.环境 三台centos机器 二.软件及容器准备 1.安装docker环境 本例安装 docker-ce版本,repo源为docker-ce.repo文件,拷贝到 /etc/yum.repos.d下 ...

  9. PTA基础编程题目集7-2然后是几点

    有时候人们用四位数字表示一个时间,比如1106表示11点零6分.现在,你的程序要根据起始时间和流逝的时间计算出终止时间. 读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计 ...

  10. github上的golang双向rpc,基于原生“net/rpc”库实现,可以注册回调

    github上的golang双向rpc,基于原生“net/rpc”库实现,可以注册回调.仅支持一个server和一个client交互. 地址:https://github.com/rocket049/ ...