NXP iMX8MM 通过 TFTP和 NFS 启动示例

1). 简介

嵌入式 Linux 设备开发调试时候为了方便部署各种配置和修改常用的一种方法就是通过网络启动,具体就是将 Linux Kernel(以及 Device tree/Device Tree overlays) 从开发主机的 TFTP 服务加载, Linux rootfs 通过开发主机的 NFS 服务加载,这样开发过程中的功能配置或者文件修改就能直接在开发主机上面完成,而无需先复制到设备端再部署。本文就基于 NXP iMX8MM ARM嵌入式平台演示 TFTP/NFS 启动的简单示例。

本文所演示的平台来自于Toradex Verdin iMX8MM 嵌入式平台,基于 NXP iMX8M Mini 系列 ARM 处理器,核心为 Cortex-A53

2). 硬件准备

a). Verdin iMX8MM ARM 核心版配合 Dahlia Carrier Board 载板,并连接调试串口以便测试。

b). Verdin iMX8MM 核心版 Boot ROM 启动选项已经 fuse ,因此 Bootloader (U-Boot) 必须要从模块 eMMC启动,所以先参考这里说明更新当前最新的 Toradex Ycoto Linux Reference Multimedia Image V6.4 到核心板 eMMC

c). Verdin iMX8MM 设备平台网口和开发主机单独用于开发的网口直连,如下图所示。由于需要在开发主机配置 DHCP 服务,因此不建议将设备和开发主机直接连接到工作网络,以免多个 DHCP 服务器冲突。

d). 从这里下载 Toradex Ycoto Linux Reference Multimedia Image Quartely 6.4.0 版本到开发主机并解压,以便后续部署。

---------------------------------------

$ cd

$ tar xvf Verdin-iMX8MM_Reference-Minimal-Image-upstream-Tezi_6.4.0-devel-202309+build.14.tar

$ cd Verdin-iMX8MM_Reference-Minimal-Image-upstream-Tezi_6.4.0-devel-202309+build.14/

$ ls -al

总计 51684

drwxrwxr-x 2 simon simon     4096 1221 12:15 .

drwxr-xr-x 3 simon simon     4096 1221 12:15 ..

-rw-r--r-- 1 simon simon     2016 92 00:37 image.json

-rw-r--r-- 1 simon simon 1291800 92 00:03 imx-boot

-rw-r--r-- 1 simon simon    69050 91 22:22 LA_OPT_NXP_SW.html

-rw-r--r-- 1 simon simon   378880 91 22:22 marketing.tar

-rw-r--r-- 1 simon simon      183 91 22:22 prepare.sh

-rw-r--r-- 1 simon simon 12981512 92 00:35 Reference-Minimal-Image-upstream-verdin-imx8mm.bootfs.tar.xz

-rw-r--r-- 1 simon simon 38155936 92 00:37 Reference-Minimal-Image-upstream-verdin-imx8mm.tar.xz

-rw-r--r-- 1 simon simon     2434 91 22:22 toradexlinux.png

-rw-r--r-- 1 simon simon     4117 91 23:47 u-boot-initial-env-sd

-rw-r--r-- 1 simon simon       18 91 22:22 wrapup.sh

---------------------------------------

3). 开发主机部署 DHCP/TFTP/NSF 服务

a). 本文示例以 Ubuntu 22.04 64bit 环境为例,其他环境可以参考这里或者其对应发行版本的相关说明。

b). 配置 DHCP 服务

./ 安装 DHCP Server

---------------------------------------

$ sudo apt-get install isc-dhcp-server

---------------------------------------

./ 如下修改 /etc/dhcp/dhcpd.conf 配置文件

---------------------------------------

--- a/etc/dhcp/dhcpd.conf 2023-12-21 11:31:13.460674880 +0800

+++ b/etc/dhcp/dhcpd.conf 2023-12-21 11:44:49.647593313 +0800

@@ -7,7 +7,7 @@

#

# option definitions common to all supported networks...

-option domain-name "example.org";

+option domain-name "verdin.net";

option domain-name-servers ns1.example.org, ns2.example.org;

default-lease-time 600;

@@ -25,7 +25,7 @@

# Use this to send dhcp log messages to a different log file (you also

# have to hack syslog.conf to complete the redirection).

-#log-facility local7;

+log-facility local7;

# No service will be given on this subnet, but declaring it helps the

# DHCP server to understand the network topology.

@@ -61,11 +61,33 @@

# max-lease-time 7200;

#}

+subnet 192.168.10.0 netmask 255.255.255.0 {

+        default-lease-time              86400;

+        max-lease-time                  86400;

+        option broadcast-address        192.168.10.255;

+        option domain-name              "verdin.net";

+        option domain-name-servers      ns1.example.org;

+        option ip-forwarding            off;

+        option routers                  192.168.10.1;

+        option subnet-mask              255.255.255.0;

+        interface                       enx000ec6cbab91;

+        range                           192.168.10.32 192.168.10.254;

+}

+

# Hosts which require special configuration options can be listed in

# host statements.   If no address is specified, the address will be

# allocated dynamically (if possible), but the host-specific information

# will still come from the host declaration.

+host eval {

+        filename                        "Image";

+        fixed-address                   192.168.10.2;

+        hardware ethernet               00:14:2d:6f:07:22;

+        next-server                     192.168.10.1;

+        option host-name                "verdin";

+        option root-path                "192.168.10.1:/srv/nfs/rootfs,wsize=1024,rsize=1024,v3";

+}

+

#host passacaglia {

# hardware ethernet 0:0:c0:5d:bd:95;

# filename "vmunix.passacaglia";

---------------------------------------

// 配置文件中,开发主机上面和设备连接的网口名为 “enx000ec6cbab91”,需要根据你的实际网口名对应修改。

// 由于 Verdin iMX8MM U-Boot 环境变量中默认如下配置 IP Address 信息,因此这里将开发主机网口 IP Address 直接配置为 192.168.10.1,否则就需要对应修改设备 U-Boot 环境变量定义。

---------------------------------------

Verdin iMX8MM # print serverip

serverip=192.168.10.1

Verdin iMX8MM # print ipaddr

ipaddr=192.168.10.2

---------------------------------------

// host eval 部分配置用于后续 NFS 启动,其中 “hardware ethernet” 是你实际使用的 Verdin iMX8MM 网口的 MAC 地址。这里配置是对应 NFSv3 协议,如果是 NFSv4 可以参考这里配置,但是需要注意 DHCP 服务配置这里和下面 NFS 服务配置协议版本必须对应。

./启动 DHCP 服务,然后可以让 Verdin iMX8MM 模块通过 eMMC 正常启动后,查看网口 eth0 是否正常通过上面设置的 DHCP 服务器获取到 192.168.10.2 IP Address 来验证 DHCP 服务。

---------------------------------------

$ sudo service isc-dhcp-server start

---------------------------------------

c). 配置 TFTP 服务

./ 安装 TFTP Server

---------------------------------------

$ sudo apt-get install tftpd-hpa

---------------------------------------

./ 配置文件 /etc/default/tftpd-hpa 可以不做修改

---------------------------------------

TFTP_USERNAME="tftp"

TFTP_DIRECTORY="/srv/tftp"

TFTP_ADDRESS=":69"

TFTP_OPTIONS="--secure"

---------------------------------------

./复制 Verdin iMX8MM Linux Kernel Boot 文件到 TFTP 目录

---------------------------------------

$ cd/Verdin-iMX8MM_Reference-Minimal-Image-upstream-Tezi_6.4.0-devel-202309+build.14/

$ sudo tar Jxf Reference-Minimal-Image-upstream-verdin-imx8mm.bootfs.tar.xz -C /srv/tftp/

$ ls -al /srv/tftp/

总计 13312

drwxr-xr-x 3 root root     4096 92 00:35 .

drwxr-xr-x 4 root root     4096 1221 12:32 ..

-rw-r--r-- 1 root root     6010 92 00:35 boot.scr

-rw-r--r-- 1 root root 13211895 92 00:35 Image.gz

-rw-r--r-- 1 root root    62002 92 00:35 imx8mm-verdin-nonwifi-dahlia.dtb

-rw-r--r-- 1 root root    62246 92 00:35 imx8mm-verdin-nonwifi-dev.dtb

-rw-r--r-- 1 root root    62000 92 00:35 imx8mm-verdin-nonwifi-yavia.dtb

-rw-r--r-- 1 root root    62206 92 00:35 imx8mm-verdin-wifi-dahlia.dtb

-rw-r--r-- 1 root root    62446 92 00:35 imx8mm-verdin-wifi-dev.dtb

-rw-r--r-- 1 root root    62200 92 00:35 imx8mm-verdin-wifi-yavia.dtb

drwxr-xr-x 2 root root     4096 92 00:35 overlays

-rw-r--r-- 1 root root       47 92 00:35 overlays.txt

---------------------------------------

./启动 TFTP 服务,然后可以通过另外一台 Linux 主机通过安装 TFTP 客户端来测试下 TFTP 服务是否正确配置成功。

---------------------------------------

$ sudo service tftpd-hpa start

---------------------------------------

d). 配置 NFS 服务

./ 安装 NFS Server

---------------------------------------

$ sudo apt-get install nfs-kernel-server

---------------------------------------

./ NFSv3 配置文件,对应上面 DHCP host eval配置;如果是 NFSv4 配置,可以参考这里

---------------------------------------

#/etc/exports

/srv/nfs/rootfs 192.168.10.2(no_root_squash,no_subtree_check,rw)

---------------------------------------

./创建 NFS 文件目录,然后复制 Verdin iMX8MM Linux rootfs 文件到 NFS 目录

---------------------------------------

# create NFS folder

$ sudo mkdir -p /srv/nfs/rootfs

# copy Verdin iMX8MM rootfs to NFS folder

$ cd/Verdin-iMX8MM_Reference-Minimal-Image-upstream-Tezi_6.4.0-devel-202309+build.14/

$ sudo tar Jxf Reference-Minimal-Image-upstream-verdin-imx8mm.tar.xz -C /srv/nfs/rootfs

$ ls -al /srv/nfs/rootfs/

总计 72

drwxr-xr-x 18 root root 4096 39 2018 .

drwxr-xr-x 3 root root 4096 1221 12:32 ..

drwxr-xr-x 2 root root 4096 39 2018 bin

drwxr-xr-x 2 root root 4096 39 2018 boot

drwxr-xr-x 2 root root 4096 39 2018 dev

drwxr-xr-x 31 root root 4096 1221 12:43 etc

drwxr-xr-x 3 root root 4096 39 2018 home

drwxr-xr-x 9 root root 4096 39 2018 lib

drwxr-xr-x 4 root root 4096 1221 12:43 media

drwxr-xr-x 2 root root 4096 39 2018 mnt

dr-xr-xr-x 2 root root 4096 39 2018 proc

drwxr-xr-x 2 root root 4096 39 2018 run

drwxr-xr-x 2 root root 4096 39 2018 sbin

drwxr-xr-x 2 root root 4096 39 2018 srv

dr-xr-xr-x 2 root root 4096 39 2018 sys

drwxrwxrwt 2 root root 4096 39 2018 tmp

drwxr-xr-x 10 root root 4096 39 2018 usr

drwxr-xr-x 8 root root 4096 1221 12:43 var

---------------------------------------

./ 由于 Toradex Ycoto Linux 默认使用 connman 来管理网络,而在 NFS rootfs 加载过程中如果启动 connman,会导致网口重置,使得 NFS 服务中断无法启动成功,因此需要如下修改 rootfs 以规避这个问题。

---------------------------------------

--- a/lib/systemd/system/connman.service 2023-12-21 17:35:38.874742678 +0800

+++ b/lib/systemd/system/connman.service 2023-12-21 13:37:47.435149329 +0800

@@ -7,6 +7,7 @@

Before=network.target multi-user.target shutdown.target

Wants=network.target

Conflicts=systemd-resolved.service

+ConditionKernelCommandLine=!root=/dev/nfs

[Service]

Type=dbus

---------------------------------------

./启动 NFS 服务

---------------------------------------

$ sudo service nfs-kernel-server restart

---------------------------------------

./ Verdin iMX8MM Ycoto Linux 上面可以通过下面命令测试 NFS 服务是否配置成功

---------------------------------------

root@verdin-imx8mm-07276322:~# mount -t nfs -o vers=3 192.168.10.1:/srv/nfs/rootfs

---------------------------------------

4). Verdin iMX8MM 设备通过 TFTP/NFS 启动

a). Verdin iMX8MM 调试串口进入 U-Boot 命令行,执行下面命令即可完成 TFTP/NFS 启动

---------------------------------------

Verdin iMX8MM # run bootcmd_dhcp

---------------------

5). 总结

本文基于NXP iMX8MM嵌入式平台演示了 TFTP/NFS 启动示例。

参考文档

https://developer.toradex.cn/linux-bsp/application-development/how-to-setup-networking-for-embedded-linux-application-development/

https://developer.toradex.cn/linux-bsp/os-development/boot/boot-from-a-tftpnfs-server/

标签: 科技行业资讯

猜你喜欢