嵌入式 - 内核驱动2 - 实现设备驱动
一、驱动程序
1. 驱动分类
1. 字符设备驱动
数据访问按字节流(按顺序)的形式,不支持随机寻址
应用程序通过 /dev
目录下的设备文件,像操作普通文件一样使用这些设备。
绝大多数设备都属于字符设备
2. 块设备驱动:
数据被组织成固定大小的块,访问是块(随机)的
例如:存储设备
3. 网络设备驱动
集成比较复杂的协议栈
例如:网卡
2. 设备号
1. 定义
代表一个具体的设备 / 驱动程序 -- 无符号32位
2. 分类
主设备号 高12位:区分设备类型 如SPI IIC
从设备号 低20位:区分同类型的不同设备 如SPIO SPI1 SPI2
3. ctags工具
1. 概念
2. 配置
1. 安装ctags命令
sudo apt-get install ctags
2. 生成tags
ctags -R
3. 寻找
tags文件可以寻找定义,但必须在当前目录下执行
3. 虚拟机操作命令
跳转到定义位置 ctrl + ]
跳转回上一位置 ctrl + o
:%s/demo/led/g 查找替换
4. 寻找定义
__define_initcall(fn, id) fn = demo_init if = 6
此时static宏展开为
initcall_t __initcall_demo_init_6 __used attribute__(__section__(".initcall6.init")) = demo_init
其中##为链接符,与前一个字符链接,#为转换为字符串,用于 " " 内拼接段名
attribute属性 放在secrion(".initcall6.init")段中
二、启动程序
1. uboot命令
uboot启动倒计时为0前按回车进入uboot命令行
1. help / ?
查看 命令 -- 功能
2. printenv = export
打印环境变量
其中参数有baudrate -- 波特率
bootdelay -- 启动延时
倒计时结束前按下回车进入uboot命令行
否则执行bootcmd
console -- 控制台 -- ttymxc0:串口0
3. setenv
设置 setenv bootdelay(环境变量名) 5(数值)
4. saveenv
保存环境变量
saveenv 环境变量名
5. setenv
删除环境变量
setenv 环境变量名
6. reset
重启uboot
ping通虚拟机需要给tftp配置地址,设置启动参数
完成单项ping通
setenv ipaddr 192.168.1.100
setenv ethaddr 00:11:22:33:44:55
setenv netmask 255.255.255.0
setenv geteway 192.168.1.1
saveenvping通:
7. tftp
步骤:
tftp下载zImage imx6ull
tftp 0x8080000 zImage 将zImage下载到内存的0x80800000地址中setenv serverip 192.168.1.200 配置下载地址(ubutu的地址)
Loading:#代表数据包
8. bootz
启动一个zImage
失败情况:
此时内核启动成功,但内核挂载失败
终端卡死,需要重启开发板
所以需要设置相关环境变量
setenv bootargs root=/dev/nfs nfsroot=192.168.1.200:/home/linux/nfs/imx6/rootfs,nfsvers=3 ip=192.168.1.100 console=ttymxc0,115200 init=/linuxrc
root:根文件系统类型
nfsroot:启动nfs根文件系统的位置,在主机下的目录 主机端口 :/ 挂载地址
ip:内核启动使用的ip
console:终端串口0
init:指定init进程,启动时需要执行的程序
2. 配置环境变量
1. 解压内核源码
在nfs目录下新建imx6作为挂载地址
在挂载目录路径下解压内核源码
sudo tar -xvf linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek.tar.gz
2. 解压根文件系统文件
sudo tar -xvf rootfs.tar.gz
3. 修改Makefile
确认编译器
4. 拷贝默认设置
所有配置都在 arch / arm / configs
cp arch/arm/configs/imx_alientek_emmc_defconfig .config
或
makeimx_alientek_emmc_defconfig
5. 进入内核源码顶层目录
以后所有操作均在顶层目录操作
cd linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek
3. 内核编译步骤
配置环境变量 => ping通虚拟机 => tftp下载 => 启动
1. tftp 部分
在内核源码顶层目录操作
1. 在drivers / char 目录新建并编译 .c文件
vim drivers / char / test.c
2. 修改同目录下的Makefile
vim drivers / char / Makefile
新增一行 obj-$(CONFIG_TEST) += test.o
3. 修改同目录下的Kconfig
vim drivers / char / Makefile
新增配置
4. 进入menuconfig
sudo make menuconfig
Device Drivers => Character devices => "this is a test" 空格勾选设置 y / n
5. 编译make
编译生成新的 zImage
sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j8
6. 拷贝zImage 到 tftp 目录下
cp arch/arm/boot/zImage /home/linux/tftpboot/
2. nfs 部分
在根文件系统目录下
1. 在目录下新建并编译 _app.c文件
vim drivers / char / test_app.c
2. 编译make
arm-linux-gnueabihf-gcc test_app.c -o test_app
3. 开发板(内核)部分
1. 在倒计时结束前进入内核命令行
2. tftp下载
tftp下载kernel到内存中,完成对kernel的传参
tftp 0x80800000 zImage
tftp 0x83000000 imx6ull-alientek-emmc.dtb
3. 内核启动
根据bootloader传递的参数挂载
挂载完成后内核 init 进程退化为用户可见的 init 进程
init 进程加载各种配置、启动各种脚本 / 程序、启动shell完成操作系统启动
bootz 0x80800000 - 0x83000000
4. shell 部分
1. 查看设备文件
确认主 / 从设备号
ls -l /dev
2. 创建设备节点
mknod /dev/test c 255 0
3. 运行程序
开发板的根目录挂载在 ubutu 的 nfs 下,所以开发板可以直接运行在nfs下编译的程序
./ test_app