《LINUX内核开发(一)》由会员分享,可在线阅读,更多相关《LINUX内核开发(一)(71页珍藏版)》请在金锄头文库上搜索。
1、LINUX 内核开发-1,Contents,Linux内核简介,Linux内核启动流程,Linux内核源代码,Linux内核配置与编译,Linux内核模块开发,Contents,Linux内核简介,Linux内核启动流程,Linux内核源代码,Linux内核配置与编译,Linux内核模块开发,Linux体系结构,Linux系统如何构成的?,Linux体系结构,Linux体系结构,从上图得知,Linux由 用户空间和内核空间两部分组成。为什么Linux系统会被划分为用户空间与内核空间?,Linux体系结构,现代CPU通常实现了不同的工作模式,以 ARM为例,实现了7种工作模式: 用户模式(usr
2、)、快速中断(fiq)、外部中断 (irq)、管理模式(svc)、数据访问中止 (abt)、系统模式(sys)、未定义指令异常(und),Linux体系结构,X86也实现了4个不同的级别:Ring0Ring3。Ring0下,可以执行特权指令,可以访问IO设备等,在Ring3则有很多限制。Linux系统利用了CPU的这一特性,使用了其中的两级来分别运行Linux内核与应用程序,这样使操作系统本身得到充分的保护。例如:如果使用X86,用户代码运行在Ring3,内核代码运行在Ring0。,Linux体系结构,内核空间与用户空间是程序执行的两种不同状态,通过系统调用和硬件中断能够完成从用户空间到内核空
3、间的转移。Linux内核如何构成的?,Linux内核架构,系统调用接口,SCI 层为用户空间提供了一套标准的系统调用函数来访问Linux内核,搭起了用户空间到内核空间的桥梁。,进程管理,进程管理的重点是创建进程(fork、exec),停止进程(kill、exit),并控制它们之间的通信(signal 或者 POSIX 机制)。进程管理还包括控制活动进程如何共享CPU,即进程调度。,内存管理,内存管理的主要作用是控制多个进程安全地共享内存区域。,网络协议栈,内核协议栈为Linux提供了丰富的网络协议实现。,虚拟文件系统(VFS),VFS隐藏各种文件系统的具体细节,为文件操作提供统一的接口。,虚拟
4、文件系统,应用程序,Ext2,设备文件,FAT,NFS,设备驱动,Linux 内核中有大量代码都在设备驱动程序中,它们控制特定的硬件设备。,Contents,Linux内核简介,Linux内核启动流程,Linux内核源代码,Linux内核配置与编译,Linux内核模块开发,目录结构,Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具可读性。内核源代码下载地址: www.kernel.org,目录结构,目录结构(展示),arch目录arch是architecture的缩写。内核所支持的每种CPU体系,在该目录下都有对应的子目录。每个CPU的子目
5、录,又进一步分解为boot,mm,kernel等子目录,分别包含控制系统引导,内存管理,系统调用等。,目录结构,| -x86 /* 英特尔cpu及与之相兼容体系结构的子目录*/ | |-boot /*引导程序*/ | | |-compressed /*内核解压缩*/ | |-tools /*生成压缩内核映像的程序*/ | |-kernel /*相关内核特性实现方式,如信号处理、时钟处理*/ | |-lib /*硬件相关工具函数*/,目录结构,block目录部分块设备驱动程序crypto目录加密、压缩、CRC校验算法documentation内核的文档drivers目录设备驱动程序,fs目录存放
6、各种文件系统的实现代码。每个子目录对应一种文件系统的实现,公用的源程序用于实现虚拟文件系统vfs。| |-devpts /* /dev/pts虚拟文件系统*/ | |-ext2 /*第二扩展文件系统*/ | |-fat /*MS的fat32文件系统*/ | |-isofs /*ISO9660光盘cd-rom上的文件系统*/ include目录内核所需要的头文件。与平台无关的头文件在include/linux 子目录下,与平台相关的头文件则放在相应的子目录中。,目录结构,init目录内核初始化代码ipc目录进程间通信的实现代码kernel目录Linux大多数关键的核心功能都是在这个目录实现。(调
7、度程序,进程控制,模块化),目录结构,目录结构,lib目录库文件代码mm目录mm目录中的文件用于实现内存管理中与体系结构无关的部分(与体系结构相关的部分在哪里实现?),目录结构,net目录网络协议的实现代码 | |-802 /*802无线通讯协议核心支持代码*/ | |-appletalk /*与苹果系统连网的协议*/ | |-ax25 /*AX25无线INTERNET协议*/ | |-bridge /*桥接设备*/ | |-ipv4 /*IP协议族V4版32位寻址模式*/ | |-ipv6 /*IP协议族V6版*/,目录结构,samples一些内核编程的范例scripts配置内核的脚本sec
8、uritySElinux的模块,目录结构,sound音频设备的驱动程序usrcpio命令实现virt内核虚拟机,Contents,Linux内核简介,Linux内核启动流程,Linux内核源代码,Linux内核配置与编译,Linux内核模块开发,Linux内核具有可定制的优点,具体步骤如下: 1. 清除临时文件、中间文件和配置文件. make cleanremove most generated files but keep the config make mrproperremove all generated files + config files make distcleanmrpro
9、per + remove editor backup and patch files,内核配置与编译,2、确定目标系统的软硬件配置情况,比如CPU的类型、网卡的型号,所需支持的网络协议等。 3、使用如下命令之一配置内核:make config:基于文本模式的交互式配置。make menuconfig:基于文本模式的菜单型配 置。(推荐使用),内核配置与编译,make oldconfig:使用已有的配置文件(.config),但是会询问新增的配置选项。make xconfig:图形化的配置(需安装图形化系统)。,内核配置与编译,内核配置与编译,make menuconfig 是最为常用的内核配置
10、方式,使用方法如下:1、使用方向键在各选项间移动;2、使用“Enter”键进入下一层选单;每个选项上的高亮字母是键盘快捷方式,使用它可以快速地到达想要设置的选单项。,内核配置与编译,3、在括号中按“y”将这个项目编译进内核中,按“m”编译为模块,按“n”为不选择(按空格键也可在编译进内核、编译为模块和不编译三者间进行切换),按“h”将显示这个选项的帮助信息,按“Esc”键将返回到上层选单。,内核配置与编译,配置菜单中的项该怎么选择呢?,内核配置与编译,配置选项说明,内核配置通常在一个已有的配置文件基 础上,通过修改得到新的配置文件 Linux内核提供了一系列可供参考的内 核配置文件,位于Arc
11、h/$cpu/configs,内核配置与编译,内核配置与编译,4、编译内核: make zImage make bzImage区别:在X86平台,zImage只能用于小于512K的内核*如需获取详细编译信息,可使用: make zImage V=1 make bzImage V=1* 编译好的内核位于arch/boot/目录下 *,5、编译内核模块: make modules 6、安装内核模块 make modules_install*将编译好的内核模块从内核源代码目录copy至/lib/modules下*,内核配置与编译,7、制作init ramdiskmkinitrd initrd-$ve
12、rsion $version 例:mkinitrd initrd-2.6.29 2.6.29*$version 可以通过查询/lib/modules下的目录得到,内核配置与编译,内核安装(X86平台),1、cp arch/x86/boot/bzImage /boot/vmlinuz-$version 2、cp $initrd /boot/ 3、修改/etc/grub.conf 或者 /etc/lilo.conf* $version 为所编译的内核版本号*,Linux内核配置与编译配置、编译、安装 基于PC平台的Linux内核,实验,Contents,Linux内核简介,Linux内核启动流程,
13、Linux内核源代码,Linux内核配置与编译,Linux内核模块开发,功能,什么是内核模块?Linux内核的整体结构非常庞大,其包含的组件也非常多,如何使用需要的组件呢:方法一:把所有的组件都编译进内核文件,即:zImage或bzImage,但这样会导致两个问题:一是生成的内核文件过大;二是如果要添加或删除某个组件,需要重新编译整个内核。,功能,有没有一种机制能让内核文件(zImage或bzImage)本身并不包含某组件,而是在该组件需要被使用的时候,动态地添加到正在运行的内核中呢?有,Linux提供了一种叫做“内核模块”的机制,就可以实现以上效果。,特点,内核模块具有如下特点: 模块本身并
14、不被编译进内核文件(zImage或者bzImage) 可以根据需求,在内核运行期间动态的安装或卸载。,范例(hello world),#include #include static int hello_init(void) printk(KERN_WARNING“Hello, world !n“);return 0; static void hello_exit(void) printk(KERN_INFO “Goodbye, worldn“); module_init(hello_init); module_exit(hello_exit);,程序结构,1、模块加载函数(必需)安装模块时被
15、系统自动调用的函数,通过module_init宏来指定,在HelloWorld模块中,模块加载函数为 ?,程序结构,2、模块卸载函数(必需)卸载模块时被系统自动调用的函数,通过module_exit宏来指定,在HelloWorld模块中,模块卸载函数为 ?,模块的编译,在Linux 2.6下编译模块,多使用makefile范例 makefile 分析范例 多文件makefile 分析,安装与卸载,加载 insmod (insmod hello.ko) 卸载 rmmod (rmmod hello) 查看 lsmod 加载 modprobe (modprobe hello)modprobe 如同
16、insmod, 也是加载一个模块到内核。它的不同之处在于它会根据文件/lib/modules/modules.dep来查看要加载的模块, 看它是否还依赖于其他模块,如果是,modprobe 会首先找到这些模块, 把它们先加载到内核。,对比,对比应用程序,内核模块具有以下不同:应用程序是从头(main)到尾执行任务,执行结束后从内存中消失。内核模块则是先在内核中注册自己以便服务于将来的某个请求,然后它的初始化函数结束,此时模块仍然存在于内核中,直到卸载函数被调用,模块才从内核中消失。,模块可选信息,1、许可证申明宏MODULE_LICENSE用来告知内核, 该模块带有一个许可证,没有这样的说明,加载模块时内核会抱怨。有效的许可证有“GPL“、“GPL v2“、“GPL and additional rights“、“Dual BSD/GPL“、“Dual MPL/GPL“和“Proprietary“。,