Banana Pi BPI-CM4 采用 Amlogic A311D 设计,配备四核 ARM Cortex-A73 与双核 ARM Cortex-A53 CPU、ARM G52 MP4(6EE)GPU,以及算力为 5.0 TOPS 的 AI NPU。它支持摄像头和 MIPI-CSI 接口、HDMI 输出及两个千兆网口,并配有 4 GB RAM 和 16 GB eMMC 闪存。
| 更多信息: Banana Pi BPI-CM4 |
准备一根 USB 转串口线和一个 5 V/3 A Type-C 电源适配器。串口线用于控制台调试,Type-C 数据线用于下载 Android 镜像和 ADB 调试。
Linux 开发需要一张至少 8 GB 的 SD 卡;Android 仅支持从 eMMC 启动。
SoC ROM 首先尝试从 eMMC 启动。因此,只要 eMMC 中存在可启动镜像,开发板就无法从 SD 卡启动。更多信息请参阅开发板的 启动顺序。
下载并安装 AML USB Burning Tool,用于通过 Type-C 下载 Android 镜像;该工具仅支持 Windows。
下载最新的 Android 镜像,并确认 MD5 校验值正确。
打开 USB_Burning_Tool.exe,选择菜单 File → Import image,然后选择 Android 镜像。
短接主板上的 USB Boot 测试点,同时用 Type-C USB 数据线连接 PC;如果已经接通电源适配器,也可以按 RST 按钮。约两秒后,开发板会进入 USB 下载模式并被 PC 正确识别。如果 eMMC 中已有可启动的 Android,还可以执行 ADB 命令“adb reboot update”或控制台命令“reboot update”进入 USB 下载模式;操作前请确保 Type-C USB 已连接到 PC。
单击下载工具中的 Start 按钮,等待升级完成。
写入成功后,拔下 Type-C USB 数据线,再连接电源适配器启动开发板。
单击 Stop 按钮取消升级过程,然后关闭 USB Burning Tool。
Aml-flash-tool 是一款在 Linux 平台上为 Amlogic Android 设备写入镜像的开源工具。
$ ./flash-tool.sh --img=/path/to/aml_upgrade_package.img --parts=all --wipe --soc=g12a --reset=y
M5 Linux flash.PNG
获取 Android 9.0 源代码:
也可以从 百度网盘(提取码:8888)或 Google Drive下载源码 tar 包。
构建 Android 9.0 源代码 请阅读源码仓库中的 README.md。
下表列出 Banana Pi CM4 的 DTBO idx 值;发布镜像中的默认 idx 为 0。
| Banana Pi CM4 DTBO idx 值表 | ||
|---|---|---|
idx 值 |
设备树 Overlay |
说明 |
0 |
android_p_overlay |
默认 DTBO,不启用额外功能 |
1 |
wifi_bt_rtl8822cs |
启用 Banana Pi RTL8822CS Wi-Fi/蓝牙模块 |
2 |
i2c1 |
启用 i2c 1 |
3 |
i2c2 |
启用 i2c 2 |
4 |
sdio |
启用 SDIO |
5 |
uart1 |
启用双引脚 UART 1 |
6 |
uart1_cts_rts |
启用四引脚 UART 1 |
7 |
uart2 |
启用双引脚 UART 2 |
8 |
hifi_pcm5122 |
启用 I2S PCM5122 HiFi DAC |
如何应用新的 DTBO
通过 sysfs 的 ADB 命令
root@dangku-desktop:/tmp# adb root
restarting adbd as root
root@dangku-desktop:/tmp# adb remount
remount succeeded
root@dangku-desktop:/tmp# adb shell
bananapi_m2s:/ # echo dtbo > /sys/class/unifykeys/name
bananapi_m2s:/ # echo "1" > /sys/class/unifykeys/write
bananapi_m2s:/ # reboot
通过 sysfs 执行 UART 控制台命令
console:/ $
console:/ $ su
console:/ # echo dtbo > /sys/class/unifykeys/name
[ 115.702781@0] unifykey: name_store() 1302, name dtbo, 4
[ 115.702856@0] unifykey: name_store() 1311
console:/ #
console:/ # echo "1" > /sys/class/unifykeys/write
[ 129.262659@0] unifykey: write_store() is a string
[ 129.262733@0] unifykey: dtbo, 1, 1
[ 129.265312@0] unifykey: amlkey_write 393
[ 129.292347@1] emmc_key_write:149, write ok
console:/ #
console:/ # reboot
设置应用(待完成)
检查启动时的 UART 调试信息,确认实际加载的 DTBO。这里的“1”表示设置 idx=1,以应用 wifi_bt_rtl8822cs DTBO。
load dtb from 0x1000000 ......
Amlogic multi-dtb tool
Single dtb detected
find 2 dtbos
dtbos to be applied: 1
Apply dtbo 1
Unifykeys 保存在 eMMC 的特定分区中。在 USB_Burning_Tool 中选择“Normal erase”不会清除该数据,后续升级仍会保留。若希望下载镜像后应用默认 DTBO idx,必须选择“Erase all”。
构建使用指定默认 DTBO 的 Android 镜像
默认内置 Overlay 定义在 device/bananapi/bananapi_m2s/Kernel.mk 中,可以在此处添加新的 DTBO Overlay。
DTBO_DEVICETREE := android_p_overlay wifi_bt_rtl8822cs i2c1 i2c2 sdio uart1 uart1_cts_rts uart2 hifi_pcm5122
默认应用的 DTBO idx 定义在 device/bananapi/bananapi_m2s/BoardConfig.mk 中,可以修改 idx 值来选择默认应用的 DTBO Overlay。
BOARD_KERNEL_CMDLINE += androidboot.dtbo_idx=0
DTS 文件位于 common/arch/arm64/boot/dts/amlogic/overlay/bananapi_m2s/
有关 Android 设备树 Overlay 的更多信息,请参阅 Android 官方文档。
从 OpenGApps下载安装包;Android 发布镜像使用 ARM/Android 9.0 版本。
下载 device_id.apk。
将 OpenGApps 软件包复制到 U 盘或 SD 卡根目录。
在 U 盘或 SD 卡根目录创建名为 factory_update_param.aml 的文本文件,写入以下 Android Recovery 参数,并将文件名替换为实际下载的软件包名称。
U 盘:
--wipe_cache
--update_package=/udisk/open_gapps-arm-9.0-pico-20210327.zip
SD 卡:
--wipe_cache
--update_package=/sdcard/open_gapps-arm-9.0-pico-20210327.zip
将 U 盘或 SD 卡插入开发板,然后开机。
安装 OpenGApps 并完成认证。
YouTube: https://youtu.be/fXOKmWfpqF8
由于硬件在启动时无法自动识别不同的 MIPI 显示屏,默认 Android 发布镜像一次只支持一种显示屏。系统默认启用 [800×1280 BPI panel],也可以在 Settings → Panel Output 中将默认显示屏切换为 [1200×1920 BPI panel]。
两款 10 英寸 MIPI 显示屏在硬件上均为竖屏,因此默认 Android 发布镜像采用竖屏模式。可以通过以下两种方式将其旋转 90/180/270 度。
在 Settings → Display → Screen rotation 中旋转 UI
使用 SurfaceFlinger 旋转,需要 修改 Android 源代码并重新构建
修改默认的 SurfaceFlinger 旋转属性:
diff --git a/device/bananapi/bananapi_m2s/bananapi_m2s.mk b/device/bananapi/bananapi_m2s/bananapi_m2s.mk
index 1f51703..d592a44 100644
--- a/device/bananapi/bananapi_m2s/bananapi_m2s.mk
+++ b/device/bananapi/bananapi_m2s/bananapi_m2s.mk
@@ -579,6 +579,6 @@ PRODUCT_PROPERTY_OVERRIDES += \
else
PRODUCT_PROPERTY_OVERRIDES += \
ro.sf.lcd_density=213 \
- ro.sf.primary_display_orientation=0
+ ro.sf.primary_display_orientation=90
endif
修改 DTS 中的触摸屏旋转配置:
diff --git a/common/arch/arm64/boot/dts/amlogic/bananapi_m2s.dts b/common/arch/arm64/boot/dts/amlogic/bananapi_m2s.dts
index 4a698b0..3d41b63 100755
--- a/common/arch/arm64/boot/dts/amlogic/bananapi_m2s.dts
+++ b/common/arch/arm64/boot/dts/amlogic/bananapi_m2s.dts
@@ -876,8 +876,8 @@
reg = <0x5d>;
reset-gpio = <&gpio GPIOA_6 GPIO_ACTIVE_HIGH>;
irq-gpio = <&gpio GPIOA_5 GPIO_ACTIVE_HIGH>;
- rotation = <4>; /* sf_rotation 0 */
- //rotation = <0>; /* sf_rotation 90*/
+ //rotation = <4>; /* sf_rotation 0 */
+ rotation = <0>; /* sf_rotation 90*/
//rotation = <5>; /* sf_rotation 180 */
//rotation = <3>; /* sf_rotation 270 */
Android 引导加载程序默认将启动徽标帧缓冲区限制为 1080p60Hz(1920×1080);Android 内核 DTB 分区表默认将启动徽标分区大小限制为 16 MB。
准备一个 16 位 BMP 文件,并命名为 boot-logo.bmp。
将 BMP 文件压缩为 boot-logo.bmp.gz。
$ gzip boot-logo.bmp
解压该工具包。
$ unzip m2s_android_bootlogo_tool.zip
$ cd m2s_android_bootlogo_tool/
$ ls -l logo/
-rwxr--r-- 1 dangku dangku 525054 Sep 25 16:54 bootup.bmp
-rwxr--r-- 1 dangku dangku 525054 Sep 25 16:54 bootup_secondary.bmp
-rwxr--r-- 1 dangku dangku 184 May 19 2020 upgrade_bar.bmp
-rwxr--r-- 1 dangku dangku 180072 May 19 2020 upgrade_error.bmp
-rwxr--r-- 1 dangku dangku 180072 May 19 2020 upgrade_fail.bmp
-rwxr--r-- 1 dangku dangku 180072 May 19 2020 upgrade_logo.bmp
-rwxr--r-- 1 dangku dangku 180072 May 19 2020 upgrade_success.bmp
-rwxr--r-- 1 dangku dangku 184 May 19 2020 upgrade_unfocus.bmp
-rwxr--r-- 1 dangku dangku 180072 May 19 2020 upgrade_upgrading.bmp
复制 boot-logo.bmp.gz:
$ cp boot-logo.bmp.gz logo/bootup.bmp
$ cp boot-logo.bmp.gz logo/bootup_secondary.bmp
使用镜像打包工具创建目标 logo.img;m2s_android_bootlogo_tool 的二进制文件和相关库复制自 <android-source-dir>/out/host/linux-x86。
$ ./logo_img_packer -r logo logo.img
. 使用 Fastboot 写入启动徽标
$ adb root
$ adb remount
$ adb reboot fastboot
等待几秒,然后检查 fastboot 是否已连接:
$ fastboot device
1234567890 fastboot
$ fastboot flashing unlock_critical
$ fastboot flashing unlock
$ fastboot flash logo logo.img
$ fastboot reboot
Linux 镜像支持从 SD 卡或 eMMC 启动。
建议使用容量至少为 8 GB 的 A1 等级存储卡。
若要从 SD 卡启动,请先格式化带有可启动系统的 eMMC。
若要从 eMMC 启动并将 SD 卡用作存储,请确保 SD 卡已格式化且未写入 Linux 镜像。
在 Linux PC 上安装 bpi-tools(如果使用其他工具写入镜像,可跳过此步)。如果无法访问该地址或安装时遇到问题,请前往 bpi-tools 源码仓库手动下载并安装。
$ apt-get install pv
$ curl -sL https://github.com/BPI-SINOVOIP/bpi-tools/raw/master/bpi-tools | sudo -E bash
下载最新的 Linux 镜像,并确认 MD5 校验值正确。
默认登录: pi/bananapi 或 root/bananapi
使用 Balena Etcher 写入镜像,支持 Windows、Linux 和 macOS。
Balena Etcher 是 Balena 提供的开源图形化镜像写入工具,可将操作系统镜像写入 SD 卡或 U 盘。
单击“Flash from file”以选择镜像。
单击“Select target”选择目标设备。
单击“Flash!”开始写入。
使用 Balena CLI 写入镜像,支持 Windows、Linux 和 macOS。
Balena CLI 是 balenaCloud/openBalena 的命令行工具,可用于写入 Linux 镜像。从 balena-io Releases下载安装程序或独立软件包,并按照 安装说明正确安装到 PC。随后可使用 Balena 的“local flash”命令将 Linux 镜像写入 SD 卡或 U 盘。
$ sudo balena local flash path/to/xxx-bpi-m2s-xxx.img.zip
$ sudo balena local flash path/to/xxx-bpi-m2s-xxx.img.zip --drive /dev/disk2
$ sudo balena local flash path/to/xxx-bpi-m2s-xxx.img.zip --drive /dev/disk2 --yes
在 Linux 中使用 dd 命令写入镜像
如果 SD 卡设备 /dev/sdX 的分区已自动挂载,请先将其卸载。bpi-copy 的实际写入方式与此 dd 命令相同。
$ sudo apt-get install pv unzip
$ sudo unzip -p xxx-bpi-cm4-xxx.img.zip | pv | dd of=/dev/sdX bs=10M status=noxfer
在 Linux 中使用 bpi-tools 写入镜像
将 SD 卡插入 Linux PC,然后运行:
$ sudo apt-get install pv unzip
$ sudo bpi-copy xxx-bpi-cm4-xxx.img.zip /dev/sdX
准备一张已写入 Linux 镜像的 SD 卡,并用该 SD 卡启动开发板。
将 Linux 镜像复制到 U 盘,将 U 盘插入开发板并挂载。
可通过以下两种方式将 Linux 镜像安装到开发板。
使用 dd 命令安装。如果 mmcblk0p1 和 mmcblk0p2 分区已自动挂载,请先卸载。bpi-copy 的实际作用与这里的 dd 命令相同。
$ sudo apt-get install pv unzip
$ sudo unzip -p xxx-bpi-cm4-xxx.img.zip | pv | dd of=/dev/mmcblk0 bs=10M status=noxfer
使用 bpi-tools 命令安装 U 盘中的 Linux 镜像
$ sudo apt-get install pv unzip
$ sudo bpi-copy xxx-bpi-cm4-xxx.img.zip /dev/mmcblk0
下载完成后,安全关闭电源并弹出 SD 卡。
获取 Linux BSP 源代码
$ git clone https://github.com/BPI-SINOVOIP/BPI-M2S-bsp
构建 BSP 源代码
请阅读源码仓库中的 README.md。
如果要分别构建 U-Boot 和内核,请仅下载 U-Boot 与 内核 源码;工具链、启动脚本及其他配置文件请从 BPI-M2S-bsp 获取。
DTB Overlay 用于配置 40 Pin GPIO 的复用功能,文件位于 VFAT 启动分区中。可使用 mount 命令查看挂载点。
root@bananapi:~# ls /boot/overlays/
custom_ir.dtbo pwm_b-backlight.dtbo spi0.dtbo
ds3231.dtbo pwm_c-beeper.dtbo uart1_cts_rts.dtbo
hifi_pcm5102a.dtbo pwm_cd-c.dtbo uart1.dtbo
hifi_pcm5122.dtbo pwm_cd.dtbo uart2.dtbo
i2c1.dtbo pwm_ef.dtbo waveshare_tft24_lcd.dtbo
i2c2.dtbo pwm_ef-f.dtbo waveshare_tft35c_lcd.dtbo
pwm_ab.dtbo sdio.dtbo waveshare_tft35c_rtp.dtbo
修改 VFAT 分区中的 /boot/env.txt,通过 overlays 环境变量启用所需功能。
# Device Tree Overlays
# uart1 -- Enable UART1 (uart_A, GPIO Header PIN8 & PIN10)
# pwm_c -- Enable PWM_C (GPIO Header PIN7)
# i2c2 -- Enable i2c2 (GPIO Header PIN3 & PIN5)
# spi0 -- Enable SPI0 (GPIO Header PIN19 & PIN21 & PIN23 & PIN24)
overlays="i2c2 spi0 uart1"
修改后必须重启开发板,DTB Overlay 才会加载。
Linux 发布镜像默认未启用摄像头,可按以下步骤启用。
修改 /boot/env.txt 中的 DTB Overlay 配置,启用摄像头 DTBO。
overlays="os08a10"
将摄像头模块添加到 /etc/modules
iv009_isp_iq
iv009_isp_lens
iv009_isp_sensor
iv009_isp
创建 /etc/modprobe.d/os08a10.conf,并添加摄像头模块选项
#choose camera calibration parameters
options iv009_isp_iq cali_name=0
#choose isp register sequence
options iv009_isp_sensor isp_seq_num=0
启用摄像头 ISP systemd 服务
$ sudo systemctl enable camera_isp_3a_server.service
重启后,摄像头设备为 /dev/video0。
默认 Linux 发布镜像一次仅支持一种 MIPI 面板,因为硬件在启动时无法检测不同的面板。系统默认启用 800×1280 BPI 面板,也可在 /boot/lcd_env.txt 中将默认面板改为 1200×1920 BPI 面板。
# Mipi panel type
# Symbol | Resolution
# ----------------------+-------------
# "lcd_0" | 10" 800x1280 panel
# "lcd_1" | 10" 1200x1920 panel
panel_type=lcd_0
| Linux 不支持双屏同时显示,因此使用 MIPI 面板时请断开 HDMI 线缆。 |
两款 10 英寸 MIPI 面板在硬件上均为竖屏,因此发布镜像默认为竖屏模式,也可以旋转 90、180 或 270 度。
对于桌面镜像,创建 Xorg 配置文件 /usr/share/X11/xorg.conf.d/10-fbdev-rotate.conf,内容如下:
Section "Device"
Identifier "Configured Video Device"
# Rotate off
# Option "Rotate" "off"
# Rotate Right / clockwise, 90 degrees
Option "Rotate" "CW"
# Rotate upside down, 180 degrees
# Option "Rotate" "UD"
# Rotate counter clockwise, 270 degrees
# Option "Rotate" "CCW"
EndSection
Section "InputClass"
Identifier "Coordinate Transformation Matrix"
MatchIsTouchscreen "on"
MatchProduct "goodix-ts"
MatchDevicePath "/dev/input/event0"
MatchDriver "libinput"
# Rotate Right / clockwise, 90 degrees
Option "CalibrationMatrix" "0 1 0 -1 0 1 0 0 1"
# Rotate upside down, 180 degrees
# Option "CalibrationMatrix" "-1 0 1 0 -1 1 0 0 1"
# otate counter clockwise, 270 degrees
# Option "CalibrationMatrix" "0 -1 1 1 0 0 0 0 1"
EndSection
对于服务器镜像,可通过以下两种方式调整帧缓冲区旋转方向:
通过 Sysfs 动态修改。
echo 0 > /sys/class/graphics/fbcon/rotate //origin 0 degree
echo 1 > /sys/class/graphics/fbcon/rotate //90 degree
echo 2 > /sys/class/graphics/fbcon/rotate //180 degree
echo 3 > /sys/class/graphics/fbcon/rotate //270 degree
修改启动配置。
修改 /boot/env.txt 中的 fb_rotate 环境变量。
# Framebuffer Rotate
# 0 - origin 0 degree
# 1 - 90 degree
# 2 - 180 degree
# 3 - 270 degree
fb_rotate=0
| 此 WiringPi 仅支持将 26 Pin GPIO 配置为输出、输入、PWM 或软件 PWM。若要使用 I2C、SPI 等复用功能,必须在 boot.ini 中启用相应的 DTB Overlay。 |
构建并安装 WiringPi。在 Debian 上构建之前,必须先 安装 sudo。
$ sudo apt-get update
$ sudo apt-get install build-essential git
$ git clone https://github.com/Dangku/amlogic-wiringPi
$ cd amlogic-wiringPi
$ chmod a+x build
$ sudo ./build
运行 gpio readall,显示全部 40 Pin 引脚的状态。
BPI GPIO 扩展板示例位于 amlogic-wiringPi/examples:
blinkall:不使用扩展板,依次闪烁排针上的所有 GPIO。
lcd-bpi:BPI LCD 1602 显示模块示例。
52pi-bpi:BPI OLED 显示模块示例。
matrixled-bpi:BPI RGB LED 矩阵扩展模块示例。
berryclip-bpi:BPI BerryClip 模块示例。
构建并安装 RPi.GPIO。在 Debian 上构建之前,必须先 安装 sudo。
$ sudo apt-get update
$ sudo apt-get install build-essential python python-dev python-setuptools git
$ git clone https://github.com/Dangku/RPi.GPIO-Amlogic.git
$ cd RPi.GPIO-Amlogic
$ sudo python setup.py clean --all
$ sudo python setup.py build install
构建并安装 WiringPi2-Python。在 Debian 上构建之前,必须先 安装 sudo。
$ sudo apt-get update
$ sudo apt-get install build-essential python python-dev python-setuptools swig git
$ git clone --recursive https://github.com/Dangku/WiringPi2-Python-Amlogic.git
$ cd WiringPi2-Python-Amlogic
$ sudo python setup.py install
Linux U-Boot 默认将启动徽标的帧缓冲区尺寸限制为 1080p60Hz(1920×1080),因此默认镜像不支持更大的分辨率;如有需要,可修改 U-Boot 源码以提供支持。
准备一个 24 位 BMP 文件,并将其命名为 boot-logo.bmp。
将该文件复制到 /boot/firmware/ 或 /boot/ 目录。
AT 测试
连接模块并启动 Linux 后,/dev 目录中会出现多个 ttyUSB* 设备文件。对于 EC20,/dev/ttyUSB2 是 AT 端口。
在 Ubuntu Desktop 上通过 qmi_wwan 连接网络
在网络管理器菜单中单击“编辑连接”。
添加新的移动宽带连接。
选择 QMI 通道设备。
安装 qmi_wwan_q 驱动后,会创建一个网络设备和一个 QMI 通道。网络设备名为 wwanX,QMI 通道为 /dev/cdc-wdmX;前者用于数据传输,后者用于 QMI 消息交互。
选择运营商所在的国家或地区。
选择运营商。
设置连接名称、运营商提供的用户名、密码以及 APN(如需要)。
设置完成后即可连接。
在 Ubuntu 和 Debian Server 上通过 pppd 连接网络
安装 pppd
$ sudo apt install ipppd
在 /etc/ppp/peers/quectel-ppp 中,将 AT 设备、用户名和密码改为当地运营商提供的参数。
在 /etc/ppp/peers/quectel-chat-connect 中,将 APN 改为当地运营商提供的参数。
可使用以下两种命令启动 pppd。PPP 拨号设置过程的日志可在 这里查看。
# pppd call quectel-ppp &
或
# quectel-pppd.sh /dev/ttyUSB2 <apn> <username> <password>
终止 pppd 进程:
# quectel-ppp-kill
在 Ubuntu 和 Debian Server 上通过 qmi_wwan 连接网络 [quectel-CM] 是用于手动建立数据连接的连接管理程序。qmi_wwan 拨号设置过程的日志可在 这里查看。
# quectel-CM &
终止 quectel-CM 进程:
# killall quectel-CM
A311D SoC ROM 和 BPI-M2S-bsp 的 U-Boot 均不支持从 NVMe 启动。因此,要从 SSD 运行 Linux,必须先在 SD 卡或 eMMC 中写入引导加载程序和启动分区,再从 SSD 加载根文件系统。启动完成后,系统将从 SSD 运行。由于 Banana Pi CM4IO 板载的是 Mini PCIe 插槽,因此还需要一块 Mini PCIe 转 NVMe 适配板。
最简单的方法是将 CM4 Linux 镜像写入 SD 卡或 eMMC,用于引导系统;同时将该镜像写入 NVMe SSD,用于加载根文件系统。
使用 SD 卡或 eMMC 启动 CM4,然后修改 /boot/boot.ini,让内核从 NVMe 分区加载根文件系统。
diff a/boot/boot.ini b/boot/boot.ini
index 2222e79..c485067 100755
--- a/boot/boot.ini
+++ b/boot/boot.ini
@@ -20,6 +20,8 @@ fi;
if test "${devtype}" = "usb"; then setenv rootfsdev "/dev/sda2"; fi
+# force set root=/dev/nvme0n1p2
+setenv rootfsdev "/dev/nvme0n1p2"
+
# Load env.txt
fatload ${devtype} ${devno}:1 ${env_loadaddr} env.txt
env import -t ${env_loadaddr} ${filesize};
重启系统,内核将从 NVMe SSD 加载根文件系统。
测试性能 可运行以下命令,通过 Pi Benchmarks 测试 SSD 性能:
sudo curl https://raw.githubusercontent.com/TheRemote/PiBenchmarks/master/Storage.sh | sudo bash
SD 卡、eMMC 和 NVMe SSD(三星 970 EVO Plus)的测试结果如下:
| 类别 | 测试 | SD 卡测试结果 | eMMC 测试结果 | NVMe SSD 测试结果 |
|---|---|---|---|---|
HDParm |
磁盘读取 |
60.67 MB/s |
148.80 MB/s |
351.29 MB/s |
HDParm |
缓存磁盘读取 |
56.71 MB/s |
141.02 MB/s |
347.03 MB/s |
DD |
磁盘写入 |
14 MB/s |
51.0 MB/s |
244 MB/s |
FIO |
4K 随机读取 |
2176 IOPS (8704 KB/s) |
8438 IOPS (33753 KB/s) |
101386 IOPS (405544 KB/s) |
FIO |
4K 随机写入 |
932 IOPS (3729 KB/s) |
10876 IOPS (43505 KB/s) |
43206 IOPS (172827 KB/s) |
IOZone |
4K 读取 |
8586 KB/s |
20311 KB/s |
119475 KB/s |
IOZone |
4K 写入 |
2385 KB/s |
19016 KB/s |
90619 KB/s |
IOZone |
4K 随机读取 |
6734 KB/s |
20807 KB/s |
51517 KB/s |
IOZone |
4K 随机写入 |
3737 KB/s |
22731 KB/s |
95139 KB/s |
得分:1076 |
得分:5446 |
得分:24550 |
在 /boot/env.txt 的内核启动参数中添加 disableuhs 选项,即可禁用 SD 卡的 UHS 功能。
# User kernel args
# Add customer kernel args here
user_kernel_args=pci=pcie_bus_safe disableuhs
CM4 板载 RTL8822CS Wi-Fi/蓝牙模块,默认镜像未启用该模块,可按以下步骤启用。
将 Wi-Fi 模块名添加到 /etc/modules,以便下次启动时自动加载。
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
88x2cs
为服务器镜像安装蓝牙软件包
$ sudo apt update
$ sudo apt install bluez rfkill
重启系统。
Linux Wi-Fi STA 模式
以下是 Wi-Fi STA 模式的 Netplan 配置文件示例 01-wlan0-sta.yaml:
network:
version: 2
renderer: networkd
wifis:
wlan0:
dhcp4: true
access-points:
"bananapi":
password: "123456789"
Linux Wi-Fi AP 模式
正确安装并配置 Wi-Fi 适配器。
获取 Wi-Fi 适配器的频段、频率、信道、HT 能力、VHT 能力及其他属性: $ iw list
使用 Netplan 和 NetworkManager 管理 Wi-Fi AP 模式。 安装 NetworkManager,因为只有 NetworkManager 渲染器支持 AP 模式。
$ sudo apt install network-manager
以下是 2.4 GHz Wi-Fi AP 模式的 Netplan 配置文件示例 01-wlan0-ap-2.4g.yaml:
network:
version: 2
renderer: NetworkManager
wifis:
wlan0:
dhcp4: no
access-points:
"bananapi":
mode: ap
band: 2.4GHz
channel: 6
auth:
key-management: psk
password: "123456789"
以下是 5 GHz Wi-Fi AP 模式的 Netplan 配置文件示例 01-wlan0-ap-5g.yaml:
network:
version: 2
renderer: NetworkManager
wifis:
wlan0:
dhcp4: no
access-points:
"bananapi":
mode: ap
band: 5GHz
channel: 36
auth:
key-management: psk
password: "123456789"
使用 Netplan 和 hostapd 管理 Wi-Fi AP 模式。
创建 Netplan 配置文件 01-wlan0-ap-hostapd.yaml:
network:
version: 2
renderer: networkd
ethernets:
wlan0:
dhcp4: no
addresses:
- 192.168.11.1/24
安装 hostapd
$ sudo apt install hostapd
创建 hostapd 配置文件 /etc/hostapd/hostapd.conf,例如:
interface=wlan0
ssid=bananapi
driver=nl80211
auth_algs=1
wpa=2
wpa_passphrase=123456789
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
#bridge=br0
beacon_int=500
#SSID not hidden
ignore_broadcast_ssid=0
hw_mode=a
channel=36
max_num_sta=8
### IEEE 802.11n
ieee80211n=1
#require_vht=0
ht_capab=[HT20][HT40+][SHORT-GI-20][SHORT-GI-40][SHORT-GI-80][DSSS_CCK-40]
### IEEE 802.11ac
ieee80211ac=1
#require_vht=0
#vht_capab=[MAX-MPDU-3895][SHORT-GI-80][SU-BEAMFORMEE]
#vht_oper_chwidth=1
#vht_oper_centr_freq_seg0_idx=42
### WMM
wmm_enabled=1
要支持 80 MHz 信道带宽,需要使用 rtw_vht_enable=2 选项加载驱动;也可以创建 /etc/modprobe.d/8822cs.conf,并写入以下内容:
options 88x2cs rtw_vht_enable=2
安装并配置 DHCP 服务器服务,以下以 isc-dhcp-server 为例:
$ sudo apt install isc-dhcp-server
在 /etc/default/isc-dhcp-server 中配置 DHCP 服务器接口:
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACESv4="wlan0"
在 /etc/dhcp/dhcpd.conf 中配置 DHCP 子网和 DNS:
...
option domain-name "example.org";
option domain-name-servers 8.8.8.8, 114.114.114.114;
...
# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.
subnet 192.168.11.0 netmask 255.255.255.0 {
range dynamic-bootp 192.168.11.1 192.168.11.100;
option broadcast-address 192.168.11.255;
option routers 192.168.11.1;
}
启动服务
$ sudo hostapd /etc/hostapd/hostapd.conf -B
$ sudo systemctl restart isc-dhcp-server
配置路由。
sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 192.168.11.0/24 -o eth0 -j MASQUERADE
可通过调试控制台消息的开头,确认引导加载程序是从 SD 卡还是 eMMC 加载的。
ROM 从 SD 卡加载引导加载程序 (Linux 日志示例)
...
BL2 Built : 15:21:42, Mar 26 2020. g12a g486bc38 - gongwei.chen@droid11-sz
Board ID = 1
Set cpu clk to 24M
Set clk81 to 24M
Use GP1_pll as DSU clk.
DSU clk: 1200 Mhz
CPU clk: 1200 MHz
Set clk81 to 166.6M
board id: 1
Load FIP HDR DDR from SD, src: 0x00010200, des: 0xfffd0000, size: 0x00004000, part: 0
fw parse done
PIEI prepare done
fastboot data verify
result: 255
Cfg max: 12, cur: 1. Board id: 255. Force loop cfg
DDR4 probe
...
ROM 从 eMMC 加载引导加载程序(Android 日志示例)
...
Board ID = 1
Set cpu clk to 24M
Set clk81 to 24M
Use GP1_pll as DSU clk.
DSU clk: 1200 Mhz
CPU clk: 1200 MHz
Set clk81 to 166.6M
eMMC boot @ 0
sw8 s
board id: 1
Load FIP HDR DDR from eMMC, src: 0x00010200, des: 0xfffd0000, size: 0x00004000, part: 0
fw parse done
PIEI prepare done
00000000
emmc switch 1 ok
ddr saved addr:00016000
Load ddr parameter from eMMC, src: 0x02c00000, des: 0xfffd0000, size: 0x00001000, part: 0
00000000
...
需要注意以下四种情况:eMMC 已写入 Android 镜像、eMMC 已写入 Linux 镜像、启动过程停在 BL2,以及 eMMC 为空。
eMMC 中已写入可启动的 Android 镜像
使用 USB Burning Tool:下载进度到 7%(格式化阶段)时,拔下 Type-C USB 线缆。
M5 android format.png
使用 Android Fastboot 工具。操作前请确认 PC 上的 adb/fastboot 工具可以正常运行。
root@dangku-desktop:/tmp# adb root
adbd is already running as root
root@dangku-desktop:/tmp# adb remount
remount succeeded
root@dangku-desktop:/tmp# adb shell
bananapi_m2s:/ # reboot fastboot
等待几秒钟,开发板将重启进入 Fastboot 模式。
root@dangku-desktop:/tmp# fastboot devices
1234567890 fastboot
root@dangku-desktop:/tmp# fastboot flashing unlock_critical
...
OKAY [ 0.044s]
finished. total time: 0.044s
root@dangku-desktop:/tmp# fastboot flashing unlock
...
OKAY [ 0.047s]
finished. total time: 0.047s
root@dangku-desktop:/tmp# fastboot erase bootloader
erasing 'bootloader'...
OKAY [ 0.059s]
finished. total time: 0.059s
root@dangku-desktop:/tmp# fastboot erase bootloader-boot0
erasing 'bootloader-boot0'...
OKAY [ 0.036s]
finished. total time: 0.036s
root@dangku-desktop:/tmp# fastboot erase bootloader-boot1
erasing 'bootloader-boot1'...
OKAY [ 0.035s]
finished. total time: 0.035s
使用 U-Boot 命令:连接调试串口线,并在上电时按 Esc 键进入 U-Boot 命令行。
bananapi_m2s_v1#amlmmc erase 1
emmckey_is_protected(): protect
start = 0,end = 57343
start = 221184,end = 30535679
Erasing blocks 0 to 8192 @ boot0
start = 0,end = 8191
Erasing blocks 0 to 8192 @ boot1
start = 0,end = 8191
bananapi_m2s_v1#reset
resetting ...
SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:F;RCY:0;EMMC:0;READ:0;CHK:1F;READ:0;CHK:1F;READ:0;CHK;
以上两种方法实际只擦除 eMMC 中 Android 的引导加载程序部分。从 SD 卡启动 Linux 后,建议再 使用 dd 命令格式化整个 eMMC。
最简单的方法是在上电前插入已写入 Linux 镜像的 SD 卡。Android 引导加载程序会检查 SD 卡 VFAT 分区中是否存在 boot.ini;若存在,便会从 SD 卡启动 Linux。启动后,可使用 dd 命令格式化整个 eMMC,再将 Linux 镜像写入 eMMC。
...
BPI: try boot from sdcard
reading boot.ini
2453 bytes read in 3 ms (797.9 KiB/s)
## Executing script at 03080000
Starting boot.ini...
reading env.txt
3483 bytes read in 7 ms (485.4 KiB/s)
HDMI: Autodetect: 1080p60hz
reading Image.gz
10924573 bytes read in 611 ms (17.1 MiB/s)
reading bananapi_m2s.dtb
88054 bytes read in 12 ms (7 MiB/s)
reading uInitrd
11704481 bytes read in 655 ms (17 MiB/s)
reading overlays/wifi_bt_rtl8822cs.dtbo
729 bytes read in 6 ms (118.2 KiB/s)
eMMC 中已写入可启动的 Linux 镜像
使用 U-Boot 命令:连接调试串口线,并在上电时按 Esc 键进入 U-Boot 命令行。
bananapi_m2s# mmc erase 0 1000
Linux U-Boot 同样会检查 SD 卡 VFAT 分区中是否存在 boot.ini;若存在,便会从 SD 卡启动 Linux。启动后,可使用 dd 命令格式化整个 eMMC,或直接将 Linux 镜像写入 eMMC。
极端情况下,引导加载程序或 U-Boot 已损坏:ROM 从 eMMC 加载后,启动过程停在 U-Boot 或 BL2。例如 DRAM 初始化失败时,eMMC 启动会停在 BL2。此时只能使用 USB Burning Tool 格式化 eMMC,或者完整写入 Android 镜像后,再尝试其他方法擦除 eMMC 或写入 Linux 镜像。
如果 eMMC 为空,ROM 会尝试直接从 SD 卡加载引导加载程序。 使用 dd 命令擦除 eMMC 中的 Android 数据 如果开发板之前写入过 Android,而现在要从装有 Linux 镜像的 SD 卡启动,则必须使用以下命令擦除整个 eMMC。
$ sudo dd if=/dev/zero of=/dev/mmcblk0boot0 bs=1M status=noxfer
$ sudo dd if=/dev/zero of=/dev/mmcblk0boot1 bs=1M status=noxfer
$ sudo dd if=/dev/zero of=/dev/mmcblk0 bs=1M status=noxfer
$ sync
如果开发板之前写入过 Android,而现在要从装有 Linux 镜像的 SD 卡启动,则必须使用以下命令擦除整个 eMMC。
$ sudo dd if=/dev/zero of=/dev/mmcblk0boot0 bs=1M status=noxfer
$ sudo dd if=/dev/zero of=/dev/mmcblk0boot1 bs=1M status=noxfer
$ sudo dd if=/dev/zero of=/dev/mmcblk0 bs=1M status=noxfer
$ sync
Cloud-init 和 Snap 服务默认启用,可按需禁用或移除。
禁用或移除 cloud-init
$ sudo touch /etc/cloud/cloud-init.disabled
或
$ sudo apt purge cloud-init
禁用或移除 snap
$ sudo apt purge snapd
发布镜像中已包含 systemd 服务 rc-local.service,但其单元文件缺少 [Install] 部分,因此 systemd 无法启用该服务。首先需要更新该文件。
$ sudo nano /lib/systemd/system/rc-local.service
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
[Install]
WantedBy=multi-user.target
Alias=rc-local.service
创建 /etc/rc.local 文件:
sudo nano /etc/rc.local
#!/bin/sh
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0
为 /etc/rc.local 添加可执行权限:
$ sudo chmod +x /etc/rc.local
启用 rc-local.service 并重启:
$ sudo systemctl enable rc-local.service
$ sudo reboot
Debian 发布镜像默认未安装 sudo。用户可使用“su -”切换为 root;如需使用 sudo,可按以下步骤安装。
$ su root
Password:(enter bananapi)
# apt-get update
# apt-get install sudo
# adduser pi sudo
完成后请注销并重新登录。
在 Ubuntu 20.04 Server 上安装 Docker Engine。
设置软件仓库
更新 apt 软件包索引,并安装使 apt 能够通过 HTTPS 使用软件仓库的软件包:
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
添加 Docker 官方 GPG 密钥:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
设置 stable 软件仓库:
$ echo \
"deb [arch=arm64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装 Docker Engine
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
运行 hello-world 镜像,验证 Docker Engine 是否安装正确。
$ sudo docker run hello-world
也可以使用一条命令安装 Docker:
$ curl -sSL get.docker.com | sudo sh
其他 Linux 发行版请参阅 Docker Engine 安装文档。