⚡ WSL2 搭建 s5p6818 Linux 嵌入式开发平台 (part 3):Wifi驱动移植、ssh移植、e2fsprogs移植

👁️‍🗨️ 1. 前期回顾

在上一篇文章中我们完成了系统运行的关键3个组成 U-Boot内核根文件系统的构建和部署,在这一篇章中我们将继续围绕s5p6818嵌入式开发平台的搭建,完成 Wifi 驱动的移植,SSH调试工具的移植,以及 e2fsprogs 磁盘管理工具的移植。

🌀 传送门:part 2


🔮 2. Wifi 驱动移植

在嵌入式设备开发中,通常会使用网线进行网络调试,比如通过网线搭建 NFS 网络文件系统 或使用 telnet / ssh 进行调试。

但是在 WSL2 系统下,由于其特殊性,无法直接识别物理网卡(有线/无线),除非使用 Windows 企业版 + Hyper-V。

因此在 WSL2 中无法像常规嵌入式环境那样搭建 NFS 或 telnet/ssh,只能依赖 PowerShell 自带的 ssh 工具 进行调试。

既然只能用 PowerShell 自带的 ssh 调试,就没有必要再拉一条网线了,直接使用 无线网络 进行网络调试反而更方便。反正无线网络迟早都要搭建。

现代网卡大多是都是免驱动的,但是我手里的这只是个超级绝版古董货,还需要移植驱动。

网卡厂家驱动的名字叫 MT7601 ,运行依赖以下四个工具/库:

  1. wireless_tools
    • 一组 Linux 下的无线网络配置工具(如 iwconfigiwlistiwpriv 等)。
    • 用于基础的无线网卡配置和调试。
  2. libnl
    • Netlink 通信库。
    • 提供用户态程序与内核进行网络相关通信的接口,是 wpa_supplicant 与内核交互的必备组件。
  3. OpenSSL
    • 通用加密库。
    • 提供 WPA/WPA2/WPA3 等协议所需的加密算法支持。
  4. wpa_supplicant
    • 无线安全认证工具。
    • 负责 WiFi 接入、身份验证和密钥管理,是整个无线网络连接的核心用户态程序。

在明确依赖之后,我们依次完成以下步骤:

  1. 移植 wireless_tools
  2. 构建 libnl
  3. 构建 OpenSSL
  4. 移植 wpa_supplicant
  5. 移植 MT7601
  6. 配置系统环境
  7. 编写开机启动脚本

🚪 2.1 移植 wireless_tools

将 wireless_toolls 源码包拷贝到合适的位置,并解压

bash 复制代码
mkdir -p /opt/project/wifi
cp wireless_tools.29.tar.gz /opt/project/wifi/
cd /opt/project/wifi/
tar -xvf wireless_tools.29.tar.gz

进入源码目录以后直接交叉编译

bash 复制代码
cd wireless_tools.29
make \
CC = arm-cortex_a9-linux-gnueabi-gcc \
AR = arm-cortex_a9-linux-gnueabi-ar \ 
RANLIB =arm-cortex_a9-linux-gnueabi-ranlib

编译完成后,将生成的二进制文件拷贝到根文件系统中

bash 复制代码
cp libiw.so.29 /opt/rootfs/lib/
cp iwconfig /opt/rootfs/bin
cp iwpriv /opt/rootfs/bin/
cp iwlist /opt/rootfs/bin/

至此,wireless_tools 移植完成。

🦠 2.2 构建 libnl

先将 libnl 库的源码包拷贝到合适的位置,并解压

bash 复制代码
cp  libnl-1.1.4.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf  libnl-1.1.4.tar.gz

进入源码目录后,删除旧库并配置编译参数

bash 复制代码
cd  libnl-1.1.4
rm lib/libnl.a
mkdir install
./configure --prefix=/opt/project/wifi/libnl/install

然后交叉编译并安装:

bash 复制代码
make \
CC=arm-cortex_a9-linux-gnueabi-gcc \
AR=arm-cortex_a9-linux-gnueabi-ar \
LD=arm-cortex_a9-linux-gnueabi-ld
make install

至此,libnl 库的构建已经完成。

💎 2.3 构建 OpenSSL

将 OpenSSL 库源码包拷贝到合适的位置,并解压

bash 复制代码
cp  openssl-1.0.1s.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf  openssl-1.0.1s.tar.gz

进入源码目录,配置编译参数

bash 复制代码
cd  openssl-1.0.1s
mkdir install
./Configure linux-armv4 \
--prefix=/opt/project/wifi/openssl-1.0.1s/install \
--cross-compile-prefix=arm-cortex_a9-linux-gnueabi- \
no-asm \
shared \

检查 Makefile 确认无误后进行交叉编译和安装

bash 复制代码
make 
make install 

至此,OpenSSL库的构建已经完成。

💰 2.4 移植 wpa_supplicant

将 wpa_supplicatn 源码包拷贝到合适的位置,并解压:

bash 复制代码
cp  wpa_supplicant-2.6.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf  wpa_supplicant-2.6.tar.gz

进入源码目录并复制.config文件

bash 复制代码
cd  wpa_supplicant-2.6/wpa_supplicant
cp defconfig .config

wpa_supplicant 的交叉编译依赖于已经构建完成的 libnl 和 openssl,所以我们需要修改.config 文件,在开头添加编译依赖路径

bash 复制代码
CC= arm-cortex_a9-linux-gnueabi-gcc -L/opt/project/wifi/libnl-1.1.4/install/lib -L/opt/project/wifi/openssl-1.0.1s/install/lib
CFLAGS += -I/opt/project/wifi/libnl-1.1.4/install/include -I/opt/project/wifi/openssl-1.0.1s/install/include
LIBS += -L/opt/project/wifi/libnl-1.1.4/install/lib -L/opt/project/wifi/openssl-1.0.1s/install/lib

然后修改 Makefile 将 wpa_cupplican 和 wpa_cli 的编译规则改成静态编译

⚠️ 注意:这里我直接修改 Makefile 是因为 wpa 这东西本身有BUG,wpa 的主程序交叉编译必须要静态编译而其他程序又必须动态编译,无论全局参数设置成动态还是静态都特么会报错,只能通过手动修改该 Makefile 解决这个问题。

然后进行交叉编译

bash 复制代码
make

编译完成后把生成的二进制文件拷贝到根文件系统中

bash 复制代码
cp wpa_supplicant /opt/rootfs/bin/
cp wpa_cli /opt/rootfs/bin/
cp wpa_passphrase /opt/rootfs/bin/

🔋 2.5 移植 MT7601

将驱动的源码包拷贝到合适的位置,并解压

bash 复制代码
cp DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2 /opt/project/wifi
cd /opt/project/wifi
tar -xvf DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2

进入到源码目录直接编译

bash 复制代码
make

⚠️ 注意:这里表面上看没有交叉编译,但实际上你打开他的 Makefile 会发现,这个驱动他会到 /opt/kernel 目录下去偷内核的交叉编译器。你内核用啥东西编的他就用啥编。而且由于是 超级绝版古董货 配套的驱动,所以只能偷 3.10 版本以下的内核,你内核版本高了它看不懂偷不动直接给你弹报错。

完成编译以后把生成文件拷贝到根文件系统

bash 复制代码
mkdir -p /opt/rootfs/home/drivers
mkdir -p /opt/rootfs/etc/Wireless/RT2870STA
cp os/linux/mt7601Usta.ko /opt/rootfs/home/drivers
cp RT2870STA.dat /opt/rootfs/etc/Wireless/RT2870STA

至此,MT7601 驱动移植已经完成。

💠 2.6 配置系统环境

在完成所有软件的构建和移植后,我们还需要再根文件系统中添加一些配置文件。首先是 wpa_cupplicant.config 配置文件。

bash 复制代码
vim /opt/rootfs/etc/wpa_supplicant.conf

在文件中添加以下内容:

vim 复制代码
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="AitaV" #热点名称
scan_ssid=1
key_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE
pairwise=TKIP CCMP
group=CCMP TKIP WEP104 WEP40
psk="123456" #密码
}

然后创建 default.script 文件

bash 复制代码
mkdir /opt/rootfs/usr/share/udhcpc/ -p
vim /opt/rootfs/usr/share/udhcpc/default.script

在文件中添加以下内容:

bash 复制代码
#!/bin/sh

# udhcpc script edited by Tim Riker <Tim@Rikers.org>

[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

RESOLV_CONF="/etc/resolv.conf"
[ -e $RESOLV_CONF ] || touch $RESOLV_CONF
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"

case "$1" in
	deconfig)
		/sbin/ifconfig $interface up
		/sbin/ifconfig $interface 0.0.0.0

		# drop info from this interface
		# resolv.conf may be a symlink to /tmp/, so take care
		TMPFILE=$(mktemp)
		grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE
		cat $TMPFILE > $RESOLV_CONF
		rm -f $TMPFILE

		if [ -x /usr/sbin/avahi-autoipd ]; then
			/usr/sbin/avahi-autoipd -k $interface
		fi
		;;

	leasefail|nak)
		if [ -x /usr/sbin/avahi-autoipd ]; then
			/usr/sbin/avahi-autoipd -wD $interface --no-chroot
		fi
		;;

	renew|bound)
		if [ -x /usr/sbin/avahi-autoipd ]; then
			/usr/sbin/avahi-autoipd -k $interface
		fi
		/sbin/ifconfig $interface $ip $BROADCAST $NETMASK

		if [ -n "$router" ] ; then
			echo "deleting routers"
			while route del default gw 0.0.0.0 dev $interface 2> /dev/null; do
				:
			done

			for i in $router ; do
				route add default gw $i dev $interface
			done
		fi

		# drop info from this interface
		# resolv.conf may be a symlink to /tmp/, so take care
		TMPFILE=$(mktemp)
		grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILE
		cat $TMPFILE > $RESOLV_CONF
		rm -f $TMPFILE

		[ -n "$domain" ] && echo "search $domain # $interface" >> $RESOLV_CONF
		for i in $dns ; do
			echo adding dns $i
			echo "nameserver $i # $interface" >> $RESOLV_CONF
		done
		;;
esac

HOOK_DIR="$0.d"
for hook in "${HOOK_DIR}/"*; do
    [ -f "${hook}" -a -x "${hook}" ] || continue
    "${hook}" "${@}"
done

exit 0

不用在乎这个脚本写的是什么,直接复制粘贴就行了(反正也不是我写的),这个脚本的主要功能就是

  • 释放 IP
  • 处理 DHCP 失效
  • 管理 avahi 自动分配本地 IP
  • 配置网卡、 IP 路由、DNS
  • 调用额外 hook 脚本扩展功能

然后给这个脚本赋予可执行权限

bash 复制代码
chmod 777 /opt/rootfs/usr/share/udhcpc/default.script

然后添加 hosts 文件

bash 复制代码
echo "127.0.0..1 localhost" > /opt/rootfs/etc/hosts

然后添加 resolv.conf 文件

bash 复制代码
mkdir /opt/rootfs/tmp
touch /opt/rootfs/etc/resolv.conf
echo "nameserver 114.114.114.114" > /opt/rootfs/etc/resolv.conf
echo "nameserver 8.8.8.8" >> /opt/rootfs/etc/resolv.conf

然后将wpa运行所需的动态库全部拷贝到 /opt/rootfs/lib目录下

bash 复制代码
cp -a /opt/toolchains/arm-cortex_a9-linux-gnueabi/sysroot/lib/* /opt/rootfs/lib/

然后参考本系列 part 2 系统构建和部署的流程,将根文件系统打包成镜像,烧写到单板上。

至此,Wifi 运行所需的系统环境已经配置完成

🔔 6.8 单板调试

完成以上一系列操作以后,可以通过 kermit 串口调试进入单板系统,依次执行以下命令进行调试

bash 复制代码
echo 4 > /proc/sys/kernel/printk
insmod /home/drivers/mt7601Usta.ko
mkdir /var/run
wpa_supplicant -B -d -Dwext -ira0 -c /etc/wpa_supplicant.conf
udhcpc -i ra0 
ifconfig  
ping www.baidu.com  

如果能ping 通百度,就说明Wifi驱动移植成功了


❤️ 3. SSH移植

SSH 我就不介绍了,我们的老熟人,平时无论是工作,还是工作之余自己 DIY 都少不了它的身影。

但是会用 SSH 和会装 SSH 完全就是两码事。往单板上装这个 SSH 难度,可以说是在用 SSH 的 十倍 以上。你在装的过程中会吃到各种 狂暴BUFF怒气BUFF ,并且血压直接 MAX ,有的甚至会出现卡了几天还没有移植成功就差一拳打爆电脑的情况(本文就是专门为这种人准备的!)。

CSDN 上虽然也有很多 SSH 移植相关的博客,但是由于 SSH 调试工具版本有高有底,再加上移植的目标平台多种多样,一般很难复现。

本文虽然不能保证一定能够复现,但是会尽可能详细的解析 SSH 交叉编译的机制,以及 SSH 移植的思路。引导读者举一反三,尽可能的提高 SSH 移植的成功率。

首先需要说明,虽然在 Ubuntu 和 Debian 这类高级 Linux 系统中都是自带 SSH 的,但是在 busybox 制作的简易版 Linux 系统上默认是没有 SSH 的,这也是我这里需要移植 SSH 的主要原因。

SSH 移植的过程主要分为:

  1. 构建 zlib 库
  2. 构建 OpenSSL 库
  3. OpenSSH 移植
  4. 配置系统环境
  5. 单板调试

🎵 3.1 构建 zlib 库

SSH 的运行依赖 zlib 库,所以我们要交叉编译构建 zlib 库

将 zlib 源码包拷贝到合适的位置,并解压

bash 复制代码
mkdir -p /opt/project/ssh
cp zlib-1.3.1.tar.gz /opt/project/ssh/
cd /opt/project/ssh
tar -xvf zlib-1.3.1.tar.gz

然后进入zlib目录,创建安装目录,

bash 复制代码
cd zlib-1.3.1
mkdir install

然后设置交叉编译环境并配置

bash 复制代码
CC=arm-cortex_a9-linux-gnueabi-gcc \
AR=arm-cortex_a9-linux-gnueabi-ar \
RANLIB=arm-cortex_a9-linux-gnueabi-ranlib \
LD=arm-cortex_a9-linux-gnueabi-ld
./configure --prefix=/opt/project/ssh/zlib-1.3.1/install 

⚠️ 注意:这里 --prefix 设置的是 zlib 库的安装目录,最好把这个目录和 OpenSSL 的安装目录分开不要放在一起,防止有的目录被覆盖导致库文件的路径不对,影响后续的 OpenSSH 编译。

然后检查 Makefile 文件,确认无误后交叉编译并安装

bash 复制代码
make
make install

⚠️ 注意:这里有一点很坑的地方就是交叉编译工具链的环境变量必须在./configure之前设置,如果执行了./configure无论你是改Makefile、export导入环境变量还是在make的时候带入环境变量,都会编译失败

最后查看安装目录确认生成目标文件

⚠️ 注意:经过我后期各种测试,zlib 的版本好像不会对 OpenSSH 编译是否成功造成影响。也就是说无论你的 OpenSSH 是什么版本,都可以放心大胆地选择用最新版本的 zlib 源码来构建 zlib 库

至此 zlib 库已经构建完成

🎶 3.2 构建 OpenSSL 库

SSH 的运行依赖 OpenSSL 库,但是我们在上一节 Wifi 驱动移植的过程中已经构建了 OpenSSL 库了,所以这里只要把上一节构建的 OpenSSL 库拷贝到合适的位置就行了。

bash 复制代码
cp /opt/project/wifi/openssl-1.0.1s /opt/project/ssh

⚠️ 注意:这里 OpenSSL 库的版本会直接影响 OpenSSH 编译是否成功。OpenSSH8.0 以上版本必须使用 OpenSSL1.1.0 以上版本构建的 OpenSSL 库;OpenSSH8.0 以下版本必须使用 OpenSSL 1.1.0 以下版本构建的 OpenSSL 库。这里我选用的是 OpenSSH7.6 和 OpenSSL1.0.1。

🔊 3.3 移植 OpenSSH

将 openssh 的源码包拷贝到合适的位置,并解压

bash 复制代码
cp openssh-7.6p1.tar.gz /opt/project/ssh
tar -xvf openssh-7.6p1.tar.gz

然后进入源码目录并配置交叉编译环境

bash 复制代码
CC=arm-cortex_a9-linux-gnueabi-gcc \
AR=arm-cortex_a9-linux-gnueabi-ar \
RANLIB=arm-cortex_a9-linux-gnueabi-ranlib \
NM=arm-cortex_a9-linux-gnueabi-nm \
./configure \
--host=arm-linux \
--with-zlib=/opt/project/ssh/zlib-1.3.1/install \
--with-ssl-dir=/opt/project/ssh/openssl-1.0.1s \

⚠️ 注意: 这里的 --with-zlib--with-ssl-dir设置的参数分别对应的是构建 zlib 库时配置交叉编译环境的 --prefix 和构建 OpenSSL 库时配置检查交叉编译环境的 --prefix 这两个参数。也就是交叉编译完成后这两个库的安装目录
⚠️ 注意:OpenSSH 和 zlib 一样,需要在 configure 前设置交叉编译工具链。否则就会报错。
⚠️ 注意:我这里用的是动态编译,后期需要将 zlib 的动态库和 OpenSSl 的动态库拷贝到单板上才能运行 SSH。理论上SSH是可以静态编译的,只要在配置交叉编译环境的时候能找到 zlib 和 Open SSL 的静态库,然后再添加 LDFLAGS=-static 就行。如果有勇气不怕踩坑的同志可以试一试,如果到时候成功了记得发个博客,给我分享个链接。

配置成功以后会输出如下信息:

检查 Makefile 文件,确认无误执行 make 命令编译

bash 复制代码
make

编译完成后,检查当前目录下是否生成以下目标文件:

这些目标文件最终需要放到单板上的相应目录下,具体位置如下图所示

⚠️ 注意:这些目标文件再单板上的位置都是 SSH 的给我们设置的默认位置,也就是你在 ./confiugre 配置交叉编译环境的时候,SSH 给我们自动配好的,SSH 再运行的时候回到这些位置里找相应的程序或者配置文件,找不到就会报错。如果要修改这些目标文件再单板上的位置,需要再 ./configure 的时候添加特殊的参数。

但是再这里我们无法直接拷贝到单板上,只能通过拷贝到根文件系统,然后将根文件系统打包成镜像烧录到单板上的方法来完成移植。

所以执行以下命令将这些目标文件拷贝到根文件系统的相应位置。

bash 复制代码
cp sshd /opt/rootfs/usr/sbin
cp ssh-agent ssh-add ssh-keyscan ssh-keygen /opt/rootfs/usr/local/bin
cp sshd_config ssh_config /opt/rootfs/usr/local/etc
cp sftp-server ssh-keysign /opt/rootfs/usr/local/libexec 

顺便再把 zlib 和 OpenSSL 的动态库也拷贝到根文件系统的相应位置

bash 复制代码
cp /opt/project/ssh/zlib--1.3.1/install/lib/libz.so* /opt/rootfs/usr/lib
cp /opt/project/ssh/openssl-1.0.1s/install/lib/libcrypto.so* /opt/rootfs/usr/lib
cp /opt/project/ssh/openssl-1.0.1s/install/lib/libssl.so* /opt/rootfs/usr/lib

🏆 3.4 配置系统环境

编辑 /opt/rootfs/usr/local/etc/sshd_config,去掉 PermitRootLogin 前面的注释符号,并将 PermitRootLogin 后面的 no 改为 yes,这样用户就可以用 root 权限登录 SSH 进行调试了。

然后创建 /opt/rootfs/etc/passwd 文件

bash 复制代码
vim /opt/rootfs/etc/passwd

并往其中写入以下内容创建 root 用户和 sshd 用户

vim 复制代码
root:oFQHytKkHIp6c:0:0:root:/:/bin/sh
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin

然后再创建必要的临时文件

bash 复制代码
mkdir -p /var/empty
chmod 755 /var/empty
chown root:root /var/empty

然后参考本系列 part 2 系统构建和部署的流程,将根文件系统打包成镜像,烧写到单板上。

至此,SSH 运行所需的系统环境已经配置完成

🎽 3.5 单板调试

完成以上一系列操作以后,可以通过 kermit 串口调试进入单板系统,进行 SSH 调试

先在单板上执行命令创建密钥

bash 复制代码
ssh-keygen -A

出现如下信息说明成功生成密钥

bash 复制代码
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519

然后启动 ssh 服务

bash 复制代码
/usr/sbin/sshd -D

然后打开一个 powershell 终端,利用ssh链接单板,链接成功后查看目录以及其他单板信息,确认是否能正常显示

如果一切都正常,那么恭喜你,终于完成了 SSH 的移植。

现在,你可以拔掉插在 PC 上的 USB 转 OTG 线和 USB 转 串口线了。因为你要移植软件到单板上已经不需要打包烧录根文件系统了,只需要用 scp 命令网络传输就行了,而且你也不需要进行串口调试了,只需要用 ssh 网络调试就行了。


🎻 4. e2fsprogs 移植

在嵌入式开发中,e2fsprogs 是一款常用的文件系统工具,主要用于 分区扩容 或 创建新分区。

我们的 s5p6818 开发板自带 8GB 存储,但实际烧写的根文件系统分区只有 200MB,大量空间无法使用。而系统内置的 busybox 工具又不具备完整的磁盘分区与扩容能力,因此需要移植 e2fsprogs 到单板上,借助其中的 resize2fs 来完成根文件系统扩容。

🧩 4.1 交叉编译 e2fsprogs

首先将e2fsprogs的源码拷贝到指定目录,并解压

bash 复制代码
mkdir -p /opt/project/fs
cp e2fsprogs-1.47.3.tar.gz /opt/project/fs 
tar -xvf e2fsprogs-1.47.3.tar.gz

然后进入目录执行./configure ,生成适配交叉编译的Makefile

bash 复制代码
cd e2fsprogs-1.47.3
CC=arm-cortex_a9-linux-gnueabi-gcc \
LDFLAGS=-static \
./configure --host=arm-linux

然后编译并生成目标文件

bash 复制代码
make

编译完成以后检查是否成功生成了目标文件

随后将 resize2fs 通过 PowerShell 的 scp/ssh 拷贝到开发板 /sbin 目录,供后续扩容使用。

🎼 4.2 调整分区表

完成以上操作以后,我们可以通过 powershell 的 ssh 链接单板进行根文件系统的扩容操作

首先在单板上通过 busybox 的 fdisk 查看分区信息,记录根文件系统分区(/dev/mmcblk0p2)的起始扇区:

bash 复制代码
fdisk -u -l /dev/mmcblk0

接着你会看到如下输出:

这里可以看到 mmcblk0p2 的起始扇区是133120

⚠️ 注意:这里记录的是扇区sector不是柱面区cylinder,一般来说 mmcblk0p1 是系统内核,mmcblk0p2 是根文件系统

接下来使用 fdisk 删除并重建分区(必须指定相同的起始扇区,否则数据会丢失):

bash 复制代码
fdisk -u /dev/mmcblk0

然后在 fdisk 交互界面里依次执行:

  • p -> 打印当前分区表(确认)
  • d -> 删除分区
  • 2 -> 删除序号为2的分区
  • n -> 新建分区
  • p -> 分区类型为 primary
  • 2 -> 分区的序号为2
  • enter or type start sector -> 输入之前记录的 start 值(不要按回车用默认)
  • enter -> 按回车用默认值(即扩展到剩余全部空间)
  • p -> 再次打印确认起始扇区与结束是否正确
  • w -> 写入并退出

完成之后重启单板,用 fdisk -u -l 再次查看,可以看到分区已经被扩展

🎨 4.3 使用 resize2fs 扩容文件系统

分区表扩展完成后,还需要调整文件系统大小:

bash 复制代码
resize2fs /dev/mmcblk0p2

执行成功后,再次查看磁盘使用情况:

bash 复制代码
df -h

可以看到根文件系统空间已经从原来的 200MB 扩展到 7GB+:

至此,至此,根文件系统扩容完成。单板上最基本的开发环境已经搭建好,不管是后续驱动调试(insmod/重新编译内核),还是应用软件移植(通过 SSH 传输部署),都无需重新制作 rootfs,大幅提高了开发效率。


💣 5. 问题与解决方案

🍉 5.1 zlib 编译失败

在 zlib 编译的时候出现以下报错:

这个报错主要的原因是交叉编译的环境变量没有配置好,导致一部分编译工具链使用了宿主机内置编译器的,另一部分使用了交叉编译器的。

而交叉编译的环境变量没有配好,大概率是由于没有在 ./configure 之前设置环境变量导致的。zlib 这个开源项目需要在 ./configure 前就把所有交叉编译环境变量全部设置后,在 ./configure 之后设置的交叉编译环境变量会被无视。

所以解决方案就是将环境变量在 ./configure 之前导入,然后再重新 ./configure 一次,然后再进行编译。

🍓 5.2 OpenSSH 配置交叉编译参数时报错找不到文件

如果你在进行 OpenSSH 的 ./configure 操作时候,出现以下报错:

或者是以下报错:

这个就非常恶心了。

因为你会发现它报错信息提到的这个文件它确实是存在的,但是 OpenSSH 它就是找不到。你死都不会想到他是因为你交叉编译环境没有设置好导致的。

OpenSSH 和 zlib 库一样需要在 ./configure 前设置交叉编译环境变量。如果你没有设置或者在后面设置他就直接无视,并且给你报这种找不到文件的错。

所以解决方法也和 zlib 的那个问题一样,在 ./configure 前设置交叉编译环境变量,重新 ./configure ,重新编译

🍊 5.3 OpenSSH 依赖路径冲突编译报错

OpenSSH 在 ./configure 的时候报错找不到 libcrypto 库的错,还有一种可能,就是你把 zlib 的安装目录和 OpenSSL 的安装目录写在一起了,两个依赖都往同一个目录里安装文件导致路径相互覆盖,OpenSSH 在检查依赖的时候因为路径混乱找不到了所以就报错了

这种情况的解决方法就是把 zlib 和 OpenSSL 的安装目录给分开,各自装各自的程序和库,然后 OpenSSH 在 ./configure 的时候给他两个路径。这样就不会出现依赖路径冲突导致的找不到库的报错了。

🍋 5.4 OpenSSH 版本不兼容报错

如果 OpenSSH 在编译的时候报错说需要 OpenSSL 的版本大于1.1.1 那大概率就是你用了 8.0 版本以上的 OpenSSH 和 1.1.0 版本以下的 OpenSSL了

解决方法就是要么都用最新的 OpenSSH 和 OpenSSL ,要么都用最老的 OpenSSH 和 OpenSSL。

🍎 5.5 单板上运行 ssh-keygen 奔溃

如果你在单板上运行 ssh-keygen 的时候程序崩溃了并出现了以下信息:

那大概率是因为你编译时选择的目标架构和你的单板不兼容。我用的 s5p6818 单板对应的架构是 linux-armv4 或 arm-linux 。所以在对 OpenSSH 和 OpenSSL 进行 ./configure 操作的时候 --host 参数的值就是这两个之一。

这个问题的解决方案,首先需要你搞清楚你用的单板是什么架构的,然后根据架构,在 ./configure的时候给 --host 赋予相应的值。再重新编译一次 OpenSSL 和 OpenSSH ,把编译出来的程序烧录到单板上再调试。

🍅 5.6 SSH 运行时目录缺失

如果你在单板上跑 sshd 程序的时候出现以下信息:

这就表示 SSH 运行时的 privilege separation 目录缺失,sshd 跑不起来了

在 OpenSSH 里,/var/empty 是一个安全沙箱目录,启动时 sshd 会把非特权子进程 chroot 到这里运行。

所以要解决这个问题,只要创建相应的目录就行了

bash 复制代码
mkdir -p /var/empty
chmod 755 /var/empty
chown root:root /var/empty

🍆 5.7 SSH链接失败

如果你在 powershell 中用 SSH 链接结果出现以下报错:

这种情况是单板上密钥更新了但是 powershell 没更新导致的

要解决这个问题需要在 powershell 上跟新密钥

powershell 复制代码
ssh-keygen -R 192.168.10.29

这里我单板的 IP 是 192.168.10.29

更新完成后重新链接这个 IP ,在弹出的提示中输入 yes 按回车,输入 SSH 链接密码,然后就能成功进入 SSH 调试了。

🥭 5.8 e2fsprogs 编译时找不到 subst 文件

如果你在 e2fsprogs 交叉编译的时候出现以下报错:

这个情况是引入了多余的环境变量 LD 和 AR 导致目录混乱找不到文件导致的

解决方法就是去掉交叉编译环境变量 LD 和 AR,再重新编译。e2fsprogs 交叉编译只需要引入 CC 和 LDFLAGS 这两个环境变量就够了。

🍍 5.9 e2fsprogs 编译 fatal error

如果你在 e2fsprogs 交叉编译的时候出现了 fatal error

那么这种情况可能是你在 .configure 的时候没有引入环境变量,而在make的时候引入环境变量导致的。

e2fsprogs 和 zlib 还有 OpenSSH 一样都对环境变量引入的时机较为敏感,必须再 ./configure 之前引入交叉编译的环境变量。

所以这个问题的解决方法就是在 ./configure 之前引入交叉编译的环境变量,然后再重新编译一次。


🍭 6. 结语

本系列总共分为 3 部分,介绍了在 WSL2 环境中,从零开始搭建 s5p6818 Linux 嵌入式开发平台,直到最后能利用无线网络进行 SSH 调试为止的所有过程。包括:

在 part1 讲了架构思路,以及WSL的安装和配置;

在 part2 讲了如何制作 U-Boot ,内核, 根文件系统,如何把他们烧录到单板上,以及如何用串口和OTG口进行调试

在 part3 也就是本篇中讲了如何在单板上移植 Wifi 驱动搭建 Wifi 网络,如何移植 SSH 调试工具,利用 Wifi 网络进行调试,以及如何利用 e2fsprogs 给根文件系统扩容,使 EMMC 能充分利用起来

至此,单板上最基本的开发环境已经搭建好,不管是后续驱动调试(insmod/重新编译内核),还是应用软件移植(通过 SSH 传输部署),都可以顺畅的进行下去。

也许你用的不是 s5p6818 这块单板,但是这些构建系统,部署系统,搭建调试网络的方法,一定能够对你有所帮助。

最后感谢您完整的看完了本系列的所有内容。

相关推荐
南枝异客4 小时前
CentOS 7 网络连接问题
linux·运维·centos
牛奶咖啡135 小时前
实现Linux的ssh免密登录实操保姆级教程
linux·ssh·生成ssh密钥对的三种方法·添加公钥到需ssh免登录服务器·测试ssh免登录的服务器·生产环境linux的优化策略
zhangrelay6 小时前
操作系统全解析:Windows、macOS与Linux的深度对比与选择指南(AI)
linux·笔记·学习
阿方索7 小时前
Linux 正则表达式
linux·运维
金色熊族8 小时前
ubuntu20.04编译qt源码5.15.3
linux·c++·qt
zhaotiannuo_19989 小时前
【Linux CentOS 7 版本更换yum源】
linux
aitav09 小时前
⚡ WSL2 搭建 s5p6818 Linux 嵌入式开发平台(part 1):环境准备与架构设计
linux·嵌入式·wsl·wsl2
一袋米扛几楼9810 小时前
【软件安全】fgets / strncpy / gets(不安全) / snprintf的对比
linux·服务器·安全
防搞活机11 小时前
ubuntu 服务器(带NVLink)更新显卡驱动 (巨坑!!)
linux·服务器·深度学习·ubuntu·gpu算力·显卡驱动