ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Linux内核驱动开发——boot loader

2026/9/27 21:30:51 拓冰建站 浏览量
Linux内核驱动开发——boot loader SecureCRT作用串口终端USB 转串口连接开发板看开机 log、进入 U-Boot 命令行、设置 bootargs、bootcmd。连接方式与普通串口相同设置好串口号以及波特率、数据位、校验位、停止位、流控位直接就可以建立连接通过该软件充当一个类似于Ubuntu里的terminal进行操控板子上的Linux系统内核启动参数consolettymxc0,115200内核会把系统控制台绑定到串口 tty 设备备/dev/ttymxc0。内核 printk 日志 → 控制台 → 串口这是内核的控制台不属于进程 stdout当串口上启动 shell/bin/shshell 的stdin0 /dev/ttymxc0键盘输入SecureCRT/minicom 发来的字符shell 的stdout1 /dev/ttymxc0标准输出shell 的stderr2 /dev/ttymxc0标准错误输出也就是shell 以及在这个 shell 下运行的程序默认把 in/out/err 全部指向串口 TTY。本质不是内核做全局重定向而是进程打开 TTY 设备作为自己的 0/1/2 文件描述符和 PC 上打开终端窗口原理一样PC 是 PTY开发板这里是硬件 UART TTY。如果我们进入系统之后需要在imx6ull的Linux系统中操作文件一般是不现实的所以都是在Ubuntu中操作文件完成后通过挂载将文件目录镜像到imx6ull的文件系统中。NFS网络文件系统。开发板直接通过网络访问 Ubuntu 主机里的文件夹不用反复传 ko/zImage/dtb驱动开发高频工具。 原理Ubuntu 把目录导出共享开发板内核 NFS 客户端把远程目录挂载到板子本地某个目录读写就像本地磁盘文件。mount -o nolock,nfsvers3 192.168.0.3:/home/1inux/nfs /mnt把 Ubuntu 主机192.168.0.3上/home/1inux/nfs这个 NFS 共享目录挂载到开发板本地/mnt目录使用NFS v3 协议关闭文件锁BootLoader 是什么BootLoader 是芯片上电后最先运行的一段裸机程序存放在 FlasheMMC、SPI Flash、NandFlash中。 作用硬件最小初始化时钟、DDR、串口、Flash、IO、电源关闭看门狗、关闭数据cache、关闭MMU、集成相关协议把 Linux 内核镜像 设备树从 Flash 加载到内存 DRAM给内核传启动参数bootargs跳转把 CPU 控制权交给 Linux 内核Linux 内核完整启动流程整体链路芯片 ROM → U-Boot (bootloader) → Linux 内核 → 根文件系统 → 用户应用阶段 1芯片内置 ROM片上固化不可修改上电复位CPU 从固定地址开始执行 ROM 代码初始化最基础硬件时钟、IO根据 BOOT 引脚配置选择启动介质eMMC / SD / SPI Flash把介质里的 U-Boot 前一小段代码加载到片内 RAM跳转执行 U-Boot Stage1阶段 2U-Boot Stage1汇编 start.S关闭看门狗、关闭中断配置基础 PLL 时钟初始化 DDR 内存将 U-Boot 完整镜像拷贝到 DDR 内存跳转到 U-Boot C 代码Stage2阶段 3U-Boot Stage2C 语言初始化串口、Flash、网卡等外设裸机驱动启动命令控制台串口交互SecureCRT/minicom 交互读取环境变量bootargs内核启动参数、bootcmd自动启动命令执行 bootcmd从 SD/eMMC 读取zImage压缩内核 dtb 设备树加载到 DDR 指定地址准备内核启动参数bootargs包含console、root等调用bootm跳转进入 Linux 内核把 CPU 控制权交给内核⚠️ 跳转后 U-Boot 不再运行内存中 U-Boot 资源会被内核覆盖。阶段 4Linux 内核启动内核自解压 内核初始化4.1 内核自解压zImagezImage 是压缩内核U-Boot 加载到内存后先执行解压代码把压缩内核解压到内核运行地址解压完成跳转到内核入口_text正式启动内核 C 代码4.2 内核早期汇编arch/arm/kernel/head.S关闭 MMU初始化页表开启 MMU虚拟内存识别 CPU 架构检查设备树 dtb 合法性建立临时栈跳转到内核 C 入口start_kernel()4.3 start_kernel () — 内核 C 入口核心这是内核最核心初始化函数初始化控制台 early_console串口提前输出 printk就是你在 SecureCRT 看到的早期打印初始化内存管理slab、buddy 内存分配器初始化中断子系统、时钟、定时器解析设备树 DTB遍历设备树节点匹配 platform 驱动调用驱动的 probe 函数设备驱动加载阶段初始化进程调度器初始化 TTY 子系统串口 ttymxc0对应你前面 stdin/stdout 重定向初始化文件系统、块设备子系统创建内核第一个用户进程initpid1阶段 5挂载根文件系统rootfs根据 bootargs 里root参数root/dev/mmcblk1p2从 eMMC 分区挂载根文件系统root/dev/nfs通过 NFS 网络挂载 Ubuntu 主机的 rootfs前面 NFS 实验内核必须找到根文件系统找不到直接 panic内核恐慌提示VFS: Unable to mount root fs阶段 6用户空间启动init 进程pid1内核启动/sbin/initpid1用户空间第一个进程init 读取配置依次启动挂载伪文件系统/proc、/sys、/dev创建设备节点启动 shell串口控制台 shell此时才有完整 stdin/stdout/stderr出现命令行提示符开发板就绪可以执行insmod、ls、mount NFS 等命令在学习调试阶段需要频繁改动U-BOOT文件所以如果还采用下载到sd卡从sd卡启动的方式是比较麻烦的每次下载十分耗费时间所以一般采用网络下载zImage和rootfsTFTP 是 U-Boot 阶段的网络文件传输方式不用把 zImage、dtb 烧写到 SD 卡 /eMMC直接从 Ubuntu 下载镜像到开发板 DDR 内存方便快速迭代调试内核和设备树。TFTP 下载U-Boot 阶段把镜像加载到 DDR 内存只存在本次上电不会写入 eMMC/SD重启就消失。烧写 mmcmmc write是把内存中的镜像永久写入 SD/eMMC断电依然保留一般是产品最终量产时才做。在实现网络下载之前要确定能连接到电脑端的Ubuntu这里可以直接ping一下Ubuntu的地址查看是否连接上了这里是连接上的前置条件就是配置好了本地imx6ull板子的环境变量中ipaddr、ethaddr、serveripipaddrU-Boot 网络驱动使用给开发板网卡分配 IP仅 U-Boot 阶段生效进入 Linux 后内核会重新配置 IPserverip告诉 U-Boot TFTP/NFS 服务器在哪tftp命令默认连接这个 IPethaddr以太网 MAC 硬件地址U-Boot 网卡驱动初始化时使用必须合法不能全 0局域网内不能重复缺少 ethaddr 会导致网卡初始化失败ping 不通。示例# 设置开发板IP setenv ipaddr 192.168.0.100 # 设置Ubuntu服务器IP setenv serverip 192.168.0.3 # 设置网卡MAC地址不能和局域网其他设备重复 setenv ethaddr 00:04:9f:04:d2:35 # 保存到Flash可选需要永久保存才执行 saveenv除以上通信地址的环境变量以外还需要保存挂载根文件系统的路径setenv bootargs root/dev/nfs nfsroot192.168.0.3:/home/linux/nfs/roots,nfsvers3 ip192.168.0.199 consolettymxc0,115200 init/linuxrcroot 指定根文件系统类型为 nfs 类型nfsroot 根文件系统位置在 ip 地址为 192.168.0.3 的主机的 /home/linux/nfs/imx6/rootfs 目录下ip 内核启动阶段使用的 ip 地址这里主要为了挂载根文件系统console 控制台使用 ttymxc0即串口 0波特率为 115200init 指定 init 进程为 /linuxrc加载完这些环境变量之后全部保存好以后每次uboot启动都要通过网络下载zImage和rootfs以及挂载根文件系统。具体命令如下# 通过tftp从Ubuntu下载zImage到开发板DDR 0x80800000 tftp 0x80800000 zImage # 通过tftp从Ubuntu下载设备树1.dtb到DDR 0x83000000 tftp 0x83000000 1.dtb # bootz启动内核格式 bootz [内核地址] - [设备树地址] bootz 0x80800000 - 0x83000000文件存放位置Ubuntu 主机TFTP 目录/tftproot里面放zImage、1.dtbNFS 根文件系统目录/nfs/rootfs开发板内核启动后会网络挂载这个目录作为根文件系统启动成功之后就可以在模拟终端中操作文件系统了尝试在Ubuntu中创建、删除文件、编译文件在imx6ull中查看运行均可完整启动流程上电后i.MX6 的 BOOT ROM先读取SD 卡上的 U-Boot拷贝到板载RAM然后跳转执行 U-Boot进入 U-Boot 运行阶段按下回车打断自动启动进入 U-Boot 交互式命令行。接着执行tftp命令通过网口从 PC 的 TFTP 服务器把zImage、.dtb下载到 DDR 指定内存地址。 执行bootz命令U-Boot 先把预先配置好的bootargs环境变量写入内存中 dtb 的chosen节点随后配置 ARM 寄存器跳转至 zImage 入口。zImage 自带自解压代码在 DDR 中将压缩内核解压得到原始 vmlinux 内核U-Boot 从此交出 CPU 控制权不再参与后续流程。内核启动过程中解析 dtb 并读取chosen节点内的bootargs参数识别root/dev/nfs按照 bootargs 里配置的 PC IP、NFS 目录、网卡 IP通过网络挂载 PC 上的 NFS 根文件系统。根文件系统挂载成功后内核执行init/linuxrc指定的用户空间首个程序正式进入用户空间完成系统启动。