Linux内核概述
内核是一个操作系统的核心,提供了操作系统最基本的功能,是操作系统工作的基础,决定着整个系统的性能和稳定性
操作系统是在内核的基础上添加了各种工具集、桌面管理器、库、shell、应用程序等
Linux层次结构
Linux内核特点
Linux内核源码结构
Linux内核源码获取
https://www.kernel.org/
主版本号.次版本号.修订版本
支持对应的硬件平台
相对成熟的版本(资料多)
稳定版本(次版本号为偶数的版本一般都是稳定版)
Linux内核源码结构

arch: 与CPU架构相关的源代码 block:磁盘设备的支持
crypto:加密相 firmware:固件
drivers:设备驱动 fs:文件系统
include:头文件 init:内核初始化
ipc:进程间通信 kernel:内核核心调度机制等
lib:库 mm:内存管理
net:网络协议 scripts:工具、脚本等
security:安全 usr:打包与压缩
virt:虚拟 tools: 工具
COPYING: 版权 CREDITS: 内核贡献者
README: 说明文档 Documentation: 帮助文档
Makefile: 编译管理 samples: 示例
... ...
Linux内核的配置与编译
Linux内核源码配置
在Linux内核源码顶层目录下的Makefile中指定(ARCH、CROSS_COMPILE)
make <soc_name>_defconfig
注1:soc_name为当前使用的处理器的名字
注2:内核源码的arch/arm/configs下对各个厂商的soc都有一个默认配置文件
执行该命令后就会将对应的配置文件中的信息导入到源码顶层目录下的.config
文件中CONFIG_xxx=y表示内核选中了该功能,内核编译时就会将该功能对应的
代码编译,内核的体积也会增大。#CONFIG_xxx is not set表示内核没有选中
该功能,内核编译时该功能对应的代码不会被编译,内核的体积也会减小。
默认配置只能保证内核拥有最基本的功能,我们需要根据自己的实际需求对内核做进一步的配置
方法1:
直接修改.config文件(不推荐)
方法2:
make menuconfig
make menuconfig
[ ] 有两种状态
输入Y,显示“*”,内核中该功能被选中,相关代码会被编译进内核
输入N,显示“ ”,内核中该功能不被选中,相关代码不会被编译进内核
< > 有三种状态
输入Y,显示“*”,内核中该功能被选中,相关代码会被编译进内核
输入N,显示“ ”,内核中该功能不被选中,相关代码不会被编译进内核
输入M,显示“M”,内核中该功能被选为模块(被编译为独立的模块)
注:使用make menuconfig配置的本质还是修改.config文件
make uImage
编译内核(编译选为“*”的选项到内核)
make modules
编译内核模块(编译选为“M”的选项为独立模块)
make dtbs
编译设备树(将设备树源文件dts编译为二进制文件dtb)
make clean
删除编译过程中产生的中间文件
实验七 Linux 内核移植
【实验目的】
掌握 Linux 内核配置和编译的基本方法
【实验环境】
1、 ubuntu 14.04 发行版
2、 FS4412 实验平台
3、 交叉编译工具:arm-none-linux-gnueabi-
【注意事项】
1、实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行
【实验步骤】
1、 在 Linux 官网下载 Linux 内核源码(这里我们下载 linux-3.14.tar.xz)
Index of /pub/linux/kernel/v3.x/
2、 拷贝内核源码包到 ubuntu 的家目录下,解压并进入其顶层目录
$ tar xvf linux-3.14.tar.xz $ cd linux-3.14 |
3、 源码并不知道我们的处理器架构及交叉编译工具是什么,我们自己在 Makefile 中指定
$ vi Makefile
将
ARCH ?= $(SUBARCH) |
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%) |
修改为以下内容(注意后边不要有多余空格),然后保存退出
ARCH ?= arm |
CROSS_COMPILE ?= arm-none-linux-gnueabi- |
4、 指定使用的处理器
$ make exynos_defconfig

5、 进入内核配置界面
$ make menuconfig
弹出如下图形化配置界面,在该界面下我们可以对 linux 进行进一步的修改和配置
方向键可选择不同的选项,‘ Enter ’键进入子菜单,‘ Y ’键选中某项功能, ‘ N ’键去除某项功能,‘ M ’键将该功能编译成内核模块,两次‘ Esc ’键退出界面,‘ ? ’键 为帮助选项,‘ / ’键为搜索选项
注 1 :若显示如下信息,是因为 ubuntu 上没有安装对应的图形库
执行如下命令安装对应的图形库,然后重新执行 make menuconfig 即可
$ sudo apt-get install libncurses5-dev
注 2:若显示如下信息,是因为终端窗口太小,需要先将窗口最大化
6、 配置内核
将‘System Type’菜单下的‘S3C UART...’修改为 2(即使用 UART2)
System Type ---> (2) S3C UART to use for low-level messages |
设置完成后通过方向键选择‘Save’保存即可,然后选择‘Exit’退出该配置界面
7、 编译内核(该过程可能需要二十分钟左右)
$ make uImage
显示如下信息表示编译成功,即在源码的 arch/arm/boot/ 目录下生成了 uImage 镜像
注:如图所示,第一次在 ubuntu 上编译 Linux 内核会提示缺少一个 mkimage 命令

该命令可在 uboot 源码中 u-boot-2013.01/tools/目录下获取(必须是编译后的 uboot) 将该命令拷贝到 ubuntu 的/usr/bin 目录下即可正确编译内核
$ sudo cp u-boot-2013.01/tools/mkimage /usr/bin/
给该命令添加可执行权限
$ sudo chmod 777 /usr/bin/mkimage
完成后回到内核的顶层目录下重新编译内核即可
8、 编译设备树
内核源码中并没有 fs4412 平台的设备树文件,这里我们从源码支持的平台中找一个硬件与我们最类似的,在其基础上进行修改,这里我们参考的是 samsung 公司的 origen
$ cp arch/arm/boot/dts/exynos4412-origen.dts arch/arm/boot/dts/exynos4412-fs4412.dts |
因为添加的设备树文件也要编译,所以对应的 Makefile 也要修改
$ vi arch/arm/boot/dts/Makefile |
在
exynos4412-origen.dtb \ |
后添加如下内容,然后保存退出
exynos4412-fs4412.dtb \ |
回到源码的顶层目录下编译设备树
$ make dtbs |
显示如下信息表示编译成功,即在 arch/arm/boot/dts/ 目录下生成了 exynos4412-fs4412.dtb
9、 测试内核和设备树
将编译生成的内核和设备树拷贝到 tftp 的工作目录
$ sudo cp arch/arm/boot/uImage /tftpboot $ sudo cp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/ $ sudo chmod 777 /tftpboot/* |
设置 uboot 的启动参数并保存
# setenv ipaddr ***.***.***.*** # setenv serverip xxx.xxx.xxx.xxx # setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000 - 42000000 # setenv bootargs root=/dev/nfs nfsroot=xxx.xxx.xxx.xxx:/opt/4412/rootfs/ rw console=ttySAC2,115200 init=/linuxrc ip=***.***.***.*** # saveenv |
主机的 ip 在同一个网段(根据自己电脑情况进行设置) 注 2:以上设置手动输入,命令粘贴可能会有中文符号回到 ubuntu 重启 tftp 和 nfs 服务器
$ sudo service tftpd-hpa restart $ sudo service nfs-kernel-server restart |
重启开发板查看现象,如图所示,内核在启动到一半时会崩溃卡死,原因在于我们在该 实验中只是对 UART 进行了配置,而其他功能都保持默认选项,内核默认配置中没选配我们使用的网卡驱动、nfs 等功能,所以在挂载根文件系统时导致内核崩溃,所以后续我们还需要配置网卡驱动、nfs 等