Board Bringup
This document provides guidance for board bring-up in IoT Yocto.
Sections
Before starting software bring-up, please verify the hardware status of the board. The following hardware components and interfaces should be inspected according to your board design:
Power source & voltage
Clock frequency
Voltage in different outputs
LEDs status
Check Boot ROM
Connect the board to serial port (UART0
) and start serial communication using a baud rate of 115200
.
If the board is well powered, ROM code logs should appear in the serial interface from UART0
port.
If not, please check whether the hardware is well powered or a powering problem has occurred. The following is an example of Boot ROM log for MT8395:
F0: 102B 0000
F3: 1006 0033 [0200]
F3: 4001 00E0 [0200]
F3: 0000 0000
V0: 0000 0000 [0001]
00: 0000 0000
BP: 0C00 0241 [0000]
G0: 1190 0000
EC: 0080 0000 [0000]
S7: 0000 0000 [0000]
T0: 0000 01AA [100F]
Jump to BL
Different SoC have different Boot ROM log, but the format should be similar.
Create New Yocto Layer
After confirming the SoC is well powered, you can now create new software configurations
for your board. To do so, you need to add new layers
on top of the meta-mediatek-bsp
and meta-rity
layers provided by IoT Yocto.
Download IoT Yocto layers by referring to Get Started with IoT Yocto.
Create a
meta-<board_name>
layer with the following basic architecture:meta-<board_name> ├── conf │ ├── machine │ │ └── <machine_name>.conf # an MACHINE identifier for your board │ ├── layer.conf # │ ├── local.conf.sample # example configuration for users of your board │ └── bblayers.conf.sample # the layers you'd like to include by default │ ├── recipes-bsp │ ├── libdram │ │ ├── files/ # patches to add board support │ │ ├── libdram-lk.bbappend # apply patches to libdram-lk.bb │ │ └── libdram.bbappend # symlink to add the patches to libdram.bb │ │ │ └── u-boot │ ├── files/ # patches to add board support │ └── u-boot_%.bbappend # add device-tree and config patches │ ├── recipes-kernel │ └── linux-mtk │ ├── files/ # patches to add device-tree kernel modification and configuration │ └── linux-mtk_%.bbappend # apply the patches to linux kernel │ ├── recipes-core │ └── wic └── custom.wks.in # Partitionning
Each recipe could extend or override the definition of existing BSP and RITY layers.
Add New Machine Configuration
For board bring-up, it usually involves adding a new machine configuration to specify the following configurations:
DRAM configuration
U-Boot device driver and configuration
Kernel device driver and configuration
Boot process configuration
Additional Yocto package and image customization
In meta-<board_name>/conf/machine
, add a <machine_name>.conf file. The content should be:
Include SoC-recipe include files. For example,
require conf/machine/include/mtxxxx.inc
You can refer to existing machine configurations in
meta-mediatek-bsp
layer to know which include files should be used.For example,
conf/machine/mt8395-evb-ufs.conf
provides configuration for UFS boot and storage configurations for MT8395 EVK mounted with UFS storage.conf/machine/mt8395-demo.conf
provides configuration for the MT8395 P1V6 (Genio 1200) demo board, which uses EMMC storage.
Set
LIBDRAM_BOARD_NAME
, See Libdram configurationSet kernel device-tree:
KERNEL_DEVICETREE
, See Kernel device treeSet u-boot configuration:
UBOOT_MACHINE
, See U-boot device treeSet OP-TEE DRAM size:
OPTEE_DRAM_SIZE
, See OP-TEE DRAM size configurationSet overrides via
MACHINEOVERRIDES
variable.Add machine and distro features using
DISTRO_FEATURES_append
andMACHINE_FEATURES_append
.
The following sections show how to achieve this by modifying different recipes.
libdram Configuration
Note
MT8395 (Genio 1200) does not require modification to libdram
. You can use the same libdram
binary as in MACHINE=i1200-demo
. For other SoCs, please continue to read.
Important
Modifying DRAM component requires proprietary software libdram
from MediaTek. You need to get the source code from MediaTek partners and distributors.
In libdram/boards/<board_name>
, add a meson.build
file that contains the reference for DDR configuration:
https://gitlab.com/mediatek/aiot/nda/libdram
libdram
├── board
│ └── <board_name>
│ └── meson.build
├── src
│ └── mtxxxx
│ ├── ddr
│ │ └── <ddr_name>.cfg
│ └── driver
│
└── tools
In meson.build
:
SoC = 'mtxxxx'
ddr = [
'<ddr_name>',
]
MediaTek supports different DDR (refer to libdram/src/<SOC>/ddr
: https://gitlab.com/mediatek/aiot/nda/libdram/-/tree/main/src).
If the used DDR is supported by MediaTek, it can directly be referenced in libdram/boards/<board_name>.
If not, please do the following step to add the new DDR configuration.
In libdram/src/<SoC>/ddr, add a configuration file that contains the DDR config <ddr_name>.cfg.
The configuration file should configure DDR registers as ‘EMI_CONA_VAL’ and ‘DRAM RANK SIZE’ …
Please refer to the used DDR datasheet to find informations about the registers.
Note that depending on the DDR used, the DDR driver in libdram/src/<SoC>/driver may need to be updated.
New libdram sources are to be listed in meson.build in libdram/src/<SoC>/.
Patch the modified libdram sources as a libdram patch file.
After adding a new machine in IoT Yocto project (refer to Add New Machine Configuration), set LIBDRAM_BOARD_NAME in machine configuration file.
meta-mediatek-bsp
└─── conf
└── machine
└── <board_name>.cfg
...
# libdram
LIBDRAM_BOARD_NAME = "<board_name>"
...
Add the libdram patch file to meta-<board_name>/recipes-bsp/libdram/files/.
Add the patch PATH to SRC_URI variable in libdram-lk.bbappend.
Add symbolic link to libdram.bbappend.
meta-<board_name>
├── recipes-bsp
│ ├── libdram
│ │ ├── files/ # patches to add board support
│ │ ├── libdram-lk.bbappend # apply patches to libdram-lk.bb
│ │ └── libdram.bbappend # symbolic link to add the patches to libdram.bb
... ...
U-Boot configuration
U-Boot Device tree
Add the device tree to u-boot/arch/arm/dts/<mtxxxx-board_name>.dts.
u-boot
└── arch
└── arm
└── dts
└── <mtxxxx-board_name>.dts
Include the SoC device tree : mtxxxx.dtsi.
Refer to already existing device tree with the same SoC.
Configure emmc : frequency, bus-width …
Configure DDR size :
It is not mandatory to change the default DDR size in u-boot device tree since u-boot only need few MB of memory at most and does not need to use the whole DDR.
memory@40000000 {
device_type = "memory";
reg = <0 0x40000000 0 0x80000000>;
} ;
0 0x40000000 is the address of the DDR in memory coded in 64 Bits, meaning that 0x0000000040000000 is the actual DDR address. This value should not be changed.
0 0x80000000 is the RAM size. In this example, it refers to 2GB of RAM.
reg = <0 0x40000000 1 0x00000000>; # meaning '0x0000000100000000'.
Add <mtxxxx-board_name>.dtb to u-boot/arch/arm/dts/Makefile.
...
dtb-$(CONFIG_ARCH_MEDIATEK) += \
<mtxxxx-board_name>.dtb
...
Patch u-boot sources and add the patch to meta-<board_name>/recipes-bsp/u-boot/files/.
Add the patch PATH to SRC_URI variable in meta-<board_name>/recipes-bsp/u-boot/u-boot_%.bbappend.
meta-<board_name>
├──recipes-bsp
│ └── u-boot
│ ├── files/ # patches to add board support
│ └── u-boot_%.bbappend # add device-tree and config patches
...
U-Boot Machine Configuration
Use already existing SoC-matching defconfig if no changes are to be added (jump to step 4).
Create a <mtxxxx_board_defconfig> that contains u-boot configuration in /configs
u-boot
└── configs
└── <mtxxxx_board_defconfig>
Patch u-boot sources and add the patch to meta-<board_name>/recipes-bsp/u-boot/files/.
Add the patch PATH to SRC_URI variable in meta-<board_name>/recipes-bsp/u-boot/u-boot_%.bbappend.
meta-<board_name>
├──recipes-bsp
│ └── u-boot
│ ├── files/ # patches to add board support
│ └── u-boot_%.bbappend # add device-tree and config patches
Set UBOOT_MACHINE variable in <machine_name>.conf
meta-<board_name>
├── conf
│ ├── machine
│ │ └── <machine_name>.conf #
│ ├── layer.conf #
│ ├── local.conf.sample #
│ └── bblayers.conf.sample #
...
UBOOT_MACHINE = "mtxxxx_board_defconfig"
OP-TEE configuration
OP-TEE DRAM Size Configuration
Use already existing SoC-matching machine config if no changes are to be added (jump to step 4).
Important
The OP-TEE DRAM size must be equal to the DRAM size configured in kernel device tree.
(Optional) If the DRAM size is large than 4GB, set
CFG_CORE_ARM64_PA_BITS,36
in <OP-TEE>/core/arch/arm/plat-mediatek/conf.mk.
optee-os
└── core
└── arch
└── arm
└── plat-mediatek
└── conf.mk
ifeq ($(PLATFORM_FLAVOR),<platform_name>)
$(call force,CFG_CORE_ARM64_PA_BITS,36)
endif
Patch optee-os sources and add the patch to meta-<board_name>/recipes-security/optee-os/files/.
Add the patch PATH to SRC_URI variable in meta-<board_name>/recipes-security/optee-os/optee-os_%.bbappend.
meta-<board_name>
├──recipes-security
│ └── optee-os
│ ├── files/ # patches to add board support
│ └── optee-os_%.bbappend # add DRAM PA bits patch
Set
OPTEE_DRAM_SIZE
variable in <machine_name>.conf
meta-<board_name>
├── conf
│ ├── machine
│ │ └── <machine_name>.conf #
│ ├── layer.conf #
│ ├── local.conf.sample #
│ └── bblayers.conf.sample #
...
OPTEE_DRAM_SIZE = "0x80000000" # meaning '0x000000080000000'.
OPTEE_DRAM_SIZE = "0x200000000" # meaning '0x0000000200000000'.
Kernel Configurations
Kernel Device Tree
Kernel device tree should be added to arch/arm64/boot/dts/mediatek/
in kernel source tree.
Create a device tree file
<mtxxxx-board_name>.dts
Refer to already existing device tree with the same SoC
Include necessary
.dtsi
file and configure RAM size (see uboot device tree configuration)
Do pin muxing and emmc configuration, such as frequency.
Add
<mtxxxx-board_name>.dtb
toarch/arm64/boot/dts/mediatek/Makefile
dtb-$(CONFIG_ARCH_MEDIATEK) += <mtxxxx-board_name>.dtb
Patch kernel sources and add the patch to meta-<board_name>/recipes-kernel/linux-mtk/files/.
Add the patch path to SRC_URI variable in meta-<board_name>/recipes-kernel/linux-mtk/linux-mtk_%.bbappend.
meta-<board_name>
├── recipes-kernel
│ └── linux-mtk
│ ├── files/ # patches to add device-tree kernel modification and configuration
│ └── linux-mtk_%.bbappend # apply the patches to linux kernel
Kernel Configuration
The kernel configuration used by yocto is a merge of the Linux ARM64 defconfig in arch/arm64/configs/defconfig and config fragments that can be found in recipes-kernel/linux-mtk/files.
Note
Please refer to Add extra kernel configuration and Kernel Development in order to add extra kernel configuration.
Yocto and Image customization
Add new prebuilt so/ko for drivers
In recipes-kernel/, create <module_name>/src folder and add <module_name>.ko.
Create a recipe file <recipe_name>.bb in meta-<board_name>/recipes-kernel/<module_name>/ in order to add the module to SRC_URI variable.
meta-<board_name>
├── recipes-kernel
│ ├── linux-mtk
│ │ ├── files/ # patches to add device-tree kernel modification and configuration
│ │ └── linux-mtk_%.bbappend # apply the patches to linux kernel
│ │
│ └── <module_name>
│ ├── src/
│ │ └── <module_name>.ko
│ │
│ └── <recipe_name>.bb
...
An example of what the recipe may look like:
SUMMARY = "Example of how to add prebuilt module"
DESCRIPTION = "${SUMMARY}"
FILESEXTRAPATHS:prepend := "${THISDIR}/src:"
inherit linux-kernel-base
S = "${WORKDIR}"
SRC_URI = "file://<module_name>.ko\"
S = "${WORKDIR}"
do_install() {
install -m 755 ${S}/<module_name>.ko
}
Add extra kernel configuration
In order to add extra kernel configuration:
Add new <board>.cfg in meta-<board_name>/recipes-kernel/linux-mtk/files/.
Create linux-mtk_%.bbappend in meta-<board_name>/recipes-kernel/linux-mtk/.
meta-<board_name>
├── recipes-kernel
│ └── linux-mtk
│ ├── files/ # config files and patches to add device-tree kernel modification and configuration
│ │ └── <board>.cfg
│ └── linux-mtk_%.bbappend # apply the patches to linux kernel
...
Append <board>.cfg to SRC_URI variable in linux-mtk_%.bbappend.
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " \
file://<board>.cfg \
"
Layer configuration
Detailed explanation is given in Create your own layer section.
Add the created layer to
meta-<board_name>/conf/bblayers.conf.sample
.
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
##OEROOT##/meta \
##OEROOT##/meta-poky \
##OEROOT##/meta-yocto-bsp \
##OEROOT##/../meta-arm/meta-arm \
##OEROOT##/../meta-arm/meta-arm-toolchain \
##OEROOT##/../meta-mediatek-bsp \
##OEROOT##/../meta-openembedded/meta-oe \
##OEROOT##/../meta-openembedded/meta-python \
##OEROOT##/../meta-rity/meta \
##OEROOT##/../meta-rity/meta-rity-bringup \
##OEROOT##/../meta-<board_name> \
"
Add meta-<board_name>/conf/layer.conf file and set layer information, priority, dependency …
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "<board_name>"
BBFILE_PATTERN:<board_name> = "^${LAYERDIR}/"
BBFILE_PRIORITY:<board_name> = "12"
# This should only be incremented on significant changes that will
# cause compatibility issues with other layers
LAYERVERSION:<board_name> = "1"
LAYERDEPENDS:<board_name> = ""
# Yocto 3.1, codename: Dunfell (LTS)
# Yocto 3.2, codename: Gatesgarth (Stable)
# Yocto 3.3, codename: Hardknott (Stable)
LAYERSERIES_COMPAT:<board_name> = "dunfell"
Adjust storage partition
Add custom.wks.in to meta-<board_name>/wic/.
meta-<board_name>
└── wic
└── custom.wks.in # Partitioning
Add the wks file to meta-<board_name>/conf/local.conf.sample
WKS_FILE:forcevariable = "custom.wks.in"
An example of image partitioning :
# SHORT-description: Create an image for MediaTek SoC based boards
# long-description: Creates a partitioned image for MediaTek SoC based boards.
bootloader --ptable gpt --timeout=0
part --source rawcopy --sourceparams="file=fip.bin" --part-name bootloaders --align 512 --fixed-size 4M
part --source rawcopy --sourceparams="file=fitImage" --part-name kernel --size 15M
part / --source rootfs --fstype=ext4 --label rootfs --part-name rootfs --part-type B921B045-1DF0-41C3-AF44-4C6F280D3FAE --active --exclude-path=home/
part /home --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/home --fstype=ext4 --label home --part-name home --part-type 933AC7E1-2EB4-4F13-B844-0E14E2AEF915 --use-uuid --size ${IMAGE_HOME_SIZE} --mkfs-extraopts "-b ${WIC_BLOCK_SIZE}"
Note
Memory reserved regions
The size of memory reserved regions used by IoT Yocto SDK is not mandatory to be changed. The memory mapping for MT8395(Genio 1200) and MT8365(Genio 350) are shown as follows:

For example if you would like to adjust the TF-A(BL31) start address and size, you could find the definition in trusted-firmware-a source and dts:
platform_def.h for MT8395(Genio 1200) :
#define TZRAM_BASE (0x54600000)
#define TZRAM_SIZE (0x00200000)
mt8195-demo.dts for MT8395(Genio 1200) :
bl31_secmon_reserved: secmon@54600000 {
no-map;
reg = <0 0x54600000 0x0 0x200000>;
};
For example if you would like to adjust the OP-TEE(BL32), you could find the definition in trusted-firmware-a source, dts and machine configurations in meta-mediatek-bsp layer:
platform_def.h for MT8395(Genio 1200) :
#define BL32_BASE (0x43200000)
#define BL32_LIMIT (0x00c00000)
mt8195-demo.dts for MT8395(Genio 1200) :
optee_reserved: optee@43200000 {
no-map;
reg = <0 0x43200000 0 0x00c00000>;
};
mediatek-common.inc for MT8395(Genio 1200) :
OPTEE_TZDRAM_START ?= "0x43200000"
OPTEE_TZDRAM_SIZE ?= "0x00c00000"
Note
Boot process (systemd) customization
Enable Systemd
Add the following lines to enable systemd by default:
meta-<board_name>
├── conf
│ ├── machine
│ │ └── <machine_name>.conf #
│ ├── layer.conf #
│ ├── local.conf.sample #
│ └── bblayers.conf.sample #
DISTRO_FEATURES_append = " systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit"
VIRTUAL-RUNTIME_init_manager = "systemd"
VIRTUAL-RUNTIME_initscripts = "systemd-compat-units"
Add Systemd Services File
Create meta-<board_name>/recipes-core/systemd/files
Add service files <service_name>,service to /files
Add systemd_%.bbappend recipe to integrate the service to systemd configuration.
meta-<board_name>
├── recipes-core
│ └── systemd
│ ├── files/
│ │ └── <service_name>.service
│ └── systemd_%.bbappend
...
Hardware documentation
Please refer to MediaTek Online or request hardware documentation from your MediaTek contact window.