当前位置: 首页 > news >正文

内核编译 设备驱动 驱动程序

内核编译

一、内核编译的步骤

编译步骤: (linux 内核源码的顶层目录下操作 )
1. 拷贝默认配置到 .config              cp config_mini2440_td35 .config
2. make menuconfig 内核配置       make menuconfig
3. make uImage                             make uImage

二、编译过程遇到的问题 

1、在 make uImage编译时报错:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373.
/home/linux/linux-2.6.32.2/kernel/Makefile:129: recipe for target 'kernel/timeconst.h' failed
make[1]: *** [kernel/timeconst.h] Error 255
Makefile:878: recipe for target 'kernel' failed
make: *** [kernel] Error 2

修改

 2、修改入口地址

通过tftp下载到开发板后,内核还不能正常启动 

 原因:

加载地址 Load Address:0x30008000

入口地址 Entry Point:要改成0x30008040

因为:uImage前64字节是头文件,要偏移64字节

3、 Image zImage uImage
Image 可以直接使用的内核镜映像
zImage 一段解压程序 + Image 的压缩文件
uImage 64 字节的头信息+ zImage

改成下图 

修改方法

 

再重新编译 

三、向内核中加入新文件

向内核中新加文件(以向 drivers/char 下新加 test.c 文件为例)
1. drivers/char 目录下创建并编辑文件 test.c
2. 修改同层目录下 Makefile ,新增一句
obj-$(CONFIG_TEST) += test.o
3. 修改同层目录下的 Kconfig ,新增一个配置选项
config TEST
bool “ this is a test
default y
help
hahaha, have big use, donot delelte!
4. make menuconfig
5. make uImage

 四、加入新的目录

1、创建一个新的目录,在该目录下写一个新的Kconfig

Kconfig的格式

2、在该目录的上一级目录的Kconfig里加入

五、补充知识

1、在 Linux 内核编译过程中,cp config_mini2440_td35 .config 命令的作用是将一个预先配置好的内核配置文件 config_mini2440_td35 复制到当前目录下的 .config 文件中。

2、make menuconfig 可视化的配置菜单(内核活地图)配置完成后,可以保存更改,这些更改将反映在当前目录下的 .config 文件中。

3、更改Kconfig的配置后,make menuconfig菜单也会被更改(Kconfig 定义make menuconfig中的选项)

4、

.config ( 存放 make menuconfig 的配置结果 )
CONFIG_BT = y
CONFIG_WIFI = n
Makefile ( 使用 .config 中的变量 )
obj-$(CONFIG_BT) += bt.o
obj-$(CONFIG_WIFI) += wifi.o
b 相对跳转 短跳转 pc += 100
ldr 绝对跳转 长跳转 pc = 200
地址相关代码: 加载地址和链接地址需要保持一致
地址无关代码:

设备驱动

设备驱动分类:
字符设备:数据访问是顺序的 ( 字节流 )
块设备:数据访问是随机的,一般是存储设备
网络设备:会集成协议, 靠名字维护

 计算机组成:软件(图上)、硬件(图下)

设备号: 32位
高12位:主设备号,区分不通类型的设备
低20位:次设备号,区分同类的不通设备 

驱动程序开发步骤

1、向内核中加入新文件(具体参考上面)
加入的demo.c文件内容 (驱动程序),加入后配置make menuconfig 编译make uImage
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/module.h>#define MAJOR_NUM 255
#define MINOR_NUM 0
#define DEV_NAME "demo"static int open(struct inode*node,struct file*file)
{printk("demo open ...\n");return 0;
}static ssize_t read(struct file*file,char __user*buf,size_t len,loff_t*offset)
{printk("demo read...\n");return 0;
}static ssize_t write(struct file*file,const char __user*buf,size_t len,loff_t*offset)
{printk("demo write ...\n");return 0;
}static int close(struct inode*node,struct file *file)
{printk("demo close...\n");return 0;
}static dev_t dev_num;
static struct  file_operations fops=
{.owner =THIS_MODULE,.open=open,.read=read,.write=write,.release=close
};
static struct cdev dev;static int __init demo_init(void)
{int ret=0;dev_num =MKDEV(MAJOR_NUM,MINOR_NUM);ret=cdev_add(&dev,dev_num,1);if(ret<0){goto err_cdrv_add;}cdev_init(&dev,&fops);ret=register_chrdev_region(dev_num,1,DEV_NAME);if(ret<0)goto err_register;printk("demo_init #######################\n");// registerreturn 0;err_cdrv_add:cdev_del(&dev);printk("demo_init cdev_add failed ...\n");return ret;err_register:unregister_chrdev_region(dev_num,1);cdev_del(&dev);printk("demo_init cdev_add failed ...\n");return ret;
}static void __exit demo_exit(void)
{unregister_chrdev_region(dev_num,1);cdev_del(&dev);printk("demo_exit #######################\n");
}module_init(demo_init);
module_exit(demo_exit);

2、在 下写应用层的程序,并用 arm-linux-gcc demo_app.c -o demo_app命令编译
应用层的程序demo_app.c的内容
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>int main(int argc, const char *argv[])
{int fd=open("/dev/demo_app",O_RDWR);if(-1==fd){perror("open");return -1;}char buf[10];read(fd,buf,sizeof(buf));write(fd,buf,sizeof(buf));close(fd);return 0;
}

3、在开发板下载内核、启动内核

4、在开发板上的Linux系统输入命令:mknod /dev/demo_app c 255 0

手动创建设备节点:
mknod /dev/demo c 255 0
/dev/demo 设备节点名称 (open 的设备名 )
c 字符设备
255 主设备号
0 次设备号

 5、最后运行应用层的程序 

相关文章:

内核编译 设备驱动 驱动程序

内核编译 一、内核编译的步骤 编译步骤&#xff1a; (linux 内核源码的顶层目录下操作 ) 1. 拷贝默认配置到 .config cp config_mini2440_td35 .config 2. make menuconfig 内核配置 make menuconfig 3. make uImage make u…...

自由学习记录

约束的泛型通配符? Java中的泛型 xiaomi和byd都继承了car&#xff0c;但是只是这两个类是car的子类而已&#xff0c;而arraylist<xiaomi> ,arraylist<byd> 两个没有半毛钱继承关系 所以传入的参数整体&#xff0c;是car的list变形&#xff0c;里面的确都能存car…...

在 C# 中使用 LINQ 查询文件列表并找出最大文件

文章目录 1. 环境准备2. 创建项目3. 引入命名空间4. 示例代码5. 运行代码6. 进阶&#xff1a;异常处理7. 总结 在现代 C# 开发中&#xff0c;LINQ (Language Integrated Query) 提供了一种强大而优雅的方式来处理集合数据。本文将详细介绍如何使用 LINQ 查询文件系统中的文件&a…...

数学建模算法与应用 第6章 微分方程建模及其求解方法

目录 6.1 微分方程建模概述 6.2 发射卫星与三阶火箭建模 Matlab代码示例&#xff1a;火箭发射模拟 6.3 微分方程数值解法 Matlab代码示例&#xff1a;欧拉法与龙格-库塔法 6.4 放射性废料的处理 Matlab代码示例&#xff1a;放射性衰变 6.5 初值问题的Matlab数值求解 习…...

数据库的相关知识

数据库的相关知识 1.数据库能够做什么&#xff1f; 存储大量数据&#xff0c;方便检索和访问保持数据信息的一致、完整共享和安全通过组合分析&#xff0c;产生新的有用信息 2.数据库作用&#xff1f; 存储数据、检索数据、生成新的数据 3.数据库要求&#xff1f; 统一、…...

Python cachetools常用缓存算法汇总

文章目录 cachetools介绍缓存操作设置数据生存时间&#xff08;TTL&#xff09;自定义缓存策略缓存装饰器缓存清理cachetools 超过缓存数量maxsize cachetools 使用示例 cachetools介绍 cachetools : 是一个Python第三方库&#xff0c;提供了多种缓存算法的实现。缓存是一种用于…...

java类和对象_成员变量方法修饰符局部变量this关键字-cnblog

java类和对象 成员变量 权限修饰符 变量类型 变量名; 成员变量可以是任意类型,整个类是成员变量的作用范围 成员变量 成员方法 权限修饰符 返回值类型 方法名() 成员方法可以有参数&#xff0c;也可以有返回值&#xff0c;用return声明 权限修饰符 private 只能在本类…...

海信和TCL雷鸟及各大品牌智能电视测评

买了型号为32E2F(9008)的海信智能的电视有一段时间了&#xff0c;要使用这个智能电视还真能考验你的智商。海信电视有很多优点&#xff0c;它的屏幕比较靓丽&#xff0c;色彩好看&#xff0c;遥控器不用对着屏幕就能操作。但也有不少缺点。 1. 海信智能电视会强迫自动更新操作…...

Linux 基本系统命令及其使用详解手册(六)

指令&#xff1a;mesg   使用权限:所有使用者   使用方式:mesg [y|n]   说明 &#xff1a; 决定是否允许其他人传讯息到自己的终端机介面   把计 :   y:允许讯息传到终端机介面上。   n:不允许讯息传到终端机介面上 。   如果没有设定,则讯息传递与否则由终端机界…...

Oracle架构之段管理和区管理

文章目录 1 段1.1 简介1.1.1 定义1.1.2 分类 1.2 段空间的管理模式1.2.1 手工段空间管理&#xff08;Manual Segment Space Management&#xff09;1.2.2 自动段空间管理&#xff08;Auto Segment Space Management&#xff09; 1.3 段空间的手工管理&#xff08;Manual Segmen…...

mybatis-plus转换数据库json类型数据为java对象

JacksonTypeHandler JacksonTypeHandler 可以实现把json字符串转换为java对象。同一类型的handler有: Fastjson2TypeHandlerFastjsonTypeHandlerGsonTypeHandlerJacksonTypeHandler 至于需要哪一个选一个用就好了 使用方式 在实体类中加入注解 TableName(value "table_…...

Java | Leetcode Java题解之第467题环绕字符串中唯一的子字符串

题目&#xff1a; 题解&#xff1a; class Solution {public int findSubstringInWraproundString(String p) {int[] dp new int[26];int k 0;for (int i 0; i < p.length(); i) {if (i > 0 && (p.charAt(i) - p.charAt(i - 1) 26) % 26 1) { // 字符之差为…...

诺贝尔物理奖与化学奖彰显AI力量,探索智能新边界

在今年的诺贝尔物理学奖和化学奖的颁奖典礼上&#xff0c;人工智能&#xff08;AI&#xff09;再次成为耀眼的明星。两位物理学奖得主约翰J霍普菲尔德和杰弗里E辛顿因在人工神经网络和机器学习领域的开创性工作而获奖&#xff0c;而化学奖则颁给了在蛋白质结构设计和预测方面做…...

基于京东:HotKey实现自动缓存热点Key!!!

一.引言 某些热点数据&#xff0c;我们提前如果能够预判到的话&#xff0c;可以提前人工给数据加缓存&#xff0c;也就是缓存预热&#xff0c;将其缓存在本地或者Redis中&#xff0c;提高访问性能同时&#xff0c;减低数据库压力&#xff0c;也减轻后端服务的压力。但是&#…...

★ 算法OJ题 ★ 二分查找算法

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;塞尔达将和大家一起做几道二分查找算法算法题 ~ ❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️ 澄岚主页&#xff1a;椎名澄嵐-CSDN博客 算法专栏&#xff1a;★ 优选算法100天 ★_椎名澄嵐的博客-CSDN博客…...

RTSP RTP RTCP SDP基础知识

理论 流&#xff08;Streaming &#xff09; 是近年在 Internet 上出现的新概念&#xff0c;其定义非常广泛&#xff0c;主要是指通过网络传输多媒体数据的技术总称。 流式传输分为两种 顺序流式传输 (Progressive Streaming) 实时流式传输 (Real time Streaming) ​​​​​…...

静态变量、变量作用域、命名空间

静态变量 静态变量一般位于程序全局data区&#xff0c;只是编程语言根据它所在的scope做语言级别访问限制。 静态变量和全局变量 可以在C语言一个函数中定义static变量&#xff0c;并比较和全局变量的地址差异。 C系语言使用static关键字标示静态变量。 PHP使用大写的STATIC关键…...

Android笔记(二十四)基于Compose组件的MVVM模式和MVI模式的实现

仔细研究了一下MVI(Model-View-Intent)模式&#xff0c;发现它和MVVM模式非常的相识。在采用Android JetPack Compose组件下&#xff0c;MVI模式的实现和MVVM模式的实现非常的类似&#xff0c;都需要借助ViewModel实现业务逻辑和视图数据和状态的传递。在这篇文章中&#xff0c…...

MySQL 是否支持 XML

MySQL 是否支持 XML&#xff1a;概述与应用 虽然 MySQL 主要以处理关系型数据为主&#xff0c;但它也提供了对 XML 数据的支持。XML&#xff08;可扩展标记语言&#xff09;是一种用于数据传输和存储的通用格式。在许多应用场景中&#xff0c;XML 被广泛用于数据交换、配置文件…...

pikachu靶场总结(四)

九、越权漏洞 1.概述 如果使用A用户的权限去操作B用户的数据&#xff0c;A的权限小于B的权限&#xff0c;如果能够成功操作&#xff0c;则称之为越权操作。 越权漏洞形成的原因是后台使用了 不合理的权限校验规则导致的。 一般越权漏洞容易出现在权限页面&#xff08;需要登…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...