From 64ff8af074a78de596d329f0de35d23b89233c29 Mon Sep 17 00:00:00 2001 From: czapek1337 Date: Sun, 16 Jan 2022 08:15:20 +0100 Subject: [PATCH] Meta: Add support for the Limine bootloader --- CMakeLists.txt | 5 +++ Meta/build-image-limine.sh | 91 ++++++++++++++++++++++++++++++++++++++ Meta/limine.cfg | 25 +++++++++++ Meta/run.sh | 6 +++ Meta/serenity.sh | 18 +++++--- 5 files changed, 140 insertions(+), 5 deletions(-) create mode 100755 Meta/build-image-limine.sh create mode 100644 Meta/limine.cfg diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b18a35cff7..1bfed5de075 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,11 @@ add_custom_target(grub-image BYPRODUCTS ${CMAKE_BINARY_DIR}/grub_disk_image USES_TERMINAL ) +add_custom_target(limine-image + COMMAND ${CMAKE_COMMAND} -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-limine.sh" + BYPRODUCTS ${CMAKE_BINARY_DIR}/limine_disk_image + USES_TERMINAL +) add_custom_target(extlinux-image COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-extlinux.sh" BYPRODUCTS "${CMAKE_BINARY_DIR}/extlinux_disk_image" diff --git a/Meta/build-image-limine.sh b/Meta/build-image-limine.sh new file mode 100755 index 00000000000..a465a2c52d1 --- /dev/null +++ b/Meta/build-image-limine.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +set -e + +die() { + echo "die: $*" + exit 1 +} + +if [ ! -d "limine" ]; then + echo "limine not found, the script will now build it" + git clone --depth 1 --branch v2.74.6 --single-branch https://github.com/limine-bootloader/limine + make -C limine +fi + +if [ "$(id -u)" != 0 ]; then + exec sudo -E -- "$0" "$@" || die "this script needs to run as root" +else + : "${SUDO_UID:=0}" "${SUDO_GID:=0}" +fi + +disk_usage() { + if [ "$(uname -s)" = "Darwin" ]; then + du -sm "$1" | cut -f1 + else + du -sm --apparent-size "$1" | cut -f1 + fi +} + +DISK_SIZE=$(($(disk_usage "$SERENITY_SOURCE_DIR/Base") + $(disk_usage Root) + 300)) + +echo "setting up disk image..." +dd if=/dev/zero of=limine_disk_image bs=1M count="${DISK_SIZE:-800}" status=none || die "couldn't create disk image" +chown "$SUDO_UID":"$SUDO_GID" limine_disk_image || die "couldn't adjust permissions on disk image" +echo "done" + +printf "creating loopback device... " +dev=$(losetup --find --partscan --show limine_disk_image) +if [ -z "$dev" ]; then + die "couldn't mount loopback device" +fi +echo "loopback device is at ${dev}" + +cleanup() { + if [ -d mnt ]; then + printf "unmounting root partition... " + umount -R mnt || ( sleep 1 && sync && umount -R mnt ) + rmdir mnt + echo "done" + fi + + if [ -d esp ]; then + printf "unmounting efi partition... " + umount -R esp || ( sleep 1 && sync && umount -R esp ) + rmdir esp + echo "done" + fi + + if [ -e "${dev}" ]; then + printf "cleaning up loopback device... " + losetup -d "${dev}" + echo "done" + fi +} + +trap cleanup EXIT + +printf "creating partition table... " +parted -s "${dev}" mklabel gpt mkpart EFI fat32 1MiB 10MiB mkpart ROOT ext2 10MiB 100% set 1 esp on || die "couldn't partition disk" +echo "done" + +printf "creating new filesystems... " +mkfs.vfat -F 32 "${dev}p1" || die "couldn't create efi filesystem" +mke2fs -q -I 128 "${dev}p2" || die "couldn't create root filesystem" +echo "done" + +printf "mounting filesystems... " +mkdir -p esp +mount "${dev}p1" esp || die "couldn't mount efi filesystem" +mkdir -p mnt +mount "${dev}p2" mnt || die "couldn't mount root filesystem" +echo "done" + +script_path=$(cd -P -- "$(dirname -- "$0")" && pwd -P) +"$script_path/build-root-filesystem.sh" + +echo "installing limine" +cp limine/build/bin/limine.sys esp +cp "$SERENITY_SOURCE_DIR"/Meta/limine.cfg esp +limine/build/bin/limine-install "${dev}" +echo "done" diff --git a/Meta/limine.cfg b/Meta/limine.cfg new file mode 100644 index 00000000000..afe4f308d8e --- /dev/null +++ b/Meta/limine.cfg @@ -0,0 +1,25 @@ +TIMEOUT=3 + +:SerenityOS (normal) +PROTOCOL=multiboot1 +CMDLINE=root=/dev/hda2 +KERNEL_PATH=boot://2/boot/Prekernel +MODULE_PATH=boot://2/boot/Kernel + +:SerenityOS (text mode) +PROTOCOL=multiboot1 +CMDLINE=fbdev=off root=/dev/hda2 +KERNEL_PATH=boot://2/boot/Prekernel +MODULE_PATH=boot://2/boot/Kernel + +:SerenityOS (no ACPI) +PROTOCOL=multiboot1 +CMDLINE=root=/dev/hda2 acpi=off +KERNEL_PATH=boot://2/boot/Prekernel +MODULE_PATH=boot://2/boot/Kernel + +:SerenityOS (with serial output) +PROTOCOL=multiboot1 +CMDLINE=root=/dev/hda2 +KERNEL_PATH=boot://2/boot/Prekernel +MODULE_PATH=boot://2/boot/Kernel diff --git a/Meta/run.sh b/Meta/run.sh index 8d320e1747b..1c395d35b5d 100755 --- a/Meta/run.sh +++ b/Meta/run.sh @@ -89,6 +89,8 @@ fi [ -z "$SERENITY_DISK_IMAGE" ] && { if [ "$SERENITY_RUN" = q35grub ] || [ "$SERENITY_RUN" = qgrub ]; then SERENITY_DISK_IMAGE="grub_disk_image" + elif [ "$SERENITY_RUN" = limine ]; then + SERENITY_DISK_IMAGE="limine_disk_image" elif [ "$SERENITY_RUN" = qextlinux ]; then SERENITY_DISK_IMAGE="extlinux_disk_image" else @@ -374,6 +376,10 @@ elif [ "$SERENITY_RUN" = "q35grub" ]; then $SERENITY_VIRT_TECH_ARG \ -netdev user,id=breh,hostfwd=tcp:127.0.0.1:8888-10.0.2.15:8888,hostfwd=tcp:127.0.0.1:8823-10.0.2.15:23 \ -device $SERENITY_ETHERNET_DEVICE_TYPE,netdev=breh +elif [ "$SERENITY_RUN" = "limine" ]; then + "$SERENITY_QEMU_BIN" \ + $SERENITY_COMMON_QEMU_ARGS \ + $SERENITY_VIRT_TECH_ARG elif [ "$SERENITY_RUN" = "ci" ]; then # Meta/run.sh ci: qemu in text mode echo "Running QEMU in CI" diff --git a/Meta/serenity.sh b/Meta/serenity.sh index 44773cad66e..9743b2b6e7d 100755 --- a/Meta/serenity.sh +++ b/Meta/serenity.sh @@ -226,6 +226,14 @@ build_target() { fi } +build_image() { + if [ "$SERENITY_RUN" = "limine" ]; then + build_target limine-image + else + build_target image + fi +} + delete_target() { [ ! -d "$BUILD_DIR" ] || rm -rf "$BUILD_DIR" [ ! -d "$SUPER_BUILD_DIR" ] || rm -rf "$SUPER_BUILD_DIR" @@ -335,14 +343,14 @@ if [[ "$CMD" =~ ^(build|install|image|copy-src|run|gdb|test|rebuild|recreate|kad lagom_unsupported build_target build_target install - build_target image + build_image ;; copy-src) lagom_unsupported build_target build_target install export SERENITY_COPY_SOURCE=1 - build_target image + build_image ;; run) if [ "$TARGET" = "lagom" ]; then @@ -351,7 +359,7 @@ if [[ "$CMD" =~ ^(build|install|image|copy-src|run|gdb|test|rebuild|recreate|kad else build_target build_target install - build_target image + build_image if [ -n "${CMD_ARGS[0]}" ]; then export SERENITY_KERNEL_CMDLINE="${CMD_ARGS[0]}" fi @@ -367,7 +375,7 @@ if [[ "$CMD" =~ ^(build|install|image|copy-src|run|gdb|test|rebuild|recreate|kad else build_target build_target install - build_target image + build_image tmux new-session "$ARG0" __tmux_cmd "$TARGET" run "${CMD_ARGS[@]}" \; set-option -t 0 mouse on \; split-window "$ARG0" __tmux_cmd "$TARGET" gdb "${CMD_ARGS[@]}" \; fi ;; @@ -377,7 +385,7 @@ if [[ "$CMD" =~ ^(build|install|image|copy-src|run|gdb|test|rebuild|recreate|kad run_tests "${CMD_ARGS[0]}" else build_target install - build_target image + build_image # In contrast to CI, we don't set 'panic=shutdown' here, # in case the user wants to inspect qemu some more. export SERENITY_KERNEL_CMDLINE="fbdev=off system_mode=self-test"