xref: /DragonBoot/tools/run-qemu.sh (revision 0ec3a34a58ffc0a9c51a23a7ee5e7d803a0060cd)
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