Replies: 4 comments 1 reply
-
Hey @xuechou! I'm very sorry I've never answered this. It somehow slipped my radar. Are you still experiencing this issue? |
Beta Was this translation helpful? Give feedback.
-
Yes, I appreciate your help @josecm. I want to add second baremetal virtual machine. But I have no idea the VM configuration is correct or not? |
Beta Was this translation helpful? Give feedback.
-
imgs/qemu-aarch64-virt/baremetal/config/baremetal.c #include <config.h>
-VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
+VM_IMAGE(baremetal_image1, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin)); /* modified */
+VM_IMAGE(baremetal_image2, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin)); /* modified */
+/**
+ * Config each VM.
+ */
struct config config = {
+ /**
+ * This macro must be always placed in the config struct, to initialize,
+ * configuration independent fields.
+ */
CONFIG_HEADER
-
- .vmlist_size = 1,
+
+ /**
+ * This defines an array of shared memory objects that may be associated
+ * with inter-partition communication objects in the VM platform definition
+ * below using the shared memory object ID, ie, its index in the list.
+ */
+ .shmemlist_size = 1,
+ .shmemlist = (struct shmem[]) {
+ [0] = {.size = 0x1000,}
+ },
+
+ /**
+ * This configuration has 2 VMs.
+ */
+ .vmlist_size = 2,
.vmlist = {
{
+ .image = {
+ .base_addr = 0x80000000,
+ /**
+ * Use the VM_IMAGE_OFFSET and VM_IMAGE_SIZE to initialize
+ * the image fields passing the identifier of the image.
+ */
+ .load_addr = VM_IMAGE_OFFSET(baremetal_image1), /* modified */
+ .size = VM_IMAGE_SIZE(baremetal_image1) /* modified */
+ },
+
+ .entry = 0x80000000,
+ .cpu_affinity = 0x3,
+ .colors = 0x0F0F0F0F,
+
+ .platform = {
+
+ .cpu_num = 2,
+
+ .region_num = 1,
+ .regions = (struct mem_region[]) {
+ {
+ .base = 0x80000000,
+ .size = 0x100000
+ }
+ },
+
+ .dev_num = 1,
+ .devs = (struct dev_region[]) {
+ {
+ /* UART0 */
+ .pa = 0x1c090000,
+ .va = 0x1c090000,
+ .size = 0x10000,
+ .interrupt_num = 1,
+ .interrupts = (uint64_t[]) {38}
+ }
+ },
+
+ .ipc_num = 1,
+ .ipcs = (struct ipc[]) {
+ {
+ .base = 0x80100000,
+ .size = 0x1000,
+ .shmem_id = 0,
+ .interrupt_num = 1,
+ .interrupts = (uint64_t[]) {42}
+ }
+ },
+
+ .arch = {
+ .gic = {
+ .gicc_addr = 0x2C000000,
+ .gicd_addr = 0x2F000000
+ }
+ }
+ },
+
+ },
+
+ {
.image = {
.base_addr = 0x00000000,
- .load_addr = VM_IMAGE_OFFSET(baremetal_image),
- .size = VM_IMAGE_SIZE(baremetal_image)
+ .load_addr = VM_IMAGE_OFFSET(baremetal_image2), /* modified */
+ .size = VM_IMAGE_SIZE(baremetal_image2) /* modified */
},
- .entry = 0x00000000,
+ .entry = 0x0000000,
+ .cpu_affinity = 0xC,
+ .colors = 0xF0F0F0F0,
.platform = {
- .cpu_num = 4,
+ .cpu_num = 2,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
- .size = 0x4000000
+ .size = 0x100000
}
},
- .dev_num = 2,
+ .dev_num = 1,
.devs = (struct dev_region[]) {
{
- /* PL011 */
- .pa = 0x9000000,
- .va = 0xFF010000,
+ /* UART1 */
+ .pa = 0x1C0B0000,
+ .va = 0x1c090000,
.size = 0x10000,
.interrupt_num = 1,
- .interrupts = (uint64_t[]) {33}
+ .interrupts = (uint64_t[]) {39}
},
- {
- /* Arch timer interrupt */
+ {
+ /* Timer interrupt */
+ .interrupt_num = 1,
+ .interrupts = (uint64_t[]) {27}
+ }
+ },
+
+ .ipc_num = 1,
+ .ipcs = (struct ipc[]) {
+ {
+ .base = 0x90000000,
+ .size = 0x1000,
+ .shmem_id = 0,
.interrupt_num = 1,
- .interrupts =
- (uint64_t[]) {27}
+ .interrupts = (uint64_t[]) {112}
}
},
.arch = {
.gic = {
- .gicd_addr = 0xF9010000,
- .gicr_addr = 0xF9020000,
+ .gicc_addr = 0x2C000000,
+ .gicd_addr = 0x2F000000
}
}
},
- }
+ },
},
};
\ No newline at end of file print from QEMUtt@xxx:~/py/bao-demos$ make PLATFORM=qemu-aarch64-virt DEMO=baremetal run
--------------------------------------------------------------------------------
5) Setup connections and jump to Bao
Qemu will let you know in which pseudo-terminals it placed the virtio serial.
For example:
char device redirected to /dev/pts/4 (label serial3)
If you are running more than one guest, open a new terminal and connect to it.
For example:
screen /dev/pts/4
If you are running a Linux guest you can also connect via ssh to it by opening
a new terminal and running:
ssh root@localhost -p 5555
Finally, make u-boot jump to where the bao image was loaded:
go 0x50000000
When you want to leave QEMU press Ctrl-a then x.
char device redirected to /dev/pts/0 (label serial3)
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.4(release):7d31f57
NOTICE: BL1: Built : 14:06:16, Dec 4 2021
NOTICE: BL1: Booting BL2
NOTICE: BL2: v2.4(release):7d31f57
NOTICE: BL2: Built : 14:06:16, Dec 4 2021
NOTICE: BL1: Booting BL31
NOTICE: BL31: v2.4(release):7d31f57
NOTICE: BL31: Built : 14:06:16, Dec 4 2021
U-Boot 2021.01 (Dec 04 2021 - 14:01:10 +0800)
DRAM: 4 GiB
Flash: 64 MiB
*** Warning - bad CRC, using default environment
In: pl011@9000000
Out: pl011@9000000
Err: pl011@9000000
Net: eth0: virtio-net#31
Hit any key to stop autoboot: 0
starting USB...
No working controllers found
USB is stopped. Please issue 'usb start' first.
scanning bus for devices...
Device 0: unknown device
Device 0: unknown device
starting USB...
No working controllers found
BOOTP broadcast 1
DHCP client bound to address 192.168.42.15 (3 ms)
Using virtio-net#31 device
TFTP from server 192.168.42.2; our IP address is 192.168.42.15
Filename 'boot.scr.uimg'.
Load address: 0x40200000
Loading: *
TFTP error: 'Access violation' (2)
Not retrying...
BOOTP broadcast 1
DHCP client bound to address 192.168.42.15 (1 ms)
Using virtio-net#31 device
TFTP from server 192.168.42.2; our IP address is 192.168.42.15
Filename 'boot.scr.uimg'.
Load address: 0x40400000
Loading: *
TFTP error: 'Access violation' (2)
Not retrying...
=> go 0x50000000
## Starting application at 0x50000000 ...
Bao Hypervisor
BAO ERROR: no handler for abort ec = 0x20
BAO ERROR: no emulation handler for abort(0xff010030 at 0x1090) |
Beta Was this translation helpful? Give feedback.
-
Hey again @xuechou! So, to start, there seemed to be an issue of the version of the bare-metal guest used on the demos. I've fixed this and updated the demo. So you might want to delete the wrkdir and pulling or clone the repo all over. Rergarding adding a second VM. Since you are using the exact the same image you only need to replicate the image and the config structure for the second VM, and reduce the number of cpus (maybe 2/2 or 3/1 for vm1/vm2). The only other point that is critical is the UART. The Qemu arm virt platform only provides a single 8250 uart which the guest is using. It might also provide other serial devices in the form of virtio console (which linux is using in the demos) but the baremetal guest does not have a driver for that. The first, simpler solution, is to share the single uart we have. However, bao does not allow the interrupt to be shared, so you have to remove it for one of the guests. This of course will result in having intermixed output of the two guests. The configuration for this would be something like: #include <config.h>
VM_IMAGE(baremetal_image, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
VM_IMAGE(baremetal_image2, XSTR(BAO_DEMOS_WRKDIR_IMGS/baremetal.bin));
struct config config = {
CONFIG_HEADER
.vmlist_size = 2,
.vmlist = {
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image),
.size = VM_IMAGE_SIZE(baremetal_image)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 2,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* PL011 */
.pa = 0x9000000,
.va = 0xFF010000,
.size = 0x10000,
.interrupt_num = 1,
.interrupts = (uint64_t[]) {33}
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
},
{
.image = {
.base_addr = 0x00000000,
.load_addr = VM_IMAGE_OFFSET(baremetal_image2),
.size = VM_IMAGE_SIZE(baremetal_image2)
},
.entry = 0x00000000,
.platform = {
.cpu_num = 2,
.region_num = 1,
.regions = (struct mem_region[]) {
{
.base = 0x00000000,
.size = 0x4000000
}
},
.dev_num = 2,
.devs = (struct dev_region[]) {
{
/* PL011 */
.pa = 0x9000000,
.va = 0xFF010000,
.size = 0x10000,
},
{
/* Arch timer interrupt */
.interrupt_num = 1,
.interrupts =
(uint64_t[]) {27}
}
},
.arch = {
.gic = {
.gicd_addr = 0xF9010000,
.gicr_addr = 0xF9020000,
}
}
},
}
},
}; In the past I've manually patched QEMU to add a second 8250 uart so that I could use it in a setup very similar to this. It is quite straightforward. If you are interested in doing that and need help, let me know. |
Beta Was this translation helpful? Give feedback.
-
I want to add the same VM to the demo: baremetal + qemu-aarch64-virt.
Then I modified
baremetal.c
from srcs/bao/configs/example/config.cBut got no handler errors when QEMU running. The code and error are appended below.
What's wrong with my VM configuration or whatever?
Beta Was this translation helpful? Give feedback.
All reactions