Linux驱动学习前置知识(了解)及基本框架

分层思想

在学习驱动开发你必须要知道的 Linux 下的系统的知识
我们之前做 Linux 的系统开发的时候 我们开发的代码是 以 main 作为 C 语言的框架
开发多进程 多线程的这种应用级开发
大家再开发种应该都遇到一种情况 : 野指针 -> 程序跑飞 -> 死掉!
大家都知道一件事:
指针指向是地址,野指针指向也是地址 -> 地址是随机!
寄存器本身是地址
STM32 的库函数底层 寄存器 -> 地址!
有没有可能发生这种事:
野指针指向了寄存器 -> CPU 的 LCD 的接口时钟地址
为什么众多开发者在学习 C 语言
出现野指针的时候为什么没有把系统搞死机
为什么没有出现开发 C 语言或者系统的时候突然关机呢!

虚拟内存

所有你在系统看到的得到的地址都是假的,都是虚拟,都是映射而来的!
你只要得到的地址,你只要在系统映射后的地址
都是由 -> DDRAM 这个运存所占用的物理地址 ( 真实地址 ) 映射而来的!
我们的程序运行在 RAM 里面,
程序的虚拟地址映射于 RAM 的真实的物理地址
程序无论如何都无法访问真实地址,更加不要想要访问硬件了!
既然是虚拟地址,你随意写入关闭你能访问的地址
都是虚假的,都不可能访问到硬件 ( 真实的地址 )
为什么系统需要这样做?
在牛掰的黑客,只能黑掉你的系统,但从不能黑掉硬件!
保护硬件!
因为系统的虚拟的地址映射
所有的程序跑的地址都是虚假的
无法访问真实物理地址!
也在保护你!
那这个东西成为我们开发驱动的一个阻碍
访问硬件更加的麻烦和复杂
实际上:
真实的系统分为两大层:
系统层:
你们之前所学所有的知识
你们之前所写的所有的代码
都是在系统层
内核层 :
运行在内核内部
的程序。他有特权,同时很危险

系统层和内核层

系统层
指的是我们之前一直正常运行在系统的程序
内核层
运行在内核里面,程序比较特殊,权限较大
内核层有访问真实物理地址的权限
有了这个基础 内核层就可以访问硬件
内核层就可以开发硬件->开发驱动

驱动的理论基础

前言

内核层 运行的程序不同于以往, 不在 C 语言+ main 框架 ,而是 内核层:入口函数 出口函数

内核层入口和出口

cpp 复制代码
#include <linux/kernel.h>
#include <linux/module.h>


//内核层代码错误有可能直接造成内核死亡 + 系统死亡
/*入口函数:
 *内核层加载的时候入口函数会自动调用
 */
 int __init myled_init(void)
 {
 return 0;
 }
/*出口函数
 *内核卸载的时候,出口函数会自动调用
 */
  void __exit myled_exit(void)
  {
 
  }
 //往往入口函数用于注册驱动/初始化驱动的
 //往往出口函数 取消注册,清理驱动,释放空间

内核层的声明

cpp 复制代码
/* 
 *声明一般放到 函数下面
 *内核层代码。其中入口函数和出口函数必须声明!
 *内核层入口声明和出口声明有专门的函数声明
 */
// 声明入口函数的函数:
   module_init(声明入口函数名);
 //声明出口函数的函数:
 module_exit(声明出口函数名);
// 声明你的代码遵循 GPL 协议的
 MODULE_LICENSE("GPL");

驱动的编译

创建一个 Makefile
Makefile 注意点:
Makefile 命名是大写
Makefile 的目标和命令隔开 Tab
Makefile 不允许所在路径中间任意一个路径有 英文

obj-m += led.o
#obj-m:代表模块 module (驱动) 目标-> led.o->led.c
KDIR:=/home/***/RK3588S/kernel
#代表你的编译的所用的内核的位置
CROSS_COMPILE_FLAG=/home/***/RK3588S/prebuilts/gcc/linux-x86/aarch64/gcc-arm-
10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-
#这是你的交叉编译器路径
all:
make -C (KDIR) M=(PWD) modules ARCH=arm64 CROSS_COMPILE=$(CROSS_COMPILE_FLAG)
#调用内核层 Makefile 编译目标为 modules->模块 文件在当前路径

架构 ARCH=arm64

clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.markers *.order

调用内核Makefile编译时,内核的需要之前编译过。

终端输入make直接编译,编译后生成一个led.ko,这个就是驱动文件,然后用adb,终端输入adb push led.ko ,将adb推到开发板。

驱动的加载与卸载

ADB进入调试模式

终端输入adb shell 进入开发板,

加载驱动

bash 复制代码
insmod led.ko

卸载驱动

bash 复制代码
rmmod led.ko

串口调试

windows使用超级终端进行串口连接

linux 上使用 screen命令连接

没有screen 的先下载screen

bash 复制代码
sudo apt install screen
bash 复制代码
sudo screen /dev/ttyUSB0  波特率

当然用minicom也行,这个串口工具使用前得先配置,它支持传输文件,可以说非常好用,有兴趣可以搜一搜,这里就不在多做说明

相关推荐
叶子20242218 分钟前
学习使用YOLO的predict函数使用
人工智能·学习·yolo
jackson凌21 分钟前
【Java学习笔记】SringBuffer类(重点)
java·笔记·学习
黑客老李2 小时前
JavaSec | SpringAOP 链学习分析
java·运维·服务器·开发语言·学习·apache·memcached
海的诗篇_2 小时前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法
傍晚冰川3 小时前
FreeRTOS任务调度过程vTaskStartScheduler()&任务设计和划分
开发语言·笔记·stm32·单片机·嵌入式硬件·学习
月初,4 小时前
MongoDB学习和应用(高效的非关系型数据库)
学习·mongodb·nosql
casual_clover4 小时前
Android 之 kotlin 语言学习笔记四(Android KTX)
android·学习·kotlin
Love__Tay5 小时前
【学习笔记】Python金融基础
开发语言·笔记·python·学习·金融
我的golang之路果然有问题6 小时前
云服务器部署Gin+gorm 项目 demo
运维·服务器·后端·学习·golang·gin
Lester_11017 小时前
嵌入式学习笔记 - freeRTOS xTaskResumeAll( )函数解析
笔记·stm32·单片机·学习·freertos