null第5章 linux内核第5章 linux内核主要内容主要内容Linux内核组成
Linux内核源码组织结构
内核及模块的编译与安装过程
内核模块5.1 Linux系统内核简述5.1 Linux系统内核简述内核是一个操作系统的核心,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
Linux内核以独占的方式执行最底层任务,保证系统正常运行,协调多个并发进程,管理进程使用的内存,使它们相互之间不产生冲突,满足进程访问磁盘的请求等等。
5.2 Linux内核组成5.2 Linux内核组成L i n u x内核是由5个主要的子系统组成的:
进程调度、内存管理、虚拟文件系统、网络接口和进程间通信。
这些子系统之间是通过
函数
excel方差函数excelsd函数已知函数 2 f x m x mx m 2 1 4 2拉格朗日函数pdf函数公式下载
调用和共享数据结构相互通信的。
5.2 Linux内核组成5.2 Linux内核组成1、进程调度(SCHED)
SCHED控制进程对CPU的访问
2、内存管理(MM)
允许多个进程安全地共享主存区域,支持虚拟内存管理。
3、虚拟文件系统(VFS,Virtual File System)
VFS隐藏了各种硬件的细节,为所有设备提供了统一的接口。VFS分两部分:
逻辑文件系统(ext2、ext3、FAT等)
设备驱动程序(设备驱动模块)
4、网络接口(NET)
NET提供了对各种网络
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
存取和各种网络硬件的支持。分为网络
协议
离婚协议模板下载合伙人协议 下载渠道分销协议免费下载敬业协议下载授课协议下载
和网络驱动程序。
5、进程间通信(IPC)
IPC支持进程间的各种通信机制5.2 Linux内核组成5.2 Linux内核组成6、系统数据结构(使用频率高的)
task_struct
Linux内核利用一个数据结构(task_struct)代表一个进程,代表进程的数据结构的指针形成一个task数组默认大小是512,表明linux中同时运行的最多进程数。
mm_struct
每个进程的虚拟内存由一个mm_struct结构来代表。
inode
VFS中的文件、目录均由对应的索引节点(inode)代表。5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构位于/usr/src/linux目录下
include 包含了建立内核时所需的大部分头文件。
init 包含了内核的初始化代码,是内核工作的起点。
arch 包含了所有硬件体系结构相关的内核代码。
drivers 包含了系统所有设备的驱动程序。
fs 包含了所有文件系统代码,ext3、fat等。
net 包含了内核的网络相关代码。
mm 包含了所有内存管理代码。
ipc 包含了进程间相互通信的代码。
kernel 包含了内核最核心代码,包括进程调度、定时器等,同时与硬件体系结构相关代码放在arch/*/kernel 目录下5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构1 系统启动与初始化
基于intel的系统,Linux可以通过GRUB 或者LILO将核心载入内存并将控制传递给它。
这部分程序 位于arch/x86/kernel/head.s。此文件完成一些处理器相关操作并跳转到init/main.c中的main()例程。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构2 内存管理
这部分代码主要位于mm目录里,而与处理器结构相关部分在arch/*/mm中。
内存缺页处理代码在mm/memory.c中。
内存映射与页面cache代码位于filemap.c中。
buffer cache则在mm/buffer.c中实现。
页交换代码mm/swap_state.c和mm/swapfile.c中。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构3 核心
大多数通用代码位于kernel目录下,而处理器
相关代码被放在arch/*/kernel中。
进程调度程序位于kernel/sched.c,
fork代码位于kernel/fork.c。
底层部分处理及中断处理的代码位于include/linux/interrupt.h里。
在include/linux/sched.h中可以找到task_struct的描叙。5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构4 PCI
PCI伪设备驱动位于drivers/pci/pci.c。
其系统全局定义放在include/linux/pci.h中。
每个处理器结构 具有特殊的PCI BIOS代码,如Alpha AXP的位于arch/alpha/kernel/bios32.c中。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构5 进程间通讯
进程间通讯所有代码都在ipc目录中。
系统V IPC对象都包含一个ipc_perm结构,它在include/linux/ipc.h中描叙。
系统V消息在ipc/msg.c中实现。
共享内存在ipc/shm.c。
信号位于ipc/sem.c中。
管道在ipc/pipe.c中实现。5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构6 中断处理
核心的中断处理代码总是与微处理器结构相关。
Intel系统的中断处理代码位于arch/i386/kernel/irq.c中,并且其定义位于include/asm-generic/irq.h中。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构7 设备驱动
Linux核心源码的大多数都是设备驱动。所有Linux的设备驱动源码都放在drivers目录中并分成以下几类:
block 块设备驱动包括IDE(在ide.c中)驱动。初始化过程在drivers/block/genhd.c中的device_setup()。块设备包括IDE与SCSI设备。
char 此目录包含字符设备的驱动,如ttys,串行口以及鼠标。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构 cdrom 包含所有Linux CDROM代码。在这里可以找到某些特殊的CDROM设备(如Soundblaster CDROM)。 IDE接口的CD驱动位于drivers/block/ide-cd.c中而SCSI CD驱动位于drivers/scsi/scsi.c中。
pci 它包含了PCI伪设备驱动源码。这里可以找到关于PCI子系统映射与初始化的代码。
scsi 这里可以找到所有的SCSI代码以及Linux支持的SCSI 设备的设备驱动。
net 包含网络驱动源码。
sound 所有的声卡驱动源码。 5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构8 文件系统
EXT2文件系统的源码位于fs/ext2中,其数据结构定义位于include/linux/ext2_fs.h, ext2_fs_i.h 以及 ext2_fs_sb.h中。
虚拟文件系统数据结构在include/linux/fs.h中描叙。代码在f s / *中,缓冲区代码在
f s/b u ff e r. c中。
5.3 Linux内核源码组织结构5.3 Linux内核源码组织结构9 网络
网络代码位于net目录而大多数包含文件位于include/net中。
BSD套接口代码位于net/socket.c中。
IPV4的 INET套接口代码位于net/ipv4/af_inet.c中。通用协议支撑代码(包括sk_buff处理过程)位于net/core中, 同时TCP/IP网络代码位于net/ipv4中。网络设备驱动位于drivers/net中。 Linux内核源代码的组成 Linux内核源代码的组成 10 核心模块
核心模块代码部分位于核心中部分位于modules包中。
核心代码位于kernel/modules.c.
数据结构与内核守护进程kerneld消息位于include/linux/module.h和include/linux/kerneld.h目录中。
同时必要时需查阅 include/linux/elf.h中的ELF文件格式。 5.4 内核编译5.4 内核编译内核源码的获取方式
从发行版本中获得Linux内核源代码
获得最新的稳定版内核源代码。
内核官网:http://www.kernel.org
保留原本设置:利用patch升级内核源代码。
为什么要升级内核为什么要升级内核现有内核中会不断发现漏洞,需要打补丁后重新编译内核,以便系统能够更加安全的运行
新的内核版本通常会带来用户所需要的新功能
新的内核版本会支持较新的硬件设备正常工作
正确地为主机配置个性化的内核会使系统运行得更加快速、稳定查看系统中的设备 查看系统中的设备 查看主机的CPU信息
# more /proc/cpuinfo
查看主机PCI设备信息
# lspci
查看系统中所使用的内核模块信息
# more /proc/modules 内核的配置内核的配置Makefile
分布在Linux内核源代码中,定义Linux内核的编译规则。
配置文件(config.in/Kconfig)(通过配置界面)给用户提供配置选择的功能,在Linux2.4以前文件名是config.in, 在2.6版以后改为Kconfig。
配置工具
文本交互配置界面、文本窗口配置界面、图形窗口配置界面、根据原有配置文件自动生成新的配置文件
配置内核前的准备工作 配置内核前的准备工作 # cd /usr/src/linux-2.6
进入内核源码目录后,才能够正确执行所有的内核配置、编译命令。
# make mrproper
在每次配置并重新编译内核前需要先执行“make mrproper”命令清理源代码树,包括过去曾经配置的内核配置文件“.config”都将被清除。内核编译模式内核编译模式内核编译模式可以分为编译到内核和编译成模块两种模式。
如果编译到内核中,在内核启动时就可以自动支持相应部分的功能,其优点是方便、速度快,机器启动即可使用这部分功能;其缺点是使内核变得庞大起来,无论是否需要这部分功能,它都会存在。建议将经常使用的部分直接编译到内核中。
如果编译成模块,则生成对应的.o文件,使用时可以动态加载,优点是不会使内核过分庞大,缺点是必须得由用户自己来调用这些模块。文本配置界面文本配置界面文本交互 配置界面
# make config
根据原有配置文件自动生成新的配置文件
# make oldconfig 文本窗口配置界面文本窗口配置界面文本窗口配置界面
# make menuconfig 图形窗口配置界面图形窗口配置界面图形窗口配置界面
# make xconfig内核的配置选项内核的配置选项进行配置时,大部分选项可以使用其缺省值,只有小部分需要根据用户不同的需要选择。
选择相应的配置时,有三种选择,它们分别代表的含义如下:
“Y”- 将该功能编译进内核
“N”- 不将该功能编译进内核
“M”- 将该功能编译成可以在需要时动态插入到内核中的模块。
一般与内核关系紧密而且经常使用的功能直接编译进内核,不经常使用的功能编译为内核模块。
内核配置文件内核配置文件kconfig文件
无论采用哪种方法对Linux内核进行配置,最终的目的都是为了生成内核配置文件“kconfig”。
内核的编译过程将完全按照“kconfig”文件中的配置内容进行编译。
内核名称标志内核名称标志“EXTRAVERSION”变量
Makefile文件中的“EXTRAVERSION”变量的值将被用于生成新内核的版本标志,该标志用于命名内核文件、内核模块目录等。内核与模块的编译、安装步骤 内核与模块的编译、安装步骤
make bzImage:编译内核
make modules:编译内核模块
make modules_install:安装内核模块
make install:安装内核make bzImagemake bzImage# make bzImage
使用“make bzImage”命令进行内核编译,编译过程将持续相当长的时间(10分钟以上)。
bzImage 文件
“arch/x86/boot/ ”目录下的bzImage 文件是新编译生成的内核文件。make modulesmake modules# make modules
使用“make modules”命令编译内核模块,编译过程将持续相当长的时间(10分钟以上)。
make modules_installmake modules_install# make modules_install
内核模块编译好后需要安装到Linux系统的相应目录中才可以使用,使用“make modules_install”命令安装内核模块 。
/lib/modules/
“/lib/modules/ ”目录用于存放Linux系统中的内核模块,内核的各版本都在该目录下建有子目录用于存放内核模块。make installmake install# make install
使用“make install”命令安装新内核到系统中 ,并且自动为使用新内核做必要的配置。
vmlinuz-2.6.38
新编译的内核被放在目录“/boot/ ”中,各内核版本有唯一的文件名称,与内核文件配合使用的initrd映像文件也在此目录中。GRUB引导配置 GRUB引导配置 /etc/grub.conf
内核安装过程已经在GRUB启动引导器的配置文件 “grub.conf”中对新内核的引导进行了适当的配置:
title CentOS (2.6.38)
root (hd0,0)
kernel /boot/vmlinuz- 2.6.38 ro root=LABEL=/
initrd /boot/initrd- 2.6.38.imgGRUB引导配置 GRUB引导配置 /boot/grub/grub.cfg
menuentry 'Ubuntu, with Linux 2.6.37' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 4bc6c473-abc7-4883-b6c9-1873b8e51e63
linux /boot/vmlinuz-2.6.37 root=UUID=4bc6c473-abc7-4883-b6c9-1873b8e51e63 ro quiet splash
initrd /boot/initrd.img-2.6.37
}
Linux内核模块Linux内核模块Linux操作系统的内核是单一体系结构(monolithic kernel)
有了模块机制后,提高Linux操作系统的可扩充性,内核编程不再是一个恶梦
什么是模块呢?
模块的全称是“动态可加载内核模块”(Loadable Kernel Module,LKM)
模块在内核空间运行
模块实际上是一种目标对象文件
没有链接,不能独立运行,但是其代码可以在运行时链接到系统中作为内核的一部分运行或从内核中取下,从而可以动态扩充内核的功能
这种目标代码通常由一组函数和数据结构组成
Linux内核模块的优点与缺点Linux内核模块的优点与缺点优点
使得内核更加紧凑和灵活
修改内核时,不必全部重新编译整个内核。系统如果需要使用新模块,只要编译相应的模块,然后使用insmod将模块装载即可
模块的目标代码一旦被链接到内核,它的作用域和静态链接的内核目标代码完全等价
缺点
装入内核的模块就成为内核的一部分,可以修改内核中的其他部分,因此,模块的使用不当会导致系统崩溃;
为了让内核模块能访问所有内核资源,内核必须维护符号表,并在装入和卸载模块时修改符号表;
模块会
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
利用其它模块的功能,所以,内核要维护模块之间的依赖性.Linux内核模块与应用程序的区别Linux内核模块与应用程序的区别 C语言程序 Linux内核模块
运行 用户空间 内核空间
入口 main() module_init()指定;
出口 无 module_exit()指定;
编译 gcc –c Makefile
连接 ld insmod
运行 直接运行 insmod
调试 gdb kdbug, kdb, kgdb等 模块相关命令 模块相关命令 insmod
[module parameters]
Load the module
注意,只有超级用户才能使用这个命令
rmmod modulename
Unload the module
lsmod
List all modules loaded into the kernel
这个命令和cat /proc/modules等价
modprobe [-r]
– Load the module specified and modules it depends模块依赖模块依赖一个模块A引用另一个模块B所导出的符号,我们就说模块B被模块A引用。
如果要装载模块A,必须先要装载模块B。否则,模块B所导出的那些符号的引用就不可能被链接到模块A中。这种模块间的相互关系就叫做模块依赖。导出符号表导出符号表如果一个模块需要向其他模块导出符号(方法或全局变量),需要使用:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
*注意:符号必须在模块文件的全局部分导出,不能在函数部分导出。更多信息可参考 文件
Modules仅可以使用由Kernel或者其他Modules导出的符号不能使用Libc
/proc/kallsyms 可以显示所有导出的符号
最简单的内核模块例子最简单的内核模块例子#include
#include
#include
MODULE_LICENSE(“GPL”);
static int _ _init hello_init(void)
{
printk(KERN_INFO "Hello world\n");
return 0;
}
static void _ _exit hello_exit(void)
{
printk(KERN_INFO "Goodbye world\n");
}
module_init(hello_init);
module_exit(hello_exit);nullInit/exit
宏:module_init/module_exit
声明模块初始化及清除函数所在的位置
装载和卸载模块时,内核可以自动找到相应的函数
module_init(hello_init);
module_exit(hello_exit);编译内核模块编译内核模块Makefile文件
obj-m := hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
Module includes more files
obj-m:=hello.o
hello-objs := a.o b.o装载和卸载模块装载和卸载模块相关命令
lsmod
insmod hello.ko
rmmod hello.konullLinux内核学习起步
内核阅读心得
深入理解linux内核课外阅读