⚡ 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 ,运行依赖以下四个工具/库:
- wireless_tools
- 一组 Linux 下的无线网络配置工具(如
iwconfig
、iwlist
、iwpriv
等)。 - 用于基础的无线网卡配置和调试。
- 一组 Linux 下的无线网络配置工具(如
- libnl
- Netlink 通信库。
- 提供用户态程序与内核进行网络相关通信的接口,是 wpa_supplicant 与内核交互的必备组件。
- OpenSSL
- 通用加密库。
- 提供 WPA/WPA2/WPA3 等协议所需的加密算法支持。
- wpa_supplicant
- 无线安全认证工具。
- 负责 WiFi 接入、身份验证和密钥管理,是整个无线网络连接的核心用户态程序。
在明确依赖之后,我们依次完成以下步骤:
- 移植 wireless_tools
- 构建 libnl
- 构建 OpenSSL
- 移植 wpa_supplicant
- 移植 MT7601
- 配置系统环境
- 编写开机启动脚本
🚪 2.1 移植 wireless_tools
将 wireless_toolls 源码包拷贝到合适的位置,并解压
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
进入源码目录以后直接交叉编译
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
编译完成后,将生成的二进制文件拷贝到根文件系统中
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 库的源码包拷贝到合适的位置,并解压
cp libnl-1.1.4.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf libnl-1.1.4.tar.gz
进入源码目录后,删除旧库并配置编译参数
cd libnl-1.1.4
rm lib/libnl.a
mkdir install
./configure --prefix=/opt/project/wifi/libnl/install
然后交叉编译并安装:
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 库源码包拷贝到合适的位置,并解压
cp openssl-1.0.1s.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf openssl-1.0.1s.tar.gz
进入源码目录,配置编译参数
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 确认无误后进行交叉编译和安装
make
make install
至此,OpenSSL库的构建已经完成。
💰 2.4 移植 wpa_supplicant
将 wpa_supplicatn 源码包拷贝到合适的位置,并解压:
cp wpa_supplicant-2.6.tar.gz /opt/project/wifi
cd /opt/project/wifi/
tar -xvf wpa_supplicant-2.6.tar.gz
进入源码目录并复制.config文件
cd wpa_supplicant-2.6/wpa_supplicant
cp defconfig .config
wpa_supplicant 的交叉编译依赖于已经构建完成的 libnl 和 openssl,所以我们需要修改.config 文件,添加编译依赖路径
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 解决这个问题。
然后进行交叉编译
make
编译完成后把生成的二进制文件拷贝到根文件系统中
cp wpa_supplicant /opt/rootfs/bin/
cp wpa_cli /opt/rootfs/bin/
cp wpa_passphrase /opt/rootfs/bin/
🔋 2.5 移植 MT7601
将驱动的源码包拷贝到合适的位置,并解压
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
进入到源码目录直接编译
make
⚠️ 注意:这里表面上看没有交叉编译,但实际上你打开他的 Makefile 会发现,这个驱动他会到 /opt/kernel 目录下去偷内核的交叉编译器。你内核用啥东西编的他就用啥编。而且由于是 超级绝版古董货 配套的驱动,所以只能偷 3.10 版本以下的内核,你内核版本高了它看不懂偷不动直接给你弹报错。
完成编译以后把生成文件拷贝到根文件系统
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 配置文件。
vim /opt/rootfs/etc/wpa_supplicant.conf
在文件中添加以下内容:
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 文件
mkdir /opt/rootfs/usr/share/udhcpc/ -p
vim /opt/rootfs/usr/share/udhcpc/default.script
在文件中添加以下内容:
#!/bin/sh# udhcpc script edited by Tim Riker <Tim@Rikers.org>[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1RESOLV_CONF="/etc/resolv.conf"
[ -e $RESOLV_CONF ] || touch $RESOLV_CONF
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"case "$1" indeconfig)/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 careTMPFILE=$(mktemp)grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILEcat $TMPFILE > $RESOLV_CONFrm -f $TMPFILEif [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -k $interfacefi;;leasefail|nak)if [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -wD $interface --no-chrootfi;;renew|bound)if [ -x /usr/sbin/avahi-autoipd ]; then/usr/sbin/avahi-autoipd -k $interfacefi/sbin/ifconfig $interface $ip $BROADCAST $NETMASKif [ -n "$router" ] ; thenecho "deleting routers"while route del default gw 0.0.0.0 dev $interface 2> /dev/null; do:donefor i in $router ; doroute add default gw $i dev $interfacedonefi# drop info from this interface# resolv.conf may be a symlink to /tmp/, so take careTMPFILE=$(mktemp)grep -vE "# $interface\$" $RESOLV_CONF > $TMPFILEcat $TMPFILE > $RESOLV_CONFrm -f $TMPFILE[ -n "$domain" ] && echo "search $domain # $interface" >> $RESOLV_CONFfor i in $dns ; doecho adding dns $iecho "nameserver $i # $interface" >> $RESOLV_CONFdone;;
esacHOOK_DIR="$0.d"
for hook in "${HOOK_DIR}/"*; do[ -f "${hook}" -a -x "${hook}" ] || continue"${hook}" "${@}"
doneexit 0
不用在乎这个脚本写的是什么,直接复制粘贴就行了(反正也不是我写的),这个脚本的主要功能就是
- 释放 IP
- 处理 DHCP 失效
- 管理 avahi 自动分配本地 IP
- 配置网卡、 IP 路由、DNS
- 调用额外 hook 脚本扩展功能
然后给这个脚本赋予可执行权限
chmod 777 /opt/rootfs/usr/share/udhcpc/default.script
然后添加 hosts 文件
echo "127.0.0..1 localhost" > /opt/rootfs/etc/hosts
然后添加 resolv.conf 文件
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目录下
cp -a /opt/toolchains/arm-cortex_a9-linux-gnueabi/sysroot/lib/* /opt/rootfs/lib/
然后参考本系列 part 2 系统构建和部署的流程,将根文件系统打包成镜像,烧写到单板上。
至此,Wifi 运行所需的系统环境已经配置完成
🔔 6.8 单板调试
完成以上一系列操作以后,可以通过 kermit 串口调试进入单板系统,依次执行以下命令进行调试
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 移植的过程主要分为:
- 构建 zlib 库
- 构建 OpenSSL 库
- OpenSSH 移植
- 配置系统环境
- 单板调试
🎵 3.1 构建 zlib 库
SSH 的运行依赖 zlib 库,所以我们要交叉编译构建 zlib 库
将 zlib 源码包拷贝到合适的位置,并解压
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目录,创建安装目录,
cd zlib-1.3.1
mkdir install
然后设置交叉编译环境并配置
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 文件,确认无误后交叉编译并安装
make
make install
⚠️ 注意:这里有一点很坑的地方就是交叉编译工具链的环境变量必须在./configure之前设置,如果执行了./configure无论你是改Makefile、export导入环境变量还是在make的时候带入环境变量,都会编译失败
最后查看安装目录确认生成目标文件
⚠️ 注意:经过我后期各种测试,zlib 的版本好像不会对 OpenSSH 编译是否成功造成影响。也就是说无论你的 OpenSSH 是什么版本,都可以放心大胆地选择用最新版本的 zlib 源码来构建 zlib 库
至此 zlib 库已经构建完成
🎶 3.2 构建 OpenSSL 库
SSH 的运行依赖 OpenSSL 库,但是我们在上一节 Wifi 驱动移植的过程中已经构建了 OpenSSL 库了,所以这里只要把上一节构建的 OpenSSL 库拷贝到合适的位置就行了。
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 的源码包拷贝到合适的位置,并解压
cp openssh-7.6p1.tar.gz /opt/project/ssh
tar -xvf openssh-7.6p1.tar.gz
然后进入源码目录并配置交叉编译环境
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 和 OpenSSL 一样,需要在 configure 前设置交叉编译工具链。否则就会报错。
⚠️ 注意:我这里用的是动态编译,后期需要将 zlib 的动态库和 OpenSSl 的动态库拷贝到单板上才能运行 SSH。理论上SSH是可以静态编译的,只要在配置交叉编译环境的时候能找到 zlib 和 Open SSL 的静态库,然后再添加
LDFLAGS=-static
就行。如果有勇气不怕踩坑的同志可以试一试,如果到时候成功了记得发个博客,给我分享个链接。
配置成功以后会输出如下信息:
检查 Makefile 文件,确认无误执行 make 命令编译
make
编译完成后,检查当前目录下是否生成以下目标文件:
这些目标文件最终需要放到单板上的相应目录下,具体位置如下图所示
⚠️ 注意:这些目标文件再单板上的位置都是 SSH 的给我们设置的默认位置,也就是你在
./confiugre
配置交叉编译环境的时候,SSH 给我们自动配好的,SSH 再运行的时候回到这些位置里找相应的程序或者配置文件,找不到就会报错。如果要修改这些目标文件再单板上的位置,需要再./configure
的时候添加特殊的参数。
但是再这里我们无法直接拷贝到单板上,只能通过拷贝到根文件系统,然后将根文件系统打包成镜像烧录到单板上的方法来完成移植。
所以执行以下命令将这些目标文件拷贝到根文件系统的相应位置。
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
🏆 3.4 配置系统环境
编辑 /opt/rootfs/usr/local/etc/sshd_config
,去掉 PermitRootLogin 前面的注释符号,并将 PermitRootLogin 后面的 no 改为 yes,这样用户就可以用 root 权限登录 SSH 进行调试了。
然后创建 /opt/rootfs/etc/passwd
文件
vim /opt/rootfs/etc/passwd
并往其中写入以下内容创建 root 用户和 sshd 用户
root:oFQHytKkHIp6c:0:0:root:/:/bin/sh
sshd:x:110:65534::/var/run/sshd:/usr/sbin/nologin
然后再创建必要的临时文件
mkdir -p /var/empty
chmod 755 /var/empty
chown root:root /var/empty
然后参考本系列 part 2 系统构建和部署的流程,将根文件系统打包成镜像,烧写到单板上。
至此,SSH 运行所需的系统环境已经配置完成
🎽 3.5 单板调试
完成以上一系列操作以后,可以通过 kermit 串口调试进入单板系统,进行 SSH 调试
先在单板上执行命令创建密钥
ssh-keygen -A
出现如下信息说明成功生成密钥
ssh-keygen: generating new host keys: RSA DSA ECDSA ED25519
然后启动 ssh 服务
/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的源码拷贝到指定目录,并解压
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
cd e2fsprogs-1.47.3
CC=arm-cortex_a9-linux-gnueabi-gcc \
LDFLAGS=-static \
./configure --host=arm-linux
然后编译并生成目标文件
make
编译完成以后检查是否成功生成了目标文件
随后将 resize2fs 通过 PowerShell 的 scp/ssh 拷贝到开发板 /sbin
目录,供后续扩容使用。
🎼 4.2 调整分区表
完成以上操作以后,我们可以通过 powershell 的 ssh 链接单板进行根文件系统的扩容操作
首先在单板上通过 busybox 的 fdisk 查看分区信息,记录根文件系统分区(/dev/mmcblk0p2)的起始扇区:
fdisk -u -l /dev/mmcblk0
接着你会看到如下输出:
这里可以看到 mmcblk0p2 的起始扇区是133120
⚠️ 注意:这里记录的是扇区sector不是柱面区cylinder,一般来说 mmcblk0p1 是系统内核,mmcblk0p2 是根文件系统
接下来使用 fdisk 删除并重建分区(必须指定相同的起始扇区,否则数据会丢失):
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 扩容文件系统
分区表扩展完成后,还需要调整文件系统大小:
resize2fs /dev/mmcblk0p2
执行成功后,再次查看磁盘使用情况:
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 到这里运行。
所以要解决这个问题,只要创建相应的目录就行了
mkdir -p /var/empty
chmod 755 /var/empty
chown root:root /var/empty
🍆 5.7 SSH链接失败
如果你在 powershell 中用 SSH 链接结果出现以下报错:
这种情况时单板上密钥更新了但是 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 和 OpenSSL 还有 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 这块单板,但是这些构建系统,部署系统,搭建调试网络的方法,一定能够对你有所帮助。
最后感谢您完整的看完了本系列的所有内容。