陳禹丞
Virtio is an open standard and framework, which defines virtualization-friendly abstarction for drivers and hardware. It is primarily used in virtualized environments to efficiently virtualize I/O devices, including network adapters, disk contollers, etc.
According to §1.4 in Virtio specification, all in-memory structures are assumed to be without additional padding. That is, all structures shall be enforced with GNU extension __attribute__((packed))
.
The mechanism for bulk data transport on Virtio devices is called a virtqueue. Each device can have zero or more virtqueues. For example, a network device can has two virtqueues for transmitting and receiving data, respectivly.
There are two types of virtqueues:
Each split virtqueue consistes of three parts:
VIRTQ_DEC_F_INDIRECT
feature. Therefore, this note will not cover it.VRING_DESC_F_WRITE
flag is set, the buffer it points to is write-only to the device and read-only otherwise.used_event
shall be neglected if VIRTIO_F_EVENT_IDX
not negotiated.avail_event
shall be neglected if VIRTIO_F_EVENT_IDX
not negotiated.In semu, all memory access are performed using mem_store
、mem_load
and mem_fetch
. Unlike rv32emu, which distinguishes between different access length and provides variation like mmu_write_w/s/b
for different operations.
Additionally, semu does not modularize virtual/physical address translation into a separate function, resulting in huge mem_store
and mem_load
function. In contrast, rv32emu does have mmu_translate
function and also inspects whether the address belongs to the PLIC or UART region within the MMIO_READ
/MMIO_WRITE
function-like macros.
Note that, in semu's implementation of virtio registers, the RV_EXC_LOAD_MISALIGN
exception is raised if the access width is not 4.
Also, ram
in semu is a raw pointer to uint32_t array, but in rv32emu is a pointer to memory_t
:
In semu, plic and uart I/O accept only word and byte instructions respectively, and raise RV_EXC_LOAD_MISALIGN
exception if trespassed. However, rv32emu does not verify whether the accessing instruction is word or byte instruction.
Virtio-blk device has been successfully migrated into rv32emu. Currently cleaning up the code.
Currently, virtio-net device in semu does not function properly, and is not covered in this note.
Linking of rv32emu with -O0
flag fails with following message:
See if the latest master
branch remains the above issue. If so, create an issue on GitHub.
otteryc After discussing the linking process and referencing c-linker-loader, we found that Link-Time Optimization (LTO) was the culprit. GCC worked fine after adding the
-fno-lto
flag. I am not quite sure whether it should be reported as an issue on GitHub.
However, clang-18 works perfectly:
The code from semu accesses the available ring and the used ring by manually offseting, which actually makes the code difficult to read. For instance: