00. 目录
01. 安装编译工具和依赖
deng@local:~/A72/x3399_linux_new/kernel$ sudo apt install git lib32z1
02. 内核源码下载
有三个方法获取Kernel源码,
-
一个是Kernel官方内核源码
-
一个是NXP官方的kernel源码
-
一个是经过我们修改适配我们板子的kernel源码
我们这里使用我们提供的源码为例,对官方源码感兴趣的小伙伴也可以下载来学习配置。我们的kernel是根据长厂家官方提供的kernel定制的,厂家的kernel是根据kernel官方某一版本进行芯片适配的。我们作为嵌入式开发者,一般只需要使用芯片厂商适配好的kernel进行开发即可,对于从kernel官方下载新版本来配置这是芯片厂商做的事情,感兴趣的伙伴也可以根据NXP官方提供的芯片手册进行适配新版本的kernel。
Kernel官方内核源码:https://git.kernel.org/
NXP内核源码: https://github.com/Freescale/linux-fslc
EBF内核源码:https://github.com/Embedfire/ebf_linux_kernel.git
git clone https://github.com/Embedfire/ebf_linux_kernel.git
03. kernel工程结构分析
学习一个软件,尤其是开源软件,首先应该从分析软件的工程结构开始。一个好的软件有良好的工程结构,对于读者学习和理解软件的架构以及工作流程都有很好的帮助。
内核源码目录如下
arch COPYING drivers init kernel make_deb.sh README sound
block CREDITS firmware ipc lib Makefile samples tools
build_image crypto fs Kbuild LICENSES mm scripts usr
certs Documentation include Kconfig MAINTAINERS net security virt
我们可以看到Linux内核源码目录下是有非常多的目录,且目录下也有非常多的文件, 下面我们简单分析一下常见目录的主要作用。
arch :主要包含和硬件体系结构相关的代码,如arm、x86、MIPS,PPC,每种CPU平台占一个相应的目录,例如我们使用的imx系列CPU就在 arch/arm/mach-imx
目录下,Linux内核目前已经支持30种左右的CPU体系结构。arch中的目录下存放的是各个平台以及各个平台的芯片对Linux内核进程调度、内存管理、 中断等的支持,以及每个具体的SoC和电路板的板级支持代码。
block :在Linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),譬如说SD卡、Nand、硬盘等都是块设备,block目录下放的是一些Linux存储体系中关于块设备管理的代码。
crypto :这个目录下存放的是常用加密和散列算法(如md5、AES、 SHA等),还有一些压缩和CRC校验算法。
Documentation:内核各部分的文档描述。
drivers :设备驱动程序,里面列出了linux内核支持的所有硬件设备的驱动源代码,每个不同的驱动占用一个子目录,如char、block、 net、 mtd、 i2c等。
fs :fs就是file system,里面包含Linux所支持的各种文件系统,如EXT、FAT、 NTFS、 JFFS2等。
include :目录包括编译核心所需要的大部分头文件,例如与平台无关的头文件在 include/linux
子目录下,与cpu架构相关的头文件在include目录下对应的子目录中。
init :内核初始化代码,这个目录下的代码就是linux内核启动时初始化内核的代码。
ipc :ipc就是 inter process commuication
,进程间通信,该目录下都是linux进程间通信的代码。
kernel :kernel就是Linux内核,是Linux中最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在arch/*/kernel目录下。
lib :lib是库的意思,lib目录下存放的都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的,因为在内核编程中是不能用C语言标准库函数的,所以需要使用lib中的库函数,除此之外与处理器结构相关的库函数代码被放在 arch/*/lib/
目录下。
mm : 目录包含了所有独立于 cpu 体系结构的内存管理代码,如页式存储管理内存的分配和释放等,而与具体硬件体系结构相关的内存管理代码位于 arch/*/mm
目录下,例如 arch/arm/mm/fault.c
。
net : 网络协议栈相关代码,net目录下实现各种常见的网络协议。
scripts :这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用了配置编译linux内核的。
security :内核安全模型相关的代码,例如最有名的SELINUX。
sound : ALSA、 OSS音频设备的驱动核心代码和常用设备驱动。
usr : 实现用于打包和压缩的cpio等。
04. 内核配置选项
Linux内核的配置系统由三个部分组成,分别是:
- Makefile:分布在 Linux内核源代码根目录及各层目录中,定义 Linux 内核的编译规则;
- 配置文件:给用户提供配置选择的功能,如Kconfig文件定义了配置项, 使用make_deb.sh脚本编译时,使用
arch/arm/configs/npi_v7_defconfig
文件对配置项进行赋值; - 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释) 和配置用户界面(linux提供基于字符界面、基于Ncurses 图形界面以及 基于 Xwindows 图形界面的用户配置界面,各自对应于make config、make menuconfig 和 make xconfig)。
make menuconfig是一个基于文本选择的配置界面, 推荐在字符终端下使用,可以通过键盘的”上”、”下”、”左”、”右”、”回车”、”空格”、”?”、”ESC”等按键进行选择配置。
#使用图形界面配置需要额外安装 libncurses-dev
sudo apt install libncurses-dev
比如我们选择配置我们开发板的ds18b20驱动: ds18b20
, 如果读者找不到这个配置选项在哪里,可以使用 make menuconfig
中的搜索功能, 在英文输入法状态下按下”/”则可以进行搜索,输入”ds18b20”找到改配置选项的位置, 当输入错误时,可使用 Ctrl+退格键 删除输入。
可使用 y、n、m
键更改ds18b20驱动的配置时, 其中y表示编译进内核中,m表示编译成模块,n表示不编译。 也可使用空格选择ds18b20驱动的配置选项。
05. 内核编译
deng@local:~/A72/x3399_linux_new$ ./mk.sh -k