xref: /DragonStub/tools/run-qemu.sh (revision f412fd2a1a248b546b7085648dece8d908077fab)
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