驱动最简单模块代码编译

首先模块代码编译加载需要哪些东西:

先看 makefile

#!/bin/bash
# -m 表示不会 编译到zImage  是生成可加载模块   目标文件
obj-m += mini_linux_module.o 
#表示坐着的kernel源码路径
KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0
#当前路径
PWD ?= $(shell pwd)
all:
#-C 表示执行这个目录下的makefile 然后返回继续执行 
	make -C $(KDIR) M=$(PWD) modules
.phony clean:
clean:
	rm -rf *.o**

这样我们 就清楚,编译生成模块代码需要这几个东西:
1、kernel 源码 这个下载解压使用menuconfig配置就好了
2、我们写的模块代码 重点是这个相当于我们写某个驱动调用的入口;
3、makefile

看下源码 :
头文件所在目录:
源码下
include/linux/init.h
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
include/linux/module.h
#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)

#include <linux/module.h>
#include <linux/init.h>
//GPL协议 来自于moudle.h的头文件中必须包含 否则内核无法调用
MODULE_LICENSE("DUAL  BSD/GPL");
MODULE_AUTHOR("danni_cj");
/*紧急事件消息,系统崩溃之前提示,表示系统不可用*/
static int HELLO_INIT(void)
{
	printk(KERN_EMERG "HELLO_INIT function enter \n");
	return 0;	
}
static void HELLO_EXIT(void)
{
	printk(KERN_MEMRG "hello_exit function enter \n");	
}
module_init(HELLO_INIT);
module_exit(HELLO_EXIT);

U盘加载
mount /dev/sda1 /mnt/udisk 挂在U盘
insmod /mnt/udisk/mini_linux_module.ko
输出:HELLO_INIT function enter
rmmod mini_linux_module
输出:hello_exit function enter
这就实现了简单的驱动模块的加载,卸载流程;

ps:
make中不清楚的 += := = 区别可以查看 我上期发的
https://blog.csdn.net/c4679281314/article/details/96441284

#################################
喜欢了你 是凑巧;
或许是你 身上的某个元素吸引了我
但真的喜欢上你时去不是偶然。
cj ->danni
################################

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux驱动需要了解Linux内核的工作原理和驱动模型。Linux驱动通常分为字符设备驱动、块设备驱动、网络设备驱动等等。其中,字符设备驱动是最常见的一种。 编Linux驱动的步骤如下: 1. 确定驱动类型:根据设备类型确定驱动类型,如字符设备驱动、块设备驱动、网络设备驱动等等。 2. 编驱动代码:编驱动代码,包括设备注册、设备初始化、设备读、设备释放等等。 3. 编Makefile文件:编Makefile文件,包括编译驱动代码、生成驱动模块文件等等。 4. 编译驱动代码:使用make命令编译驱动代码,生成驱动模块文件。 5. 加载驱动模块:使用insmod命令加载驱动模块。 6. 测试驱动:使用测试程序测试驱动是否正常工作。 下面是一个简单的字符设备驱动示例: ``` #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/cdev.h> #define DEVICE_NAME "testdev" #define CLASS_NAME "testclass" MODULE_LICENSE("GPL"); static int major; static struct class *testclass; static struct cdev testcdev; static int test_open(struct inode *inode, struct file *file) { printk(KERN_INFO "testdev: open\n"); return 0; } static int test_release(struct inode *inode, struct file *file) { printk(KERN_INFO "testdev: release\n"); return 0; } static ssize_t test_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { printk(KERN_INFO "testdev: read\n"); return 0; } static ssize_t test_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { printk(KERN_INFO "testdev: write\n"); return count; } static struct file_operations test_fops = { .owner = THIS_MODULE, .open = test_open, .release = test_release, .read = test_read, .write = test_write, }; static int __init test_init(void) { int ret; ret = alloc_chrdev_region(&major, 0, 1, DEVICE_NAME); if (ret) { printk(KERN_ERR "testdev: alloc_chrdev_region failed\n"); goto err_alloc_chrdev_region; } cdev_init(&testcdev, &test_fops); testcdev.owner = THIS_MODULE; ret = cdev_add(&testcdev, major, 1); if (ret) { printk(KERN_ERR "testdev: cdev_add failed\n"); goto err_cdev_add; } testclass = class_create(THIS_MODULE, CLASS_NAME); if (IS_ERR(testclass)) { printk(KERN_ERR "testdev: class_create failed\n"); ret = PTR_ERR(testclass); goto err_class_create; } device_create(testclass, NULL, major, NULL, DEVICE_NAME); printk(KERN_INFO "testdev: init done\n"); return 0; err_class_create: cdev_del(&testcdev); err_cdev_add: unregister_chrdev_region(major, 1); err_alloc_chrdev_region: return ret; } static void __exit test_exit(void) { device_destroy(testclass, major); class_destroy(testclass); cdev_del(&testcdev); unregister_chrdev_region(major, 1); printk(KERN_INFO "testdev: exit done\n"); } module_init(test_init); module_exit(test_exit); ``` 在编驱动代码后,需要编Makefile文件。Makefile文件示例如下: ``` obj-m += testdev.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean ``` 其中,obj-m表示要编译驱动模块文件名,$(shell uname -r)表示当前内核版本号,$(PWD)表示当前目录。 使用make命令编译驱动代码,生成驱动模块文件: ``` $ make ``` 使用insmod命令加载驱动模块: ``` $ sudo insmod testdev.ko ``` 使用rmmod命令卸载驱动模块: ``` $ sudo rmmod testdev ``` 使用dmesg命令查看驱动输出信息: ``` $ dmesg ``` 编编译Linux驱动需要一定的Linux内核知识和编程经验,建议在学习前先学习Linux内核和Linux编程基础知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值