
目录一、内核源码获取方式二、源码目录结构1. 体系结构相关 vs 无关2. Makefile 中的变量三、内核配置系统Kconfig / Makefile1. 配置变量如 CONFIG_NET的来源2. 配置修改流程四、搭建开发环境编译前的准备1. 交叉编译器2. 架构变量 ARCH3. 激活脚本简化操作五、内核编译流程详解1. 整体步骤2. 详细编译过程以ARM为例3. 常用镜像文件说明六、启动内核的前提条件与操作1. Bootloader如U-Boot所需文件2. 启动命令示例U-Boot3. 若启动失败常见原因七、移植步骤以i.MX6ULL为例1. 配置交叉编译环境2. 采用厂商参考配置3. 微调配置裁剪/添加功能4. 编译内核镜像5. 编译设备树6. 使用U-Boot加载并启动参考第六节。八、辅助工具说明九、关键文件路径总结一、内核源码获取方式方式特点芯片厂商提供推荐厂商已在公版上完成基础适配开发者在其基础上修改配置即可适配自有硬件省时省力。主线Linux内核从 www.kernel.org 下载适用于通用或全新平台需自行移植。二、源码目录结构1. 体系结构相关 vs 无关体系结构相关位于arch/目录按CPU架构分子目录如arm/,x86/包含该架构特有的汇编、内存管理、中断等代码。例如arch/arm/include/asm/io.h提供ARM平台的I/O操作。体系结构无关其余目录如kernel/,mm/,fs/,net/等提供通用功能与硬件解耦。2. Makefile 中的变量变量含义obj-y表示该对象文件或子目录将被编译进内核镜像built-in。obj-m表示该对象将被编译为可加载内核模块.ko。obj-表示不参与编译通常配合条件判断。示例obj-$(CONFIG_NET) : socket.o core/若CONFIG_NETy则socket.o和core/子目录下的内容会被加入内核。三、内核配置系统Kconfig / Makefile1. 配置变量如CONFIG_NET的来源配置变量定义在Kconfig文件中通过配置工具如make menuconfig进行选择和赋值。最终生成.config文件主Makefile会包含它从而决定obj-*的具体内容。2. 配置修改流程参考配置芯片厂商提供默认配置如npi_v7_defconfig。交互式修改make menuconfig需安装libncurses-dev。保存配置修改后保存.config更新。四、搭建开发环境编译前的准备1. 交叉编译器需指定CROSS_COMPILE前缀例如arm-linux-gnueabihf-。设置环境变量或直接在make命令中传入export CROSS_COMPILEarm-linux-gnueabihf- export ARCHarm2. 架构变量ARCH主Makefile中由ARCH ? $(SUBARCH)定义通常需手动设置为目标架构如arm。该值决定使用arch/$(ARCH)/下的源码。3. 激活脚本简化操作建议编写一个脚本如env_setup.sh统一设置ARCH、CROSS_COMPILE以及工具链路径每次编译前source该脚本。五、内核编译流程详解1. 整体步骤1. make defconfig # 生成 .config 2. make menuconfig # 可选微调配置 3. make # 编译内核镜像、模块、设备树若配置2. 详细编译过程以ARM为例阶段工具输入输出说明HOSTCC 编译主机端的工具编译目标文件CC交叉编译器.c/.S.o每个目录下的源文件编译为对象文件。归档为built-in.aAR目录下所有.obuilt-in.a每个参与内核的子目录生成一个静态库。链接内核LD各built-in.a 链接脚本vmlinuxELF格式的可执行内核文件含调试信息。生成符号表SYSMAPvmlinuxSystem.map供调试内核崩溃时定位PC/LR。去除ELF头OBJCOPYvmlinuxarch/arm/boot/Image纯二进制镜像未压缩可直接烧写但较大。自解压压缩脚本 gzip等Imagearch/arm/boot/zImage自带解压代码的压缩镜像Flash中常用。可选添加U-Boot头mkimagezImageuImageU-Boot专用格式包含头部信息。3. 常用镜像文件说明文件名特点Image未压缩体积大启动快直接执行。zImage压缩自解压适用于ARM体积小。bzImage大内核压缩格式多见于x86。uImage在zImage前增加U-Boot头部用bootm启动。六、启动内核的前提条件与操作1. Bootloader如U-Boot所需文件内核镜像zImage 或 uImage。设备树文件.dtb描述硬件配置。根文件系统可选initrd/initramfs若内核未内置根文件系统驱动则需提供临时根fs。2. 启动命令示例U-Boot# 仅加载内核设备树需内核能挂载实际根文件系统 tftp 0x80800000 zImage tftp 0x83000000 imx6ull-mmc-npi.dtb bootz 0x80800000 - 0x83000000 # 若需initrd临时根文件系统 tftp 0x80800000 zImage tftp 0x83000000 imx6ull-mmc-npi.dtb tftp 0x88000000 initrd.img bootz 0x80800000 0x88000000:0x4ecebc 0x83000000启动参数如root需由U-Boot设置或通过设备树传递用于指定真正的根文件系统设备。3. 若启动失败常见原因未指定root参数内核找不到根文件系统无法执行/init。设备树与硬件不匹配。内核配置缺少必要驱动如存储、网络等。七、移植步骤以i.MX6ULL为例1. 配置交叉编译环境export ARCHarm export CROSS_COMPILEarm-linux-gnueabihf-2. 采用厂商参考配置make npi_v7_defconfig # 生成 .configls arch/arm/configs/npi_v7_defconfig3. 微调配置裁剪/添加功能bashsudo apt install libncurses5-dev # 安装依赖 make menuconfig4. 编译内核镜像bashmake zImage # 仅编译内核核心 # 或 make # 编译全部含模块、设备树在内核编译过程中除了zImage还会生成其他几个关键文件它们的位置和作用如下文件位置说明zImagearch/arm/boot/zImage压缩后的内核映像文件是最终用于启动Linux系统的文件。vmlinux内核源码根目录 (/opt/linux_4.19.35_imx6ull/vmlinux)未压缩的原始内核文件ELF格式包含调试信息体积较大主要用于内核调试。Imagearch/arm/boot/Image由vmlinux经objcopy处理后生成的未压缩的纯二进制内核映像。System.map内核源码根目录 (/opt/linux_4.19.35_imx6ull/System.map)内核符号表记录了内核中所有符号函数、变量的地址对内核调试至关重要。5. 编译设备树bashmake imx6ull-mmc-npi.dtb6. 使用U-Boot加载并启动参考第六节。八、辅助工具说明工具用途bear监控make过程生成compile_commands.json供clangd等静态分析工具使用如VSCode智能提示。VSCode以目录为项目可通过工作区workspace管理多个项目便于阅读和编辑内核源码。九、关键文件路径总结文件/目录作用arch/$(ARCH)/体系结构相关代码Makefile根目录顶层构建规则.config内核配置单Kconfig各目录配置选项定义vmlinuxELF格式内核含调试信息System.map内核符号表arch/arm/boot/Image未压缩二进制内核arch/arm/boot/zImage压缩自解压内核ARM常用