LicheePi Zero 配置 Archlinux

在全志(Allwinner) V3s上部署U-BOOT, Linux Kernel 5.3 和ArchLinuxARM rootfs

 

工具链配置

使用arm-linux-gnueabihf交叉工具链进行编译, 可以在archlinuxcn源中找到对应工具链.

sunxi-fel下载工具. 对应仓库community

编译主线U-Boot

从Github拉取U-Boot编译, 从LicheePi的u-boot仓库获取LicheePi_Zero_800x480LCD_defconfig, 放入config文件夹, 执行编译

1
2
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LicheePi_Zero_800x480LCD_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

编译完成获得 u-boot-sunxi-with-spl.bin

使用MicroUSB线连接板子, 执行sunxi-fel version测试连接有效性, 执行sunxi-fel uboot u-boot-sunxi-with-spl.bin, 若成功在串口看到u-boot的消息则可以进行下一步操作

编译主线Linux

从Github拉取Linux源代码, 最新版本 5.4.0 RC7 启动会卡在Kernel Starting, 这里暂时使用git reset 089cf7切回 5.3.0 RC7 版本

主线Linux设备树有一点点小问题, 修改 arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dts, 添加tft屏幕节点, 内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
chosen{
#address-cells = <1>;
#size-cells = <1>;
ranges;
simplefb_lcd: framebuffer@0 {
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de0-lcd0";
clocks = <&ccu CLK_BUS_TCON0>, <&display_clocks 0>,
<&display_clocks 6>, <&ccu CLK_TCON0>;
status = "disabled";
};
};

在soc节点的i2c@01c2ac00子节点下添加触摸屏节点

1
2
3
4
ns2009@48 {
compatible = "nsiway,ns2009";
reg = <0x48>;
};

在soc节点添加音频Codec节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
dma: dma-controller@1c02000 {
compatible = "allwinner,sun8i-v3s-dma";
reg = <0x01c02000 0x1000>;
interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_DMA>;
resets = <&ccu RST_BUS_DMA>;
#dma-cells = <1>;
};
codec_analog: codec-analog {
compatible = "allwinner,sun8i-v3s-codec-analog";
reg = <0x1c23000 0x04>;
};
codec: codec@1c22c00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-v3s-codec";
reg = <0x01c22c00 0x400>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
clock-names = "apb", "codec";
resets = <&ccu RST_BUS_CODEC>;
dmas = <&dma 9>, <&dma 9>;
dma-names = "rx", "tx";
allwinner,codec-analog-controls = <&codec_analog>;
//status = "disabled";
//allwinner,pa-gpios = <&pio 7 9 GPIO_ACTIVE_HIGH>; /* PH9 */
allwinner,audio-routing =
"Headphone", "HP",
"Headphone", "HPCOM",
"MIC1", "Mic",
"Mic", "MBIAS";
status = "okay";
};

准备好后从LicheePi的Linux仓库获取 licheepi_zero_defconfig 放入arch/arm/configs/licheepi_zero_defconfig, 执行make ARCH=arm licheepi_zero_defconfig生成配置.

执行make ARCH=arm menuconfig, 在Device Drivers->Staging drivers里找到RTL8723BS, 启用后保存退出.

执行make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j3开始编译Linux, 泡一杯咖啡, 等待主线Linux编译完成

执行make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules编译驱动, 执行make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16 INSTALL_MOD_PATH=out modules_install安装驱动, 到这里主线Linux编译完成

配置TF卡实现自启动

找一张至少4GB的TF卡, 用fdisk删除全部分区, 保存更改, 使用命令dd if=sunxi-u-boot-with-spl.bin of=/dev/mmcblk0 bs=1024 seek=8将u-boot写入TF卡8byte偏移处. 使用fdisk在2MB位置创建大小为16MB的分区, 创建大小至少4GB的分区, 剩余空间再创建一个分区, 保存分区表. 我使用的分区大小配置为 16MB, 22GB, 8GB.

对三个分区分别进行格式化操作

1
2
3
mkfs.vfat /dev/mmcblk0p1
mkfs.ext4 /dev/mmcblk0p2
mkswap /dev/mmcblk0p3

创建文件夹sd, 挂载第一个分区mount /dev/mmcblk0p1 sd, 复制linux/arch/arm/boot/zImagesd, 复制linux/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dtbsd, 在sd创建boot.cmd文件, 写入以下内容

1
2
3
4
setenv bootargs console=tty0 console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 rw
load mmc 0:1 0x40000000 sun8i-v3s-licheepi-zero-dock.dtb
load mmc 0:1 0x40005000 zImage
bootz 0x40005000 - 0x40000000

执行命令mkimage -C none -A arm -T script -d boot.cmd boot.scr, 取消挂载sd, 挂载第二分区mount /dev/mmcblk0p2 sd.

Arch Linux ARM获取rootfs. 执行d解压到sd, 复制linux/out/libsd/lib, 编辑sd/etc/fstab, 添加/dev/mmcblk0p3 none swap sw 0 0, 取消挂载sd, 使用udisksctl power-off -b /dev/mmcblk0弹出TF卡

将TF卡插入板子, 插好Wifi模块和TFT屏幕, 连接串口, 打开监视器, 给板子上电

ArchLinux ARM 基本配置

配置网络

Arch Linux ARM 默认不带wpa_supplicant, 使用MicroUSB连接后可以通过USB虚拟网卡上网. 在宿主机配置网卡接口

1
2
3
4
5
6
7
8
9
10
11
target="enp0s20f0u2"
source="wlp3s0"
ip link set up dev $target
ip addr add 192.168.137.1/24 dev $target
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o $source -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $target -o $source -j ACCEPT
iptables -I INPUT -p udp --dport 67 -i $target -j ACCEPT
iptables -I INPUT -p udp --dport 53 -s 192.168.137.1/24 -j ACCEPT
iptables -I INPUT -p tcp --dport 53 -s 192.168.137.1/24 -j ACCEPT

配置DHCP服务器, 编辑/etc/dhcpd.conf

1
2
3
4
5
option domain-name-servers 223.5.5.5, 114.114.114.114;
subnet 192.168.137.0 netmask 255.255.255.0 {
range 192.168.137.100 192.168.137.120;
option routers 192.168.137.1;
}

使用命令dhcpd $target启动DHCP服务器, 在串口终端上使用dhcpcd usb0连接.

pacman源设定

使用账户root, 密码root登入Arch Linux ARM, 配置/etc/pacman.d/mirrorlist, 添加USTC ArchLinuxARM源, 在最上面添加Server = https://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo

配置/etc/pacman.conf, 添加archlinuxcn源, 在最底部添加

1
2
[archlinuxcn] 
Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch

执行下面的命令初始化pacman

1
2
3
4
pacman-key --init
pacman -Sy
pacman-key --populate archlinuxarm
pacman -S archlinuxarm-keyring

安装必要的包. pacman -S vim gdb

wifi配置

使用pacman安装wpa_supplicant. 编辑/etc/wpa_supplicant/wpa_supplicant.conf, 添加以下内容:

1
2
3
4
network={
ssid="ssid"
psk="psk"
}

执行wpa_supplicant -B -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf测试WIFI可用性, 成功连接后使用dhcpcd wlan0获取IP地址.

配置Wlan开机自动连接

复制/etc/wpa_supplicant/wpa_supplicant.conf/etc/wpa_supplicant/wpa_supplicant-wlan0.conf, 执行ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/使能dhcpcd的wpa_supplicant hook脚本, 执行systemctl enable dhcpcd, systemctl enable wpa_supplicant@wlan0.service, 重新启动即可看到效果.