内核移植(编译)
- 职责拆解与交付物梳理
- [一. 内核移植(编译)](#一. 内核移植(编译))
-
- [1. 获取内核源码](#1. 获取内核源码)
- [2. 移植linux源码](#2. 移植linux源码)
-
- [2.1. 将内核源码拷贝到ubuntu中,并解压](#2.1. 将内核源码拷贝到ubuntu中,并解压)
- [2.2. 打补丁](#2.2. 打补丁)
- [2.3. 生成标准板配置文件](#2.3. 生成标准板配置文件)
- [2.4. 安装相关的工具(库)](#2.4. 安装相关的工具(库))
- [2.5. 增加配置内核](#2.5. 增加配置内核)
- [2.6. 编译linux内核源码](#2.6. 编译linux内核源码)
- [二. 编译设备树文件](#二. 编译设备树文件)
-
- [1. 将fsmp157的设备树文件拷贝到linux内核源码中](#1. 将fsmp157的设备树文件拷贝到linux内核源码中)
- [2. 修改 `arch/arm/boot/dts/Makefile`](#2. 修改
arch/arm/boot/dts/Makefile) - [3. 编译设备树文件](#3. 编译设备树文件)
- [4. 更新`/tftpboot`中的设备树文件](#4. 更新
/tftpboot中的设备树文件)
- [三. 根文件系统制作---buildroot](#三. 根文件系统制作---buildroot)
-
- [1. 概念及获取](#1. 概念及获取)
- [2. 将buildroot和交叉编译器拷贝到ubuntu的tools,并解压](#2. 将buildroot和交叉编译器拷贝到ubuntu的tools,并解压)
- [3. 配置 buildroot](#3. 配置 buildroot)
- [4. 编译buildroot](#4. 编译buildroot)
- [四. 在开发板中测试新创建的文件系统](#四. 在开发板中测试新创建的文件系统)
-
- [1. 将文件系统路径配置到nfs中](#1. 将文件系统路径配置到nfs中)
- [2. 修改uboot参数](#2. 修改uboot参数)
- [3. 取消rootfs登录账号和密码](#3. 取消rootfs登录账号和密码)
- [4. 设置用户名和主机名](#4. 设置用户名和主机名)
本文档详细介绍了 Linux内核移植与编译流程 。主要内容包括:获取内核源码(官方镜像或芯片原厂BSP包)、解压标准内核并打补丁、生成配置文件(multi_v7_defconfig)、安装必要工具库、通过menuconfig配置内核选项(支持eMMC和网卡驱动)、编译生成uImage内核镜像等关键步骤。文档特别强调了交叉编译环境配置验证、补丁管理建议以及版本控制注意事项,为嵌入式Linux开发人员提供了从源码获取到镜像生成的全流程指导。编译完成后,将生成的uImage内核镜像拷贝至/tftpboot目录即完成移植工作。

职责拆解与交付物梳理
| 角色 | 主要任务 | 关键交付物 | 核心依赖 |
|---|---|---|---|
| 硬件工程师 | 需求评审、原理图、PCB、BOM、 | 硬件调试 硬件母板/子板、调试手册 | 芯片原厂参考设计、器件文档 |
| Linux 系统工程师 | Bootloader/Kernel 移植、根文件系统制作、系统裁剪 | U‑Boot、Linux 内核、根文件系统镜像 (rootfs.ext4、rootfs.tar) | SoC BSP、交叉工具链、Buildroot |
| Linux 驱动工程师 | 片上/板级驱动开发与调试 | Kernel patch、Device Tree 更新、驱动说明 | 内核源码、目标板硬件资料 |
| Linux 应用工程师 | 产品功能模块实现、上层应用 | 应用程序、启动脚本、配置文件 | 系统工程师提供的 rootfs & SDK |
| 测试/运维支持 | 烧录脚本、工装、量产流程 | 自动化脚本、测试报告 | 系统镜像、测试工具 |
推荐学习路径:
- 熟悉
git、make、交叉编译基础。 - 掌握内核配置、
Device Tree、常见总线驱动。 - 跟随真实项目完成一次从 BSP 到
rootfs的端到端交付。 - 了解
Buildroot或Yocto,以适应不同客户需求。 - 加强调试工具链:
gdbserver、perf、trace-cmd、ftrace、ethtool等等...
一. 内核移植(编译)
1. 获取内核源码
bash
1》从官网获取
https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/ -----原厂工程师
2》从芯片原厂
三星,高通,MTK,海思,RK,全志,ST等 ------产品工程师
linux内核源码如下:
en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz
bash
源码获取渠道:
官方镜像站
此处提供的链接(https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/)是 Linux Kernel 官方镜像。针对 STM32MP1 BSP 使用的 linux-5.4.31.tar.xz,可直接从该站点获取,保证源码完整性与 PGP 签名验证。
SoC原厂BSP包
ST的 en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz 集成了标准内核、patch 以及 fragment 配置,便于快速组装官方配置。
2. 移植linux源码
2.1. 将内核源码拷贝到ubuntu中,并解压
bash
1》解压
tar -xvf en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz
2》进入linux-stm32mp-5.4.31-r0,解压标准的内核源码
cd stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0
tar -xvf linux-5.4.31.tar.xz //解压标准内核源码
2.2. 打补丁
bash
1》进入内核源码目录
cd linux-5.4.31/
2》打补丁
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done
解压与打补丁建议:
建议在 for 循环前加入 set -e 并记录日志,方便回滚:
for p in ../*.patch; do echo "Applying $p" | tee -a ../patch.log; patch -p1 < "$p"; done
2.3. 生成标准板配置文件
bash
先导入交叉工具链
source /opt/sdk/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
1》 生成 multi_v7_defconfig 默认配置
make ARCH=arm multi_v7_defconfig "fragment*.config"
2》在默认 multi_v7_defconfig 配置中加入 ST 官方提供的 fragment config
for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
yes '' | make ARCH=arm oldconfig
3》 生成自己的默认配置文件
cp .config arch/arm/configs/stm32_fsmp1a_defconfig
4》取消 git 中的 SHA1
echo "" > .scmversion
//标准版基本配置已经配置好,在编译前如果需要编译额外的功能或者驱动,可以使用 meunconfig 来对内核进行配置
5》将配置好的内核源码拷贝到 ~/mp157/kernel
cp -af linux-5.4.31 ~/mp157/kernel/
7》返回到内核目录 ~/mp157/kernel/ ,并删除其他文件
cd ~/mp157/kernel/
rm -r en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/
2.4. 安装相关的工具(库)
bash
sudo apt-get install -y gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential chrpath socat cpio python python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping
sudo apt-get install -y libsdl1.2-dev xterm make xsltproc docbook-utils fop dblatex xmlto python-git-doc ncurses-dev libncurses5-dev libncursesw5-dev lib32ncurses5 libssl-dev linux-headers-generic u-boot-tools device-tree-compiler bison flex g++ libyaml-dev
sudo apt-get install -y coreutils bsdmainutils sed curl bc lrzsz corkscrew cvs subversion mercurial nfs-common nfs-kernel-server libarchive-zip-perl dos2unix texi2html diffstat libxml2-utils
2.5. 增加配置内核
bash
在内核源码目录下执行下面的命令:
make ARCH=arm menuconfig
由于内核源码默认配置已经支持 eMMC和网卡,在此列出主要选项,如下:
Device Drivers --->
Generic Driver Options --->
[*] Support for uevent helper //支持热插拔,在/proc下生成/proc/sys/kernel/hotplug
Device Drivers --->
<*> MMC/SD/SDIO card support --->
[*] STMicroelectronics STM32 SDMMC Controller
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support --->
<*> STMicroelectronics Multi-Gigabit Ethernet driver
<*> STMMAC Platform bus support
<*> Support for snps,dwc-qos-ethernet.txt DT binding.
<*> Generic driver for DWMAC
<*> STM32 DWMAC support
2.6. 编译linux内核源码
bash
1》编译内核源码
make ARCH=arm -j4 uImage LOADADDR=0xC2000040
//编译后生成文件uImage,如下:
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-5.4.31
Created: Tue Sep 19 03:15:30 2023
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 7312584 Bytes = 7141.20 KiB = 6.97 MiB
Load Address: c2000040
Entry Point: c2000040
Kernel: arch/arm/boot/uImage is ready
2》将uImage 拷贝到/tftpboot/
cp arch/arm/boot/uImage /tftpboot/ //将新编译的uImage拷贝到/tftpboot中
配置与版本管理注意点:
- 环境变量
source /opt/sdk/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi后建议执行echo $CC、echo $ARCH确认交叉链已生效,避免与主机GCC混用。
●merge_config.sh
scripts/kconfig/merge_config.sh默认输出.config,你已通过yes '' | make oldconfig消除交互式提示,推荐改用make ARCH=arm olddefconfig(非交互)以减少疏漏。
● 配置固化
cp .config arch/arm/configs/stm32_fsmp1a_defconfig后,可在版本库中保留该defconfig,方便同事复现环境。
● Git 版本提示
echo "" > .scmversion可以关闭-dirty字样;若打算长期维护建议保留 Git repo,在.gitignore中添加中间文件即可。
二. 编译设备树文件
在linux内核源码中,设备树文件一般在: arch/arm/boot/dts/
1. 将fsmp157的设备树文件拷贝到linux内核源码中
bash
将 D:\peter\ARM体系结构与系统移植\源码\设备树文件 目录中下面的所有文件
stm32mp151.dtsi
stm32mp157a-fsmp1a.dts
stm32mp15-pinctrl.dtsi
stm32mp15xx-dkx.dtsi
stm32mp15xx-fsmp1x.dtsi
拷贝到: linux内核源码的 arch/arm/boot/dts/ 目录中
2. 修改 arch/arm/boot/dts/Makefile
bash
1》打开Makefile
vim arch/arm/boot/dts/Makefile
2>添加下面一行
992 stm32mp157a-fsmp1a.dtb\
3. 编译设备树文件
bash
1》指定编译某个设备树文件:
make ARCH=arm -j4 stm32mp157a-fsmp1a.dtb LOADADDR=0xC2000040
或
2》编译 arch/arm/boot/dts/中所有的设备树文件
make ARCH=arm -j4 dtbs LOADADDR=0xC2000040
4. 更新/tftpboot中的设备树文件
bash
cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb /tftpboot/ //将新编译的设备树文件拷贝到/tftpboot中
- **编译与产物管理:
- 编译命令与输出已验证。建议统一产物目录,避免误传:**
bash
mkdir -p ~/mp157/kernel/build
make ARCH=arm O=build multi_v7_defconfig
make ARCH=arm O=build -j$(nproc) uImage LOADADDR=0xC2000040
cp build/arch/arm/boot/uImage /tftpboot/
LOADADDR 要与板级 u-boot 配置保持一致,建议写入 Makefile.kernel 或文档中,减少手动输入错误。
设备树配置要点:
- 文件同步
- 将自定义 DTS/DTSI 拷贝进
arch/arm/boot/dts/,同时修改Makefile。可以在arch/arm/boot/dts/Makefile中使用模块化插入或stm32mp157*.dtb分组,方便未来维护。
- 将自定义 DTS/DTSI 拷贝进
- 编译器选项
- 单独编译:
make ARCH=arm O=build stm32mp157a-fsmp1a.dtb - 全量编译:
make ARCH=arm O=build dtbs - 产物统一输出
build/arch/arm/boot/dts/
- 单独编译:
- 版本控制
- 可以建立
board/stm32mp157a/目录存放自定义 DTS & fragment,避免直接覆盖官方文件,便于差异管理。
- 可以建立
三. 根文件系统制作---buildroot

1. 概念及获取
bash
在linux文件系统制作中,使用busybox可以生成linux的系统命令,但是系统需要的c库和第三方库,需要自己单独获取,这种原始的制作根文件系统的方法比较麻烦,而且制作的根文件系统默认是没有账号和密码
buildroot 工具集成了busybox,而且还集成各种常见的软件和第三方库,在制作根文件系统时,就不需要自己在单独获取其他库,为制作根文件系统带来了很大的方便。
获取buildroot ----官网: https://buildroot.org/download.html
//使用buildroot制作根文件系统需要用到:
buildroot-2021.02.1.tar.xz //源码
arm-fsmp1x-linux-gnueabihf_sdk-buildroot.tar.gz //交叉工具链

2. 将buildroot和交叉编译器拷贝到ubuntu的tools,并解压
bash
1》创建文件系统的目录
farsight@ubuntu:~$ mkdir mp157/rootfs
1》解压buildroot源码
farsight@ubuntu:~/mp157/rootfs$ tar xvf buildroot-2021.02.1.tar.xz
2》解压交叉工具链
farsight@ubuntu:~/mp157/rootfs$ tar -xvf arm-fsmp1x-linux-gnueabihf_sdk-buildroot.tar.gz
3. 配置 buildroot
bash
//导入交叉工具链
source /opt/sdk/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
//进入到buildroot源码目录下,
cd buildroot-2021.02.1/
//执行: make menuconfig
1》配置目标选项
Target options --->
Target Architecture (ARM (little endian)) --->
Target Binary Format (ELF) --->
Target Architecture Variant (cortex-A7) --->
Target ABI (EABIhf) --->
Floating point strategy (NEON/VFPv4) --->
ARM instruction set (ARM) --->
2》配置交叉工具链
Toolchain --->
Toolchain type (External toolchain) --->
Toolchain (Custom toolchain) ---> //使用自己的交叉编译器
Toolchain origin (Pre-installed toolchain) ---> //预装的编译器
(/home/farsight/mp157/rootfs/arm-fsmp1x-linux-gnueabihf_sdk-buildroot) Toolchain path
($(ARCH)-fsmp1x-linux-gnueabihf) Toolchain prefix //交叉编译器的前缀
External toolchain gcc version (9.x) --->
External toolchain kernel headers series (5.4.x) ---> //交叉编译器Linux版本号
External toolchain C library (glibc/eglibc) --->
[*] Toolchain has SSP support?
[ ] Toolchain has RPC support? //取消勾选
[*] Toolchain has C++ support?
[*] Enable MMU support
3》系统配置
System configuration --->
(farsight) System hostname //主机名,自定义
(Welcome to farsight STM32MP157a) System banner //欢迎语
Init system (BusyBox) --->
/dev management (Dynamic using devtmpfs + mdev) --->
[*] Enable root login with password //使能登录密码
(123) Root password //设置登录密码
4》 配置文件系统镜像 ---filesystem image
Filesystem images --->
[*] ext2/3/4 root filesystem
ext2/3/4 variant (ext4) --->
(1G) exact size //ext4 根文件系统
5》禁止内核和u-boot编译
Kernel --->
[ ] Linux Kernel //不能选择该选项
Bootloaders --->
[ ] U-Boot //不能选择该选项
6》配置目标包
Target packages --->
System tools --->
[*] kmod //使能内核模块相关命令
Libraries --->
Graphics --->
[*] libdrm --->
[*] Install test programs
Networking applications --->
[*] openssh //使能openssh
sudo make busybox-menuconfig
Linux Module Utilities --->
[*] depmod (27 kb) //使能depmod
4. 编译buildroot
bash
sudo make
//生成文件:ls output/images/
rootfs.ext2 rootfs.ext4 rootfs.tar
//在/opt中创建根文件系统目录rootfs,将生成的根文件系统解包到:myrootfs
mkdir /opt/myrootfs
tar -xvf output/images/rootfs.tar -C /opt/myrootfs
Buildroot 根文件系统制作:
官方最新版本对比: 根据 Buildroot 官方下载页(https://buildroot.org/download.html):
| 发布线 | 当前版本 | 发布日期 | 状态 |
|---|---|---|---|
| 2025.11.x | 2025.11-rc2 | 2025-11-20 | 最新 RC(预期 2026 年 3 月成为稳定版) |
| 2025.08.x | 2025.08.2 | 2025-11-20 | 稳定 LTS 替换(维护到 2025 年 12 月) |
| 2025.02.x | 2025.02.8 | 2025-11-20 | 长期维护版(LTS,支持到 2028 年 3 月) |
此处使用的 buildroot-2021.02.1 较老,若无兼容性限制,你也可以升级到 2025.02.x LTS,可获得新包 与 安全维护。下载链接可从页面提供的 .tar.gz / .tar.xz 获取,对应 PGP 签名亦可校验。
工具链与配置建议:
source /opt/sdk/...是 ST 官方 SDK 的环境;若升级 Buildroot,需确认交叉链与External toolchain版本号匹配。kernel headers、gcc version应与交叉链实际匹配。Toolchain prefix中可使用$(ARCH)-fsmp1x-linux-gnueabihf,但需确认ARCH在环境变量中正确(多数情况下ARCH=arm,也可以直接写arm-fsmp1x-linux-gnueabihf,避免变量为空)。Filesystem images:- 若 NFS 开发,
rootfs.tar足够;若需要烧写 eMMC/SD 卡,可保留rootfs.ext4或使用tar+mkfs.ext4自行生成。 exact size (1G)会生成固定大小镜像;如果后期需要压缩或缩小镜像,可以改用Auto或脚本后处理。
- 若 NFS 开发,
四. 在开发板中测试新创建的文件系统
1. 将文件系统路径配置到nfs中
bash
1》打开nfs配置文件
sudo vim /etc/exports
2》在文件末尾添加下面一行
/opt/myrootfs *(rw,sync,no_root_squash,no_subtree_check)
3》重启nfs服务
sudo /etc/init.d/nfs-kernel-server restart
2. 修改uboot参数
bash
重启开发板,进入uboot命令行
STM32MP> setenv bootargs root=/dev/nfs nfsroot=192.168.30.5:/opt/myrootfs ip=192.168.60.7 rootwait rw earlyprintk console=ttySTM0,115200 init=/linuxrc
STM32MP> saveenv
重启开发板,观察结果:
[ 6.479696] bootserver=255.255.255.255, rootserver=192.168.30.5, rootpath=
[ 6.488237] ALSA device list:
[ 6.489890] #0: STM32MP1-FSMP1A
[ 6.557474] VFS: Mounted root (nfs filesystem) on device 0:17.
[ 6.562685] devtmpfs: mounted
[ 6.567262] Freeing unused kernel memory: 1024K
[ 6.606957] Run /linuxrc as init process
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Saving random seed: OK
Starting network: ip: RTNETLINK answers: File exists
FAIL
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
Starting sshd: /var/empty must be owned by root and not group or world-writable.
OK
Welcome to Haha
HQYJ login: root
Password:
# ls
# ls /
bin lib media proc sbin usr
dev lib32 mnt root sys var
etc linuxrc opt run tmp
3. 取消rootfs登录账号和密码
bash
1》打开文件系统myrootfs中的配置文件etc/inittab
vim /opt/myrootfs/etc/inittab
2》修改下面一行
注释下面一行:
#console::respawn:/sbin/getty -L console 0 vt100 # GENERIC_SERIAL
添加下面一行:
console::respawn:-/bin/sh
3》重启开发板,观察:、
[ 7.554619] VFS: Mounted root (nfs filesystem) on device 0:17.
[ 7.560099] devtmpfs: mounted
[ 7.564284] Freeing unused kernel memory: 1024K
[ 7.606728] Run /linuxrc as init process
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Initializing random number generator: OK
Saving random seed: OK
Starting network: ip: RTNETLINK answers: File exists
FAIL
Starting sshd: /var/empty must be owned by root and not group or world-writable.
OK
#
#
#
# ls
bin lib media proc sbin usr
dev lib32 mnt root sys var
etc linuxrc opt run tmp
4. 设置用户名和主机名
bash
1》打开文件系统myrootfs中的配置文件etc/profile
2》在文件末尾添加下面内容:
export HOSTNAME=HQYJ //主机名
export USER=root //用户名
export HOME=root //用户家目录名
export PS1="[$USER@$HOSTNAME \w]\# " //命令提示符格式
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
3》重启开发板,观察:
[ 6.516506] devtmpfs: mounted
[ 6.520478] Freeing unused kernel memory: 1024K
[ 6.566750] Run /linuxrc as init process
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Initializing random number generator: OK
Saving random seed: OK
Starting network: ip: RTNETLINK answers: File exists
FAIL
Starting sshd: /var/empty must be owned by root and not group or world-writable.
OK
[root@HQYJ /]#
[root@HQYJ /]#
以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!