带您进入内核开发的大门 | 第一个内核程序

2,579 阅读2分钟

内核开发往往给人开发难度大的印象,大家觉得内核开发非常神秘,很高大上。其实内核开发并没有想象的那么复杂,它跟普通的用户态开发基本类似,稍微复杂一点的是内核的调试。本文通过一个简单的内核程序,让大家了解内核开发,并进入内核开发的大门。

带您进入内核开发的大门 | 第一个内核程序

开发环境

为了避免将自己的操作系统搞挂,本文在虚拟机中进行开发,这样我们可以随便折腾。本文所用的环境信息如下。

操作系统:Ubuntu 16.04 Server版 内核版本:4.4.0-31 编译环境:gcc 5.4.0

程序代码

主程序代码

本文代码也遵从惯例,开发一个非常简单的HelloWorld程序,在程序启动的时候打印一条HelloWorld信息,先展示代码。

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
static int hello_init(void)
{
     printk("Hello, itworld123.com");
     return 0;
}
static void hello_exit(void)
{
      printk("Bye!");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SunnyZhang<shuningzhang@126.com>");

可以是用任何文本工具将本代码保存在一个文本文件(hello.c)中进行测试。在Linux系统中可以顺序执行如下命令:

mkdir helloworld cd helloworld vim hello.c

用vim打开文件后,将上述代码拷贝到里面,然后保存退出(好啰嗦,不会使用vim的话,请搜索相关内容学习)。

工程管理

在用户态开发时,为了方便编译,通常需要一个Makefile文件管理我们的源文件。内核开发也需要一个Makefile文件。具体内容如下:

obj-m += hello.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
all: 
 make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
 make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

同样,还是在helloworld目录下,通过vim命令建立一个名称为Makefile的文件,并拷贝上述内容。

完成上述内容后,我们其实就完成了一个最简单内核程序的开发,本文先不具体解释上述代码的具体含义,先编译运行看一下效果。

程序运行

在helloworld目录下面执行make命令就可以进行编译,最后会生成一个名称为hello.ko的问题。该文件就是我们最终完成的可执行文件。在root用户下,执行如下命令:

insmod hello.ko

如果不是root用户会报错,此时可以切换到root用户,或者执行如下命令:

sudo insmod hello.ko

在生产环境通常是不建议直接使用root用户的,但为了学习方便可以使用root用户。

执行上述命令后,我们继续执行如下命令:

dmesg

此时可以看到在最后有我们打印的信息:

Hello, itworld123.com

完成测试之后,可以执行如下命令卸载程序(模块):

rmmod hello

至此,我们完成了一个Linux内核模块,并成功的运行了它,是不是非常简单!