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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user