Linux内核编译、启动和相关驱动构建_内核驱动编译-程序员宅基地

技术标签: linux开发笔记  嵌入式  

Linux内核编译、启动和相关驱动构建

01

修改与编译内核

前面小哥主要是跟大家讲解了uboot的烧录、使用等等,而对于嵌入式Linux环境而言其实主要是分为三大块 : uboot,Linux Kernel(内核),文件系统,当然高版本的内核存在设备树文件等等,不过感觉还不足以认为是一大块,只能说是驱动的一部分。

那么本文就主要是通过uboot把Linux系统运行起来,而挂载根文件系统并进入终端命令行估计得到下一篇文章了。

如果大家手上有已经移植或制作OK的Linux内核image和文件系统,只需要将他们烧录到板子上的对应存储位置上,然后设置uboot中的一些启动参数即可完成整个Linux系统的启动。

然而每块开发板的外设总会存在或多或少的差异,这样就需要开发人员修改相应的与硬件交互的代码(Linux驱动),或者调整各部分在内存分布的大小与地址等,以适应新的硬件平台,这个过程就叫做移植。

看起来移植很高大上,相对Linux内核这么庞大的代码而言还是小部分,毕竟Linux系统在开发过程中都会考虑与硬件相关部分进行的分离,并且大部分开发板都会参考官方发布的单板来进行布局。

好了,那么小哥就大致讲解一下这个过程。

02

移植与烧录内核

这里使用的是百问网科技超级老的jz2440开发板,他们提供了对应内核版本的适配其开发板的移植补丁,也就是说在Linux-3.4.2原始的内核源码上通过提供的补丁包自动化的进行代码的修改以适应当前开发板,从单片机的角度看来就是修改一些引脚,配置驱动等等。

然而小哥手头板子的NandFlash上存在坏块,uboot,内核、文件系统等都会烧录到NandFlash上,你可以认为就是单片机的Flash,不过单片机的Flash大部分为NorFlash,而由于存在坏块所以对相关的分区进行调整,否则坏块会导致相应的烧录文件不完整而启动失败。

由于后面打算移植QT,而之前拿到的补丁包没有移植好触摸驱动和网卡驱动,即使打了之前拿到的补丁还需要继续进行相关代码上的移植,那慢慢来,先把一些适配的补丁打上:

1tar jxvf linux-3.4.2.tar.bz22cd linux-3.4.2/3patch -p1 <../linux-3.4.2_100ask.patch

Linux-3.4.2_100ask.patch就是百问网提供的补丁包,所谓的补丁包不是什么高级东西,就是通过patch命令根据.patch文件的修改描述,直接添加和修改内核中文件的内容,与我们手动修改本质上是一样的。

不过它把所有的差异都整理成了一个文件,实现了一种一键修改源文件工程的目的,因为内核源码官方都可以获取,而我们只需要一个补丁包就可以通过打补丁把官方源码改成适配自己单板的源码,美滋滋~

03

内核分区修改

前面uboot也存在这样的一个默认分区表kernel部分分了36M,同样内核中的默认分区表中的内核区域也分配了36M。

很多人该问了为什么有两个默认的分区表?

前面小哥讲解了存储地址与运行地址,Linux内核中的相关操作都是基于Linux内核中的分区表,比如uboot向Linux内核的传参中:

就是告诉内核加载文件系统需要在MTD的第三个区分进行加载,那么uboot在进行文件系统烧录的时候就需要把烧录文件放到第三个分区地址区域,且与内核中的分区地址一致,不然Linux内核挂载文件失败。

其实对于uboot中的分区,仅仅只是为了部署Linux环境而设置的,一旦启动内核了uboot的生命周期就结束了,比如之前我们在uboot中使用nand write 源地址 目的地址 长度,我们也可以直接简化为对对应分区的操作:nand write 0x30000000 kernel。从上图中uboot的环境变量bootcmd中使用的kernel,也是类似的使用方法。

那为什么要把Linux内核分区设置36M呢?

其实我当前编译的Linux内核映像也才几M的大小,主要是Linux内核中这种分区方式是连续的,前一个区的结束地址是后一个分区的起始地址,然而经过小哥测试,刚好文件系统分区前面一部分NandFlash存在坏块,这样会导致文件系统不完整,后期挂载会失败,所以这样通过加载内核分区以使得文件系统分区地址后移的方式来规避掉这些坏块,同时对于内核部分由于其烧录文件不大,有效文件不会烧录到坏块部分,算是一个捷径。

03

网卡驱动修改

uboot虽然可以进行TFTP网络服务,但是并不意味着Linux内核也可以正常使用,他们两个驱动是分开的,一旦uboot成功启动内核以后uboot的生命周期就结束了。Linux内核也必须拥有正确的网卡驱动才能够使用相应的网络服务,其实这跟我们windows系统是一样的,当我们电脑没有相应的驱动,相应的硬件也是无法使用的,比如最好用的网络文件系统NFS。

由于我们使用的是dm9000网卡,且mini2440单板已经得到很好的支持,所以我们参考直接移植过来即可,主要是填充相应的平台设备结构体以描述dm9000网卡资源并注册与驱动匹配。

首先要包含dm9000网卡的头文件,以便使用到其头文件中的宏定义或者数据,然后使用resource结构体描述dm9000网卡的一些资源,包括IO资源和中断资源,并且使用平台设备platformdevice来描述dm9000网卡,以便后续总线上device与driver匹配在,这样也就实现了设备与驱动的分离。

最后把平台设备作为smdk2440众多设备初始化中的一员加入到initdata中,以便系统启动的时候便加载设备和匹配驱动。

有了以上移植,基本上单板的网卡驱动就搞定了,相应的网络相关的服务就可以使用了,不像单片机那样你还要直接移植相应的网络协议栈等等,一旦搞定了驱动,基本上跟windows系统上面开发应用程序大同小异~

04

LCD驱动程序修改

对于LCD的支持其实与前面网卡驱动修改其实是类似的,还是采用Linux设备与驱动分开的思想,基本上驱动部分不用太多修改,仅仅只需要把驱动部分根据Linux提供的框架进行相应的描述填充即可,说得直白一点就是填充再赋值结构体,你可以认为这些都是固定的套路吧~

这里小哥使用的是4.3寸的屏幕,所以进行如下填充与配置:

同样因为2440是自带LCD控制器的,唯一要做的就是把LCD控制这块以及LCD屏幕的属性描述清楚,如上面各个结构体设置所选择LCD的相关属性,比如尺寸,刷新时序等等,最后把整个结构体填充好并注册。

同时记得确认一下menconfig里面是否已经选择了LCD_FB,并选择编译到Linux内核,执行命令:

1make menuconfig CROSS_COMPILE=/home/book/WorkSpace/Qt/src/arm-linux-gcc-4.4.3/opt/FriendlyARM/toolschain/4.4.3/bin/arm-linux- ARCH=arm -j8

1Device Drivers ---> 2 Graphics support ---> 3 Support for frame buffer devices ---> 4 S3C2410 LCD framebuffer support

配置好以后,记得save到对应的.config即可,这样编译前的配置才能够生效。

05

触摸驱动编译与移植

玩单片机的小伙伴都知道电阻触摸屏,就是通过获得屏幕横纵的AD采样值最终来定位屏幕上的位置,而S3C2440也是存在触摸屏的外设接口的,我们通过配置触摸屏外设接口,即可驱动触摸屏获得相应的ADC值最终定位到屏幕上所点击的位置。

在Linux中对于鼠标、触摸等等都属于输入设备,所以这类驱动都可以归为输入子系统input,那么我们只需要注册一个输入子系统即完成了触摸屏驱动。

触摸驱动程序主要分为这样几步,首先获得一个输入设备结构体,然后根据触摸的特性进行相关的事件的配置,因为输入系统都是以事件的方式上报给系统,不同的事件当然配置也就不同,配置好了以后就把输入设备结构体注册到系统,以便设备识别。

而当所配置的事件一旦条件触发,就会把触发信号和数据通过input_report上报给系统,供系统使用,所以单片机你想做得通用化,也可以直接这么玩,不过考虑到单片机的简洁,还是慎重考虑~

虽然我们可以直接把该驱动程序编译成.ko驱动程序,可是这样需要每次内核启动完成以后就需要重新加载驱动,有点麻烦,所以考虑把它编译到Linux内核中。

要把驱动程序添加到内核需要做三件事:

1)添加源码到相应目录;

2)在相应的Kconfig文件中增加编译选项;

3)在makefile中增加相应的编译项。

前面我们大致编写了源码并且放到了相应的目录,这里就只需要完成后面的两项,这两项可能相应的语法规则刚开始并不是很熟,不过可以查阅相应的知识补充,也可以直接照着其他touch驱动类似编写即可。

比如s3c2410的Kconfig如下编写:

于是我们可以模仿着把S3C2440类似的添加到后面:

第二步完成,接下来在当前目录的Makefile添加编译项目:

照着S3C2410的来即可。

虽然我们完成上面的三步,但只是完成了能够提供选择的是否编译进内核的驱动选项,在menuconfig菜单中你可以看到,而到底最终是否编译到内核,还需要在menconfig菜单中进行配置选择并保存到config中。

1Device Drivers ---> 2 Input device support ---> 3 Touchscreens --->

至此,触摸的驱动就编写并添加到了内核中。

06

内核的编译与烧录

一切准备就绪,那就是编译内核了,编译内核的目的就是为了获得Linux kernel映像文件,最终烧录到板子上的内容。

如下是我使用的编译命令,由于没有把相应的路径放到环境变量,所以这里就制定了编译器路径,比较长。

1make uImage CROSS_COMPILE=/home/book/WorkSpace/Qt/src/arm-linux-gcc-4.4.3/opt/FriendlyARM/toolschain/4.4.3/bin/arm-linux- ARCH=arm -j8

如果编译过程中遇到什么不理解的error,基本上都是根据所报错误的提示,进行网络查找,一般都可以得到解决,因为大家都遇到过~

最后顺利编译内核成功,如下是编译结果:

以上的输出信息,我们也可以了解到想要的uImage所在路径,以及文件的大小,类型和入口地址等。

我们借助uboot直接通过TFTP服务把uImage先下载到SDRAM中,然后在使用NandFlash命令烧录到Flash中对应的分区即可。

其实烧录过程在往期的uboot中已经说得很详细了,这里主要提两点:

1)由于uboot是一个单任务的裸机程序,所以连接好网线以后,你的电脑网络状态还是没有连接的,所以需要uboot主动发起网络,电脑端就会有网络链接状态显示了。

2)在进行网络通信过程中,要记得关掉电脑主机的防火墙,以便链接失败。

我们使用TFTP服务,需要设置好服务器IP,也就是我们的电脑主机IP地址,然后通过TFTP命令获得相应的内核文件,实验结果如下:

这样我们就把uimage下载到了SDRAM的0x30000000的位置,接下来我们需要把他烧录到对应的NandFlash的Kernel分区上,使用如下命令:

1nand erase.part kernel2nand write 0x30000000 kernel

重新启动开发板,即可看到成功启动了内核:

但是最终由于我们还没有为Linux系统构建文件系统,系统启动还需要一些必备的启动文件和工具,最终会报错。

不过我们今天的目标达到,Linux内核得到了启动,并且移植好了我们想要的一些驱动。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xuerongdeng/article/details/124106591

智能推荐

级联样式表_级联样式表| 第三部分-程序员宅基地

文章浏览阅读173次。级联样式表 CSS-难以成熟 (CSS — Difficult to maturation)Unlike software, the CSS specifications are developed by successive versions, which would allow a browser to refer to a particular version. CSS was devel..._级联样式表是哪年产生的

sql server学习笔记——批处理语句、存储过程_sql的批处理-程序员宅基地

文章浏览阅读1.7k次。目录批处理语句1、批处理语句简介示例一:示例二:存储过程一、什么是存储过程1、存储过程的简介2、存储过程包含的内容3、存储过程的优点4、存储过程的分类系统存储过程:用户定义存储过程5、常用的系统储存过程(1)一般常用的存储过程(2)xp_cmdshell二、创建存储过程1、定义存储过程的语法2、不带参数的存储过程3、带参数..._sql的批处理

css代码的定位及浮动

上次,我们解除了css的内外边距、鼠标悬停及其练习。现在我们学习css元素练习和定位。

一种简单的蒙特卡洛树搜索并行化方法-程序员宅基地

文章浏览阅读2.2k次,点赞4次,收藏6次。本文提出了 WU-UCT, 一种新颖的并行 MCTS 算法, 通过监控未观察样本的数量来解决并行化过程中统计数据过时的问题. 基于新设计的统计数据, 它有正确地修正了UCT节点选择策略, 实现了有效的探索和利用的权衡. _树搜索并行化

python多页爬取page_python爬虫实现爬取同一个网站的多页数据的实例讲解-程序员宅基地

文章浏览阅读3.2k次。对于一个网站的图片、文字音视频等,如果我们一个个的下载,不仅浪费时间,而且很容易出错。Python爬虫帮助我们获取需要的数据,这个数据是可以快速批量的获取。本文小编带领大家通过python爬虫获取获取总页数并更改url的方法,实现爬取同一个网站的多页数据。一、爬虫的目的从网上获取对你有需要的数据二、爬虫过程1、获取url(网址)。2、发出请求,获得响应。3、提取数据。4、保存数据。三、爬虫功能可以..._python 爬虫 get_page_size

《从0到1学习Flink》—— Flink 读取 Kafka 数据批量写入到 MySQL_flink+kafka统计数据后插入mysql-程序员宅基地

文章浏览阅读2.1k次。本文原创地址是: http://www.54tianzhisheng.cn/2019/01/15/Flink-MySQL-sink/ , 未经允许禁止转载。前言之前其实在 《从0到1学习Flink》—— 如何自定义 Data Sink ? 文章中其实已经写了点将数据写入到 MySQL,但是一些配置化的东西当时是写死的,不能够通用,最近知识星球里有朋友叫我: 写个从 kafka 中读取数据,..._flink+kafka统计数据后插入mysql

随便推点

还在用PPT做组织架构图?公司都在用的架构图软件是什么?_书本里印刷的结构图是用什么软件做的-程序员宅基地

文章浏览阅读3.1k次。还在用PPT、Word和Excel画企业组织结构图吗?对于人力资源的同事来说,画组织结构图是一键非常头疼的事情,尤其是对于一些大公司和人员变动较大的公司来说,需要经常更换组织结构图,每次变动都要耗费大量的时间和精力去重新绘图。其实绘制织结构图很简单,之所以难是因为没有找对工具和方法!今天小编就教你如何用亿图图示轻松绘制一个既美观又专业的组织结构图!下图是一个简单的组织结构图例子,小编就以此为例,详细讲解一下好看清晰、实用的公司组织结构图是怎么画出来的。1、新建组织结构图2、创建组织结构_书本里印刷的结构图是用什么软件做的

ESP32-C3 BLE5.0 扩展蓝牙名称长度的流程_蓝牙广播名称过长-程序员宅基地

文章浏览阅读1.8k次,点赞4次,收藏5次。BLE5.0 扩展蓝牙名称长度_蓝牙广播名称过长

centos8安装NVIDIA显卡驱动,docker模式运行机器学习_centos8安装显卡驱动-程序员宅基地

文章浏览阅读3.5k次。centos8安装NVIDIA显卡驱动,docker模式运行机器学习_centos8安装显卡驱动

利用优先级拥抱需求变更_需求优先级反复变化-程序员宅基地

文章浏览阅读2.4k次。需求变更这件事,每个开发人员都遇到过,每个产品经理也都遇到过。 以前,我们会追求需求不变更,但无论是产品型团队还是项目型团队,需求不变更都是天方夜谈,不可能实现的。即使把需求变更的成本提得很高,流程搞得很复杂,又要填变更单,又要几级经理审批,又要需求评审,依然无法避免。 于是,团队的目标变成了少变更,希望尽量少的变更既能满足业务的需要,又能减少开发团队的反感。但‘少’是个相对的概念_需求优先级反复变化

素数筛法_筛法求素数-程序员宅基地

文章浏览阅读2.3k次。一,素数筛法如果需要用到素数表,要么硬编码,要么自己求出前若干项素数。硬编码适合小表,大表只能自己求,而最常见的就是筛法。_筛法求素数

【深度长文】细思极恐的YouTube可跳过广告-程序员宅基地

文章浏览阅读1.8k次。【预警】:Youtube的可跳过广告尽管极其精妙(看完你就知道了),但其实并没有到细思极恐的程度;同时本文也并非深度长文,长是比较长,深不深度就另说了!作为一个广告PM,这种标题党行为都是为了优化点击率。开篇就明确文章属标题党,如今像我这样的良心作者已经不多了,快猛戳关注啊!有一些互联网产品:你认为它很简单、甚至很愚蠢,然而实际上它的设计却无比精妙、细思极恐,YouTube的5秒可跳过的贴片广

推荐文章

热门文章

相关标签