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