ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Linux驱动初探(hello word)

2021-09-26 23:33:48  阅读:236  来源: 互联网

标签:word dtb make hello topeet Linux imx arch arm


1.开发环境搭建:

系统:ubuntu16.04

1.1:SSH环境搭建

这里我是用的是使用buildroot制作的最小文件系统,在选项里把SSH服务勾上,制作得到具备SSH功能的文件系统。这里大家可以自行搜索,或者开发板自带文件系统已经有SSH功能可以略过。

1.1.1搭建网络

设备:win10笔记本,网线,iMX6uL/ULL,网线转接口(轻薄本无法直接连接网线)
第一步:共享主机网络(我这里共享的是无线网卡)

在这里插入图片描述
这里选择以太网4是因为我开发板的网卡适配器就是以太网4,大家这里这里根据实际选择。
第二部:设置开发板适配器的静态IP
在这里插入图片描述
配置iPv4属性,IP地址可以随便填,只要不冲突(双击适配器看详细信息,如果出现两个IPv4说明IP冲突,需要更改),注意这里的IP前3段需要跟主机的相同,也就是所谓的同一网段,这里大家可以查看自己的无线网IP请添加图片描述
这里可以看出我的网段就是192.168.31.xx ,所以开发板适配器只要网段一致即可。
开发板使用 命令设置静态IP,例如我的地址设为192.168.31.20:

ifconfig eth0 192.168.31.20 up //eth0可根据实际更改

配置好后,win10与开发板互ping
在这里插入图片描述
在这里插入图片描述
注意不要ping win10的无线网卡。

1.1.2开发板配置SSH

终端输入 vi /etc/ssh/sshd_config (注意这里一定是SSHD_config,sshh后面有个d不要改错)
在这里插入图片描述
将登录密码选项改掉:
在这里插入图片描述

改为
permitRootLogin yes :

否则win10登录将被拒。
配置好后,键入命令

/etc/init.d/S50ssh restart //这里的ssh的文件名字可能不一样,但是都在init.d这个目录下,自己找到

在这里插入图片描述
这里用到的的软件是L:
请添加图片描述
连接192.168.31.20,连接成功就可以在win10十分轻松拖动文件到开发板运行。
把文件拖到这里就可以同步在开发板,是不是很方便。
在这里插入图片描述

1.2:linux内核编译,与设备树移植

为了方便大家编译设备树源码,本章节将介绍如何编译 imx6ull 设备树源码。
第一步设置交叉编译环境
1 Ubuntu14.04(参考用户手册或者入门视频教程,关于搭建编译环境的部分)
输入以下命令安装设备树编译器,如下图所示:

apt-get install device-tree-compiler

2 下载 uboot 和内核的源码和编译器,源码是 linux-imx-rel_imx_4.1.15_2.1.0_ga_20200611.tar.gz,编译器是gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
3 编译器的安装和设置环境变量
拷贝 gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz 到 Ubuntu“/usr/local/arm/”目录下,然
后输入以下命令解压,如下图所示:
tar -vxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz
在这里插入图片描述
拷贝内核源码到 Ubuntu 上并解压,进入解压源码“linux-imx-rel_imx_4.1.15_2.1.0_ga”目录下,输入以
下命令设置临时环境变量(注意,设置临时环境变量后,此终端窗口不能关闭,关闭了的话,设置的临时
环境变量就失效了),如下图所示

导入环境变量//
export ARCH=arm //指明系统架构
export CROSS_COMPILE=arm-linux-gnueabihf-
//这里大家灵活变通,交叉编译链能用就行

第二步 编译命令
设置好环境变量后,在“linux-imx-rel_imx_4.1.15_2.2.0_ga”目录下,输入 kernel 和设备树一起编译的
命令,如下图所示:

cp arch/arm/configs/imx_v7_defconfig .config
./create.sh

create.sh的脚本代码:

#!/bin/bash
  
export ARCH=arm

#export CROSS_COMPILE=/usr/local/arm/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-

export CROSS_COMPILE=arm-linux-gnueabihf-

#make mrproper  # means CLEAN

make imx_v7_defconfig

#if   [ "$1" = "nand" ]
#then
#       cp arch/arm/boot/dts/imx6ul-14x14-evk_nand.dts arch/arm/boot/dts/imx6ul-14x14-evk.dts
#else
#       cp arch/arm/boot/dts/imx6ul-14x14-evk_emmc.dts arch/arm/boot/dts/imx6ul-14x14-evk.dts
#fi

make uImage LOADADDR=0x10008000 -j8

make modules

make topeet_emmc_4_3.dtb
make topeet_emmc_5_0.dtb
make topeet_emmc_7_0.dtb
make topeet_emmc_1024x600.dtb
make topeet_emmc_9_7.dtb
make topeet_emmc_10_1.dtb
make topeet_emmc_hdmi.dtb

make topeet_nand_4_3.dtb
make topeet_nand_5_0.dtb
make topeet_nand_7_0.dtb
make topeet_nand_1024x600.dtb
make topeet_nand_9_7.dtb
make topeet_nand_10_1.dtb
make topeet_nand_hdmi.dtb

cd ./arch/arm/boot/dts/
./create_dtb imx6ul_topeet_nand.dtb topeet_nand_4_3.dtb topeet_nand_7_0.dtb topeet_nand_10_1.dtb topeet_nand_1024x600.dtb topeet_nand_5_0.dtb topeet_nand_9_7.dtb topeet_nand_hdmi.dtb

arch/arm/configs/imx_v7_deconfig 是 默 认 的 编 译 配 置 文 件 , 如 果 修 改 内 核 配 置 文 件 , 需 要 覆 盖 掉
arch/arm/configs/imx_v7_deconfig,才能编译成功。我们需要在内核源码目录下面输入命令

cp arch/arm/configs/imx_v7_defconfig .config
export ARCH=arm
make menuconfig

我们在图形化界面配置驱动后,然后我们将系统默认配置文件
arch/arm/configs/arch/arm/configs/imx_v7_defconfig备份为arch/arm/configs/imx_v7_defconfigbak,输入以下命
令:

cp arch/arm/configs/imx_v7_defconfig arch/arm/configs/imx_v7_defconfigbak

我们再将根目录上配置好的.config 覆盖原来的配置文件,输入以下命令:

cp .config arch/arm/configs/imx_v7_defconfig

现在我们现在配置好的.config 变成了我们配置的默认文件,返回到我们的内核根目录下,运行我们的
脚本

./create.sh

编译完成如下图所示
在这里插入图片描述
第三步生成的镜像目录
内核镜像:”arch/arm/boot”目录下生成“zImage”文件
设备树镜像:“arch/arm/boot/dts”目录下生成设备树文件
最后将所有烧写到开发板。
在这里插入图片描述
成功进入系统后,再重新配置下SSH服务。

驱动编写与编译

Linux 下的应用程序是如何调用驱动程序的?
Linux 设备驱动会以内核模块的形式出现,因为 linux 内核的整体架构就非常庞大,包含的组件也非常多,
如果把所有的功能都编译到 linux 内核中会使得内核非常臃肿,为了解决这个问题,更方便地新增和删除功
能,linux 提供了这样的机制,这种机制被称为模块。为了大家对模块有一个感性的认识,我们先来看一个
最简单的驱动-helloworld。
驱动分为四个部分:
 头文件
 驱动模块的入口函数和出口函数
 声明信息
 功能实现
我们在 windows 上面新建一个 helloworld.c 文件,这里使用 sourceinsight 来编辑文件,大家也可以用其
他编译器来编写程序。
第一步 包含头文件

#include <linux/init.h> //包含宏定义的头文件
#include <linux/module.h> //包含初始化加载模块的头文件

第二步 驱动模块的入口函数和出口函数

module_init();
module_exit();

第三步 声明模块拥有开源许可证

MODULE_LICENSE("GPL");

第四步 功能实现:内核模块加载的时候打印 hello world! ,内核模块卸载的时候打印 gooodbye!
注意:内核打印函数不能用 printf,因为内核没有办法使用 C 语言库。

static int hello_init(void){
printk("hello world! \n");
return 0;
}
static void hello_exit(void){
printk("gooodbye! \n");
}

完整的一个最简单的 Linux 内核模块,如下图所示。
在这里插入图片描述
大致流程如图,但先不必深究,我们现在只需要知道需要两个函数。`

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int hello_init (void)
{

    printk("hello word!\n");
    return 0;

}

static void hello_exit(void)
{

    printk("bye bye !\n");


}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");  //版本申明

写好代码后将代码放在内核源码下进行编译。

代码编译:

创建Makefile文件

obj-m += helloworld.o //先写生成的中间文件的名字是什么,-m 的意思是把我们的驱动编译成模块
KDIR:=/home/topeet/driver/imx6ull/linux-imx-rel_imx_4.1.15_2.1.0_ga/
PWD?=$(shell pwd) //获取当前目录的变量
all:
make -C $(KDIR) M=$(PWD) modules //make 会进入内核源码的路径,然后把当前路径下的代码编译成
模块

注意:
1 KDIR:=/home/topeet/driver/imx6ull/linux-imx-rel_imx_4.1.15_2.1.0_ga/是设备树内核的源码路径,请大家根
据自己的实际情况进行修改。
2 设备树内核源码一定要先编译通过,才能编译驱动,否则会报错。
3 make -C 前面的空格是一个 tab 键
设置交叉编译器,输入以下命令:

export CROSS_COMPILE=arm-none-linux-gnueabi- 
export ARCH=arm

编译它会产生 helloworld.ko 目标文件,如下图所示
在这里插入图片描述
使用SSH传输到开发板即可。
使用命令:

insmod hello.ko//挂载
rmmod hello //卸载

在这里插入图片描述
第一个驱动成功,麻雀虽小五脏俱全,理解这个简单的驱动就一通百通了。

标签:word,dtb,make,hello,topeet,Linux,imx,arch,arm
来源: https://blog.csdn.net/Javalllq/article/details/120498577

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有