写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

本博客全网唯一合法URL:https://www.cnblogs.com/acm-icpcer/p/8029656.html

最近学院里的nfc老师要我们做个设备驱动,之前从没接手过这个东西,加上老师给的材料错误也是一大堆,搞了差不多一个星期才搞出来。特此写一个博客,以免后来人和我一样跳坑。

总体考虑

要去写设备驱动程序,说白了就三大步骤:下载内核源码构建内核源码树(也就是下载你的目的内核源码包并解压就行了)、编译内核(这样才能让操作系统感知自己写的驱动程序)、写代码(编写内核程序并编译测试)。这三步哪一步都很艰难。

我是在自己笔记本上用虚拟机VMware装的ubuntu操作系统,相比于装双系统有一大缺点和一大优点,优点是将编译好的新内核装入操作系统时不用担心系统崩溃,缺点是装虚拟机的时候没考虑周全,搞得虚拟机的硬盘太小了,估计容量不够用。

那么综合考虑之后,对于我来说是四大步骤:1、给虚拟机扩容;2下载内核源码构建内核源码树;3、编译内核;4、写代码。

下面来一一介绍:

1、虚拟机扩容

 

(1)虚拟机逻辑扩盘。仅仅在这一步扩盘是完全不够的!还要在虚拟机内部设置挂载,不然的话虚拟机无法感知到你扩展的硬盘。这相当于你给一台实际的台式电脑加了一块新硬盘后,还要在操作系统内进行设置。我在这里是扩成80GB。

(2)在终端使用命令

sudo apt-get install Gparted

下载Gparted部件。

(3)打开Gparted:

(4)打开Gparted应用,你可以看到已分配分区状况和新增未分配的分区 :

(5)然后依次删除/dev/sda5和/dev/sda2,删除后,就会剩下/dev/sda1(14GB)和未分配的(15GB),不然的话你怎么都无法将unallocated部分挂载。

(6)接下来重新调整/dev/sda1的大小,我这里调整为75529MiB(73.76GB),然后剩下6.24GB作为linux_swap,重新将未分配的6.24GB格式化,先new出一个extended的分区,然后再在这个extended的分区里new一个逻辑分区,并且file system选择为linux-swap,最后选择绿色的钩钩,完成保存。最后执行完后,如下图所示:

(7)这样我就把虚拟机的硬盘扩成了80GB,编译内核源码绝对是绰绰有余的了。

(注:本小节参考了博客:http://blog.csdn.net/Timsley/article/details/50742755

2、构建内核源码树

(1)我的虚拟机的操作系统是ubuntu16.04。我是在这里下载的源码包:https://www.kernel.org/pub/linux/kernel/v4.x/,我下载的源码包是linux-4.10.14.tar.xz

附:大家千万不要在非www.kernel.org开头的网站上随意下载内核源码!

(2)下载完之后解压即可:

3、编译内核

(1)安装基本的工具软件。

逐次在终端执行以下四条命令:

sudo apt-get install libncurses5-dev libssl-dev 

sudo apt-get install build-essential openssl 

sudo apt-get install zlibc minizip 

sudo apt-get install libidn11-dev libidn11

(2)在终端进入你的解压的内核源码的目录,比如我内核源码解压后在home/expr/expr4/linux-4.10.14,那么进入终端后就是:

(3)依次执行以下三条命令:

sudo make mrproper 

sudo make clean 

sudo make menuconfig

其中mrproper为清除编译过程中产生的所有中间文件,clean为清除上一次产生的编译中间文件,在menuconfig中出现选择的图形化界面后,直接按右方向键选择到exit退出,退出提示中选择保存,实现内核的默认配置

(4)执行命令:

sudo make –j8

因为我的笔记本cpu是i7四核八线程,所以我直接用8个线程并行编译,这样编译速度就是普通的make命令的8倍。最近双一流建设学校发了财换了一大批新电脑,所以在我学校的高性能计算实验室编译内核,因为处理器是新买的intel  core  i7  6700k,8线程编译的话20分钟就搞定了,普通笔记本应该要1~2小时。

下面放一波编译的时候截的图:

正在编译内核

编译的时候监测笔记本状态,怕内存泄漏

(5)依次执行命令:

sudo make modules_install        //安装内核模块

sudo make install      //安装内核

下面放一波编译的时候截的图:

正在执行sudo make modules_install

正在执行sudo make modules_install

正在执行sudo make install

新内核成功嵌入操作系统

(6)重新启动系统,如果是虚拟机的话记得重启进入BIOS界面之前一定要点击鼠标进入虚拟机的界面实现键盘捕获。在重启开机界面按住shift键不放手,选择高级选项,进入内核选择加载界面,选择自己编译的内核的正常模式:

进入内核选择模式,选择自己编译的内核:

(7)至此,工作完成了50%。随着操作系统的启动,我新编译的内核也正式诞生了!

(注:本小节参考了博客:http://blog.csdn.net/Xiaobai__Lee/article/details/72048829

4、写自己的设备驱动程序

(1)写在前面:

在编程的时候,不要轻易复制任何网站的代码,99.99%都是跑不通的。Makefile文件尤其不要随便在网上下载,因为这个东西对格式要求非常高,新手随便在网上下的Makefile文件也是99.99%都是跑不通。要跑通,有两个关键:1、认真分析每一条源代码;2、有问题,多去搜一下看看。

(2)我在ubuntu下编写的代码如下:

(3)要在内核态下编译我们写好的设备驱动程序源码,必须使用Makefile文件。

Makefile文件内容截图,每个关键字都出现彩色的时候说明基本上没写错

(4)在终端下进入设备驱动程序源码所在的文件夹,例如,我的源码放在home/expr/expr4/expr4/code/,那么就是这样:

(5)输入make命令,之后在文件夹下直接生成.ko文件:

(6)继续在终端下输入命令:sudo insmod globalmem.ko将刚刚生成的globalmem.ko文件加载进入内核。

(7)用命令lsmod查看是否加载成功,如果成功就是这样:

可以看到第一个module就是我刚刚生成的globalmem。

(8)到这里工作完成了85%。可以先不急着去写测试程序,可以先用原语测试一下驱动,因为我的这个驱动是处理字符的驱动程序,所以我是这样测试的:

也就是进入root模式后用原语将字符串“tz”送入驱动,驱动就会输出“tz”。

(9)现在就可以踏踏实实地去写测试程序了:

(10)编译这个C程序,并运行:

测试程序运行正常,表明设备驱动运行正常。

至此,我的教程就结束了。有疑问的朋友可以直接在评论区留言,非常希望和各位朋友一起讨论!

TZ@华中农业大学信息学院高性能计算实验室

2017/12/12夜

最全最详细:ubuntu16.04下linux内核编译以及设备驱动程序的编写(针对新手而写)的更多相关文章

  1. 最全最详细:ubuntu16.04下内核编译以及设备驱动程序的编写(针对新手而写)

    写在前面:本博客为本人原创,转载请注明出处!同时,本博客严禁任何下载站随意抓取!!! 本博客唯一合法URL: 总体考虑 要去写设备驱动程序,说白了就三大步骤:下载内核源码构建内核源码树(也就是下载你的 ...

  2. 深入理解Linux内核-块设备驱动程序

    扇区: 1.硬盘控制器将磁盘看成一大组扇区2.扇区就是一组相邻字节3.扇区按照惯例大小设置位512字节4.存放在块设备中的数据是通过它们在磁盘上的位置来标识,即首个扇区的下标和扇区的数目.5.扇区是硬 ...

  3. 使用ubuntu16.04配置linux内核和busybox出现错误的解决方法总结

    也许很多人都知道,ARM裸机1期加强版课程用的是ubuntu 16.04,当用这个ubuntu编译内核和制作文件系统的时候会出现一些问题,售后团队用了一天时间找到了如下解决方法.   更多干货关注威信 ...

  4. Ubuntu16.04下的modules模块编译加载

    一.首先编写对应的驱动程序的相关内容:(最简单的hello.c程序) #include<linux/init.h> #include<linux/module.h> MODUL ...

  5. Ubuntu16.04下caffe CPU版的详细安装步骤

    一.caffe简介 Caffe,是一个兼具表达性.速度和思维模块化的深度学习框架. 由伯克利人工智能研究小组和伯克利视觉和学习中心开发. 虽然其内核是用C++编写的,但Caffe有Python和Mat ...

  6. Linux:Ubuntu16.04下创建Wifi热点

    Linux:Ubuntu16.04下创建Wifi热点 说明: 1.Ubuntu16.04里面可以直接创建热点,而不用像以前的版本,还要其他辅助工具. 2.本篇文章转载自编程人生 具体步骤如下: 1.  ...

  7. Linux:Ubuntu16.04下创建Wifi热点

    Linux:Ubuntu16.04下创建Wifi热点说明 1.Ubuntu16.04里面可以直接创建热点,而不用像以前的版本,还要其他辅助工具. 2.本篇文章参考自编程人生 具体步骤如下: 1. 点击 ...

  8. Linux入门(13)——Ubuntu16.04下将图片和pdf互转

    Ubuntu16.04下将图片和pdf互转 将图片转为PDF: convert 图片 PDF convert pic.jpg pic.pdf 将PDF转为图片: convert PDF 图片 conv ...

  9. Linux入门(16)——Ubuntu16.04下配置sublime text 3使用markdown

    sublime text 3安装两个插件: MarkDown Editing OmniMarkupPreviewer 有的人使用 MarkDown Editing markdownpreviewer ...

随机推荐

  1. Swift 4迁移总结:喜忧参半,新的起点

    Swift 4迁移总结:喜忧参半,新的起点 每日一篇优秀博文 这次Swift 3 到 4 的迁移代码要改动的地方比较少,花了一个下午的时间就完成了迁移.Swift 把原来 4.0 的目标从 ABI 稳 ...

  2. JAVA(一)JAVA基础/面向对象基础/高级面向对象

    成鹏致远 | lcw.cnblog.com |2014-01-23 JAVA基础 1.开发环境搭建 JAVA程序的执行流程 JAVA命令->要使用一个*.class文件(类文件)->通过c ...

  3. 【emWin】例程三十一:窗口对象——Multipage

    简介: ULTIPAGE 类似于笔记本中的分隔卡或文件柜中的标签.通过使用MULTIPAGE 小工具,应用程序可为窗口或对话框的相同区域定义多个页面.每个页面包含特定 类型的信息或用户选择相应页面时应 ...

  4. 删除最少字符生成Palindrome

    看到一个哥们G家电面试题,求删除最少字符生成Palindrome.大神们都在讨论dp,我完全想不到. 放一个没优化的DFS. 乐神说是O(n3)复杂度, 有机会的话要减少使用substring,并且要 ...

  5. Openlayers离线载入天地图

    概述: 经过一个春节的休整,今天最终開始了! 任何时候.都不要忘记学习.学习是一辈子的事情!今天,我来说说怎样实现天地图的离线以及Openlayers载入离线数据实现天地图数据的展示. 实现: 1.获 ...

  6. Java 同时返回多个不同类型的方法

    Java 同时返回多个不同类型的方法 2016年12月02日 16:05:07 FXBStudy 阅读数:10045   前言:虽然对于这种需求不常用,且比较冷门,但是还是有其存在的价值,再次做一下整 ...

  7. 关于指针*前后const代表的意思——记住一个口诀“左内右本”

    记住一个口诀“左内右本”:const出现在*的左边,则说明指针所指向的内容是常量const出现在*的右边,则说明指针本身是常量如果*左右两边都出现const,那么说明指针本事是常量,它所指向的内容也是 ...

  8. Android qualcomm WCNSS_qcom_cfg.ini 参数介绍

    本文介绍WCNSS_qcom_cfg.ini中常用参数的作用. wifi 日志等级 vosTraceEnableBAP=255 vosTraceEnableTL=255 vosTraceEnableW ...

  9. Linux日常使用命令

    pwd  当前目录的路径ls -a 显示隐藏文件ls -l h*  显示所有以h开头的文件ls -d  b*  显示所有以b开头的文件夹ls -l  *.log  所有后缀是.log 的文件dir 显 ...

  10. Ubuntu下Apache虚拟主机+反向代理

    反向代理 就是通过一台代理服务器,让Internet用户可以访问到内部网络上的服务器 下图中192.168.0.4 可以理解带有2个网卡,一个是公网ip,一个是192.168.0.4 代理内外中的2个 ...