Linux-----驱动

一、内核驱动与启动流程

1. Linux内核驱动
  • Nor Flash: 可线性访问,有专门的数据及地址总线(与内存访问方式相同)。

  • Nand Flash: 不可线性访问,访问需要控制逻辑(软件)。

2. Linux启动流程
  • ARM架构:

    • IRAM (4KB): 内部RAM,用于存储初始引导程序。

    • Nor Flash (2M): 存储u-boot程序。

    • 内存 (64M): 用于加载内核和根文件系统。

    • Nand Flash (256M): 存储内核、根文件系统等数据。

  • 启动过程:

    1. Bootloader (u-boot):

      • 初始化CPU、异常向量表、栈、时钟、内存等。

      • 关闭看门狗、中断、Cache、MMU。

      • 初始化相关硬件和软件协议。

      • 将内核加载到内存。

      • 向内核传递参数(根文件系统类型、位置、控制台等)。

      • 启动内核。

    2. 内核 (kernel):

      • 文件管理、内存管理、进程管理、网络管理、设备管理。

      • 启动到最后阶段加载根文件系统。

      • init进程启动后台服务程序、加载配置、启动shell和应用程序。

    3. 根文件系统 (rootfs):

      • 包含程序(应用、系统、命令)、配置文件、库文件、普通文件(txt、mp3)。

3. Windows与Linux对比
  • Windows: 使用BIOS启动。

  • Linux: 使用bootloader引导内核启动,内核加载rootfs。

4. 具体启动步骤
  • Nor Flash:

    • 系统上电后,PC指向0地址,直接执行Nor Flash中的u-boot程序。

  • Nand Flash:

    • 系统上电后,自动搬移u-boot前4KB程序到IRAM。

    • CPU执行IRAM中的代码,u-boot初始化内存并将剩余代码搬移到内存执行。

5. 内核与文件系统
  • 内核 (uImage):

    • 启动前u-boot向内核传递参数(tag_list)。

    • Nand Flash: u-boot直接读取Nand Flash中的uImage并写入内存的0x30008000地址处,启动内核。

    • Ubuntu: 通过TFTP下载uImage到内存的0x30008000地址处,启动内核。

  • 根文件系统 (rootfs):

    • Nand Flash: uImage启动到最后阶段时,直接挂载Nand Flash中的rootfs。

    • Ubuntu: uImage启动到最后阶段时,通过NFS挂载Ubuntu中的rootfs。

6. 前置步骤

  1. 向Nor Flash 0地址处烧写u-boot.bin。

  2. 拷贝uImage到Ubuntu的TFTP服务目录下。

  3. 将rootfs.tar.gz拷贝到Ubuntu的NFS服务目录下,并解压

    sudo tar -xvf rootfs.tar.gz
7. U-Boot命令
  • 环境变量管理:

    • printenv: 打印环境变量。

    • reset: 重启。

    • setenv serverip 192.168.1.3: 设置环境变量。

    • saveenv: 保存环境变量到Nand Flash。

    • setenv serverip: 删除环境变量。

  • 下载与启动:

    • tftp 0x30008000 uImage: 通过TFTP协议下载uImage到内存的0x30008000地址处。

    • bootm 0x30008000: 启动内存0x30008000地址处的内核。

    • go 0x30008000: 运行内存0x30008000地址处的程序。

8. 设置启动参数
setenv bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.1.3:/home/linux/nfs/rootfs ip=192.168.1.123 init=/linuxrc
  • console: 控制台(终端)。

  • root: 根文件系统类型。

  • nfsroot: 根文件系统位置。

  • ip: 内核阶段使用的IP。

  • init: 指定init进程。

二、内核编译

1. 内核编译步骤
  • Kconfig: 定义make menuconfig的配置选项。

  • make menuconfig: 内核配置。

  • .config: 配置文件,决定哪些文件被编译进内核。

    • CONFIG_SSL = n: 不启用SSL。

    • CONFIG_MM = y: 启用内存管理。

  • makefile: 条件编译,编译内核。

2. 内核镜像类型
  • Image: 可以直接使用的内核镜像。

  • zImage: 一段解压代码 + Image的压缩文件。

  • uImage: 64字节的头信息 + zImage。

3. 地址相关代码
  • 地址相关代码: 链接地址和加载地址一致。

  • 地址无关代码: 链接地址和加载地址无关。

4. 跳转指令
  • 相对跳转、短跳转: b fun

  • 绝对跳转、长跳转: ldr pc, 0x00000000

5. 内核目录结构

6. 向内核新增文件

以向drivers/char下添加demo.c为例:

  1. drivers/char目录下新建并编辑demo.c

  2. 修改同层目录下的Makefile,添加:

    makefile
    obj-$(CONFIG_DEMO) += demo.o
  3. 修改同层目录下的Kconfig,添加一个DEMO的配置。

  4. 执行make menuconfig

  5. 执行make uImage

7. 内核编译命令
  • 配置内核

    cp config_mini2440_t35 .config
    make menuconfig
  • 编译内核

    make uImage
8. 内核镜像说明
  • Image: 可直接使用的内核镜像。

  • zImage: 压缩的内核镜像,包含解压代码。

  • uImage: 带有64字节头信息的压缩内核镜像。

9. Makefile和Kconfig
  • 每层目录都有MakefileKconfig文件,用于配置和编译内核。

10. 编译流程总结
  1. 配置内核: 使用make menuconfig选择内核配置选项。

  2. 编译内核: 使用make uImage生成内核镜像。

  3. 验证内核: 确保生成的内核镜像可以正常启动。

11. 注意事项
  • 配置文件: .config文件决定了哪些模块被编译进内核。

  • 条件编译: 使用obj-$(CONFIG_XXX)进行条件编译。

  • 目录结构: 每层目录都有MakefileKconfig文件,确保编译过程正确。

三、驱动程序

1. 设备文件与驱动模块
  • 设备文件: 用户空间程序通过设备文件与驱动程序交互。

    • 示例: open("/dev/led");

  • 驱动模块: 内核中的驱动程序负责控制硬件设备。

    • 示例: sys_open(led)调用驱动模块。

2. 设备驱动类型
  • 字符设备驱动: 数据按顺序访问,90%以上的设备使用字符设备驱动。

  • 块设备驱动: 可以随机访问,主要用于存储设备。

  • 网络设备驱动: 网卡,集成复杂协议,通过套接字通信,没有设备号,靠名字维护。

3. 设备号
  • 设备号: 用于标识设备。

    • 主设备号 (高12位): 区分设备类型。

    • 次设备号 (低20位): 区分同类的不同设备。

  • 示例: dev_t 是32位设备号。

4. 创建设备节点
  • 使用mknod命令创建设备节点

    mknod /dev/demo3 c 255 0
    • /dev/demo3: 设备节点名。

    • c: 字符设备。

    • 255: 主设备号。

    • 0: 次设备号。

5. 驱动模块结构
  • 驱动模块: 包含openreadwriteioctlclose等函数。

  • 示例: drv_leddrv_keydrv_adc分别对应LED、按键、ADC设备。

6. 设备驱动流程
  1. 应用程序调用设备文件:

    • open("/dev/led");

  2. 内核调用驱动模块:

    • sys_open(led)drv_led

  3. 驱动模块控制硬件设备:

    • drv_led控制LED设备。

7. 设备号与驱动模块关系
  • 每个设备号对应一个驱动模块。

  • 内核通过设备号找到对应的驱动模块。

8. 设备号结构
+--------+--------+----+-------+
| 8      | 8      | 2  | 14    |
+--------+--------+----+-------+
设备类型  命令编号  数据  参数大小
魔幻数           流向
  • 设备类型 (魔幻数): 8位,标识设备类型。

  • 命令编号: 8位,标识具体命令。

  • 数据流向: 2位,标识数据方向。

  • 参数大小: 14位,标识参数大小。

9. 设备驱动总结
  • 字符设备: 顺序访问,适用于大多数设备。

  • 块设备: 随机访问,适用于存储设备。

  • 网络设备: 复杂协议,通过套接字通信。

  • 设备号: 区分设备类型和具体设备。

  • 驱动模块: 内核中的程序,负责控制硬件设备。

10. 关键命令
  • 创建设备节点: mknod

  • 设备文件操作: openreadwriteioctlclose

11. 注意事项
  • 设备号分配: 确保主设备号和次设备号唯一。

  • 驱动模块编写: 需要实现openreadwrite等函数。

  • 设备文件操作: 应用程序通过设备文件与驱动模块交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76494.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wincc脚本全部不运行

Wincc脚本全部不运行 前言解决办法操作步骤 前言 这里主要是指旧项目移植到Wincc的高版本,移植后界面的一些功能均会失效。(例如脚本不执行,项目编辑器不可用等情况) 解决办法 Wincc的项目文件中有Dcf文件,Dcf文件包…

使用numpy构建逻辑回归模型及训练流程

逻辑回归模型构建及训练流程 关于逻辑回归的数据,有很多学习⽤的⽰例样本。这⾥我们使⽤scikit learn提供的数据集⽣成函数来创建 具体参数可参照官网 Scikit-learn 是⽤ Python 开发的开源机器学习库,⼴泛⽤于数据挖掘和数据分析。 特点:易…

python的多线程和多进程程序编程

CPU密集型使用多进程,IO密集型使用多线程 查看进程ID和线程ID的命令分别是os.getpid()和threading.current_thread() 多进程使用multiprocessing就可以了,通常使用进程池来完成操作,阻塞主进程使用join方法 多线程使用threading模块&#…

代码随想录算法训练营第十五天

LeetCode题目: 654. 最大二叉树617. 合并二叉树700. 二叉搜索树中的搜索98. 验证二叉搜索树2843. 统计对称整数的数目 其他: 今日总结 往期打卡 654. 最大二叉树 跳转: 654. 最大二叉树 学习: 代码随想录公开讲解 问题: 给定一个不重复的整数数组 nums 。 最大二叉树 可以用…

[GN] Uart协议解码器源码各个方法

系列文章目录 sigrokdecode 模块学习指南 — 准备阶段 通讯协议 - Uart sigrokdecode 模块 UART协议解码器源码解析 Uart协议解码器源码各个方法 文章目录 系列文章目录引入库parity_ok注解类型枚举options参数annotations 注解annotation_rows 注解分组接收(RX&a…

技术分享|iTOP-RK3588开发板Ubuntu20系统旋转屏幕方案

iTOP-3588开发板采用瑞芯微RK3588处理器,是全新一代AloT高端应用芯片,采用8nmLP制程,搭载八核64位CPU,四核Cortex-A76和四核Cortex-A55架构,主频高达2.4GHz。是一款可用于互联网设备和其它数字多媒体的高性能产品。 在…

Unity IL2CPP内存泄漏追踪方案(基于Memory Profiler)技术详解

一、IL2CPP内存管理特性与泄漏根源 1. IL2CPP内存架构特点 内存区域管理方式常见泄漏类型托管堆(Managed)GC自动回收静态引用/事件订阅未取消原生堆(Native)手动管理非托管资源未释放桥接层GCHandle/PInvoke跨语言引用未正确释放 对惹,这里有一个游戏开发交流小组…

消融实验_草稿

五列数据 \begin{table}[htbp]\caption{Performance Comparison of Standalone KD Variants vs MIRKD-enhanced Variants on ACNE04 Dataset\label{AblationKD}}\centering\renewcommand{\arraystretch}{1.2}\scriptsize\begin{tabularx}{\linewidth}{{}l *{3}{>{\centering…

面向对象高级(1)

文章目录 final认识final关键字修饰类:修饰方法:修饰变量final修饰变量的注意事项 常量 单例类什么是设计模式?单例怎么写?饿汉式单例的特点是什么?单例有啥应用场景,有啥好处?懒汉式单例类。 枚举类认识枚…

不用额外下载jar包,idea快速查看使用的组件源码

以nacos为例子,在idea中引入了nacos依赖,就可以查看源码了。 2. idea选择open(不关闭项目直接选择file-open也可以), 在maven的仓库里找到对应的包,打开 2.idea中选择 jar包,选择 add as library 3.这样j…

小白学习java第12天:IO流之缓冲流

1.IO缓冲流: 之前我们学习的都是原始流(FileInputStream字节输入流、FileOutputStream字节输出流、FIleReader字符输入流、FIleWriter字符输出流)其实我们可以知道对于这些其实性能都不是很好,要么太慢一个一个,要么就…

高速电路设计概述

1.1 低速设计和高速设计的例子 本节通过一个简单的例子,探讨高速电路设计相对于低速电路设计需要考虑哪些不同的问题。希望读者通过本例,对高速电路设计建立一个表象的认识。至于高速电路设计中各方面的设计要点,将在后续章节展开详细的讨论…

MySQL8.0.31安装教程,附pdf资料和压缩包文件

参考资料:黑马程序员 一、下载 点开下面的链接:https://dev.mysql.com/downloads/mysql/ 点击Download 就可以下载对应的安装包了, 安装包如下: 我用夸克网盘分享了「mysql」,链接:https://pan.quark.cn/s/ab7b7acd572b 二、解…

在Java项目中,引入【全局异常处理器】

目录 一.为什么引入全局异常处理器(目前项目碰到了什么问题)? 1.问题描述 2.与预期的差别 3.解决方案 二.解决上述问题 1.定义【业务异常类】 2.在serviceImpl层,手动抛出【违反唯一性约束】这个异常 3.定义【全局异常处理…

newspaper公共库获取每个 URL 对应的新闻内容,并将提取的新闻正文保存到一个文件中

示例代码: from newspaper import Article from newspaper import Config import json from tqdm import tqdm import os import requestswith open(datasource/api/news_api.json, r) as file:data json.load(file)print(len(data)) save_path datasource/sourc…

前端核心知识:Vue 3 编程的 10 个实用技巧

文章目录 1. **使用 ref 和 reactive 管理响应式数据**原理解析代码示例注意事项 2. **组合式 API(Composition API)**原理解析代码示例优势 3. **使用 watch 和 watchEffect 监听数据变化**原理解析代码示例注意事项 4. **使用 provide 和 inject 实现跨…

【Web API系列】XMLHttpRequest API和Fetch API深入理解与应用指南

前言 在现代Web开发中,客户端与服务器之间的异步通信是构建动态应用的核心能力。无论是传统的AJAX技术(基于XMLHttpRequest)还是现代的Fetch API,它们都为实现这一目标提供了关键支持。本文将从底层原理、核心功能、代码实践到实…

[特殊字符] Spring Boot 日志系统入门博客大纲(适合初学者)

一、前言 📌 为什么日志在项目中如此重要? 在开发和维护一个后端系统时,日志就像程序运行时的“黑匣子”,帮我们记录系统的各种行为和异常。一份良好的日志,不仅能帮助我们快速定位问题,还能在以下场景中…

IP协议之IP,ICMP协议

1.因特网中的主要协议是TCP/IP,Interneet协议也叫TCP/IP协议簇 2.ip地址用点分十进制表示,由32位的二进制表示,两部分组成:网络标识主机标识 3.IP地址分类; A:0.0.0.0-127.255.255.255 B:128.0.0.0-191.255.255.25…

GPIO_ReadInputData和GPIO_ReadInputDataBit区别

目录 1、GPIO_ReadInputData: 2、GPIO_ReadInputDataBit: 总结 GPIO_ReadInputData 和 GPIO_ReadInputDataBit 是两个函数,通常用于读取微控制器GPIO(通用输入输出)引脚的输入状态,特别是在STM32系列微控制器中。它们之间的主要…