Linux内核模块入门HelloWold

简介

本文主要是介绍怎么编写一个最简单的Linux内核模块“HelloWold”。

hello.c

直接上代码,首先是模块的源码文件hello.c:

/**
 * hello.c
 * Simple hello world driver module with module_init, module_exit
 */

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

MODULE_LICENSE ("GPL");

static int __init hello_2_init (void)
{
    
    
    printk (KERN_INFO "Hello world\n");
    return 0;
}

static int __exit hello_2_exit (void)
{
    
    
    printk (KERN_INFO "Goodbye world\n");
    return 0;
}

module_init (hello_2_init);
module_exit (hello_2_exit);

这个hello.c内容比较简单:在模块加载的时候,在内核日志中输出“Hello world”,在模块卸载的时候,在内核日志中输出“Goodbye world”。

Makefile

接下来是模块的make描述文件Makefile

ifeq ($(KERNELRELEASE),)

#KERNELDIR ?= /home/kernel2.6/linux-2.6.14

KERNELDIR ?= /lib/modules/$(shell uname -r)/build M=$(PWD) modules
PWD := $(shell pwd)

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

.PHONY: modules modules_install clean

else
	obj-m := hello.o
endif

第一个 ifeq ($(KERNELRELEASE),) 目前并没有用处,它的由来是指在Linux源码根目录下的 Makefile 编译内核时,KERNELRELEASE 宏会被定义,那么如果从源码根目录开始的 make 则会将 hello.o 模块编译进内核。

KERNELDIR ?= /lib/modules/ ( s h e l l u n a m e − r ) / b u i l d M = (shell uname -r)/build M= (shellunamer)/buildM=(PWD) modules 是对 KERNELDIR 进行赋值,这个变量是后面我们用到的指代内核源码目录用的。

PWD := $(shell pwd) 是对 PWD 变量进行赋值,作用是将 $(shell pwd) 的返回结果即求得当前目录的路径赋值给PWD,这个变量在后面指代要编译的驱动程序所在的位置。

modules:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

上面这句是Makefile的规则:这里的 $(MAKE) 就相当于make, “-C” 选项的作用是指将当前工作目录转移到所指定的位置。“M=” 选项的作用是当用户需要以某个内核为基础编译一个外部模块时,需要在 make modules 命令中加入“M=dir”,程序会自动到所指定的 dir 中查找模块源码,将其编译,生成KO文件。

modules_install:
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

上面这个命令是模块的安装

.PHONY: modules modules_install clean

上面这句话是的作用是保证modulesmodules_installclean这三个命令能正常完成。.PHONY 这是一个特殊目标名称,还有其它的,如:.SUFFIXES,.DEFAULT,.PRECIOUS,.INTERMEDIATE,.SECONDARY,.SECONDEXPANSION,.DELETE_ON_ERROR,.IGNORE .LOW_RESOLUTION_TIME .SILENT .EXPORT_ALL_VARIABLES .NOTPARALLEL

它们的具体用法可以参考GNU手册中的Special Built-in Target Names章节。

.PHONY目标的具体意思是如果在 Makefile 的工作目录中有名如:modulesmodules_installclean等文件时命令会出错。它是防止这出错的方式。

模块的编译、加载和删除

(1)将以上两个文件复制到Linux环境中的指定的文件夹,例如/home/linux/test/hello-world。
(2)切换root用户:

# sudo su

(3)进入我们模块源码文件夹

# cd /home/linux/test/hello-world

(4)编译模块

# make

(5)通过insmod命令将模块加入内核:

# insmod hello.ko

(6)通过lsmod 查看内核模块:

# lsmod | grep hello

(7)通过rmmod删除内核中的模块:

# rmmod hello.ko

(8)如果想要查看我们打印的内核日志,可以使用dmesg命令:

# dmesg

猜你喜欢

转载自blog.csdn.net/hanshiying007/article/details/129284279