「系统玩家」玩转小爱mini (二):为小爱音箱编译Tina Linux固件
system-player
2022年07月02日 14:16

Tina Linux是全志基于Openwrt开发的芯片SDK,包含了内核、驱动、bootlader、lib及应用层等嵌入式linux软件系统的各个部分,以及构建系统、交叉编译工具链等完整开发工具。

Tina Linux系统框图

小爱mini的固件是基于Tina Linux开发的。本文介绍使用Tina Linux源码为小爱mini编译固件。

使用docker建立编译环境

编译Tina linux推荐使用ubuntu作为主机环境。相对于真实主机或虚拟机,使用docker更为便捷。

使用ubuntu 16.04:

代码块
Shell
自动换行
复制代码
docker pull ubuntu:16.04
复制成功

安装依赖:

代码块
Shell
自动换行
复制代码
apt-get install git zlib1g-dev libexpat1-dev python texinfo build-essential unzip libssl-dev libxml-simple-perl libxml-sax-perl libxml2-dev libxml2-utils xsltproc wget bc ccache libc6-dev-i386 lib32ncurses5-dev lib32z1-dev gnupg cpio vim curl gawk busybox
复制成功

获取Tina linux源码

repo工具

需要使用Tina Linux中的repo

代码块
Shell
自动换行
复制代码
curl https://raw.githubusercontent.com/tinalinux/repo/stable/repo > repo
chmod a+x repo
复制成功

下载代码

代码块
Shell
自动换行
复制代码
./repo init -u https://github.com/tinalinux/manifest -b r16-v2.1.y -m r16/v2.1.y.xml
./repo sync
./repo start r16-v2.1.y --all
复制成功

这个仓库中缺少bootloader部分代码, 从github中找到个H3-BSP4.4-bootloader: https://github.com/Allwinner-Homlet/H3-BSP4.4-bootloader.git

下载后改名为bootloader放到tina_linux/lichee/brandy/目录下, 直接可用

编译

在docker中编译, root用户下需要加入

代码块
Shell
自动换行
复制代码
export FORCE_UNSAFE_CONFIGURE=1
复制成功

而且要使用 bash, 使用zsh会出现很多莫名错误

代码块
Shell
自动换行
复制代码
source build/envsetup.sh
lunch astar_parrot-tina
make
pack [-d]
复制成功

编译完成后在out/astar-parrot目录可以得到固件:

代码块
Shell
自动换行
复制代码
astar-parrot-uImage  compile_dir  md5sums   rootfs.img  staging_dir  tina_astar-arrot_uart0.img boot.img   image  packages  sha256sums  tina_astar-parrot_card0.img
复制成功

但未经修改的源码直接编译出的固件显然无法直接用于小爱mini。首先是nand分区表不一致,然后是kernel的硬件外设(设备树)不一致,以及tina linux中不包含小爱mini的音频芯片AC108的驱动。

前两项可以修改tina_linux/target/allwinner/astar-parrot/configs/中的sys_config.fex和sys_partition.fex。但AC108的驱动不太容易搞定。感兴趣的同学可以尝试一下。

如果主要的目的是将小爱mini作为自己的设备开发使用,那么采取的策略是只烧写rootfs分区,uboot和kernel继续用原来的。kernel不动,驱动就都是可用的。

此外,可以使用make menuconfig对Tina linux进行配置,比如加入dropbear。以及编译uboot、boot0等。

配置Tina linux

代码块
Shell
自动换行
复制代码
make menuconfig
复制成功

配置Tina Linux

编译uboot

R16是A33的马甲, 芯片代号为sun8iw5p1 可以在tina_linux/lichee/brandy/目录中执行:

代码块
Shell
自动换行
复制代码
./build.sh -p sun8iw5p1
复制成功

也可以在tina_linux/lichee/brandy/u-boot-2011.09/目录中:

代码块
Shell
自动换行
复制代码
make distclean
make sun8iw5p1_config
make -j8
复制成功

如果出现cannot find -lcrypto -lssl的错误 需要编译openssl, 并放到u-boot-2011.09/openssl/中

代码块
Shell
自动换行
复制代码
cd tina_linux/lichee/extern-libs/openssl-1.0.1g
vim Makefile  #修改Makefile中的 交叉编译工具目录
             #(tina_linux/lichee/brandy/gcc-linaro/bin/arm-linux-gnueabi-gcc)
make -j8
cp libcrypto.a libssl.a ../../u-boot-2011.09/openssl/
复制成功

烧写

在tina_linux/tools/aw_tools/中有全志的烧写工具PhoenixSuitLiveSuit,分别用于windows和linux平台。

尝试发现,PhoenixSuit和LiveSuit无法顺利烧写固件,都会卡在nand初始化的地方。

代码块
Shell
自动换行
复制代码
[     25.766]NAND: NAND_UbootInit
NAND_UbootInit start
NB1 : enter NAND_LogicInit
uboot:nand version: 3 5001 20160411 1437  
NAND_PIORequest, failed!
nand : get CapacityLevel fail, 46b977cd
NB1 : nand phy init fail
[     27.528]nand init fail
fail to find part named env
Using default environment
复制成功

正常启动时的nand log:

代码块
Shell
自动换行
复制代码
uboot:nand version: 3 5011 20180329 16671134  
nand : get id_number_ctl fail, 0
uboot:nand info: 1580f198 ffff16f2 4000008c 0 0  
复制成功

显示nand的驱动版本日期不一样。

自己编译的uboot运行时同样会卡在nand初始化的地方。 还是使用fastboot烧写,具体烧写方法见上篇,玩转小爱mini (一):获取root shell​

代码块
Shell
自动换行
复制代码
fastboot erase rootfs1
fastboot flash rootfs1 rootfs.img
复制成功

顺利运行:

代码块
Shell
自动换行
复制代码
BusyBox v1.24.1 () built-in shell (ash)

_____  _              __     _
|_   _||_| ___  _ _   |  |   |_| ___  _ _  _ _
 | |   _ |   ||   |  |  |__ | ||   || | ||_'_|
 | |  | || | || _ |  |_____||_||_|_||___||_,_|
 |_|  |_||_|_||_|_|  Tina is Based on OpenWrt!
----------------------------------------------
Tina Linux (Neptune, 593A1793)
----------------------------------------------
root@TinaLinux:/#
复制成功

修改tina rootfs

自己编译的tina rootfs用于小爱mini中,还需做一些修改:

- 使用原/lib/firmware/ 中的wifi固件 - 使用原/lib/modules/3.4.39/ 中的内核模块 - 建立/data目录 - 修改/etc/config/fstab, 挂载UDISK到/data,注释掉其余的 - rc.local中设置amixer

代码块
Shell
自动换行
复制代码
amixer cset iface=MIXER,name='headphone volume'  54
amixer cset iface=MIXER,name='DACL Mixer AIF1DA0L Switch' 1                                 
amixer cset iface=MIXER,name='DACR Mixer AIF1DA0R Switch' 1                                 
amixer cset iface=MIXER,name='Left Output Mixer DACL Switch' 1                               
amixer cset iface=MIXER,name='Left Output Mixer DACR Switch' 1                               
amixer cset iface=MIXER,name='HP_L Mux' 1                                                   
amixer cset iface=MIXER,name='HP_R Mux' 0                                                   
amixer cset iface=MIXER,name='Headphone Switch' 1
amixer cset iface=MIXER,name='MIC1 boost amplifier gain' 2                        
#set input                                                                
amixer cset iface=MIXER,name='LEFT ADC input Mixer MIC1 boost Switch' 1  
amixer cset iface=MIXER,name='AIF1 AD0L Mixer ADCL Switch' 1
复制成功

启动后默认 network没有up, 需要ifconfig lo up和ifconfig wlan0 up。

修改rootfs的方法是用unsquashfs和mksquashfs对rootfs.img进行修改再打包,具体同样见上篇。

直接可用的有:led,wifi,按键,录音放音,adb。

硬件使用

1. wifi

在/data/wifi/wpa_supplicant.conf设置wifi的ssid和密码后,执行

代码块
Shell
自动换行
复制代码
wpa_supplicant -Dnl80211 -iwlan0 -c/data/wifi/wpa_supplicant.conf &
udhcpc -i wlan0 -x hostname:Xmini
复制成功

2. led 向/proc/ws2812/rgb0写入数值可以控制led

代码块
Shell
自动换行
复制代码
echo 0 0 0 > /proc/ws2812/rgb0
复制成功

三个数值范围 0-255,分别为红、绿、蓝 3. 录放音 录音设备:

代码块
Shell
自动换行
复制代码
root@TinaLinux:/tmp# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: sndcodec [sndcodec], device 0: SUNXI-CODEC codec-aif1-0 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 0: sndcodec [sndcodec], device 1: aif2-clk codec-aif2-1 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 0: sndcodec [sndcodec], device 2: aif3_clk codec-aif3-2 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 1: sndi2s0 [sndi2s0], device 0: SUNXI-I2S0 ac108-pcm0-0 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
复制成功

放音设备:

代码块
Shell
自动换行
复制代码
root@TinaLinux:/tmp# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: sndcodec [sndcodec], device 0: SUNXI-CODEC codec-aif1-0 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 0: sndcodec [sndcodec], device 1: aif2-clk codec-aif2-1 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
card 0: sndcodec [sndcodec], device 2: aif3_clk codec-aif3-2 []
 Subdevices: 1/1
 Subdevice #0: subdevice #0
复制成功

录音命令:

代码块
Shell
自动换行
复制代码
# arecord -D hw:1,0 -f S16_LE -r 16000 -c 4 abc.wav
复制成功

放音命令:

代码块
Shell
自动换行
复制代码
# aplay abc.wav
复制成功

4. bluetooth 需要使用小爱中的bsa_server,hcd文件,驱动。

将tina中的bsa_server和/etc/bt/ 替换为小爱mini中的后,bsa_server可以启动起来。

tina中有个bt_test程序,首先执行了/etc/bluetooth/btenable.sh 启动 bsa_server。 顺利启动后,手机可以连接上,名称"aw bt test001&#​34;,但是无法播放音乐。

小爱mini中负责蓝牙连接/播放音乐的程序是mibt_ble。

小结

本文介绍了为小爱智能音箱mini编译原版Tina Linux。在自己的硬件设备中烧写自己编译的固件,掌控自己的设备还是挺有意思的,值得一玩。本文发布于B站专栏​,禁止转载。感兴趣的同学如有问题或想交流,可以通过以下方式联系我(base64):邮箱:c3lzdGVtLXBsYXllckBvdXRsb29rLmNvbQo=,wx:c3lzdGVtMnBsYXllcgo=。