Kernel Development

The Linux kernel is a system software that performs hardware initialization and manages resources of a system. It hides implementation details of underlying hardware and provides an unified interface to applications built upon it. Yocto Project provides a simple way to allow users to build kernel image and customize it to fit application needs.

The following sections will explain how to build, modify, re-build and load the modified kernel in IoT Yocto.

Build and load kernel

To build kernel image in Yocto Project, perform the following steps:

  1. Set up a build environment by following instructions in environment setup.

  2. Build reference board kernel for the associated SoC:

    MACHINE=<machine> bitbake linux-mtk
    

    The available values for <machine> can be:

    • i350-evk for Genio 350-EVK. This is an alias to mt8365-evk.

    • i1200-demo for Genio 1200-Demo Board. This is an alias to mt8395-demo.

    The resulting kernel binary is located in <build-dir>/tmp/work/<machine>-poky-linux/linux-mtk/<version>.

    The corresponding kernel images suitable for flashing process is located in <build-dir>/tmp/deploy/images/<machine>.

  3. Kernel patches and custom kernel configuration can be changed by modifying linux-mtk_<version>.bb and related board config (*.cfg).

    These files (linux-mtk_<version>.bb and *.cfg) can be found in <source-dir>/meta-mediatek-bsp/recipes-kernel/linux/.

  4. Once new kernel image is built you can use AIOT tools to update the kernel partition with:

    aiot-flash kernel
    

For building Linux outside of Yocto source tree, please refer to BSP development guide.

Modify Kernel Configuration

The kernel configuration is stored as Yocto kernel config fragments in the path like:

src/meta-mediatek-bsp/recipes-kernel/linux/linux-mtk/<config file>

Where the <config file> is the configuration fragment associated with SoC and boards:

  • SoC specific config fragment for MT8365 is mt8365.cfg.

  • Board specific config fragment for i350 EVK is mt8365-evk.cfg.

For example, to enable the USB FunctionFS for MT8365, you can add the following lines to mt8365.cfg:

# USB
CONFIG_USB_FUNCTIONFS=m
CONFIG_USB_FUNCTIONFS_GENERIC=y

and rebuild the linux-mtk recipe.

Sometimes a board config fragment might has a different name from the name used for building image. To locate which fragment is used by which board (the value of MACHINE used in bitbake command), you can search configuration files under src/meta-mediatek-bsp/conf/machine/ for machine names.

For example, the command MACHINE=i1200-demo bitbake linux-mtk reads configurations from src/meta-mediatek-bsp/conf/machine/i1200-demo.conf, which is an alias to mt8395-demo.conf. And in mt8395-demo.conf, there is a machine override setting like this:

MACHINEOVERRIDES =. "mt8195-demo:mt8395-demo:i1200-demo:"

These overridden machine names are used by recipes-kernel/linux/linux-mtk-common.inc to determine which kernel configuration fragment to be loaded:

SRC_URI:append:mt8195-demo = " file://mt8195-demo.cfg "
SRC_URI:append:mt8365-evk = " file://mt8365-evk.cfg "

As a result, the configuration fragment mt8195-demo.cfg will be included to the KCONFIG when MACHIINE is set to i1200-demo.

Modify kernel Source

To modify kernel source, perform the following:

  1. Run devtool modify linux-mtk to get kernel source

  2. Kernel source is located under <build-dir>/workspace/sources/linux-mtk

  3. Modify kernel source

  4. Build modified kernel by bitbake linux-mtk or devtools build linux-mtk

  5. Flash the fitImage by running AIOT tools command aiot-flash kernel

  6. Commit your changes and format them as patches with git:

    git commit -s
    git format-patch <previous-commit>..<current-commit>
    
  7. You can apply the generated git patch by putting those patches to src/meta-mediatek-bsp/recipes-kernel/linux/linux-mtk/.

  8. Add the file name of the patch to the SRC_URI in corresponding .bb recipe file. For example, if you are working on linux-mtk_5.10.bb, the SRC_URI becomes:

    SRC_URI += "${@bb.utils.contains('DISTRO_FEATURES', 'optee', 'file://optee.cfg', '', d)} \
                ${@bb.utils.contains('MACHINE_FEATURES', 'vesper-hat', 'file://vesper.cfg', '', d)}file://usbnet.cfg \
                file://pm.cfg \
                ${@bb.utils.contains('DISTRO_FEATURES', 'nfs', 'file://nfs.cfg', '', d)} \
                ${@bb.utils.contains("DISTRO_FEATURES", "bringup", "${BRINGUP_CFG}", "", d)} \
                ${@bb.utils.contains("DISTRO_FEATURES", "demo", "${DEMO_CFG}", "", d)} \
                file://mt8365-evk.cfg \
                file://mt8365.cfg \
                file://0001-your-new-patch.patch \
                "
    

    by appending the line file://0001-your-new-patch.patch \.

Step 6. to 8. can also be combined together using the following bitbake command:

devtool update-recipe linux-mtk

Flash kernel image

After building linux-mtk, the built image can be found under the path <build-dir>/tmp/deploy/images/<machine>. Now we can flash the fitImage with AIOT tools:

aiot-flash kernel

Kernel Debugging Tools

Ramoops oops/panic logger

Ramoops can be used to examine the kernel logs and trace buffers when OS freezing, fatal kernel panic or OOPS happens. For more information on Ramoops, please refer to Ramoops oops/panic logger.

To enable Ramoops, perform the following steps:

  1. Add PSTORE configurations to kernel config file, as instructed in Modify Kernel Configuration.

    CONFIG_PSTORE_CONSOLE=y
    CONFIG_PSTORE_FTRACE=y
    CONFIG_PSTORE_PMSG=y
    CONFIG_PSTORE_RAM=m
    CONFIG_PSTORE=y
    
  2. Create a new config file ramoops.cfg and put it under the folder src/meta-rity/meta-rity-demo/recipes-kernel/linux/files, and modify linux-mtk_%.bbappend to include this config file:

    DEMO_CFG = " \
    file://usb-audio.cfg \
    file://exfat.cfg \
    file://ramoops.cfg \
    
  3. Rebuild and flash the kernel image.

In the shell of target board, load ramoops module and perform testing:

$ modprobe ramoops
$ <perform your test>
$ reboot

After rebooting, read the kernel log from the previous boot:

$ modprobe ramoops
$ cat /sys/fs/pstore/console-ramoops-0
$ cat /sys/fs/pstore/dmesg-ramoops-0

Register Access Tools

Devmem2

Using the Devmem tool, which allows the reading and writing of peripheral registers.

To use Devmem, enter the following command:

devmem2 address [type [data]]
Where:
  • [address] Memory address to act upon.

  • [type] Access operation type: [b]yte, [h]alfword, [w]ord.

  • [data] Data to be written.