Zephyr OS on VIM3

Which Khadas SBC do you use?

Khadas VIM3 (A311D Soc)

Which system do you use? Android, Ubuntu, OOWOW or others?

Zephyr

Which version of system do you use? Khadas official images, self built images, or others?

Latest Zephyr SDK generated Image (v3.4)

Please describe your issue below:

I am trying to port the Zephyr Image to VIM-3 board. For reference, I am looking into files provided by Zephyr Official Document for the Khadas Edge-V.

With help of reference I was able to create soc/board files that were required to generated the zephyr.bin for the VIM3. After that, I had use mkimage to convert it and used the u-boot to load the same (as described in the reference link).

But after bootm command to load the image, it is getting stuck at “Starting Kernal”.

Following are the

  • Command I used during the u-boot:
    tftpboot ${pxefile_addr_r} zephyr.img; bootm start ${pxefile_addr_r}; bootm loados; bootm go
  • dtsi content:


#include <arm64/armv8-a.dtsi>
#include <zephyr/dt-bindings/interrupt-controller/arm-gic.h>
#include <zephyr/dt-bindings/interrupt-controller/irq.h>
#include <zephyr/dt-bindings/clock/g12a-clkc.h>
#include <zephyr/dt-bindings/clock/g12a-aoclkc.h>
#include <mem.h>


/ {
	interrupt-parent = <&gic>;
	#address-cells = <1>;
	#size-cells = <1>;

	cpus {
		#address-cells = <2>;
		#size-cells = <0>;

		cpu@0 {
			device_type = "cpu";
			compatible = "arm,cortex-a53";
			reg = <0x0 0x0>;
			enable-method = "psci";
		};
		cpu@1 {
			device_type = "cpu";
			compatible = "arm,cortex-a53";
			reg = <0x0 0x1>;
			enable-method = "psci";
		};
		cpu@2 {
			device_type = "cpu";
			compatible = "arm,cortex-a73";
			reg = <0x0 0x100>;
			enable-method = "psci";
		};
		cpu@3 {
			device_type = "cpu";
			compatible = "arm,cortex-a73";
			reg = <0x0 0x101>;
			enable-method = "psci";
		};
		cpu@4 {
			device_type = "cpu";
			compatible = "arm,cortex-a73";
			reg = <0x0 0x102>;
			enable-method = "psci";
		};
		cpu@5 {
			device_type = "cpu";
			compatible = "arm,cortex-a73";
			reg = <0x0 0x103>;
			enable-method = "psci";
		};
        
	};

	psci: psci {
		compatible = "arm,psci-1.0";
		method = "smc";
	};

	sram0: memory@10000000 {
		reg = <0x10000000 DT_SIZE_M(128)>;
	};

	timer {
		compatible = "arm,armv8-timer";
		interrupt-parent = <&gic>;
		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>,
			         <GIC_PPI 14 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>,
			         <GIC_PPI 11 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>,
			         <GIC_PPI 10 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>;
                    };

//---------------------working------------------------------//
	uart2: serial@ff803000 {
		compatible = "amlogic,a311d-uart", "ns16550";
		reg = <0xff803000 0x1000>;
		interrupt-parent = <&gic>;
		interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING IRQ_DEFAULT_PRIORITY>;
		status = "disabled";
		reg-shift = <2>;
		clock-frequency = <24000000>;
	};

	clkc_AO: clock-controller {
		compatible = "amlogic,meson-axg-aoclkc";
		#clock-cells = <1>;
		#reset-cells = <1>;
		clocks = <&xtal>;
		clock-names = "xtal";
	};

	gic: interrupt-controller@ffc01000 {
		compatible = "arm,gic-v3", "arm,gic";
		reg = <0x0 0xffc01000 0 0x1000>,
				<0x0 0xffc02000 0 0x2000>,
				<0x0 0xffc04000 0 0x2000>,
				<0x0 0xffc06000 0 0x2000>;
		interrupt-controller;
		#interrupt-cells = <4>;
		#address-cells = <0>;
		#clock-cells = <0>;
	};

	xtal: xtal-clk {
		compatible = "fixed-clock";
		clock-frequency = <24000000>;
		//clock-output-names = "xtal";
		#clock-cells = <0>;
	};
};

Hello @shisin

The zephyr docs are for Edge with Rockchip platform, at the moment zephyr doesn’t support any amlogic platforms, you can check in their docs.

https://docs.zephyrproject.org/latest/kconfig.html#!CONFIG_SOC_

Regards.

Hi,
Thanks for replying.

I am aware of the fact that zephyr right now doesn’t support the VIM3(Amlogic), due which I am trying to port the Zephyr to VIM3, by taking reference from Edge-V(Rockchip).

So, I had followed the Porting Guide provided by the Official Zephyr Doc and taking reference from Edge-V Board files also. I had created following files (if wanted I can share the content of those file) and a311d.dtsi for soc initialization(as shared in previous post):
image

After which I was able to generate zephyr.bin image for Khadas VIM-3, and then I had used u-boot official image provided by the Khadas to setup the TFTP Server environment to load zephyr image, with help of following command:

tftpboot ${pxefile_addr_r} zephyr.img; bootm start ${pxefile_addr_r}; bootm loados; bootm go

with help of printenv, pxefile_addr_r value was 0x01080000 and for the load memory addr I have provided value 0x10000000.

But after above command, u-boot got stuck on the “Starting Kernel”

Can you please let me know, where I might have gone incorrect?

Regards
shisin

@shisin can you share your kernel defconfig and other file details ?

Sure!

As mentioned by the Zephyr’s Porting guide , board.cmake, CMakeLists.txt are optional. So, I have kept them empty (cross checked with Edge-V files).

Following are the content of the

  • Kconfig.board
config BOARD_KHADAS_VIM3
	bool "Khadas VIM3"
	depends on SOC_SERIES_A311D
  • Kconfig.defconfig
config BOARD
	default "khadas_vim3"
	depends on BOARD_KHADAS_VIM3

  • khadas_vim3_defconfig
# Platform Configuration
CONFIG_SOC_SERIES_A311D=y
CONFIG_SOC_A311D=y
CONFIG_BOARD_KHADAS_VIM3=y
CONFIG_ARM64_VA_BITS_40=y
CONFIG_ARM64_PA_BITS_40=y
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000
CONFIG_CACHE_MANAGEMENT=y
CONFIG_ARMV8_A_NS=y

# Serial Drivers
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y

# Enable Console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
  • khadas_vim3.dts
 /dts-v1/;

 #include <amlogic/a311d.dtsi>
 
 / {
     model = "Khadas VIM3";
     compatible = "khadas,vim3";
 
     chosen {
         zephyr,sram = &sram0;
         zephyr,console = &uart2;
         zephyr,shell-uart = &uart2;
     };
 
     cpus {
         /delete-node/ cpu@1;
         /delete-node/ cpu@2;
         /delete-node/ cpu@3;
         /delete-node/ cpu@4;
         /delete-node/ cpu@5;
     };
 };
 
 &uart2 {
     status = "okay";
 };
  • khadas_vim3.yaml
identifier: khadas_vim3
name: Khadas VIM3 (single core, non SMP)
type: mcu
arch: arm64
toolchain:
  - zephyr
  - cross-compile
ram: 8192

One more thing, in previous post, I forgot to mention, after I had build the zephyr.bin, before loading the image I have mkimage (as suggested for the Edge-V also)
mkimage -C none -A arm64 -O linux -a 0x10000000 -e 0x10000000 -d build/zephyr/zephyr.bin build/zephyr/zephyr.img

Let me know, if anymore details are required.
Thanks!!

CONFIG_SOC_A311D=y this is not observed from Zephyr docs, are you porting the kernel yourself as well ?

I did follow the Zephyr doc, please check following snapshot from porting guide:

Yeah, I am trying run the console application(end objective is different but for starting point, I am working with console application) on VIM3, so everything is required to port for zephyr.

@shisin okay, I can check next week and get back to you.

Hi @Electr1,
Did you get the chance to look into this issue?

Let me know, if anything is required from me.

Hello @shisin, I’m looking at it.

This isn’t anywhere in the source of zephyr RTOS, so you have ported it yourself, right ?

This maybe leading to the usage of some other uart port on the device, have you verified this ?

Okay, it’s mentioned in first post.

Yes, as described in the first post, for a311d.dtsi file, I have ported myself(a311d.dtsi file content in the Issue description). I have used the uart2 at memory address 0xff80300

	uart2: serial@ff803000 {
		compatible = "amlogic,a311d-uart", "ns16550";
		reg = <0xff803000 0x1000>;
		interrupt-parent = <&gic>;
		interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING IRQ_DEFAULT_PRIORITY>;
		status = "disabled";
		reg-shift = <2>;
		clock-frequency = <24000000>;
	};

I have used this address by taking reference from Amlogic A311D datasheet

and cross verified from the dtsi used in the Android Kernel(they also utilize this address as well)

@shisin can you share the ported version of the code for me try build and verify on my side ?

@Electr1 , Can you please let me know, how can I share my code base with you? Because I am not able to find the attachment option(for my compressed folder) in the Reply.

@shisin please share as github/gitlab, or google drive.

@Electr1 Sorry for the delay. I was Out of Office last week.

Please find following github repo with required changes
shiPsin/zephyr: Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures. (github.com)

Okay I’ll take a look.

Gentle Reminder.

@Electr1, Did you get the chance to look into the code?

Hi @shisin I’m going through your changes to identify any missing or wrong components

I apologize for the delay, I will try to let you know as soon as possible.

@shisin

I have checked your code from the repository, I think that might not be the issue itself.
VIM3 needs scripts to boot linux kernel from uboot, can you check this out ?

As result, the load addr may also be wrong, you need to check it

Hi @Electr1,

I looked into the script you had provided, it seems at the start of boot time this script runs and check for the kernel image on the available memory. It also setup all the environment variable for address.

As for my uboot image which I downloaded from the Khadas site, it tries to setup following environment variables and addresses. It seems I am using those only (as mention in the earlier post i.e. command to load the Zephyr)

U-Boot 2021.07 (Oct 08 2023 - 17:38:49 +0800) khadas-vim3

Model: Khadas VIM3
SoC:   Amlogic Meson G12B (A311D) Revision 29:b (10:2)
DRAM:  3.8 GiB
MMC:   sd@ffe03000: 0, sd@ffe05000: 1, mmc@ffe07000: 2
Loading Environment from MMC... OK
DISPLAY: setup failsave FullHD mode
In:    serial
Out:   serial
Err:   serial
fusb302_init: Device ID: 0x91
CC connected in 1 as UFP
fusb302 detect chip.port_num = 0
Net:   eth0: ethernet@ff3f0000
Card did not respond to voltage select! : -110
Couldn't find partition mmc 1
Can't set block device
** Unrecognized filesystem type **
Can't set block device
Card did not respond to voltage select! : -110
Couldn't find partition mmc 1:2
Can't set block device
** No partition table - mmc 2 **
Couldn't find partition mmc 2:2
Can't set block device
[i] display embed logo
starting USB...
Bus usb@ff500000: Register 3000140 NbrPorts 3
Starting the controller
USB XHCI 1.10
scanning bus usb@ff500000 for devices... 2 USB Device(s) found
       scanning usb for storage devices... 0 Storage Device(s) found
Setting bus to 0
port mode is usb3.0
Hit SPACE in 2 seconds to stop autoboot=>  
=> printenv
arch=arm
baudrate=115200
board=vim3
board_name=vim3
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script} && script ${scriptaddr} 
boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootaa64.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtconi
boot_efi_bootmgr=if fdt addr ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr;fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_net_usb_start=;
boot_pci_enum=pci enum
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.cmd boot.ini boot.scr.uimg boot.scr
boot_source=emmc
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets=spi usb0 nvme0 mmc0 mmc1 mmc2  pxe dhcp 
bootcmd=run distro_bootcmd
bootcmd_dhcp=devtype=dhcp; run boot_net_usb_start; run boot_pci_enum; if dhcp ${scriptaddr} ${boot_script_dhcp}; then script ${scriptaddr}; fi;setenv efi_fdtfile ${fdtfile}; setenv efi_old_vci ${bootp_vci};sete;
bootcmd_mmc0=devnum=0; run mmc_boot
bootcmd_mmc1=devnum=1; run mmc_boot
bootcmd_mmc2=devnum=2; run mmc_boot
bootcmd_nvme0=devnum=0; run nvme_boot
bootcmd_pxe=run boot_net_usb_start; run boot_pci_enum; dhcp; if pxe get; then pxe boot; fi
bootcmd_romusb=if test "${boot_source}" = "usb" && test -n "${scriptaddr}"; then echo '(ROM USB boot)'; source ${scriptaddr}; fi
bootcmd_spi=test "$boot_source" = "spi" && sf probe && sf read $loadaddr 0x160000 0x008000 && script - - 0 1
bootcmd_usb0=devnum=0; run usb_boot
bootdelay=2
bootfile=boot.scr.uimg
cpu=armv8
distro_bootcmd=setenv nvme_need_init; for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
ethact=ethernet@ff3f0000
ethaddr=c8:63:14:72:4e:95
fdt_addr_r=0x08008000
fdtaddr=f0f0da40
fdtcontroladdr=f0f0da40
fdtfile=amlogic/meson-g12b-a311d-khadas-vim3.dtb
fdtoverlay_addr_r=0x08070000
hostname=meson-g12b-a311d-khadas-vim3
ipaddr=10.45.28.22
kernel_addr_r=0x08080000
kernel_comp_addr_r=0x0d080000
kernel_comp_size=0x2000000
load_efi_dtb=fdt_src="${devtype} ${devnum}:${distro_bootpart}"; fdt_file=${prefix}${efi_fdtfile}; load $fdt_src ${fdt_addr_r} $fdt_file && echo EFI fdt: $fdt_file && env exists fdtoverlay_addr_r && fdt_ovl_dir=e
load_logo=ll=0; test $boot_source = spi && sf probe && sf read $loadaddr 0x170000 0x10000 && ll=1; test $ll = 0 && ll=1 && load mmc 1 $loadaddr splash.bmp || load mmc 2 $loadaddr splash.bmp || load mmc 1:2 $loa 
loadaddr=0x01000000
logoaddr=0x00000000f0f1ec14
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
nvme_boot=run boot_pci_enum; run nvme_init; if nvme dev ${devnum}; then devtype=nvme; run scan_dev_for_boot_part; fi
nvme_init=if ${nvme_need_init}; then setenv nvme_need_init false; nvme scan; fi
nvme_need_init=false
port_mode=0
preboot=run load_logo; usb start; kbi init; test "$nvme_boot" = "" || kbi portmode r; sleep 1;
pxefile_addr_r=0x01080000
pxeuuid=00000000-0000-0000-0000-000000000000
ramdisk_addr_r=0x13000000
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootft
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;run boot_efi_boote
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAIe
scriptaddr=0x08000000
serveraddr=10.45.28.76
serverip=10.45.28.76
soc=meson
stderr=vidconsole,serial
stdin=usbkbd,serial
stdout=vidconsole,serial
tftp_filename=zephyr.img
tftp_remote_ip=10.45.28.20
usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi
vendor=amlogic

Environment size: 6121/32764 bytes



Please check and let me know, if I am missing something.

-Shiv