论文部分内容阅读
摘要:随着嵌入式系统越来越广泛的应用,Linux由于其自身的特点成为最受欢迎的嵌入式操作系统之一。该文阐述了Linux在嵌入式系统中的应用,重点介绍了Linux可加载内核模块机制的基本原理和特点,以及编写和加载内核模块基本方法。
关键词:嵌入式Linux内核;可加载
中图分类号:TP316文献标识码:A文章编号:1009-3044(2008)26-1759-02
1 引言
一直以来,Linux操作系统以其开源性、稳定性、安全性和漏洞少等优良性能受到很多专业技术人员和公司的好评。而随着嵌入式技术的发展及广泛应用,Linux也由于其体积小、易于裁减、运行速度高和网络性能良好等优点成为嵌入式系统常用的操作系统之一,其中它的可加载内核模块机制体现出了强大的功能。
2 Linux在嵌入式系统中的应用
嵌入式系统(Embedded Systems)是计算机的一种应用形式,它是指“以具体应用为中心,以计算机和信息技术的发展为基础,将用户所需的特点功能嵌入到产片、装置或大型系统中,软硬件可裁剪,从而能够适应实际应用中对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统”。
正是由于嵌入式系统的应用特点,它对操作系统的要求并不同于一般的计算机系统。首先不同的宿主设备对嵌入式系统的要求都不一样,因此嵌入式操作系统的功能要足够强大,才能应付各种各样不同场合的使用。同时由于系统资源非常有限,嵌入式操作系统又必须满足精简高效、占用资源少、响应速度快的特点。对于设备控制系统,还有很重要的一个要求就是安全性和稳定性要好,不允许在控制过程中经常出现故障。
作为真正的32位操作系统,Linux能够很好地满足嵌入式系统的需要。Linux的可加载内核模块机制,支持设计人员可以根据不同嵌入式系统的需要,在不同的场合动态地选择不同功能的内核模块进行加载,内核可控制在100KB以内,这样既可实现对不同需求的支持,又可以一定程度上保证系统内核的精简,更好地实现操作系统功能专一而高效、高度节约资源、启动速度快、节省开发成本等目标。
3 Linux可加载内核模块机制
内核是Linux操作系统的核心,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
当Linux系统要实现对某种特定功能的支持时,可以把相应部分编译到内核中,也可以把该部分编译成模块。如果编译到内核中,在内核启动时就可以自动支持相应部分的功能,但是会使内核变得庞大起来。如果编译成模块,就会生成对应的.ko文件,在需要使用时进行动态加载,这样就不会使内核过分庞大。所以通常将经常使用的部分直接编译到内核中,偶尔需要使用的部分作为动态可加载内核模块使用。
使用这种可加载内核模块机制,内核模块在需要时才加载到内核空间,不需要的时候可以释放内存资源,这样可以使内核更小更精简,从而避免占据太多的内核空间。而当需要添加内核功能时,只需要添加编译模块代码就可以了,不需要对基本内核进行频繁的改动。
对这种可加载内核模块的访问主要是通过内核中的一个全局变量module_list实现的。每当用户将一个模块加载到内核中时,这个模块就会被添加到由module_list形成的链表中。每当内核要使用到这个模块所提供的函数时,内核就会检索这个链表,找到相应的模块中的函数或变量。内核将资源登记在符号表中,模块可通过符号表使用核心资源。当模块加载入内核时,系统将新加载模块提供的资源和符号加到内核符号表中,通过这种通信机制,模块之间可以实现资源的互相访问。
4 内核模块的实现
4.1 内核模块的编写
一个内核模块至少要包含两个函数:用于加载时的模块初始化函数init_module()和用于卸載的模块结束函数cleanup_module()。实际应用中这两个函数可以用任意函数名代替,但是必须在函数定义后用宏module_init()和module_exit()进行声明,如:
static int __init lcd_init(void){…}
static void __exit lcd_exit(void){…}
module_init(lcd_init );
module_exit(lcd_exit);
4.2 内核模块的编译
编译时需要通过一个Makefile文件来完成,其具体内容可参考下面生成lcd.ko的Makefile文件:
obj -m =lcd.ko
KDIR :=/usr/arc/linux-2.6
PWD :=$(shell pwd)
Default:
$(MAKE) -C $(KDIR)SUBDIRS=$(PWD) modules
Makefile文件必须跟目标源文件放在同一个目录下,执行Make命令来完成该模块的编译,生成相应的.ko文件。
4.3 内核模块的加载和卸载
当需要使用某个模块的功能时,可以使用insmod命令进行加载。此时模块从用户态进入到内核态,insmod程序找到要求加载的内核模块,首先将其输出符号在内核中的相应地址进行修改,然后为新模块申请足够的内核内存空间,并更新其符号表,然后内核调用模块的初始化函数完成模块的安装。
模块使用完后可以用rmmod命令卸载,此模块占用的内核内存将被回收。但是内核中其他部分还在使用的模块是不能被卸载的。
5 结束语
对于Linux的可加载内核模块机制及应用,涉及到的知识非常广泛,并不是这里简单的几句话就能够深入分析清楚。本文在介绍了Linux内核机制的基本原理的基础上,简单说明了内核模块的编写和编译过程,供广大爱好者为更好地进一步学习Linux打下良好的基础。
参考文献:
[1] 陈莉君.深入分析Linux源码[M].北京:中国电力出版社,2004.
[2] 李善平,刘文峰.Linux与嵌入式系统[M].北京:清华大学出版社,2003.
[3] 周应华.对Linux可加载内核模块应用框架的研究[J].计算机系统应用,2007,(4):69-72,76.
[4] 陈刚,卢显良.基于Linux-2.6内核模块程序设计[J].福建电脑,2004,(6):16-17.
[5] 刘天华,陈枭.Linux可加载内核模块机制的研究与应用[J].微计算机信息,2007,(20):55-56,134.
关键词:嵌入式Linux内核;可加载
中图分类号:TP316文献标识码:A文章编号:1009-3044(2008)26-1759-02
1 引言
一直以来,Linux操作系统以其开源性、稳定性、安全性和漏洞少等优良性能受到很多专业技术人员和公司的好评。而随着嵌入式技术的发展及广泛应用,Linux也由于其体积小、易于裁减、运行速度高和网络性能良好等优点成为嵌入式系统常用的操作系统之一,其中它的可加载内核模块机制体现出了强大的功能。
2 Linux在嵌入式系统中的应用
嵌入式系统(Embedded Systems)是计算机的一种应用形式,它是指“以具体应用为中心,以计算机和信息技术的发展为基础,将用户所需的特点功能嵌入到产片、装置或大型系统中,软硬件可裁剪,从而能够适应实际应用中对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统”。
正是由于嵌入式系统的应用特点,它对操作系统的要求并不同于一般的计算机系统。首先不同的宿主设备对嵌入式系统的要求都不一样,因此嵌入式操作系统的功能要足够强大,才能应付各种各样不同场合的使用。同时由于系统资源非常有限,嵌入式操作系统又必须满足精简高效、占用资源少、响应速度快的特点。对于设备控制系统,还有很重要的一个要求就是安全性和稳定性要好,不允许在控制过程中经常出现故障。
作为真正的32位操作系统,Linux能够很好地满足嵌入式系统的需要。Linux的可加载内核模块机制,支持设计人员可以根据不同嵌入式系统的需要,在不同的场合动态地选择不同功能的内核模块进行加载,内核可控制在100KB以内,这样既可实现对不同需求的支持,又可以一定程度上保证系统内核的精简,更好地实现操作系统功能专一而高效、高度节约资源、启动速度快、节省开发成本等目标。
3 Linux可加载内核模块机制
内核是Linux操作系统的核心,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
当Linux系统要实现对某种特定功能的支持时,可以把相应部分编译到内核中,也可以把该部分编译成模块。如果编译到内核中,在内核启动时就可以自动支持相应部分的功能,但是会使内核变得庞大起来。如果编译成模块,就会生成对应的.ko文件,在需要使用时进行动态加载,这样就不会使内核过分庞大。所以通常将经常使用的部分直接编译到内核中,偶尔需要使用的部分作为动态可加载内核模块使用。
使用这种可加载内核模块机制,内核模块在需要时才加载到内核空间,不需要的时候可以释放内存资源,这样可以使内核更小更精简,从而避免占据太多的内核空间。而当需要添加内核功能时,只需要添加编译模块代码就可以了,不需要对基本内核进行频繁的改动。
对这种可加载内核模块的访问主要是通过内核中的一个全局变量module_list实现的。每当用户将一个模块加载到内核中时,这个模块就会被添加到由module_list形成的链表中。每当内核要使用到这个模块所提供的函数时,内核就会检索这个链表,找到相应的模块中的函数或变量。内核将资源登记在符号表中,模块可通过符号表使用核心资源。当模块加载入内核时,系统将新加载模块提供的资源和符号加到内核符号表中,通过这种通信机制,模块之间可以实现资源的互相访问。
4 内核模块的实现
4.1 内核模块的编写
一个内核模块至少要包含两个函数:用于加载时的模块初始化函数init_module()和用于卸載的模块结束函数cleanup_module()。实际应用中这两个函数可以用任意函数名代替,但是必须在函数定义后用宏module_init()和module_exit()进行声明,如:
static int __init lcd_init(void){…}
static void __exit lcd_exit(void){…}
module_init(lcd_init );
module_exit(lcd_exit);
4.2 内核模块的编译
编译时需要通过一个Makefile文件来完成,其具体内容可参考下面生成lcd.ko的Makefile文件:
obj -m =lcd.ko
KDIR :=/usr/arc/linux-2.6
PWD :=$(shell pwd)
Default:
$(MAKE) -C $(KDIR)SUBDIRS=$(PWD) modules
Makefile文件必须跟目标源文件放在同一个目录下,执行Make命令来完成该模块的编译,生成相应的.ko文件。
4.3 内核模块的加载和卸载
当需要使用某个模块的功能时,可以使用insmod命令进行加载。此时模块从用户态进入到内核态,insmod程序找到要求加载的内核模块,首先将其输出符号在内核中的相应地址进行修改,然后为新模块申请足够的内核内存空间,并更新其符号表,然后内核调用模块的初始化函数完成模块的安装。
模块使用完后可以用rmmod命令卸载,此模块占用的内核内存将被回收。但是内核中其他部分还在使用的模块是不能被卸载的。
5 结束语
对于Linux的可加载内核模块机制及应用,涉及到的知识非常广泛,并不是这里简单的几句话就能够深入分析清楚。本文在介绍了Linux内核机制的基本原理的基础上,简单说明了内核模块的编写和编译过程,供广大爱好者为更好地进一步学习Linux打下良好的基础。
参考文献:
[1] 陈莉君.深入分析Linux源码[M].北京:中国电力出版社,2004.
[2] 李善平,刘文峰.Linux与嵌入式系统[M].北京:清华大学出版社,2003.
[3] 周应华.对Linux可加载内核模块应用框架的研究[J].计算机系统应用,2007,(4):69-72,76.
[4] 陈刚,卢显良.基于Linux-2.6内核模块程序设计[J].福建电脑,2004,(6):16-17.
[5] 刘天华,陈枭.Linux可加载内核模块机制的研究与应用[J].微计算机信息,2007,(20):55-56,134.