一.内核模块holle.c文件
#include <linux/module.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");
MODULE_DESCRIPTION("Hello World Module");
MODULE_ALIAS("a simplest module");
static int __init hello_init()
{
}
static void __exit hello_exit()
{
}
module_init(hello_init);
module_exit(hello_exit);
相应的makefile
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := /lib/modules/2.6.18-53.el5/build
all:
clean:
endif
多文件的makefile
ifneq ($(KERNELRELEASE),)
obj-m := mymodule.o
mymodule-objs := file1.o file2.o file3.o
else
KDIR := /lib/modules/2.6.18-53.el5/build
all:
clean:
endif
二,安装与卸载
加载:insmod(insmod hello.ko)
卸载:rmmod (rmmod hello)
查看:lsmod
加载:modprobe (modprobe hello)
它根据文件
/lib/modules/2.6.18-128.e15/modules.dep
来查看要加载的模块,看它是否还依赖于其他模块,如果是,modprobe会首先找到这些模块,把他们先加载倒内核。
三,许可证申明
如MODULE_LICENSE (“GPL”);
模块描述(可选)
MODULE_DESCRIPTION(“Hello world Module”);
模块版本(可选)
MODULE_VERSION(“V1.0”);
模块别名(可选)
MODULE_ALIAS(“a simple module”);
四,模块参数
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);
五.记录系统所有输出函数kallsyms。Proc是文件
/proc/kallsyms记录了内核中所有导出的符号的名字与地址(记录输出到系统当中可以给其他模块使用的函数的名字)
可以用cat /proc/kallsyms来查看
内核符号导出
EXPORT_SYMBOL(符号名)
EXPORT_SYMBOL_GPL(符号名)
其中EXPORT_SYMBOL_GPL只能用于包含GPL许可证的模块
例如
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
int add_integar(int a,int b)
{
}
int sub_integar(int a,int b)
{
}
static int __init sym_init()
{
}
static void __exit sym_exit()
{
}
module_init(sym_init);
module_exit(sym_exit);
EXPORT_SYMBOL(add_integar);
EXPORT_SYMBOL(sub_integar);
六.解决内核版本不匹配问题
方法:确保编译内核模块时,所依赖的内核代码版本等同于当前正在运行的内核
可通过uname –r察看当前运行的内核版本。
七.内核打印
1.printk只能用与内核打印,printf只能用于应用程序打印
printk是有优先级的。如下
KERN_EMERG
KERN_ALERT
KERN_CRIT
KERN_ERR
KERN_WARNINGb
KERN_INFO
KERN_DEBUG
优先级越高数字越小
如果没有设优先级,那默认优先级是4
2.控制台优先级配置
cat /proc/sys/kernel/printk
6 4 1 7
6 是控制台的优先级。。。打印信息的优先级要比它高才能打印出。
4 是默认的优先级
3.不管你的打印信息有没有打印,,,在
cat /var/log/messages 中都有记录
八.反汇编命令
Arm-linuc-objdump –D –S holle.ko –>log
如果想要用make编译是打印详细的信息。用make –V=1
九.进程和程序的区别
1.程序是存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体。
2.进程是一个执行中的程序,它是动态的实体
进程是分配资源的最小单位,线程是调度的最小单位
十.进程四要素:
1.有一段程序供其执行,这段程序不一定是某个进程专有,可以与其他进程公用。
2.有进程专用的内核空间堆栈。
3在内核中有一个task_struct数据结构,即通常所说的“进程控制快”,有了这个数据结构,进程才能成为内核调度的一个基本单位接受内核的调度
4.进程有独立的用户空间。而线程有用户空间(线程分为,用户线程,内核线程)
十一.进程状态(1和2是常用的)
1.
进程正在被CPU执行,或者已经准备就绪,随时可以执行,当一个进程刚被创建时,就处于TASK_RUNNING
2.
处于等待中的进程,待等待条件为真时被唤醒,也可以被信号或者中断唤醒
3.
处于等待中的进程,等待资源有效时唤醒,但不可以有其它进程通过信号(signal)或中断唤醒
4.
进程中止执行,当接收到SIGSTOP和SIGTSTP等信号时,进程进入该状态,接收到SIGCONT信号后,进程重新回到TASK_RUNNING
5.
Linux2.6.25新引入的进程睡眠状态,原理类似于TASK_UNINTERRUPTIBLE,但是可以被致命信号(SIGKILL)唤醒。
6.
正处于被调试状态的进程
7.
进程退出时(调用do_exit),state字段被设置为该状态