内核中制作ko文件的步骤_转:Linux下编写和加载 .ko 文件(驱动模块文件)

https://blog.csdn.net/qq_38880380/article/details/79227760

一、.ko 文件介绍

.ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载。

二、优点

(1)这样可以缩小内核体积;

(2)使用方便。

三、.ko文件一般的用处

(1)作为一个功能模块,需要使用时,直接插入运行就行。如在imx6上连接模拟摄像头,先运行模拟摄像头对应的驱动模块 camera.ko文件,然后对应的工程执行文件运行就行。

四、使用.ko 文件

1、加载驱动模块test.ko

(1)方法一

进入test.ko驱动模块文件所在的目录,然后直接   insmod  test.ko

(2)方法二

将test.ko文件拷贝到/lib/module/#uname-r#/目录下,这里,#uname -r#意思是,在终端中输入

uname -r后显示的内核版本及名称,例如mini2440中#uname-r#就是2.6.32.2-FriendlyARM。

然后 depmod(会在/lib/modules/#uname -r#/目录下生成modules.dep和modules.dep.bb文件,表明模块的依赖关系)

最后 modprobe test(注意这里无需输入.ko后缀) 即可

注:两种方法的区别

modprobe和insmod类似,都是用来动态加载驱动模块的,区别在于modprobe可以解决load module时的依赖关系,它是通过/lib/modules/#uname -r/modules.dep(.bb)文件来查找依赖关系的;而insmod不能解决依赖问题。也就是说,如果你确定你要加载的驱动模块不依赖其他驱动模块的话,既可以insmod也可以modprobe,当然insmod可以在任何目录下执行,更方便一些。而如果你要加载的驱动模块还依赖其他ko驱动模块的话,就只能将模块拷贝到上述的特定目录,depmod后再modprobe。

2、查看已加载的驱动模块列表

在任何目录下输入命令

lsmod

3、卸载驱动模块

在任何目录下, 输入命令

rmmod 注:“module_name”是lsmod显示的模块名称,而不是对应的ko文件名

五、编写生成.ko 文件

Linux下hello.ko内核模块制作的全过程

1. linux系统用的是Redflag 6.0 SP1 下载地址:ftp://ftp.redflag-linux.com/pub/redflag/dt6sp1/SP1/redflag-6-sp1.iso, 系统安装很容易,安提示做就好。

所用的内核源码目录树下载地址:ftp://ftp.redflag-linux.com/pub/redflag/dt6sp1/SP1/redflag-6-tool-sp1-src1.iso,将此iso文件挂载到/mnt下,安装其中的内核rpm包。

挂载方法:mount -t iso9660 redflag-6-tool-sp1-src1.iso /mnt/ -o loop

内核目录树安装方法:cd /mnt/RedFlag/SRMPS/

rpm -i kernel-2.6.23.1-4.src.rpm

3. 编写hello模块代码,源码如下:

hello.c

#include 

#include 

MODULE_LICENSE("GPL");

static int hello_init(void)

{

printk(KERN_ALERT "Hello, world\n");

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye, cruel world\n");

}

module_init(hello_init);

module_exit(hello_exit);

4. 编写hello模块的Makefile文件,Makefile内容如下:

Makefile

#Makefile 2.6

obj-m :=hello.o

KERNEL :=/usr/src/kernels/$(uname -r)/

PWD :=$(shell pwd)

modules :

$(MAKE) -C $(KERNEL) M=$(PWD) modules

.PHONEY:clean

clean :

rm -f *.o *.ko

5. 编译模块

在命令行进入hello.c所在的文件夹下执行make命令即可完成hello模块的编译。用ls命令可以查看到hello.ko文件,此文件就是我们自定义的内核模块。

6. 安装hello模块

命令行下执行命令:insmod hello.ko 。通过命令:cat /var/log/messages

可以看到下面这样的信息:“Aug  6 13:37:59 localhost kernel: Hello, world”,说明模块加载成功了。

7. 另外一种模块Makefile的编写方法

Makefile

# If KERNELRELEASE is defined, we've been invoked from the

# kernel build system and can use its language.

ifneq ($(KERNELRELEASE),)

obj-m := hello.o

# Otherwise we were called directly from the command

# line; invoke the kernel build system.

else

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

de

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux,可以通过修改内核的驱动程序来实现屏幕旋方向的修改。具体步骤如下: 1. 首先需要确定屏幕的旋方向,以及屏幕使用的显示控制器。根据不同的显示控制器,可能需要修改不同的驱动程序。 2. 打开Linux内核源码,在驱动程序的目录下找到相关的文件,例如对于使用DRM进行显示的情况,可以在`drivers/gpu/drm`目录下找到相关的驱动程序。 3. 找到需要修改的驱动程序文件,例如`drm_panel.c`,在该文件查找与屏幕旋相关的代码。 4. 根据需要修改的旋方向,修改相关的代码。例如,如果需要将屏幕旋90度,可以修改代码如下: ```c static const struct drm_display_mode panel_mode = { .clock = 74250, .hdisplay = 1080, .hsync_start = 1080 + 88, .hsync_end = 1080 + 88 + 44, .htotal = 1080 + 88 + 44 + 148, .vdisplay = 1920, .vsync_start = 1920 + 4, .vsync_end = 1920 + 4 + 5, .vtotal = 1920 + 4 + 5 + 36, .vrefresh = 60, .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, }; ``` 可以看到,需要修改的是`hdisplay`和`vdisplay`,将它们分别改为1920和1080即可实现屏幕旋90度。 5. 修改完成后,重新编译内核,并加载新的内核模块即可。 关于Linux内核驱动的编写,可以参考以下步骤: 1. 首先需要确定需要编写的驱动类型,例如字符设备驱动、块设备驱动、网络设备驱动等。 2. 打开Linux内核源码,在相关的驱动程序目录下创建一个新的文件,例如`my_driver.c`。 3. 在文件定义驱动程序的数据结构和相关的操作函数,例如: ```c struct my_driver_data { struct device *dev; int data; }; static int my_driver_open(struct inode *inode, struct file *file) { struct my_driver_data *data; data = kmalloc(sizeof(struct my_driver_data), GFP_KERNEL); data->dev = file->f_path.dentry->d_inode; file->private_data = data; return 0; } static int my_driver_release(struct inode *inode, struct file *file) { struct my_driver_data *data = file->private_data; kfree(data); return 0; } static ssize_t my_driver_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct my_driver_data *data = file->private_data; int ret; ret = copy_to_user(buf, &data->data, sizeof(int)); return sizeof(int) - ret; } static ssize_t my_driver_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { struct my_driver_data *data = file->private_data; int ret; ret = copy_from_user(&data->data, buf, sizeof(int)); return sizeof(int) - ret; } static const struct file_operations my_driver_fops = { .owner = THIS_MODULE, .open = my_driver_open, .release = my_driver_release, .read = my_driver_read, .write = my_driver_write, }; ``` 可以看到,定义了一个`my_driver_data`结构体,包含设备指针和一个整数型数据;以及对应的设备操作函数`my_driver_open`、`my_driver_release`、`my_driver_read`和`my_driver_write`。 4. 在文件定义驱动程序的初始化函数和销毁函数,例如: ```c static int __init my_driver_init(void) { int ret; ret = register_chrdev(0, "my_driver", &my_driver_fops); if (ret < 0) { printk(KERN_ERR "my_driver: failed to register driver\n"); return ret; } return 0; } static void __exit my_driver_exit(void) { unregister_chrdev(0, "my_driver"); } ``` 可以看到,初始化函数调用了`register_chrdev`函数来注册设备,并指定了设备操作函数;销毁函数调用了`unregister_chrdev`函数来注销设备。 5. 在驱动程序的顶部添加必要的宏定义和头文件包含,例如: ```c #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/device.h> #include <linux/uaccess.h> MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("My Driver"); MODULE_VERSION("0.1"); static int __init my_driver_init(void); static void __exit my_driver_exit(void); ``` 6. 编写Makefile文件,将驱动程序编译为内核模块,例如: ``` obj-m += my_driver.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 ``` 7. 在Linux内核源码目录下,执行`make modules`命令编译内核模块,然后执行`insmod my_driver.ko`命令加载新的内核模块。 注意,在编写和修改内核驱动程序时,需要谨慎操作,建议在虚拟机环境下进行测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值