编译内核文件.ko
1、操作系统:linux
2、编译使用的文件
# ls
hello.c helloworld.h Makefile world.c
最简单的编译ko只需要一个.c文件和一个Makefile即可
3、文件详情
首先看Makefile
obj-m :=start.o
start-objs := hello.o world.o
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH :=/usr/src/linux-headers-${LINUX_KERNEL}/
PWD :=$(shell pwd)
modules :
$(MAKE) -C $(LINUX_KERNEL_PATH) M=$(PWD) modules
.PHONEY:clean
clean :
rm -f *.o *.ko *.mod.c
分析
obj-m := ///这个后面即是最后生成的**.ko,此处为start.ko。可以并列多个。
**-objs := ///**和你上面的ko名字对应,后面的为生成这个ko所需的.o文件(由同名的.c文件编译)
LINUX_KERNEL := $(shell uname -r) ///uname -r 查看内核版本
LINUX_KERNEL_PATH :=/usr/src/linux-headers-${LINUX_KERNEL}/ ///这个即为内核版本文件夹路径
PWD :=$(shell pwd) ///pwd 当前目录
modules :
$(MAKE) -C $(LINUX_KERNEL_PATH) M=$(PWD) modules
.PHONEY:clean
clean : /// make clean 时删除 .o .ko .mod.c
rm -f *.o *.ko *.mod.c
最重要的.c文件
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include "helloworld.h"
MODULE_LICENSE("GPL");
static int hello_init(void)
{
printk("999 Hello, world\n");
test_world();
return 0;
}
static void hello_exit(void)
{
printk("Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
分析
#include <linux/init.h> ///这两个为内核编译必备头文件
#include <linux/module.h>
#include "helloworld.h"
MODULE_LICENSE("GPL"); ///module证书?
static int hello_init(void) ///加载ko,insmod
{
printk("999 Hello, world\n");
test_world();
return 0;
}
static void hello_exit(void) ///卸载ko,rmmod
{
printk("Goodbye, cruel world\n");
}
module_init(hello_init); ///每个ko文件的最后都必须有module_init和module_exit
module_exit(hello_exit);
配角文件
world.c
#include <linux/kernel.h>
void test_world(void){
printk("world---\n");
}
helloworld.h
void test_world(void);
4、编译方法
输入make即可
正确编译的话应该会有以下文件,包含最终ko
# ls
hello.c hello.o helloworld.h Makefile modules.order Module.symvers start.ko start.mod.c start.mod.o start.o world.c world.o
5、加载卸载ko
加载:insmod start.ko
卸载:rmmod start.ko
查看内核消息:dmesg