1#!/bin/bash 2 3# uboot版本 4UBOOT_VERSION="v2023.10" 5RISCV64_UBOOT_PATH="arch/riscv64/u-boot-${UBOOT_VERSION}-riscv64" 6 7export ARCH=${ARCH:=riscv64} 8echo "ARCH: ${ARCH}" 9 10# 磁盘镜像 11DISK_NAME="disk-${ARCH}.img" 12 13QEMU=qemu-system-${ARCH} 14QEMU_MEMORY="512M" 15QEMU_SMP="2,cores=2,threads=1,sockets=1" 16QEMU_ACCELARATE="" 17QEMU_DISK_IMAGE="../output/${DISK_NAME}" 18QEMU_DRIVE="-drive id=disk,file=${QEMU_DISK_IMAGE},if=none" 19QEMU_DEVICES=" -device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 " 20 21# 标准的trace events 22# qemu_trace_std=cpu_reset,guest_errors 23qemu_trace_std=cpu_reset 24 25QEMU_ARGUMENT="" 26 27if [ ${ARCH} == "riscv64" ]; then 28 QEMU_MACHINE=" -machine virt " 29 QEMU_MONITOR="" 30 QEMU_ARGUMENT+=" --nographic " 31 32else 33 echo "不支持的架构" 34 exit 1 35fi 36QEMU_ARGUMENT+=" -d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d ${QEMU_MONITOR} -d ${qemu_trace_std} " 37QEMU_ARGUMENT+=" -s ${QEMU_MACHINE} " 38QEMU_ARGUMENT+=" ${QEMU_DEVICES} ${QEMU_DRIVE} " 39 40 41TMP_LOOP_DEVICE="" 42 43# 安装riscv64的uboot 44install_riscv_uboot() 45{ 46 47 if [ ! -d ${RISCV64_UBOOT_PATH} ]; then 48 echo "正在下载u-boot..." 49 uboot_tar_name="u-boot-${UBOOT_VERSION}-riscv64.tar.xz" 50 51 uboot_parent_path=$(dirname ${RISCV64_UBOOT_PATH}) || (echo "获取riscv u-boot 版本 ${UBOOT_VERSION} 的父目录失败" && exit 1) 52 53 if [ ! -f ${uboot_tar_name} ]; then 54 wget https://mirrors.dragonos.org.cn/pub/third_party/u-boot/${uboot_tar_name} || (echo "下载riscv u-boot 版本 ${UBOOT_VERSION} 失败" && exit 1) 55 fi 56 echo "下载完成" 57 echo "正在解压u-boot到 '$uboot_parent_path'..." 58 mkdir -p $uboot_parent_path 59 tar xvf u-boot-${UBOOT_VERSION}-riscv64.tar.xz -C ${uboot_parent_path} || (echo "解压riscv u-boot 版本 ${UBOOT_VERSION} 失败" && exit 1) 60 echo "解压完成" 61 rm -rf u-boot-${UBOOT_VERSION}-riscv64.tar.xz 62 fi 63 echo "riscv u-boot 版本 ${UBOOT_VERSION} 已经安装" 64} 65 66run_qemu() 67{ 68 echo "正在启动qemu..." 69 70 if [ ${ARCH} == "riscv64" ]; then 71 QEMU_ARGUMENT+=" -kernel ${RISCV64_UBOOT_PATH}/u-boot.bin " 72 fi 73 74 echo "qemu命令: ${QEMU} ${QEMU_ARGUMENT}" 75 ${QEMU} ${QEMU_ARGUMENT} 76} 77 78 79format_as_mbr() { 80 echo "Formatting as MBR..." 81 # 使用fdisk把disk.img的分区表设置为MBR格式(下方的空行请勿删除) 82fdisk ${QEMU_DISK_IMAGE} << EOF 83o 84n 85 86 87 88 89a 90w 91EOF 92 93} 94 95 96mount_disk_image(){ 97 echo "正在挂载磁盘镜像..." 98 TMP_LOOP_DEVICE=$(sudo losetup -f --show -P ${QEMU_DISK_IMAGE}) || exit 1 99 100 # 根据函数入参判断是否需要格式化磁盘镜像 101 if [ "$1" == "mnt" ]; then 102 mkdir -p ../output/mnt 103 sudo mount ${TMP_LOOP_DEVICE}p1 ../output/mnt 104 fi 105 106 echo "挂载磁盘镜像完成" 107} 108 109umount_disk_image(){ 110 echo "正在卸载磁盘镜像..." 111 if [ "$1" == "mnt" ]; then 112 sudo umount ../output/mnt 113 fi 114 sudo losetup -d ${TMP_LOOP_DEVICE} || (echo "卸载磁盘镜像失败" && exit 1) 115 echo "卸载磁盘镜像完成" 116} 117 118prepare_disk_image() 119{ 120 # 如果磁盘镜像不存在,则创建磁盘镜像 121 122 echo "正在准备磁盘镜像..." 123 if [ ! -f ${QEMU_DISK_IMAGE} ]; then 124 echo "正在创建磁盘镜像..." 125 qemu-img create -f raw ${QEMU_DISK_IMAGE} 256M || (echo "创建磁盘镜像失败" && exit 1) 126 format_as_mbr 127 128 mount_disk_image 129 echo "loop device: ${TMP_LOOP_DEVICE}" 130 echo "正在格式化磁盘镜像..." 131 sudo mkfs.vfat -F 32 ${TMP_LOOP_DEVICE}p1 132 umount_disk_image 133 134 echo "Successfully mkfs" 135 136 chmod 777 ${QEMU_DISK_IMAGE} 137 138 echo "创建磁盘镜像完成" 139 fi 140 echo "磁盘镜像已经准备好" 141} 142 143 144write_disk_image(){ 145 mkdir -p ../output/sysroot 146 echo "正在写入磁盘镜像..." 147 mount_disk_image mnt 148 149 mkdir -p ../output/sysroot/efi/boot 150 if [ ${ARCH} == "riscv64" ]; then 151 cp ../output/dragon_stub-riscv64.efi ../output/sysroot/efi/boot/bootriscv64.efi 152 fi 153 154 sudo cp -r ../output/sysroot/* ../output/mnt 155 156 umount_disk_image mnt 157 echo "写入磁盘镜像完成" 158 159} 160 161main() 162{ 163 install_riscv_uboot 164 prepare_disk_image 165 write_disk_image 166 run_qemu 167} 168 169main