Linux驱动第一篇-----最简单的内核模块

最简单的内核模块就是从Hello world开始的:

首先看下Linux的内核结构
Linux驱动第一篇-----最简单的内核模块_第1张图片
Linux驱动第一篇-----最简单的内核模块_第2张图片
Linux驱动第一篇-----最简单的内核模块_第3张图片

再看下Linux目录结构:
Linux内核源码采用树形结构。功能相关的文件放到不同的子目录下面
,使程序更具有可读行
Linux驱动第一篇-----最简单的内核模块_第4张图片

arch目录
– arch目录是平台目录。内核支持的所有CPU架构,在该目录下都有对应的
子目录。每个CPU的子目录,又进一步分解为boot,mm,kernel等子目录
,分别控制系统引导,内存管理,系统调用。还有动态调频,主频率设
置部分等
Linux驱动第一篇-----最简单的内核模块_第5张图片
Linux驱动第一篇-----最简单的内核模块_第6张图片
Linux驱动第一篇-----最简单的内核模块_第7张图片
Linux驱动第一篇-----最简单的内核模块_第8张图片

接下来就是最小Linux驱动
Linux头文件位置
– 类似#include 的头文件,它们是在Linux源码目录下的
include/linux/module.h
• #include 头文件
– 所有的Linux 代码必须遵循GPL 协议,如果不知道Linux 的GPL 协议,去查
一下资料
– 如果你不声明GPL 协议,你的模块将无法在Linux 中使用的
– MODULE_LICENSE(_license)添加遵循GPL协议,必须的!
– MODULE_AUTHOR(_author)代码作者

#include
– 包含初始化宏定义的头文件,代码中的函数module_init和module_exit在此
文件中
– 入口函数module_init(x)
– 出口函数module_exit(x)

首先我们先建一个.c的文件,命名为mini_linux_module.c

#include  //代码的module_init和module_exit在此文件夹中
#include //包含加载模块的头文件,代码的MODULE_LICENSE在此头文件中

MODULE_LICENSE("Dual   BSD/GPL"); //声明是开源的,没有内核版本限制

static int __init hello_init(void)
{
    printk(KERN_EMERG  "Hello, world."); //打印信息 KERN_EMERG表示紧急信息
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_EMERG  "Goodbye, world.");
}


module_init(hello_init);  //初始化函数
module_exit(hello_exit); //卸载函数

驱动模块的编译
• Linux的驱动可以和Linux源码放在一起编译,也可以单独拿出来编译。
– 为了理解整个Linux内核编译过程,可以从学习Linux模块的编译入手
• Makefile文件
– 单独编译驱动需要写一个Makefile文件

#!/bin/bash
#通知编译器我们要编译模块的哪些源码
#这里是编译itop4412_hello.c这个文件编译成中间文件itop4412_hello.o
obj-m += mini_linux_module.o 

#源码目录变量,这里用户需要根据实际情况选择路径
#作者是将Linux的源码拷贝到目录/home/topeet/android4.0下并解压的
KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0

#当前目录变量
PWD ?= $(shell pwd)

#make命名默认寻找第一个目标
#make -C就是指调用执行的路径
#$(KDIR)Linux源码目录,作者这里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
#modules要执行的操作
all:
	make -C $(KDIR) M=$(PWD) modules
		
#make clean执行的操作是删除后缀为o的文件
clean:
	rm -rf *.o

编译生成的.KO文件就是驱动模块
– insmod加载模块命令
– lsmod查看模块命令
– rmmod卸载模块命令

你可能感兴趣的:(linux)