OneCloud记录

配置信息

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, 就可以启动为千兆网卡

遇到的问题:

  1. 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/144850658
https://1syan.com/read/39.html
https://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.html
https://www.right.com.cn/forum/thread-2803127-1-1.html
https://www.right.com.cn/forum/thread-4031647-1-1.html
英菲克固件带root
https://www.right.com.cn/forum/thread-4034368-1-1.html

https://www.right.com.cn/forum/thread-4034559-1-3.html
https://www.right.com.cn/forum/thread-837057-1-1.html

相关下载
https://pan.baidu.com/s/1RNBZGNbM1ZubrRuSegZ4kQ 提取码:okts
https://cloud.189.cn/t/Z3a6jmYviYzu 访问码:aib8
https://pan.baidu.com/s/12c2tQ3w6ncgnfI9BclSBdA 提取码:7ab0
https://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

posted on 2020-12-26 17:28  Milton  阅读(2938)  评论(0编辑  收藏  举报

导航