一给 发表于 2022-6-24 06:21:22

嵌入式 Linux 内核驱动开发【The first day: 36093万字】

https://img-blog.csdnimg.cn/8635a54c692c4d72856501914d5c842f.gif#pic_center

嵌入式 Linux 内核驱动开发【1】



[*]嵌入式 Linux 内核驱动开发前言
[*]第1章 Linux 内核裁剪和定制
[*]

[*]【1】Linux 内核开发简介
[*]【2】 Linux 源码阅读工具
[*]

[*]【1.2.1】Source Insight
[*]【1.2.2 Eclipse】
[*]【1.2.3】 vim+ctags+cscope
[*]【1.2.4】 LXR
   
[*]【3】Linux 内核源码
[*]

[*]【1.3.1 目录树概览】
[*]【1.3.2】 快速确定主板关联代码
   
[*]【4】 Linux 内核中的 Makefile 文件
[*]

[*]【1.4.1】 顶层 Makefile
[*]【1.4.2】 子目录的 Makefile
   
[*]【5】 Linux 内核中的 Kconfig 文件
[*]

[*]【1.5.1】 Kconfig 基本语法
[*]【1.5.2】 配置项和配置开关
   
[*]【6】 配置和编译 Linux 内核
[*]

[*]【1.6.1】 快速配置内核
[*]【1.6.2】 内核配置详情
[*]【1.6.3】 编译内核
   
[*]【7】 Linux 内核裁剪实例
[*]

[*]【1.7.1】 GPIO 子系统配置
[*]【1.7.2 】LED 子系统配置
[*]【1.7.3】 串口配置
[*]【1.7.4】 USB Host 驱动配置
[*]【1.7.5】 USB Gadget 驱动配置
[*]【1.7.6】 SD/MMC 驱动配置
[*]【1.7.7】 网卡驱动配置
[*]【1.7.8】 NFS Client 配置
[*]【1.7.9】 PPP 拨号配置
[*]【1.7.10】 MTD 配置
[*]【1.7.11】 UBIFS 文件系统配置
[*]【1.7.12】 CAN 驱动配置
   
[*]【8】 EPC-28x 平台内核快速编译


由于篇幅太大,以章分块,按天写
嵌入式 Linux 内核驱动开发前言

   本篇主要讲述嵌入式 Linux 产品开发过程中的内核/驱动开发部分相关内容,包括 Linux 内核裁剪定制、驱动编写和驱动移植等。进行嵌入式 Linux 驱动开发,一些特定外设需要从零开始编写驱动,然而很多外设基本都有可参考驱动,在实际工作中仅需进行移植,本篇特 意给出了 3个驱动移植实例。
本篇一共分 11 章,各章标题和内容概要如下:
    第 1 章 Linux 内核裁剪和定制,首先介绍了几种内核源码查看工具,然后对内核目录树和相关文件进行介绍,接着给出了内核配置详情以及裁剪实例;
 第 2 章 Linux 设备驱动基础,由浅入深的介绍了 Linux驱动编写相关知识点,从内核模块、字符设备驱动到平台设备驱动都有详细讲解,并给出了相应的范例代码;
 第 3 章 LED 子系统和驱动,分析了内核中的 LED 子系统,并给出了相关实现实 例;
 第 4 章 GPIO 驱动,分析了内核中的GPIOLIB子系统,并给出了相关实现实例;
 第 5 章 输入子系统和按键驱动,分析了内核中的输入子系统,并给出了按键驱动 实现范例;
 第 6 章 I2C 总线和外设驱动,分析了内核中的 I2C 子系统,并给出了 I2C 接口 EEPROM 驱动实现范例;
 第 7 章 SPI总线和外设驱动,简要分析了 SPI 总线驱动,并实现了两种典型 SPI 设备驱动;
 第 8 章 UART 和 SC16IS752驱动,简析了 UART 驱动子系统,并对 SC16IS752 的驱动实现进行了详细分析;
 第 9 章 SGTL5000声卡驱动移植,介绍 SGTL5000 在 i.MX283 平台的移植过程;
 第 10 章 AP6181 无线网卡驱动移植,介绍 AP6181 无线网卡在i.MX283平台的移植过程;
 第 11 章 SIM6360-PCIE 模块驱动移植,介绍SIM6360-PCIE 模块驱动移植和 PPP 拨号上网的过程。
本篇的内容涵盖了嵌入式 Linux 产品开发过程中底层开发的大部分工作,给出的实例也都具有很强的参考意义。
第1章 Linux 内核裁剪和定制

【1】Linux 内核开发简介

   这里所说的“Linux 内核开发”仅仅是指嵌入式 Linux 产品开发中内核和驱动相关开发工作,与 Linus所领导的内核开发团队的内核开发有很大不同。 产品开发中对内核进行二次开发,需要开发人员具备如下一些基本技能和背景知识:


[*] 具备操作系统的基本知识,理解操作系统原理,最好了解 ~~Linux 操作系统~~ ;
[*] 内核绝大部分都是 C 语言编写的,~~C 语言~~ 是必备技能;
[*] 内核是用 ~~GNU C 编写的~~ ,尽管符合 ISO C89 标准,但还是使用了一些 GNU 扩展,所以对 GNU C 的一些扩展也必须有所了解;
[*] 对 ~~Linux 内核源码~~ 基本分布有大致了解;
[*] 产品级的内核开发通常还包括一些内核驱动工作,对~~外设工作原理和驱动编写~~ 也必须有一定的了解。
【2】 Linux 源码阅读工具

   俗话说“工欲善其事,必先利其器”,面对几百兆的 Linux 内核代码,要阅读、查看或者搜索其中的代码,大部分初次接触到 Linux 内核代码的开发人员,都有无从下手的感觉。
下面推荐几个源码阅读和索引工具,能为后续内核开发提供一些便利。
【1.2.1】Source Insight

   Source Insight 是 Windows 平台下一款流行度极高的源码阅读和编辑工具。不少 Linux开发人员还是习惯于在 Windows 下进行源码编辑,甚至查看和编辑 Linux 内核源码,依然在 Source Insight 中完成。
注意:蓝色字体的超链接是我改过的为了好看而已
安装 Source Insight 软件后,新建一个工程,取名并指定数据存放位置,如图 1.1 所示。
https://img-blog.csdnimg.cn/d1081e961d8f43f4aadc5e6651c1a622.png
https://img-blog.csdnimg.cn/3e7496658a8e44d5a783eb79d75aaf56.png
然后添加源码。浏览选中 Linux 内核源码文件夹后,点击“Add Tree”按钮,将内核源码树的全部文件添加到工程中,如图 1.3 所示。
https://img-blog.csdnimg.cn/5002e469622b422a84e2ba2ec2781f5d.png
添加完成,即可在 Source Insight 中进行源码阅读和编辑了,如图 1.4 所示。
https://img-blog.csdnimg.cn/0b47ef2a278246098727b07dcd0a5453.png
【1.2.2 Eclipse】

   Eclipse 是一个跨平台 IDE,既能运行于 Windows 平台,也能在 Linux 下运行。不少习惯于 图形界面操作的开发人员,在 Linux 下则习惯于用 Eclipse 来查看和编辑 Linux 源码。 如果仅仅是在 Eclipse 中查看 Linux 内核源码,则可以不必事先安装交叉编译器,否则 则须事先安装好交叉编译器。
创建内核源码工程。点击 FileNewProject,开始创建工程,在工程创建界面选择创建 C 工程,如图 1.5 所示。
https://img-blog.csdnimg.cn/4984c3f0ceec41e098e9c00cafccac02.png
点击 Next,在 C Project 界面的 Project name 栏中填写工程名称,去掉“Use default location”的勾,点击 Browse 将 Location 设置为 Linux 内核源码目录,如图 1.6 所示。如果不在 Eclipse中编译内核,则使用 Linux GCC 即可,否则请使用安装好的 Cross GCC
https://img-blog.csdnimg.cn/e6f3b38a7c0145acbce7822f69cd752c.png
然后点击 Finish,完成 Linux 内核源码导入,在 Eclipse 中即可进行代码阅读和编辑了,如图 1.7 所示。
https://img-blog.csdnimg.cn/db738082d23a4726b991c29bb342f0e6.png
   在 Eclipse 中进行源码跟踪,只需选择函数、变量或者宏定义后按 F3 即可。更多的操作可在 Navigate 中找到。
【1.2.3】 vim+ctags+cscope

   Vi/Vim 是一个文本编辑器,在 Vim 中能高效的实现代码编辑。但 Vim 的功能不仅仅是一个文本编辑器,借助 ctags 和cscope 的配合,Vim 能实现堪比图形 IDE 环境的源码编辑和阅读功能,在某种程度上甚至比图形 IDE 更方便。 Vi/Vim 的安装不再介绍了。如果不是通过远程登录在远程服务器上工作,而是在本地桌面系统操作,还可以用 gvim 启动 Vi 编辑器。
1. Taglist
   Taglist 是 Vim 的一个源码浏览插件,可从http://www.vim.org 网站获得。下载到压缩包后,在本地解压,然后将解压得到目录中的 plugin 目录复制到~/.vim 目录。如果用户主目录 下没有.vim目录,则建立命令mkdir .vim一个这样的目录即可。
2. Ctags
   Ctags 是一个用于产生 tags 文件的软件,可以下载源码进行编译安装,在 Ubuntu 下, 可通过 apt-get 进行安装:
$ sudo apt-get install exuberant-ctags 3. 源码阅读和跟踪
   进入准备查看的源码所在目录,首先生成 tags 文件:
$ ctags -R    执行时间长短取决于源码数量的多少,执行完毕,在当前目录下可看到一个 tags 文件。 源码越多,执行时间越长,产生的 tags文件也越大。
注意:如果修改了源码,代码行号发生了变化,需要重新生成 tags 文件。
   (1)查看函数等定义。用 Vi/Vim 打开一个 C 文件。若想知道某个函数、变量、结构 或者宏定义在什么地方定义,先将光标移动到函数(变量、结构或者宏定义)上,然后按 CTRL+]即可。查看后,按 CTRL+o
可回到原来所在位置。
(2)查看文件函数列表。打开C 文件后,在Vi/Vim的命令状态下输入:TlistToggle(Vi/Vim的命令输入支持补全),在 Vi/Vim 左边就会出现函数列表侧栏,如图 1.8 所示。按 CTRL+ww (2 次> w),可在列表和代码查看区间切换。
https://img-blog.csdnimg.cn/c4be8011791d43e382e3cdfa056500b1.png
如果在本地桌面,用 Gvim 打开 C 文件,使用起来比较接近 IDE 集成环境。用鼠标双击函数即可跳转到函数定义的地方,CTRL+鼠标右键即可回退到原来所在位置。更多实用特性,还需要在实际操作中体验。
【1.2.4】 LXR

   LXR 是 Linux Cross Referencer 的缩写,是一个比较流行的 Linux 源码查看工具,当然也不仅仅局限于查看 Linux 源码。LXR 的下载地址为:http://lxr.sourceforge.net,参考该网站
的安装说明,很容易在本机搭建一个本地 LXR 用于源码查看。
如果不想搭建本地 LXR,可以直接浏览已经搭好的 LXR 网站,推荐两个网站:一个是开源中国网站提供的 Linux 源码在线阅读 http://lxr.oss.org.cn,另一个是http://lxr.free-electrons.com 网站,前者速度较快,但是提供的 Linux 内核版本较少,后者则提供的版本较多。网站提供了源码阅读、关键字搜索和自由文本搜索功能。两者的网页快照分别如图 1.9 和图 1.10 所示。
https://img-blog.csdnimg.cn/e10bb49f18f84de58d4a9c0dba81bd15.png
https://img-blog.csdnimg.cn/2d114c39dfec48349d90af69082f0924.png
【3】Linux 内核源码

【1.3.1 目录树概览】

   解压 Linux 内核源码压缩包,将得到内核源码。内核源码很复杂,包含多级目录,形成 一个庞大的树状结构,通常称为 Linux源码目录树。进入源码所在目录,可以看到目录树顶 层通常包含如下目录和文件:
https://img-blog.csdnimg.cn/2114beb70a244d7a898b2fa659516967.png
各个目录文件的简要说明如表 1.1 所列。
目录内容arch/包含各体系结构特定的代码,如 arm、x86、ia64、mips 等,在每个体系结构目录下通常都有: -boot 内核需要的特定平台代码 -kernel 体系结构特有的代码 -lib 通用函数在特定体系结构的实现 -math-emu 模拟 FPU 的代码,在 ARM 中,使用 mach-xxx 代替 -mm 特定体系结构的内存管理实现 -include 特定体系的头文件block/存放块设备相关代码crypto/存放加密、压缩、CRC 校验等算法相关代码Documentation/存放相关说明文档,很多实用文档,包括驱动编写等drivers/存放 Linux 内核设备驱动程序源码。驱动源码在 Linux 内核源码中站了很大比例,常见外设几乎都有可参考源码,对驱动开发而言,该目录非常重要。该目录包含众多驱动,目录按照设备类别进行分类,如 char、block、input、i2c、spi、pci、usb 等firmware/存放处理器相关的一些特殊固件fs/存放所有文件系统代码,如 fat、ext2、ext3、ext4、ubifs、nfs、sysfs 等include/存放内核所需、与平台无关的头文件,与平台相关的头文件已经被移动到 arch 平台的include 目录,如 ARM 的头文件目录 init/包含内核初始化代码ipc/存放进程间通信代码kernel/包含 Linux 内核管理代码lib/库文件代码实现mm/存放内存管理代码net/存放网络相关代码samples/存放提供的一些内核编程范例,如 kfifo;后者相关用户态编程范例,如 hidraw srcipts/存放一些脚本文件,如 menuconfig 脚本security/存放系统安全性相关代码sound存放声音、声卡相关驱动tools/编译过程中一些主机必要工具usr/cpio 相关实现virt/内核虚拟机 KVMLinux 内核源码数量很庞大,解压后大约好几百兆字节,要能在如此庞大的源码中找到 有效代码,熟悉 Linux 源码目录树的结构是基本要求。每个目录所包含的代码量差异也很大, 下面是从 http://www.kernel.org 下载的一份源码解压后的统计结果,其中drivers目录几乎占了源 码总量的一半,arch 目录也差不多有 1/4:
https://img-blog.csdnimg.cn/82b0c8e6d96e4d61820dc0dbe12505a5.png
【1.3.2】 快速确定主板关联代码

   拿到一份源码和一块评估板,如何快速找到与这块板相关的源码,是很多研发人员都曾遇到过的问题。如果对内核源码结构有大概了解,要完成这些事情也不难,通常可按照基础代码、驱动代码和其它代码等方面来梳理。
1. 基础代码
   Linux
移植通常分为体系结构级别移植、处理器级别移植和板级移植,各级别移植难易程度差异很大,工作量和调试方式也各不相同。一般的产品开发人员所进行的内核移植,通常都是板级移植,这是几个级别中最简单的。
从代码层面来看,通常把能让一个主板最小系统能运行的代码称为基础代码,这部分代码通常包含体系结构移植代码、处理器核心代码以及板级支持包的部分代码。理清了这部分代码,对于了解和掌握整个主板相关代码具有重要意义。
确定主板名称和默认配置文件。
   例如,对于 EPC-28x 工控板,其对应的默认内核配置 文件为”表示,如图 1.11 所示。
https://img-blog.csdnimg.cn/a8f1e9af7fbc4206953c25978582d244.png
子菜单的菜单项则由config来定义,随后的“bool”、“default”、“help”等都是该菜单项的属性:
# Intel/Marvell Dev Platforms
obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
obj-$(CONFIG_MACH_ZYLONITE300) += zylonite.o zylonite_pxa300.o    这两行语句定义了一个bool选项,在.config中的配置变量名称为CONFIG_DEVKMEM,选项提示信息为“/dev/kmem virtual device support”,在内核配置界面的实际表现为:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION =3    由于设置其默认属性 default 为 y,所以该选项默认选中。
help 引出帮助信息,在内核配置界面,选择选项后,通过可以查看帮助信息。
2. 属性
   类型定义:每个菜单项都必须定义类型,可选类型有:bool、tristate、string、hex 和 int, 各类型描述如表 1.3所列。
https://img-blog.csdnimg.cn/ab2b2ea0c70a425797c78046caf45467.png
定义选项的类型后面可以加菜单信息,用引号(“”)给出,留空则不加提示信息。
   对于布尔型选项,在配置界面用[ ]表示:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION =3    
[*]表示选中,对应 CONFIG_XXX=y,[ ]则表示未选中。
对于三态选项,在配置界面用< >表示:
ARCH ?= $(SUBARCH)     表示选中,对应 CONFIG_XXXx=y,表示编译为模块,对应 CONFIG_XXX=m, < >表示未选中。 子菜单也可同时设置类型,如下列代码在定义 PWM 菜单的同时定义了菜单属性为三态:
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh.*/sh/ ) 在配置界面表现为:
$make ARCH=arm    说明:子菜单的配置值会影响其子选项的可能值。例如三态子菜单配置为,则其三 态子选项依旧可有 3种可能值,即可配置为、或者不选中;而三态子菜单配置为, 则其子选项只有和不选中两种状态可用。
默认值:有写选项可以设置默认值,无论是哪种类型,都可以通过 default 设置其默认值,例如:
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
……
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) –E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump    选中:前面这个示例的 select,表示了一种选中关系,即选中某个选项后,会自动选中 某个或者某些选项。
前面这个示例表明,选中 ARM后,会自动选中HAVE_AOUT。 依赖关系:如果一个选项能否生效与否与其它选项的设置有关,则必须通过 depends on 来声明这种依赖关系。例如,只有使能了 SMP 才能设置 CPU 个数变量 NR_CPUS,在Kconfig中则写成:
$ make ARCH=arm CROSS_COMPILE= arm-linux-gnueabihf-    帮助:通过 help 关键字引入帮助,帮助的正文必须另起一行。
菜单选项属性的每个关键字,必须用 TAB 键与行首隔开,不能用等数的空格替代。
3. 目录层次迭代
   通过source可以直接引用下级目录的 Kconfig 文件,形成新的菜单项或者子菜单,这样方便每个目录独立管理各自的配置内容。“source "drivers/tty/Kconfig"”就是直接引用 文件,形成更多菜单(项)。
【1.5.2】 配置项和配置开关

   通过config 定义的菜单配置项,在内核配置后会产生一个以“CONFIG_”开头的配置开关变量,该开关变量可在·Makefile 中或者源代码中使用。
例如:“config BAR”将会产生一个开关变量 CONFIG_BAR,在 Makefile 中可以这么使用:
CROSS_COMPILE = arm-linux-gnueabihf-    在源代码中可用这个开关变量来进行一些条件处理,例如:
CROSS_COMPILE =/home/ctools/linux-devkit/bin/arm-linux-gnueabihf-    如果定义的 BAR 是三态变量,则还可以根据需要这样使用:
obj-y += usb-host.o # 默认编译 usb-host.c 文件
obj-y += gpio/ # 默认编译 gpio 目录 【6】 配置和编译 Linux 内核

   对内核进行正确配置后,才能进行编译。配置不当的内核,很有可能编译出错,或者不能正确运行。
【1.6.1】 快速配置内核

   进入 Linux 内核源码数顶层目录,输入make menuconfig命令,可进入如图 1.12 所示的 基于 Ncurses 的 Linux 内核配置主界面(注意:主机须安装 ncurses 相关库才能正确运行该 命令并出现配置界面)。如果没有在 Makefile 中指定 ARCH,则须在命令行中指定:
obj-$(CONFIG_WDT) += wdt.o # wdt.c 编译控制
obj-$(CONFIG_PCI) += pci/ # pci 目录编译控制 https://img-blog.csdnimg.cn/9daf0f760e0c4c229b3cfbfe3b899602.png
https://img-blog.csdnimg.cn/fdf1405e24074a8e9e5e5d279d90e3c9.png
   配置完毕,将光标移动到配置界面末尾,选中“Save an Alternate Configuration File”后回车,保存当前内核配置,默认配置文件名为.config,如图 1.13 所示。
https://img-blog.csdnimg.cn/9ac341e0156a4e1c8c20beea95333133.png
保存完毕,选择退出内核配置界面,回到终端命令行。
当然,也可以将配置文件命名为其它文件名,如 config-bak 等,但该配置不会被 Makefile
文件使用,Makefile 默认使用文件名为.config 的配置文件,所以重新命名配置文件通常在保留或者备份内核配置信息时使用。 也可以不用“Save an Alternate Configuration File”操作,连按 ESC 或选择退出内核配置界面,将会出现如图 1.14 所示的保存配置提示信息,选择后回车,内核配置将会被保存为.config 文件。
https://img-blog.csdnimg.cn/cc480a5d4b154bb0815c7d3337007135.png
备份内核配置,在命令行下将.config 文件复制为其它文件名来得更简单快捷:
menu "Character devices"

source "drivers/tty/Kconfig"

config DEVKMEM
bool "/dev/kmem virtual device support"
default y
help
Say Y here if you want to support the /dev/kmem device. The
/dev/kmem device is rarely used, but can be used for certain
kind of kernel debugging operations.
When in doubt, say "N".
……
endmenu    装载某个配置文件,可在配置界面选中“Load an Alternate Configuration File”,然后填 入已存在的配置文件名称。也可在命令行下将配置文件复制为.config:
config DEVKMEM
bool "/dev/kmem virtual device support"    在目录下有很多*_defconfig 文件,这些都是内核的预设配置文件,分别对应各种不同的参考板。如果要使用其中的配置文件作为内核编译配置,可用“make xxx_defconfig”命令来完成。对于已经设定好的内核配置,也可以命名为某个文件名,放到 目录下,在以后直接用 make 来调用该配置即可。例如将当前配置命名为 m3352_defconfig 并放到目录下,后续只需执行下列命令即可使用当前配 置:
[*] /dev/kmem virtual device support 【1.6.2】 内核配置详情

Linux 内核配置菜单比较复杂,下面对一些比较重要的配置界面进行介绍,更多的详细配置,建议进行实际操作。另外,由于 Linux 内核版本差异,实际看到的内核配置界面可能与本节的介绍有所差异。
图 1.12 所示的内核配置主界面,实际包含了如表 1.4 所列的各项一级菜单。
https://img-blog.csdnimg.cn/b69244c86c94458683e0b66906aea74f.png
https://img-blog.csdnimg.cn/8d08397a64cf43eb841991a054c58a28.png
https://img-blog.csdnimg.cn/e0ab420609b34a7e836fa8fc33e98abb.png
   一级菜单下的每一项几乎都有复杂的下级子菜单,各自的配置选项也很丰富,每项的意义也各不相同,如果逐一进行描述,将会是一件非常繁琐的事。而实际产品开发中,并不需要完全了解内核的每一个配置项,通常只需要了解其中一些相关项即可。
1. 通用设置
   进入 General setup 是内核通用设置菜单界面,菜单选项众多,通常可以关注表 1.5 所列 选项。
https://img-blog.csdnimg.cn/c42727d9dffc4609b95648a5b2826ddd.png
2. 内核特性
   Kernel Features 是内核特性配置菜单,常用选项介绍如表 1.6 所列。
https://img-blog.csdnimg.cn/bff5052c60084635835e4a1bea7a88f6.png
https://img-blog.csdnimg.cn/f87ef4154ff447d196ba77da6a588a88.png
3. 启动选项
   启动选项一般关心内核启动参数设置即可,可设置默认启动参数和内核参数类型。 默认启动参数通过“Default kernel command string”设置,例如:
[*] /dev/kmem virtual device support    内核参数类型通过 Kernel command line type 来设置,可选值:
<*> Kernel .config support    如果设置为“Always use the default kernel command string”则只能使用默认内核启动参数,通常会设置为“Use bootloader kernel arguments if available”,可接受 Bootloader 传递的参数启动。
4. 网络支持
   网络支持部分,包括了以太网、CAN、红外、蓝牙、无线等各种网络的支持配置选项。 网络选项配置。从 Networking support Networking options,可进入网络选项配置界面, 网络的配置很复杂,常用的一些配置选项和说明如表 1.7 所列。
https://img-blog.csdnimg.cn/20f8984d27e4416786b05ee298c32873.png
https://img-blog.csdnimg.cn/5a450c75b94143e5ab2ad0129ed7d809.png
通常来说,使用Linux的系统都会用到网络,而使用网络又往往离不开 TCP/TP,故建 议在配置中选中 TCP/IP选项,并选中下级全部选项,配置后的 TCP/IP 选项如程序清单 1.2 所示。
   程序清单 1.2 TCP/IP 配置
menuconfig GENERIC_PWM
tristate "PWM Support"
default n
help
Enables PWM device support implemented via a generic
framework. If unsure, say N.    这些配置中,三态选项也可以配置为,在需要的时候再插入模块。
对于 IPv6,现在已经有不少应用需求,建议配置为,并选中配置菜单中的全部选项,在需要的时候再插入模块。
特别说明一下CAN的配置选项。CAN-Bus 相关协议支持以及 CAN 设备驱动配置项都在这里,并没有将 CAN 设备驱动放在 drivers 配置菜单中。CAN-Bus 子系统配置界面如图
1.15 所示。
https://img-blog.csdnimg.cn/a581f48ba84c48b686af92dd53869e1d.png
其中的“CAN Device Drivers”子菜单下可选择具体的 CAN 设备,如图 1.16 所示。具体选择哪个 CAN 设备驱动,与具体的硬件平台相关。
https://img-blog.csdnimg.cn/1395a23d4a0447849c62f563ea6dbabe.png
5. 设备驱动
   Linux 内核支持众多外设,设备驱动程序很多,配置界面也很复杂,有众多配置项,如 表 1.8 所列。
https://img-blog.csdnimg.cn/a6d9ab8c1571431cbeab54dc527e066d.png
https://img-blog.csdnimg.cn/05b73efd85bf4c3983ea478ceb16445b.png
https://img-blog.csdnimg.cn/38f0cad314b6491db90ead2a88f7d478.png
https://img-blog.csdnimg.cn/ac4fe31a4af24e68a12be7d39f168529.png
https://img-blog.csdnimg.cn/fae74ce9ac1e4c9e9e7e19eeea795165.png
6. 文件系统
   进入 File systems,是内核文件系统配置界面,可以看到很多文件系系统配置选项,如 图 1.17 所示。
https://img-blog.csdnimg.cn/eb8f4a9037b74336ae42418f7a140769.png
    一个完整的嵌入式 Linux 系统往往会支持多种文件系统,但绝非“File systems”菜单下的全部。这里仅对当前主流系统比较常用的一些文件系统配置项进行介绍,如表 1.9 所列。
https://img-blog.csdnimg.cn/2825dcdf86304b1ab772b248f4af1b75.png
https://img-blog.csdnimg.cn/06b7a43389de453584418cd136a4b49d.png
https://img-blog.csdnimg.cn/9b18d28efeea4b179f3c4cd5c40652e1.png
【1.6.3】 编译内核

   内核配置完成,输入 make 命令即可开始编译内核。如果没有修改 Makefile 文件并指定 ARCH 和 CROSS_COMPILE参数,则须在命令行中指定:
< > PWM Support --->    目前大多数主机都是多核处理器,为了加快编译进度,可以开启多线程编译,在 make 的时候加上“-jN”即可,N 的值为处理器核心数目的 2倍。例如对于 I7 4 核处理器,可将 N 设置为 8:
< > PWM Support ---> -j8    采用多线程编译的优点是能加快编译进度,缺点是如果内核中有错误,某个编译线程遇到错误终止了编译,而其它编译线程却还在继续,出错线程的错误提示通常会被其它编译线 程的输出信息淹没,不利于排查。对于这种情况,则建议改为单线程编译,直到错误排除。
   如果编译不出错,编译完成,会生成 vmlinux、Image、zImage 等文件,各文件说明如 表 1.10 所列。
https://img-blog.csdnimg.cn/dd1f87ad280f4e02a66895fe52c0ada9.png
1. zImage
   zImage是通常情况下默认的压缩内核,可以直接加载到内存地址并开始执行。它从 文件经过 objcopy 处理得到。在 ARM Linux 下最终生成 zImage 的各个参数记录在文件中。AM3352 内核生成 zImage 的
实际参数为:
config NR_CPUS
int "Maximum number of CPUs (2-32)"
range 2 32
depends on SMP
default "4"    说明 1:路径信息与实际具体编译环境有关。
说明 2:如果在 64 位 ubuntu 下编译 Linux 内核,在编译过程中很有可能出现
“arm-fsl-linux-gnueabi/bin/as: error while loading shared libraries: libz.so.1: cannot open shared object file: No such file or directory”这样的错误,这是因为没有正确安装libz库所致,
可“sudo apt-get install zlib1g:i386”命令安装解决。
2. uImage
   对于 ARM Linux 系统,大多数采用U-Boot引导,很少直接使用 zImage 映像,实际上更多的是 uImage。uImage 是 U-Boot 默认采用的内核映像文件,它是在 zImage 内核映像之前加上了一个长度为 64 字节信息头的映像。这 64 字节信息头包括映像文件的类型、加载位置、生成时间、大小等信息(可参考 U-Boot 源码文件的 image_header_t 数据结构定义)。进入目录,用 ls 命令查看,uImage 文件大小比 zImage 大 64字节:
obj-$(CONFIG_BAR) += file_bar.o    在 U-Boot 下,通过 bootm 命令可以引导 uImage 映像文件启动。
3. mkimage 工具
   从zImage生成uImage需要 用到 mkimage 工具。该工具可在编译 U-Boot 源码后从 tools 目录下获得,复制到系统/usr/bin 目录即可;对于 Ubuntu 系统,还可用 sudo apt-get install u-boot-tools 命令安装得到。进入 mkimage 文件所在目录执行该文件,或者在安装 mkimage 工具后,直接在终端输入 mkimage 命令,可以得到 mkimage 工具的用法:
#if defined (CONFIG_BAR)
实际处理代码
#endif    使用 mkimage 工具根据 zImage 制作 uImage 映像文件的命令如下:
#if defined (CONFIG_BAR) || defined (CONFIG_BAR_MODULE)
实际处理代码
#endif    命令参数中需要指定体系结构、操作系统类型、压缩方式和入口地址等信息,各参数说明如表 1.11 所列。
https://img-blog.csdnimg.cn/7617310f3b004b0e8c79eaabd82463e9.png
    对于EPC-28x处理器,内存起始地址为 0x40000000,从 zImage 生成 uImage 映像文件的命令实际操作范例:
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
-C none -a $(LOADADDR) -e $(STARTADDR) \
-n 'Linux-$(KERNELRELEASE)' -d $< $@    说明:内存地址与处理器相关,在不同处理器上可能有差异。
mkimage 除了可以制作 uImage 映像文件之外,还可以查看一个 uImage 映像文件的文件头信息,用法:
$ cp .config config-bak    例如,用 mkimage 工具查看 EPC-28x 工控主板的 uImage 内核映像,可以得到如下信息:
$ cp config-bak .config    如果只有zImage内核映像文件,需要转换成 uImage 映像文件,则只能通过上述命令来实现。但是如果有内核源码,那生成 uImage 的方法就简单很多。实际上,Linux 内核已经支持直接生成 uImage 格式映像文件,在文件中给出了uImage的生
成规则:
$ make m3352_defconfig 或者
$ make ARCH=arm CROSS_COMPILE= arm-linux-gnueabihf- m3352_defconfig    生成 uImage 的编译命令为 make uImage:
< > PWM Support ---> -j8 uImage    在 ARM Linux 下最终生成uImage的各个参数记录在文件中。对于在 EPC-28x 的 Linux 内核,实际参数为:
( ) Use bootloader kernel arguments if available
( ) Extend bootloader kernel arguments
( ) Always use the default kernel command string 4. 编译内核模块
   如果内核中有配置为的模块或者驱动,需要在编译内核后再通过 make modules 命 令编译这些模块或者驱动:
< > PWM Support ---> modules   编译得到的内核模块文件以“.ko”结尾,这些可以通过insmod命令插入到运行的内核中。
有的模块编译得到单一的“.ko”文件,且不依赖于其它模块,这样的模块可以直接用insmod 命令插入系统而不会出现错误。
有的模块则可能编译后得到多个“.ko”文件,或者依赖于其它模块文件,且各文件插入还有顺序要求,这就是常说的模块依赖。对于这样的情况,用 insmod 命令手工尝试得到依赖关系,然后按顺序插入也是可以的,但不推荐这样做,毕竟很麻烦。
建议编译模块后,再通过 make modules_install 命令安装模块,可将编译得到的全部模块安装到某一目录下,并且还会生成模块的依赖关系文件。默认情况下会将内核模块安装到编译机器的“/”目录下,这一方面需要root权限,另一方面容易与主机文件混淆。建议通过INSTALL_MOD_PATH参数指定模块安装路径:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-    安装后将在安装目录下生成“lib/modules/内核版本/”目录,该目录下通常有下列文件 和目录:
https://img-blog.csdnimg.cn/636efa8251b4479a94c3134e75508319.png
   所有的内核模块都在kernel目录下,modules.dep 是全部模块的依赖关系文件。将“lib/modules/内核版本/”复制到目标系统后根目录后,就可以用 modprobe 命令进行模块安装,而不用手工逐一加载各个模块。该文件内容多少与内核模块多少相关,现在摘取一个实例片段进行说明:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j8    每行开头至冒号(:)之前的表示一个内核模块,冒号之后的表示该模块所依赖的其它模块, 必须先加载后面的模块才能加载该模块文件。冒号后面为空则表示该模块没有依赖关系。 第(1)行表示模块文件 bonding.ko 没有依赖关系,可以直接用 insmod 命令加载到内核中:
cmd_arch/arm/boot/zImage := /home/ctools/i686-arago-linux/usr/bin/arm-linux-gnueabihf-objcopy -O binary
-R .comment -S arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage    用 insmod 加载模块,必须指明文件路径,否则不能加载。用 modprobe 命令加载则无需 带路径:
$ cd arch/arm/boot
$ ls -la Image zImage uImage
-rwxrwxr-x 1 chenxibing chenxibing 6460852 Jul 25 09:24 Image
-rw-rw-r-- 1 chenxibing chenxibing 3135544 Jul 25 09:24 uImage
-rwxrwxr-x 1 chenxibing chenxibing 3135480 Jul 25 09:24 zImage    第(2)和(3)则共同说明了模块文件ftdi_sio.ko依赖于usbserial.ko文件,usbserial.ko 没有依赖文件。用 insmod 命令用法如下:
$ ./mkimage 或者 mkimage
Usage: ./mkimage -l image
-l ==> list image header information
./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type'
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)
-n ==> set image name to 'name'
-d ==> use image data from 'datafile'
-x ==> set XIP (execute in place)
./mkimage [-D dtc_options] -f fit-image.its fit-image
./mkimage -V ==> print version information and exit    用 modprobe 命令就简单了:
$ mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image 1.6.4 运行内核
   得到 uImage 映像文件后,将 uImage 加载到内存地址ep-0x40处,通过 bootm 命令即可 运行内核:
$ mkimage -A arm -O linux -T kernel -C none -a 0x40008000 -e 0x40008000 -n 'Linux-2.6.35' -d
arch/arm/boot/zImage arch/arm/boot/uImage    uImage 启动会打印文件头信息并进行校验和计算,校验通过后开始内核自解压并运行:
$ mkimage -l uImage_file 【7】 Linux 内核裁剪实例

   从零开始配置内核是不明智的,建议在某一个默认配置的基础上进行修改,以达到自己 产品的实际需求。 裁剪和配置内核的基本原则:
$ mkimage -l uImage
Image Name: Linux-2.6.35.3-571-gcca29a0-g191
Created: Tue Nov 17 11:57:47 2015
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2572336 Bytes = 2512.05 kB = 2.45 MB
Load Address: 40008000
Entry Point: 40008000    下面给出一些常见功能的配置裁剪实例,很多功能与所采用的主板硬件相关,与其它不 同主板的内核配置上不一定完全相同,但还是有一些参考意义。
【1.7.1】 GPIO 子系统配置

   Linux 2.6 以上内核引入了子系统, GPIO 子系统将全部 GPIO 的操作接口都通过“/sys/class/gpio/” 目录导出,非常方便用户使用。 输入下列命令,进入内核配置菜单:
obj-$(CONFIG_WDT) += wdt.o # wdt.c 编译控制
obj-$(CONFIG_PCI) += pci/ # pci 目录编译控制    在主菜单界面中选择“Device Drivers”:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j8 uImage    进入“Device Drivers”界面,选择并进入“GPIO Support”:
cmd_arch/arm/boot/uImage := /bin/bash /home/vmuser/prj/m28x/kernel/linux-2.6.35.3/scripts/mkuboot.sh -A arm
-O linux -T kernel -C none -a 0x40008000 -e 0x40008000 -n 'Linux-2.6.35.3-571-gcca29a0-g1914ba0' -d
arch/arm/boot/zImage arch/arm/boot/uImage    在“GPIO Support”中选中“/sys/class/gpio…”:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules   配置后重新编译内核,使用新内核的系统即可通过“/sys/class/gpio/”访问系统的 GPIO了。
【1.7.2 】LED 子系统配置

   Linux LED 子系统提供了“/sys/class/leds/”的访问接口,启用 LED 子系统能很方便地 操作系统的 LED 资源。
    在“Device Drivers”配置界面,选中“LED Support”支持:
$ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabiINSTALL_MOD_PATH=/home/chenxibing/work/rootfs
modules_install    进入“LED Support”子菜单,选中 LED 类支持和 LED 触发器支持,并根据需要设置触发器:
kernel/drivers/net/bonding/bonding.ko: (1)
kernel/drivers/usb/serial/usbserial.ko: (2)
kernel/drivers/usb/serial/ftdi_sio.ko:kernel/drivers/usb/serial/usbserial.ko (3)    只要将系统的 LED 设备驱动添加到 LED 子系统中,即可通过“/sys/class/leds/”接口来进行访问。
【1.7.3】 串口配置

   串口是嵌入式 Linux 必不可少的外设,默认控制台通常就是串口,所以必须在内核中使能串口以及串口控制台支持。
在“Device Drivers”配置界面,选择“Character devices”:
# insmod kernel/drivers/net/bonding/bonding.ko    进入“Character devices”配置菜单,选择“Serial drivers”:
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 35
EXTRAVERSION =3Serial drivers --->[ ] ARM JTAG DCC console    进入“Serial drivers”,在配置界面进行串口控制器配置。嵌入式 Linux 默认控制台是串口,所以还需使能串口控制台支持。串口控制器与具体处理器相关,需要根据硬件进行选择,很多处理器移植代码会默认选中自身的串口驱动支持,例如 EPC-28x,已经默认选中了“i.MXS Application serial port support”:
# indmod kernel/drivers/usb/serial/usbserial.ko
# insmod kernel/drivers/usb/serial/ftdi_sio.ko 【1.7.4】 USB Host 驱动配置

   USB 可以外接多种设备,不同设备的驱动配置也是不同的。下面以常用的 U 盘、USB鼠标键盘配置为例进行介绍。
1. 使用 U 盘
   U 盘在 Linux 系统下被认为是 SCSI 设备,所以必须在内核中选择支持 SCSI。在主菜单 界面选择“Device Drivers”,进入设备驱动配置界面,选择“SCSI device support”:
# modprobe ftdi_sio    进入“SCSI device support”配置界面,进行如下配置:
# tftp 40007fc0 uImage
# bootm 40007fc0    然后在驱动中配置 USB 控制器。进入“Device Drivers”,选中“USB support”:
## Booting kernel from Legacy Image at 40007fc0 ...
Image Name: Linux-2.6.35.3-571-gcca29a0-gd43
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2653928 Bytes = 2.5 MB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
……
以下省略    进入“USB support”菜单,选中“Support for Host-side USB”,并根据处理器的控制器 情况配置 USB 控制器。下面是 EPC-28x 处理器 USB 控制器的配置:
 基于某一个最接近的主板配置来修改;
 必须的、能确定的选项选中;
 不能确定的则不要改变原来配置;
 可选可不选的,建议根据 help 信息决定或者不选;
 一次改动不要太多,渐进式修改和验证;
 注意及时备份配置文件,出现意外可以回退恢复。    使用 U 盘,必须使能 USB 大容量类支持,选中“USB Mass Storage support”:
$ make ARCH=arm menuconfig    大多数情况下,U 盘都在用 FAT 格式,为了能正常使用 U 盘,还需在内核中使能 FAT支持。菜单路径和配置如下:
[*] Networking support --->
Device Drivers --->
File systems --->
Kernel hacking --->    保存配置,重新编译内核,基于新内核的系统就能使用 U 盘了。
2. 使用 USB 键盘和鼠标
   使用 USB 键盘或者鼠标,需要在内核中使能 HID 支持。在“Device Drivers”菜单界面,选中“HID Devices”:
[*] SPI support --->
PPS support --->
PTP clock support
-*- GPIO Support --->
<*> PWM Support --->    进入“HID Devices”,选中“USB Human Interface Device (full HID) support”
--- GPIO Support
[*] /sys/class/gpio/... (sysfs interface)
*** Memory mapped GPIO drivers: ***    另外,还需使能 Event 支持。在“Device Drivers”配置界面,选择“Input device support”:
<*> MMC/SD/SDIO card support --->
< > Sony MemoryStick card support (EXPERIMENTAL) --->
[*] LED Support --->
[ ] Accessibility support --->    进入“Input device support”,选中“Event interface”:
--- LED Support
[*] LED Class Support
*** LED drivers ***
...
[*] LED Trigger support
*** LED Triggers ***
<*> LED Timer Trigger
<*> LED Heartbeat Trigger
< > LED backlight Trigger
<*> LED GPIO Trigger
<*> LED Default ON Trigger Input device support --->
Character devices --->
-*- I2C support ---> 【1.7.5】 USB Gadget 驱动配置

   USB Gadget 能通过 USB Device 实现诸如 U 盘模拟、USB 串口、USB 网卡等多种功能。 首先在内核配置使能“USB Gadget Support”:
[*] /dev/kmem virtual device support
Serial drivers --->
[ ] ARM JTAG DCC console    然后进入“USB Gadget Support”,根据实际情况选择 USB 控制器,如下是 AM335x 的USB 控制器选择:
<M> 8250/16550 and compatible serial support
*** Non-8250 serial port support ***
<*> i.MXS debug serial port support
<*> i.MXS Application serial port support    最后在配置菜单中,根据实际需要选择配置相应的功能。对于 USB Gadget 的功能,建议编译为模块,在需要的时候插入模块,用完后将模块卸载:
[*] Block devices --->
[*] Misc devices --->
SCSI device support --->
< > Serial ATA and Parallel ATA drivers ---> 【1.7.6】 SD/MMC 驱动配置

   在“Device Drivers”菜单中使能“MMC/SD/SDIO card support”:
< > RAID Transport Class
<*> SCSI device support
< > SCSI target support
[*] legacy /proc/scsi/ support
*** SCSI support type (disk, tape, CD-ROM) ***
<*> SCSI disk support
< > SCSI tape support
< > SCSI OnStream SC-x0 tape support    进入“MMC/SD/SDIO card support”,使能“MMC block device driver”。在“MMC/SD/SDIO Host Controller Drivers”下选择处理器对应的 SD/MMC 控制器:
< > Sound card support --->
[ ] HID Devices --->
[*] USB support --->
<*> MMC/SD/SDIO card support --->    另外还需根据 SD/MMC 卡的文件系统格式在内核中配置相应的文件系统支持。如果是FAT 格式,请参考前面“使用 U 盘”中 VFAT 的配置;如果采用 Ext2/3/4 格式,则进行如下配置:
--- USB support
<*> Support for Host-side USB
[*] USB device filesystem (DEPRECATED)
[*] USB device class-devices (DEPRECATED)
[*] USB runtime power management (suspend/resume and wakeup)
<*> EHCI HCD (USB 2.0) support
[*] Support for Freescale controller
[*] Support for Host1 port on Freescale controller
[*] Support for DR host port on Freescale controller
[*] Root Hub Transaction Translators 【1.7.7】 网卡驱动配置

   配置网卡首先要在主菜单中使能网络,即选中“Networking support”:

<*> USB Mass Storage support
[ ] USB Mass Storage verbose debug File systems --->
DOS/FAT/NT Filesystems --->
<*> MSDOS fs support
<*> VFAT (Windows-95) fs support
(437) Default codepage for FAT
(iso8859-1) Default iocharset for FAT
< > NTFS file system support <*> Sound card support --->
[*] HID Devices --->
[*] USB support --->
<*> MMC/SD/SDIO card support --->    只有开启“Networking support”支持后才能在“Device Drivers”菜单中看到“Network device support”子菜单:
--- HID Devices
-*- Generic HID support
[ ] /dev/hidraw raw HID device support
*** USB Input Devices ***
<*> USB Human Interface Device (full HID) support
[ ] PID device support
[ ] /dev/hiddev raw HID device support
Special HID drivers --->    选中“Network device support”并进入,根据主板实际硬件,在“Ethernet driver support”中配置物理网卡。如下是基于 EPC-28x 的主板网卡配置示例:
< > Telephony support --->
Input device support --->
Character devices --->
-*- I2C support ---> 【1.7.8】 NFS Client 配置

   使用 NFS 文件系统,首先需要保证网卡可用,且在内核已经配置了网卡。在“File system”配置界面使能“Network File Systems”并进行配置:
< > Joystick interface
<*> Event interface
< > Event debugging    选中“Root file system on NFS”,能够通过 NFS 挂载服务器上的根文件系统,这点在裁剪文件系统中特别有用。
【1.7.9】 PPP 拨号配置

   PPP 拨号配置,在“Device Drivers”的“Network device support”菜单下。选中并使能“PPP (point-to-point protocol) support”及子选项即可使用 PPP 拨号功能。这里以模块方式编译:
`当然,还需要 USB Host 支持,参考前面“使用 U 盘”配置部分配置好 USB 控制器。
保存配置并编译内核,使用新内核的系统即可支持 USB 键盘和鼠标。`   编译内核后通过 make modules 编译模块,在目录下会生成 slhc.ko、pppox.ko、pppoe.ko 等模块。将这些模块复制到目标系统中,然后按照下列顺序依次插入模块:
Device Drivers --->
[*] USB support --->
<*> USB Gadget Support ---> <*> USB Peripheral Controller (Inventra HDRC USB Peripheral (TI, ADI, ...)) ---> 【1.7.10】 MTD 配置

   在内核配置主菜单界面,进入“Device Drivers”界面,选择“Memory Technology Device (MTD) support”:
<M> USB Gadget Drivers
< > Gadget Zero (DEVELOPMENT)
< > Audio Gadget (EXPERIMENTAL)
<M> Ethernet Gadget (with CDC Ethernet support)
[*] RNDIS support
...
<M> File-backed Storage Gadget (DEPRECATED)
[ ] File-backed Storage Gadget testing version
<M> Mass Storage Gadget
< > Serial Gadget (with CDC ACM and CDC OBEX support)    并进入“Memory Technology Device (MTD) support”,进行如下配置:
Device Drivers --->
<*> MMC/SD/SDIO card support --->    进入“NAND Device Support”,对系统 NAND 控制器进行选择:
--- MMC/SD/SDIO card support
...
*** MMC/SD/SDIO Card Drivers ***
<*> MMC block device driver
(8) Number of minors per block device
[*] Use bounce buffer for simple hosts
< > SDIO UART/GPS class support
< > MMC host test driver
*** MMC/SD/SDIO Host Controller Drivers ***
...
[*] Freescale i.MX Secure Digital Host Controller Interface
<*> MXS MMC support    保存配置,编译内核。采用新内核启动的系统,在驱动无误的情况下,可以看到系统的MTD 分区信息。如下是 EPC-28x 进入系统后,可通过/proc/mtd 文件查看:
File systems --->
<*> Second extended fs support
<*> Ext3 journalling file system support
<*> The Extended 4 (ext4) filesystem 【1.7.11】 UBIFS 文件系统配置

   UBIFS 是工作于 UBI 子系统之上的文件系统,而 UBI 又工作于 MTD 设备上,所以首先需要在 MTD 中使能 UBI:
Power management options --->
[*] Networking support --->
Device Drivers --->
File systems --->    进入“Enable UBI - Unsorted block images”,对 UBI 进行配置:
为了正常使用网络,通常还需在“`Networking options`”中配置 `TCP/IP`:    其中“Percentage of reserved eraseblocks for bad eraseblockshandling”设置用于坏块管理 的保留块的百分比,默认是 1%,可以适当调整大一些,不过必须与 U-Boot 中的设置一致。 还需在文件系统设置中使能和配置 UBIFS:
[*] Networking support --->
Networking options --->
<*> Packet socket
<*> Unix domain sockets
< > PF_KEY sockets
[*] TCP/IP networking
[*] IP: multicasting
[ ] IP: advanced router
[*] IP: kernel level autoconfiguration
[*] IP: DHCP support
[*] IP: BOOTP support
[*] IP: RARP support 【1.7.12】 CAN 驱动配置

   前面已经提到过,CAN 设备驱动的配置路径不在“Devie Drivers”下,而是在“Networking support”中。进入内核配置主菜单,选择“Networking support”:

<*> USB Mass Storage support
[ ] USB Mass Storage verbose debug    选中或者模块编译“CAN bus subsystem support”:
[*] --- Ethernet (10 or 100Mbit) --->

<*> FEC ethernet controller (of ColdFire and some i.MX CPUs)
[*] Second FEC ethernet controller (on some ColdFire CPUs)    进入“CAN bus subsystem support”,选中“Raw CAN Protocol”和“Broadcast Manager CAN Protocol”:
File systems --->
[*] Network File Systems --->
<*> NFS client support
[*] NFS client support for NFS version 3
[*] NFS client support for the NFSv3 ACL protocol extension
[*] NFS client support for NFS version 4
[*] NFS client support for NFSv4.1 (EXPERIMENTAL)
[*] Root file system on NFS    然后进入“CAN Device Drivers”,对 CAN 设备驱动进行配置,如下:
Device Drivers --->
[*] Network device support --->
<M> PPP (point-to-point protocol) support
<M> PPP BSD-Compress compression
<M> PPP Deflate compression
[*] PPP filtering
<M> PPP MPPE compression (encryption) (EXPERIMENTAL)
[*] PPP multilink support (EXPERIMENTAL)
<M> PPP over Ethernet (EXPERIMENTAL)
<M> PPP support for async serial ports
<M> PPP support for sync tty ports 【8】 EPC-28x 平台内核快速编译

   从 EPC-28x光盘内获取内核源码包EPC-28x.xxxxx.tar.bz2,然后把它拷贝到Ubuntu 下面,执行如下步骤:
1. 解压缩
#insmod slhc.ko
#insmod ppp_generic.ko
#insmod pppox.ko
#insmod pppoe.ko    解压后产生内核目录 linux-2.6.35.3。
2. 编译内核
   EPC-28x 内核源码的 Makefile 文件内已经配置好了 ARCH 和 CROSS_COMPILE,所以 在 make 时无需指定ARCH 和CROSS_COMPILE。 EPC-28x 的源码已经包含配置好的.config 文件,无需 makemenuconfig 配置即可使用默 认配置,除非需要改动内核配置。
插入模块后,生成/dev/ppp 设备节点,通过 ppp 拨号脚本即可进行拨号了。   编译完成,将得到内核文件。 另外,在执行 make distclean 或者 make mrproper 之前,请先将.config 配置文件备份, 如:
< > Connector - unified userspace <-> kernelspace linker --->
<*> Memory Technology Device (MTD) support --->
Device Tree and Open Firmware support --->
< > Parallel port support ---> 第二章,等你
https://img-blog.csdnimg.cn/54ac6ce8a0c3493882387bbe8e319487.gif#pic_center

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 嵌入式 Linux 内核驱动开发【The first day: 36093万字】