6

开发板如何适配OpenHarmony 3.2-开源基础软件社区-51CTO.COM

 1 year ago
source link: https://ost.51cto.com/posts/22868
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

OpenAtom OpenHarmony(以下简称“OpenHarmony”) 3.2 Beta5版本在OpenHarmony 3.1 Release版本的基础上,有以下改变:性能上有很大的提升、标准系统应用开发框架增强、标准系统分布式能力增强。

本文介绍诚迈科技基于RK3568设计的HCPAD-100开发板以及基于RK3566设计的中控屏HongzPad2022在OpenHarmony 3.2 Beta5版本上的适配过程。

涉及到开发板的添加/u-boot /linux-5.10/分区表/根文件系统/显示/触摸/USB的移植过程以及OpenHarmony所依赖的驱动特性介绍。

如何添加新的开发板进行编译

参照DAYU200的工程配置文件我们新建自己的编译命令。1)在device/board/目录新建archermind目录,新建rk3568/rk3588/rk3399目录,并添加相关的工程文件。

开发板如何适配OpenHarmony 3.2-开源基础软件社区

2)在vendor目录新建archermind目录。新建以下几个目录,并添加相关的工程文件。

开发板如何适配OpenHarmony 3.2-开源基础软件社区

3)修改vendor/archermind/hongzos_rk3568/config.json文件,product_name改成hongzos_rk3568,device_build_path改成第一步新建的目录。

{
  "product_name": "hongzos_rk3568",
  "device_company": "rockchip",
  "device_build_path": "device/board/archermind/rk3568",
  "target_cpu": "arm",
  "type": "standard",
  "version": "3.0",
  "board": "rk3568",

通过./build.sh --product-name hongzos_rk3568来编译出我们自己开发板的镜像,编译完后对应开发板的image镜像放在out/rk3568/packages/phone/目录。相关代码放在文章最后的参考链接。

开发板如何适配OpenHarmony 3.2-开源基础软件社区

U-Boot移植

U-boot是通过二进制镜像直接放在device/board/hihope/rk3568/loader目录下的,这个目录下涉及到文件如下:

1)下载rk官方发布的uboot源码

git clone https://github.com/rockchip-linux/u-boot.git

2)修改make.sh, 指定RKBIN_TOOLS的路径

RKBIN_TOOLS=rkbin/tools

3)增加代码读取ramdisk分区到指定的内存位置,修改cmd/pxe.c

#include "boot_rkimg.h"
#define BLK_CNT(_num_bytes, _block_size)        \
                ((_num_bytes + _block_size - 1) / _block_size)

static char* load_ramdisk_from_partition(void *buffer)
{
        struct blk_desc *desc = rockchip_get_bootdev();
        disk_partition_t part_ramdisk_boot;
        static char initrd_str[28];
        long blk_cnt = 0, blks_read = 0;
        long blk_start = 0;
        if (part_get_info_by_name(desc, "ramdisk", &part_ramdisk_boot) < 0) {
                printf("No ramdisk partition\n");
                return NULL;
        }
        blk_cnt = part_ramdisk_boot.size;
        blk_start = part_ramdisk_boot.start;
        printf("Load from partition ' ramdisk ' to address 0x%p, count: %ld total block(s) by ludao\n", buffer, blk_cnt);
        blks_read = blk_dread(desc, blk_start, blk_cnt, buffer);
        if (blks_read != blk_cnt) {
             return NULL;
        }
        printf("Read from partition ' ramdisk ' done, from 0x%lx total block(s) 0x%lx\n", blk_start, blk_cnt);
        sprintf(initrd_str, "0x%p:0x%lx", buffer, blk_cnt*(part_ramdisk_boot.blksz));
        printf("Openharmony ramdisk_addr_r = %s\n", initrd_str);

        return initrd_str;
}
static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        if (label->initrd) {
                if (get_relfile_envaddr(cmdtp, label->initrd, "ramdisk_addr_r") < 0) {
                        printf("Skipping %s for failure retrieving initrd\n",
                                        label->name);
                        return 1;
                }

                bootm_argv[2] = initrd_str;
                strncpy(bootm_argv[2], env_get("ramdisk_addr_r"), 18);
                strcat(bootm_argv[2], ":");
                strncat(bootm_argv[2], env_get("filesize"), 9);
        }else{
                void *buffer = (void *)env_get_ulong("ramdisk_addr_r", 16, 0);
                bootm_argv[2] = load_ramdisk_from_partition(buffer);
                if(bootm_argv[2]){
                    printk("initrd = %s \n", bootm_argv[2]);
                }
        }

4)指定交叉编译器和平台开始编译,编译完成后根目录会生成u-boot.bin

./make.sh CROSS_COMPILE=aarch64-linux-gnu- rk3568

所有相关代码已经放到开源社区,大家可以下载下来直接编译使用,相关代码放在文章最后的参考链接。

Linux-5.10移植

1)内核编译脚本

linux编译脚本的是放在device/board/hihope/rk3568/kernel目录下的build_kernel.sh文件,由于kernel/linux/linux-5.10是公共代码,OpenHarmony编译脚本是通过打补丁的方式来适配不同平台,不同的平台有自己的内核补丁。

编译脚本会先把kernel/linux/linux-5.10拷贝到out/kernel/src_tmp/linux-5.10/,然后打上3568的内核补丁patch -p1 < kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch后编译生成自己的镜像,不利于我们开发,我们自己开发过程中做如下修改,这样方便我们开发过程中的修改。

先进入kernel/linux/linux-5.10目录
patch -p1 < kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch
修改device/board/hihope/rk3568/kernel/build_kernel.sh
注释掉 
//patch -p1 < ${KERNEL_PATCH}

2)设备树的定制,首先我们需要有自己的板子的设备树例如rk3568-chujue-linux.dts

把设备树放到kernel/linux/linux-5.10/arch/arm64/boot/dts/rockchip/目录
修改kernel/linux/linux-5.10/ make-ohos.sh

model_list=(
        "TB-RK3568X0   arm64 0xfe660000 rk3568-toybrick-x0-linux  Image rockchip_linux_defconfig"
        "TB-RK3568X10  arm64 0xfe660000 rk3568-toybrick-x10-linux Image rockchip_linux_defconfig"
)

修改其中的TB-RK3568X0,把rk3568-toybrick-x0-linux改成我们自己的rk3568-chujue-linux.dts,

TB-RK3568X0是在device/board/hihope/rk3568/kernel/build_kernel.sh指定的

这样编程后生产设备树就是我们自己开发板的,设备树如果不对,机器将会无法开机,U-boot也会无法开启。

3)内核config的定制

文件位置kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig3.2 显示设备需要打开CONFIG_DRM_PANEL_SIMPLE配置显示才能正常显示

CONFIG_DRM_PANEL_SIMPLE = y
kernel/linux/linux-5.10/drivers/gpu/drm/panel/panel-simple.c
注释掉
//int panel_simple_loader_protect(struct drm_panel *panel)

4)启动Logo定制修改device/board/hihope/rk3568/kernel目录的图片即可

开发板如何适配OpenHarmony 3.2-开源基础软件社区

5)启动参数的定制

kernel/linux/linux-5.10/ make-ohos.sh

cmdline="append earlycon=uart8250,mmio32,${uart} root=PARTUUID=614e0000-0000-4b53-8000-1d28000054a9 rw rootwait rootfstype=ext4

1)rk3568采样的是GPT格式的分区表,v3.2新增加了三个分区sys_prod, chip-prod,ramdisk通过修改以下文件来修改分区表的配置,我们可以直接使用dayu开发板的分区表。device/board/hihope/rk3568/loader/parameter.txt

FIRMWARE_VER:11.0
MACHINE_MODEL:rk3568_r
MACHINE_ID:007
MANUFACTURER: rockchip
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: rk3568_r
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE:mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(misc),0x00003000@0x00006000(resource),0x00030000@0x00009000(boot_linux:bootable),0x00002000@0x00039000(ramdisk),0x00400000@0x0003B000(system),0x00200000@0x0043B000(vendor),0x00019000@0x0063B000(sys-prod),0x00019000@0x00654000(chip-prod),0x00010000@0x0066D000(updater),-@0x0067D000(userdata:grow)
uuid:system=614e0000-0000-4b53-8000-1d28000054a9
uuid:boot_linux=a2d37d82-51e0-420d-83f5-470db993dd35

device/board/hihope/rk3568/cfg/fstab.rk3568

# fstab file.
#<src>                                                  <mnt_point> <type>    <mnt_flags and options>                              <fs_mgr_flags>
/dev/block/platform/fe310000.sdhci/by-name/system               /usr       ext4     ro,barrier=1  wait,required
/dev/block/platform/fe310000.sdhci/by-name/vendor              /vendor        ext4     ro,barrier=1  wait,required
/dev/block/platform/fe310000.sdhci/by-name/sys-prod              /sys_prod        ext4     ro,barrier=1  wait
/dev/block/platform/fe310000.sdhci/by-name/chip-prod              /chip_prod        ext4     ro,barrier=1  wait
/dev/block/platform/fe310000.sdhci/by-name/userdata               /data       f2fs     discard,noatime,nosuid,nodev,fscrypt=2:aes-256-cts:aes-256-xts  wait,check,fileencryption=software,quota
/dev/block/platform/fe310000.sdhci/by-name/misc /misc none none wait,required

2)如何修改RKDevTool.exe工具加载的分区表

parameter.txt文件中的CMDLINE字段中有mtdparts=,其中0x00002000@0x00002000(uboot)的括号里面是分区的名字,@后面的0x00002000是分区的开始地址,以4k为单位的偏移地址,@前面是分区的大小,注意修改的时候要注意连续性,不要有重叠的位置。

根文件系统

1)ramdisk从3.1到3.2的变化

3.1中ramdisk.Img是放在out/kernel/src_tmp/linux-5.10/boot_linux/目录下被打包到boot_linux.img中。

3.2的ramdisk.Img是直接放在单独的分区里面,由Boot在开机的模式不同的情况下选择加载不同的根文件系统

2)如何修改ramdisk

在.gn文件里面添加对应的配置文件,生成的文件将会被放到ramdisk镜像里面

image_list += [
      "ramdisk",
      "updater_ramdisk",
    ]

显示模块适配

1)Devices tree配置

通过设备树来打开mipi 通道1的配置和hdmi的设备,OpenHarmony 3.2 Beta5 是支持多屏异显的,OpenHarmony 3.1 Release 不支持。

&dsi1 {
        status = "okay";
        //rockchip,lane-rate = <200>;
        dsi1_panel: panel@0 {
                status = "okay";
                compatible = "simple-panel-dsi";
                reg = <0>;
                backlight = <&backlight>;
                reset-delay-ms = <60>;
                enable-delay-ms = <60>;
                prepare-delay-ms = <60>;
                unprepare-delay-ms = <60>;
                disable-delay-ms = <60>;
                dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
                        MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>;
                dsi,format = <MIPI_DSI_FMT_RGB888>;
                dsi,lanes  = <4>;
                panel-init-sequence = [
                        05 78 01 11
                        05 14 01 29
                ];

                panel-exit-sequence = [
                        05 00 01 28
                        05 00 01 10
                ];

                disp_timings1: display-timings {
                        native-mode = <&dsi1_timing0>;
                        dsi1_timing0: timing0 {
                                clock-frequency = <150000000>;
                hactive = <1200>;
                vactive = <1920>;
                hback-porch = <120>;
                hfront-porch = <10>;
                vback-porch = <10>;

&hdmi {
        status = "okay";
        rockchip,phy-table =
                <92812500  0x8009 0x0000 0x0270>,
                <165000000 0x800b 0x0000 0x026d>,
                <185625000 0x800b 0x0000 0x01ed>,
                <297000000 0x800b 0x0000 0x01ad>,
                <594000000 0x8029 0x0000 0x0088>,
                <000000000 0x0000 0x0000 0x0000>;
};

2)内核打开相关的配置

3.2中默认关闭了CONFIG_DRM_PANEL_SIMPLE,但是我们的设备数中字段需要依赖这个配置项,所以需要打开它。

CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_ANALOGIX_DP=y
CONFIG_DRM_DW_HDMI=y
CONFIG_DRM_DW_HDMI_I2S_AUDIO=y
CONFIG_DRM_DW_HDMI_CEC=y
CONFIG_DRM_DW_MIPI_DSI=y

3)HAL层的适配

开发板如何适配OpenHarmony 3.2-开源基础软件社区

显示HDI需要适配两部分:gralloc 和 display_device。

display device适配

display device模块提供显示设备管理、layer管理、硬件加速等功能。

drm设备节点定义

在//device/soc/rockchip/rk3568/hardware/display/src/display_device/drm_device.cpp文件中,可根据实际情况修改

std::shared_ptr<HdiDeviceInterface> DrmDevice::Create()
{
    DISPLAY_DEBUGLOG();
    if (mDrmFd == nullptr) {
        const std::string name("rockchip");
        int drmFd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); // drmOpen(name.c_str(), nullptr);
}

如开发板不支持硬件合成或是有问题的时候,需要在drm_display.cpp文件中跳过gfx的初始化。

int32_t DrmDisplay::Init()
{
    ...
    ...
    ret = preComp->Init();                                                                                          // gfx初始化,这里需要跳过
    DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("can not init HdiGfxComposition"));  // 或者不判断返回值
}

同时在//device/soc/rockchip/rk3568/hardware/display/src//hdi_gfx_composition.cpp文件中修改set_layers方法,全部使用CPU合成显示。

int32_t HdiGfxComposition::SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer)
{
#if 0                                      // CPU合成
            layer->SetDeviceSelect(COMPOSITION_CLIENT);
#else
            if ((layer->GetCompositionType() != COMPOSITION_VIDEO) &&
                (layer->GetCompositionType() != COMPOSITION_CURSOR)) {
                layer->SetDeviceSelect(COMPOSITION_DEVICE);
            } else {
                layer->SetDeviceSelect(layer->GetCompositionType());
            }
#endif
}

gralloc适配

gralloc模块提供显示内存管理功能,OpenHarmony提供了使用与Hi3516DV300参考实现。drm设备节点定义在

//device/soc/rockchip/rk3568/hardware/display/src/display_gralloc/display_gralloc_gbm.c文件中,可根据实际情况修改

const char *g_drmFileNode = "/dev/dri/card0";

1)Devices tree配置

我们的开发板使用的是gt9XX的触摸屏,所以我们把相关的信息配置进去。

gt9xx: gt911@14 {
        compatible = "goodix,gt9xx";
        reg = <0x14>;
        pinctrl-names = "default";
        pinctrl-0 = <&tp_gpio>;
        goodix_irq_gpio = <&gpio3 RK_PB4 IRQ_TYPE_LEVEL_LOW>;
        goodix_rst_gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
          /*touchscreen-inverted-x;*/
          status = "okay";
        };

2)内核驱动配置

打开内核配置CONFIG_TOUCHSCREEN_GT9XX=y

驱动源码里面把所有ABS_MT_WIDTH_MAJOR相关的属性去掉。3.2不识别有这个属性的输入设备。

kernel/linux/linux-5.10/drivers/input/touchscreen/gt9xx/gt9xx.c

//input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);

USB调试适配

1) 调试工具

开发板的USB host是标准的linux驱动架构,OpenHarmony 对这块基本不需要做修改,USB的设备包括鼠标,sdcard都会默认支持。

USB 作为devices,最常用的功能是连接电脑,用电脑端的hdc shell来调试设备,这样我们才能在后续工作中抓取日志分析。

hdc shell “dmesg -Tw” 实时获取kernel 日志

hdc shell “hilog” 获取OpenHarmony 日志

2)USB devices设备的端口选择

init.rk3568.usb.cfg文件中有Usb初始化参数设置,其中最主要的是

sys.usb.controller设置成正确的基地址以及设备类型

"setparam sys.usb.controller fcc00000.dwc3"

至此我们的开发板拥有自己的开发基线,也已经可以进入到桌面,触摸屏,USB鼠标,hdc调试都已经正常工作,我们接下来进行下一阶段的适配工作。

以下是源码仓库地址

​https://gitee.com/harchermindy/vendor_archermind​

​https://gitee.com/harchermindy/device_board_archermind​

​https://gitee.com/harchermindy/uboot-rk-openharmony​

​https://gitee.com/harchermindy/linux-5.10​

开发板如何适配OpenHarmony 3.2-开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK