<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Raspi on Leafee98&#39;s Blog</title>
    <link>https://blog.leafee98.com/tags/raspi/</link>
    <description>Recent content in Raspi on Leafee98&#39;s Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Mon, 11 Sep 2023 12:35:21 +0800</lastBuildDate><atom:link href="https://blog.leafee98.com/tags/raspi/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>为树莓派添加 USB 网卡的记录</title>
      <link>https://blog.leafee98.com/posts/add-usb-ethernet-adaptor-for-raspberry/</link>
      <pubDate>Mon, 11 Sep 2023 12:35:21 +0800</pubDate>
      
      <guid>https://blog.leafee98.com/posts/add-usb-ethernet-adaptor-for-raspberry/</guid>
      <description>&lt;p&gt;我一直在用树莓派连接有线网络，然后令树莓派放出 WiFi 供台式电脑连接，这个流程是完全可以工作的，但美中不足的是树莓派放出的 WiFi 只有大概 50 Mbit/s 的速度，而树莓派所连接的有线网络是 100 Mbits/s，相当于是白白给自己的网络体验打了个对折。&lt;/p&gt;
&lt;p&gt;思虑良久（约一年），终于下定决心买下了一款 USB 转 RJ45 接口的 USB 网卡，我所购买的是裕合联的 USB3.0 有线网卡千兆铝合金，型号 YHL-U5503BK。&lt;/p&gt;
&lt;p&gt;把网线、网卡、树莓派、台式电脑都接上，🤔，基本上是工作的……具体情况大概是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在树莓派开机时，把 USB 网卡插上，能正确识别到新的网卡，也可以进行 IP 等的配置。&lt;/li&gt;
&lt;li&gt;在树莓派关机时，把 USB 网卡插上，再开机，网卡被识别为一个大容量存储设备，网络配置自然也不能进行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在一系列的尝试过后，发现在网卡被识别为大容量存储设备时，使用 &lt;code&gt;usbreset 0bda:8151&lt;/code&gt;，可以使其重新被识别为网卡，此时在 journalctl 的系统日志中也可以发现 USB 设备断开连接并且同一个接口中又新添加了一个设备，同时要注意到 Vendor ID 和 Product ID 也发生了改变。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ lsusb -tv
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
        ID 152d:1561 JMicron Technology Corp. / JMicron USA Technology Corp. JMS561U two ports SATA 6Gb/s bridge
    |__ Port 2: Dev 3, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
        ID 0bda:8151 Realtek Semiconductor Corp. RTL8151 Adapteon Business Mobile Networks BV
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        ID 2109:3431 VIA Labs, Inc. Hub

$ sudo usbreset 0bda:8151
Resetting USB 10/100/1000 LAN ... failed [No such device]

$ lsusb -tv
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
    ID 1d6b:0003 Linux Foundation 3.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M
        ID 152d:1561 JMicron Technology Corp. / JMicron USA Technology Corp. JMS561U two ports SATA 6Gb/s bridge
    |__ Port 2: Dev 4, If 0, Class=Vendor Specific Class, Driver=r8152, 5000M
        ID 0bda:8153 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
    ID 1d6b:0002 Linux Foundation 2.0 root hub
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        ID 2109:3431 VIA Labs, Inc. Hub
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在发现 usbreset 可以使其正常工作以后，便在 &lt;code&gt;/etc/udev/rules.d/90-my-usbrj45.rules&lt;/code&gt; 中使用下面这一行配置，在 &lt;code&gt;0bda:8151&lt;/code&gt; 添加时，直接对其 usbreset，然后就能够正常使用了，&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ACTION==&amp;#34;add&amp;#34;, ATTR{idVendor}==&amp;#34;0bda&amp;#34;, ATTR{idProduct}==&amp;#34;8151&amp;#34; RUN+=&amp;#34;/usr/bin/usbreset 0bda:8151&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;不过虽然解决了，依然感觉不是很优雅，询问群友得知，在连接时先被识别为大容量存储设备、然后可以切换为其他工作模式而被识别为另一种设备的行为，是所谓的免驱硬件常见的工作方式，一般在 Windows 下，设备被识别为大容量存储设备后，系统可以从此设备中拿到驱动安装文件，安装以后再切换到实际工作的模式。在 Linux 下 usb_modeswitch 可以触发硬件工作模式的切换。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Several new USB devices have their proprietary Windows drivers onboard, most of them WAN dongles. When plugged in for the first time, they act like a flash storage and start installing the Windows driver from there. If the driver is already installed, it makes the storage device disappear and a new device, mainly composite with modem ports, shows up.&lt;/p&gt;
&lt;p&gt;&amp;ndash; &lt;a href=&#34;https://linux.die.net/man/1/usb_modeswitch&#34; title=&#34;usb_modeswitch(1) - Linux man page&#34;&gt;usb_modeswitch(1)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是在直接使用 usb_modeswitch 时，一条“没有给定切换方法”的警告有点令人奇怪，并且重新 lsusb 查看发现并没有什么效果，大容量存储设备还是大容量存储设备。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ sudo usb_modeswitch -v 0bda -p 8151
Look for default devices ...
 Found devices in default mode (1)
Access device 004 on bus 002
Get the current device configuration ...
Current configuration number is 1
Use interface number 0
 with class 255
Warning: no switching method given. See documentation
-&amp;gt; Run lsusb to note any changes. Bye!
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;不过既然裕合联是个小品牌，但是它可能用的东西是通用模块或者是其他大厂的下游也说不定，印象里面 VID:PID 是唯一的所以以之作为关键字应该可以找到有用的信息。&lt;/p&gt;
&lt;p&gt;果不其然以 &lt;code&gt;usb_modeswitch 0bda 8151&lt;/code&gt; 为关键字找到了 &lt;a href=&#34;https://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=2972&#34; title=&#34;switch codes for Realtek USB ethernet adapter - USB_ModeSwitch&#34;&gt;这个&lt;/a&gt; 和 &lt;a href=&#34;https://forum.manjaro.org/t/solved-rtl8151-ethernet-not-working-via-multiport-adapter/41773/9&#34; title=&#34;[SOLVED] [RTL8151] Ethernet not working via multiport adapter - Support / Network - Manjaro Linux Forum&#34;&gt;这个&lt;/a&gt;，其中得到的下面的命令就能够切换工作模式。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;sudo usb_modeswitch -v 0bda -p 8151 -V 0bda -P 8152 -M 555342430860d9a9c0000000800006e0000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此外为了得到一个较有意义的网卡名称在 udev 中添加了一条配置将网卡名称改为 usbrj45，同时在符合期望 VID 和 PID 的情况下执行上面的切换运行状态的命令，于是最后的结果就是创建了一个 &lt;code&gt;/etc/udev/rules.d/90-my-usbrj45.rules&lt;/code&gt;，文件内容如下，其中 MAC 地址被抹去：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# persistent link nane of usbrj45
SUBSYSTEM==&amp;#34;net&amp;#34;, ACTION==&amp;#34;add&amp;#34;, ATTR{address}==&amp;#34;xx:xx:xx:xx:xx:xx&amp;#34;, NAME=&amp;#34;usbrj45&amp;#34;
ACTION==&amp;#34;add&amp;#34;, ATTR{idVendor}==&amp;#34;0bda&amp;#34;, ATTR{idProduct}==&amp;#34;8151&amp;#34; RUN+=&amp;#34;/sbin/usb_modeswitch -v 0bda -p 8151 -M 555342430860d9a9c0000000800006e0000000000000000000000000000000&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;收获&#34;&gt;收获 &lt;a href=&#34;#%e6%94%b6%e8%8e%b7&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;linux-选择驱动的方式&#34;&gt;Linux 选择驱动的方式 &lt;a href=&#34;#linux-%e9%80%89%e6%8b%a9%e9%a9%b1%e5%8a%a8%e7%9a%84%e6%96%b9%e5%bc%8f&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;经过这一大圈的调查，了解到 VID （Vendor ID）是 USB 厂商识别码，每个厂商都会有一个 ID，其唯一性由 &lt;a href=&#34;https://www.usb.org&#34;&gt;USB-IF&lt;/a&gt; 负责，而 PID （Product ID） 就是厂商自己这一款产品的 ID，其唯一性由厂商自己负责。&lt;/p&gt;
&lt;p&gt;所以可以认为对于一个 USB 设备，其 VID:PID 的组合是唯一的，于是 Linux 通过既定格式组合这两个属性并追加其他属性，得到一个长长的字符串，随后到 &lt;code&gt;/lib/modules/$(uname -r)/modules.alias&lt;/code&gt; 中寻找能够匹配这个字符串的模块，匹配的模块会被加载来操控硬件设备。&lt;/p&gt;
&lt;p&gt;在我的网卡的例子中，把 &lt;code&gt;/etc/udev/udev.conf&lt;/code&gt; 中 &lt;code&gt;udev_log&lt;/code&gt; 设置为 &lt;code&gt;debug&lt;/code&gt; 后可以从 journalctl 中看到被组合得到的字符串，像这样：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2-2:1.0: hwdb modalias key: &amp;#34;usb:v0BDAp8151d3100dc00dsc00dp00ic08isc06ip50in00&amp;#34;
2-2:2.0: hwdb modalias key: &amp;#34;usb:v0BDAp8153d3100dc00dsc00dp00ic02isc06ip00in00&amp;#34;
2-2:2.1: hwdb modalias key: &amp;#34;usb:v0BDAp8153d3100dc00dsc00dp00ic0Aisc00ip00in01&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后这个字符串能够匹配到 modules.alias 中的这两个模块，于是模块被加载并用来操控硬件：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ grep -e v0BDAp8151 -e v0BDAp8153 /lib/modules/$(uname -r)/modules.alias
alias usb:v0BDAp8153d*dc*dsc*dp*ic02isc06ip00in* cdc_ether
alias usb:v0BDAp8153d*dc*dsc*dp*ic02isc06ip00in* r8153_ecm
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;字符串拼接的细节和 USB 以外的其他设备的描述可以见 &lt;a href=&#34;https://unix.stackexchange.com/questions/499716/how-does-linux-know-how-and-what-drivers-to-install-in-a-new-installation/499771#499771&#34; title=&#34;ubuntu - How does Linux know how and what drivers to install in a new installation - Unix &amp;amp; Linux Stack Exchange&#34;&gt;这里&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;关于-udev&#34;&gt;关于 udev &lt;a href=&#34;#%e5%85%b3%e4%ba%8e-udev&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;udev 能够在每次添加或者移除设备时收到信号，并可以进行如在 /dev 目录下创建额外的符号、更改设备名称等操作。&lt;/p&gt;
&lt;p&gt;udev 有规则文件，可以在满足条件时修改设备的属性或运行特定的程序，规则文件细节可以看 &lt;a href=&#34;https://man7.org/linux/man-pages/man7/udev.7.html&#34; title=&#34;udev(7) - Linux manual page&#34;&gt;udev(7)&lt;/a&gt; 。&lt;/p&gt;
&lt;p&gt;在 raspbian 中，&lt;code&gt;/usr/lib/udev/rules.d/40-usb_modeswitch.rules&lt;/code&gt; 中有大量的自动切换工作模式的规则，如果我所使用的 USB 网卡在这里也有写好的规则的话，这篇文章就不会出现了。&lt;/p&gt;
&lt;h2 id=&#34;参考&#34;&gt;参考 &lt;a href=&#34;#%e5%8f%82%e8%80%83&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=2972&#34; title=&#34;switch codes for Realtek USB ethernet adapter - USB_ModeSwitch&#34;&gt;switch codes for Realtek USB ethernet adapter - USB_ModeSwitch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://forum.manjaro.org/t/solved-rtl8151-ethernet-not-working-via-multiport-adapter/41773/9&#34; title=&#34;[SOLVED] [RTL8151] Ethernet not working via multiport adapter - Support / Network - Manjaro Linux Forum&#34;&gt;[SOLVED] [RTL8151] Ethernet not working via multiport adapter - Support / Network - Manjaro Linux Forum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://unix.stackexchange.com/questions/499716/how-does-linux-know-how-and-what-drivers-to-install-in-a-new-installation/499771#499771&#34; title=&#34;ubuntu - How does Linux know how and what drivers to install in a new installation - Unix &amp;amp; Linux Stack Exchange&#34;&gt;ubuntu - How does Linux know how and what drivers to install in a new installation - Unix &amp;amp; Linux Stack Exchange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://linux.die.net/man/1/usb_modeswitch&#34; title=&#34;usb_modeswitch(1) - Linux man page&#34;&gt;usb_modeswitch(1) - Linux man page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://askubuntu.com/questions/1247572/how-to-automate-usb-modeswitch&#34; title=&#34;networking - How to automate usb_modeswitch? - Ask Ubuntu&#34;&gt;networking - How to automate usb_modeswitch? - Ask Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man7/udev.7.html&#34; title=&#34;udev(7) - Linux manual page&#34;&gt;udev(7) - Linux manual page&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>树莓派Arch Base系统无头配置wifi</title>
      <link>https://blog.leafee98.com/posts/%E6%A0%91%E8%8E%93%E6%B4%BEarch-base%E7%B3%BB%E7%BB%9F%E6%97%A0%E5%A4%B4%E9%85%8D%E7%BD%AEwifi%E8%BF%9E%E6%8E%A5/</link>
      <pubDate>Thu, 06 Feb 2020 19:31:00 +0800</pubDate>
      
      <guid>https://blog.leafee98.com/posts/%E6%A0%91%E8%8E%93%E6%B4%BEarch-base%E7%B3%BB%E7%BB%9F%E6%97%A0%E5%A4%B4%E9%85%8D%E7%BD%AEwifi%E8%BF%9E%E6%8E%A5/</guid>
      <description>&lt;h2 id=&#34;开门见山&#34;&gt;开门见山 &lt;a href=&#34;#%e5%bc%80%e9%97%a8%e8%a7%81%e5%b1%b1&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;本文讲解了基于ArchLinux的发行版在没有显示器/键盘/网线, 只有读卡器/一台电脑/WIFI的情况下配置无线连接的事. 细节讲解在后边.&lt;/p&gt;
&lt;p&gt;在我为了无头配置wifi而焦头烂额的时候, 我终于看到了&lt;a href=&#34;https://ladvien.com/installing-arch-linux-raspberry-pi-zero-w/&#34;&gt;这么一篇博文&lt;/a&gt;, 而博文中有这样一番代码.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh

set -e

if [[ $# -ne 3 ]] ; then
   echo &amp;#34;Usage: $0 &amp;lt;/dev/disk&amp;gt; &amp;lt;ssid&amp;gt; &amp;lt;passphase&amp;gt;&amp;#34;
   exit 1
fi

DISK=&amp;#34;$1&amp;#34;
SSID=&amp;#34;$2&amp;#34;
PASS=&amp;#34;$3&amp;#34;

if [[ ! -b &amp;#34;${DISK}&amp;#34; ]] ; then
   echo &amp;#34;Not a block device: ${DISK}&amp;#34;
   exit 1
fi

if [[ &amp;#34;${USER}&amp;#34; != &amp;#34;root&amp;#34; ]] ; then
   echo &amp;#34;Must run as root.&amp;#34;
   exit 1
fi

echo Mounting
mkdir root
mount &amp;#34;${DISK}2&amp;#34; root

cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; root/etc/systemd/network/wlan0.network
[Match]
Name=wlan0

[Network]
DHCP=yes
EOF

wpa_passphrase &amp;#34;${SSID}&amp;#34; &amp;#34;${PASS}&amp;#34; &amp;gt; root/etc/wpa_supplicant/wpa_supplicant-wlan0.conf

ln -s \
   /usr/lib/systemd/system/wpa_supplicant@.service \
   root/etc/systemd/system/multi-user.target.wants/wpa_supplicant@wlan0.service

echo Unmounting
umount root

echo Cleaning up
rmdir root
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;此后又经历了一些小事(大半天), 整个无头配置wifi连接的事就完成了.&lt;/p&gt;
&lt;h2 id=&#34;我就是不想看代码版&#34;&gt;&amp;ldquo;我就是不想看代码&amp;quot;版 &lt;a href=&#34;#%e6%88%91%e5%b0%b1%e6%98%af%e4%b8%8d%e6%83%b3%e7%9c%8b%e4%bb%a3%e7%a0%81%e7%89%88&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;通篇代码都是为了防止用户搞出什么妖魔鬼怪做得防护措施, &lt;strong&gt;核心代码就三条, 从&lt;code&gt;cat&lt;/code&gt;命令开始, 到&lt;code&gt;ln&lt;/code&gt;命令结束&lt;/strong&gt;, 接下来讲讲这几条代码做的事情. &lt;em&gt;闲太长的直接看后面的总结&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;在代码讲解之前先把代码的前半部分先跑一遍, 结果就是&lt;strong&gt;sd卡的系统分区(非引导分区)被挂载到了工作目录下的root目录. 并且当前拥有root权限&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&#34;第一句&#34;&gt;第一句 &lt;a href=&#34;#%e7%ac%ac%e4%b8%80%e5%8f%a5&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; root/etc/systemd/network/wlan0.network
[Match]
Name=wlan0

[Network]
DHCP=yes
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;首先是第一句核心代码, 这一句是创建一个&lt;code&gt;systemd.network&lt;/code&gt;文件并写入内容, &lt;strong&gt;此文件详细用途可自行使用命令&lt;code&gt;man systemd.network&lt;/code&gt;查询用法&lt;/strong&gt;. 概括来说就是可以创建以&lt;code&gt;.network&lt;/code&gt;为后缀的任意名称的文件在&lt;code&gt;/etc/systemd/network/&lt;/code&gt;, 这些文件会由进程&lt;code&gt;systemd-networkd&lt;/code&gt;读取并执行, 用来配置几个网络设备.&lt;/p&gt;
&lt;p&gt;这些文件还有两个目录可以放, 分别是&lt;code&gt;/run/systemd/network/&lt;/code&gt;和&lt;code&gt;/usr/lib/systemd/network/&lt;/code&gt;, 不同目录下的相同名字的文件的行为会被前一个覆盖掉, 优先级是&lt;code&gt;/etc/&lt;/code&gt;大于&lt;code&gt;/run/&lt;/code&gt;大于&lt;code&gt;/usr/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[Match]&lt;/code&gt;节是用来指定要配置的网络设备, 如果有多个文件都匹配到了同一个设备, 那么按照文件名的字符序, 先匹配到此设备的会成功配置, 其他匹配到次设备的文件会被忽略. 注意文件目录的不同不会影响到文件字符序的排名. 在这一节中, 指定要配置的网络设备名为&lt;code&gt;wlan0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[Network]&lt;/code&gt;节指定网络设备的具体配置内容. 在这里仅启动DHCP服务.&lt;/p&gt;
&lt;h3 id=&#34;第二句&#34;&gt;第二句 &lt;a href=&#34;#%e7%ac%ac%e4%ba%8c%e5%8f%a5&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;wpa_passphrase &amp;#34;${SSID}&amp;#34; &amp;#34;${PASS}&amp;#34; &amp;gt; root/etc/wpa_supplicant/wpa_supplicant-wlan0.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;先来讲讲&lt;code&gt;wpa_passphrase&lt;/code&gt;命令的功能, 超级简单, 就是把无线的名称和密码以特定的格式打印到标准输出. 通过下面的例子可以清楚看出来效果.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ wpa_passphrase name_of_wireless password_of_wireless
network={
        ssid=&amp;#34;name_of_wireless&amp;#34;
        #psk=&amp;#34;password_of_wireless&amp;#34;
        psk=0551d34036ce41f72fcc66632e57c6b40f1313a86f92be9c28dbb6e89d597c04
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后是&lt;code&gt;/etc/wpa_supplicant/wpa_supplicant-wlan0.conf&lt;/code&gt;文件, 首先应该知道&lt;code&gt;wpa_supplicant&lt;/code&gt;是一个用于管理无线网络连接的套件, 而&lt;code&gt;wpa_supplicant&lt;/code&gt;程序是主程序, 其他两个辅助完成功能. 除了&lt;code&gt;wpa_supplicant&lt;/code&gt;和&lt;code&gt;wpa_passphrase&lt;/code&gt;以外, 还有一个程序是&lt;code&gt;wpa_cli&lt;/code&gt;, 用于交互式配置无线网络连接, &lt;del&gt;功能丰富到不会用&lt;/del&gt;. &lt;strong&gt;此套件的配置文件可以自行使用&lt;code&gt;man supplicant.conf&lt;/code&gt;命令查询&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;说了这么多也没说到到底为什么是这个文件, 暂时先不提, 等把第三句看完.&lt;/p&gt;
&lt;h3 id=&#34;第三句&#34;&gt;第三句 &lt;a href=&#34;#%e7%ac%ac%e4%b8%89%e5%8f%a5&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ln -s \
   /usr/lib/systemd/system/wpa_supplicant@.service \
   root/etc/systemd/system/multi-user.target.wants/wpa_supplicant@wlan0.service
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这一句话说废话就是创建了一个指向某个奇怪的文件的软链接放在了另一个奇怪的地方, 说玄幻一些就是手动启用了&lt;code&gt;wpa_supplicant@&lt;/code&gt;服务, 先别打我, 等我说完.&lt;/p&gt;
&lt;p&gt;ArchLinux和基于ArchLinux的发行版都使用&lt;code&gt;systemd&lt;/code&gt;来管理服务, 而且越来越多的linux发行发行版开始转变到&lt;code&gt;systemd&lt;/code&gt;, 简单来说就是&lt;code&gt;systemd&lt;/code&gt;就是用来管理开机启动项的, 但是另一方面来说, 众多启动项彼此交错, 从挂载磁盘到配置网络, 从启动一个终端到初始化图形化界面, 相互之间顺序虽然不严格, 但是绝对不能出现冲突的顺序, 如果网络都还没配置好, 那启动了http服务也是白搭. 另一方面&lt;code&gt;systemd&lt;/code&gt;还会监视进程, 一旦某个服务异常终止, 立即要尝试重新启动, 此外还要重定向一下服务进程的输出并作为日志保存.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;systemd&lt;/code&gt;的配置文件主要有两个位置, &lt;code&gt;/etc/systemd/&lt;/code&gt;, &lt;code&gt;/usr/lib/systemd/&lt;/code&gt;, 此外还有&lt;code&gt;/run/systemd/&lt;/code&gt;应该也是, 这里面可以保存服务等的配置文件, 调用时使用&lt;code&gt;systemctl start &amp;lt;服务名&amp;gt;&lt;/code&gt;即可启动服务, 若想开机启动服务, 则要配置&lt;code&gt;[install]&lt;/code&gt;之后才可以使用&lt;code&gt;systemctl enable &amp;lt;服务名&amp;gt;&lt;/code&gt;来实现.&lt;/p&gt;
&lt;p&gt;通过以下例子可以看出来, 如果代码过长是横拉屏幕而不是自动换行的话应该看起来很不错, 这里在每一次输入命令前都加了一个额外的空行便于观看.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; test-service.service
&amp;gt; [Service]
&amp;gt; ExecStart=echo &amp;#34;hello, world!&amp;#34;
&amp;gt; [Install]
&amp;gt; WantedBy=multi-user.target
&amp;gt; EOF

# systemctl start test-service

# systemctl status test-service
● test-service.service
   Loaded: loaded (/etc/systemd/system/test-service.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

2月 06 21:23:39 manjaro systemd[1]: Started test-service.service.
2月 06 21:23:39 manjaro echo[25515]: hello, world!
2月 06 21:23:39 manjaro systemd[1]: test-service.service: Succeeded.

# systemctl enable test-service
Created symlink /etc/systemd/system/multi-user.target.wants/test-service.service → /etc/systemd/system/test-service.service.

# systemctl disable test-service
Removed /etc/systemd/system/multi-user.target.wants/test-service.service.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个例子我们创建了一个最简单的服务并启动了它, 然后使用&lt;code&gt;systemctl status&lt;/code&gt;查看它的状态, 显示当前未活动(&lt;code&gt;inactive&lt;/code&gt;), 没有自动启动安排(&amp;lsquo;disabled`), 然后下面三行是日志, 指示了启动/运行结果/结束.&lt;/p&gt;
&lt;p&gt;然后重点来了, 我们使用&lt;code&gt;systemctl enable&lt;/code&gt;和&lt;code&gt;systemctl disable&lt;/code&gt;来启用自动启动和禁用自动启动, 然后&lt;code&gt;systemctl&lt;/code&gt;做了什么? 它说它创建了链接! 仔细看可以发现, 软链接创建的位置就是我们写的&lt;code&gt;WantedBy&lt;/code&gt;的参数指明的target, 而且链接指向原本的服务.&lt;/p&gt;
&lt;p&gt;, 接下来我们看一看我们刚刚创建的软链接指向的服务文件的内容.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Unit]
Description=WPA supplicant daemon (interface-specific version)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/usr/bin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I

[Install]
Alias=multi-user.target.wants/wpa_supplicant@%i.service
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但看&lt;code&gt;ExecStart&lt;/code&gt;一条, 启动了一个&lt;code&gt;wpa_supplicant&lt;/code&gt;程序, 使用&lt;code&gt;-c&lt;/code&gt;参数制定了我们第二句写的文件.&lt;/p&gt;
&lt;p&gt;到这里再提一下, &lt;strong&gt;以&lt;code&gt;@&lt;/code&gt;为文件名结尾的服务文件有特殊意义&lt;/strong&gt;, 即服务被调用时, &lt;code&gt;@&lt;/code&gt;后填写什么与调用哪一个服务文件无关, 而是在服务文件内可以使用%I来获得从字符&lt;code&gt;@&lt;/code&gt;后到&lt;code&gt;.service&lt;/code&gt;后缀名之间的文本. 比如启动一个&lt;code&gt;foo@bar.service&lt;/code&gt;的服务, 那么&lt;code&gt;systemd&lt;/code&gt;就会启动一个&lt;code&gt;foo@.service&lt;/code&gt;的服务并把&lt;code&gt;bar&lt;/code&gt;作为&lt;code&gt;%I&lt;/code&gt;的替换.&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结 &lt;a href=&#34;#%e6%80%bb%e7%bb%93&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;所以破案了, 我们第三句创建的软链接启用了一个&lt;code&gt;systemd&lt;/code&gt;服务, 并把设备名作为&lt;code&gt;%I&lt;/code&gt;参数传给服务文件, 然后服务通过此参数又找到了第二句写的配置文件来链接无线网络. 此外第一句启用了网络设备的DHCP服务, 以免连接上无线却没有IP导致无法通信.&lt;/p&gt;
&lt;h2 id=&#34;碎碎念&#34;&gt;碎碎念 &lt;a href=&#34;#%e7%a2%8e%e7%a2%8e%e5%bf%b5&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;h3 id=&#34;起因&#34;&gt;起因 &lt;a href=&#34;#%e8%b5%b7%e5%9b%a0&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;先是想尝试折腾交叉编译, 然后发现raspbian是arm32的, 就突然觉得raspbian不好使了, 就寻思着换用archLinux或者以之为基础的发行版.&lt;/p&gt;
&lt;p&gt;其实总体来说换个系统没什么麻烦的, 无非就是把系统映像往SD卡里面一写, 然后网线一插并开机, ssh上就万事大吉了, 最多就是在写映像时有的需要手动分一下区罢了.&lt;/p&gt;
&lt;p&gt;然后目前的问题则是, &lt;strong&gt;在连一根网线也没有的情况下, 如何才能让树莓派开机就连上wifi&lt;/strong&gt;. 所以查了N久资料以后看到这番代码以后, 终于配置成功并出现了这篇文章.&lt;/p&gt;
&lt;h3 id=&#34;当下&#34;&gt;当下 &lt;a href=&#34;#%e5%bd%93%e4%b8%8b&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;最开始想使用manjaro, 下载以后苦于没有找到什么无头安装的方法, 于是下载了archlinux, 然后发现虽然archlinuxarm可以无头安装, 但是直接配置wifi又没有什么方法, 于是就回到原点. 直到找到了这段代码, 便成功安装了archlinuxarm, 然后发现好像也不是arm64, 又看到manjaro从19.10版本后支持无头安装, 并且manjaro下载就是64bit的, 于是欣然决定, 再换到manjaro, 所以现在是在用manjaro&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料 &lt;a href=&#34;#%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://ladvien.com/installing-arch-linux-raspberry-pi-zero-w/&#34;&gt;Installing Arch Linux on Raspberry Pi with Immediate WiFi Access&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;man page of &lt;code&gt;systemd&lt;/code&gt;, &lt;code&gt;systemd.network&lt;/code&gt;, &lt;code&gt;systemd.service&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.raspberrypi.org/forums/viewtopic.php?t=250676&#34;&gt;Manjaro headless installation and wifi setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
