增加uefi启动 (#101)

* 增加uefi启动

* 修改脚本

* uefi修改

* 删除错误的注释

* 修正写入磁盘镜像的脚本

* 修改X86_64为x86_64

Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
YJwu2023 2022-12-09 16:08:54 +08:00 committed by GitHub
parent 1a2eaa402f
commit 7f439c5ddb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 172 additions and 36 deletions

View File

@ -66,12 +66,18 @@ gdb:
# 写入磁盘镜像
write_diskimage:
sudo sh -c "cd tools && bash $(ROOT_PATH)/tools/write_disk_image.sh && cd .."
sudo sh -c "cd tools && bash $(ROOT_PATH)/tools/write_disk_image.sh --bios=legacy && cd .."
# 写入磁盘镜像(uefi)
write_diskimage-uefi:
sudo sh -c "cd tools && bash $(ROOT_PATH)/tools/write_disk_image.sh --bios=uefi && cd .."
# 不编译直接启动QEMU
qemu:
sh -c "cd tools && bash run-qemu.sh && cd .."
sh -c "cd tools && bash run-qemu.sh --bios=legacy && cd .."
# 不编译直接启动QEMU(UEFI)
qemu-uefi:
sh -c "cd tools && bash run-qemu.sh --bios=uefi && cd .."
# 编译并写入磁盘镜像
build:
$(MAKE) all -j $(NPROCS)
@ -81,7 +87,13 @@ build:
docker:
@echo "使用docker构建"
sudo bash tools/build_in_docker.sh || exit 1
# uefi方式启动
run-uefi:
$(MAKE) all -j $(NPROCS)
$(MAKE) write_diskimage-uefi || exit 1
$(MAKE) qemu-uefi
# 编译并启动QEMU
run:
$(MAKE) all -j $(NPROCS)

BIN
tools/arch/x86_64/OVMF.fd Normal file

Binary file not shown.

View File

@ -176,4 +176,9 @@ fi
# 创建磁盘镜像
bash create_hdd_image.sh
congratulations
# 解决kvm权限问题
USR=$USER
sudo adduser $USR kvm
sudo chowm $USR /dev/kvm
congratulations

View File

@ -1,9 +1,18 @@
echo "Creating virtual disk image..."
########################################################################
# 这是一个用于创建磁盘镜像的脚本
# 用法:./create_hdd_image.sh -P MBR/GPT
# 要创建一个MBR分区表的磁盘镜像请这样运行它 bash create_hdd_image.sh -P MBR
# 要创建一个GPT分区表的磁盘镜像请这样运行它 bash create_hdd_image.sh -P GPT
# 请注意这个脚本需要root权限
# 请注意运行这个脚本之前需要在您的计算机上安装qemu-img和fdisk以及parted
#
# 这个脚本会在当前目录下创建一个名为disk.img的文件这个文件就是磁盘镜像
# 在完成后会将这个文件移动到bin目录下
########################################################################
# 创建一至少为32MB磁盘镜像类型选择raw
qemu-img create -f raw disk.img 32M
# 使用fdisk把disk.img的分区表设置为MBR格式(下方的空行请勿删除)
format_as_mbr() {
echo "Formatting as MBR..."
# 使用fdisk把disk.img的分区表设置为MBR格式(下方的空行请勿删除)
fdisk disk.img << EOF
o
n
@ -14,6 +23,59 @@ n
w
EOF
}
format_as_gpt() {
echo "Formatting as GPT..."
sudo parted disk.img << EOF
mklabel gpt
y
mkpart
p1
FAT32
0
-1
I
set
1
boot
on
print
q
EOF
}
echo "Creating virtual disk image..."
ARGS=`getopt -o P: -- "$@"`
# 创建一至少为64MB磁盘镜像类型选择raw
qemu-img create -f raw disk.img 64M
#将规范化后的命令行参数分配至位置参数($1,$2,...)
eval set -- "${ARGS}"
#echo formatted parameters=[$@]
#根据传入参数进行MBR/GPT分区
case "$1" in
-P)
if [ $2 == "MBR" ];
then
format_as_mbr
elif [ $2 == "GPT" ];
then
format_as_gpt
else
echo "Invalid partition type: $2"
exit 1
fi
;;
--)
# 如果没有传入参数-P则默认为MBR分区
format_as_mbr
;;
*)
echo "Invalid option: $1"
exit 1
;;
esac
LOOP_DEVICE=$(sudo losetup -f --show -P disk.img) \
|| exit 1
echo ${LOOP_DEVICE}p1

View File

@ -1,36 +1,53 @@
# 进行启动前检查
flag_can_run=1
ARGS=`getopt -o p -l bios: -- "$@"`
eval set -- "${ARGS}"
echo "$@"
allflags=$(qemu-system-x86_64 -cpu help | awk '/flags/ {y=1; getline}; y {print}' | tr ' ' '\n' | grep -Ev "^$" | sed -r 's|^|+|' | tr '\n' ',' | sed -r "s|,$||")
# 请根据自己的需要,在-d 后方加入所需的trace事件
# 标准的trace events
qemu_trace_std=cpu_reset,guest_errors,trace:check_exception,exec,cpu
qemu_trace_std=cpu_reset,guest_errors,exec,cpu
# 调试usb的trace
qemu_trace_usb=trace:usb_xhci_reset,trace:usb_xhci_run,trace:usb_xhci_stop,trace:usb_xhci_irq_msi,trace:usb_xhci_irq_msix,trace:usb_xhci_port_reset,trace:msix_write_config,trace:usb_xhci_irq_msix,trace:usb_xhci_irq_msix_use,trace:usb_xhci_irq_msix_unuse,trace:usb_xhci_irq_msi,trace:usb_xhci_*
qemu_accel=kvm
if [ $(uname) == Darwin ]; then
qemu_accel=hvf
fi
QEMU=qemu-system-x86_64
QEMU_DISK_IMAGE="../bin/disk.img"
QEMU_MEMORY="512M"
QEMU_SMP="2,cores=2,threads=1,sockets=1"
QEMU_MONITOR="stdio"
QEMU_TRACE="${qemu_trace_std}"
QEMU_CPU_FEATURES="IvyBridge,apic,x2apic,+fpu,check,${allflags}"
QEMU_RTC_CLOCK="clock=host,base=localtime"
QEMU_SERIAL="file:../serial_opt.txt"
QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none"
QEMU_DEVICES="-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 -net nic,model=virtio -usb -device qemu-xhci,id=xhci,p2=8,p3=4 -machine accel=${qemu_accel}"
QEMU_ARGUMENT="-d ${QEMU_DISK_IMAGE} -m ${QEMU_MEMORY} -smp ${QEMU_SMP} -boot order=d -monitor ${QEMU_MONITOR} -d ${qemu_trace_std} "
QEMU_ARGUMENT+="-s -S -cpu ${QEMU_CPU_FEATURES} -rtc ${QEMU_RTC_CLOCK} -serial ${QEMU_SERIAL} -drive ${QEMU_DRIVE} ${QEMU_DEVICES}"
if [ $flag_can_run -eq 1 ]; then
qemu-system-x86_64 -d ../bin/disk.img -m 512M -smp 2,cores=2,threads=1,sockets=1 \
-boot order=d \
-monitor stdio -d ${qemu_trace_std} \
-s -S -cpu IvyBridge,apic,x2apic,+fpu,check,${allflags} -rtc clock=host,base=localtime -serial file:../serial_opt.txt \
-drive id=disk,file=../bin/disk.img,if=none \
-device ahci,id=ahci \
-device ide-hd,drive=disk,bus=ahci.0 \
-net nic,model=virtio \
-usb \
-device qemu-xhci,id=xhci,p2=8,p3=4 \
-machine accel=${qemu_accel}
case "$1" in
--bios)
case "$2" in
uefi) #uefi启动新增ovmf.fd固件
${QEMU} -bios arch/X86_64/OVMF.fd ${QEMU_ARGUMENT}
;;
legacy)
${QEMU} ${QEMU_ARGUMENT}
;;
esac
esac
else
echo "不满足运行条件"
fi
fi

View File

@ -1,9 +1,21 @@
###############################################
# 该脚本用于将disk_mount目录下的文件写入到disk.img的第一个分区中
# 并在磁盘镜像中安装grub引导程序
#
# 用法bash write_disk_image.sh --bios legacy/uefi
# 如果之前创建的disk.img是MBR分区表那么请这样运行它bash write_disk_image.sh --bios legacy
# 如果之前创建的disk.img是GPT分区表那么请这样运行它bash write_disk_image.sh --bios uefi
###############################################
ARCH="x86_64"
# 内核映像
root_folder=$(dirname $(pwd))
kernel="${root_folder}/bin/kernel/kernel.elf"
boot_folder="${root_folder}/bin/disk_mount/boot"
mount_folder="${root_folder}/bin/disk_mount"
ARGS=`getopt -o p -l bios: -- "$@"`
eval set -- "${ARGS}"
#echo formatted parameters=[$@]
echo "开始写入磁盘镜像..."
@ -23,7 +35,7 @@ bins[0]=${kernel}
for file in ${bins[*]};do
if [ ! -x $file ]; then
echo "$file 不存在!"
exit 1
exit
fi
done
@ -39,13 +51,28 @@ if [ ${ARCH} == "i386" ] || [ ${ARCH} == "x86_64" ]; then
fi
fi
# 拷贝程序到硬盘
# 判断是否存在硬盘镜像文件,如果不存在,就创建一个(docker模式下由于镜像中缺少qemu-img不会创建)
if [ ! -f "${root_folder}/bin/disk.img" ]; then
echo "创建硬盘镜像文件..."
sudo bash ./create_hdd_image.sh || exit 1
case "$1" in
--bios)
case "$2" in
uefi)
sudo bash ./create_hdd_image.sh -P GPT #GPT分区
;;
legacy)
sudo bash ./create_hdd_image.sh -P MBR #MBR分区
;;
esac
;;
*)
# 默认创建MBR分区
sudo bash ./create_hdd_image.sh -P MBR #MBR分区
;;
esac
fi
# 拷贝程序到硬盘
mkdir -p ${root_folder}/bin/disk_mount
bash mount_virt_disk.sh || exit 1
mkdir -p ${boot_folder}/grub
@ -54,7 +81,6 @@ cp ${kernel} ${root_folder}/bin/disk_mount/boot
mkdir -p ${root_folder}/bin/disk_mount/bin
mkdir -p ${root_folder}/bin/disk_mount/dev
mkdir -p ${root_folder}/bin/disk_mount/proc
cp -r ${root_folder}/bin/user/* ${root_folder}/bin/disk_mount/bin
touch ${root_folder}/bin/disk_mount/dev/keyboard.dev
@ -73,8 +99,22 @@ fi
# rm -rf ${iso_folder}
LOOP_DEVICE=$(lsblk | grep disk_mount|sed 's/.*\(loop[0-9]*\)p1.*/\1/1g'|awk 'END{print $0}')
echo $LOOP_DEVICE
grub-install --target=i386-pc --boot-directory=${root_folder}/bin/disk_mount/boot/ /dev/$LOOP_DEVICE
case "$1" in
--bios)
case "$2" in
uefi) #uefi
grub-install --target=x86_64-efi --efi-directory=${mount_folder} --boot-directory=${boot_folder} --removable
;;
legacy) #传统bios
grub-install --target=i386-pc --boot-directory=${boot_folder} /dev/$LOOP_DEVICE
;;
esac
;;
*)
echo "参数错误"
;;
esac
sync
bash umount_virt_disk.sh