目录
一、Linux kernel 源码
1.查看Linux系统版本,通过网站 https://www.kernel.org/ 获取对应版本的源码,可以选择自动或者手动下载。
wget -c https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.15.tar.gz
如果出现time out的情况,直接手动进入 https://mirrors.edge.kernel.org/pub/linux/kernel/ 下载。
2.新建文件夹,将下载后的.tar.gz 压缩文件存入并解压。
tar -xf linux-4.15.tar.gz
3.查看源码组成
arch:包含各体系结构特定的代码,如 arm、x86、ia64、mips等。
block:存放块设备相关代码documentation:与核心有关的说明文件。
crypto:存放加密、压缩、CRC校验等算法相关代码。
Documentation:存放相关说明文档,很多 实用文档,包括 驱动编写等。
drivers:存放 Linux 内核设备驱动程序源码。驱动源码在 Linux 内核源码中站了很大比例,常见外设几乎都有可参考源码,对驱动开发而言,该目录非常重要。该目录包含众多驱动,目录按照 设备类别 进行分类,如char、block、input、i2c、spi、pci、usb等。
firmware:存放处理器相关的一些特殊固件。
fs:核心所支持的filesystems,例如vfat,reiserfs,nfs等。
include:存放内核所需、与平台无关的头文件,相关的头文件已经被移动到arch平台的include目录,如 ARM 的头文件目录<arch/arm/include/asm/>。
init:一些核心初始化的功能,包括挂载与init程序的呼叫等。
ipc:存放进程间通信代码。
kernel:包含 Linux 内核管理代码。
lib:库文件代码实现。
mm:与内存单元有关的各项数据,包括swap与虚拟内存等。
net:存放网络相关代码。
samples:存放提供的一些内核编程范例,如kfifo;后者相关用户态编程范例,如hidraw。
scripts:存放一些脚本文件,如menuconfig脚本。
security:存放系统安全性相关代码。
sound:存放声音、声卡相关驱动。
tools:编译过程中一些主机必要工具。
usr:cpio相关实现。
virt:与虚拟化机器有关的信息,目前核心支持的是KVM(Kernel base Virtual Machine)
二、简单的内核模块程序
1.在linux源码中的drivers/ 目录下创建hello文件夹作为驱动程序目录,用于存放源代码、Kconfig配置文件和Makefile,规范编写以上三个文件。
mkdir linux-4.15/drivers/hello
2.创建源代码文件。
cd linux-4.15/drivers/hello
touch hello.c
其中,源文件代码如下:
#include <linux/module.h>
#include <linux/init.h>
//加载时执行
static int __init hello_init(void)
{
printk(KERN_ALERT "Welcome\n");//KERN_ALERT为打印信息级别参数
return 0;
}
//卸载时执行
static void __exit hello_exit(void)
{
printk(KERN_ALERT "Bye\n");//printk是内核中的打印函数
}
//版权声明
MODULE_LICENSE("GPL");
//以下两个函数属于 Linux 的驱动框架
module_init(hello_init);
module_exit(hello_exit);
3.在驱动目录中创建Kconfig文件,对内核进行配置。
cd linux-4.15/drivers/hello
touch Kconfig
其中,文件内容如下:
config HELLO //执行配置时会生成变量CONFIG_HELLO,该变量在编译时会被Makefile引用
tristate "hello driver"
help
just a simplest driver.
default y //将变量CONFIG_HELLO的值设置为y,使该驱动被编译到内核中
配置好驱动中的Kconfig后需要将该文件添加到 Linux 内核的整体配置文件中,在drivers/Kconfig文件的最后。
source "drivers/hello/Kconfig" //添加的驱动Kconfig配置文件路径
endmenu //结束
4.创建Makefile文件
cd linux-4.15/drivers/hello
touch Makefile
其中,内容如下:
//CONFIG_HELLO 看作一个变量,此处被设置为y,表示将hello驱动编译进内核
obj-$(CONFIG_HELLO) += hello.o
此外,需要在dirvers目录下的Makefile文件最后添加该文件的路径。
obj-$(CONFIG_HELLO) += hello/
5.切换到内核目录下进行编译。
cd linux-4.15/
make -j4
6.编译为驱动模块有两种方式,第一种是全部编译,需要将驱动配置为M,表示编译为驱动模块。
make menuconfig //打开配置页面后将hello驱动配置为 M
并在内核目录 linux-4.15/ 下执行编译指令,最终在驱动目录下得到文件 hello.ko
make -j4 modules
第二种是只编译该驱动模块,在hello目录下只保留源文件,新建Makefile文件,内容如下;
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_PATH) M=$(PWD) clean
endif
并在该驱动目录下执行make指令,得到驱动模块hello.ko