Linux内核驱动开发(一)
Linux内核初探
linux操作系统历史
开发模式
git
- 分布式管理
- git clone 获取
- git push 提交
- git pull 更新
邮件组 mailing list
patch
内核代码组成
Makfile
arch 体系系统架构相关
block 块设备
crypto 加密算法
drivers 驱动(85%)
- atm 通信
- bluetooth 蓝牙
firmware:外设
fs 文件系统
include 头文件
init 启动代码
ipc 进程通信代码
kernel 内核
lib 库
mm 内存管理
net 网络相关
scripts 脚本
security 安全相关
sound 音频相关
tools 工具(perf 测试工具)
usr 生成打包等
virt 虚拟化
内核配置和编译
- 工具链(编译器 arm-linux-gcc、链接工具 ld、查看 objdump、调试)
- 配置内核(决定需要编译的代码模块)
- 编译内核(生成可执行文件)
vmlinux(原始,未压缩的可执行文件)、zImage(压缩的可执行文件=压缩vmlinux+解压程序头)和uImage(用于给uboot引导的zImage)
花里胡哨:
ls -a 显示隐藏文件,即.***
Y 编译内核 N 不编译内核 M 模块编译
make -j4 zImage
CC 一个.o ;LD 一个目标下的.o
Linux内核的基本概念
物理地址&虚拟地址
地址转换:内核使用的地址一定是内核地址,但是cpu使用的是物理地址,中间存在一个转换过程。
- phys_to_virt:
- virt_to_phys:
页表:虚拟 -》物理;内存管理最小单位为页(大小为4k);页表大小=所有物理地址/4k。
- 页表初始化:start_kernel->mm_init->mm_alloc_pgd(划出一段内存,页表初始化)
- ioremap(cookie,size):最后调用 分配pgd
- 页表初始化:start_kernel->mm_init->mm_alloc_pgd(划出一段内存,页表初始化)
内存属性:可读、可写、可执行。
Linux内核中的内存管理
页(4k byte)为单位进行管理
分配内存举例
- alloc_pages(gfp_mask,order):分配内存的底层调用,可以分配整页的内存;gfp_mask是不同选项的组合(GFP_NOWAIT:分配不允许等待;GFP_ATOMIC;GFP_NOFS:不能进行文件操作;GFP_KERNEL:给内核用;GFP_USER;GFP_IOFS:分配内存可以IO操作);order分配2的次方的页
- kmalloc:分配内存的函数(以字节为单位),分配内存必定是连续的。
- vmalloc:分配内存物理上不连续,虚拟地址连续。
系统调用(Linux特用):用户调用内核函数(API)的媒介,具体实现(通过一个 异常 ,使得应用程序陷入内核中执行)
内核进程、线程
内核只有线程,没有进程
线程的task_struct(核心结构):包括进程的优先级、堆栈信息、打开文件句柄信息
线程的调度(3种优先级:SCHED_RR、SCHED_PRI、SCHED_RT);调度的时机:时钟中断发生;Linux发生内核态和用户态相互切换;Liunx执行完信号
内核中同步和线程间通信方式
原子操作:不可能被打断的基本操作
同步通信方式
自旋锁(spin_lock)
信号量(up:释放 和 down:)
异步通信方式
- 信号 – signal :处理信号的函数在task_struct中指明。
- 信号 – signal :处理信号的函数在task_struct中指明。
中断
- 中断的硬件概念:就是一个外部的电平信号
- 中断处理的上半部:需要linux内核关闭其他硬件信号
- 中断处理的下半部:上半部中来不及处理、比较冗长的程序段;需要等待其他程序结果,或者需要等待获取其他资源的程序段。
时钟和定时器管理
- 时钟硬件概念:能够产生一种定时中断的电路
- RTC(实时时钟或实时计数器)和system timer(很多情况就是用来作为延迟和计算相对时间)
- tick(时钟中断的周期,HZ)& jiffies(全局变量,如果是64位系统,就是64位的变量,记录了从上电开始,所经历的tick数)
文件系统
- 虚拟文件系统(VFS):是linux内核为了屏蔽物理文件系统的差异所产生的一个中间层。
- 物理文件系统(ext4:最大特点是具有完善的日志系统,yaffs2:比较适合在nand flash部署的文件系统,ubifs和btfs)
Linux驱动程序开发基础
内核模块编程
驱动模块化编程的好处
- 驱动编译进内核,导致内核非常大
- 很多驱动都只是在特定机器上使用
- 实现热插拔提供基础
模块编程的代码实例
- 实例验证hello.ko模块
- 实例验证hello.ko模块
Makefile的写法
- 其他- 模块位置可以随意放置- 内核代码更新,模块代码也要更新
驱动程序访问硬件的特殊性
DMA
dma的基本硬件概念:是存在外设设备中的一个硬件控制器,作用是不需要cpu协助,就可以搬移内存数据到外设的存储设备中。
dma的基本配置过程:通过程序配置dma控制器,告诉dma控制器它可以访问的内存地址。然后cpu将要传给外设的数据写到事前约定好的地址。
IO子系统:在嵌入式系统中,实现对外围附属设备进行控制的有效手段。通过IO端口进行0和1操作,可以发指令或者传递信息给附属设备。
Linux设备模型:最初目的是实现只能电源管理
kobject
一个设备驱动会建立一个kobject,偶尔也有因为功能复杂的原因而建立多个kobject。
koject会有一个一个kobj_type属性。
- entry :本人所在目录- parent:父节点- kset:一组类似性质的kobject集合- ktype:类型- kref:这个对象的引用计数
kobject一般都是sysfs中的一个目录,从而形成对用户空间的交互。
引用计数kref。
kset:一组类似性质的kobject集合;一个kset也就是一个子系统,它是sysfs的一个顶层目录的表征。比如block子系统,各种总线子系统。
sysfs:虚拟文件系统(管理内核的设备而非磁盘,它是kobject对象的完整视图)
主要api(sysfs_create_file; sysfs_create_link; sysfs_remove_file; sysfs_remove_link)
提供丰富的内核和用户空间交互的手段
sysfs主要目录结构
- block:块设备,独立于所链接的总线。- devices:被所有内核识别的硬件设备,依照链接他们的总线对其进行组织。- bus:系统中用于连接设备的总线- drivers:在内核中注册的设备驱动程序- class:系统中设备的类型(声卡,网卡,显卡等);同一类可能包含由不同总线连接的设备,于是由不同的驱动程序驱动。- power:处理一些硬件设备电源状态的文件。- firmware:处理一些硬件设备固件的文件。
udev:处理热插拔机制,通过设备驱动加载时,注册kobject后,向用户空间发送uevent实现的。
Linux驱动的分类
字符设备:一般都是以串行顺序依次进行访问,典型的包括触摸屏,鼠标,按键等。
- cdev结构:
- cdev结构:
块设备:一般以扇区、块为单位进行读写访问,例如硬盘,cdrom,flash等
网络设备:以太网的设备。
杂项设备:没法归类或复合设备。
Linux内核的基本调试方法
printk
- 级别
- dmesg
- 打开和关闭调试信息
oops
kprobe
kcore
Linux内核驱动开发(一)相关推荐
- 树莓派基于Linux内核驱动开发详解
一.驱动认知 首先理解Linux内核框图 文件系统认知,Linux内核框图 1.什么是驱动 linux内核驱动.软件层面上的驱动 广义上是指:这一段代码操作了硬件去动,所以这一段代码就叫硬件的驱动程序 ...
- 嵌入式 Linux 内核驱动开发【The first day: 36093万字】
嵌入式 Linux 内核驱动开发[1] 嵌入式 Linux 内核驱动开发前言 第1章 Linux 内核裁剪和定制 [1]Linux 内核开发简介 [2] Linux 源码阅读工具 [1.2.1]Sou ...
- Linux内核驱动开发的EXPORT_SYMBOL
前言 很抱歉各位粉丝啊,博主好久没有更新原创文章,从今天起开始恢复写文章的时光.前段时间各种不顺利,到时心情低落.现在恢复状态了. 简介 本文主要来讲讲Linux内核驱动中,EXPORT_SYMBOL ...
- Linux内核驱动开发-USB热插拔信息调取
前言: 前段时间上科大嵌入式安卓开发溜了个作业,开发一个驱动,可以实现读取USB热插拔信息,程序调用显示USB设备名称和插拔时间.代码已经放在了我的Github上,供大家参考. 思路: USB热插拔的 ...
- Linux 内核驱动开发基础
1.裸板驱动和linux驱动的异同点 裸板驱动:uart驱动程序:uart_inituart_putsuart_getsi2c控制器驱动:i2c_starti2c_stopi2c_txi2c_rxg- ...
- 树莓派基于Linux内核驱动开发
一.驱动认知 1.1 为什么要学习写驱动 树莓派开发简单是因为有厂家提供的wiringPi库,实现超声波,实现继电器操作,做灯的点亮-都非常简单. 但未来做开发时,不一定都是用树莓派,则没有wirin ...
- 第三阶段:43-47.树莓派基于Linux内核驱动开发
目录 一.驱动认知 1.1 为什么要学习写驱动 1.2 文件名与设备号 1.3 open函数打通上层到底层硬件的详细过程 二.基于框架编写驱动代码 2.1 编写上层应用代码 2.2 修改内核驱动框架代 ...
- linux 内核驱动开发
一.为什么要学习内核? 有些人要学习内核,而有些人则可以不学习它.你如果以后要从事系统研发或驱动开发的话,就要学习内核. 刚刚接触内核,主要学习内核的接口函数.不要深入的去读内核,因为你读也读不懂,内 ...
- linux内核驱动开发 培训,嵌入式Linux驱动开发培训 - 华清远见教育集团官网
9.LINUX下USB驱动开发基础 9.1 USB规范介绍 9.2 USB主机控制器 9.3 USB HUB 9.4 USB设备状态 9.5 USB描述符 9.6 USB请求 9.7 USB通讯数据格 ...
最新文章
- java 视频 缩略图_Java截取视频文件缩略图
- php如何实现根据地区内筛选,PHP区块查询实现方法分析
- 2022年全球及中国燃气供应系统 (FGSS)行业设施规模与十四五布局建设报告
- python 小波去噪,用Pywavelet去噪信号?
- Netflix如何使用机器学习来提升流媒体质量?
- Tuxera NTFS for Mac中文官网正式推出
- 微信小程序setTimeout自动跳转页面
- android数据的五种存储方式
- linux日常常用命令分析
- 贝叶斯分析好坏_高人进,关于贝叶斯估计的几个重要问题!
- 程序员也要学英语——连词、并列句和从句
- 申诉受理 - 工业和信息化部电信用户申诉受理中心 - PoweredCMSECMS
- 巴菲特致股东的一封信:1999年
- 发链(FAB)技术有望突破区块链交易瓶颈
- redis 存 JSONObject 报 nested exception is java.io.NotSerializableException:
- 摄像头视频推流python_python中用FFmpeg向rtmp服务器推流,实现摄像头直播
- 【SCSS】1300- 这些 SCSS 使用技巧真好用~
- 几种身份认证方式的分析
- 轻松实现各种文档格式转换,doc转pdf、doc转png图片、pdf转png图片,可以实现Windows、Linux、MacOS平台上部署(附源码和说明)
- 【MATLAB教程案例7】基于Gardner环的定时误差检测matlab仿真