20230126使AIO-3568J开发板在原厂Android11下跑起来
2023/1/26 18:22

1、前提
2、修改dts设备树
3、适配板子的dts
4、(修改uboot)编译系统烧入固件验证

前提
因源码是直接使用原厂的SDK,没有使用firefly配套的SDK源码,所以手上这块firefly aio-3568i板子在硬计上与原厂使用的板子会有些差异;
就是因为这些差异会导致新固件烧入后,debug串口 打印许多错息,可能的话,系统还会崩溃掉,跑不起来

主要差异在哪里呢?比如:
1、DDR类型和品牌多样性;
2、电源管理PMU: RK809 PMU芯片各路输出电压不同,需要修改dts配置
3、CPU,GPU电压配置或电压域配置问题
4、GPIO控制管脚分配控制的芯片器件不同这些问题只需我们到dts 设备树上进行修改,重新适配下我们手上的aio-3568i板子

1、【临时使用可以不用修改的!^_】修改dts设备树
找当前kernel使用的是哪个dts文件先配置Android分支:
/build/envsetup.sh
lunch rk3566_r-userdebug

查找方法:
查看编译脚本用的是哪个dts文件
查看build.sh脚本,找到kernel当前使用的dts名称:

Y:\rk3568_Android11.0_ToyBrick\device\rockchip\rk356x\rk3568_r\BoardConfig.mk
PRODUCT_KERNEL_DTS := rk3568-evb1-ddr4-v10
修改为:
PRODUCT_KERNEL_DTS := rk3568-evb2-lp4x-v10

# only save the version code
SDK_VERSION=`get_build_var CURRENT_SDK_VERSION`
UBOOT_DEFCONFIG=`get_build_var PRODUCT_UBOOT_CONFIG`
KERNEL_ARCH=`get_build_var PRODUCT_KERNEL_ARCH`
KERNEL_DEFCONFIG=`get_build_var PRODUCT_KERNEL_CONFIG`
if [ "$KERNEL_DTS" = "" ] ; then
KERNEL_DTS=`get_build_var PRODUCT_KERNEL_DTS`
fi
echo "-------------------KERNEL_DTS:$KERNEL_DTS"
PACK_TOOL_DIR=RKTools/linux/Linux_Pack_Firmware
IMAGE_PATH=rockdev/Image-$TARGET_PRODUCT
export PROJECT_TOP=`gettop`

lunch $TARGET_PRODUCT-$BUILD_VARIANT

服务器shell终端输入: get_build_var PRODUCT_KERNEL_DTS
ubuntu:~/rk356x/rk356x android11$ get build var PRODUCT KERNEL DTS68-evb1-ddr4-v10
从中可知道kernel是使用rk3568-evb1-ddr4-v10.dts

可以到源码中查找:
kernel/arch/arm64/boot/dts/rk3568-evb1-ddr4-v10.dts
替换dts文件
如如果需要替换为其他名称的dts,可以到这个文件下修改
device/rockchip/rk356x/rk3568_r/BoardConfig.mk

演示:因AIO-3568J的DDR是LPDDR4,所以替换个rk3568-evb2-p4x-v10.dts
修改: device/rockchip/rk356x/rk3568_r/BoardConfig.mk
PRODUCT_UBOOT_CONFIG := rk3568
PRODUCT_KERNEL_DTS := rk3568-evb2-lp4x-v10
BOARD_GSENSOR_MXC6655XA_SUPPORT := true
BOARD_CAMERA_SUPPORT_EXT := true
BOARD_HS_ETHERNET := true

再次执行: get build_var PRODUCT_KERNEL DTS
即可看到kernel使用的dts变为rk3568-evb2-lp4x-v10.dts

rootroot@rootroot-HP-ZHAN-66-Pro-A-14-G3:~/rk3568_Android11.0_ToyBrick$ 
rootroot@rootroot-HP-ZHAN-66-Pro-A-14-G3:~/rk3568_Android11.0_ToyBrick$ get_build_var PRODUCT_KERNEL_DTS
rk3568-evb2-lp4x-v10
rootroot@rootroot-HP-ZHAN-66-Pro-A-14-G3:~/rk3568_Android11.0_ToyBrick$

适配板子的dts
先打开板子的原理图和位置图
嵌入式开发和学习,板子硬件的原理图和位置图PDF图纸是不可或少的哈aio-3568i-位置图背面pdf          2021/8/6 23:56
aio-3568j-位置图正面pdf          2021/8/6 23:57
MB-JM3-RK3568-V12-20210616pdf    2021/8/7 8:25

【临时使用可以不用修改的!^_但是是给WIFI和以太网RJ45供电的,长期使用可能会损害相关器件!^_】
2、因AIO-3568J板子是核心板+底板形式,firefly官方并没有开放核心板的原理图,所以dts的配置需要参考发布的Android11源码;
主要参考:IO电源域和RK809配置部分;
可看下此篇文章IO电源域和RK809知识点:
https://blog.csdn.net/soar999999/article/details/120102934

[[RK3568 Android11] 教程之IO电源域和rk809 DTS讲解
两套SDK源码对比最终的dts配置如下:
lIO电源域配置 (rk3568-evbd.tsi) :

Y:\rk3568_Android11.0_ToyBrick\kernel\arch\arm64\boot\dts\rockchip\rk3568-evb.dtsi
 /*
  * There are 10 independent IO domains in RK3566/RK3568, including PMUIO[0:2] and VCCIO[1:7].
  * 1/ PMUIO0 and PMUIO1 are fixed-level power domains which cannot be configured;
  * 2/ PMUIO2 and VCCIO1,VCCIO[3:7] domains require that their hardware power supply voltages
  *    must be consistent with the software configuration correspondingly
  *    a/ When the hardware IO level is connected to 1.8V, the software voltage configuration
  *       should also be configured to 1.8V accordingly;
  *    b/ When the hardware IO level is connected to 3.3V, the software voltage configuration
  *       should also be configured to 3.3V accordingly;
  * 3/ VCCIO2 voltage control selection (0xFDC20140)
  *    BIT[0]: 0x0: from GPIO_0A7 (default)
  *    BIT[0]: 0x1: from GRF
  *    Default is determined by Pin FLASH_VOL_SEL/GPIO0_A7:
  *    L:VCCIO2 must supply 3.3V
  *    H:VCCIO2 must supply 1.8V
  */
&pmu_io_domains {
    status = "okay";
    pmuio1-supply = <&vcc3v3_pmu>;
    pmuio2-supply = <&vcc3v3_pmu>;
    vccio1-supply = <&vccio_acodec>;
    vccio3-supply = <&vccio_sd>;
    vccio4-supply = <&vcc_1v8>;
    vccio5-supply = <&vcc_3v3>;
    vccio6-supply = <&vcc_1v8>;
    vccio7-supply = <&vcc_3v3>;
};

&pwm4 {
    status = "okay";
};

【以下完全相同:就不上源码了!】
RK809各路输出电压配置 (rk3568-evb.dtsi) :

P:\AIO-3568J\rk3568_Android11.0_ToyBrick\kernel\arch\arm64\boot\dts\rockchip\rk3568-firefly-core.dtsi

3、【经过确认:可以不用修改。虽然Firefly的rbin的版本比ToyBrick的新!^_】

编译系统烧入固件验证
DTS里IO电源域和RK809都配置好后,编译固件,烧录到板子上验证烧录后,AIO-3568J板子会大概率崩溃重启,偶尔能进入Android系统桌面

用使比较软件对比了原厂的SDK包和firefly发布的SDK包,uboot和kernel部分没看出哪里有区别;然后对firefly固件和原厂SDK编译出来的固件开机log; 发现使用的DDR配置版本不同,firely使用的的版本比较新,所以尝试更新下DDR版本:路径: 
sdk/rkbin

比较目录后,果真是有区别;
解决办法: 把firefly的rkbin目录有差异的地方都拷贝过来;
重新编译固件: ./build.sh -UKAu
修改过后,AIO-3568J板子每次开机都能稳定的运行,没有出现崩溃和重启现象;老化了一段时间,系统正常;

Y:\rk3568_Android11.0_ToyBrick\rkbin\RKBOOT\RK3566MINIALL.ini
[CHIP_NAME]
NAME=RK3568
[VERSION]
MAJOR=1
MINOR=1
[CODE471_OPTION]
NUM=1
Path1=bin/rk35/rk3566_ddr_1056MHz_v1.08.bin
Sleep=1
[CODE472_OPTION]
NUM=1
Path1=bin/rk35/rk356x_usbplug_v1.09.bin
[LOADER_OPTION]
NUM=2
LOADER1=FlashData
LOADER2=FlashBoot
FlashData=bin/rk35/rk3566_ddr_1056MHz_v1.08.bin
FlashBoot=bin/rk35/rk356x_spl_v1.11.bin
[OUTPUT]
PATH=rk356x_spl_loader_v1.08.111.bin
[SYSTEM]
NEWIDB=true
[FLAG]
471_RC4_OFF=true
RC4_OFF=true

新版本:
[CHIP_NAME]
NAME=RK3568
[VERSION]
MAJOR=1
MINOR=1
[CODE471_OPTION]
NUM=1
Path1=bin/rk35/rk3566_ddr_1056MHz_v1.09.bin
Sleep=1
[CODE472_OPTION]
NUM=1
Path1=bin/rk35/rk356x_usbplug_v1.10.bin
[LOADER_OPTION]
NUM=2
LOADER1=FlashData
LOADER2=FlashBoot
FlashData=bin/rk35/rk3566_ddr_1056MHz_v1.09.bin
FlashBoot=bin/rk35/rk356x_spl_v1.11.bin
[OUTPUT]
PATH=rk356x_spl_loader_v1.09.111.bin
[SYSTEM]
NEWIDB=true
[FLAG]
471_RC4_OFF=true
RC4_OFF=true

4、替换uboot的三个文件,重新编译uboot。刷机就可以进去了!
Y:\rk3568_Android11.0_ToyBrick\u-boot\arch\arm\mach-rockchip\board.c

#include <asm/arch/param.h>
#ifdef CONFIG_DM_CHARGE_DISPLAY
#include <power/charge_display.h>
#endif
#ifdef CONFIG_DM_DVFS
#include <dvfs.h>
#endif
#ifdef CONFIG_ROCKCHIP_IO_DOMAIN
#include <io-domain.h>
#endif
#ifdef CONFIG_DM_REGULATOR
#include <power/regulator.h>
#endif
#ifdef CONFIG_DRM_ROCKCHIP
#include <video_rockchip.h>
#endif
#ifdef CONFIG_ROCKCHIP_DEBUGGER
#include <rockchip_debugger.h>
#endif
#include <of_live.h>
#include <dm/root.h>
#include <console.h>
#include <boot_rkimg.h>

#define BLK_OFFSET_31K    62
#define ABNORMAL_BOOT_COUNT    2
static long abnormal_boot_detect(void)
{
#ifdef CONFIG_ABNORMAL_BOOT_DETECT
    long ret;
    char *buf;
    struct blk_desc *dev_desc;
    char flag;
    dev_desc = rockchip_get_bootdev();
    lbaint_t start = BLK_OFFSET_31K;

buf = (char *)memalign(ARCH_DMA_MINALIGN, RK_BLK_SIZE);
    if(!buf) {
        printf("%s: out of memory!\n", __func__);
        return -ENOMEM;
    }

ret = blk_dread(dev_desc, start, 1, buf);
    if(ret < 0) {
        printf("%s: failed to get abnormal boot flag, ret=%lu\n",
                __func__, ret);
        return ret;
    }

flag = buf[0];
    if(flag < ABNORMAL_BOOT_COUNT) {
        printf("Abnormal boot count: %d\n", flag);
        flag++;
        buf[0] = flag;
        ret = blk_dwrite(dev_desc, start, 1, buf); 
    } else {
        buf[0] = 0;
        ret = blk_dwrite(dev_desc, start, 1, buf); 
        printf("Enter bootrom download...");
        mdelay(100);
        writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
        do_reset(NULL, 0, 0, NULL);
        printf("failed!\n");
    }

return ret;
#else
    return 0;
#endif
}

static void board_debug_init(void)
{
    if (!gd->serial.using_pre_serial &&
        !(gd->flags & GD_FLG_DISABLE_CONSOLE))
        debug_uart_init();

if (tstc()) {
        gd->console_evt = getc();
        if (gd->console_evt <= 0x1a) /* 'z' */
            printf("Hotkey: ctrl+%c\n", gd->console_evt + 'a' - 1);
    }

if (IS_ENABLED(CONFIG_CONSOLE_DISABLE_CLI))
        printf("Cmd interface: disabled\n");
}

#ifdef CONFIG_MTD_BLK
static void board_mtd_blk_map_partitions(void)
{
    struct blk_desc *dev_desc;

dev_desc = rockchip_get_bootdev();
    if (dev_desc)
        mtd_blk_map_partitions(dev_desc);
}
#endif

int board_init(void)
{
    board_debug_init();
    abnormal_boot_detect();

#ifdef DEBUG
    soc_clk_dump();
#endif

Y:\rk3568_Android11.0_ToyBrick\u-boot\arch\arm\mach-rockchip\boot_mode.c

#include <asm/arch/toybrick.h>
#include <optee_include/OpteeClientInterface.h>
#include <u-boot/sha256.h>

static int load_SnMacAc_from_vendor(char *sn, char *mac, char *actcode)
{
    int ret;

memset(sn, 0, TOYBRICK_SN_LEN + 1);
    memset(mac, 0, TOYBRICK_MAC_LEN + 1);
    memset(actcode, 0, TOYBRICK_ACTCODE_LEN + 1);

ret = toybrick_get_sn(sn);
    if (ret <= 0) {
        printf("Load sn form vendor failed\n");
        return -EIO;
    }

ret = toybrick_get_mac(mac);
    if (ret != TOYBRICK_MAC_LEN) {
        printf("Load mac form vendor failed\n");
        return -EIO;
    }

ret = toybrick_get_actcode(actcode);
    if (ret != TOYBRICK_ACTCODE_LEN) {
        printf("Load actcode form vendor failed\n");
        return -EIO;
    }

printf("Load SnMacAc from vendor: sn %s, mac %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
            sn, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    return 0;
}

static int save_SnMacAc_to_vendor(char *sn, char *mac, char *actcode)
{
    int ret;

ret = toybrick_set_sn(sn);
    if (ret <= 0) {
        printf("Save sn to vendor failed\n");
        return -EIO;
    }

ret = toybrick_set_mac(mac);
    if (ret != TOYBRICK_MAC_LEN) {
        printf("Save mac to vendor failed\n");
        return -EIO;
    }

ret = toybrick_set_actcode(actcode);
    if (ret != TOYBRICK_ACTCODE_LEN) {
        printf("Save actcode to vendor failed\n");
        return -EIO;
    }

return 0;
}

static int load_SnMacAc_from_rpmb(char *sn, char *mac, char *actcode)
{
    int ret;
    sha256_context ctx;
    uint8_t digest[SHA256_SUM_LEN + 1] = {0};
    uint8_t hash_pre[SHA256_SUM_LEN + 1] = {0};
    uint8_t data_sha256[TOYBRICK_SHA_LEN + 1]={0};

memset(sn, 0, TOYBRICK_SN_LEN + 1);
    memset(mac, 0, TOYBRICK_MAC_LEN + 1);
    memset(actcode, 0, TOYBRICK_ACTCODE_LEN + 1);
    ret = trusty_read_toybrick_SnMacAc(data_sha256, TOYBRICK_SHA_LEN);
    if (ret != 0) {
        printf("Load SnMacAc from rpmb failed\n");
        return -EIO;
    }
    memcpy(hash_pre, data_sha256, SHA256_SUM_LEN);
    sha256_starts(&ctx);
    sha256_update(&ctx,(const uint8_t *)(data_sha256 + SHA256_SUM_LEN), TOYBRICK_DATA_LEN);
    sha256_finish(&ctx, digest);
    if (memcmp(digest, hash_pre, SHA256_SUM_LEN) != 0) {
        printf("SnMacAc from rpmb is invalid\n");
        return -EINVAL;
    }
    memcpy(sn, data_sha256 + SHA256_SUM_LEN, TOYBRICK_SN_LEN);
    memcpy(mac, data_sha256 + SHA256_SUM_LEN + TOYBRICK_SN_LEN, TOYBRICK_MAC_LEN);
    memcpy(actcode, data_sha256 + SHA256_SUM_LEN + TOYBRICK_SN_LEN + TOYBRICK_MAC_LEN, TOYBRICK_ACTCODE_LEN);

if (strlen(sn) == 0) {
        printf("SnMacAc from rpmb is empty\n");
        return -EINVAL;
    }

printf("Load SnMacAc from rpmb: sn %s, mac %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
            sn, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    return 0;
}

static int save_SnMacAc_to_rpmb(char *sn, char *mac, char *actcode)
{
    int ret;
    sha256_context ctx;
    uint8_t digest[SHA256_SUM_LEN + 1] = {0};
    uint8_t data[TOYBRICK_DATA_LEN + 1]={0};
    uint8_t data_sha256[TOYBRICK_SHA_LEN + 1]={0};

memset(&data, 0, sizeof(data));
    memset(&data_sha256, 0, sizeof(data_sha256));
    memcpy(data, sn, TOYBRICK_SN_LEN);
    memcpy(data + TOYBRICK_SN_LEN, mac, TOYBRICK_MAC_LEN);
    memcpy(data + TOYBRICK_SN_LEN + TOYBRICK_MAC_LEN, actcode, TOYBRICK_ACTCODE_LEN);

sha256_starts(&ctx);
    sha256_update(&ctx,(const uint8_t *)data, TOYBRICK_DATA_LEN);
    sha256_finish(&ctx, digest);
    memcpy(data_sha256, digest, SHA256_SUM_LEN);
    memcpy(data_sha256 + SHA256_SUM_LEN, data, TOYBRICK_DATA_LEN);
    
    ret = trusty_write_toybrick_SnMacAc(data_sha256, TOYBRICK_SHA_LEN);
    if (ret != 0) {
        printf("Save SnMacAc to rpmb failed\n");
        return -EIO;
    }

return 0;
}

static int toybrick_check_SnMacAc(void)
{
    int ret = 0;
    int ret_vendor, ret_rpmb;
    char vendor_sn[TOYBRICK_SN_LEN + 1];
    char vendor_mac[TOYBRICK_MAC_LEN + 1];
    char vendor_actcode[TOYBRICK_ACTCODE_LEN + 1];
    char rpmb_sn[TOYBRICK_SN_LEN + 1];
    char rpmb_mac[TOYBRICK_MAC_LEN + 1];
    char rpmb_actcode[TOYBRICK_ACTCODE_LEN + 1];

ret_vendor = load_SnMacAc_from_vendor(vendor_sn, vendor_mac, vendor_actcode);
    ret_rpmb = load_SnMacAc_from_rpmb(rpmb_sn, rpmb_mac, rpmb_actcode);

if (ret_vendor < 0 && ret_rpmb < 0) {
        printf("No SnMacAc found in vendor and rpmb, goto loader ...\n");
        run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0);
        //set_back_to_bootrom_dnl_flag();
        do_reset(NULL, 0, 0, NULL);
    } else if (ret_vendor < 0) {
        printf("No SnMacAc found in vendor, load from rpmb and save to vendor\n");
        ret = save_SnMacAc_to_vendor(rpmb_sn, rpmb_mac, rpmb_actcode);
        do_reset(NULL, 0, 0, NULL);
    } else if (ret_rpmb < 0) {
        printf("No SnMacAc found in rpmb, load from vendor and save to rpmb\n");
        ret = save_SnMacAc_to_rpmb(vendor_sn, vendor_mac, vendor_actcode);
    } else if (memcmp(vendor_sn, rpmb_sn, TOYBRICK_SN_LEN) != 0){
        printf("Warn: SN(%s %s) form vendor and rpmb is different!\n",
                vendor_sn, rpmb_sn);
        ret = save_SnMacAc_to_vendor(rpmb_sn, rpmb_mac, rpmb_actcode);
        do_reset(NULL, 0, 0, NULL);
    } else if (memcmp(vendor_mac, rpmb_mac, TOYBRICK_MAC_LEN) != 0){
        printf("Warn: MAC form vendor and rpmb is different!\n");
        ret = save_SnMacAc_to_vendor(rpmb_sn, rpmb_mac, rpmb_actcode);
        do_reset(NULL, 0, 0, NULL);
    } else if (memcmp(vendor_actcode, rpmb_actcode, TOYBRICK_ACTCODE_LEN) != 0){
        printf("Warn: Actcode form vendor and rpmb is different!\n");
        ret = save_SnMacAc_to_vendor(rpmb_sn, rpmb_mac, rpmb_actcode);
        do_reset(NULL, 0, 0, NULL);
    } else {
        printf("Toybrick check SnMacAc OK, sn %s\n", vendor_sn);
        ret = 0;
    }

return ret;
}

int setup_boot_mode(void)
{
    char env_preboot[256] = {0};
#ifndef CONFIG_ROCKCHIP_RK3288
    toybrick_check_SnMacAc();
#endif
    switch (rockchip_get_boot_mode()) {
    case BOOT_MODE_BOOTLOADER:
        printf("enter fastboot!\n");
#if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV)
        snprintf(env_preboot, 256,
                "setenv preboot; mmc dev %x; fastboot usb 0; ",
                CONFIG_FASTBOOT_FLASH_MMC_DEV);
#elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV)
        snprintf(env_preboot, 256,
                "setenv preboot; fastboot usb 0; ");
#endif

Y:\rk3568_Android11.0_ToyBrick\u-boot\arch\arm\mach-rockchip\boot_rkimg.c

#include <asm/arch/uimage.h>
#include <asm/arch/toybrick.h>
#include <dm/ofnode.h>

#define KEY_DOWN_MIN_VAL    0
#define KEY_DOWN_MAX_VAL    30

__weak int rockchip_dnl_key_pressed(void)
{
#if defined(CONFIG_DM_KEY)
#ifdef CONFIG_CMD_ROCKUSB
    return key_is_pressed(key_read(KEY_VOLUMEUP));
#else
    return key_is_pressed(key_read(KEY_MENU));
#endif

#elif defined(CONFIG_ADC)
    const void *blob = gd->fdt_blob;
    int node, ret, channel = 1;
    u32 val, chns[2];

node = fdt_node_offset_by_compatible(blob, 0, "adc-keys");
    if (node >= 0) {
        if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2))
            channel = chns[1];
    }

ret = adc_channel_single_shot("saradc", channel, &val);
    if (ret) {
        printf("%s: Failed to read saradc, ret=%d\n", __func__, ret);
        return 0;
    }

return ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL));
#endif

return 0;
}

#if defined(CONFIG_ROCKCHIP_EARLY_DISTRO_DTB)
static int rockchip_read_distro_dtb(void *fdt_addr)
{
    const char *cmd = "part list ${devtype} ${devnum} -bootable devplist";
    char *devnum, *devtype, *devplist;
    char devnum_part[12];
    char fdt_hex_str[19];
    char *fs_argv[5];
    char flag[TOYBRICK_FLAG_LEN + 1];
    char dtb_path[128];
    int index = -1;
    //int size;
    //int ret;

if (!rockchip_get_bootdev() || !fdt_addr)
        return -ENODEV;

if (run_command_list(cmd, -1, 0)) {
        printf("Failed to find -bootable\n");
        return -EINVAL;
    }

devplist = env_get("devplist");
    if (!devplist)
        return -ENODEV;

devtype = env_get("devtype");
    devnum = env_get("devnum");
    sprintf(devnum_part, "%s:%s", devnum, devplist);
    sprintf(fdt_hex_str, "0x%lx", (ulong)fdt_addr);

fs_argv[0] = "load";
    fs_argv[1] = devtype,
    fs_argv[2] = devnum_part;
    fs_argv[3] = fdt_hex_str;

if(toybrick_get_flag(flag, &index) < 0)
        strcpy(dtb_path, CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH);
    else
        sprintf(dtb_path, "%s.%s", CONFIG_ROCKCHIP_EARLY_DISTRO_DTB_PATH, flag);
    fs_argv[4] = dtb_path;

if (do_load(NULL, 0, 5, fs_argv, FS_TYPE_ANY))
        return -EIO;

if (fdt_check_header(fdt_addr))
        return -EBADF;

printf("DTB(Distro): %s\n", dtb_path);

return 0;
}
#endif

参考资料:
https://blog.csdn.net/soar999999/article/details/120102401
[RK3568 Android11] 教程之原厂SDK源码适配AIO-3568J板子跑起来

https://t.rock-chips.com/wiki.php
ToyBrick
前言
本站旨在高效地知识分享--所见即所得。
让Toybrick板用户能够快速上手,利用Toybrick系列开发板快速开发、评估以及产品化。

https://t.rock-chips.com/wiki.php?filename=%E6%9D%BF%E7%BA%A7%E6%8C%87%E5%8D%97/TB-RK3568X
TB-RK3568X

https://t.rock-chips.com/wiki.php?filename=%E8%B5%84%E6%96%99%E4%B8%8B%E8%BD%BD/%E8%B5%84%E6%96%99%E4%B8%8B%E8%BD%BD
Android源码下载
Android源码下载地址
https://eyun.baidu.com-s/3c2U4Y7A#sharelink/path=%2F

20230126使AIO-3568J开发板在原厂Android11下跑起来相关推荐

  1. 20230129在AIO-3568J开发板在原厂Android11下跑通6275s

    20230129在AIO-3568J开发板在原厂Android11下跑通6275s 0.使用Firefly的AIO-3568J的自带Andorid11,内核按照Firefly的模式编译,Android ...

  2. 关于友善电子开发板RK3399再Ubuntu系统下串口绑定

    一.在友善电子RK3399开发板上面的Ubuntu系统下串口绑定. 我的需求是在两个不同厂家的串口号进行绑定,以前用一个厂家的两个串口进行绑定,然后发现无法识别那个串口因为串口序列号是一致的,所以本文 ...

  3. jeston nano开发板 在ubuntu18.04环境下搭建的ROS和arduino小车

    一.准备安装Ubuntu系统 (在vmware上安装)#方便后面的调试 首先,需要我们去官网下载镜像文件,但是由于官方的服务器搭建在境外,因此我们更倾向于使用国内镜像进行下载,比如清华大学镜像,一般来 ...

  4. linux开发板usb摄像头,ARM9+Linux下USB摄像头图像采集

    终于实现了在Micro2440+Linux2.6.29环境下通过NFS文件系统实现USB摄像头图像采集.在此,做一个总结,以备后续参考. 实验条件:RedHat9.0(内核版本2.4.18),Micr ...

  5. i.MX6ULL驱动开发 | 33 - NXP原厂网络设备驱动浅读(LAN8720 PHY)

    一.硬件原理 1. 以太网硬件架构 正点原子imx6ull开发板的以太网硬件整体架构如下图: 2. LAN8720A PHY芯片 3. RJ45接口 用来插网线的是RJ45座,与PHY芯片相连的时候中 ...

  6. 迅为RK3399开发板支持在Ubuntu系统下安装Docker

    Docker提供了打包应用软件及其运行环境的机制,降低了应用配置管理的复杂度,可以将开发环境.代码.配置文件等一并打包到这个容器中,并发布和应用到任意平台中,极大提升了应用交付的效率. Docker一 ...

  7. 嵌入式 linux 程序不能运行,嵌入式Linux中在开发板上/usr/bin目录下不能运行自己交叉编译的程序...

    ~~一个很不知道错在哪里的问题 我编译了内核与文件系统后成功下载后 我将我交叉编译的hello,led测试程序,key测试程序下载到/usr/bin中不能运行:其现象如下: [root@YWW-244 ...

  8. kermit开发板启动Linux乱码,Ubuntu下C-kermit的使用

    c-kermit是Linux下简单易用的串口工具,配置简单,现说说我的安装使用方法,我用的USB转串口+VM,环境不同可能设备名不一样 1.安装: sudo apt-get install ckerm ...

  9. 韦东山JZ2440开发板之EOP在win10下驱动安装方法

    今天用win10安装EOP驱动时发现了两个问题,解决方法放在这里,供有需要的朋友借鉴 1.首先安装时一直提示无法找到驱动,后来经仔细观察发现,驱动文件少了一个ftd2xx.h的文件,重新下载,安装成功 ...

最新文章

  1. 以太坊区块链Ethereum开发资料汇总
  2. 百度Apollo 3.5是如何设计Cyber RT计算框架的?
  3. 如何写出符合Python审美的代码风格?
  4. 148. Leetcode 455. 分发饼干 (贪心算法-基础题目)
  5. 解决Button在IE6、7下的自适应宽度问题
  6. 倍增:st表(模板)(洛谷P3865)
  7. Python学习笔记(4):Python如何设置类似C语言静态函数
  8. 得到python对象的真实大小
  9. c#启动mysql数据库服务器_c# - 使用C#应用程序连接Web服务器中的mysql数据库
  10. centos7.5 su: 无法设置组: 不允许的操作(实测补充)(这是乱获取权限导致的,要注意权限问题)以及推荐文件操作
  11. Android开发小结Part2:目录
  12. Eclipse中java文件头注释格式设置
  13. http2-frame-WINDOW_UPDATE
  14. ignite mysql 持久化_2 ignite关键特性
  15. 用blender环绕物体拍摄
  16. 缓存穿透、击穿、雪崩
  17. 网站开发进阶(十一)如何将一个jsp页面嵌套在另一个页面中
  18. 程序员求职简历,项目经验怎么写?免费修改简历并提供简历模板
  19. LiveNVR监控流媒体Onvif/RTSP功能支持海康摄像头通过海康SDK的方式接入直播观看录像回看预置位操作
  20. 阿里云的PolarDB要开源了?这个数据库到底强在哪?

热门文章

  1. anaconda打不开解决办法
  2. 【赠书福利】掘金爆火小册同名《Spring Boot源码解读与原理剖析》正式出书了!...
  3. 腾讯、阿里、百度等互联网巨头究竟如何布局元宇宙的?
  4. 小程序开发工具_有哪些好用的微信小程序开发工具?如何选择?
  5. R 语言:简短的示例
  6. 光纤传输设备学习资料:12路Base Camera link 全景影像复合光纤传输设备
  7. matlab到word文字转变,Matlab代码或中文复制到word变成乱码的解决技巧
  8. 关键元器件选型设计指引--通用逻辑器件(逻辑IC)
  9. Vue中的export和export default{}用法
  10. 3种解决方案:如何彻底删除C盘的垃圾文件