配置信息
S805, 1G RAM, 8G ROM, USB2.0 * 2, 1GB LAN, SD Cardreader
S805参数: 32-bit, ARMv7-A, Cortex-A5, 1.5GHz 4核. 这个不是64位的CPU.
原生玩客云刷机的步骤
因为玩客云原生系统uboot无法输入命令,且启动后TTL终端需要用户登录, 所以需要先将带uboot的固件刷入
刷入安卓电视盒
在这个固件刷入后,才能在uboot菜单输入命令让盒子从SD和USB启动。
- 拆开盒子,取出PCB板,焊上TTL
- 电脑上安装USB_Burning_Tool_v2.1.6,注意系统不能是Win10英文版,这个版本读取镜像会有问题, 换成Win7就没问题
- 运行USB Burning Tool,连接USB双公头到靠近HDMI的USB口,短接触点,PCB板上电,此时在USB Burning Tool中能看到出现的新设备
- 选择inphic_firmware_v1.img或inphic_firmware_v2.img,点击
开始
刷机- V2是沙发桌面,V1是另一种不常见的桌面,都是源自同一固件制作的
- 固件都未ROOT,需要自行ROOT
- 如果是第一次安装USB Burning Tool,第一次连接,刷机可能会失败,因为在3%或4%这步PCB重启时驱动反应较慢会超时,再来一次就好了
- 刷入成功后,拔掉USB双公头线,拔电重启
用SD/TF卡运行Armbian
- 解开 Armbian_5.74_Aml-s805_Ubuntu_bionic_default_3.10.108_20190205
- 用USBWriter.exe将镜像写入U盘或SD/TF卡
- TTL线连接PCB板,电脑上用XShell打开SERIAL连接
- 在Win10下,P2302需要安装旧版的驱动,否则不能用
- 加电,出现输出后立即拍空格,出现UBOOT提示符,输入下面的命令
第一组
- # set env
- setenv bootfromrecovery 0
- setenv bootfromnand 0
- setenv start_mmc_autoscript 'if fatload mmc 0 11000000 s805_autoscript; then autoscr 11000000; fi;'
- setenv start_usb_autoscript "if fatload usb 0 11000000 s805_autoscript; then autoscr 11000000; fi; if fatload usb 1 11000000 s805_autoscript; then autoscr 11000000; fi;"
-
- setenv start_autoscript 'if usb start; then run start_usb_autoscript; fi; if mmcinfo; then run start_mmc_autoscript; fi;'
- setenv bootcmd 'run start_autoscript; run storeboot'
- # setenv firstboot 1
- saveenv
第二组
- # set env
- setenv bootfromrecovery 0
- setenv bootfromnand 0
- setenv bootcmd 'run start_autoscript; run storeboot'
- setenv start_autoscript 'if mmcinfo; then run start_mmc_autoscript; fi; if usb start; then run start_usb_autoscript; fi; run start_emmc_autoscript;'
- setenv start_emmc_autoscript 'if fatload mmc 1 11000000 emmc_autoscript; then autoscr 11000000; fi;'
- setenv start_mmc_autoscript 'if fatload mmc 0 11000000 s805_autoscript; then autoscr 11000000; fi;'
- setenv start_usb_autoscript 'for usbdev in 0 1 2 3; do if fatload usb ${usbdev} 11000000 s805_autoscript; then autoscr 11000000; fi; done'
- saveenv
上面任一组都可以,然后用这个命令检查
- # show env
- printenv
然后拔电,插上已经写入Armbian镜像的SD卡,或者U盘,U盘必须用靠近网口那个USB口, 然后加电, 就会启动进入Armbian
注意:
- 如果是用SD卡套的TF卡,注意这个读卡器比较挑,有些卡套不识别。
- 启动后先出安卓的LOGO,然后黑屏,然后才会有命令行输出, 有些Armbian镜像只有TTL输出,没有HDMI输出
- 国内制作的部分Armbian镜像, 必须用Windows下的USBWriter写入, 如果用Linux下的Disk Writer, 会导致uboot无法识别U盘的分区而导致读取USB中的启动脚本失败.
更新UBOOT
准备一张格式化为Fat32的分区小于512M的SD卡, 新的u-boot.bin放这个卡上, 在启动时进入uboot界面, 插入SD卡, 输入以下命令
- # 启动mmc
- mmcinfo
- # 将u-boot.bin这个文件从mmc 0读出, 放到内存开始地址为12000000的地方
- # 注:u-boot.bin 为 u-boot 的名字,如果名字不一样,需要作相应的更改。
- fatload mmc 0 12000000 u-boot.bin
- # 将12000000的内容 写入到rom的 0 60000 地址区间
- store rom_write 12000000 0 60000
- # 断电重启
修改autoscript
有时候镜像中的s805_autoscript设置得不对导致启动失败,需要修改. 直接修改s805_autoscript, 会导致启动时校验失败, 需要用mkimage工具重新生成, 命令历史如下
- $ mkimage -l s805_autoscript
- GP Header: Size 27051956 LoadAddr 7c441e58
- $ mv s805_autoscript s805_autoscript.bak
- $ mkimage -A arm -O linux -T script -C none -d s805_autoscript.cmd s805_autoscript
- Image Name:
- Created: Sun Dec 27 21:28:00 2020
- Image Type: ARM Linux Script (uncompressed)
- Data Size: 1284 Bytes = 1.25 KiB = 0.00 MiB
- Load Address: 00000000
- Entry Point: 00000000
- Contents:
- Image 0: 1276 Bytes = 1.25 KiB = 0.00 MiB
-
- $ mkimage -l s805_autoscript
- Image Name:
- Created: Sun Dec 27 21:28:00 2020
- Image Type: ARM Linux Script (uncompressed)
- Data Size: 1284 Bytes = 1.25 KiB = 0.00 MiB
- Load Address: 00000000
- Entry Point: 00000000
- Contents:
- Image 0: 1276 Bytes = 1.25 KiB = 0.00 MiB
对于一些只能从USB启动的img, 可以通过修改s805_autoscript的方式让其通过SD卡槽也能启动, 对于玩客云, 修改s805_autoscript.cmd中的这一行, 将 mmc 1 都改为 mmc 0, 因为玩客云只有mmc 0
if fatload mmc 1 ${kernel_addr} uImage; then if fatload mmc 1 ${initrd_addr} uInitrd; then if fatload mmc 1 ${env_addr} uEnv.txt; then env import -t ${env_addr} ${filesize};fi; if fatload mmc 1 ${dtb_addr} ${dtb_name}; then unifykey get mac;setenv bootargs ${bootargs} mac=${mac};run boot_start; else imgread dtb boot ${dtb_addr}; run boot_start;fi;fi;fi;
然后再用前面的命令,将s805_autoscript.cmd转化为s805_autoscript, 代替原文件,就可以从SD卡槽启动了.
其他的Armbian版本
目前能下载的Armbian镜像, 普遍存在两个问题: 网卡不能正常工作, HDMI没有输出. 这两者正常的只有3.10.108这个内核的版本.
内核是5.x的现在还没见到HDMI正常工作的, 因为可以从TTL进行配置, 所以如果仅作为服务器使用, 这样也可以接受.
修复网卡:
对于balbes150提供的内核为5.7.0以后的版本,都可以用替换dtb的方式修复网卡.
用这里提供的meson8b-odroidc1.dtb文件,替换掉镜像里的同名文件,并修改 uEnv.txt 文件设置为这个dtb, 就可以启动为千兆网卡
遇到的问题:
- Debian Buster版本中,用iptables命令出现"iptables-legacy tables present, use iptables-legacy to see them"提示
这是因为Buster已经更换了新的iptables实现,具体看这个链接 https://wiki.debian.org/iptables
NOTE: Debian Buster uses the nftables framework by default.
Starting with Debian Buster, nf_tables is the default backend when using iptables, by means of the iptables-nft layer (i.e, using iptables syntax with the nf_tables kernel subsystem). This also affects ip6tables, arptables and ebtables.
You can switch back and forth between iptables-nft and iptables-legacy by means of update-alternatives (same applies to arptables and ebtables).
The default starting with Debian Buster:
- # update-alternatives --set iptables /usr/sbin/iptables-nft
- # update-alternatives --set ip6tables /usr/sbin/ip6tables-nft
- # update-alternatives --set arptables /usr/sbin/arptables-nft
- # update-alternatives --set ebtables /usr/sbin/ebtables-nft
Switching to the legacy version:
- # update-alternatives --set iptables /usr/sbin/iptables-legacy
- # update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
- # update-alternatives --set arptables /usr/sbin/arptables-legacy
- # update-alternatives --set ebtables /usr/sbin/ebtables-legacy
参考以下的链接
Armbian S805相关讨论https://forum.armbian.com/topic/1919-armbian-for-amlogic-s805/
上面这个主题的后续讨论,因为“Now images for S805 and S802\S812 are shared with core 5”https://forum.armbian.com/topic/3023-armbian-for-amlogic-s805-and-s802s812/
在另一个论坛的讨论https://forum.freaktab.com/forum/tv-player-support/amlogic-based-tv-players/606133-linux-images-for-s802-s805-s812-s905-s905x-s912-sd-usb-emmc
- s805\s802\s812
-
- Thanks to the work done by Martin and the developers of Libreelec (Chewitt etc). An early alpha version of Libreelec with a 5.6 core is now available.This version is intended for General evaluation of the system's ability to run on s805\s802\s812. This version uses a new DTB configuration mechanism that is common with the latest Armbian versions for all RK+AW+AML platforms. You need to edit the file to configure it (uEnv.txt). If multi-loading is already enabled on your device, the system should start automatically after setting up DTB.
https://yadi.sk/d/2TMsShn0sgvsOA
Armbian S8xx下载 from balbes150, 这些是5.x内核使用新的dtb后整合S805,S812的镜像https://yadi.sk/d/-MwoNitZonsRCg
Armbian S805下载https://yadi.sk/d/QCGU0PIv3G5kEa
Armbian S805下载https://yadi.sk/d/DnCkh3KBvAFES
玩客云的下载 -- 这些国内自行编译的镜像, 必须在windows下用USBWriter写入才行, 如果在Linux下用disk writer,在uboot中会无法识别U盘的分区导致引导失败https://yadi.sk/d/3HM6lyepys95Tg
参考链接
https://zhuanlan.zhihu.com/p/144850658https://1syan.com/read/39.htmlhttps://www.xiaowenweb.com/fl/770/3/https://post.smzdm.com/p/akmg53qr/https://www.mydigit.cn/forum.php?mod=viewthread&tid=174374
https://www.right.com.cn/forum/thread-4023909-1-1.htmlhttps://www.right.com.cn/forum/thread-2803127-1-1.htmlhttps://www.right.com.cn/forum/thread-4031647-1-1.html
英菲克固件带roothttps://www.right.com.cn/forum/thread-4034368-1-1.html
https://www.right.com.cn/forum/thread-4034559-1-3.htmlhttps://www.right.com.cn/forum/thread-837057-1-1.html
相关下载https://pan.baidu.com/s/1RNBZGNbM1ZubrRuSegZ4kQ 提取码:oktshttps://cloud.189.cn/t/Z3a6jmYviYzu 访问码:aib8https://pan.baidu.com/s/12c2tQ3w6ncgnfI9BclSBdA 提取码:7ab0https://pan.baidu.com/s/1G5GWvkG-9oR1Nx1auVJqgQ 提取码:g7mt
通过程序控制三色灯的亮灭
前面的灯虽然只有一个,但是有三种颜色红绿蓝,通过两两组合还可以产生紫黄青白一共七种颜色. 对灯的控制是通过GPIO实现的.
如何查看GPIO信息可以参考 https://docs.khadas.com/zh-cn/vim3/HowToAccessGpio.html
对应这个设备的C代码
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <fcntl.h>
- #include <sys/types.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/select.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <sched.h>
- #include <string.h>
-
- #define PLPM_BASE 0xc8100014
-
- #define __IO volatile
-
- void *var_addr_satr=0;
- unsigned int var_addr_size=0;
- unsigned int *gpioaddr;
- void *gpio_base= 0;
-
- int gpio_init(void) {
- int fd;
- unsigned int addr_start,addr_offset;
- unsigned int PageSize,PageMask;
-
- fd = open("/dev/mem",O_RDWR);
- if(fd < 0) {
- return -1;
- }
-
- PageSize = sysconf(_SC_PAGESIZE);
- PageMask = ~(PageSize-1);
-
- //printf("take PageSize=%d\n",PageSize);
- addr_start = PLPM_BASE & PageMask ;
- addr_offset= PLPM_BASE & ~PageMask;
-
- var_addr_size = PageSize*2;
- var_addr_satr = (void*) mmap(0, var_addr_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start);
-
- if(var_addr_satr == MAP_FAILED) {
- return -1;
- }
-
- gpio_base = var_addr_satr;
- gpio_base += addr_offset;
-
- //printf("take var addr = 0x%8x\n",(unsigned int)var_addr_satr);
- //printf("make gpio_base = 0x%8x\n",(unsigned int)gpio_base);
-
- close(fd);
- return 0;
- }
-
- int gpio_deinit(void) {
- int fd;
-
- fd = open("/dev/mem",O_RDWR);
- if(fd < 0) {
- return -1;
- }
-
- if(munmap(var_addr_satr,var_addr_size) == 0) {
- //printf("remove var addr ok\n");
- } else {
- //printf("remove var addr erro\n");
- }
-
- close(fd);
- return 0;
- }
-
- void red_on(void) {
- unsigned int temp;
- temp = *(gpioaddr+4)|0x00040000;
- *(gpioaddr+4)=temp;
- }
- void red_off(void) {
- *(gpioaddr+4) = *(gpioaddr+4)&(~0x00040000);
- }
- void red_toggle(void) {
- unsigned char c;
- c = (*(gpioaddr+4)&0x00040000)>>18;
- if (c == 0) {
- red_on();
- } else {
- red_off();
- }
- }
-
- void green_on(void) {
- *(gpioaddr+4) = *(gpioaddr+4)|0x00080000;
- }
- void green_off(void) {
- *(gpioaddr+4) = *(gpioaddr+4)&(~0x00080000);
- }
- void green_toggle(void) {
- unsigned char c;
- c = (*(gpioaddr+4)&0x00080000)>>19;
- if (c == 0) {
- green_on();
- } else {
- green_off();
- }
- }
-
- void blue_on(void) {
- *(gpioaddr+4) = *(gpioaddr+4)|0x00100000;
- }
- void blue_off(void) {
- *(gpioaddr+4) = *(gpioaddr+4)&(~0x00100000);
- }
- void blue_toggle(void) {
- unsigned char c;
- c = (*(gpioaddr+4)&0x00100000)>>20;
- if (c == 0) {
- blue_on();
- } else {
- blue_off();
- }
- }
-
- unsigned char key_scan(void) {
- unsigned char key=0;
- key=((*(gpioaddr+5)&0x00000020)>>5);
- return key;
- }
-
- int main(int argc,char * argv[]) {
- if (argc < 2 || argc > 4) {
- printf("led [red|green|blue] [0|1]\n");
- return 1;
- }
-
- unsigned int temp;
- if (gpio_init() != 0) {
- printf("gpio_init failed\n");
- return -1;
- }
-
- gpioaddr = (unsigned int *)gpio_base;
- // Turn off GPIOAO_4,GPIOAO_5 reuse
- temp = *gpioaddr&(~0x01800066);
- *gpioaddr = temp;
- // Enable GPIOAO_2,GPIOAO_3,GPIOAO_4 output,GPIOAO_5 input
- temp = *(gpioaddr+4)&(~0x0000001c);
- *(gpioaddr+4) = temp;
-
- temp = *(gpioaddr+4)|0x00000020;
- *(gpioaddr+4) = temp;
-
- if (argc == 2) {
- if (strcmp((const char*)argv[1],"red")==0)
- red_toggle();
-
- if (strcmp((const char*)argv[1],"green")==0)
- green_toggle();
-
- if (strcmp((const char*)argv[1],"blue")==0)
- blue_toggle();
- }
-
- if (argc == 3) {
- if (strcmp((const char*)argv[1],"red")==0) {
- if (strcmp((const char*)argv[2],"0")==0) {
- red_off();
- } else {
- red_on();
- }
- }
-
- if (strcmp((const char*)argv[1],"green")==0) {
- if (strcmp((const char*)argv[2],"0")==0) {
- green_off();
- } else {
- green_on();
- }
- }
-
- if (strcmp((const char*)argv[1],"blue")==0) {
- if (strcmp((const char*)argv[2],"0")==0) {
- blue_off();
- } else {
- blue_on();
- }
- }
- }
-
- gpio_deinit( );
- return 0;
- }
编译和使用
- # 编译
- gcc led.c -o led
- # 触发红色亮灭
- ./led red
- # 关闭红色
- ./led red 0
- # 打开红色
- ./led red 1
如果将其放入 /usr/bin, 再将命令添加到 /etc/rc.loacl, 放到 exit 0 之前, 就能实现启动结束后变色的效果
- # By default this script does nothing.
-
- # Switch led to green to indicate the systemd has been started
- /usr/bin/onecloud_led red 0
- /usr/bin/onecloud_led blue 0
- /usr/bin/onecloud_led green 1
-
- exit 0