Linux内核驱动——Ubuntu 网络启动环境配置与操作

目录

[一、Linux 启动流程](#一、Linux 启动流程)

[1.1 内核与根文件系统均在 SD 卡中(本地启动)](#1.1 内核与根文件系统均在 SD 卡中(本地启动))

[1.2 内核与根文件系统均在 Ubuntu 主机(网络启动)](#1.2 内核与根文件系统均在 Ubuntu 主机(网络启动))

[二、Ubuntu 网络启动环境配置](#二、Ubuntu 网络启动环境配置)

[2.1 TFTP 服务配置](#2.1 TFTP 服务配置)

[2.2 NFS 服务配置](#2.2 NFS 服务配置)

[三、U-Boot 常用命令](#三、U-Boot 常用命令)

[3.1 基础命令:环境验证与配置](#3.1 基础命令:环境验证与配置)

[3.2 核心命令:TFTP 下载与内核启动](#3.2 核心命令:TFTP 下载与内核启动)

[四、bootargs 启动](#四、bootargs 启动)

[4.1 完整命令配置](#4.1 完整命令配置)

[4.2 启动完成](#4.2 启动完成)

五、内核恐慌与启动失败

[5.1 内核恐慌典型现象](#5.1 内核恐慌典型现象)

[5.2 排查步骤](#5.2 排查步骤)

六、总结


一、Linux 启动流程

(1)系统上电触发 ROM 启动

  • 系统上电后,先执行 IMX6 内部 ROM 中的启动程序(根据 boot mode 选择对应的外设);

(2)Bootloader 初始化与自搬移

  • 拷贝 SD 卡中的 Bootloader 前半部分程序到 IMX6 内部的 RAM 中,Bootloader 必须在自己的前半部分初始化好内存,并将自己的后半部分搬移到内存执行;

之后分为本地启动和网络启动两种情况。

1.1 内核与根文件系统均在 SD 卡中(本地启动)

(3)加载内核到内存

  • Bootloader 完成初始化后,从 SD 卡中读取内核镜像(zImage),将其搬移到内存的 0x80800000 地址处;

(4)启动内核并挂载根文件系统

  • Bootloader 通过 bootz 命令启动内核(PC 指针指向 0x80800000),内核启动完成后,自动挂载 SD 卡中存储的根文件系统,最终进入 shell 终端。

1.2 内核与根文件系统均在 Ubuntu 主机(网络启动)

(3)TFTP 下载内核与设备树

  • Bootloader 通过网络(依赖 SD 卡中配置的网络参数)连接 Ubuntu 主机的 TFTP 服务,将 Ubuntu 中的 zImage 下载到内存 0x80800000 地址,将设备树文件(imx6.dtb)下载到 0x83000000 地址;

(4)引导内核启动

  • Bootloader 向内核传递 bootargs 启动参数(指定 NFS 根文件系统路径、IP 地址等),执行bootz 命令启动内核;

(5)NFS 挂载根文件系统

  • 内核启动后,根据 bootargs 配置,通过网络挂载 Ubuntu 主机 NFS 服务中的根文件系统(rootfs),完成系统初始化并进入 shell。

二、Ubuntu 网络启动环境配置

当内核及根文件系统位于 Ubuntu 主机时,需在 Ubuntu 上配置 TFTP(传输内核镜像) 和 **NFS(共享根文件系统)**服务。

2.1 TFTP 服务配置

TFTP 协议用于快速传输小型文件(如内核镜像、设备树),开发板通过 UBoot 命令直接从 Ubuntu 下载,无需拷贝到 SD 卡:

(1)安装 TFTP 服务

bash 复制代码
sudo apt-get install tftpd-hpa tftp-hpa

(2)配置 TFTP 服务目录

  • 创建 TFTP 共享目录(建议与 NFS 目录同级,方便管理):
bash 复制代码
mkdir -p /home/linux/nfs/tftpboot
sudo chmod 777 /home/linux/nfs/tftpboot  # 赋予读写权限
  • 修改 TFTP 配置文件(/etc/default/tftpd-hpa),添加以下内容:
bash 复制代码
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/linux/nfs/tftpboot"  # 刚才创建的共享目录
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure --create"

(3)拷贝核心文件到 TFTP 目录

  • 将编译好的内核镜像(zImage)和 IMX6 设备树文件(imx6.dtb)拷贝到 TFTP 服务目录:
bash 复制代码
cp zImage imx6.dtb /home/linux/nfs/tftpboot/

(4)重启 TFTP 服务生效

bash 复制代码
sudo systemctl restart tftpd-hpa

2.2 NFS 服务配置

NFS 用于共享根文件系统,开发板内核启动后通过网络挂载,支持实时修改根文件系统中的驱动模块、配置文件:

(1)安装 NFS 服务

bash 复制代码
sudo apt-get install nfs-kernel-server

(2)配置 NFS 共享目录

  • 创建根文件系统存储目录(建议在 NFS 主目录下新建子目录,避免混乱):
bash 复制代码
mkdir -p /home/linux/nfs/imx6/rootfs

(3)解压根文件系统镜像

  • 将下载的根文件系统压缩包(rootfs.tar.bz2)拷贝到 NFS 共享目录并解压:
bash 复制代码
# 进入根文件系统存储目录
cd /home/linux/nfs/imx6/rootfs
# 解压压缩包(保留原始权限和目录结构)
sudo tar -xvf rootfs.tar.bz2

解压完成后,目录下会生成 bin、etc、lib、root 等系统目录,后续驱动模块(.ko 文件)可直接放在该目录下供开发板加载。

三、U-Boot 常用命令

3.1 基础命令:环境验证与配置

  • **help 或 ?:**查看 U-Boot 支持的所有命令。
  • **reset:**重启开发板(等效于硬件复位)。
  • **ping:**测试开发板与网络设备(如 PC、路由器)的连通性(例:ping 192.168.1.3)。
  • **printenv:**打印所有环境变量(环境变量均为字符串类型,如 ipaddr=192.168.1.100)。
  • **setenv:**设置环境变量(例:setenv ipaddr 192.168.1.100);若需删除变量,可执行 setenv name(将变量值置空)。
  • **saveenv:**保存环境变量到存储设备(如 SD 卡、NAND Flash),确保重启后变量生效。

3.2 核心命令:TFTP 下载与内核启动

(1)配置 TFTP 相关环境变量

bash 复制代码
# 设置开发板IP(与Ubuntu同网段)
setenv ipaddr 192.168.1.100
# 设置Ubuntu主机IP(TFTP/NFS服务器IP)
setenv serverip 192.168.1.3
# 保存配置
saveenv

(2)TFTP 下载内核与设备树

bash 复制代码
# 下载内核zImage到内存0x80800000地址(IMX6固定地址)
tftp 0x80800000 zImage
# 下载设备树imx6.dtb到内存0x83000000地址
tftp 0x83000000 imx6.dtb

(3)启动内核

执行 bootz 命令,指定内核和设备树在内存中的地址:

bash 复制代码
bootz 0x80800000 - 0x83000000

格式说明:bootz 内核地址 - 设备树地址,中间的 "-" 表示不指定 initrd 镜像。

四、bootargs 启动

4.1 完整命令配置

bootargs 是 U-Boot 传递给内核的核心参数,直接决定内核的控制台输出、根文件系统类型及挂载路径,以下是网络启动场景的经典配置(适配 IMX6 开发板):

bash 复制代码
setenv bootargs console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.3:/home/linux/nfs/imx6/rootfs,nfsvers=3 ip=192.168.1.100 init=/linuxrc

参数详解:

  • **console:**内核输出控制台(通过串口工具监视启动日志,ttyMXC0 为串口设备,115200 为波特率)。
  • **root:**根文件系统类型(/dev/nfs 表示通过 NFS 网络挂载根文件系统)。
  • **nfsroot:**NFS 服务器的 IP 及共享目录(格式为服务器 IP:共享目录路径,nfsvers=3 指定 NFS 版本)。
  • **ip:**内核启动时使用的 IP 地址(需与 ipaddr 环境变量一致)。
  • **init:**指定初始化进程(系统启动后运行的第一个进程,此处为 /linuxrc 脚本)。

4.2 启动完成

bootargs 启动完成后将出现以下界面,可在此输入命令行与 Ubuntu 连接:
bootargs启动完成

例如,在 Ubuntu 中新建 main.c 文件并编译后,可在 ARM 开发板上运行 a.out 程序:
ARM开发板和Ubuntu交叉开发环境

五、内核恐慌与启动失败

5.1 内核恐慌典型现象

若启动日志中出现类似信息:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0),核心原因是内核找不到或无法挂载根文件系统。
内核恐慌

5.2 排查步骤

(1)验证网络连通性

在 UBoot 命令行执行 ping 192.168.1.3(UbuntuIP),若提示 host is alive 说明网络正常;若提示 ping failed,需检查:

  • 开发板与 Ubuntu 是否连接同一路由器 / 交换机;
  • ipaddr 和 serverip 是否在同一网段;
  • 开发板 MAC 地址(ethaddr)是否配置(部分开发板需手动设置:setenv ethaddr xx:xx:xx:xx:xx:xx)。

(2)检查 NFS 服务配置

  • 验证 Ubuntu 的 NFS 共享目录权限:ls -ld /home/linux/nfs/imx6/rootfs,确保有 rwx 权限;
  • 验证 NFS 配置是否生效:showmount -e 192.168.1.3,若输出包含共享目录,说明配置正常;
  • 重启 NFS 服务:sudo systemctl restart nfs-kernel-server,解决服务未启动问题。

(3)检查 bootargs 参数

  • 确保 nfsroot 路径与 Ubuntu 的 NFS 共享目录完全一致(注意大小写、目录层级);
  • 确保 nfsvers=3 参数存在(部分内核不支持 NFSv4,指定 v3 兼容性更强);
  • 重新执行 setenv bootargs [完整参数] 和 saveenv,避免参数输入错误。

六、总结

本节聚焦 Ubuntu 网络启动的全流程实操,核心收获如下:

  • 掌握两种 SD 卡启动场景的差异,网络启动(TFTP+NFS)更适合驱动开发的实时调试需求;
  • 完成 Ubuntu 的 TFTP/NFS 服务配置,实现内核 / 设备树快速下载和根文件系统共享;
  • 熟练使用 UBoot 命令配置网络、下载镜像、启动内核,理解 bootargs 参数的核心作用;
  • 学会排查内核恐慌等常见启动问题,确保启动链路畅通。
相关推荐
YYYing.2 小时前
【Linux/C++进阶篇(二) 】超详解自动化构建 —— 日常开发中的“脚本” :Makefile/CMake
linux·c++·经验分享·ubuntu
范纹杉想快点毕业2 小时前
嵌入式实时系统架构设计:基于STM32与Zynq的中断、状态机与FIFO架构工程实战指南,基于Kimi设计
c语言·c++·单片机·嵌入式硬件·算法·架构·mfc
wdfk_prog2 小时前
[Linux]学习笔记系列 -- [drivers][gpio[[gpiolib]
linux·笔记·学习
砚上有墨2 小时前
问题记录:云平台计算节点内存故障,热迁移失败导致系统重启。
linux·运维·云计算
Diros1g2 小时前
ubuntu多网卡网络配置
网络·ubuntu·php
bloglin999992 小时前
ubuntu系使用root用户登录显示密码错误
linux·运维·ubuntu
70asunflower2 小时前
[特殊字符] Flameshot 完全指南:Ubuntu 下的终极截图工具
linux·运维·ubuntu
HIT_Weston2 小时前
118、【Ubuntu】【Hugo】首页板块配置:Template Lookup Order(.Kind)
linux·ubuntu·kind
API开发2 小时前
CentOS 单独安装Docker Compose v2
linux·docker·centos·docker compose