3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Lichee Nano - Wi-Fi接続とクロスコンパイルしたプログラムの実行

Last updated at Posted at 2021-10-28

Lichee Nano

Lichee Nano は Allwinner F1C100s を搭載した開発ボードです.
Lichee Nano

公式サイトの方法では, USB が認識できない等の問題があったため Linux 5.2 のビルドを行い USB の認識及び Wi-Fi 接続までの方法とクロスコンパイルしたプログラムの実行までを記載.

output.jpg

ビルド環境 (uboot, Linux 5.2, buildroot)

公式サイトでも記されている通り, ビルド環境は Ubuntu 16.04 LTS 64bit の使用をおすすめします.
使用している環境が Arch Linux であったため, Docker で Ubuntu 16.04 イメージを使用してビルドを行いました.
Ubuntu 16.04 のイメージの取得, 実行は下記リンクを参照してください.
DockerでUbuntu 16.04 LTSのイメージを利用してみよう
また, Docker を利用した方法ではビルドしたファイルの転送を事前に考えておく必要があります. docker run コマンドでコンテナを作成する際に -v オプションを使用してホストディレクトリをコンテナ内にマウントする方法が一番楽かもしれません.
ちなみに私は, すべてビルドし終えたあとにファイル転送が必要なことに気づいたため sshd, scp を使用してファイルの送受信を行いました.

uboot, Linux, buildroot のビルド

各ビルド対象ビルド時にエラーが発生する場合, 表示される内容を確認して問題の対処を行ってください.
Ubuntu 16.04 LTS を使用している場合, ビルドに必要なパケージがインストールされていないことをはじめに疑ってください.

Toolchain のインストール

下記の方法より Toolchain のダウンロードと展開, /opt ディレクトリへの移動を行います.

wget http://releases.linaro.org/components/toolchain/binaries/7.2-2017.11/arm-linux-gnueabi/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz

tar -vxJf gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi.tar.xz
sudo cp -r ./gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi /opt/

次に, /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi/bin へのパスを通します.

export PATH=$PATH:/opt/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabi/bin

~/.bashrc への書き込みを行う方法でも問題ありません. 書き込み後設定の反映を行ってください.

source ~/.bashrc

uboot

uboot のクローンを作成
Lichee-Pi/u-boot.git プロジェクトから nano-v2018.01 ブランチのクローンを作成.

git clone https://github.com/Lichee-Pi/u-boot.git -b nano-v2018.01

Micro SD(TF Card) より開始する u-boot のビルド

ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make licheepi_nano_defconfig

boot.scr 生成のため, 下記 boot.cmd を保存.

boot.cmd
setenv bootargs console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 rw
load mmc 0:1 0x80C00000 suniv-f1c100s-licheepi-nano.dtb
load mmc 0:1 0x80008000 zImage
bootz 0x80008000 - 0x80C00000

u-boot/tools/mkimage より boot.scr の生成.

tools/mkimage -C none -A arm -T script -d boot.cmd boot.scr

Linux

Linux(nano-5.2-tf) のクローンを作製

git clone https://github.com/Lichee-Pi/linux.git --depth=1 -b nano-5.2-tf

デフォルト構成ファイルのダウロードと名称の変更

# wget http://nano.lichee.pro/_static/step_by_step/lichee_nano_linux.config
wget https://raw.githubusercontent.com/sipeed/Nano-Doc-Backup/master/_static/step_by_step/lichee_nano_linux.config
mv lichee_nano_linux.config .config

もしくは

#curl -L http://nano.lichee.pro/_static/step_by_step/lichee_nano_linux.config > .config
curl -L 'https://raw.githubusercontent.com/sipeed/Nano-Doc-Backup/master/_static/step_by_step/lichee_nano_linux.config' > .config

コンパイル

ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make

任意: USB デバイスを認識させる

コンパイルを実行する前に, USB デバイスを認識させるためのパッチを当てる必要があります.
USBデバイスを認識させる方法は, 下記の記事に詳細が記載されています.

LicheePi NanoでUSBデバイスを認識させる - Qiita
whycna.com

[v2,5/5] ARM: suniv: f1c100s: enable USB on Lichee Pi Nano - Patchwork
ここで提示されているパッチは, 上記の中に含まれていますので参考まで.

diff --git a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
index ca644541a..890a57717 100644
--- a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
+++ b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
@@ -20,7 +20,7 @@
 	};
 
 	panel: panel {
-		compatible = "lg,lb070wv8", "simple-panel";
+		compatible = "qiaodian,qd43003c0-40", "simple-panel";
 		#address-cells = <1>;
 		#size-cells = <0>;
 		enable-gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>;
@@ -79,3 +79,17 @@
 	pinctrl-0 = <&uart0_pe_pins>;
 	status = "okay";
 };
+
+&otg_sram {
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpio = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
index 26d8e5577..437bdf7d9 100644
--- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
+++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
@@ -221,6 +221,31 @@
 			resets = <&ccu RST_BUS_UART2>;
 			status = "disabled";
 		};
+		usb_otg: usb@1c13000 {
+			compatible = "allwinner,suniv-musb";
+			reg = <0x01c13000 0x0400>;
+			clocks = <&ccu CLK_BUS_OTG>;
+			resets = <&ccu RST_BUS_OTG>;
+			interrupts = <26>;
+			interrupt-names = "mc";
+			phys = <&usbphy 0>;
+			phy-names = "usb";
+			extcon = <&usbphy 0>;
+			allwinner,sram = <&otg_sram 1>;
+			status = "disabled";
+		};
+
+		usbphy: phy@1c13400 {
+			compatible = "allwinner,suniv-usb-phy";
+			reg = <0x01c13400 0x10>;
+			reg-names = "phy_ctrl";
+			clocks = <&ccu CLK_USB_PHY0>;
+			clock-names = "usb0_phy";
+			resets = <&ccu RST_USB_PHY0>;
+			reset-names = "usb0_reset";
+			#phy-cells = <1>;
+			status = "disabled";
+		};
 		fe0: display-frontend@1e00000 {
 			compatible = "allwinner,suniv-f1c100s-display-frontend";
 			reg = <0x01e00000 0x20000>;
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 856927382..3cd9e946a 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -98,6 +98,7 @@
 #define POLL_TIME			msecs_to_jiffies(250)
 
 enum sun4i_usb_phy_type {
+	suniv_phy,
 	sun4i_a10_phy,
 	sun6i_a31_phy,
 	sun8i_a33_phy,
@@ -859,6 +860,14 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct sun4i_usb_phy_cfg suniv_cfg = {
+	.num_phys = 1,
+	.type = suniv_phy,
+	.disc_thresh = 3,
+	.phyctl_offset = REG_PHYCTL_A10,
+	.dedicated_clocks = true,
+};
+
 static const struct sun4i_usb_phy_cfg sun4i_a10_cfg = {
 	.num_phys = 3,
 	.type = sun4i_a10_phy,
@@ -973,6 +982,7 @@ static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
 };
 
 static const struct of_device_id sun4i_usb_phy_of_match[] = {
+	{ .compatible = "allwinner,suniv-usb-phy", .data = &suniv_cfg },
 	{ .compatible = "allwinner,sun4i-a10-usb-phy", .data = &sun4i_a10_cfg },
 	{ .compatible = "allwinner,sun5i-a13-usb-phy", .data = &sun5i_a13_cfg },
 	{ .compatible = "allwinner,sun6i-a31-usb-phy", .data = &sun6i_a31_cfg },
diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
index 832a41f9e..83f3fa5b0 100644
--- a/drivers/usb/musb/sunxi.c
+++ b/drivers/usb/musb/sunxi.c
@@ -714,14 +714,17 @@ static int sunxi_musb_probe(struct platform_device *pdev)
 	INIT_WORK(&glue->work, sunxi_musb_work);
 	glue->host_nb.notifier_call = sunxi_musb_host_notifier;
 
-	if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb"))
+	if (of_device_is_compatible(np, "allwinner,sun4i-a10-musb") ||
+	    of_device_is_compatible(np, "allwinner,suniv-musb")) {
 		set_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags);
+	}
 
 	if (of_device_is_compatible(np, "allwinner,sun6i-a31-musb"))
 		set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
 
 	if (of_device_is_compatible(np, "allwinner,sun8i-a33-musb") ||
-	    of_device_is_compatible(np, "allwinner,sun8i-h3-musb")) {
+	    of_device_is_compatible(np, "allwinner,sun8i-h3-musb") ||
+	    of_device_is_compatible(np, "allwinner,suniv-musb")) {
 		set_bit(SUNXI_MUSB_FL_HAS_RESET, &glue->flags);
 		set_bit(SUNXI_MUSB_FL_NO_CONFIGDATA, &glue->flags);
 	}
@@ -812,6 +815,7 @@ static int sunxi_musb_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id sunxi_musb_match[] = {
+	{ .compatible = "allwinner,suniv-musb", },
 	{ .compatible = "allwinner,sun4i-a10-musb", },
 	{ .compatible = "allwinner,sun6i-a31-musb", },
 	{ .compatible = "allwinner,sun8i-a33-musb", },

任意: MT7601U チップが搭載された Wi-Fi 子機の認識

はじめに, Raspberry Pi 対象の記事であるが MT7601U 対象の記事.
Raspberry Piでmt7601uの無線LAN子機が認識されない問題を解決 | クソざこCoding

私の対処に問題があったのか, 上記の方法では解決できなかった. 出典は失念してしまいましたがエラーメッセージを検索して成功した例を下記のパッチに記します.
このパッチを当てた状態で再度ビルドを行ってください.
最後に MT7601U を動作させるためにドライバが必要となります. Meditek 社の MT7601U のページよりダウンロードを行います.
MediaTek | MT7601U
ダウンロードしたファイル DPO_MT7601U_LinuxSTA_3.0.0.4_20130913.tar.bz2 を展開し, DPO_MT7601U_LinuxSTA_3.0.0.4_20130913/mcu/bin/MT7601_formal_1.7.bin を Lichee Nano の /lib/firmware/mt7601u.bin として保存を行います.

mt76x0_usb.patch
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 2dc67e6..63bb552 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -136,11 +136,13 @@ static const struct ieee80211_ops mt76x0u_ops = {
 	.release_buffered_frames = mt76_release_buffered_frames,
 };
 
-static int mt76x0u_init_hardware(struct mt76x02_dev *dev)
+//static int mt76x0u_init_hardware(struct mt76x02_dev *dev)
+static int mt76x0u_init_hardware(struct mt76x02_dev *dev, bool reset)
 {
 	int err;
 
-	mt76x0_chip_onoff(dev, true, true);
+	//mt76x0_chip_onoff(dev, true, true);
+	mt76x0_chip_onoff(dev, true, reset);
 
 	if (!mt76x02_wait_for_mac(&dev->mt76))
 		return -ETIMEDOUT;
@@ -173,7 +175,8 @@ static int mt76x0u_register_device(struct mt76x02_dev *dev)
 	if (err < 0)
 		goto out_err;
 
-	err = mt76x0u_init_hardware(dev);
+	//err = mt76x0u_init_hardware(dev);
+	err = mt76x0u_init_hardware(dev, true);
 	if (err < 0)
 		goto out_err;
 
@@ -309,7 +312,8 @@ static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf)
 	if (ret < 0)
 		goto err;
 
-	ret = mt76x0u_init_hardware(dev);
+	//ret = mt76x0u_init_hardware(dev);
+	ret = mt76x0u_init_hardware(dev, false);
 	if (ret)
 		goto err;

変更部分をコメントアウトして修正したため, 多少変なパッチファイルとなっています.

buildroot

buildroot のダウンロードと展開

wget https://buildroot.org/downloads/buildroot-2017.08.tar.gz
tar xvf buildroot-2017.08.tar.gz
cd buildroot-2017.08/

ルートファイルシステムのコンパイル でデフォルト構成ファイルがダウンロードする指示がありますがアクセスができないため, make menuconfig より構成を行ってください.
最小の構成は, 上記のページに記されているもののみです. 一応これだけでも動作の確認は行なえます.
buildroot のコンパイルには時間がかかります.

Target options  --->
    Target Architecture Variant (arm926t)  --->
[ ] Enable VFP extension support
    Target ABI (EABI)  --->
    Floating point strategy (Soft float)  --->

System configuration  --->
    (Lichee Pi) System hostname
    (licheepi) Root password
    [*] remount root filesystem read-write during boot 

menuconfig より buildroot の構成を編集.

make menuconfig

ビルドの実行

make

ビルド成功後, buildroot-2017.08/output/images/roots.tar が作成されます.

SD カードへのインストール.

下記のビルドしたファイル及び必要なファイルをホスト環境に複製します.

  • u-boot/u-boot-sunxi-with-spl.bin
  • u-boot/boot.scr
  • linux/arch/arm/boot/zImage
  • linux/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dtb
  • buildroot-2017.08/output/images/rootfs.tar

SDカードのパーティション設定とフォーマット

認識順序によって sdXX 部分の名称が固定でないため, ここでは X としています. USBメモリ等記憶メディアが認識されていない場合, sdb が SDカードになると思われます.
パーディション sdX1 はビルドしたカーネルとデバイスツリーを格納できる容量で設定を行ってください.
残りのパーティションは任意に設定を行うことができます. パーティション sdX2 に残りすべてを割り当てても問題ありません.

パーティション sdX1 は vfat, パーティション sdX2 は ext4 のファイルシステムでフォーマットを行います.

# fdisk /dev/sdX

# mkfs.vfat /dev/sdX1
# mkfs.ext4 /dev/sdX2

u-boot の書き込み

# dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=1024 seek=8

Kernel, rootfs のインストール

マウントポイントの作製とマウント

NOTE: ここで現在のディレクトリに対してマウントポイントとなるディレクトリの作製を行っていますが, 特別な意味は存在しません. SDカードのパーティションをマウントできれば良いのです. 好みの問題です.

# mkdir -pv mnt/rootfs mnt/boot
# mount /dev/sdX1 mnt/boot
# mount /dev/sdX2 mnt/rootfs

カーネル, ブートファイルのコピー

# cp -v zImage mnt/boot
# cp -v boot.scr mnt/boot
# cp -v u-boot-sunxi-with-spl.bin mnt/boot

rootfs の展開と umount

# tar xvf roots.tar -C mnt/rootfs
# sync
# umount mnt/rootfs
# umount mnt/boot

Wi-Fi への接続

Wi-Fi への接続は, wpa_supplicant を使用した方法を記載します.
wpa_supplicantwpa_passphrase を有効にするには buildroot ビルド時に構成より指定する必要があります.

Target packages --->
  Networking applications -->
    [*] wpa_supplicant
    [*]   Enable nl80211 support
    [*]   Install wpa_cli binary
    [*]   Install wpa_client shaed library
    [*]   Install wpa_passphrage

デバイスの確認

ip コマンドより認識されているネットワークデバイスの確認を行う. ここで使用想定するデバイス名は wlan0 とします.

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: usb0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
    link/ether 82:6a:7e:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
    link/ether 1c:bf:ce:8a:ee:17 brd ff:ff:ff:ff:ff:ff

# ip link set dev wlan0 up

wpa_supplicant の実行

はじめに wpa_supplicant の設定ファイルを作成します.

# mkdir -v /etc/wpa_supplicant
# wpa_passphrage [SSID] [PASSWORD] >> /etc/wpa_supplicant/wlan0.conf

wpa_supplicant の実行及び動的 IP を割り当てる場合ならば dhcpcd も実行.

# wpa_supplicant -Dnl80211 -i wlan0 -c /etc/wpa_supplicant/wlan0.conf -B
Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
[  132.223615] wlan0: authenticate with a4:71:74:xx:xx:xx
[  132.292065] wlan0: send auth to a4:71:74:xx:xx:xx (try 1/3)
[  132.301098] wlan0: authenticated
[  132.308490] wlan0: associate with a4:71:74:xx:xx:xx (try 1/3)
[  132.321067] wlan0: RX AssocResp from a4:71:74:xx:xx:xx (capab=0x431 status=0 aid=3)
[  132.373016] wlan0: associated
[  132.380301] random: wpa_supplicant: uninitialized urandom read (4096 bytes read)

# dhcpcd
all: IPv6 kernel autoconf disabled
all: IPv6 kernel autoconf disabled
DUID 00:01:00:01:c7:92:bd:27:1c:bf:ce:8a:ee:17
wlan0: IAID ce:8a:ee:17
wlan0: adding address fe80::662:94eb:4379:d8ca
[  139.879676] random: dhcpcd: uninitialized urandom read (120 bytes read)
if_addaddress6: Operation not supported
usb0: waiting for carrier
wlan0: rebinding lease of 192.168.100.154
wlan0: probing address 192.168.100.154/24
wlan0: leased 192.168.100.154 for 604800 seconds
wlan0: adding route to 192.168.100.0/24
wlan0: adding default route via 192.168.100.1
forked to background, child pid 214

接続状態の確認

ip コマンドを使用して wlan0 に IP アドレスが割り当てられていることを確認します.
ネットワークの導通確認は任意の方法で行ってください. 一例 ping -c 3 www.example.com

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: usb0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 82:6a:7e:8b:2f:83 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq qlen 1000
    link/ether 1c:bf:ce:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.154/24 brd 192.168.100.255 scope global wlan0
       valid_lft forever preferred_lft forever

Hello, World!

Arch User Repository に存在する arm-linux-gnueabi-gcc のクロスコンパイラで生成された実行ファイルは, Lichee Nano 環境においてはエラーが発生する.
また, u-boot 及び Linux カーネルビルド時に使用した Toolchain でも同様な現象が発生する.

hello.c
#include <stdio.h>

int main(
    int argc,
    char *argv[]) {
  fprintf(stderr, "Hello, World!\n");

  return 0;
}

ホスト側でコンパイル.

$ arm-linux-gnueabi-gcc -o hello src/main.c \
  -march=armv5te \
  -mfloat-abi=soft \
  -mabi=aapcs-linux \
  -marm \
  -mtls-dialect=gnu \
  -mtune=arm926ej-s

Lichee Nano 側で実行.

$ ./hello
Segmentation fault

解決策

buildroot ビルド時に生成された buildroot-2017.08/output/host/bin/arm-buildroot-eabi-gcc を使用する. これが正攻法なのかわかりませんが, 今の所うまく行っています.

arm-buildroot-linux-gnueabi-gcc \
  -o hello src/main.c \
  -march=armv5te \
  -mfloat-abi=soft \
  -mabi=aapcs-linux \
  -marm \
  -mtls-dialect=gnu \
  -mtune=arm926ej-s
$ ./hello 
Hello, World!
$ /lib/ld-linux.so.3 --list `pwd`/hello
        libc.so.6 => /lib/libc.so.6 (0xb6dea000)
        /lib/ld-linux.so.3 (0xb6f2f000)

認識及びネットワークに接続できた Wi-Fi 子機

メーカ 名称 チップセット
TP-Link TL-WN823N v2/v3 Realtek RTL8192EU
BUFFALO INC. WLI-UC-GNM2 Ralink RT3070
Ralink Technology, Corp. MT7601U Wireless Adapter MediaTek MT7601U
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?