@samitouri / QOSamiQemu / commits / a539bb911e

tests/functional/riscv64: Add K230 Linux boot tests

The K230 machine supports direct Linux boot and firmware boot through the SDK U-Boot, but neither path has functional test coverage. Add one test for each boot path. Both tests use the Yocto initramfs assets and wait for the shell prompt to confirm a successful boot. Fetch the boot assets from the k230-boot-assets repository maintained by Chao Liu. Pin the URLs to a repository commit and verify each asset with its SHA-256 digest. Signed-off-by: Junze Cao <caojunze424@gmail.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260711125320.72319-1-caojunze424@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Junze Cao committed Jul 11, 2026 at 20:53 UTC a539bb911ee1085c69ce00781acd2f13bd3cb82b
3 files changed +111
MAINTAINERS
+1
@@ -1830,6 +1830,7 @@ F: hw/riscv/k230.c
1830 F: hw/watchdog/k230_wdt.c
1831 F: include/hw/riscv/k230.h
1832 F: include/hw/watchdog/k230_wdt.h
1833 +F: tests/functional/riscv64/test_k230.py
1834 F: tests/qtest/k230-wdt-test.c
1835
1836 RX Machines
tests/functional/riscv64/meson.build
+2
@@ -2,6 +2,7 @@
2
3 test_riscv64_timeouts = {
4 'boston' : 120,
5 + 'k230' : 120,
6 'tuxrun' : 120,
7 }
8
@@ -13,6 +14,7 @@ tests_riscv64_system_quick = [
14 tests_riscv64_system_thorough = [
15 'endianness',
16 'boston',
17 + 'k230',
18 'sifive_u',
19 'tt_atlantis',
20 'tuxrun',
tests/functional/riscv64/test_k230.py new
+108
@@ -0,0 +1,108 @@
1 +#!/usr/bin/env python3
2 +#
3 +# Functional tests that boot Linux on a Kendryte K230 machine.
4 +#
5 +# The direct boot test lets QEMU load OpenSBI, Linux, the device tree, and the
6 +# initramfs. The firmware boot test starts the K230 SDK U-Boot and uses bootm
7 +# to launch OpenSBI and Linux from images preloaded into RAM.
8 +#
9 +# Author:
10 +# Junze Cao
11 +#
12 +# SPDX-License-Identifier: GPL-2.0-or-later
13 +
14 +import os
15 +
16 +from qemu_test import Asset, LinuxKernelTest
17 +from qemu_test import exec_command_and_wait_for_pattern
18 +from qemu_test import interrupt_interactive_console_until_pattern
19 +
20 +
21 +class K230Machine(LinuxKernelTest):
22 +
23 + ASSET_KERNEL = Asset(
24 + ('https://raw.githubusercontent.com/zevorn/k230-boot-assets/'
25 + 'c3c32fb46e8307c5063f13e8f367c98bf9273cd1/'
26 + 'yocto/direct-boot/Image'),
27 + '3a44970213fa68ad318d308518adfc0bf4bee72ed1b2926f9b468f82ef7d7829')
28 + ASSET_DTB = Asset(
29 + ('https://raw.githubusercontent.com/zevorn/k230-boot-assets/'
30 + 'c3c32fb46e8307c5063f13e8f367c98bf9273cd1/'
31 + 'yocto/direct-boot/k230-canmv.dtb'),
32 + '5050240b48ce0988c73eaefa73e4945a40abca503cf488d22a3adf6ef50bbe4c')
33 + ASSET_INITRD = Asset(
34 + ('https://raw.githubusercontent.com/zevorn/k230-boot-assets/'
35 + 'c3c32fb46e8307c5063f13e8f367c98bf9273cd1/'
36 + 'yocto/direct-boot/rootfs.cpio.gz'),
37 + '4e1869a99a232ee60324f71f3a9e84a79b03ccabb5b73f8a727c5ff5be5c0914')
38 + ASSET_UBOOT = Asset(
39 + ('https://raw.githubusercontent.com/zevorn/k230-boot-assets/'
40 + 'c3c32fb46e8307c5063f13e8f367c98bf9273cd1/common/u-boot'),
41 + '0915b9a92a7c911846a8cf691866ef14ef050a51d04209f884ae8e9ec33f36d2')
42 + ASSET_FW_JUMP = Asset(
43 + ('https://raw.githubusercontent.com/zevorn/k230-boot-assets/'
44 + 'c3c32fb46e8307c5063f13e8f367c98bf9273cd1/'
45 + 'common/fw_jump.uImage'),
46 + 'cf7788e470f1d6e8c85491ecdc2705518db1b6af54080e8c7a3464bad0d902b7')
47 +
48 + def wait_for_linux_shell(self):
49 + self.wait_for_console_pattern('meta-k230 initramfs starting...')
50 + self.wait_for_console_pattern('~ #')
51 +
52 + def test_k230_direct_boot(self):
53 + self.set_machine('k230')
54 + kernel_path = self.ASSET_KERNEL.fetch()
55 + dtb_path = self.ASSET_DTB.fetch()
56 + initrd_path = self.ASSET_INITRD.fetch()
57 +
58 + self.vm.set_console()
59 + self.vm.add_args('-kernel', kernel_path,
60 + '-dtb', dtb_path,
61 + '-initrd', initrd_path,
62 + '-append', 'console=ttyS0,115200 earlycon=sbi',
63 + '-no-reboot')
64 + self.vm.launch()
65 + self.wait_for_linux_shell()
66 +
67 + def test_k230_uboot_boot(self):
68 + self.set_machine('k230')
69 + kernel_path = self.ASSET_KERNEL.fetch()
70 + dtb_path = self.ASSET_DTB.fetch()
71 + initrd_path = self.ASSET_INITRD.fetch()
72 + uboot_path = self.ASSET_UBOOT.fetch()
73 + fw_jump_path = self.ASSET_FW_JUMP.fetch()
74 + initrd_end = 0x0a100000 + os.path.getsize(initrd_path)
75 +
76 + self.vm.set_console()
77 + self.vm.add_args(
78 + '-bios', uboot_path,
79 + '-device',
80 + f'loader,file={fw_jump_path},addr=0xc100000,force-raw=on',
81 + '-device',
82 + f'loader,file={kernel_path},addr=0x8200000,force-raw=on',
83 + '-device',
84 + f'loader,file={initrd_path},addr=0xa100000,force-raw=on',
85 + '-device',
86 + f'loader,file={dtb_path},addr=0xa000000,force-raw=on',
87 + '-no-reboot')
88 + self.vm.launch()
89 +
90 + interrupt_interactive_console_until_pattern(self, 'K230#')
91 + commands = (
92 + 'setenv bootargs console=ttyS0,115200 earlycon=sbi',
93 + 'fdt addr 0xa000000',
94 + 'fdt resize 8192',
95 + 'fdt set /chosen linux,initrd-start <0x0 0xa100000>',
96 + f'fdt set /chosen linux,initrd-end <0x0 0x{initrd_end:x}>',
97 + )
98 + for command in commands:
99 + exec_command_and_wait_for_pattern(self, command, 'K230#')
100 +
101 + exec_command_and_wait_for_pattern(
102 + self, 'bootm 0xc100000 - 0xa000000',
103 + 'Starting kernel ...', failure_message='ERROR')
104 + self.wait_for_linux_shell()
105 +
106 +
107 +if __name__ == '__main__':
108 + LinuxKernelTest.main()