写点什么

开发板如何适配 OpenHarmony 3.2

  • 2023-04-04
    上海
  • 本文字数:6830 字

    阅读完需:约 22 分钟

简介

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 目录,并添加相关的工程文件。



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



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/目录。相关代码放在文章最后的参考链接。



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 = ykernel/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 目录的图片即可



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.0MACHINE_MODEL:rk3568_rMACHINE_ID:007MANUFACTURER: rockchipMAGIC: 0x5041524BATAG: 0x00200800MACHINE: rk3568_rCHECK_MASK: 0x80PWR_HLD: 0,0,A,0,1TYPE: GPTCMDLINE: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-1d28000054a9uuid: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=yCONFIG_DRM_ANALOGIX_DP=yCONFIG_DRM_DW_HDMI=yCONFIG_DRM_DW_HDMI_I2S_AUDIO=yCONFIG_DRM_DW_HDMI_CEC=yCONFIG_DRM_DW_MIPI_DSI=y
复制代码


3)HAL 层的适配

源码结构



显示 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开发者官方账号 2021-12-15 加入

OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展

评论

发布
暂无评论
开发板如何适配OpenHarmony 3.2_Open Harmony_OpenHarmony开发者_InfoQ写作社区