Yocto中WIC控制以及WKS文件

在使用i.MX BSP的时候,最后总会生成wic文件,那么wic文件是什么呢?它又是如何打包的呢?

WIC

wic文件包含了BootLoader、Kernel以及文件系统。在wic文件中以及创建了分区来表明uboot,/boot和文件系统的位置。因此在烧写的时候,只需要烧写wic文件能正常启动系统。yocto中支持基本的kickstart命令来生成wic文件。

Yocto中的打包过程

Yocto中wic文件的打包由\meta-freescale\wic目录下的wks.in脚本控制,对于8m系统是由imx-imx-boot-bootpart.wks.in控制。

imx-imx-boot-bootpart.wks.in

创建一个可以用dd写入SD卡的映像,用于i.MX8M SoC系列。包括挂载并写入uboot,kernel和rootfs,指定分区表为msdos。

uboot文件的偏移量是32k;

/boot偏移量是8M开始,分区大小为64MB;

文件系统根目录从8Mb开始

# short-description: Create SD card image with a boot partition
# long-description:
# Create an image that can be written onto a SD card using dd for use
# with i.MX SoC family
# It uses u-boot + other binaries gathered together on imx-boot file
#
# The disk layout used is:
#  - ---------- -------------- --------------
# | | imx-boot |     boot     |    rootfs    |
#  - ---------- -------------- --------------
# ^ ^          ^              ^              ^
# | |          |              |              |
# 0 |        8MiB          72MiB          72MiB + rootfs + IMAGE_EXTRA_SPACE (default 10MiB)
#   ${IMX_BOOT_SEEK} 32 or 33kiB, see reference manual
#
//挂载并写入u-boot文件,seek为32
part u-boot --source rawcopy --sourceparams="file=imx-boot" --ondisk mmcblk --no-table --align ${IMX_BOOT_SEEK}
//挂载并写入/boot文件夹
part /boot --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 8192 --size 64
//挂载/,写入rootfs
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 8192
//指定应如何安装引导加载程序,这里使用msdoc分区表
bootloader --ptable msdos

imx-boot-container-bootpart.wks.in

创建一个可以用dd写入SD卡的映像,用于i.MX8M SoC系列,它使用了由U-Boot配方直接提供的名为flash.bin的二进制启动容器,以及由U-Boot的binman工具创建的U-Boot ITB文件。这些文件被添加到启动分区,作为原始拷贝填充到映像中。由U-Boot准备的启动容器已经包含了SPL、U-Boot本身、U-Boot DTB文件、ATF和可选的OP-TEE组件。

作为主线U-Boot的一部分而构建的启动容器与整个mx8m系列使用不同的WKS文件,因为2021.04以后的U-Boot版本提供两个独立的二进制文件,即flash.bin和u-boot.itb。这些文件被打包到启动分区。由U-Boot构建本身产生的二进制文件可以直接替代恩智浦的imx-boot。这些二进制文件的创建是由UBOOT_PROVIDES_BOOT_CONTAINER 变量控制。

#
# The disk layout used is:
#  - ----------- -------------- ----------------------------
# | | flash.bin | u-boot.itb |     boot     |    rootfs    |
#  - ----------- -------------- ----------------------------
# ^ ^           ^            ^              ^              ^
# | |           |            |              |              |
# 0 |        384KiB         8MiB          72MiB          72MiB + rootfs + IMAGE_EXTRA_SPACE (default 10MiB)
#   ${IMX_BOOT_SEEK} 32 or 33kiB, see reference manual
#
part u-boot --source rawcopy --sourceparams="file=flash.bin" --ondisk mmcblk --no-table --align ${IMX_BOOT_SEEK}
part u-boot-itb --source rawcopy --sourceparams="file=u-boot.itb" --ondisk mmcblk --no-table --align 384
part /boot --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 8192 --size 64
part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 8192

bootloader --ptable msdos

imx-base.inc

包含板级信息和BSP软件信息,提供各种文件的命名后缀,指定wks文件,uboot入口信息UBOOT_ENTRYPOINT,驱动,串口信息,内核zImage。udev rules和firmware信息,optee版本信息。

# Provides the i.MX common settings

include conf/machine/include/fsl-default-settings.inc
include conf/machine/include/fsl-default-versions.inc

require conf/machine/include/utilities.inc

# Machines or distros can define which BSP it should use by default. We are
# intending to default for mainline BSP by default and specific machines or
# DISTROs might change it if need.
#
# Two values are considered valid: mainline, nxp
IMX_DEFAULT_BSP ?= "mainline"

# Those are SoC families we'd like to force the use of mainline BSP.
IMX_DEFAULT_BSP:mxs ?= "mainline"
IMX_DEFAULT_BSP:mx5 ?= "mainline"

MACHINEOVERRIDES =. "use-${IMX_DEFAULT_BSP}-bsp:"

# UBOOT_BINARY is used inside the wks files to dynamically find the required
# U-Boot file.
UBOOT_BINARY ?= "u-boot.${UBOOT_SUFFIX}"

# Using the 'IMX_DEFAULT_BOOTLOADER' the machine can support multiple bootloader
# versions. This is done for NXP reference board where we support 'u-boot-fslc'
# and 'u-boot-imx'.
#
# So, for example in imx6qdlsabresd, we support both flavor and for this we
# define:
#
# ,----[ imx6qdlsabresd.conf ]
# | ### u-boot-fslc settings ###
# |
# | SPL_BINARY:pn-u-boot-fslc = "SPL"
# | UBOOT_MACHINE:pn-u-boot-fslc ?= "mx6sabresd_defconfig"
# | UBOOT_SUFFIX:pn-u-boot-fslc = "img"
# |
# | ### u-boot-imx settings ###
# |
# | # The u-boot-imx does not provide unified functionality for DL/Q/QP SoC
# | # variants. Change the defconfig to the targeted SoC variant.
# | UBOOT_MACHINE:pn-u-boot-imx ?= "mx6qsabresd_defconfig"
# | UBOOT_SUFFIX:pn-u-boot-imx = "imx"
# `----
#
# As result, the 'UBOOT_SUFFIX' is dynamically set based on the preferred U-Boot
# flavor to use.
#
# For machines where one of the flavors is required, we can force it. An example
# is the imx53qsb, which we define:
#
# ,----[ imx53qsb.conf ]
# | # This machine is not supported by u-boot-imx as it is not tested by NXP on this
# | # board. So we force it to use u-boot-fslc which is based on mainline here.
# | IMX_DEFAULT_BOOTLOADER = "u-boot-fslc"
# |
# | UBOOT_MAKE_TARGET = "u-boot.imx"
# | UBOOT_SUFFIX = "imx"
# |
# | UBOOT_MACHINE = "mx53loco_config"
# `----
IMX_DEFAULT_BOOTLOADER ??= "u-boot-fslc"
UBOOT_SUFFIX ?= "${UBOOT_SUFFIX:pn-${IMX_DEFAULT_BOOTLOADER}}"

# We need to export the original variable to allow it to be used when generating
# wic based images.
SPL_BINARY ??= "${@get_spl_binary(d)}"

IMX_DEFAULT_MFGTOOL = "${@bb.utils.contains('IMX_DEFAULT_BOOTLOADER', 'u-boot-imx','u-boot-imx-mfgtool', 'u-boot-fslc', d)}"

PREFERRED_PROVIDER_u-boot ??= "${IMX_DEFAULT_BOOTLOADER}"
PREFERRED_PROVIDER_u-boot-mfgtool ??= "${IMX_DEFAULT_MFGTOOL}"
PREFERRED_PROVIDER_virtual/bootloader ??= "${IMX_DEFAULT_BOOTLOADER}"

PREFERRED_PROVIDER_u-boot-mxsboot-native ??= "u-boot-fslc-mxsboot-native"

UBOOT_ENTRYPOINT:mxs    = "0x40008000"
UBOOT_ENTRYPOINT:mx51   = "0x90008000"
UBOOT_ENTRYPOINT:mx53   = "0x70008000"
UBOOT_ENTRYPOINT:mx6    = "0x10008000"
UBOOT_ENTRYPOINT:mx6sl  = "0x80008000"
UBOOT_ENTRYPOINT:mx6sll = "0x80008000"
UBOOT_ENTRYPOINT:mx6sx  = "0x80008000"
UBOOT_ENTRYPOINT:mx6ul  = "0x80008000"
UBOOT_ENTRYPOINT:mx6ull = "0x80008000"
UBOOT_ENTRYPOINT:mx6ulz = "0x80008000"
UBOOT_ENTRYPOINT:mx7    = "0x80008000"
UBOOT_ENTRYPOINT:mx7ulp = "0x60008000"
UBOOT_ENTRYPOINT:mx8m   = "0x40480000"
UBOOT_ENTRYPOINT:vf = "0x80008000"

# Some derivates can utilize the boot container provided by U-Boot,
# below variable sets that those machines which have a imx-boot-container
# in their MACHINEOVERRIDES can inherit a imx-boot-container class
UBOOT_PROVIDES_BOOT_CONTAINER = "0"
UBOOT_PROVIDES_BOOT_CONTAINER:imx-boot-container = "1"

PREFERRED_PROVIDER_virtual/xserver = "xserver-xorg"
XSERVER_DRIVER                  = "xf86-video-fbdev"
XSERVER_DRIVER:imxgpu2d         = "xf86-video-imx-vivante"
XSERVER_DRIVER:vf               = "xf86-video-modesetting"
XSERVER_DRIVER:append:mx8       = " xf86-video-modesetting"
XSERVER_DRIVER:use-mainline-bsp = " \
    xf86-video-fbdev \
    xf86-video-modesetting \
    xserver-xorg-extension-glx \
"
XSERVER = "xserver-xorg \
           xf86-input-evdev \
           ${XSERVER_DRIVER}"

# Ship kernel modules
MACHINE_EXTRA_RRECOMMENDS = "kernel-modules"

# Tunes for hard/soft float-point selection. Note that we allow building for
# thumb support giving distros the chance to enable thumb by setting
# ARM_INSTRUCTION_SET = "thumb"
#
# handled by software
# DEFAULTTUNE:mx6 ?= "cortexa9t-neon"
# handled by hardware
DEFAULTTUNE:mx6    ?= "cortexa9thf-neon"
DEFAULTTUNE:mx6ul  ?= "cortexa7thf-neon"
DEFAULTTUNE:mx6ull ?= "cortexa7thf-neon"
DEFAULTTUNE:mx6ulz ?= "cortexa7thf-neon"
DEFAULTTUNE:mx7    ?= "cortexa7thf-neon"
DEFAULTTUNE:vf     ?= "cortexa5thf-neon"

DEFAULTTUNE:mx8m   ?= "cortexa53-crypto"
DEFAULTTUNE:mx8qm  ?= "cortexa72-cortexa53-crypto"
DEFAULTTUNE:mx8qxp ?= "cortexa35-crypto"

INHERIT += "machine-overrides-extender"

MACHINEOVERRIDES_EXTENDER:mx6q   = "imxfbdev:imxipu:imxvpu:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx6dl  = "imxfbdev:imxpxp:imxipu:imxvpu:imxgpu:imxgpu2d:imxgpu3d:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx6sx  = "imxfbdev:imxpxp:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx6sl  = "imxfbdev:imxpxp:imxgpu:imxgpu2d:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx6sll = "imxfbdev:imxpxp:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx6ul  = "imxfbdev:imxpxp"
MACHINEOVERRIDES_EXTENDER:mx6ull = "imxfbdev:imxpxp:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx6ulz = "imxfbdev:imxpxp:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx7d   = "imxfbdev:imxpxp:imxepdc"
MACHINEOVERRIDES_EXTENDER:mx7ulp = "imxfbdev:imxpxp:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8qm  = "imxdrm:imxdpu:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8mm  = "imxdrm:imxvpu:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8mn  = "imxdrm:imxgpu:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8mp  = "imxdrm:imxvpu:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8mq  = "imxdrm:imxvpu:imxgpu:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8qxp = "imxdrm:imxdpu:imxgpu:imxgpu2d:imxgpu3d"
MACHINEOVERRIDES_EXTENDER:mx8dxl = "imxfbdev"

MACHINEOVERRIDES_EXTENDER_FILTER_OUT:use-mainline-bsp = " \
    imx \
    \
    mx6 \
    mx6q \
    mx6dl \
    mx6sx \
    mx6sl \
    mx6sll \
    mx6ul \
    mx6ull \
    mx6ulz \
    \
    mx7 \
    mx7d \
    mx7ulp \
    \
    mx8 \
    mx8m \
    mx8qm \
    mx8mm \
    mx8mn \
    mx8mp \
    mx8mq \
    mx8qxp \
    mx8dxl \
"

# Sub-architecture support
MACHINE_SOCARCH_SUFFIX ?= ""
MACHINE_SOCARCH_SUFFIX:mx6q = "-mx6qdl"
MACHINE_SOCARCH_SUFFIX:mx6dl = "-mx6qdl"
MACHINE_SOCARCH_SUFFIX:mx6sx = "-mx6sx"
MACHINE_SOCARCH_SUFFIX:mx6sl = "-mx6sl"
MACHINE_SOCARCH_SUFFIX:mx6sll= "-mx6sll"
MACHINE_SOCARCH_SUFFIX:mx7d = "-mx7d"
MACHINE_SOCARCH_SUFFIX:mx7ulp = "-mx7ulp"
MACHINE_SOCARCH_SUFFIX:vf60 = "-vf60"
MACHINE_SOCARCH_SUFFIX:vf50 = "-vf50"
MACHINE_SOCARCH_SUFFIX:mx6ul  = "-mx6ul"
MACHINE_SOCARCH_SUFFIX:mx6ull = "-mx6ul"
MACHINE_SOCARCH_SUFFIX:mx6ulz = "-mx6ul"
MACHINE_SOCARCH_SUFFIX:mx8qm  = "-mx8"
MACHINE_SOCARCH_SUFFIX:mx8mm  = "-mx8mm"
MACHINE_SOCARCH_SUFFIX:mx8mn  = "-mx8mn"
MACHINE_SOCARCH_SUFFIX:mx8mp  = "-mx8mp"
MACHINE_SOCARCH_SUFFIX:mx8mq  = "-mx8m"
MACHINE_SOCARCH_SUFFIX:mx8qxp = "-mx8"
MACHINE_SOCARCH_SUFFIX:mx8dxl = "-mx8dxl"
MACHINE_SOCARCH_SUFFIX:use-mainline-bsp = "-imx"

MACHINE_ARCH_FILTER = "virtual/kernel"
MACHINE_SOCARCH_FILTER:append:imx = " \
    alsa-lib \
    gstreamer1.0 \
    weston \
"
MACHINE_SOCARCH_FILTER:append:imxvpu = " \
    imx-codec \
    imx-vpuwrap \
    libimxvpuapi \
    virtual/imxvpu \
"
MACHINE_SOCARCH_FILTER:append:imxgpu = " \
    virtual/egl \
    virtual/mesa \
    virtual/libopenvg \
    libdrm \
    cairo \
    libgal-imx \
    opencv \
    pango \
"
MACHINE_SOCARCH_FILTER:append:imxgpu2d = " \
    virtual/libg2d \
"
MACHINE_SOCARCH_FILTER:append:imxgpu3d = " \
    virtual/libgl \
    virtual/libgles1 \
    virtual/libgles2 \
"
MACHINE_SOCARCH_FILTER:append:use-mainline-bsp = " \
    virtual/egl \
    virtual/libopenvg \
    virtual/libg2d \
    virtual/libgl \
    virtual/libgles1 \
    virtual/libgles2 \
    virtual/mesa \
    cairo \
    pango \
    qtbase \
"
MACHINE_SOCARCH_FILTER:append:mx6q = " \
    opencl-icd-loader \
    opencl-clhpp \
    opencl-headers \
"
MACHINE_SOCARCH_FILTER:append:mx8 = " \
    opencl-icd-loader \
    opencl-clhpp \
    opencl-headers \
"
MACHINE_SOCARCH_FILTER:append:mx8qm = " \
    virtual/libopenvx \
"

INHERIT += "fsl-dynamic-packagearch"

SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS:append = " \
    imx-gpu-viv->kernel-module-imx-gpu-viv \
    libimxvpuapi->virtual/imxvpu \
    imx-vpuwrap->virtual/imxvpu \
    imx-codec->virtual/imxvpu \
    imx-test->virtual/imxvpu \
"

# Firmware
MACHINE_FIRMWARE ?= ""
MACHINE_FIRMWARE:append:mx27 = " firmware-imx-vpu-imx27"
MACHINE_FIRMWARE:append:mx7d = " linux-firmware-imx-sdma-imx7d firmware-imx-epdc"
MACHINE_FIRMWARE:append:mx6 = " linux-firmware-imx-sdma-imx6q"
MACHINE_FIRMWARE:append:mx6q = " firmware-imx-vpu-imx6q"
MACHINE_FIRMWARE:append:mx6dl = " firmware-imx-vpu-imx6d firmware-imx-epdc"
MACHINE_FIRMWARE:append:mx6sl = " firmware-imx-epdc"
MACHINE_FIRMWARE:append:mx6sll = " firmware-imx-epdc"
MACHINE_FIRMWARE:append:mx6ull = " firmware-imx-epdc"
MACHINE_FIRMWARE:append:mx53 = " firmware-imx-vpu-imx53 firmware-imx-sdma-imx53"
MACHINE_FIRMWARE:append:mx51 = " firmware-imx-vpu-imx51 firmware-imx-sdma-imx51"
MACHINE_FIRMWARE:append:mx8mm  = " linux-firmware-imx-sdma-imx7d"
MACHINE_FIRMWARE:append:mx8mn  = " linux-firmware-imx-sdma-imx7d"
MACHINE_FIRMWARE:append:mx8mp  = " linux-firmware-imx-sdma-imx7d firmware-imx-easrc-imx8mn firmware-imx-xcvr-imx8mp firmware-sof-imx"
MACHINE_FIRMWARE:append:mx8mq  = " linux-firmware-imx-sdma-imx7d"
MACHINE_FIRMWARE:append:mx8qm  = " firmware-imx-vpu-imx8"
MACHINE_FIRMWARE:append:mx8qxp = " firmware-imx-vpu-imx8"
MACHINE_FIRMWARE:append:use-mainline-bsp = " linux-firmware-imx-sdma-imx6q linux-firmware-imx-sdma-imx7d firmware-imx-vpu-imx6q firmware-imx-vpu-imx6d"

MACHINE_EXTRA_RRECOMMENDS += "${MACHINE_FIRMWARE}"

# Extra audio support
IMX_ALSA_EXTRA = ""
IMX_ALSA_EXTRA:use-nxp-bsp = "imx-alsa-plugins"
MACHINE_EXTRA_RRECOMMENDS:append:mx6 = " ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', '${IMX_ALSA_EXTRA}', '', d)}"
MACHINE_EXTRA_RRECOMMENDS:append:mx7 = " ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', '${IMX_ALSA_EXTRA}', '', d)}"
MACHINE_EXTRA_RRECOMMENDS:append:mx8 = " ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', '${IMX_ALSA_EXTRA}', '', d)}"

# Extra Cypress Wi-Fi and BTW firmware (Murata)
MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'bcm4339', 'linux-firmware-bcm4339', '', d)}"
MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'bcm43430', 'linux-firmware-bcm43430', '', d)}"
MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'bcm43455', 'linux-firmware-bcm43455', '', d)}"
MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'bcm4356', 'linux-firmware-bcm4356-pcie', '', d)}"
MACHINE_FIRMWARE:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'bcm4359', 'linux-firmware-bcm4359-pcie', '', d)}"

# Extra QCA Wi-Fi & BTE driver and firmware
MACHINE_EXTRA_RRECOMMENDS:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'qca6174', 'packagegroup-fsl-qca6174', '', d)}"
MACHINE_EXTRA_RRECOMMENDS:append = " ${@bb.utils.contains('MACHINE_FEATURES', 'qca9377', 'packagegroup-fsl-qca9377', '', d)}"

# Extra udev rules
MACHINE_EXTRA_RRECOMMENDS += "udev-rules-imx"

# Jailhouse
MACHINE_EXTRA_RRECOMMENDS += " \
    ${@bb.utils.filter('COMBINED_FEATURES', 'jailhouse', d)} \
"

# GStreamer 1.0 plugins
MACHINE_GSTREAMER_1_0_PLUGIN        ?= ""
MACHINE_GSTREAMER_1_0_PLUGIN:mx6dl  ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx6q   ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx6sl  ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx6sx  ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx6ul  ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx6ull ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx7d   ?= "gstreamer1.0-plugins-imx-meta"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8mm  ?= "imx-gst1.0-plugin"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8mn  ?= "imx-gst1.0-plugin"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8mp  ?= "imx-gst1.0-plugin"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8mq  ?= "imx-gst1.0-plugin"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8qm  ?= "imx-gst1.0-plugin"
MACHINE_GSTREAMER_1_0_PLUGIN:mx8qxp ?= "imx-gst1.0-plugin"

PREFERRED_VERSION_gstreamer1.0:mx8              ?= "1.18.0.imx"
PREFERRED_VERSION_gstreamer1.0-plugins-base:mx8 ?= "1.18.0.imx"
PREFERRED_VERSION_gstreamer1.0-plugins-good:mx8 ?= "1.18.0.imx"
PREFERRED_VERSION_gstreamer1.0-plugins-bad:mx8  ?= "1.18.0.imx"
PREFERRED_VERSION_gstreamer1.0-plugins-ugly:mx8 ?= "1.18.0"
PREFERRED_VERSION_gstreamer1.0-libav:mx8        ?= "1.18.0"
PREFERRED_VERSION_gstreamer1.0-rtsp-server:mx8  ?= "1.18.0"

# Determines if the SoC has support for Vivante kernel driver
SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT        = "0"
SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT:imxgpu = "1"

# Handle Vivante kernel driver setting:
#   0 - machine does not have Vivante GPU driver support
#   1 - machine has Vivante GPU driver support
MACHINE_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT ?= "${SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT}"

# Graphics libraries
PREFERRED_PROVIDER_virtual/egl      ?= "mesa"
PREFERRED_PROVIDER_virtual/libgl    ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles1 ?= "mesa"
PREFERRED_PROVIDER_virtual/libgles2 ?= "mesa"

PREFERRED_PROVIDER_virtual/egl:imxgpu        ?= "imx-gpu-viv"
PREFERRED_PROVIDER_virtual/libgl:imxgpu3d    ?= "imx-gpu-viv"
PREFERRED_PROVIDER_virtual/libgles1:imxgpu3d ?= "imx-gpu-viv"
PREFERRED_PROVIDER_virtual/libgles2:imxgpu3d ?= "imx-gpu-viv"
PREFERRED_PROVIDER_virtual/libg2d            ?= "imx-gpu-g2d"
PREFERRED_PROVIDER_virtual/libg2d:imxdpu     ?= "imx-dpu-g2d"
PREFERRED_PROVIDER_opencl-clhpp:imxgpu       ?= "imx-gpu-viv"
PREFERRED_PROVIDER_opencl-headers:imxgpu     ?= "imx-gpu-viv"
PREFERRED_PROVIDER_opencl-icd-loader:imxgpu  ?= "imx-gpu-viv"

PREFERRED_VERSION_weston:imx ?= "9.0.0.imx"
PREFERRED_VERSION_weston:use-mainline-bsp = ""

PREFERRED_VERSION_wayland-protocols:mx6 ?= "1.20.imx"
PREFERRED_VERSION_wayland-protocols:mx7 ?= "1.20.imx"
PREFERRED_VERSION_wayland-protocols:mx8 ?= "1.20.imx"

# Use i.MX libdrm Version
PREFERRED_VERSION_libdrm:mx6 ?= "2.4.102.imx"
PREFERRED_VERSION_libdrm:mx7 ?= "2.4.102.imx"
PREFERRED_VERSION_libdrm:mx8 ?= "2.4.102.imx"

# Use i.MX optee Version
PREFERRED_VERSION_optee-os:mx8     ?= "3.10.0.imx"
PREFERRED_VERSION_optee-client:mx8 ?= "3.10.0.imx"
PREFERRED_VERSION_optee-test:mx8   ?= "3.10.0.imx"

#Use i.MX opencv Version for mx8
PREFERRED_VERSION_opencv:mx8 ?= "4.5.2.imx"

# Handle default kernel
IMX_DEFAULT_KERNEL = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mxs = "linux-fslc"
IMX_DEFAULT_KERNEL:mx5 = "linux-fslc"
IMX_DEFAULT_KERNEL:mx6 = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx7 = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx8 = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx7ulp = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx6sll = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx6ul = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:mx6ull = "linux-fslc-imx"
IMX_DEFAULT_KERNEL:use-mainline-bsp = "linux-fslc"

PREFERRED_PROVIDER_virtual/kernel ??= "${IMX_DEFAULT_KERNEL}"

SOC_DEFAULT_IMAGE_FSTYPES = "wic.bmap wic.gz"
SOC_DEFAULT_IMAGE_FSTYPES:mxs = "uboot-mxsboot-sdcard wic.bmap wic.gz"

# Do not update fstab file when using wic images
WIC_CREATE_EXTRA_ARGS ?= "--no-fstab-update"

OPTEE_BIN_EXT ??= ""
OPTEE_BOOT_IMAGE         = "tee.bin uTee-${OPTEE_BIN_EXT}"
OPTEE_BOOT_IMAGE:aarch64 = "tee.bin"

IMAGE_FSTYPES ?= "${SOC_DEFAULT_IMAGE_FSTYPES}"

IMAGE_BOOT_FILES ?= " \
    ${KERNEL_IMAGETYPE} \
    ${@make_dtb_boot_files(d)} \
    ${@bb.utils.contains('MACHINE_FEATURES', 'optee', '${OPTEE_BOOT_IMAGE}', '', d)} \
"

### wic default support
OPTEE_WKS_FILE_DEPENDS         = "optee-os"
OPTEE_WKS_FILE_DEPENDS:aarch64 = ""

WKS_FILE_DEPENDS ?= " \
    virtual/bootloader \
    \
    e2fsprogs-native \
    bmap-tools-native \
    ${@bb.utils.contains('MACHINE_FEATURES', 'optee', '${OPTEE_WKS_FILE_DEPENDS}', '', d)} \
"

WKS_FILE_DEPENDS:append:mx8 = " imx-boot"
WKS_FILE_DEPENDS:append:mx8m = " imx-boot"

# We need to restrict the append so we don't add this for other i.MX SoC's.
# Derivatives that are not yet adopted the usage of boot container provided
# by U-Boot build are still targeted to use 'imx-boot' package provided by
# NXP. Moving those derivatives to mainline BSP would require to define an
# 'imx-boot-container' override, and test if the U-Boot built 'flash.bin'
# binary is used a replacement.
# Note, that the results binary name of the boot container is set to 'imx-boot'
# for both NXP and Mainline BSP.
# For Mainline BSP: the 'flash.bin' boot container is renamed during the
# deployment task extesion execution defined in imx-boot-container class.
# For NXP BSP: rename is done in 'imx-boot' recipe at the execution of compile
# task.
WKS_FILE_DEPENDS:append:use-mainline-bsp:aarch64 = " \
    ${@oe.utils.ifelse(d.getVar('UBOOT_PROVIDES_BOOT_CONTAINER') == '0', 'imx-boot', '')} \
"

SOC_DEFAULT_WKS_FILE ?= "imx-uboot-bootpart.wks.in"
SOC_DEFAULT_WKS_FILE:mx8m ?= "imx-imx-boot-bootpart.wks.in"

SOC_DEFAULT_WKS_FILE:mx8 ?= "imx-imx-boot-bootpart.wks.in"
SOC_DEFAULT_WKS_FILE:mxs ?= "imx-uboot-mxs-bootpart.wks.in"

# Boot container built as a part of mainline U-Boot uses different WKS
# file as the entire mx8m series, as U-Boot versions later than 2021.04 are
# providing two separate binaries, namely flash.bin and u-boot.itb. Those
# files are packed into the boot partition.
# Binaries produced by U-Boot build itself are serving as a direct
# replacement of imx-boot from NXP.
# Creation of those binary files is controlled by UBOOT_PROVIDES_BOOT_CONTAINER
# variable defined above.
SOC_DEFAULT_WKS_FILE:imx-boot-container ?= "imx-boot-container-bootpart.wks.in"

WKS_FILE ?= "${SOC_DEFAULT_WKS_FILE}"

SERIAL_CONSOLES = "115200;ttymxc0"
SERIAL_CONSOLES:mxs = "115200;ttyAMA0"

KERNEL_IMAGETYPE = "zImage"
KERNEL_IMAGETYPE:aarch64 = "Image"

MACHINE_FEATURES = "usbgadget usbhost vfat alsa touchscreen"

# Add the ability to specify imx machines
MACHINEOVERRIDES =. "imx:"

HOSTTOOLS_NONFATAL:append:mx8 = " sha384sum"

imx8mp-evk.inc

ATF_LOAD_ADDR,dtb信息,uboot文件的后缀信息。

MACHINEOVERRIDES =. "imx-boot-container:mx8:mx8m:mx8mp:"

require conf/machine/include/imx-base.inc
require conf/machine/include/arm/armv8a/tune-cortexa53.inc

# Mainline BSP defaults to "generic" cortexa53 configuration,
# adjust it here to include crypto extension which enables
# inline NEON and FPU code generation
DEFAULTTUNE:use-mainline-bsp = "cortexa53-crypto"

MACHINE_FEATURES += "pci wifi bluetooth"

# NXP BSP can consume proprietary jailhouse and Marvell drivers
# OP-TEE is also applicable to NXP BSP, mainline BSP seems not to have
# a full support for it yet.
MACHINE_FEATURES:append:use-nxp-bsp = " optee jailhouse mrvl8997"

# Mainline kernel contains only one DTB file for
# imx8mpevk machine
KERNEL_DEVICETREE = " \
    freescale/${KERNEL_DEVICETREE_BASENAME}.dtb \
"

UBOOT_DTB_NAME = "${KERNEL_DEVICETREE_BASENAME}.dtb"

IMX_DEFAULT_BOOTLOADER:use-nxp-bsp = "u-boot-imx"
IMX_DEFAULT_BOOTLOADER:use-mainline-bsp = "u-boot-fslc"

UBOOT_SUFFIX = "bin"

UBOOT_CONFIG ??= "sd"
UBOOT_CONFIG[sd]      = "${UBOOT_CONFIG_BASENAME}_defconfig,sdcard"
UBOOT_CONFIG[ecc]     = "${UBOOT_CONFIG_BASENAME}_inline_ecc_defconfig"
UBOOT_CONFIG[mfgtool] = "${UBOOT_CONFIG_BASENAME}_defconfig"

SPL_BINARY = "spl/u-boot-spl.bin"

ATF_PLATFORM = "imx8mp"
ATF_LOAD_ADDR = "0x970000"

# Extra firmware package name, that is required to build boot container for fslc bsp
IMX_EXTRA_FIRMWARE = "firmware-imx-8m"

IMXBOOT_TARGETS = \
    "${@bb.utils.contains('UBOOT_CONFIG', 'fspi', '${IMXBOOT_TARGETS_BASENAME}_flexspi', \
                                                  '${IMXBOOT_TARGETS_BASENAME}', d)}"

IMX_BOOT_SOC_TARGET = "iMX8MP"

SERIAL_CONSOLES = "115200;ttymxc1"

# Add support for Syslinux to mainline BSP.
# U-Boot has the Distro Boot mode enabled by default, which
# require that either Syslinux to be enabled, or a boot script
# to be used to define the boot process.
# We opt-in for Syslinux, since it is designated as a preferred
# distro boot mode according to the U-Boot documentation.
UBOOT_EXTLINUX:use-mainline-bsp = "1"
UBOOT_EXTLINUX_LABELS:use-mainline-bsp = "default"
UBOOT_EXTLINUX_DEFAULT_LABEL:use-mainline-bsp = "i.MX8M Plus EVK"

UBOOT_EXTLINUX_MENU_DESCRIPTION:default:use-mainline-bsp = "i.MX8M Plus EVK"
UBOOT_EXTLINUX_FDT:default:use-mainline-bsp     = "../${KERNEL_DEVICETREE_BASENAME}.dtb"
UBOOT_EXTLINUX_CONSOLE:default:use-mainline-bsp = "console=${console}"
UBOOT_EXTLINUX_ROOT:default:use-mainline-bsp    = "root=/dev/mmcblk1p2"

# Add extlinux.conf to the lis of files, which are deployed onto the
# boot partition
IMAGE_BOOT_FILES:append:use-mainline-bsp = " extlinux.conf;extlinux/extlinux.conf"

LOADADDR = ""
UBOOT_SUFFIX = "bin"
UBOOT_MAKE_TARGET = "all"
IMX_BOOT_SEEK = "32"

OPTEE_BIN_EXT = "8mp"
TEE_LOAD_ADDR = "0x56000000"

# Add additional firmware
MACHINE_FIRMWARE:append = " linux-firmware-ath10k"

imx8mp-lpddr4-evk.conf

dtb文件,DDR FIRMWARE信息,flash_evk后缀。

require include/imx8mp-evk.inc

# The device tree name is implicit for LPDDR4, so can't use MACHINE here
KERNEL_DEVICETREE_BASENAME = "imx8mp-evk"

# NXP kernel has additional DTB files for various board configuration and
# derivates. Include them here for NXP BSP only
KERNEL_DEVICETREE:append:use-nxp-bsp = " \
	freescale/imx8mp-ab2.dtb \
	freescale/imx8mp-evk-basler.dtb \
	freescale/imx8mp-evk-basler-ov2775.dtb \
	freescale/imx8mp-evk-basler-ov5640.dtb \
	freescale/imx8mp-evk-dual-basler.dtb \
	freescale/imx8mp-evk-dual-ov2775.dtb \
	freescale/imx8mp-evk-ecspi-slave.dtb \
	freescale/imx8mp-evk-flexcan2.dtb \
	freescale/imx8mp-evk-hifiberry-dacplus.dtb \
	freescale/imx8mp-evk-inmate.dtb \
	freescale/imx8mp-evk-iqaudio-dacplus.dtb \
	freescale/imx8mp-evk-iqaudio-dacpro.dtb \
	freescale/imx8mp-evk-it6263-lvds-dual-channel.dtb \
	freescale/imx8mp-evk-jdi-wuxga-lvds-panel.dtb \
	freescale/imx8mp-evk-ndm.dtb \
	freescale/imx8mp-evk-ov2775.dtb \
	freescale/imx8mp-evk-ov2775-ov5640.dtb \
	freescale/imx8mp-evk-pcie-ep.dtb \
	freescale/imx8mp-evk-rm67191.dtb \
	freescale/imx8mp-evk-rm67199.dtb \
	freescale/imx8mp-evk-root.dtb \
	freescale/imx8mp-evk-rpmsg.dtb \
	freescale/imx8mp-evk-sof-wm8960.dtb \
	freescale/imx8mp-evk-spdif-lb.dtb \
	freescale/imx8mp-evk-usdhc1-m2.dtb \
"

UBOOT_CONFIG_BASENAME = "imx8mp_evk"
UBOOT_CONFIG[fspi] = "${UBOOT_CONFIG_BASENAME}_defconfig"

# Set DDR FIRMWARE
DDR_FIRMWARE_VERSION = "202006"
DDR_FIRMWARE_NAME = " \
	lpddr4_pmu_train_1d_dmem_${DDR_FIRMWARE_VERSION}.bin \
	lpddr4_pmu_train_1d_imem_${DDR_FIRMWARE_VERSION}.bin \
	lpddr4_pmu_train_2d_dmem_${DDR_FIRMWARE_VERSION}.bin \
	lpddr4_pmu_train_2d_imem_${DDR_FIRMWARE_VERSION}.bin \
"

IMXBOOT_TARGETS_BASENAME = "flash_evk"

part/partition命令

使用一下命令在系统上创建一个分区:

part|partition [--asprimary] [--fstype FSTYPE] [--grow] [--maxsize MAXSIZEMB]
           [--noformat] [--onbiosdisk ONBIOSDISK] [--ondisk DISK]
           [--onpart ONPART] [--recommended] [--size SIZE]
           [--fsoptions FSOPTS] [--label LABEL] [--fsprofile FSPROFILE]
           [--encrypted] [--passphrase PASSPHRASE] [--escrowcert <url>]
           [--backuppassphrase] [--resize] [--hibernation]
           [--cipher CIPHER] [--mkfsoptions MKFSOPTS]
           [--luks-version LUKS_VERSION] [--pbkdf PBKDF]
           [--pbkdf-memory PBKDF_MEMORY] [--pbkdf-time PBKDF_TIME]
           [--pbkdf-iterations PBKDF_ITERATIONS]
           <mntpoint>
  • --size:最小分区大小。指定为整数值,可选地后跟单位之一“k”/“K”表示千字节,“M”表示兆字节,“G”表示吉字节。如果没有给出默认单位是“M”。如果您使用--source.

  • --fixed-size:确切的分区大小。指定为整数值,可选地后跟单位之一“k”/“K”表示千字节,“M”表示兆字节,“G”表示吉字节。如果没有给出默认单位是“M”。不能与 一起指定--size。如果分区数据大于--fixed-size.

  • --source:此选项是特定于 Wic 的选项,用于命名填充分区的数据源。此选项最常见的值是“rootfs”,但您可以使用映射到有效源插件的任何值。有关源插件的信息,请参阅 Yocto 项目开发任务手册中的“使用 Wic 插件接口”部分。

    如果使用,Wic 会根据需要创建一个分区,并用命令行选项指向的根文件系统或从命令行选项派生的等效根文件系统的内容填充它。用于创建分区的文件系统类型由 为分区指定的选项的值驱动。有关详细信息,请参阅以下条目 。--source rootfs``-r``-e``--fstype``--fstype

    如果您使用,Wic 会根据需要创建一个分区,并使用由命令行选项指向的数据或从命令行派生的等效根文件系统使用指定插件名称生成的分区的内容填充它 -线选项。这些内容到底是什么以及使用的文件系统类型取决于给定的插件实现。--source plugin-name``-r``-e

    如果不使用该--source选项,该wic命令将创建一个空分区。因此,您必须使用该--size 选项来指定空分区的大小。

  • --ondisk--ondrive:强制在特定磁盘上创建分区。

  • --fstype:设置分区的文件系统类型。有效值为:

    • btrfs
    • erofs
    • ext2
    • ext3
    • ext4
    • squashfs
    • swap
    • vfat
  • --fsoptions: 指定挂载文件系统时要使用的自由格式的选项字符串。该字符串被复制到 /etc/fstab已安装系统的文件中,并且应该用引号引起来。如果未指定,则默认字符串为“defaults”。

  • --label label:指定要在分区上创建的文件系统的标签。如果给定标签已被另一个文件系统使用,则为分区创建一个新标签。

  • --active:将分区标记为活动的。

  • --align (in KBytes):此选项是 Wic 特定选项,表示在给定 x KBytes 的边界上启动分区。

  • --offset:此选项是 Wic 特定的选项,表示将分区放置在指定的偏移量处。如果分区不能放置在指定的偏移量,则镜像构建将失败。指定为整数值,可选地后跟单位之一“s”/“S”表示 512 字节扇区,“k”/“K”表示千字节,“M”表示兆字节,“G”表示吉字节。如果没有给出默认单位是“k”。

  • --no-table:此选项是特定于 Wic 的选项。使用该选项为分区保留空间并使其填充。但是,分区不会添加到分区表中。

  • --exclude-path:此选项是特定于 Wic 的选项,它从结果图像中排除给定的相对路径。此选项仅对 rootfs 源插件有效。

  • --extra-space:此选项是 Wic 特定选项,在分区内容填充的空间之后添加额外空间。最终大小可以超过--size 选项指定的大小。默认值为 10M。指定为整数值,可选地后跟单位之一“k”/“K”表示千字节,“M”表示兆字节,“G”表示吉字节。如果没有给出默认单位是“M”。

  • --overhead-factor:此选项是 Wic 特定的选项,它将分区的大小乘以选项的值。您必须提供一个大于或等于“1”的值。默认值为“1.3”。

  • --part-name:此选项是特定于 Wic 的选项,用于指定 GPT 分区的名称。

  • --part-type:此选项是特定于 Wic 的选项,用于指定 GPT 分区的分区类型全局唯一标识符 (GUID)。您可以在https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs找到分区类型 GUID 的列表 。

  • --use-uuid:此选项是 Wic 特定选项,它会导致 Wic 为分区生成随机 GUID。生成的标识符在引导加载程序配置中用于指定根分区。

  • --uuid:此选项是 Wic 特定的选项,用于指定分区 UUID。

  • --fsuuid:此选项是 Wic 特定的选项,用于指定文件系统 UUID。如果在运行 Wic 之前将预配置的文件系统 UUID 添加到引导加载程序配置中的内核命令行,则可以使用此选项生成或修改 WKS_FILE 。

  • --system-id:此选项是 Wic 特定选项,用于指定分区系统 ID,它是一个字节长的十六进制参数,带或不带 0x 前缀。

  • --mkfs-extraopts:此选项指定要传递给mkfs实用程序的附加选项。某些文件系统的某些默认选项不会生效。请参阅 Wic 对 kickstart 的帮助(即 )。

bootloader命令

bootloader [--append APPENDLINE] [--location {mbr,partition,none,boot}]
       [--password PASSWORD] [--driveorder DRIVEORDER] [--timeout TIMEOUT]
       [--default DEFAULT] [--iscrypted] [--md5pass MD5PASS]
       [--boot-drive BOOTDRIVE] [--leavebootorder] [--extlinux]
       [--disabled] [--nombr]

可选参数:

--append APPENDLINE

指定额外的内核参数。例如:

bootloader --location=mbr --append="hdd=ide-scsi ide=nodma"

注意如果 plymouth 安装在目标系统上,安装程序将添加引导加载程序参数。您可以在该 部分禁用这些选项。rhgb quiet``-plymouth``%packages

Fedora3 版本中的新功能。

--linear

使用线性模式访问硬盘(仅适用于 LILO)

Fedora3 版本中的新功能。

在 Fedora4 版本中删除。

--nolinear

不要使用线性模式访问硬盘(仅适用于 LILO)

Fedora3 版本中的新功能。

在 Fedora4 版本中删除。

--location {mbr,partition,none,boot}

指定写入引导记录的位置。有效值如下:mbr(默认值)、partition(在包含内核的分区的第一个扇区上安装引导加载程序)或 none(不安装引导加载程序)。

注意 bootloader –location=none与 bootloader –location=none –disabled不同。 –location=none防止使目标机器可引导的额外安装步骤,例如在 x86 BIOS 系统上写入 MBR。但是,相应的 RPM 包仍然被安装,并且可以附加–disabled来防止它。bootloader –disabled only 不会阻止引导加载程序的安装,如果没有提供其他选项,Anaconda 会抱怨。

Fedora3 版本中的新功能。

--password PASSWORD

如果使用 GRUB,请设置 GRUB 引导加载程序密码。这应该用于限制对 GRUB shell 的访问,其中可以传递任意内核选项。

Fedora3 版本中的新功能。

--useLilo

强制使用 LILO

Fedora3 版本中的新功能。

在 Fedora4 版本中删除。

--driveorder DRIVEORDER

定义引导加载程序应该使用的显式硬盘顺序

Fedora3 版本中的新功能。

--timeout TIMEOUT

指定引导加载程序超时并引导默认选项之前的秒数。

Fedora8 版本中的新功能。

--default DEFAULT

在引导加载程序配置中设置默认引导映像。

Fedora8 版本中的新功能。

--lba32

强制使用 LBA32 模式进行硬盘访问(仅限 LILO)

Fedora3 版本中的新功能。

自版本 Fedora12 以来已弃用。

在 Fedora14 版本中删除。

--iscrypted

如果给定,则由 指定的密码--password=已经加密,应该传递给引导加载程序配置,无需额外修改。

Fedora15 版本中的新功能。

--md5pass MD5PASS

如果使用 GRUB,类似于--password=密码应该已经加密。

Fedora3 版本中的新功能。

在 Fedora15 版本中更改。

的别名。--password=MD5PASS --iscrypted

--boot-drive BOOTDRIVE

指定应将引导加载程序写入哪个驱动器,从而指定计算机将从哪个驱动器引导。

Fedora17 版本中的新功能。

--leavebootorder

在 EFI 或 ISeries/PSeries 机器上,此选项可防止安装程序更改现有的可引导映像列表。

Fedora18 版本中的新功能。

--extlinux

使用 extlinux 引导加载程序而不是 GRUB。此选项仅适用于 extlinux 支持的机器。

Fedora19 版本中的新功能。

--disabled

不要安装引导加载程序。

注意 bootloader –location=none与 bootloader –location=none –disabled不同。 –location=none防止使目标机器可引导的额外安装步骤,例如在 x86 BIOS 系统上写入 MBR。但是,相应的 RPM 包仍然被安装,并且可以附加–disabled来防止它。bootloader –disabled only 不会阻止引导加载程序的安装,如果没有提供其他选项,Anaconda 会抱怨。

Fedora21 版本中的新功能。

--nombr

不要将引导加载程序安装到 MBR

Fedora21 版本中的新功能。

--upgrade

升级安装在磁盘上的引导加载程序

Fedora3 版本中的新功能。

自版本 Fedora29 以来已弃用。

在 Fedora34 版本中删除。

参考链接

https://docs.yoctoproject.org/ref-manual/kickstart.html

https://pykickstart.readthedocs.io/en/latest/kickstart-docs.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漫游嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值