linux驱动编译环境搭建与实例编程

配置编译环境

安装gcc,make

sudo apt install gcc
sudo apt install make

配置交叉编译工具链(以飞腾为例)

sudo mkdir /data/toolchain -p
sudo tar -zxvf toolchain.ls.tgz -C /data/toolchain/   #默认环境变量需要修改

交叉编译环境变量配置

sudo vim /data/toolchain/setenv/setenv_linaro_7.2.1

打开文件后将下列配置替换上去

#!/bin/sh
ARCH=arm64
CROSS_COMPILE=aarch64-linux-gnu-
PATH=/data/toolchain/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/bin:$PATH
CC="aarch64-linux-gnu-gcc"
LD="$CROSS_COMPILE"ld
CXX="$CROSS_COMPILE"g++
​
export ARCH CROSS_COMPILE PATH CC CXX LD

设置环境变量生效

source /data/toolchain/setenv/setenv_linaro_7.2.1

方法一:将以上命令写入.profile文件末尾

方法二:将以上命令写入.bashrc文件末尾

方法三:将以上命令写入/etc/environment文件末尾

方法四:如有多个平台编译工具链可制作源文件编脚本,将环境变量设置命令写入其中,简单脚本示例如下:

#!/bin/sh
source /data/toolchain/setenv/setenv_linaro_7.2.1
make build

解压内核并编译

linux内核原码获取:www.kernel.org

下载内核源码后解压然后使用以下命令进行编译

make oldconfig
make preparey
make scripts

接下来制作一个简单的驱动文件编译

驱动示例

环境配置完成接下来可以编辑一个简单的驱动程序进行测试:

hello.c文件

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/uaccess.h>
​
#define EN_DEBUG                    1                      /* 调试信息开关 */
#if EN_DEBUG
#define PRINT(x...)                 printk(KERN_EMERG x)   /* 提高打印等级 */
#else
#define PRINT(x...)
#endif
​
static dev_t         s_dev;                        /* 动态生成的设备编号 */
static struct cdev  *s_cdev;                       /* 字符设备驱动结构体 */
static struct class *hello_class;                  /* 该驱动的类 */
static struct device *hello_device;                /* 该驱动的设备 */
​
​
static struct file_operations hello_fops = {
    .owner = THIS_MODULE,
};
​
static int __init drv_init(void)
{
    PRINT("[KERNEL]:%s ------ \n", __FUNCTION__);
    
    s_cdev = cdev_alloc();                          /* 申请一个字符设备 */
    cdev_init(s_cdev, &hello_fops);                 /* 初始化字符设备,与file_operations绑定 */
    alloc_chrdev_region(&s_dev, 0, 1, "hello");     /* 动态申请一个设备编号 */
    cdev_add(s_cdev, s_dev, 1);                     /* 添加一个字符设备到系统 */
    
    hello_class = class_create(THIS_MODULE, "hello"); /* 将本模块创建一个类,并注册到内核 */
    hello_device = device_create(hello_class, NULL, s_dev, NULL, "hello"); /* 创建设备并注册到内核 */    
    return 0;
}
static void __exit drv_exit(void)
{
    PRINT("[KERNEL]:%s ------ \n", __FUNCTION__);
    cdev_del(s_cdev);                              /* 从内核注销cdev设备对象 */
    unregister_chrdev_region(s_dev, 1);            /* 注销一个字符设备 */
    device_destroy(hello_class, s_dev);            /* 销毁设备 */
    class_destroy(hello_class);                    /* 销毁类 */
}
​
module_init(drv_init);                             /* 模块初始化 */
module_exit(drv_exit);                             /* 模块卸载 */
​
MODULE_AUTHOR("hrx");                              /* 模块作者 */
MODULE_DESCRIPTION("Linux Driver");                /* 模块描述 */
MODULE_VERSION("1.0.0");                           /* 模块版本 */
MODULE_LICENSE("GPL");                             /* 模块遵守的License */

Makefile文件

PWD = $(shell pwd)
#Linux内核根目录路径
KERNEL_DIR = $(PWD)/../linux-ft-458279d1/
#驱动名称
DRVNAME = hello
#obj-m选项表示以模块进行编译,独立生成一个.ko文件,不会被编译进内核
#obj-y选项表示打算编译进内核,不需要生成独立的.ko文件
obj-m += hello.o
build:
    $(MAKE) -C $(KERNEL_DIR) M=$(PWD)
clean:
    @rm -rf *.o *.ko .*.cmd *.mod.c *.order *.symvers .tmp_versions *~

然后将生成的ko文件拷入linux设备中执行

insmod hello.ko

如果命令执行后无提示即表示驱动加载成功,使用lsmod可查看驱动是否已加载,如果装载失败,可使用demsg命令查看报错提示。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值