首页 > 编程语言 >内核编译 设备驱动 驱动程序

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

时间:2024-10-10 11:49:32浏览次数:3  
标签:驱动程序 demo make dev 编译 内核 include config

内核编译

一、内核编译的步骤

编译步骤: (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");
	// register
	return 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、最后运行应用层的程序 

标签:驱动程序,demo,make,dev,编译,内核,include,config
From: https://blog.csdn.net/T66656/article/details/142754052

相关文章

  • HarmonyOS开发——编译报错“The reason and usedScene attributes are mandatory for
    问题现象:DevEcoStudio编译失败,提示“ThereasonandusedSceneattributesaremandatoryforuser_grantpermissions”。问题原因:从DevEcoStudioNEXTDeveloperPreview2版本开始新增规则:APP包中,所有entry和featurehap的module下的requestPermissions权限清单必须指定(......
  • 手把手教你学PCIE(6.9)--驱动程序开发实例的网络设备驱动程序开发
    目录1.开发环境准备1.1安装开发工具1.2创建项目目录2.驱动程序代码2.1驱动程序头文件2.2驱动程序主文件3.编译驱动程序4.加载和卸载驱动程序5.测试驱动程序6.总结开发一个网络设备驱动程序是一个复杂的任务,涉及到网络协议栈的集成和硬件设备的管理。在......
  • 第二十二章 编译WebRTC框架
    源代码地址:https://webrtc.googlesource.com/src.git下载后放到src目录下gitclone https://chromium.googlesource.com/chromium/src/buildtools下载后放到src目录下gitclone https://chromium.googlesource.com/chromium/src/build需要https://chromium.googlesource.co......
  • Android反编译APK与解析软件包img
    1,Jadx反编译APK下载JadxJADX相当于是apktool+dex2jar+jd-gui的结合体,既能反编译代码也能反编译资源支持的文件有:(apk,dex,jar,class,smali,zip,xapk,aar,arsc,jadx,aab)等。打开之后界面如下,点击打开文件,再选择对应所需要反编译的apk(或者直接拖入apk)等......
  • Linux内核机制—smp_hotplug_thread
    一、简介只是一个创建per-cpu线程执行用户提供的回调的机制。内核中已存在的注册staticstructsmp_hotplug_threadidle_inject_threads={//drivers/powercap/idle_inject.c.store=&idle_inject_thread.tsk,.setup=idle_inject_setup,.thread_fn=id......
  • 快速编译安装nginx服务
    文章目录1软件包下载2安装编译依赖环境3编译安装Nginx4将Nginx做成服务5启动Nginx服务6访问Nginx页面7其他配置1、软件包下载nginx官网下载地址:https://nginx.org/en/download.html2、安装编译依赖环境1、安装编译环境yum -y install gcc gcc-c++2......
  • C++编译并运行后出现Process finished with exit code 139 (interrupted by signal 11
    问题描述:        代码运行意外终止,报错信息为Processfinishedwithexitcode139(interruptedbysignal11:SIGSEGV)CMakeList文件如下:cmake_minimum_required(VERSION3.26)project(SLAM)set(CMAKE_CXX_STANDARD17)set(CMAKE_CXX_STANDARD_REQUIRED......
  • GCC编译器CFLAGS、LDFLAGS详解
    目录CFLAGSLDFLAGS在编译C/C++程序时,可以使用CFLAGS和LDFLAGS环境变量来设置编译器和链接器的选项。下面对CFLAGS和LDFLAGS进行详解:CFLAGSCFLAGS是用于设置C/C++编译器选项的环境变量。它可以用来指定编译过程中的各种选项,如优化级别、警告级别、头文件包含路......
  • 为什么 React 和 Vue 不采用像 Svelte 那样的编译方式?
    在前端框架的竞争中,Svelte近年来以其极高的性能和轻量级的架构吸引了众多开发者的注意。与React和Vue等传统框架不同,Svelte通过编译时优化实现高效的UI更新,不依赖于虚拟DOM。然而,尽管Svelte的这种方法具有明显的性能优势,React和Vue仍然没有采用类似的编译方式......
  • linux 系统用户态与内核态概念
    内核态(KernelMode)和用户态(UserMode)是现代操作系统中两种不同的CPU运行模式,用来保护系统的稳定性和安全性。它们的主要区别在于对硬件资源的访问权限和系统调用的执行上下文。以下是对内核态和用户态的详细解释:1.内核态(KernelMode)定义:内核态是操作系统内核所运行的模式。在......