Hongmeng System Research No. 3:プラットフォーム移植の第一歩を踏み出す

OpenHarmony OS 2.0がリリースされたとき、標準システムは1つのハードウェアプラットフォームHi3516DV300のみをサポートしていましたが、AndroidとIOSは開発者が使用できるエミュレーターを提供していました。これも理解できます。結局のところ、Huaweiは長い間機器サプライヤーであり、その専門知識はハードウェアですが、ソフトウェア開発のバックグラウンドが不足しています。Hongmengアプリ開発はエミュレーターを提供しますが、これは実際のマシンエミュレーターであり、使用する前にHuaweiの開発プラットフォームに接続する必要があります。

OpenHarmony OS 2.0標準システムはエミュレーターをサポートしていないので、自分たちでそれを実行して、十分な食料と衣服を用意しましょう!

この記事では、次のことを学びます。

  1. OpenHarmonyOS2.0標準システムに新しい製品定義を追加する方法。

  2. 新しいプラットフォームをビルドシステムに移植する方法。

  3. エミュレーター用にLinuxカーネルをコンパイルします。

一般的に使用されるシミュレータソフトウェアはQEMUで、さまざまなハードウェアモデルをシミュレートでき、ARM、ARM64、RISC-V、X86およびその他の命令もサポートします。多くの既存の組み込みLinuxの資料や書籍では、Vexpress A9を例として取り上げているため、この移植ではVexpressA9もターゲット移植として採用されています。QEMUによってエミュレートされたVExpressA9プラットフォームの概要は次のとおりです。

QEMU / VExpress A9は、ARMVExpress-A9FPGA開発ボードのソフトウェアシミュレーションのためにQEMUシミュレーターで使用される命令レベルの仮想マシンです。QEMU / VExpressはソフトウェアエミュレーションモードであるため、シングルコアCortex-A9、マルチコアCortex-A9、マルチコアCortex-A15などのさまざまなモードに構成できます。 VExpressFPGA開発ボード上のほとんどのペリフェラルをシミュレートします。

OpenHarmonyの製品定義を追加しました

OpenHarmonyシステムのbuild.shコンパイルスクリプトは、ここではvexpress-a9という名前の製品名パラメーターproduct-nameを取得する必要があります。

製品定義はproductdefine/commonディレクトリにあり、そのサブディレクトリproductsの下にHi3516DV300.jsonファイルがあります。これはHi3516DV300モデルに対応します。コピーを作成し、vexpress-a9.jsonという名前を付け、vexpress-a9.jsonファイルを編集して、次を追加します。

  "product_name": "Hi3516DV300",
  "product_device": "hi3516dv300",
  "hisilicon_products:hisilicon_products":{},

これらの3行を次のように変更します。

  "product_name": "vexpress-a9",
  "product_device": "vexpress-a9",
  "qemu_products:qemu_products":{},

product_deviceがデバイス名の場合、productdefine / common / device /にはJSONファイルvexpress-a9.jsonも必要であり、そのコンテンツはhi3516dv300.jsonからコピーできます。

{
    "target_os": "ohos",
    "target_cpu": "arm"
}

OpenHarmonyのサブシステム定義を追加します

Hongmengシステムは、IoTデバイスから携帯電話まで、さまざまなタイプのデバイスをサポートします。ハードウェアリソースと機能要件も異なるため、システム要件をカスタマイズおよび調整でき、システムはさまざまなモジュールとサブシステムに分割されます。

サブシステムの定義はbuild/subsystem_config.jsonファイルです。ご覧のとおり、ここでのサブシステム名は基本的にproductdefine / common / products/Hi3516DV300.jsonに1対1で対応しています。このように、サブシステムの比較的完全なセットがここで定義され、各製品が独自のニーズに応じてサブシステムの独自のサブセットを定義していることが理解できます。ここでは、QEMUのサブシステムエントリを追加します。

    "qemu_products": {
      "project": "hmf/qemu_products",
      "path": "device/qemu/build",
      "name": "qemu_products",
      "dir": "device/qemu"
    },

サブシステムには、名前、パス、およびサブシステムビルドスクリプトへのパスが含まれます。ここで、qemu_productsのコンパイルスクリプトパスはdevice / qemu / buildです。最初に、ohos.buildを追加します。このファイルを作成する必要があります。作成しないと、ビルドスクリプトはこのサブシステムの構築を実行しません。device/ hisilicon/buildを参照してください。 /ohos。ビルドファイル:

{
    "subsystem": "qemu_products",
    "parts": {
        "qemu_products": {
            "module_list": [
                "//device/qemu/build:products_group"
            ]
        }
    }
}

module_listは依存関係のターゲットを指定するため、次のディレクトリにBUILD.gnファイルも追加する必要があります。

import("//build/ohos.gni")

group("products_group") {
  if (device_type == "vexpress-a9") {
    deps = [
      "//device/qemu/vexpress-a9:vexpress-a9_group",
    ]
  }
}

このビルドファイルは、device / qemu /vexpress-a9/の下のビルドターゲットvexpress-a9_groupに依存します。この時点で、新しいプラットフォームの移行のステップに入りました。

新しいプラットフォームの移植には、カーネルコンパイル、ドライバー開発、ルートファイルシステム、イメージ生成など、複雑で作業負荷が非常に大きいコンテンツが多数含まれているため、最初にカーネルコンパイルについて説明します。

VexpressA9のカーネルをコンパイルします

組み込みLinuxカーネルコンパイルに関する多くの情報がインターネット上にあります。ここでは、HongmengOSのビルドシステムにカーネルコンパイル手順を追加する方法について説明します。

device / hisilicon / hi3516dv300の下にあるビルドスクリプトを参照すると、カーネルのコンパイルは主に3つのステップに分かれています。

  1. Linux4.19カーネルにHi3516DV300製品のパッチを適用します。

  2. カーネルをコンパイルし、カーネルイメージuImageを生成します。

  3. Hi3516DV300のドライバーをパッケージ化します。

Vexpress A9の場合、それほど複雑にすることはなく、元のLinux4.19ソースコードでカーネルイメージをコンパイルします。

カーネルイメージには、zImageとuImageの2種類があり、zImageをQEMUで直接ロードでき、u-bootを介してuImageをロードする必要があるため、最初にzImageをコンパイルします。

  1. デバイス/qemu/vexpress-a9/にBUILD.gnファイルを追加します。

import("//build/ohos.gni")

print("vexpress-a9_group in")
group("vexpress-a9_group") {
  deps = [
    "kernel:kernel",
  ]
}
  1. 新しいディレクトリdevice/qemu / vexpress-a9 / kernelを作成し、このディレクトリにBUILD.gn、kernel.mk、build_kernel.shファイルを追加します。

その中で、BUILD.gnはHongmengビルドシステムのルール定義ファイルです。

import("//build/ohos.gni")

kernel_build_script_dir = "//device/qemu/vexpress-a9/kernel"
kernel_source_dir = "//kernel/linux-4.19"

action("kernel") {
  script = "build_kernel.sh"
  sources = [ kernel_source_dir ]

  outputs = [ "$root_build_dir/packages/phone/images/zImage" ]
  args = [
    rebase_path(kernel_build_script_dir, root_build_dir),
    rebase_path("$root_out_dir/../KERNEL_OBJ"),
    rebase_path("$root_build_dir/packages/phone/images"),
    device_type,
  ]
}

その中で定義されているビルドターゲット「カーネル」は、build_kernel.shスクリプトを実行します。

echo "call build_kernel.sh"

pushd ${1}

export OHOS_ROOT_PATH=$(pwd)/../../../..
#note out_dir style:out/xx/
export OUT_DIR=$2

LINUX_KERNEL_OUT=${OUT_DIR}/kernel/src_tmp/linux-4.19
LINUX_KERNEL_ZIMAGE_FILE=$LINUX_KERNEL_OUT/arch/arm/boot/zImage

make -f kernel.mk

if [ -f ${LINUX_KERNEL_ZIMAGE_FILE} ];then
    echo "zImage: ${LINUX_KERNEL_UIMAGE_FILE} build success"
else
    echo "zImage build failed!!!"
    exit 1
fi

mkdir -p ${3}
cp ${2}/kernel/src_tmp/linux-4.19/arch/arm/boot/zImage ${3}/zImage
popd

kernel.mkファイルはスクリプトで再び使用されます。

PRODUCT_NAME=$(TARGET_PRODUCT)

OHOS_BUILD_HOME := $(OHOS_ROOT_PATH)

KERNEL_SRC_PATH := $(OHOS_BUILD_HOME)/kernel/linux-4.19

KERNEL_SRC_TMP_PATH := $(OUT_DIR)/kernel/src_tmp/linux-4.19


PREBUILTS_GCC_DIR := $(OHOS_BUILD_HOME)/prebuilts/gcc

PREBUILTS_CLANG_DIR := $(OHOS_BUILD_HOME)/prebuilts/clang
CLANG_HOST_TOOLCHAIN := $(PREBUILTS_CLANG_DIR)/host/linux-x86/clang-r353983c/bin


CLANG_CC := $(CLANG_HOST_TOOLCHAIN)/clang

KERNEL_HOSTCC := $(CLANG_HOST_TOOLCHAIN)/clang

KERNEL_PREBUILT_MAKE := make

KERNEL_ARCH := arm
KERNEL_TARGET_TOOLCHAIN := $(PREBUILTS_GCC_DIR)/linux-x86/arm/gcc-linaro-7.5.0-arm-linux-gnueabi/bin
KERNEL_TARGET_TOOLCHAIN_PREFIX := $(KERNEL_TARGET_TOOLCHAIN)/arm-linux-gnueabi-

KERNEL_PERL := /usr/bin/perl

KERNEL_CROSS_COMPILE :=
KERNEL_CROSS_COMPILE += CC="$(CLANG_CC)"
KERNEL_CROSS_COMPILE += HOSTCC="$(KERNEL_HOSTCC)"
KERNEL_CROSS_COMPILE += PERL=$(KERNEL_PERL)
KERNEL_CROSS_COMPILE += CROSS_COMPILE="$(KERNEL_TARGET_TOOLCHAIN_PREFIX)"

KERNEL_MAKE := \
    PATH="$(BOOT_IMAGE_PATH):$$PATH" \
    $(KERNEL_PREBUILT_MAKE)

KERNEL_IMAGE_FILE := $(KERNEL_SRC_TMP_PATH)/arch/arm/boot/zImage

$(KERNEL_IMAGE_FILE):
 echo "build kernel..."
 rm -rf $(KERNEL_SRC_TMP_PATH);mkdir -p $(KERNEL_SRC_TMP_PATH);cp -arfL $(KERNEL_SRC_PATH)/. $(KERNEL_SRC_TMP_PATH)/
 $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) distclean
 $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) vexpress_defconfig
 $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) zImage
 $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) dtbs
 $(KERNEL_MAKE) -C $(KERNEL_SRC_TMP_PATH) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) modules

.PHONY: build-kernel
build-kernel: $(KERNEL_IMAGE_FILE)

このMakefileで、クロスコンパイルツールチェーンを指定し、カーネルコンパイルを実行して、最後にzImageイメージを生成します。

ビルドスクリプトを使用してシステムをコンパイルしてみましょう。

./build.sh --product-name vexpress-a9 --ccache

次に、QEMUエミュレーターを使用してカーネルを開始します。

$ qemu-system-arm -M vexpress-a9 -m 512M -dtb ./out/KERNEL_OBJ/kernel/src_tmp/linux-4.19/arch/arm/boot/dts/vexpress-v2p-ca9.dts -kernel ./out/KERNEL_OBJ/kernel/src_tmp/linux-4.19/arch/arm/boot/zImage -nographic

結果は次のとおりです。

ご覧のとおり、カーネルがロードされて起動しますが、ルートファイルシステムがありません。ルートファイルシステムの作成とロードについては、後で説明します。

まとめ

Hongmeng OSのビルドシステムは比較的複雑で、bashスクリプト、pythonスクリプト、GNビルドシステム、makeビルドシステム、JSONファイルなどと絡み合っています。一部のファイルはコンパイルプロセス中に生成されますが、これは非常に理解しにくいものです。この記事を通して、Hongmeng標準システムを移植する手順は次のとおりであることがわかります。

  1. 製品定義のJSONファイルを作成する

  2. サブシステム定義のJSONファイルを書き込む

  3. カーネルイメージ、ドライバー、システムイメージ、ユーザーイメージなどの生成を含む、デバイスのビルドスクリプトを追加します。通常はdevice / <manufactory>/<device_type>の下にあります。

OpenHarmony 2.0システムのソースコードを変更するために、giteeでいくつかのOpenHarmony 2.0ソースコードライブラリもフォークします。上記の変更は私のフォークソースコードライブラリにあり、興味のある友人は次のサイトにアクセスできます。

https://gitee.com/mogoweb

今後もHongmengシステムの移植を分析していきますので、ご期待ください!

おすすめ

転載: blog.csdn.net/mogoweb/article/details/118282758