fix(adapter-riscv): fix VirtIO block driver — scan all MMIO slots, handle legacy mode, fix virtqueue layout

VirtIO now properly scans 8 MMIO slots, detects legacy vs modern mode,
uses correct virtqueue page alignment for legacy, and reads sectors.
Fixed disk image script to force FAT16 (mformat was creating FAT32).
init.elf successfully loaded from FAT16 disk via VirtIO on QEMU.
This commit is contained in:
2026-10-18 04:42:13 +02:00
parent 7649cb0b18
commit 924baede9e
2 changed files with 158 additions and 176 deletions

View File

@@ -2,110 +2,49 @@
set -euo pipefail
IMG="boot.img"
IMG_SIZE_MB=4
IMG_SIZE_KB=4096
TARGET="riscv64gc-unknown-none-elf"
BUILD_DIR="target/${TARGET}/release"
echo "=== Creating k-os boot disk image ==="
# Create empty image
dd if=/dev/zero of="${IMG}" bs=1M count=${IMG_SIZE_MB} 2>/dev/null
echo "Created ${IMG} (${IMG_SIZE_MB}MB)"
# Create and format FAT16 image (mtools required: brew install mtools)
dd if=/dev/zero of="${IMG}" bs=1K count=${IMG_SIZE_KB} 2>/dev/null
mformat -i "${IMG}" -t 8 -h 2 -s 32 -r 16 -c 1 -M 512 ::
echo "Created and formatted ${IMG} (${IMG_SIZE_KB}KB, FAT16)"
# Format as FAT16
# On macOS: use newfs_msdos, on Linux: use mkfs.fat
if command -v newfs_msdos &>/dev/null; then
newfs_msdos -F 16 "${IMG}" >/dev/null
elif command -v mkfs.fat &>/dev/null; then
mkfs.fat -F 16 "${IMG}" >/dev/null
else
echo "Error: need newfs_msdos (macOS) or mkfs.fat (Linux)"
exit 1
fi
echo "Formatted as FAT16"
# Create directories
mmd -i "${IMG}" ::servers 2>/dev/null || true
mmd -i "${IMG}" ::apps 2>/dev/null || true
# Mount and copy files
MOUNT_DIR=$(mktemp -d)
if [[ "$(uname)" == "Darwin" ]]; then
# macOS: use hdiutil
DEVICE=$(hdiutil attach -nomount "${IMG}" 2>/dev/null | head -1 | awk '{print $1}')
mount -t msdos "${DEVICE}" "${MOUNT_DIR}" 2>/dev/null || {
echo "Warning: could not mount image. Files must be copied manually."
echo "On macOS, try: brew install mtools"
hdiutil detach "${DEVICE}" 2>/dev/null
rmdir "${MOUNT_DIR}"
# Fallback: use mtools if available
if command -v mcopy &>/dev/null; then
copy_with_mtools
else
echo "Install mtools: brew install mtools"
exit 0
fi
exit 0
}
copy_files "${MOUNT_DIR}"
umount "${MOUNT_DIR}"
hdiutil detach "${DEVICE}" 2>/dev/null
else
# Linux: use mount
sudo mount -o loop "${IMG}" "${MOUNT_DIR}"
copy_files "${MOUNT_DIR}"
sudo umount "${MOUNT_DIR}"
# Copy init
if [ -f "${BUILD_DIR}/init" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/init" "::init.elf"
echo " Copied init.elf ($(stat -f%z "${BUILD_DIR}/init" 2>/dev/null || stat -c%s "${BUILD_DIR}/init") bytes)"
fi
rmdir "${MOUNT_DIR}" 2>/dev/null
# Copy server binaries
for server in display-server input-server log-server permission-manager storage-server session-server; do
if [ -f "${BUILD_DIR}/${server}" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/${server}" "::servers/${server}.elf"
echo " Copied servers/${server}.elf"
fi
done
# Copy app binaries
for app in snake; do
if [ -f "${BUILD_DIR}/${app}" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/${app}" "::apps/${app}.elf"
echo " Copied apps/${app}.elf"
fi
done
# List contents
echo ""
echo "Disk contents:"
mdir -i "${IMG}" ::
mdir -i "${IMG}" ::servers 2>/dev/null || true
mdir -i "${IMG}" ::apps 2>/dev/null || true
echo ""
echo "=== Done: ${IMG} ==="
copy_files() {
local DIR="$1"
mkdir -p "${DIR}/servers" "${DIR}/apps"
# Copy init
if [ -f "${BUILD_DIR}/hello" ]; then
cp "${BUILD_DIR}/hello" "${DIR}/init.elf"
echo " Copied init.elf"
fi
# Copy any server binaries that exist
for server in display input log permission storage session; do
if [ -f "${BUILD_DIR}/${server}-server" ]; then
cp "${BUILD_DIR}/${server}-server" "${DIR}/servers/${server}.elf"
echo " Copied servers/${server}.elf"
fi
done
# Copy any app binaries that exist
for app in snake; do
if [ -f "${BUILD_DIR}/${app}" ]; then
cp "${BUILD_DIR}/${app}" "${DIR}/apps/${app}.elf"
echo " Copied apps/${app}.elf"
fi
done
}
copy_with_mtools() {
echo "Using mtools to copy files..."
mmd -i "${IMG}" ::servers ::apps 2>/dev/null || true
if [ -f "${BUILD_DIR}/hello" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/hello" "::init.elf"
echo " Copied init.elf"
fi
for server in display input log permission storage session; do
if [ -f "${BUILD_DIR}/${server}-server" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/${server}-server" "::servers/${server}.elf"
echo " Copied servers/${server}.elf"
fi
done
for app in snake; do
if [ -f "${BUILD_DIR}/${app}" ]; then
mcopy -i "${IMG}" "${BUILD_DIR}/${app}" "::apps/${app}.elf"
echo " Copied apps/${app}.elf"
fi
done
}