内核开发基础

1、Linux内核简介

a、Linux系统是如何构成的?

Linux系统可以分成用户空间和内核空间
用户空间:用户程序,C库;
内核空间:内核,系统调用接口,体系结构相关代码;

b、为什么Linux系统会被划分为用户空间与内核空间?

现代CPU通常实现了不同的工作模式,以ARM为例,实现了7种工作模式:
系统模式(Sys),用户模式(Usr)、管理模式(Svc)、外部中断模式(Irq)、快速中断模式(Fiq)、数据访问中止模式(abt)、未定义指令异常模式(und);X86也实现了4个不同的级别:Ring0——Ring3。Ring0下,可以执行特权指令,可以访问IO设备等,在Ring3则有很多限制。Linux系统利用了CPU这一特性,使用了其中的两极来分别运行Linux内核与应用程序,这样是 操作系统本身得到充分的保护。例如:如果使用X86,用户代码运行在Ring3,内核代码运行在Ring0。

c、内核空间与用户空间是程序执行的两种不同的状态,通过系统调用和硬件中断能够完成从用户空间到内核空间的转移。

d、Linux内核是如何构成的?

(7个部分):1>系统调用接口(SCI):SCI层为用户空间提供了一套标准的系统调用函数来访问Linux内核,搭起了用户空间到内核空间的桥梁。
              
2>进程管理(PM):进程管理的重点是创建进程(fork,exec),停止进程(kill,exit),并控制他们之间的通信(signal或者POSIX机制)。进程管理还包括控制进程如何共享CPU,即进程调度。

3>内存管理(MM):内存管理的主要作用是控制多个进程安全的共享内存区域,对内存回收,映射管理。

4>虚拟文件系统(VFS):VFS隐藏各种文件系统的具体细节,为文件操作提供统一的接口。

5>架构体系相关代码(Arch):内核所支持的各种CPU体系的相关代码,跨平台移植时需要修改。

6>网络协议栈(NS):网络协议栈为Linux提供了丰富的网络协议实现。

7>设备驱动(DD):Linux内核有大量代码都在设备驱动程序中,他们控制特定的硬件设备。

2、Linux内核源代码

Linux内核源代码采用树形结构进行组织,非常合理地把功能相关的文件都放在同一个子目录下,使得程序更具有可读性。内核源代码下载地址: www.kernel.org

1> arch目录:architecture的缩写。 内核所支持的每种CPU体系,在该目录下都有对应的子目录。每个CPU的子目录,又进一步分解为boot,mm,kernel等子目录,分别包含控制系统引导,内存管理,系统调用等。

2>block目录:部分块设备驱动程序。

3>crypto目录:加密、压缩,CRC校验算法。

4>documention:内核的文档。

5> drivers目录:设备驱动程序。

6>fs目录:存放各种文件系统的实现代码,每个子目录对应一种文件系统的实现,公用的源程序用于实现虚拟文件系统VFS。

||--devpts:/dev/pts虚拟文件系统

||--ext2:第二扩展文件系统

||--fat:MS的fat32文件系统

||--isofs:ISO9660光盘cd-rom上的文件系统

7>include目录:内核所需要的头文件。 与平台无关的头文件在include/linux子目录下,与平台有关的头文件则放在相应的子目录中。

8>lib目录:库文件代码。

9>mm目录:mm目录中的文件用于实现内存管理中与 体系结构无关的部分。体系结构有关的部分在arch目录。

10>net目录:网络协议的实现代码
||--802:802无线通讯协议核心支持代码

||--appletalk:与苹果系统联网的协议

||--ax25:AX25无线INTERNET协议

||--bridge:桥接设备

||--ipv4:IP协议族V4版32位寻址模式

||--ipv6:IP协议族V6版

11>samples:一些内核编程的范例。

12>scripts:配置内核的脚本。

13>security:SElinux的模块。

14>sound:音频设备的驱动程序。

15>usr:cpio命令实现。用于制作根文件系统的,把文件系统和内核放置一起的命令。是用户程序。

16>virt:内核虚拟机。


3、LInux内核配置与编译(必备技能)
Linux内核具有可制订的优点,具体步骤如下:

1>清除临时文件,中间文件和配置文件。

make clean
    remove most genrated files but keep the config(删除大多数产生的文件保存配置文件)

make mrproer
    remove all generated files + config files(删除所有产生的文件包括配置文件)

make distclean
    mrproper + remove editor backup and patch files

2>确定目标系统的软硬件配置情况,比如CPU的类型、网卡的型号、所需支持的网络协议等。

3>使用如下命令之一配置内核:

make config:基于文本模式的交互式配置 。

*  make menuconfig:基于文本模式的菜单型配置。(推荐使用)

make oldconfig: 使用已有的配置文件(.config),但是会询问新增的配置选项。

make xconfig: 图形化的配置(需安装图形化系统)。

4> make menuconfig是最为常用的内核配置方式,使用方法如下:

a>使用方向键在各选项间移动;

b>使用ENTER键进入下一层选单;每个选项上的高亮字母是键盘快捷方式,使用它可以快速地达到想要设置的选单项。

c> 在括号中按“y”将这个项目编译进内核中,按“m”编译为模块,按“n”为不选择(按空格键也可在编译进内核、编译为模块和不编译三者间进行切换),按“h”将显示这个选项的帮助信息,按“Esc”键将返回到上层选单。

5>配置菜单中的项该怎么选择呢?

Code maturity level options(代码成熟度选项)
Prompt for debelopment and/or incomplete code/drivers
    显示尚在开发中或尚未完成的代码与驱动,除非你是测试人员或者开发者,否则请勿选择。

General setup(常规设置)
Local version-append to kernel release
    在内核版本后面加上自定义的版本字符串(小于64字符)可以用“uname -a”命令看到
Automatically append version ingormation to the version string
    自动在版本字符串后面添加版本信息,编译时需要perl以及git仓库支持
Support for paging of anonymous memory(swap)
    使用交换分区或者交换文件来作为虚拟内存
System V IPC
    System V 进程间通信(IPC)支持许多程序需要这个功能建议选
POSIX Message Queues
    POSIX消息队列支持
BSD Process Accounting
    将进程的统计信息写入文件的用户级系统调用,主要包括进程的创建时间/创建者/内存占用等信息
          BSD Process Accounting version 3 file format
        使用新的第三版文件格式,可以包含每个进程的PID和其父进程的PID但是不兼容老版本的文件格式
Export task/process statics through netlink

Loadable module support(可加载模块支持)

Enable loadable module support
    打开可加载模块支持,如果打开它则必须通过“make modules install”把内核模块安装在/lib/modules/中
     Module unloading
    允许卸载已经加载的模块
     Forced module unloading
    允许强制卸载正在使用中的模块(比较危险)
         Module versioning support
    允许使用其他版本的模块(可能会出问题)
             Source checksum for all modules
    为所有的模块校验源码,如果你不是自己编写内核就不需要它
                 Automatic kernel module loading
    让内核通过运行modprobe来自动加载所需要的模块,比如可以自动解决模块的依赖关系

块设备、CPU类型、电源管理、总线、可执行文件的格式、网络、


内核配置通常在一个已有的配置文件基础上,通过修改得到新的配置文件,Linux内核提供了一系列可供参考的内核配置文件位于Arch/$cpu/configs

4>编译内核:

make zImage     make  bzImage
区别:在X86平台,zImage只能用于小于512K的内核

如果想获取详细编译信息,可使用: make zImage V = 1  make bzImage V = 1

编译好的内核位于arch/<cpu>/boot/目录下

5>编译内核模块: make modules

6>安装内核模块: make modules_install
将编译好的内核模块从内核源代码目录copy至/lib/nodules下。

7>制作init ramdisk
mkinitrd initrd-$version $version
例:
    mkinitrd initrd-2.6.29  2.6.29
$version可以通过查询/lib/modules下的目录得到。


8>内核安装( X86

a、cp arch/x86/boot/bzImage/boot/vmlinuz-$version

b、cp $initrd/boot/

c、修改/etc/grub.conf或者/etc.lilo.conf

$version为所编译的内核版本号


4、内核模块开发

1>什么是内核模块?
    Linux内核的整体结构非常庞大,其他包含的组件也非常多,如何使用需要的组件呢:

方法一:把所有的组件都编译进内核文件,即zImage或bzImage,但这样会导致两个问题: 一是生成的内核文件过大;二是如果要添加或删除耨个组件,需要重新编译整个内核。

方法二:有一种机制( 内核模块机制)能让内核文件(zImage或bzImage) 本身并不包含某个组件,而是该组件需要被使用的时候,动态的添加到正在运行的内核中。

2>内核模块特点

*模块本身并不被编译进内核文件(zImage或者bzImage)
*可以根据需求,在内核运行期间动态的安装或卸载。

#include<linux/init.h>
#include<linux/module.h>

static int hello_init(void)
{
    printk(KERN_WARNING"Hello,world!\n");
    return 0;
}

static void hello_exit(void)
{
    printk(KERN_INFO"Goodbye,world\n");
}

module_init(hello_init);
module_exit(hello_exit);

1、模块加载函数(必需)
安装模块时被系统自动调用的函数,通过module_init宏来指定。

2、模块卸载函数(必需)
卸载模块时被系统自动调用的函数,通过module_exit宏来指定。

在Linux2.6下编译一般使用makefile编译模块。

/*makefile*/
****************************************************************************
ifneq ($(KERNELRELEASE),)

obj-m := hello.o

else

KDIR := /lib/modules/2.6.18-53.e15/build
all:
        make -C $(KDIR) M=$(PWD)modules
clean:
        rm -f *.ko *.o *.mod.o *.symvers

endif
***************************************************************

内核模块时多个源文件的makefile
***************************************************************

ifneq ($(KERNELRELEASE),)

obj-m :=mymodule.o
mymodule-objs := main.o add.o

else

KDIR := /lib/modules/2.6.18-53.e15/build
all:
        make -C $(KDIR) M=$(PWD)modules
clean:
        rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif

***************************************************************************
安装于卸载

加载insmod(insmod hello.ko)
卸载rmmod(rmmod hello)
查看lsmod
加载modprobe(modprobe hello)

modprobe如同insmod,也是加载一个模块到内核。它的不同之处在于它会根据文件
/lib/modules/<$version>/modules.dep来查看要加载的模块,看是否还依赖于其他模块,如果是会首先找到这些模块,把它们加载到内核。

模块可选信息

1>许可证信息

MODULE_LICENSE用来告知内核,该模块带有一个许可证,没有这样的说明,加载模块时内核会抱怨。有效的许可证有“GPL”、“GPLv2”“GPL and additional rights”、“DualBSD/GPL”
“Dual MPL/GPL”和“Proprietary”。

2>作者申明(可选)
MODULE_AUTHOR(“Simon Li”);

3>模块描述(可选)
MODULE_DESCRIPTION("Hello World")

4>模块版本(可选)
MODULE_VERSION("V1.0")

5>模块别名(可选)
MODULE_ALIAS("a simple module");

6>模块参数
通过 module_param指定模块参数用于在加载模块时传递参数模块。
module)param(name,type,perm)
name是模块参数的 名称,type是这份参数的 类型,perm是模块参数的 访问权限
type常见值:
bool:int: charp:

perm常见值:
S_IRUGO:任何用户都对/sys/module中出现的该参数具有读权限
S_IWUSR:允许root用户修改/sys/module中出现的该参数

例如:
int a = 3;
char* st;
module_param(a,int,S_IRUGO);
module_param(st,charp,S_IRUGO);

7>内核符号导出
/proc/kallsyms记录了内核中所有导出的符号的名字与地址。
EXPORT_SYMBOL(符号名)
EXPORT_SYMBOL_GPL(符号名)
其中EXPORT_SYMBOL_GPL只能用于包含GPL许可证的模块。

8>常见的问题
版本不匹配:disagrees about version of symbol struct_module insmod:error inserting 'hello.ko':-1 Invalid module format

解决办法:
1、使用modprobe--force-modversion强行插入
2、确保编译内核模块时,所依赖的内核代码版本等同于当前正在运行的内核。
可通过uname -r查看当前运行的版本号。

总结--对比应用

对比应用程序,内核模块具有以下不同:
医用程序是从头到尾执行任务,执行结束后从内存中消失。内核模块是现在内核中注册自己以便服务于将来的某个请求,然后它的初始化函数结束,此时模块任然存在于内核中,知道卸载函数调用,模块才从内核中国消失。
内核打印:
pringk是内核中出现最频繁的函数之一,通过printk与printf对比,将有助于理解。
不同点:printk在内核中使用,printf在应用程序中使用,printk允许根据严重程度,通过附加不同的“优先级”来对消息分类。

在<linux/kernel.h>中定义了8中记录级别。按照优先级递减的顺序分别是:
KERN_EMERG<0>用于紧急消息,常常是那些崩溃前的消息。
KERN_ALERT<1>需要立刻行动的消息。
KERN_CRIT<2>严重情况。
KERN_ERR<3>错误情况。
KERN_WARNING<4>有问题的警告
KERN_NOTICE<5>正常情况,但是任然值得注意
KERN_INFO<6>信息型消息。
KERN_DEBUG<7>用作调试消息。

没有指定优先级的printk默认使用DEFAULT_MESSAGE_LOGLEVEL优先级,它是一个在kernel/printk.c中定义的整数。在2.6.29内核中#define DEFAULT_MESSAGE_LOGLEVEL 4。

控制优先级配置
/proc/sys/kernel/printk
6 4 1 7
*Console_loglevel
*Default_message_loglevel
*Minimim_console_level
*Default_console_loglevel



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类型管理页面显示所有任务资讯公告类型,在此页面既可以让管理员添加新的任务资讯公告信息类型,也能对已有的任务资讯公告类型信息执行编辑更新,失效的任务资讯公告类型信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值