ZyLiu's Blog

开启Hikey 970开发板USB AUDIO功能

字数统计: 1.9k阅读时长: 7 min
2020/05/10 Share

4月30日,领导突然交给我一个任务,在Hikey970开发板上搭建录音环境。我只想说另请高明吧。我实在……我也不是谦虚,我一个上层应用开发怎么突然做起嵌入式来了呢?但是,领导讲“已经研究决定了”,后来我就念了两首诗,叫“苟利国家生死以,岂因祸福避趋之”。

准备

领导还在跟我讨论买什么样的麦克风的时候,我突然在论坛中看到,Hikey970开发板默认不支持USB AUDIO,需要修改内核配置开启。好嘛,还买个啥麦克风,先把音频输入调通再说吧。

根据Android usb audio录音这篇博文的介绍,打开USB AUDIO配置还是比较容易的,只需要修改/kernel-4.9/sound/usb/Kconfig文件中的SND_USB_AUDIO块即可。

下载AOSP源码

还好我不是从零开始,前人已经总结了源码编译AOSP详细步骤

用repo下载AOSP源码

首先需要安装repo

我使用WSL用apt命令安装,报错。
最后使用博客windows环境下repo下载Android源代码中推荐的人修改好的repo客户端,点此下载

初始化repo仓库

使用如下命令,以清华大学AOSP镜像仓库初始化repo:

1
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-9.0.0_r8 --no-repo-verify --repo-branch=stable

开始下载源码

论坛中使用如下命令进行repo仓库同步:

1
repo sync -j4

-j4的含义为使用四线程进行仓库同步。
但由于AOSP源码过多,常常由于网络原因导致同步中断,报如下错误:

1
error: error: Exited sync due to fetch errors

因此需要加上强制同步的选项:

1
repo sync -j4 -f --force-sync

下载过程中遇到的坑

aux.h文件无法创建

开始我是在PowerShell环境进行的源码下载,但每当下载到aux.h文件时,就会报错文件无法被创建。经查资料,发现aux是Windows平台的保留文件名,无法被用户使用。不信你可以创建一个aux.txt试试。

其实除aux之外,Windows还有许多预留文件名不能用,这篇文章做了很好的总结。

具体如下:

1
CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9

在WSL环境进行repo sync,可以解决这个问题。

大小写不敏感导致的文件丢失

AOSP源码中,有许多源文件是除大小写外相同的,这样在Windows系统clone仓库时可能导致其中一个文件被当作重名文件丢失,或者在编译时会导致错误包含头文件 (坑爹的Windows)

可通过如下python脚本批量设置目录下所有文件夹的文件大小写敏感:

1
2
3
4
5
6
7
8
import os

path = r'F:\\git_repo\\repo-tsinghua-linux\\tools'

for folderName, subfolders, fileNames in os.walk(path):
os.system('fsutil.exe file SetCaseSensitiveInfo ' + folderName + ' enable')

print("Success!")

也可在WSL下使用如下命令设置或获取目录是否大小写敏感(需要apt install attr):

1
2
3
4
# 设置
setfattr -n system.wsl_case_sensitive -v 1 "/mnt/f/git_repo/repo-tsinghua-linux/kernel/linux/net/netfilter"
# 获取
getfattr -n system.wsl_case_sensitive "/mnt/f/git_repo/repo-tsinghua-linux/kernel/linux/net/netfilter"

可以通过上述方式先创建一个大小写敏感的目录,然后将代码仓库解压到该目录下,则新生成的目录都是大小写敏感的了。

下载并编译Hikey 970内核源码

本地clone

根据论坛的建议,原生的kernel不能boot这个版本的AOSP,会导致各种问题,需要重新clone linaro官方针对hikey970的kernel源码。

1
git clone https://github.com/96boards-hikey/linux.git -b hikey970-v4.9 linux

但国内的网络环境,clone github仓库只有20KBps的速度,下载这三四个GB的仓库要到猴年马月。

于是首先尝试挂代理,我的计算机上部署有V2ray的socks5代理,代理端口号为10808,于是使用如下命令进行git全局代理设置:

1
2
3
4
5
6
# 开启全局代理
git config --global http.proxy 'socks5://127.0.0.1:10808'
git config --global https.proxy 'socks5://127.0.0.1:10808'
# 关闭全局代理
git config --global --unset http.proxy
git config --global --unset https.proxy

但设置代理后,像内核源码这么大的仓库,还是会失败。

VPS clone

在经历无数次的失败后,我直接使用VPS clone源码,然后用FTP协议将仓库打包传送到了本地。

修改USB AUDIO配置

整个任务就是围绕这一步进行的,前文说过,打开USB AUDIO配置的方法为,只需要修改/kernel-4.9/sound/usb/Kconfig文件中的SND_USB_AUDIO块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
config SND_USB_AUDIO
tristate "USB Audio/MIDI driver"
select SND_HWDEP
select SND_RAWMIDI
select SND_PCM
select BITREVERSE
# 新增下面这行
default y
# 新增上面这行
help
Say Y here to include support for USB audio and USB MIDI
devices.

To compile this driver as a module, choose M here: the module
will be called snd-usb-audio.

内核编译

使用如下命令进行编译,注意需要目录大小写敏感。

1
2
3
4
5
6
7
8
9
10
cd $AOSP_ROOT/kernel/linux

# 环境变量
export ARCH=arm64
export CROSS_COMPILE=$AOSP_ROOT/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-

# 编译Image
make hikey970_defconfig && make -j4 Image.gz modules
# 生成kirin970-hikey970.dtb
make hisilicon/kirin970-hikey970.dtb

生成的目标为:

1
2
$AOSP_ROOT/kernel/linux/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dts
$AOSP_ROOT/kernel/linux/arch/arm64/boot/Image

生成系统镜像

其实,本次任务并不需要完整的编译整个AOSP,我们可以使用96boards官方提供的AOSP系统镜像,只是替换其中的内核即可。

AOSP/bootloader编译

我们跳过了AOSP编译这一步,实属无奈,120GB的硬盘都沾满了,实在放不下那么多目标文件。

同样,bootloader获取也跳过,直接用官方镜像。

AOSP编译生成的目标文件为:

1
2
3
4
5
6
# 即使是编译生成的boot.img,也需要手动替换其内核
$AOSP_ROOT/out/target/product/hikey970/boot.img
$AOSP_ROOT/out/target/product/hikey970/system.img
$AOSP_ROOT/out/target/product/hikey970/cache.img
$AOSP_ROOT/out/target/product/hikey970/userdata.img
$AOSP_ROOT/out/target/product/hikey970/dt.img

bootloader编译的产物为:

1
2
3
4
$AOSP_ROOT/bootloader/l-loader/ptable-aosp-64g.img
$AOSP_ROOT/bootloader/tools-images-hikey970/sec_xloader.img
$AOSP_ROOT/bootloader/l-loader/l-loader.bin
$AOSP_ROOT/bootloader/l-loader/fip.bin

而我们下载的官方镜像目录下的文件如下:

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
hikey970
├── buildinfo.txt
├── image
│   ├── Hikey970_download_images.xml
│   ├── boot.img
│   ├── boot_ramdisk.img
│   ├── cache.img
│   ├── dt.img
│   ├── fip.bin
│   ├── installed-files.txt
│   ├── kernel.img
│   ├── l-loader.bin
│   ├── lpm3.img
│   ├── prm_ptable.img
│   ├── ptable_for_fastboot.img
│   ├── ramdisk.img
│   ├── sec_usb_xloader.img
│   ├── sec_usb_xloader2.img
│   ├── sec_xloader.img
│   ├── system.img
│   ├── update_Hikey970.bat
│   ├── userdata.img
│   ├── uefi
│   │   ├── fip.bin
│   │   ├── l-loader.bin
│   │   ├── lpm3.img
│   │   ├── prm_ptable.img
│   │   ├── ptable_for_fastboot.img
│   │   ├── sec_usb_xloader.img
│   │   ├── sec_usb_xloader2.img
│   │   ├── sec_xloader.img
│   │   └── update_Hikey970.bat

可以看到,所有目标文件都是存在的。

重新打包boot.img

解包boot.img

$AOSP_ROOT/system/core/mkbootimg目录下,有着unpack_bootimg可执行程序,可以在WSL中运行,它可以将boot.img解包:

1
unpackbootimg  -i  ./boot.img  -o ./output

则会生成output目录,目录下有bootramdisksecond三个文件。其中,boot就是我们要替换的内核,而ramdisk包含了Andoroid系统的文件系统信息,这里不展开了。

生成新boot

其实就是将内核编译的两个产物合并为一个:

1
cat $AOSP_ROOT/kernel/linux/arch/arm64/boot/Image $AOSP_ROOT/kernel/linux/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dtb > $AOSP_ROOT/Image-dtb

打包boot.img

将刚刚生成的Image-dtb也拷贝到output目录下,然后执行:

1
mkbootimg --kernel ./output/Image-dtb --ramdisk ./output/ramdisk --cmdline "androidboot.hardware=hikey970 firmware_class.path=/system/etc/firmware loglevel=15 buildvariant=userdebug androidboot.selinux=permissive clk_ignore_unused=true initrd=0xBE19D000,0x16677F earlycon=pl011,0xfff32000,115200 console=ttyAMA6 androidboot.serialno=54DA9CD5022525E4 clk_ignore_unused=true" -o boot.img

则生成了全新的boot.img

烧写

Windows环境下,执行update_Hikey970.bat即可。

验证

cat /proc/asound/cards命令查看设备,果然有了USB AUDIO设备,成功~

CATALOG
  1. 1. 准备
  2. 2. 下载AOSP源码
    1. 2.1. 用repo下载AOSP源码
      1. 2.1.1. 首先需要安装repo
      2. 2.1.2. 初始化repo仓库
      3. 2.1.3. 开始下载源码
    2. 2.2. 下载过程中遇到的坑
      1. 2.2.1. aux.h文件无法创建
      2. 2.2.2. 大小写不敏感导致的文件丢失
  3. 3. 下载并编译Hikey 970内核源码
    1. 3.1. 本地clone
    2. 3.2. VPS clone
    3. 3.3. 修改USB AUDIO配置
    4. 3.4. 内核编译
  4. 4. 生成系统镜像
    1. 4.1. AOSP/bootloader编译
    2. 4.2. 重新打包boot.img
      1. 4.2.1. 解包boot.img
      2. 4.2.2. 生成新boot
      3. 4.2.3. 打包boot.img
  5. 5. 烧写
  6. 6. 验证