机顶盒B860AV2.1改造为Ubuntu服务器(一)S905L-B移植主线Uboot
机顶盒B860AV2.1改造为Ubuntu服务器(一)S905L-B移植主线Uboot
简介
最终目标
目的是将家里面闲置或网上淘的宽带机顶盒,自己适配主线Uboot、主线Linux和Ubuntu文件系统,让机顶盒变成一个运行Ubuntu系统的小服务器。
原材料和环境
-
闲置的机顶盒一个,我这里的是几十块钱买的中兴魔百盒,型号B860AV2.1
-
USB转TTL线一根,用于连接板上TTL串口,方便调试
-
SD卡一张,用于烧录适配的Uboot和Linux系统
-
电脑使用虚拟机安装Ubuntu系统,用于编译Uboot和Linux
机顶盒的型号不一定必须使用哪种,不同地区不同运营商安装的盒子型号可能都不一样,主要保证主芯片是晶晨的S905系列芯片就行了,外围电路和参数都差不太多,可能就是内容容量不一样,wifi蓝牙芯片型号不一样而已,对后面的适配影响不大。

拆开外面的塑料壳,里面就是主板了,中间散热片下面是主芯片,采用的晶晨的一颗四核A53处理器S905L-B。外围是1GB的DDR和8GB的EMMC,对外有12V电源输入、1路百兆网口、1路HDMI、2路USB2.0、1路SD卡、1路红外、1路Wifi,芯片为RTL8189FTV。板上USB接口旁的插针是CPU调试串口

S905是晶晨推出的一款专门用于机顶盒应用的SOC,S905又分很多种型号,像S905、S905X、S905L、S905W、S905D等等,不同型号内部功能性能有细微差异。
网上对S905系列已经有一些适配的Linux系统,像ARMBIAN就是做得比较好的一个。ARMBIAN是专门给各种型号的单板适配的一套Linux系统,GITHUB上可以获取到源代码,网上也有很多大佬分享他们给各种机顶盒制作的ARMBIAN镜像。但根据我之前为我这个机顶盒板子(B860AV2.1)找现成能用的ARMBIAN系统镜像的经历来看,使用网上的ARMBIAN镜像主要有几个不爽的地方:
-
兼容性问题:别人适配的镜像不一定和自己手里的板子兼容,网上S905的ARMBIAN系统大部分是国外一些大佬适配的,他们那边S905X这个型号比较多,因此适配的系统运行在我自己这个S905L-B芯片上可能就有问题,可能出现启动卡死或直接不启动的问题,需要不停更换不同的镜像或设备树尝试,这个过程比较繁琐和无聊;
-
引导启动问题:S905的ARMBIAN镜像里面没有Uboot,烧写系统前需要先有一个带Uboot的安卓系统,再在安卓系统中安装个软件修改Uboot让其支持引导ARMBIAN启动,也是操作起来比较烦,搞崩了还需要重新刷机成安卓再重新安装软件;
另一个小原因是一般安卓带的Uboot都是比较老的,也可能不支持一些Uboot的命令,像tftp、nfs等,没有一些命令对后面的折腾造成一些不方便的影响。
-
学习不到知识:如果只是为了能运行起Linux系统,那用下网上别人的镜像刷机还是可以的,但是既然都折腾起刷机了,肯定还是想通过这个过程学习到点新东西的。用别人的镜像总是在查教程和尝试,对我来说是比较乏味,我更喜欢自己动手实现一个系统,我自己能控制每一部分功能和知道每部分东西的作用。
-
用别人的镜像不能定制化适配一些东西:别人的镜像已经做好了,有可能缺少自己像用的外设驱动导致板子上这个功能在Linux下用不起来,常见的就是WIFI,蓝牙这些,如果能自己适配的话可以有更好的体验,同时也能在适配的过程中学习到新东西。
基于上面几个原因,让我有兴趣尝试自己做一个Linux系统镜像出来,目标是系统镜像包含最新版Bootloader和Linux内核,文件系统采用熟悉的Ubuntu,鉴于内存比较小和S905较低的频率,图形界面先不要求,能联网通过ssh控制就行了。适配镜像第一步就是先做个Bootloader出来,下面本文就介绍下给S905L-B适配主线Uboot的过程。
连接串口线到电脑
按照上面图中的引脚标识,使用3.3V USB转串口线连接到板上的插针,波特率设置为115200,给板子插电开机,正常上电后串口就会打印板子启动的日志信息,当然最开始的时候板子里面还是安卓系统,打印的就是上电后Uboot启动信息和引导安卓系统启动的日志。

安卓刷机
这部分主要是简单介绍下给S905型号的板子进行安卓系统刷机的教程,和适配Linux系统关系不大,仅作为补充记录。
给S905板子刷安卓系统需要用到USB Burn Tool这个工具,需要在网上下载安装这个软件。同时还需要短接板子上EMMC的启动信号到地,让S905启动失败从而进入USB烧写模式。
短接点在不知道的情况下就需要手动尝试,一般是在EMMC背面,可以找电阻或电容的焊盘确认对应的信号是不是EMMC数据或时钟线,最好是使用示波器测试下波形,上电有高低变化的就是数据信号线了,使用镊子将信号对地短路,再给板子上电就能进入USB刷机模式了。
对于我这款B860AV2.1的板子来说,短接点找到一个,在C125丝印旁边的一个空焊盘,这里我为了后面刷机短接方便,直接给焊盘飞了个按键到地,需要刷机时按按键短接就行了。

短接后再上电,使用公对公USB线连接板子上靠近网卡的USB接口到电脑,刷机软件正常就应该会识别到S905芯片了。

在网上下好安卓刷机包,点击文件导入,等待加载完成后点击开始按钮开始刷机,等待完成后安卓系统刷机就完成了。


移植主线Uboot
前面说了,安卓系统镜像自带的Uboot一般版本比较老,而且可能带的一些工具命令不全,对后面的适配调试过程有影响,因此最好的办法就是我们自己适配一个Uboot程序,方便自定义支持更多的命令和打印最新的版本(主要是强迫症)。
S905 Uboot启动流程
Amlogic S905系列常用的启动介质有EMMC、SD卡、USB,上电复位后CPU内部BootRom(BL1)开始执行,尝试从EMMC、SD卡和USB读取Bootloader文件并启动,Bootloader启动流程参考ATF(arm-trusted-firmware),ATF启动流程可参考下图。

主线Uboot作为Blootloader的BL33部分,在最后阶段启动,在BootRom和Uboot之间还需要BL2和BL3阶段的启动文件。对于S905系列CPU来说,要想构建完整的Bootloader,除Uboot(BL33)外,还需要BL2.bin、BL21.bin、BL30.bin、BL301.bin、BL31.img,以及负责签名、加密、打包文件的工具脚本。其中BL2.bin、BL30.bin是不开源的,只能从其他开发板厂家获取bin文件,BL21.bin、BL301.bin和BL31.bin可以从Uboot源码中编译得到,整个Bootloader的制作流程可参考以下流程图。

从上面的启动过程和需要的文件就可以看出,S905这个芯片在Bootloader阶段对定制开发就控制得比较严格,不仅需好几个文件,还需要对文件进行签名加密,相比于其他芯片,如瑞芯微的RK3288、RK3399,Bootloader的组成要更复杂些。猜测这也是ARMBIAN没有适配Uboot的原因之一,对于不同后缀的S905来说需要的文件还不一样,做成一个统一的版本兼容各种型号还是有点繁杂。
本次适配Uboot我就只针对我的板子上这款S905L-B来适配,不保证编译出的文件能直接用在其他型号的S905板子上,但适配流程是通用的,其他型号也可以参考下面的流程来适配自己的板子。
适配主线Uboot
下载源码和工具
制作主线Uboot会使用到Uboot源码和s905镜像工具,在Linux虚拟机中通过git clone到本地。
git clone https://github.com/u-boot/u-boot.git
git clone https://github.com/repk/gxlimg.git
git clone https://github.com/LibreELEC/amlogic-boot-fip --depth=1
Uboot的编译环境搭建这儿就不展开介绍了,网上教程都是通用的,主要就是下载跨编译器gcc-aarch64-linux-gnu和其他相关的一些依赖软件。
编译Uboot源码工程
Uboot部分代码比较通用,我们选一个S905系列芯片的板子的配置文件编译即可,这儿我选择khadas-vim_defconfig这个板子的配置,khadas-vim网上可以查到是一个搭载S905X的板子。
在Uboot源码文件夹下依次执行下面的命令编译Uboot。
make khadas-vim_defconfig
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
执行menu menuconfig,修改Uboot配置。
make menuconfig
修改环境变量存储在FAT文件系统,存储设备设置为SD卡对应的设备号,我这里是1。

修改启动设备配置,支持从SD/EMMC启动。

修改命令支持,支持bootz命令。

保存退出。
执行make命令开始编译Uboot。
make -j32
执行完最后一步后等待Uboot编译完成,没报错的话最终编译会生成一个u-boot.bin文件。

适配已有开发板型号的S905系列芯片
对于S905x等已有对应开发板的CPU型号,直接使用amlogic-boot-fip这里面的工具即可,脚本会使用开发板提供的BL30.bin等文件打包生成完整Bootloader。
# khadas-vim换成对应型号的开发板名字
# /path/to/u-boot/u-boot.bin换成上一步生成的u-boot.bin文件路径
# my-output-dir 换成输出文件的路径
./build-fip.sh khadas-vim /path/to/u-boot/u-boot.bin my-output-dir
执行完后会在输出文件夹里面生成u-boot.bin.sd.bin文件,这个文件就可以用来烧写到SD卡后启动板卡了,烧写步骤见下下节。关于这个工具的详细用法,参考工具github链接
没有开发板型号的S905系列芯片
根据我的观察,国内的S905系列的机顶盒用的芯片基本都不是S905X这个版本的,像我的机顶盒就是S905L-B,这个就不好找对应的开发板型号了(可能没有),因此前面描述这个工具就不能用了(上面工具用和实际芯片不匹配的开发板型号生成的启动文件烧写到SD卡,大概率是会在启动阶段的,BL30.bin文件会检测CPU型号,不对应的话会导致启动失败,报错“wrong chip id”)。要拿到对应的启动代码,最方便的是从一个可启动的固件中提取出来,然后再把新编译的Uboot替换掉原版固件中BL33的部分,再将所有文件重新打包成一个完整的启动烧写文件。这里就用一个可启动的安卓固件为例来展示替换掉其中的BL33(Uboot程序)的过程。
-
首先要有一个可启动的安卓系统,可以是原版安卓,也可以是刷机的,只要里面的Uboot能正常启动就行。可以连接串口查看,上电后按空格或其他按键打断Uboot启动,进入Uboot Shell界面。
![image-20241114021205760]()
-
进入Uboot后,利用mmc命令复制出emmc中的bootloader,复制EMMC的前4MB空间,去掉第1个扇区,第一个扇区是分区表。
#列出所有MMC设备(SD卡和EMMC)
mmc list
# 切换到EMMC设备,我的板子dev 1对应的EMMC,不同的板子不一样,需使用mmc info命令列出设备信息,根据容量和宽度等判断是否是EMMC
mmc dev 1
# 从EMMC的第1个扇区到后面共4MB的空间到内存0x1000000处
mmc read 0x1000000 1 0x2000
板子上插入一张不用的SD卡,将内存中读出来的文件再写入到SD卡中。
# 切换到SD卡,我的板子dev 0对应SD卡
mmc dev 0
# 将内存0x1000000处的4MB的内容写入到SD卡0扇区开始
mmc write 0x1000000 0 0x2000
将SD卡从板子取下来,通过读卡器插入电脑,使用dd命令提取出里面备份出来的原版Bootloader镜像到backup-boot.img。
# /dev/sdb替换为SD卡路径
sudo dd if=/dev/sdb of=backup-boot.img bs=512 count=8192
-
使用gxlimg工具提取文件
前面克隆了gxlimg工具后,还需要在本地编译下生成可执行文件gxlimg,直接执行make命令编译。
make

新建个文件夹用于存储解出来的文件。
mkdir backup
使用gxlimg命令解压原版bootloader到backup文件夹。
./gxlimg -e backup-boot.img ./backup

如果想得到bin文件的话还可以进一步解密和取消签名(不是必须的)。
./gxlimg -t bl3x -d ./backup/bl33.enc ./backup/bl33.bin
./gxlimg -t bl3x -d ./backup/bl31.enc ./backup/bl31.img
./gxlimg -t bl3x -d ./backup/bl30.enc ./backup/bl30.bin
./gxlimg -t bl3x -d ./backup/bl301.enc ./backup/bl301.bin
./gxlimg -t bl2 -u ./backup/bl2.sign ./backup/bl2.bin
- 使用gxlimg工具将解包出来的文件和新编译的u-boot.bin重新打包生成Bootloader gxl-boot.bin,但是打包之前将BL33.enc替换为主线Uboot,具体步骤如下:
# 加密Uboot,../u-boot/u-boot.bin换成前面编译出来的u-boot.bin文件路径
./gxlimg -t bl3x -c ../u-boot/u-boot.bin backup/u-boot.bin.enc
# 重新生成包含主线Uboot的Bootloader文件gxl-boot.bin
./gxlimg -t fip --bl2 backup/bl2.sign --bl30 backup/bl30.enc --bl301 backup/bl301.enc --bl31 backup/bl31.enc --bl33 backup/u-boot.bin.enc ./gxl-boot.bin

将新Bootloader烧写到SD卡
使用dd命令将gxl-boot.bin烧写到SD卡,跳过第1个扇区。
sudo dd if=gxl-boot.bin of=/dev/sdb bs=512 seek=1
验证新Uboot
首先需要先把EMMC中原版的Bootloader擦除掉,否则S905会默认先从EMMC启动,SD卡烧写了Uboot也不会执行。在原版Uboot里面通过mmc命令擦除前面4M区域的内容。
mmc dev 1
mmc erase 0 0x2000
插入SD卡,重新上电启动,没问题的话可以看到新编译的Uboot正常启动了。

小结
到此主线Uboot的适配就结束了,因为机顶盒主板上面功能比较简单,就是把CPU的几个USB口、网口、MMC驱动起来就行了,没有搞GPIO来控制电源上下电这个设计,因此整个移植过程还是比较顺利,使用其他板子的默认配置和设备配置都能起来。主要的难点就是获取那几个没有官方资料支持的加密文件上,理清楚了S905的启动流程才能对移植过程中涉及到的文件的功能有清晰的认识,理论上其他后缀的S905系列SOC就也可以通过这种方法来支持最新的Uboot了。
下一步就是移植最新版的主线Linux和Ubuntu根文件系统了,会涉及到Linux的编译、网络加载启动、根文件系统制作和完整烧写镜像文件制作过程。


浙公网安备 33010602011771号