Linux驱动模块编写

17 篇文章 0 订阅
14 篇文章 0 订阅

Linux驱动直接写函数,init,exit不需要想windows指定函数名,但是需要注册函数。用module_init

#include <linux/kernel.h>
#include <linux/module.h>
MODULE_LICENSE ("GPL");//开源协议GPL 或者MIT BSD
MODULE_AUTHOR ("TOM");//作者
MODULE_DESCRIPTION ("MY_TEST");//描述此驱动
//EXPORT_NO_SYMBOLS;//不导出符号,函数 可以不写
//EXPORT_SYMBOL(hello_data);//导出hello_data
int test_init(void)
{
    printk(KERN_INFO "hello world\n");//调试级别
    return 0;
}
void test_exit(void)
{
   printk(KERN_INFO "goodbye world\n");
}
module_init(test_init); //注册DriverEntry	 
module_exit(test_exit); //注册DriverUnload	 

Makefile编译,生成hello.ko

EXTRA_CFLAGS    := -g//一些编译选项 ;=的意思是在原来的数上加上其它编译选项
obj-m =hello.o
#hello-objs := file1.o file2.o,如果有多个源文件,加上这么一行
KVERSION = $(shell uname -r)
all:
	make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules(这里前面是tab按键)
clean:
	make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

Makefile无后缀名,且M是大写
make –C之前是一个tab键而不是空格
如果只有一个C文件,那么hello.o要与hello.c同名
make不能使用sudo 

写好,代码之后执行,make编译

然后安装运行

sudo insmod hello.ko //加载hello.ko
sudo rmmod hello.ko //卸载hello.ko
sudo lsmod  //显示ALL驱动
sudo modinfo hello //查看驱动信息
dmesg | tail //查看最近linux打印信息
sudo cat /proc/kmsg //同上,滚动输出(pro)

 

Ubuntu模块自启动:

将驱动拷到/lib/modules/2.6.32.65/kernel/lib/
/lib/modules/2.6.32.65/kernel/lib/hello.ko

编辑modules
/etc/modules

增加驱动名,不需要加ko

参数设置

可以为模块与模块直接传参数,在模块

module_param(who,charp,S_IRUSR)//这个权限是文件所有者可读

加载时候就是insmod kello.ko who="world" time=5

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>  
      
MODULE_LICENSE("Dual BSD/GPL");     

static char *who= "world";             
static int times = 1; 
      
module_param(times,int,S_IRUSR);     
module_param(who,charp,S_IRUSR);   

static int hello_init(void)       
{
    int i;
    for(i=0;i<times;i++)
       printk(KERN_ALERT "(%d) hello, %s!\n",i,who);
     return 0;
}

static void hello_exit(void) 
{
    printk(KERN_ALERT"Goodbye, %s!\n",who);
}

module_init(hello_init);
module_exit(hello_exit);

多模块之间共享数据接口

EXPORT_SYMBOL(hello_data);导出

extern int hello_data;使用,要先加载导出在加载导入,卸载反着,但是要先编译导出模块得到Modules.symves,拷贝到导入,才能编译通过,要不然编译这个导入时候不知道导入符号的位置,或者在编译导入的makefile里加入

KBUILD_EXTRA_SYMBOLS = /mnt/hgfs/MallocFree_2018/Linux/10ten-hellokernel/demo/hello-2/Module.symvers

R0和R3通信

首先加在内核驱动

然后可以通过 cat /proc/devices查看安装上的驱动生成的设备主功能号

通过 sudo mknod /dev/second c xxx yyy 命令创建/dev/second设备节点

编译客户端文件并执行。

Character devices:
  1 mem
  4 /dev/vc/0
  4 tty
  4 ttyS
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  6 lp
  7 vcs
 10 misc
 13 input
 14 sound

Linux内核调试

Linux的奔溃分为模块OOPS,系统PANIC 

OOPS

oops之后,模块被Killed,有可能不会panic,因为oops可能在进程上下文,并不是中断上下文

若果想oops之后panic,在/etc/syctl.conf中

kernel.panic_on_oops=1
kernel.panic=20

然后sudo sysctl -p

如果oops使用命令:demesg->oops stack or cat /proc/kmsg

然后使用 objdump -S oops.o 查看出错误rip偏移的代码,就定位到代码出错处。

如果panic,系统信息肯定就没了,只能

切换到终端:物理机ALT+CTRL+F1,虚拟机ALT+CTRL+空格+ALT+CTRL+F1

切换到UI:....+F7

OPPS-KDUMP

生成dump文件,需要安装Kexec-tools

sudo apt-get install linux-crashdump
sudo vim /etc/default/kexec
     LOAD_KEXEC=true
reboot
sudo /etc/init.d/kdump start
sudo echo "c">/proc/sysrq-trigger
ls /var/crash/vmcore
去http://ddebs.ubuntu.com/pool/main/linux下载与uname -a命令输出匹配的符号
dpkg -i linux-image-版本编号-XXX ddeb

sudo crash /usr/lib/debug/boot/vmlinux-版本号-generic /var/crash/vmcore
bt/ps/log 查看信息

printk

如果出bug,用printk打日志

printk(KERN_INFO "xxx\n");

kern_info是日志级别。printk可能没输出到终端,去/var/log/messages查看,如果klogd没有运行,消息不会传递到用户控件,只能/proc/kmsg.

gdb

也可以gdb观察内核,但是不能修改,设置断点,单步调试,只能查看

还有KDB,KGDB(支持双机调试)

strace

可以显示系统调用信息,包括调用时的参数信息,跟windows平台的API monitor差不多。

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值